From aa024acae3912d7d58e38fdd8185a115f2ab4e8f Mon Sep 17 00:00:00 2001 From: Paul Stansifer Date: Fri, 24 Aug 2012 12:19:19 -0700 Subject: [PATCH] Use a faked-up function as a key, because functions aren't identical cross-crate in Windows. --- src/libsyntax/ast.rs | 12 ++++++++++-- src/libsyntax/parse/token.rs | 14 ++++++++++---- src/rustdoc/extract.rs | 14 ++++++++++---- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b921fbf5a28b..4cc161e1b5cf 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -30,8 +30,16 @@ fn deserialize_span(_d: D) -> span { #[auto_serialize] type spanned = {node: T, span: span}; + +/* can't import macros yet, so this is copied from token.rs. See its comment + * there. */ +macro_rules! interner_key ( + () => (unsafe::transmute::<(uint, uint), &fn(+@@token::ident_interner)>( + (-3 as uint, 0u))) +) + fn serialize_ident(s: S, i: ident) { - let intr = match unsafe{task::local_data_get(parse::token::interner_key)}{ + let intr = match unsafe{task::local_data_get(interner_key!())}{ none => fail ~"serialization: TLS interner not set up", some(intr) => intr }; @@ -39,7 +47,7 @@ fn serialize_ident(s: S, i: ident) { s.emit_str(*(*intr).get(i)); } fn deserialize_ident(d: D) -> ident { - let intr = match unsafe{task::local_data_get(parse::token::interner_key)}{ + let intr = match unsafe{task::local_data_get(interner_key!())}{ none => fail ~"deserialization: TLS interner not set up", some(intr) => intr }; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 8eb9270efe26..759d99511fea 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -325,8 +325,14 @@ mod special_idents { type ident_interner = util::interner::interner<@~str>; /** Key for thread-local data for sneaking interner information to the - * serializer/deserializer. It sounds like a hack because it is one. */ -fn interner_key(+_x: @@ident_interner) { } + * serializer/deserializer. It sounds like a hack because it is one. + * Bonus ultra-hack: functions as keys don't work across crates, + * so we have to use a unique number. See taskgroup_key! in task.rs + * for another case of this. */ +macro_rules! interner_key ( + () => (unsafe::transmute::<(uint, uint), &fn(+@@token::ident_interner)>( + (-3 as uint, 0u))) +) fn mk_ident_interner() -> ident_interner { /* the indices here must correspond to the numbers in special_idents */ @@ -343,8 +349,8 @@ fn mk_ident_interner() -> ident_interner { |x,y| str::eq(*x, *y), init_vec); /* having multiple interners will just confuse the serializer */ - unsafe{ assert task::local_data_get(interner_key) == none }; - unsafe{ task::local_data_set(interner_key, @rv) }; + unsafe{ assert task::local_data_get(interner_key!()) == none }; + unsafe{ task::local_data_set(interner_key!(), @rv) }; rv } diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs index 2bfc0da36f92..6ab1aa78cc09 100644 --- a/src/rustdoc/extract.rs +++ b/src/rustdoc/extract.rs @@ -5,18 +5,24 @@ import doc::item_utils; export from_srv, extract, to_str, interner; + +/* can't import macros yet, so this is copied from token.rs. See its comment + * there. */ +macro_rules! interner_key ( + () => (unsafe::transmute::<(uint, uint), + &fn(+@@syntax::parse::token::ident_interner)>((-3 as uint, 0u))) +) + // Hack; rather than thread an interner through everywhere, rely on // thread-local data fn to_str(id: ast::ident) -> ~str { - let intr = unsafe{ task::local_data_get( - syntax::parse::token::interner_key) }; + let intr = unsafe{ task::local_data_get(interner_key!()) }; return *(*intr.get()).get(id); } fn interner() -> syntax::parse::token::ident_interner { - return *(unsafe{ task::local_data_get( - syntax::parse::token::interner_key) }).get(); + return *(unsafe{ task::local_data_get(interner_key!()) }).get(); } fn from_srv(