diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2019-08-11 11:48:22 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2019-08-17 08:59:36 +0100 |
| commit | 497b50206229c28b89150960e2193964d02e8ef6 (patch) | |
| tree | 2c57e70e69ec558c081a5a90593ee2d3d480f932 | |
| parent | 211d1e073527915f7ce1854ad8b30dc0c45845e8 (diff) | |
| download | rust-497b50206229c28b89150960e2193964d02e8ef6.tar.gz rust-497b50206229c28b89150960e2193964d02e8ef6.zip | |
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.
| -rw-r--r-- | src/librustc_metadata/decoder.rs | 16 | ||||
| -rw-r--r-- | src/librustc_metadata/encoder.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax_pos/hygiene.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax_pos/symbol.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/hygiene/auxiliary/codegen-attrs.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/hygiene/cross-crate-codegen-attrs.rs | 12 |
6 files changed, 59 insertions, 32 deletions
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0bec31d7076..4365b1bee58 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -348,6 +348,22 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> { } } +impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> { + fn specialized_decode(&mut self) -> Result<Ident, Self::Error> { + // FIXME(jseyfried): intercrate hygiene + + Ok(Ident::with_dummy_span(Symbol::decode(self)?)) + } +} + +impl SpecializedDecoder<SyntaxContext> for DecodeContext<'_, '_> { + fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> { + // FIXME(jseyfried): intercrate hygiene + + Ok(SyntaxContext::empty()) + } +} + impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> { Fingerprint::decode_opaque(&mut self.opaque) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index fb675d7d841..34ccdad8636 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -31,8 +31,9 @@ use std::u32; use syntax::ast; use syntax::attr; use syntax::source_map::Spanned; -use syntax::symbol::{kw, sym}; +use syntax::symbol::{kw, sym, Ident}; use syntax_pos::{self, FileName, SourceFile, Span}; +use syntax_pos::hygiene::SyntaxContext; use log::{debug, trace}; use rustc::hir::{self, PatKind}; @@ -173,6 +174,20 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> { } } +impl SpecializedEncoder<Ident> for EncodeContext<'tcx> { + fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> { + // FIXME(jseyfried): intercrate hygiene + ident.name.encode(self) + } +} + +impl SpecializedEncoder<SyntaxContext> for EncodeContext<'tcx> { + fn specialized_encode(&mut self, _ctxt: &SyntaxContext) -> Result<(), Self::Error> { + // FIXME(jseyfried): intercrate hygiene + Ok(()) + } +} + impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> { #[inline] fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> { diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 87d930f897a..1e40994e77b 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -751,14 +751,6 @@ impl Decodable for ExpnId { } } -impl Encodable for SyntaxContext { - fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> { - Ok(()) // FIXME(jseyfried) intercrate hygiene - } -} +impl UseSpecializedEncodable for SyntaxContext {} -impl Decodable for SyntaxContext { - fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> { - Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene - } -} +impl UseSpecializedDecodable for SyntaxContext {} diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 27fc66d3b09..bed898f10b4 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -8,6 +8,7 @@ use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::newtype_index; use rustc_macros::symbols; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; use std::fmt; @@ -847,28 +848,9 @@ impl fmt::Display for Ident { } } -impl Encodable for Ident { - fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { - if !self.span.modern().from_expansion() { - s.emit_str(&self.as_str()) - } else { // FIXME(jseyfried): intercrate hygiene - let mut string = "#".to_owned(); - string.push_str(&self.as_str()); - s.emit_str(&string) - } - } -} +impl UseSpecializedEncodable for Ident {} -impl Decodable for Ident { - fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> { - let string = d.read_str()?; - Ok(if !string.starts_with('#') { - Ident::from_str(&string) - } else { // FIXME(jseyfried): intercrate hygiene - Ident::from_str(&string[1..]).gensym() - }) - } -} +impl UseSpecializedDecodable for Ident {} /// A symbol is an interned or gensymed string. A gensym is a symbol that is /// never equal to any other symbol. diff --git a/src/test/ui/hygiene/auxiliary/codegen-attrs.rs b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs new file mode 100644 index 00000000000..74afedbeb77 --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs @@ -0,0 +1,10 @@ +#![feature(decl_macro)] + +macro m($f:ident) { + #[export_name = "export_function_name"] + pub fn $f() -> i32 { + 2 + } +} + +m!(rust_function_name); diff --git a/src/test/ui/hygiene/cross-crate-codegen-attrs.rs b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs new file mode 100644 index 00000000000..af6b1334387 --- /dev/null +++ b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs @@ -0,0 +1,12 @@ +// Make sure that macro expanded codegen attributes work across crates. +// We used to gensym the identifiers in attributes, which stopped dependent +// crates from seeing them, resulting in linker errors in cases like this one. + +// run-pass +// aux-build:codegen-attrs.rs + +extern crate codegen_attrs; + +fn main() { + assert_eq!(codegen_attrs::rust_function_name(), 2); +} |
