From: Nicholas Nethercote Date: Fri, 17 May 2019 00:44:51 +0000 (+1000) Subject: Remove `Symbol::gensym()`. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=88d29992bdd3d881b336b724675c59323e70e2e7;p=rust.git Remove `Symbol::gensym()`. --- diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 585c6fde634..6931b3542f7 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -140,7 +140,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { // Generate the submodule itself let name = f.kind.fn_name("allocator_abi"); - let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name)); + let allocator_abi = Ident::from_str(&name).gensym(); let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items); let module = f.cx.monotonic_expander().flat_map_item(module).pop().unwrap(); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f70ca6f859b..3b58a99d19f 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -314,7 +314,7 @@ fn build_reduced_graph_for_use_tree( Ident::new(keywords::SelfLower.name(), new_span) ), kind: ast::UseTreeKind::Simple( - Some(Ident::new(Name::gensym("__dummy"), new_span)), + Some(Ident::from_str_and_span("__dummy", new_span).gensym()), ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID, ), diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 21024eb41ef..c988dc61bec 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -7,7 +7,7 @@ use crate::ext::build::AstBuilder; use crate::parse::token; use crate::ptr::P; -use crate::symbol::{keywords, Symbol}; +use crate::symbol::keywords; use crate::tokenstream::{TokenTree}; use smallvec::smallvec; @@ -121,13 +121,13 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>, let span = span.apply_mark(ecx.current_expansion.mark); - let sym = Ident::new(Symbol::gensym(&format!("__register_diagnostic_{}", code)), span); + let name = Ident::from_str_and_span(&format!("__register_diagnostic_{}", code), span).gensym(); MacEager::items(smallvec![ ecx.item_mod( span, span, - sym, + name, vec![], vec![], ) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 06651750de7..672b7b42855 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -252,8 +252,8 @@ pub fn compile( def: &ast::Item, edition: Edition ) -> SyntaxExtension { - let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs")); - let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs")); + let lhs_nm = ast::Ident::from_str("lhs").gensym(); + let rhs_nm = ast::Ident::from_str("rhs").gensym(); // Parse the macro_rules! invocation let body = match def.node { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index fe8c9f03a2c..1be7986ad53 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -2,7 +2,7 @@ use crate::attr; use crate::edition::Edition; use crate::ext::hygiene::{Mark, SyntaxContext}; -use crate::symbol::{Symbol, keywords, sym}; +use crate::symbol::{Ident, Symbol, keywords, sym}; use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan}; use crate::ptr::P; use crate::tokenstream::TokenStream; @@ -66,10 +66,12 @@ pub fn maybe_inject_crates_ref( for orig_name_str in names.iter().rev() { // HACK(eddyb) gensym the injected crates on the Rust 2018 edition, // so they don't accidentally interfere with the new import paths. + let orig_name_sym = Symbol::intern(orig_name_str); + let orig_name_ident = Ident::with_empty_ctxt(orig_name_sym); let (rename, orig_name) = if rust_2018 { - (Symbol::gensym(orig_name_str), Some(Symbol::intern(orig_name_str))) + (orig_name_ident.gensym(), Some(orig_name_sym)) } else { - (Symbol::intern(orig_name_str), None) + (orig_name_ident, None) }; krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer( @@ -79,7 +81,7 @@ pub fn maybe_inject_crates_ref( )], vis: dummy_spanned(ast::VisibilityKind::Inherited), node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)), - ident: ast::Ident::with_empty_ctxt(rename), + ident: rename, id: ast::DUMMY_NODE_ID, span: DUMMY_SP, tokens: None, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 3fd0790161c..3dc7aad9459 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -232,11 +232,11 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>, items, }; - let sym = Ident::with_empty_ctxt(Symbol::gensym("__test_reexports")); + let name = Ident::from_str("__test_reexports").gensym(); let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent }; cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent); let it = cx.ext_cx.monotonic_expander().flat_map_item(P(ast::Item { - ident: sym, + ident: name, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemKind::Mod(reexport_mod), @@ -245,7 +245,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>, tokens: None, })).pop().unwrap(); - (it, sym) + (it, name) } /// Crawl over the crate, inserting test reexports and the test main function @@ -373,9 +373,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { main_body); // Honor the reexport_test_harness_main attribute - let main_id = Ident::new( - cx.reexport_test_harness_main.unwrap_or(Symbol::gensym("main")), - sp); + let main_id = match cx.reexport_test_harness_main { + Some(sym) => Ident::new(sym, sp), + None => Ident::from_str_and_span("main", sp).gensym(), + }; P(ast::Item { ident: main_id, diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index c582fb422c9..200445d1248 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -429,7 +429,7 @@ fn mk_decls( let module = cx.item_mod( span, span, - ast::Ident::with_empty_ctxt(Symbol::gensym("decls")), + ast::Ident::from_str("decls").gensym(), vec![doc_hidden], vec![krate, decls_static], ).map(|mut i| { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 2bf3b1fa465..fb99be0fe33 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -630,10 +630,12 @@ pub struct Ident { impl Ident { #[inline] + /// Constructs a new identifier from a symbol and a span. pub const fn new(name: Symbol, span: Span) -> Ident { Ident { name, span } } + /// Constructs a new identifier with an empty syntax context. #[inline] pub const fn with_empty_ctxt(name: Symbol) -> Ident { Ident::new(name, DUMMY_SP) @@ -644,11 +646,16 @@ pub fn from_interned_str(string: InternedString) -> Ident { Ident::with_empty_ctxt(string.as_symbol()) } - /// Maps a string to an identifier with an empty syntax context. + /// Maps a string to an identifier with an empty span. pub fn from_str(string: &str) -> Ident { Ident::with_empty_ctxt(Symbol::intern(string)) } + /// Maps a string and a span to an identifier. + pub fn from_str_and_span(string: &str, span: Span) -> Ident { + Ident::new(Symbol::intern(string), span) + } + /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context. pub fn with_span_pos(self, span: Span) -> Ident { Ident::new(self.name, span.with_ctxt(self.span.ctxt())) @@ -676,11 +683,14 @@ pub fn modern_and_legacy(self) -> Ident { Ident::new(self.name, self.span.modern_and_legacy()) } + /// Transforms an identifier into one with the same name, but gensymed. pub fn gensym(self) -> Ident { let name = with_interner(|interner| interner.gensymed(self.name)); Ident::new(name, self.span) } + /// Transforms an underscore identifier into one with the same name, but + /// gensymed. Leaves non-underscore identifiers unchanged. pub fn gensym_if_underscore(self) -> Ident { if self.name == keywords::Underscore.name() { self.gensym() } else { self } } @@ -742,30 +752,34 @@ fn decode(d: &mut D) -> Result { Ok(if !string.starts_with('#') { Ident::from_str(&string) } else { // FIXME(jseyfried): intercrate hygiene - Ident::with_empty_ctxt(Symbol::gensym(&string[1..])) + Ident::from_str(&string[1..]).gensym() }) } } /// A symbol is an interned or gensymed string. A gensym is a symbol that is -/// never equal to any other symbol. E.g.: -/// ``` -/// assert_eq!(Symbol::intern("x"), Symbol::intern("x")) -/// assert_ne!(Symbol::gensym("x"), Symbol::intern("x")) -/// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x")) -/// ``` +/// never equal to any other symbol. +/// /// Conceptually, a gensym can be thought of as a normal symbol with an /// invisible unique suffix. Gensyms are useful when creating new identifiers /// that must not match any existing identifiers, e.g. during macro expansion -/// and syntax desugaring. +/// and syntax desugaring. Because gensyms should always be identifiers, all +/// gensym operations are on `Ident` rather than `Symbol`. (Indeed, in the +/// future the gensym-ness may be moved from `Symbol` to hygiene data.) /// -/// Internally, a Symbol is implemented as an index, and all operations +/// Examples: +/// ``` +/// assert_eq!(Ident::from_str("x"), Ident::from_str("x")) +/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x")) +/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x").gensym()) +/// ``` +/// Internally, a symbol is implemented as an index, and all operations /// (including hashing, equality, and ordering) operate on that index. The use /// of `newtype_index!` means that `Option` only takes up 4 bytes, /// because `newtype_index!` reserves the last 256 values for tagging purposes. /// -/// Note that `Symbol` cannot directly be a `newtype_index!` because it implements -/// `fmt::Debug`, `Encodable`, and `Decodable` in special ways. +/// Note that `Symbol` cannot directly be a `newtype_index!` because it +/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(SymbolIndex); @@ -783,11 +797,6 @@ pub fn intern(string: &str) -> Self { with_interner(|interner| interner.intern(string)) } - /// Gensyms a new `usize`, using the current interner. - pub fn gensym(string: &str) -> Self { - with_interner(|interner| interner.gensym(string)) - } - pub fn as_str(self) -> LocalInternedString { with_interner(|interner| unsafe { LocalInternedString { @@ -895,11 +904,6 @@ fn interned(&self, symbol: Symbol) -> Symbol { } } - fn gensym(&mut self, string: &str) -> Symbol { - let symbol = self.intern(string); - self.gensymed(symbol) - } - fn gensymed(&mut self, symbol: Symbol) -> Symbol { self.gensyms.push(symbol); Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1) @@ -1267,11 +1271,13 @@ fn interner_tests() { assert_eq!(i.intern("cat"), Symbol::new(1)); // dog is still at zero assert_eq!(i.intern("dog"), Symbol::new(0)); - assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32)); + let z = i.intern("zebra"); + assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32)); // gensym of same string gets new number: - assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32 - 1)); + assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32 - 1)); // gensym of *existing* string gets new number: - assert_eq!(i.gensym("dog"), Symbol::new(SymbolIndex::MAX_AS_U32 - 2)); + let d = i.intern("dog"); + assert_eq!(i.gensymed(d), Symbol::new(SymbolIndex::MAX_AS_U32 - 2)); } #[test]