diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e0abe8da82b9c..f19afd67faa21 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -37,6 +37,7 @@ use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind}; use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind}; use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::ext::base::{SyntaxExtension, Resolver as SyntaxResolver}; +use syntax::ext::expand::mark_tts; use syntax::ext::hygiene::Mark; use syntax::feature_gate::{self, emit_feature_err}; use syntax::ext::tt::macro_rules; @@ -95,14 +96,14 @@ impl<'b> Resolver<'b> { // Extract and intern the module part of the path. For // globs and lists, the path is found directly in the AST; // for simple paths we have to munge the path a little. - let module_path: Vec = match view_path.node { + let module_path: Vec<_> = match view_path.node { ViewPathSimple(_, ref full_path) => { full_path.segments .split_last() .unwrap() .1 .iter() - .map(|seg| seg.identifier.name) + .map(|seg| seg.identifier) .collect() } @@ -110,7 +111,7 @@ impl<'b> Resolver<'b> { ViewPathList(ref module_ident_path, _) => { module_ident_path.segments .iter() - .map(|seg| seg.identifier.name) + .map(|seg| seg.identifier) .collect() } }; @@ -159,7 +160,7 @@ impl<'b> Resolver<'b> { (module_path.clone(), node.name.name, rename) } else { let name = match module_path.last() { - Some(name) => *name, + Some(ident) => ident.name, None => { resolve_error( self, @@ -207,11 +208,16 @@ impl<'b> Resolver<'b> { }; let mut custom_derive_crate = false; + // The mark of the expansion that generates the loaded macros. + let mut opt_mark = None; for loaded_macro in self.crate_loader.load_macros(item, is_crate_root) { + let mark = opt_mark.unwrap_or_else(Mark::fresh); + opt_mark = Some(mark); match loaded_macro.kind { LoadedMacroKind::Def(mut def) => { if def.use_locally { self.macro_names.insert(def.ident.name); + def.body = mark_tts(&def.body, mark); let ext = macro_rules::compile(&self.session.parse_sess, &def); import_macro(self, def.ident.name, ext, loaded_macro.import_site); } @@ -249,6 +255,17 @@ impl<'b> Resolver<'b> { }); self.define(parent, name, TypeNS, (module, sp, vis)); + if let Some(mark) = opt_mark { + let invocation = self.arenas.alloc_invocation_data(InvocationData { + module: Cell::new(module), + def_index: CRATE_DEF_INDEX, + const_integer: false, + legacy_scope: Cell::new(LegacyScope::Empty), + expansion: Cell::new(LegacyScope::Empty), + }); + self.invocations.insert(mark, invocation); + } + self.populate_module_if_necessary(module); } else if custom_derive_crate { // Define an empty module diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 298f41b971d06..7091d7d2a6321 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -53,9 +53,9 @@ use rustc::ty; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet}; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ast::{self, FloatTy}; -use syntax::ast::{CRATE_NODE_ID, Name, NodeId, IntTy, UintTy}; +use syntax::ast::{CRATE_NODE_ID, Name, NodeId, Ident, IntTy, UintTy}; use syntax::ext::base::SyntaxExtension; use syntax::parse::token::{self, keywords}; use syntax::util::lev_distance::find_best_match_for_name; @@ -509,7 +509,7 @@ struct BindingInfo { } // Map from the name in a pattern to its binding mode. -type BindingMap = FnvHashMap; +type BindingMap = FnvHashMap; #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum PatternSource { @@ -714,7 +714,7 @@ enum ModulePrefixResult<'a> { /// One local scope. #[derive(Debug)] struct Rib<'a> { - bindings: FnvHashMap, + bindings: FnvHashMap, kind: RibKind<'a>, } @@ -1178,18 +1178,18 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { } trait Named { - fn name(&self) -> Name; + fn ident(&self) -> Ident; } impl Named for ast::PathSegment { - fn name(&self) -> Name { - self.identifier.name + fn ident(&self) -> Ident { + self.identifier } } impl Named for hir::PathSegment { - fn name(&self) -> Name { - self.name + fn ident(&self) -> Ident { + Ident::with_empty_ctxt(self.name) } } @@ -1364,7 +1364,7 @@ impl<'a> Resolver<'a> { /// Resolves the given module path from the given root `search_module`. fn resolve_module_path_from_root(&mut self, mut search_module: Module<'a>, - module_path: &[Name], + module_path: &[Ident], index: usize, span: Option) -> ResolveResult> { @@ -1387,7 +1387,7 @@ impl<'a> Resolver<'a> { // upward though scope chains; we simply resolve names directly in // modules as we go. while index < module_path_len { - let name = module_path[index]; + let name = module_path[index].name; match self.resolve_name_in_module(search_module, name, TypeNS, false, span) { Failed(_) => { let segment_name = name.as_str(); @@ -1441,7 +1441,7 @@ impl<'a> Resolver<'a> { /// Attempts to resolve the module part of an import directive or path /// rooted at the given module. fn resolve_module_path(&mut self, - module_path: &[Name], + module_path: &[Ident], use_lexical_scope: UseLexicalScopeFlag, span: Option) -> ResolveResult> { @@ -1479,7 +1479,7 @@ impl<'a> Resolver<'a> { // This is not a crate-relative path. We resolve the // first component of the path in the current lexical // scope and then proceed to resolve below that. - let ident = ast::Ident::with_empty_ctxt(module_path[0]); + let ident = module_path[0]; let lexical_binding = self.resolve_ident_in_lexical_scope(ident, TypeNS, span); if let Some(binding) = lexical_binding.and_then(LexicalScopeBinding::item) { @@ -1525,12 +1525,12 @@ impl<'a> Resolver<'a> { /// Invariant: This must only be called during main resolution, not during /// import resolution. fn resolve_ident_in_lexical_scope(&mut self, - mut ident: ast::Ident, + mut ident: Ident, ns: Namespace, record_used: Option) -> Option> { if ns == TypeNS { - ident = ast::Ident::with_empty_ctxt(ident.name); + ident = Ident::with_empty_ctxt(ident.name); } // Walk backwards up the ribs in scope. @@ -1577,11 +1577,22 @@ impl<'a> Resolver<'a> { /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`; /// (b) some chain of `super::`. /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) * - fn resolve_module_prefix(&mut self, module_path: &[Name], span: Option) + fn resolve_module_prefix(&mut self, module_path: &[Ident], span: Option) -> ResolveResult> { + if &*module_path[0].name.as_str() == "$crate" { + let mut ctxt = module_path[0].ctxt; + while ctxt.source().0 != SyntaxContext::empty() { + ctxt = ctxt.source().0; + } + let module = self.invocations[&ctxt.source().1].module.get(); + let crate_root = + if module.def_id().unwrap().is_local() { self.graph_root } else { module }; + return Success(PrefixFound(crate_root, 1)) + } + // Start at the current module if we see `self` or `super`, or at the // top of the crate otherwise. - let mut i = match &*module_path[0].as_str() { + let mut i = match &*module_path[0].name.as_str() { "self" => 1, "super" => 0, _ => return Success(NoPrefixFound), @@ -1591,7 +1602,7 @@ impl<'a> Resolver<'a> { self.module_map[&self.current_module.normal_ancestor_id.unwrap()]; // Now loop through all the `super`s we find. - while i < module_path.len() && "super" == module_path[i].as_str() { + while i < module_path.len() && "super" == module_path[i].name.as_str() { debug!("(resolving module prefix) resolving `super` at {}", module_to_string(&containing_module)); if let Some(parent) = containing_module.parent { @@ -1649,7 +1660,7 @@ impl<'a> Resolver<'a> { /// Searches the current set of local scopes for labels. /// Stops after meeting a closure. - fn search_label(&self, mut ident: ast::Ident) -> Option { + fn search_label(&self, mut ident: Ident) -> Option { for rib in self.label_ribs.iter().rev() { match rib.kind { NormalRibKind => { @@ -1813,7 +1824,7 @@ impl<'a> Resolver<'a> { // plain insert (no renaming) let def_id = self.definitions.local_def_id(type_parameter.id); let def = Def::TyParam(def_id); - function_type_rib.bindings.insert(ast::Ident::with_empty_ctxt(name), def); + function_type_rib.bindings.insert(Ident::with_empty_ctxt(name), def); self.record_def(type_parameter.id, PathResolution::new(def)); } self.type_ribs.push(function_type_rib); @@ -2271,7 +2282,7 @@ impl<'a> Resolver<'a> { pat_id: NodeId, outer_pat_id: NodeId, pat_src: PatternSource, - bindings: &mut FnvHashMap) + bindings: &mut FnvHashMap) -> PathResolution { // Add the binding to the local ribs, if it // doesn't already exist in the bindings map. (We @@ -2372,7 +2383,7 @@ impl<'a> Resolver<'a> { pat_src: PatternSource, // Maps idents to the node ID for the // outermost pattern that binds them. - bindings: &mut FnvHashMap) { + bindings: &mut FnvHashMap) { // Visit all direct subpatterns of this pattern. let outer_pat_id = pat.id; pat.walk(&mut |pat| { @@ -2573,7 +2584,7 @@ impl<'a> Resolver<'a> { // Resolve a single identifier fn resolve_identifier(&mut self, - identifier: ast::Ident, + identifier: Ident, namespace: Namespace, record_used: Option) -> Option { @@ -2681,12 +2692,8 @@ impl<'a> Resolver<'a> { namespace: Namespace) -> Result<&'a NameBinding<'a>, bool /* true if an error was reported */> { - let module_path = segments.split_last() - .unwrap() - .1 - .iter() - .map(|ps| ps.identifier.name) - .collect::>(); + let module_path = + segments.split_last().unwrap().1.iter().map(|ps| ps.identifier).collect::>(); let containing_module; match self.resolve_module_path(&module_path, UseLexicalScope, Some(span)) { @@ -2715,7 +2722,7 @@ impl<'a> Resolver<'a> { bool /* true if an error was reported */> where T: Named, { - let module_path = segments.split_last().unwrap().1.iter().map(T::name).collect::>(); + let module_path = segments.split_last().unwrap().1.iter().map(T::ident).collect::>(); let root_module = self.graph_root; let containing_module; @@ -2734,7 +2741,7 @@ impl<'a> Resolver<'a> { } } - let name = segments.last().unwrap().name(); + let name = segments.last().unwrap().ident().name; let result = self.resolve_name_in_module(containing_module, name, namespace, false, Some(span)); result.success().ok_or(false) @@ -2835,7 +2842,7 @@ impl<'a> Resolver<'a> { } SuggestionType::NotFound } - fn resolve_labeled_block(&mut self, label: Option, id: NodeId, block: &Block) { + fn resolve_labeled_block(&mut self, label: Option, id: NodeId, block: &Block) { if let Some(label) = label { let def = Def::Label(id); self.with_label_rib(|this| { @@ -2976,9 +2983,8 @@ impl<'a> Resolver<'a> { msg = format!("did you mean {}?", msg); } else { // we display a help message if this is a module - let name_path = path.segments.iter() - .map(|seg| seg.identifier.name) - .collect::>(); + let name_path: Vec<_> = + path.segments.iter().map(|seg| seg.identifier).collect(); match self.resolve_module_path(&name_path[..], UseLexicalScope, @@ -3237,7 +3243,7 @@ impl<'a> Resolver<'a> { if name == lookup_name && ns == namespace { if filter_fn(name_binding.def()) { // create the path - let ident = ast::Ident::with_empty_ctxt(name); + let ident = Ident::with_empty_ctxt(name); let params = PathParameters::none(); let segment = PathSegment { identifier: ident, @@ -3271,7 +3277,7 @@ impl<'a> Resolver<'a> { _ if module.parent.is_none() => path_segments.clone(), ModuleKind::Def(_, name) => { let mut paths = path_segments.clone(); - let ident = ast::Ident::with_empty_ctxt(name); + let ident = Ident::with_empty_ctxt(name); let params = PathParameters::none(); let segm = PathSegment { identifier: ident, @@ -3317,7 +3323,7 @@ impl<'a> Resolver<'a> { } }; - let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect(); + let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier).collect(); let mut path_resolution = err_path_resolution(); let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, Some(path.span)) { Success(module) => { @@ -3469,26 +3475,24 @@ impl<'a> Resolver<'a> { } } -fn names_to_string(names: &[Name]) -> String { +fn names_to_string(names: &[Ident]) -> String { let mut first = true; let mut result = String::new(); - for name in names { + for ident in names { if first { first = false } else { result.push_str("::") } - result.push_str(&name.as_str()); + result.push_str(&ident.name.as_str()); } result } fn path_names_to_string(path: &Path, depth: usize) -> String { - let names: Vec = path.segments[..path.segments.len() - depth] - .iter() - .map(|seg| seg.identifier.name) - .collect(); - names_to_string(&names[..]) + let names: Vec<_> = + path.segments[..path.segments.len() - depth].iter().map(|seg| seg.identifier).collect(); + names_to_string(&names) } /// When an entity with a given name is not available in scope, we search for @@ -3551,15 +3555,15 @@ fn show_candidates(session: &mut DiagnosticBuilder, fn module_to_string(module: Module) -> String { let mut names = Vec::new(); - fn collect_mod(names: &mut Vec, module: Module) { + fn collect_mod(names: &mut Vec, module: Module) { if let ModuleKind::Def(_, name) = module.kind { if let Some(parent) = module.parent { - names.push(name); + names.push(Ident::with_empty_ctxt(name)); collect_mod(names, parent); } } else { // danger, shouldn't be ident? - names.push(token::intern("")); + names.push(token::str_to_ident("")); collect_mod(names, module.parent.unwrap()); } } @@ -3568,7 +3572,7 @@ fn module_to_string(module: Module) -> String { if names.is_empty() { return "???".to_string(); } - names_to_string(&names.into_iter().rev().collect::>()) + names_to_string(&names.into_iter().rev().collect::>()) } fn err_path_resolution() -> PathResolution { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index cf5ea236b3ec7..0f42b4520c9b7 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -29,10 +29,10 @@ use syntax_pos::Span; #[derive(Clone)] pub struct InvocationData<'a> { pub module: Cell>, - def_index: DefIndex, + pub def_index: DefIndex, // True if this expansion is in a `const_integer` position, for example `[u32; m!()]`. // c.f. `DefCollector::visit_ast_const_integer`. - const_integer: bool, + pub const_integer: bool, // The scope in which the invocation path is resolved. pub legacy_scope: Cell>, // The smallest scope that includes this invocation's expansion, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 0939e6f1644de..2b3945bd0d920 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -24,7 +24,7 @@ use rustc::ty; use rustc::lint::builtin::PRIVATE_IN_PUBLIC; use rustc::hir::def::*; -use syntax::ast::{NodeId, Name}; +use syntax::ast::{Ident, NodeId, Name}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::Span; @@ -69,7 +69,7 @@ impl<'a> ImportDirectiveSubclass<'a> { pub struct ImportDirective<'a> { pub id: NodeId, parent: Module<'a>, - module_path: Vec, + module_path: Vec, imported_module: Cell>>, // the resolution of `module_path` subclass: ImportDirectiveSubclass<'a>, span: Span, @@ -252,7 +252,7 @@ impl<'a> Resolver<'a> { // Add an import directive to the current module. pub fn add_import_directive(&mut self, - module_path: Vec, + module_path: Vec, subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, @@ -816,7 +816,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } -fn import_path_to_string(names: &[Name], subclass: &ImportDirectiveSubclass) -> String { +fn import_path_to_string(names: &[Ident], subclass: &ImportDirectiveSubclass) -> String { if names.is_empty() { import_directive_subclass_to_string(subclass) } else { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index d1fe7853445f2..bd47b1e7c121c 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -295,7 +295,9 @@ impl<'a> Classifier<'a> { "Option" | "Result" => Class::PreludeTy, "Some" | "None" | "Ok" | "Err" => Class::PreludeVal, + "$crate" => Class::KeyWord, _ if tas.tok.is_any_keyword() => Class::KeyWord, + _ => { if self.in_macro_nonterminal { self.in_macro_nonterminal = false; @@ -310,9 +312,6 @@ impl<'a> Classifier<'a> { } } - // Special macro vars are like keywords. - token::SpecialVarNt(_) => Class::KeyWord, - token::Lifetime(..) => Class::Lifetime, token::Underscore | token::Eof | token::Interpolated(..) | diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6aeb46fd52276..e84a9208029a5 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -939,6 +939,6 @@ impl Folder for Marker { } // apply a given mark to the given token trees. Used prior to expansion of a macro. -fn mark_tts(tts: &[TokenTree], m: Mark) -> Vec { +pub fn mark_tts(tts: &[TokenTree], m: Mark) -> Vec { noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None}) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a74d335d6046d..5496d27c08740 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -58,7 +58,6 @@ impl<'a> ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: ast::Ident, - imported_from: Option, lhses: Vec, rhses: Vec, valid: bool, @@ -76,7 +75,6 @@ impl TTMacroExpander for MacroRulesMacroExpander { generic_extension(cx, sp, self.name, - self.imported_from, arg, &self.lhses, &self.rhses) @@ -87,7 +85,6 @@ impl TTMacroExpander for MacroRulesMacroExpander { fn generic_extension<'cx>(cx: &'cx ExtCtxt, sp: Span, name: ast::Ident, - imported_from: Option, arg: &[TokenTree], lhses: &[TokenTree], rhses: &[TokenTree]) @@ -116,10 +113,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, _ => cx.span_bug(sp, "malformed macro rhs"), }; // rhs has holes ( `$id` and `$(...)` that need filled) - let trncbr = new_tt_reader(&cx.parse_sess.span_diagnostic, - Some(named_matches), - imported_from, - rhs); + let trncbr = + new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs); let mut p = Parser::new(cx.parse_sess(), cx.cfg().clone(), Box::new(trncbr)); p.directory = cx.current_expansion.module.directory.clone(); p.restrictions = match cx.current_expansion.no_noninline_mod { @@ -223,7 +218,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension { ]; // Parse the macro_rules! invocation (`none` is for no interpolations): - let arg_reader = new_tt_reader(&sess.span_diagnostic, None, None, def.body.clone()); + let arg_reader = new_tt_reader(&sess.span_diagnostic, None, def.body.clone()); let argument_map = match parse(sess, &Vec::new(), arg_reader, &argument_gram) { Success(m) => m, @@ -269,7 +264,6 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension { let exp: Box<_> = Box::new(MacroRulesMacroExpander { name: def.ident, - imported_from: def.imported_from, lhses: lhses, rhses: rhses, valid: valid, diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 205c709d6cb40..38a926b6e87c9 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -14,7 +14,7 @@ use syntax_pos::{Span, DUMMY_SP}; use errors::{Handler, DiagnosticBuilder}; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use parse::token::{DocComment, MatchNt, SubstNt}; -use parse::token::{Token, Interpolated, NtIdent, NtTT, SpecialMacroVar}; +use parse::token::{Token, Interpolated, NtIdent, NtTT}; use parse::token; use parse::lexer::TokenAndSpan; use tokenstream::{self, TokenTree}; @@ -39,10 +39,7 @@ pub struct TtReader<'a> { stack: Vec, /* for MBE-style macro transcription */ interpolations: HashMap>, - imported_from: Option, - // Some => return imported_from as the next token - crate_name_next: Option, repeat_idx: Vec, repeat_len: Vec, /* cached: */ @@ -59,10 +56,9 @@ pub struct TtReader<'a> { /// (and should) be None. pub fn new_tt_reader(sp_diag: &Handler, interp: Option>>, - imported_from: Option, src: Vec) -> TtReader { - new_tt_reader_with_doc_flag(sp_diag, interp, imported_from, src, false) + new_tt_reader_with_doc_flag(sp_diag, interp, src, false) } /// The extra `desugar_doc_comments` flag enables reading doc comments @@ -73,7 +69,6 @@ pub fn new_tt_reader(sp_diag: &Handler, /// (and should) be None. pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler, interp: Option>>, - imported_from: Option, src: Vec, desugar_doc_comments: bool) -> TtReader { @@ -93,8 +88,6 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler, None => HashMap::new(), Some(x) => x, }, - imported_from: imported_from, - crate_name_next: None, repeat_idx: Vec::new(), repeat_len: Vec::new(), desugar_doc_comments: desugar_doc_comments, @@ -189,14 +182,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { sp: r.cur_span.clone(), }; loop { - match r.crate_name_next.take() { - None => (), - Some(sp) => { - r.cur_span = sp; - r.cur_tok = token::Ident(r.imported_from.unwrap()); - return ret_val; - }, - } let should_pop = match r.stack.last() { None => { assert_eq!(ret_val.tok, token::Eof); @@ -346,18 +331,6 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { sep: None }); } - TokenTree::Token(sp, token::SpecialVarNt(SpecialMacroVar::CrateMacroVar)) => { - r.stack.last_mut().unwrap().idx += 1; - - if r.imported_from.is_some() { - r.cur_span = sp; - r.cur_tok = token::ModSep; - r.crate_name_next = Some(sp); - return ret_val; - } - - // otherwise emit nothing and proceed to the next token - } TokenTree::Token(sp, tok) => { r.cur_span = sp; r.cur_tok = tok; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 1e286c143de9b..1a84a750463c8 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -276,7 +276,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc) pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec, cfg: ast::CrateConfig) -> Parser<'a> { - let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts); + let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts); let mut p = Parser::new(sess, cfg, Box::new(trdr)); p.check_unknown_macro_variable(); p diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 61268d457ce44..eac78f5e6c68c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -48,8 +48,7 @@ use parse::classify; use parse::common::SeqSep; use parse::lexer::{Reader, TokenAndSpan}; use parse::obsolete::ObsoleteSyntax; -use parse::token::{self, intern, MatchNt, SubstNt, SpecialVarNt, InternedString}; -use parse::token::{keywords, SpecialMacroVar}; +use parse::token::{self, intern, keywords, MatchNt, SubstNt, InternedString}; use parse::{new_sub_parser_from_file, ParseSess}; use util::parser::{AssocOp, Fixity}; use print::pprust; @@ -2653,8 +2652,12 @@ impl<'a> Parser<'a> { num_captures: name_num }))); } else if self.token.is_keyword(keywords::Crate) { + let ident = match self.token { + token::Ident(id) => ast::Ident { name: token::intern("$crate"), ..id }, + _ => unreachable!(), + }; self.bump(); - return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))); + return Ok(TokenTree::Token(sp, token::Ident(ident))); } else { sp = mk_sp(sp.lo, self.span.hi); self.parse_ident().unwrap_or_else(|mut e| { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3d4dd9ec06457..26b5b99c8cce6 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -52,21 +52,6 @@ pub enum DelimToken { NoDelim, } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] -pub enum SpecialMacroVar { - /// `$crate` will be filled in with the name of the crate a macro was - /// imported from, if any. - CrateMacroVar, -} - -impl SpecialMacroVar { - pub fn as_str(self) -> &'static str { - match self { - SpecialMacroVar::CrateMacroVar => "crate", - } - } -} - #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] pub enum Lit { Byte(ast::Name), @@ -148,8 +133,6 @@ pub enum Token { // In right-hand-sides of MBE macros: /// A syntactic variable that will be filled in by macro expansion. SubstNt(ast::Ident), - /// A macro variable with special meaning. - SpecialVarNt(SpecialMacroVar), // Junk. These carry no data because we don't really care about the data // they *would* carry, and don't really want to allocate a new ident for diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 89834da28219c..c6f63d772426a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -285,8 +285,6 @@ pub fn token_to_string(tok: &Token) -> String { token::Comment => "/* */".to_string(), token::Shebang(s) => format!("/* shebang: {}*/", s), - token::SpecialVarNt(var) => format!("${}", var.as_str()), - token::Interpolated(ref nt) => match *nt { token::NtExpr(ref e) => expr_to_string(&e), token::NtMeta(ref e) => meta_item_to_string(&e), diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index b35b4617ea11e..f22f920a7fa0e 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -134,7 +134,6 @@ impl TokenTree { AttrStyle::Inner => 3, } } - TokenTree::Token(_, token::SpecialVarNt(..)) => 2, TokenTree::Token(_, token::MatchNt(..)) => 3, TokenTree::Token(_, token::Interpolated(Nonterminal::NtTT(..))) => 1, TokenTree::Delimited(_, ref delimed) => delimed.tts.len() + 2, @@ -188,11 +187,6 @@ impl TokenTree { } delimed.tts[index - 1].clone() } - (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => { - let v = [TokenTree::Token(sp, token::Dollar), - TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str())))]; - v[index].clone() - } (&TokenTree::Token(sp, token::MatchNt(name, kind)), _) => { let v = [TokenTree::Token(sp, token::SubstNt(name)), TokenTree::Token(sp, token::Colon), @@ -223,7 +217,6 @@ impl TokenTree { -> macro_parser::NamedParseResult { // `None` is because we're not interpolating let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic, - None, None, tts.iter().cloned().collect(), true); diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 6ce534d52b883..40ff4852e3856 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -38,7 +38,7 @@ - ((::std::fmt::format as + (($crate::fmt::format as fn(std::fmt::Arguments<'_>) -> std::string::String {std::fmt::format})(((::std::fmt::Arguments::new_v1 as fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})(({