Skip to content

Commit 26babaa

Browse files
committed
auto merge of #6559 : jbclements/rust/hygiene-fns-and-cleanup, r=jbclements
This includes new, tested, hygiene support functions. It also removes the interner_key! macro and replaces it with a function, which should be inline-able. It also contains some parser patch-ups and some docfixes. On my machine, this patch passes all tests.
2 parents f3b458b + b71a1ec commit 26babaa

File tree

14 files changed

+359
-271
lines changed

14 files changed

+359
-271
lines changed

doc/rust.md

+16-12
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,14 @@ do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ;
22502250
A _do expression_ provides a more-familiar block-syntax for a [lambda expression](#lambda-expressions),
22512251
including a special translation of [return expressions](#return-expressions) inside the supplied block.
22522252

2253+
Any occurrence of a [return expression](#return-expressions)
2254+
inside this `block` expression is rewritten
2255+
as a reference to an (anonymous) flag set in the caller's environment,
2256+
which is checked on return from the `expr` and, if set,
2257+
causes a corresponding return from the caller.
2258+
In this way, the meaning of `return` statements in language built-in control blocks is preserved,
2259+
if they are rewritten using lambda functions and `do` expressions as abstractions.
2260+
22532261
The optional `ident_list` and `block` provided in a `do` expression are parsed as though they constitute a lambda expression;
22542262
if the `ident_list` is missing, an empty `ident_list` is implied.
22552263

@@ -2296,19 +2304,15 @@ A _for expression_ is similar to a [`do` expression](#do-expressions),
22962304
in that it provides a special block-form of lambda expression,
22972305
suited to passing the `block` function to a higher-order function implementing a loop.
22982306

2299-
Like a `do` expression, a `return` expression inside a `for` expresison is rewritten,
2300-
to access a local flag that causes an early return in the caller.
2301-
2302-
Additionally, any occurrence of a [return expression](#return-expressions)
2303-
inside the `block` of a `for` expression is rewritten
2304-
as a reference to an (anonymous) flag set in the caller's environment,
2305-
which is checked on return from the `expr` and, if set,
2306-
causes a corresponding return from the caller.
2307-
In this way, the meaning of `return` statements in language built-in control blocks is preserved,
2308-
if they are rewritten using lambda functions and `do` expressions as abstractions.
2307+
In contrast to a `do` expression, a `for` expression is designed to work
2308+
with methods such as `each` and `times`, that require the body block to
2309+
return a boolean. The `for` expression accommodates this by implicitly
2310+
returning `true` at the end of each block, unless a `break` expression
2311+
is evaluated.
23092312

2310-
Like `return` expressions, any [`break`](#break-expressions) and [`loop`](#loop-expressions) expressions
2311-
are rewritten inside `for` expressions, with a combination of local flag variables,
2313+
In addition, [`break`](#break-expressions) and [`loop`](#loop-expressions) expressions
2314+
are rewritten inside `for` expressions in the same way that `return` expressions are,
2315+
with a combination of local flag variables,
23122316
and early boolean-valued returns from the `block` function,
23132317
such that the meaning of `break` and `loop` is preserved in a primitive loop
23142318
when rewritten as a `for` loop controlled by a higher order function.

src/librustdoc/extract.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,18 @@ use doc;
1717
use core::local_data::local_data_get;
1818
use syntax::ast;
1919
use syntax;
20-
21-
/* can't import macros yet, so this is copied from token.rs. See its comment
22-
* there. */
23-
macro_rules! interner_key (
24-
() => (cast::transmute::<(uint, uint),
25-
&fn(v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
26-
)
20+
use syntax::parse::token::{ident_interner};
21+
use syntax::parse::token;
2722

2823
// Hack; rather than thread an interner through everywhere, rely on
2924
// thread-local data
3025
pub fn to_str(id: ast::ident) -> ~str {
31-
let intr = unsafe{ local_data_get(interner_key!()) };
32-
33-
return copy *(*intr.get()).get(id);
26+
let intr = token::get_ident_interner();
27+
return copy *(*intr).get(id);
3428
}
3529

36-
pub fn interner() -> @syntax::parse::token::ident_interner {
37-
return *(unsafe{ local_data_get(interner_key!()) }).get();
30+
pub fn interner() -> @ident_interner {
31+
return token::get_ident_interner();
3832
}
3933

4034
pub fn from_srv(

src/libsyntax/ast.rs

+16-20
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
use codemap::{span, spanned};
1414
use abi::AbiSet;
1515
use opt_vec::OptVec;
16+
use parse::token::get_ident_interner;
1617

1718
use core::cast;
18-
use core::option::{None, Option, Some};
19+
use core::option::{Option};
1920
use core::to_bytes;
2021
use core::to_bytes::IterBytes;
2122
use core::to_str::ToStr;
23+
use core::hashmap::HashMap;
2224
use std::serialize::{Encodable, Decodable, Encoder, Decoder};
2325

2426

@@ -38,14 +40,20 @@ pub struct ident { repr: Name, ctxt: SyntaxContext }
3840
// that's causing unreleased memory to cause core dumps
3941
// and also perhaps to save some work in destructor checks.
4042
// the special uint '0' will be used to indicate an empty
41-
// syntax context
43+
// syntax context.
4244

4345
// this uint is a reference to a table stored in thread-local
4446
// storage.
4547
pub type SyntaxContext = uint;
4648

47-
pub type SCTable = ~[SyntaxContext_];
49+
pub struct SCTable {
50+
table : ~[SyntaxContext_],
51+
mark_memo : HashMap<(SyntaxContext,Mrk),SyntaxContext>,
52+
rename_memo : HashMap<(SyntaxContext,ident,Name),SyntaxContext>
53+
}
54+
// NB: these must be placed in any SCTable...
4855
pub static empty_ctxt : uint = 0;
56+
pub static illegal_ctxt : uint = 1;
4957

5058
#[deriving(Eq, Encodable, Decodable)]
5159
pub enum SyntaxContext_ {
@@ -59,7 +67,8 @@ pub enum SyntaxContext_ {
5967
// "to" slot must have the same name and context
6068
// in the "from" slot. In essence, they're all
6169
// pointers to a single "rename" event node.
62-
Rename (ident,Name,SyntaxContext)
70+
Rename (ident,Name,SyntaxContext),
71+
IllegalCtxt()
6372
}
6473

6574
// a name represents an identifier
@@ -70,27 +79,14 @@ pub type Mrk = uint;
7079

7180
impl<S:Encoder> Encodable<S> for ident {
7281
fn encode(&self, s: &mut S) {
73-
unsafe {
74-
let intr =
75-
match local_data::local_data_get(interner_key!()) {
76-
None => fail!("encode: TLS interner not set up"),
77-
Some(intr) => intr
78-
};
79-
80-
s.emit_str(*(*intr).get(*self));
81-
}
82+
let intr = get_ident_interner();
83+
s.emit_str(*(*intr).get(*self));
8284
}
8385
}
8486

8587
impl<D:Decoder> Decodable<D> for ident {
8688
fn decode(d: &mut D) -> ident {
87-
let intr = match unsafe {
88-
local_data::local_data_get(interner_key!())
89-
} {
90-
None => fail!("decode: TLS interner not set up"),
91-
Some(intr) => intr
92-
};
93-
89+
let intr = get_ident_interner();
9490
(*intr).intern(d.read_str())
9591
}
9692
}

0 commit comments

Comments
 (0)