Skip to content

Commit 497b502

Browse files
committed
Stop emulating cross-crate hygiene with gensyms
Most `Ident`s are serialized as `InternedString`s the exceptions are: * Reexports * Attributes * Idents in macro definitions Using gensyms helped reexports emulate hygiene. However, the actual item wouldn't have a gensymmed name so would be usable cross-crate. So removing this case until we have proper cross-crate hygiene seems sensible. Codegen attributes (`inline`, `export_name`) are resolved by their `Symbol`. This meant that opaque macro-expanded codegen attributes could cause linker errors. This prevented making built-in derives hygienic.
1 parent 211d1e0 commit 497b502

File tree

6 files changed

+59
-32
lines changed

6 files changed

+59
-32
lines changed

src/librustc_metadata/decoder.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,22 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
348348
}
349349
}
350350

351+
impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
352+
fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
353+
// FIXME(jseyfried): intercrate hygiene
354+
355+
Ok(Ident::with_dummy_span(Symbol::decode(self)?))
356+
}
357+
}
358+
359+
impl SpecializedDecoder<SyntaxContext> for DecodeContext<'_, '_> {
360+
fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> {
361+
// FIXME(jseyfried): intercrate hygiene
362+
363+
Ok(SyntaxContext::empty())
364+
}
365+
}
366+
351367
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
352368
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
353369
Fingerprint::decode_opaque(&mut self.opaque)

src/librustc_metadata/encoder.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ use std::u32;
3131
use syntax::ast;
3232
use syntax::attr;
3333
use syntax::source_map::Spanned;
34-
use syntax::symbol::{kw, sym};
34+
use syntax::symbol::{kw, sym, Ident};
3535
use syntax_pos::{self, FileName, SourceFile, Span};
36+
use syntax_pos::hygiene::SyntaxContext;
3637
use log::{debug, trace};
3738

3839
use rustc::hir::{self, PatKind};
@@ -173,6 +174,20 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
173174
}
174175
}
175176

177+
impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
178+
fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
179+
// FIXME(jseyfried): intercrate hygiene
180+
ident.name.encode(self)
181+
}
182+
}
183+
184+
impl SpecializedEncoder<SyntaxContext> for EncodeContext<'tcx> {
185+
fn specialized_encode(&mut self, _ctxt: &SyntaxContext) -> Result<(), Self::Error> {
186+
// FIXME(jseyfried): intercrate hygiene
187+
Ok(())
188+
}
189+
}
190+
176191
impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
177192
#[inline]
178193
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {

src/libsyntax_pos/hygiene.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -751,14 +751,6 @@ impl Decodable for ExpnId {
751751
}
752752
}
753753

754-
impl Encodable for SyntaxContext {
755-
fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
756-
Ok(()) // FIXME(jseyfried) intercrate hygiene
757-
}
758-
}
754+
impl UseSpecializedEncodable for SyntaxContext {}
759755

760-
impl Decodable for SyntaxContext {
761-
fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
762-
Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
763-
}
764-
}
756+
impl UseSpecializedDecodable for SyntaxContext {}

src/libsyntax_pos/symbol.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_data_structures::indexed_vec::Idx;
88
use rustc_data_structures::newtype_index;
99
use rustc_macros::symbols;
1010
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
11+
use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
1112

1213
use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
1314
use std::fmt;
@@ -847,28 +848,9 @@ impl fmt::Display for Ident {
847848
}
848849
}
849850

850-
impl Encodable for Ident {
851-
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
852-
if !self.span.modern().from_expansion() {
853-
s.emit_str(&self.as_str())
854-
} else { // FIXME(jseyfried): intercrate hygiene
855-
let mut string = "#".to_owned();
856-
string.push_str(&self.as_str());
857-
s.emit_str(&string)
858-
}
859-
}
860-
}
851+
impl UseSpecializedEncodable for Ident {}
861852

862-
impl Decodable for Ident {
863-
fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
864-
let string = d.read_str()?;
865-
Ok(if !string.starts_with('#') {
866-
Ident::from_str(&string)
867-
} else { // FIXME(jseyfried): intercrate hygiene
868-
Ident::from_str(&string[1..]).gensym()
869-
})
870-
}
871-
}
853+
impl UseSpecializedDecodable for Ident {}
872854

873855
/// A symbol is an interned or gensymed string. A gensym is a symbol that is
874856
/// never equal to any other symbol.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(decl_macro)]
2+
3+
macro m($f:ident) {
4+
#[export_name = "export_function_name"]
5+
pub fn $f() -> i32 {
6+
2
7+
}
8+
}
9+
10+
m!(rust_function_name);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Make sure that macro expanded codegen attributes work across crates.
2+
// We used to gensym the identifiers in attributes, which stopped dependent
3+
// crates from seeing them, resulting in linker errors in cases like this one.
4+
5+
// run-pass
6+
// aux-build:codegen-attrs.rs
7+
8+
extern crate codegen_attrs;
9+
10+
fn main() {
11+
assert_eq!(codegen_attrs::rust_function_name(), 2);
12+
}

0 commit comments

Comments
 (0)