Skip to content

Commit a089c6f

Browse files
committed
auto merge of #5908 : jbclements/rust/add-hygiene-machinery, r=graydon
This pull request changes the representation of identifiers by adding an integer to the side of each one. This integer will eventually be a reference to a side-table of syntax contexts, presumably stored in TLS. This pull request also adds a bunch of utility functions required for hygiene, and associated tests, but doesn't actually deploy those functions. Finally, it also has a number of small cleanup items.
2 parents fdb4ef3 + e7aa24d commit a089c6f

File tree

8 files changed

+541
-114
lines changed

8 files changed

+541
-114
lines changed

src/libsyntax/ast.rs

+99-33
Original file line numberDiff line numberDiff line change
@@ -22,45 +22,53 @@ use core::to_str::ToStr;
2222
use std::serialize::{Encodable, Decodable, Encoder, Decoder};
2323

2424

25-
/* can't import macros yet, so this is copied from token.rs. See its comment
26-
* there. */
27-
macro_rules! interner_key (
28-
() => (cast::transmute::<(uint, uint),
29-
&fn(+v: @@::parse::token::ident_interner)>(
30-
(-3 as uint, 0u)))
31-
)
32-
3325
// an identifier contains an index into the interner
3426
// table and a SyntaxContext to track renaming and
3527
// macro expansion per Flatt et al., "Macros
3628
// That Work Together"
3729
#[deriving(Eq)]
38-
pub struct ident { repr: Name }
30+
pub struct ident { repr: Name, ctxt: SyntaxContext }
3931

4032
// a SyntaxContext represents a chain of macro-expandings
4133
// and renamings. Each macro expansion corresponds to
4234
// a fresh uint
35+
36+
// I'm representing this syntax context as an index into
37+
// a table, in order to work around a compiler bug
38+
// that's causing unreleased memory to cause core dumps
39+
// and also perhaps to save some work in destructor checks.
40+
// the special uint '0' will be used to indicate an empty
41+
// syntax context
42+
43+
// this uint is a reference to a table stored in thread-local
44+
// storage.
45+
pub type SyntaxContext = uint;
46+
47+
pub type SCTable = ~[SyntaxContext_];
48+
pub static empty_ctxt : uint = 0;
49+
4350
#[deriving(Eq)]
44-
pub enum SyntaxContext {
45-
MT,
46-
Mark (Mrk,~SyntaxContext),
47-
Rename (~ident,Name,~SyntaxContext)
51+
#[auto_encode]
52+
#[auto_decode]
53+
pub enum SyntaxContext_ {
54+
EmptyCtxt,
55+
Mark (Mrk,SyntaxContext),
56+
// flattening the name and syntaxcontext into the rename...
57+
// HIDDEN INVARIANTS:
58+
// 1) the first name in a Rename node
59+
// can only be a programmer-supplied name.
60+
// 2) Every Rename node with a given Name in the
61+
// "to" slot must have the same name and context
62+
// in the "from" slot. In essence, they're all
63+
// pointers to a single "rename" event node.
64+
Rename (ident,Name,SyntaxContext)
4865
}
4966

50-
/*
51-
// ** this is going to have to apply to paths, not to idents.
52-
// Returns true if these two identifiers access the same
53-
// local binding or top-level binding... that's what it
54-
// should do. For now, it just compares the names.
55-
pub fn free_ident_eq (a : ident, b: ident) -> bool{
56-
a.repr == b.repr
57-
}
58-
*/
59-
// a name represents a string, interned
60-
type Name = uint;
67+
// a name represents an identifier
68+
pub type Name = uint;
6169
// a mark represents a unique id associated
6270
// with a macro expansion
63-
type Mrk = uint;
71+
pub type Mrk = uint;
6472

6573
impl<S:Encoder> Encodable<S> for ident {
6674
fn encode(&self, s: &S) {
@@ -1310,22 +1318,77 @@ pub enum inlined_item {
13101318
ii_dtor(struct_dtor, ident, Generics, def_id /* parent id */)
13111319
}
13121320

1321+
/* hold off on tests ... they appear in a later merge.
13131322
#[cfg(test)]
13141323
mod test {
1315-
//are asts encodable?
1316-
1317-
// it looks like this *will* be a compiler bug, after
1318-
// I get deriving_eq for crates into incoming :)
1319-
/*
1324+
use core::option::{None, Option, Some};
1325+
use core::uint;
13201326
use std;
13211327
use codemap::*;
13221328
use super::*;
13231329
1330+
1331+
#[test] fn xorpush_test () {
1332+
let mut s = ~[];
1333+
xorPush(&mut s,14);
1334+
assert_eq!(s,~[14]);
1335+
xorPush(&mut s,14);
1336+
assert_eq!(s,~[]);
1337+
xorPush(&mut s,14);
1338+
assert_eq!(s,~[14]);
1339+
xorPush(&mut s,15);
1340+
assert_eq!(s,~[14,15]);
1341+
xorPush (&mut s,16);
1342+
assert_eq! (s,~[14,15,16]);
1343+
xorPush (&mut s,16);
1344+
assert_eq! (s,~[14,15]);
1345+
xorPush (&mut s,15);
1346+
assert_eq! (s,~[14]);
1347+
}
1348+
1349+
#[test] fn test_marksof () {
1350+
let stopname = uints_to_name(&~[12,14,78]);
1351+
let name1 = uints_to_name(&~[4,9,7]);
1352+
assert_eq!(marksof (MT,stopname),~[]);
1353+
assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1354+
// does xoring work?
1355+
assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1356+
~[16]);
1357+
// does nested xoring work?
1358+
assert_eq! (marksof (Mark (5,
1359+
@Mark (10,
1360+
@Mark (10,
1361+
@Mark (5,
1362+
@Mark (16,@MT))))),
1363+
stopname),
1364+
~[16]);
1365+
// stop has no effect on marks
1366+
assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1367+
~[9,14,12]);
1368+
// rename where stop doesn't match:
1369+
assert_eq! (marksof (Mark (9, @Rename
1370+
(name1,
1371+
@Mark (4, @MT),
1372+
uints_to_name(&~[100,101,102]),
1373+
@Mark (14, @MT))),
1374+
stopname),
1375+
~[9,14]);
1376+
// rename where stop does match
1377+
;
1378+
assert_eq! (marksof (Mark(9, @Rename (name1,
1379+
@Mark (4, @MT),
1380+
stopname,
1381+
@Mark (14, @MT))),
1382+
stopname),
1383+
~[9]);
1384+
}
1385+
1386+
// are ASTs encodable?
13241387
#[test] fn check_asts_encodable() {
13251388
let bogus_span = span {lo:BytePos(10),
13261389
hi:BytePos(20),
13271390
expn_info:None};
1328-
let _e : crate =
1391+
let e : crate =
13291392
spanned{
13301393
node: crate_{
13311394
module: _mod {view_items: ~[], items: ~[]},
@@ -1334,10 +1397,13 @@ mod test {
13341397
},
13351398
span: bogus_span};
13361399
// doesn't matter which encoder we use....
1337-
let _f = (_e as std::serialize::Encodable::<std::json::Encoder>);
1400+
let _f = (@e as @std::serialize::Encodable<std::json::Encoder>);
13381401
}
1339-
*/
1402+
1403+
13401404
}
1405+
1406+
*/
13411407
//
13421408
// Local Variables:
13431409
// mode: rust

0 commit comments

Comments
 (0)