From 48635226d8d71f18b09ea40f5cdbe34dbaaf378f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 18 Jun 2019 22:23:13 +0300 Subject: Remove `MacroKind::ProcMacroStub` It's internal to resolve and always results in `Res::Err` outside of resolve. Instead put `DefKind::Fn`s themselves into the macro namespace, it's ok. Proc macro stubs are items placed into macro namespase for functions that define proc macros. https://github.com/rust-lang/rust/pull/52383 The rustdoc test is changed because the old test didn't actually reproduce the ICE it was supposed to reproduce. --- src/libsyntax/ext/base.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index c0ba41b8af4..8d5e4a3369e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -527,8 +527,6 @@ pub enum MacroKind { Attr, /// A derive attribute macro - #[derive(Foo)] Derive, - /// A view of a procedural macro from the same crate that defines it. - ProcMacroStub, } impl MacroKind { @@ -537,7 +535,6 @@ impl MacroKind { MacroKind::Bang => "macro", MacroKind::Attr => "attribute macro", MacroKind::Derive => "derive macro", - MacroKind::ProcMacroStub => "crate-local procedural macro", } } -- cgit 1.4.1-3-g733a5 From ec376c783e3a64445c4b55fb5980ae922319a916 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 19 Jun 2019 01:00:49 +0300 Subject: Move `MacroKind` into `libsyntax_pos` So it can be eventually used in `ExpnInfo` --- src/libsyntax/ext/base.rs | 29 +---------------------------- src/libsyntax_pos/hygiene.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 28 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8d5e4a3369e..09ff44115b4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -24,6 +24,7 @@ use std::path::PathBuf; use std::rc::Rc; use std::default::Default; +pub use syntax_pos::hygiene::MacroKind; #[derive(Debug,Clone)] pub enum Annotatable { @@ -518,34 +519,6 @@ impl MacResult for DummyResult { } } -/// Represents different kinds of macro invocations that can be resolved. -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum MacroKind { - /// A bang macro - foo!() - Bang, - /// An attribute macro - #[foo] - Attr, - /// A derive attribute macro - #[derive(Foo)] - Derive, -} - -impl MacroKind { - pub fn descr(self) -> &'static str { - match self { - MacroKind::Bang => "macro", - MacroKind::Attr => "attribute macro", - MacroKind::Derive => "derive macro", - } - } - - pub fn article(self) -> &'static str { - match self { - MacroKind::Attr => "an", - _ => "a", - } - } -} - /// A syntax extension kind. pub enum SyntaxExtensionKind { /// A token-based function-like macro. diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index f52952ca402..6a2aba17a79 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -723,6 +723,34 @@ impl ExpnFormat { } } +/// The kind of macro invocation or definition. +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum MacroKind { + /// A bang macro `foo!()`. + Bang, + /// An attribute macro `#[foo]`. + Attr, + /// A derive macro `#[derive(Foo)]` + Derive, +} + +impl MacroKind { + pub fn descr(self) -> &'static str { + match self { + MacroKind::Bang => "macro", + MacroKind::Attr => "attribute macro", + MacroKind::Derive => "derive macro", + } + } + + pub fn article(self) -> &'static str { + match self { + MacroKind::Attr => "an", + _ => "a", + } + } +} + /// The kind of compiler desugaring. #[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub enum CompilerDesugaringKind { -- cgit 1.4.1-3-g733a5 From 16918a8e28d4e7a476f31ff3d3c1e2d998c086af Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 19 Jun 2019 01:08:45 +0300 Subject: Rename some things in `syntax_pos/hygiene` More consistent with other naming: ExpnFormat -> ExpnKind ExpnKind::name -> ExpnKind::descr DesugaringKind::name -> DesugaringKind::descr Shorter, no tautology: CompilerDesugaring -> Desugaring CompilerDesugaringKind -> DesugaringKind --- src/librustc/hir/lowering.rs | 35 +++++++++-------- src/librustc/ich/impls_syntax.rs | 8 ++-- .../infer/error_reporting/need_type_info.rs | 6 +-- src/librustc/lint/internal.rs | 4 +- src/librustc/lint/mod.rs | 16 ++++---- src/librustc/mir/mod.rs | 2 +- src/librustc/traits/error_reporting.rs | 8 ++-- src/librustc_allocator/expand.rs | 5 ++- src/librustc_borrowck/borrowck/mod.rs | 6 +-- src/librustc_mir/borrow_check/conflict_errors.rs | 4 +- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_save_analysis/lib.rs | 5 +-- src/librustc_typeck/check/_match.rs | 4 +- src/librustc_typeck/check/mod.rs | 4 +- src/libsyntax/ext/base.rs | 14 +++---- src/libsyntax/ext/derive.rs | 4 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/source_map.rs | 4 +- src/libsyntax/std_inject.rs | 4 +- src/libsyntax/test.rs | 4 +- src/libsyntax_ext/proc_macro_decls.rs | 4 +- src/libsyntax_ext/test.rs | 4 +- src/libsyntax_ext/test_case.rs | 4 +- src/libsyntax_pos/hygiene.rs | 44 +++++++++++----------- src/libsyntax_pos/lib.rs | 24 ++++++------ 25 files changed, 111 insertions(+), 110 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2a9fd58f84b..549c34d961a 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -62,8 +62,7 @@ use syntax::ast::*; use syntax::errors; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::print::pprust; -use syntax::source_map::{self, respan, ExpnInfo, CompilerDesugaringKind, Spanned}; -use syntax::source_map::CompilerDesugaringKind::CondTemporary; +use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned}; use syntax::std_inject; use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; @@ -872,7 +871,7 @@ impl<'a> LoweringContext<'a> { /// allowed inside this span. fn mark_span_with_reason( &self, - reason: CompilerDesugaringKind, + reason: DesugaringKind, span: Span, allow_internal_unstable: Option>, ) -> Span { @@ -880,7 +879,7 @@ impl<'a> LoweringContext<'a> { mark.set_expn_info(ExpnInfo { def_site: Some(span), allow_internal_unstable, - ..ExpnInfo::default(source_map::CompilerDesugaring(reason), span, self.sess.edition()) + ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) }); span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } @@ -1188,7 +1187,7 @@ impl<'a> LoweringContext<'a> { }; let unstable_span = self.mark_span_with_reason( - CompilerDesugaringKind::Async, + DesugaringKind::Async, span, self.allow_gen_future.clone(), ); @@ -1733,7 +1732,7 @@ impl<'a> LoweringContext<'a> { // Not tracking it makes lints in rustc and clippy very fragile, as // frequently opened issues show. let exist_ty_span = self.mark_span_with_reason( - CompilerDesugaringKind::ExistentialType, + DesugaringKind::ExistentialType, span, None, ); @@ -2603,7 +2602,7 @@ impl<'a> LoweringContext<'a> { let span = output.span(); let exist_ty_span = self.mark_span_with_reason( - CompilerDesugaringKind::Async, + DesugaringKind::Async, span, None, ); @@ -3275,7 +3274,7 @@ impl<'a> LoweringContext<'a> { }; let desugared_span = - this.mark_span_with_reason(CompilerDesugaringKind::Async, span, None); + this.mark_span_with_reason(DesugaringKind::Async, span, None); // Construct an argument representing `__argN: ` to replace the argument of the // async function. @@ -4410,7 +4409,9 @@ impl<'a> LoweringContext<'a> { _ => { // Lower condition: let cond = self.lower_expr(cond); - let span_block = self.mark_span_with_reason(CondTemporary, cond.span, None); + let span_block = self.mark_span_with_reason( + DesugaringKind::CondTemporary, cond.span, None + ); // Wrap in a construct equivalent to `{ let _t = $cond; _t }` // to preserve drop semantics since `if cond { ... }` does not // let temporaries live outside of `cond`. @@ -4469,7 +4470,9 @@ impl<'a> LoweringContext<'a> { // Lower condition: let cond = this.with_loop_condition_scope(|this| this.lower_expr(cond)); - let span_block = this.mark_span_with_reason(CondTemporary, cond.span, None); + let span_block = this.mark_span_with_reason( + DesugaringKind::CondTemporary, cond.span, None + ); // Wrap in a construct equivalent to `{ let _t = $cond; _t }` // to preserve drop semantics since `while cond { ... }` does not // let temporaries live outside of `cond`. @@ -4508,7 +4511,7 @@ impl<'a> LoweringContext<'a> { ExprKind::TryBlock(ref body) => { self.with_catch_scope(body.id, |this| { let unstable_span = this.mark_span_with_reason( - CompilerDesugaringKind::TryBlock, + DesugaringKind::TryBlock, body.span, this.allow_try_trait.clone(), ); @@ -4836,7 +4839,7 @@ impl<'a> LoweringContext<'a> { let mut head = self.lower_expr(head); let head_sp = head.span; let desugared_span = self.mark_span_with_reason( - CompilerDesugaringKind::ForLoop, + DesugaringKind::ForLoop, head_sp, None, ); @@ -4990,13 +4993,13 @@ impl<'a> LoweringContext<'a> { // } let unstable_span = self.mark_span_with_reason( - CompilerDesugaringKind::QuestionMark, + DesugaringKind::QuestionMark, e.span, self.allow_try_trait.clone(), ); let try_span = self.sess.source_map().end_point(e.span); let try_span = self.mark_span_with_reason( - CompilerDesugaringKind::QuestionMark, + DesugaringKind::QuestionMark, try_span, self.allow_try_trait.clone(), ); @@ -5811,12 +5814,12 @@ impl<'a> LoweringContext<'a> { } } let span = self.mark_span_with_reason( - CompilerDesugaringKind::Await, + DesugaringKind::Await, await_span, None, ); let gen_future_span = self.mark_span_with_reason( - CompilerDesugaringKind::Await, + DesugaringKind::Await, await_span, self.allow_gen_future.clone(), ); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index c09b2003f38..f679a65c642 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -398,7 +398,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { call_site, - format, + kind, def_site, default_transparency, allow_internal_unstable, @@ -407,13 +407,13 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { edition }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat { +impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { MacroAttribute(sym), MacroBang(sym), - CompilerDesugaring(kind) + Desugaring(kind) }); -impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind { +impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind { CondTemporary, Async, Await, diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 4426b5c0e85..770d5155777 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -5,7 +5,7 @@ use crate::infer::InferCtxt; use crate::infer::type_variable::TypeVariableOriginKind; use crate::ty::{self, Ty, Infer, TyVar}; use crate::ty::print::Print; -use syntax::source_map::CompilerDesugaringKind; +use syntax::source_map::DesugaringKind; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -194,12 +194,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )); } else if let Some(pattern) = local_visitor.found_local_pattern { if let Some(simple_ident) = pattern.simple_ident() { - match pattern.span.compiler_desugaring_kind() { + match pattern.span.desugaring_kind() { None => labels.push(( pattern.span, format!("consider giving `{}` {}", simple_ident, suffix), )), - Some(CompilerDesugaringKind::ForLoop) => labels.push(( + Some(DesugaringKind::ForLoop) => labels.push(( pattern.span, "the element type for this iterator is not specified".to_owned(), )), diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index 34899736949..0b514f5927d 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -247,10 +247,10 @@ impl EarlyLintPass for LintPassImpl { } fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool { - if expn_info.format.name() == sym::impl_lint_pass { + if expn_info.kind.descr() == sym::impl_lint_pass { true } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() { - info.format.name() == sym::declare_lint_pass + info.kind.descr() == sym::declare_lint_pass } else { false } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 59b08b832d2..2bf4f1d3cfb 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -35,7 +35,7 @@ use crate::util::nodemap::NodeMap; use errors::{DiagnosticBuilder, DiagnosticId}; use std::{hash, ptr}; use syntax::ast; -use syntax::source_map::{MultiSpan, ExpnFormat, CompilerDesugaringKind}; +use syntax::source_map::{MultiSpan, ExpnKind, DesugaringKind}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; use syntax::symbol::{Symbol, sym}; @@ -883,11 +883,11 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { None => return false, }; - match info.format { - ExpnFormat::MacroAttribute(..) => true, // definitely a plugin - ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::ForLoop) => false, - ExpnFormat::CompilerDesugaring(_) => true, // well, it's "external" - ExpnFormat::MacroBang(..) => { + match info.kind { + ExpnKind::MacroAttribute(..) => true, // definitely a plugin + ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, + ExpnKind::Desugaring(_) => true, // well, it's "external" + ExpnKind::MacroBang(..) => { let def_site = match info.def_site { Some(span) => span, // no span for the def_site means it's an external macro @@ -911,8 +911,8 @@ pub fn in_derive_expansion(span: Span) -> bool { None => return false, }; - match info.format { - ExpnFormat::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("), + match info.kind { + ExpnKind::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("), _ => false, } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 59a032d53cf..ff868bf2a2a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -928,7 +928,7 @@ impl<'tcx> LocalDecl<'tcx> { /// `__next` from a `for` loop. #[inline] pub fn from_compiler_desugaring(&self) -> bool { - self.source_info.span.compiler_desugaring_kind().is_some() + self.source_info.span.desugaring_kind().is_some() } /// Creates a new `LocalDecl` for a temporary. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d6cc68bcdab..fb7ed147445 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder}; use std::fmt; use syntax::ast; use syntax::symbol::sym; -use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat}; +use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind}; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn report_fulfillment_errors(&self, @@ -62,7 +62,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // if one is the result of a desugaring and the other is not. let mut span = error.obligation.cause.span; if let Some(ExpnInfo { - format: ExpnFormat::CompilerDesugaring(_), + kind: ExpnKind::Desugaring(_), def_site: Some(def_span), .. }) = span.ctxt().outer_expn_info() { @@ -373,9 +373,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { flags.push((sym::parent_trait, Some(t))); } - if let Some(k) = obligation.cause.span.compiler_desugaring_kind() { + if let Some(k) = obligation.cause.span.desugaring_kind() { flags.push((sym::from_desugaring, None)); - flags.push((sym::from_desugaring, Some(k.name().to_string()))); + flags.push((sym::from_desugaring, Some(k.descr().to_string()))); } let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index d402b0ddf6e..18bbb257128 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -8,7 +8,7 @@ use syntax::{ }, attr, source_map::{ - respan, ExpnInfo, MacroAttribute, + respan, ExpnInfo, ExpnKind, }, ext::{ base::{ExtCtxt, Resolver}, @@ -87,7 +87,8 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { // Create a fresh Mark for the new macro expansion we are about to do let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::global_allocator), item.span, self.sess.edition, &[sym::rustc_attrs] + ExpnKind::MacroAttribute(sym::global_allocator), item.span, self.sess.edition, + &[sym::rustc_attrs], )); // Tie the span to the macro expansion info we just created diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 34db080ef66..9a581cb03ec 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -33,7 +33,7 @@ use std::cell::{Cell, RefCell}; use std::fmt; use std::rc::Rc; use std::hash::{Hash, Hasher}; -use syntax::source_map::CompilerDesugaringKind; +use syntax::source_map::DesugaringKind; use syntax_pos::{MultiSpan, Span}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use log::debug; @@ -734,8 +734,8 @@ impl BorrowckCtxt<'_, 'tcx> { }, moved_lp.ty)); } - if let (Some(CompilerDesugaringKind::ForLoop), Ok(snippet)) = ( - move_span.compiler_desugaring_kind(), + if let (Some(DesugaringKind::ForLoop), Ok(snippet)) = ( + move_span.desugaring_kind(), self.tcx.sess.source_map().span_to_snippet(move_span), ) { if !snippet.starts_with("&") { diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index f23cffeda68..7b5fce4abbc 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; -use syntax::source_map::CompilerDesugaringKind; +use syntax::source_map::DesugaringKind; use super::nll::explain_borrow::BorrowExplanation; use super::nll::region_infer::{RegionName, RegionNameSource}; @@ -174,7 +174,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("variable moved due to use{}", move_spans.describe()), ); } - if Some(CompilerDesugaringKind::ForLoop) == move_span.compiler_desugaring_kind() { + if Some(DesugaringKind::ForLoop) == move_span.desugaring_kind() { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { err.span_suggestion( move_span, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 25ac93cc242..31a9766af30 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -335,7 +335,7 @@ fn do_mir_borrowck<'a, 'tcx>( } let span = local_decl.source_info.span; - if span.compiler_desugaring_kind().is_some() { + if span.desugaring_kind().is_some() { // If the `mut` arises as part of a desugaring, we should ignore it. continue; } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index effd69dc61d..fab2537f9d8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -37,7 +37,6 @@ use syntax::parse::lexer::comments::strip_doc_comment_decoration; use syntax::print::pprust; use syntax::visit::{self, Visitor}; use syntax::print::pprust::{arg_to_string, ty_to_string}; -use syntax::source_map::MacroAttribute; use syntax_pos::*; use json_dumper::JsonDumper; @@ -845,7 +844,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callee_span = callee.def_site?; // Ignore attribute macros, their spans are usually mangled - if let MacroAttribute(_) = callee.format { + if let ExpnKind::MacroAttribute(_) = callee.kind { return None; } @@ -870,7 +869,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callee_span = self.span_from_span(callee_span); Some(MacroRef { span: callsite_span, - qualname: callee.format.name().to_string(), // FIXME: generate the real qualname + qualname: callee.kind.descr().to_string(), // FIXME: generate the real qualname callee_span, }) } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index d24f92a6faf..de42a6a35c8 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -15,7 +15,7 @@ use syntax::ast; use syntax::source_map::Spanned; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::Span; -use syntax_pos::hygiene::CompilerDesugaringKind; +use syntax_pos::hygiene::DesugaringKind; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; @@ -184,7 +184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // In the case of `if`- and `while`-expressions we've already checked // that `scrutinee: bool`. We know that the pattern is `true`, // so an error here would be a duplicate and from the wrong POV. - s.is_compiler_desugaring(CompilerDesugaringKind::CondTemporary) + s.is_desugaring(DesugaringKind::CondTemporary) }) .is_some()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4acba6d38fa..d32ee67f745 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -119,7 +119,7 @@ use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfT use rustc::ty::util::{Representability, IntTypeExt, Discr}; use rustc::ty::layout::VariantIdx; use syntax_pos::{self, BytePos, Span, MultiSpan}; -use syntax_pos::hygiene::CompilerDesugaringKind; +use syntax_pos::hygiene::DesugaringKind; use syntax::ast; use syntax::attr; use syntax::feature_gate::{GateIssue, emit_feature_err}; @@ -2165,7 +2165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If span arose from a desugaring of `if` or `while`, then it is the condition itself, // which diverges, that we are about to lint on. This gives suboptimal diagnostics. // Instead, stop here so that the `if`- or `while`-expression's block is linted instead. - !span.is_compiler_desugaring(CompilerDesugaringKind::CondTemporary) { + !span.is_desugaring(DesugaringKind::CondTemporary) { self.diverges.set(Diverges::WarnedAlways); debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 09ff44115b4..0c986574cec 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream}; use errors::{DiagnosticBuilder, DiagnosticId}; use smallvec::{smallvec, SmallVec}; use syntax_pos::{Span, MultiSpan, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnInfo, ExpnFormat}; +use syntax_pos::hygiene::{ExpnInfo, ExpnKind}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; @@ -642,18 +642,18 @@ impl SyntaxExtension { } } - fn expn_format(&self, symbol: Symbol) -> ExpnFormat { + fn expn_kind(&self, descr: Symbol) -> ExpnKind { match self.kind { SyntaxExtensionKind::Bang(..) | - SyntaxExtensionKind::LegacyBang(..) => ExpnFormat::MacroBang(symbol), - _ => ExpnFormat::MacroAttribute(symbol), + SyntaxExtensionKind::LegacyBang(..) => ExpnKind::MacroBang(descr), + _ => ExpnKind::MacroAttribute(descr), } } - pub fn expn_info(&self, call_site: Span, format: &str) -> ExpnInfo { + pub fn expn_info(&self, call_site: Span, descr: &str) -> ExpnInfo { ExpnInfo { call_site, - format: self.expn_format(Symbol::intern(format)), + kind: self.expn_kind(Symbol::intern(descr)), def_site: Some(self.span), default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), @@ -780,7 +780,7 @@ impl<'a> ExtCtxt<'a> { let mut last_macro = None; loop { if ctxt.outer_expn_info().map_or(None, |info| { - if info.format.name() == sym::include { + if info.kind.descr() == sym::include { // Stop going up the backtrace once include! is encountered return None; } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 2a56f3dd756..24050be792b 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -1,6 +1,6 @@ use crate::attr::HasAttrs; use crate::ast; -use crate::source_map::{ExpnInfo, ExpnFormat}; +use crate::source_map::{ExpnInfo, ExpnKind}; use crate::ext::base::ExtCtxt; use crate::ext::build::AstBuilder; use crate::parse::parser::PathStyle; @@ -57,7 +57,7 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P pretty_name.push(')'); cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable( - ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition, + ExpnKind::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match], )); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 053686b8b1f..879069c1418 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -506,7 +506,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let suggested_limit = self.cx.ecfg.recursion_limit * 2; let mut err = self.cx.struct_span_err(info.call_site, &format!("recursion limit reached while expanding the macro `{}`", - info.format.name())); + info.kind.descr())); err.help(&format!( "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", suggested_limit)); diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index ac30cbb471a..bbf62ef1e23 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -7,10 +7,8 @@ //! within the SourceMap, which upon request can be converted to line and column //! information, source code snippets, etc. - pub use syntax_pos::*; -pub use syntax_pos::hygiene::{ExpnFormat, ExpnInfo}; -pub use ExpnFormat::*; +pub use syntax_pos::hygiene::{ExpnKind, ExpnInfo}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 6630bf90815..7ee073117e9 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -3,7 +3,7 @@ use crate::attr; use crate::edition::Edition; use crate::ext::hygiene::{Mark, SyntaxContext}; use crate::symbol::{Ident, Symbol, kw, sym}; -use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, respan}; +use crate::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use crate::ptr::P; use crate::tokenstream::TokenStream; @@ -17,7 +17,7 @@ use syntax_pos::{DUMMY_SP, Span}; fn ignored_span(sp: Span, edition: Edition) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(Symbol::intern("std_inject")), sp, edition, &[sym::prelude_import] + ExpnKind::MacroAttribute(Symbol::intern("std_inject")), sp, edition, &[sym::prelude_import] )); sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index c717f140ca3..35a1a552a13 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -15,7 +15,7 @@ use smallvec::{smallvec, SmallVec}; use syntax_pos::{DUMMY_SP, NO_EXPANSION, Span, SourceFile, BytePos}; use crate::attr::{self, HasAttrs}; -use crate::source_map::{self, SourceMap, ExpnInfo, MacroAttribute, dummy_spanned, respan}; +use crate::source_map::{self, SourceMap, ExpnInfo, ExpnKind, dummy_spanned, respan}; use crate::config; use crate::entry::{self, EntryPointType}; use crate::ext::base::{ExtCtxt, Resolver}; @@ -280,7 +280,7 @@ fn generate_test_harness(sess: &ParseSess, }; mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::test_case), DUMMY_SP, sess.edition, + ExpnKind::MacroAttribute(sym::test_case), DUMMY_SP, sess.edition, &[sym::main, sym::test, sym::rustc_attrs], )); diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 45e65288a24..dee8f4b3eb5 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -4,7 +4,7 @@ use crate::deriving; use syntax::ast::{self, Ident}; use syntax::attr; -use syntax::source_map::{ExpnInfo, MacroAttribute, respan}; +use syntax::source_map::{ExpnInfo, ExpnKind, respan}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; @@ -348,7 +348,7 @@ fn mk_decls( ) -> P { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, + ExpnKind::MacroAttribute(sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, &[sym::rustc_attrs, Symbol::intern("proc_macro_internals")], )); let span = DUMMY_SP.apply_mark(mark); diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 24d3055e711..7f4f1fd7e01 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -9,7 +9,7 @@ use syntax::ast; use syntax::print::pprust; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; -use syntax::source_map::{ExpnInfo, MacroAttribute}; +use syntax::source_map::{ExpnInfo, ExpnKind}; use std::iter; pub fn expand_test( @@ -63,7 +63,7 @@ pub fn expand_test_or_bench( let (sp, attr_sp) = { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::test), attr_sp, cx.parse_sess.edition, + ExpnKind::MacroAttribute(sym::test), attr_sp, cx.parse_sess.edition, &[sym::rustc_attrs, sym::test], )); (item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)), diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 186673c142f..5f88e2e098a 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -16,7 +16,7 @@ use syntax::ast; use syntax::source_map::respan; use syntax::symbol::sym; use syntax_pos::Span; -use syntax::source_map::{ExpnInfo, MacroAttribute}; +use syntax::source_map::{ExpnInfo, ExpnKind}; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -29,7 +29,7 @@ pub fn expand( let sp = { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - MacroAttribute(sym::test_case), attr_sp, ecx.parse_sess.edition, + ExpnKind::MacroAttribute(sym::test_case), attr_sp, ecx.parse_sess.edition, &[sym::test, sym::rustc_attrs], )); attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 6a2aba17a79..f36a4d5816e 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -162,7 +162,7 @@ impl Mark { HygieneData::with(|data| { if data.default_transparency(self) == Transparency::Opaque { if let Some(expn_info) = &data.marks[self.0 as usize].expn_info { - if let ExpnFormat::MacroAttribute(name) = expn_info.format { + if let ExpnKind::MacroAttribute(name) = expn_info.kind { if name.as_str().starts_with("derive(") { return true; } @@ -654,7 +654,7 @@ pub struct ExpnInfo { /// pointing to the `foo!` invocation. pub call_site: Span, /// The format with which the macro was invoked. - pub format: ExpnFormat, + pub kind: ExpnKind, // --- The part specific to the macro/desugaring definition. // --- FIXME: Share it between expansions with the same definition. @@ -681,10 +681,10 @@ pub struct ExpnInfo { impl ExpnInfo { /// Constructs an expansion info with default properties. - pub fn default(format: ExpnFormat, call_site: Span, edition: Edition) -> ExpnInfo { + pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo { ExpnInfo { call_site, - format, + kind, def_site: None, default_transparency: Transparency::SemiTransparent, allow_internal_unstable: None, @@ -694,31 +694,31 @@ impl ExpnInfo { } } - pub fn with_unstable(format: ExpnFormat, call_site: Span, edition: Edition, + pub fn with_unstable(kind: ExpnKind, call_site: Span, edition: Edition, allow_internal_unstable: &[Symbol]) -> ExpnInfo { ExpnInfo { allow_internal_unstable: Some(allow_internal_unstable.into()), - ..ExpnInfo::default(format, call_site, edition) + ..ExpnInfo::default(kind, call_site, edition) } } } /// The source of expansion. #[derive(Clone, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] -pub enum ExpnFormat { +pub enum ExpnKind { /// e.g., #[derive(...)] MacroAttribute(Symbol), /// e.g., `format!()` MacroBang(Symbol), /// Desugaring done by the compiler during HIR lowering. - CompilerDesugaring(CompilerDesugaringKind) + Desugaring(DesugaringKind) } -impl ExpnFormat { - pub fn name(&self) -> Symbol { +impl ExpnKind { + pub fn descr(&self) -> Symbol { match *self { - ExpnFormat::MacroBang(name) | ExpnFormat::MacroAttribute(name) => name, - ExpnFormat::CompilerDesugaring(kind) => kind.name(), + ExpnKind::MacroBang(name) | ExpnKind::MacroAttribute(name) => name, + ExpnKind::Desugaring(kind) => kind.descr(), } } } @@ -753,7 +753,7 @@ impl MacroKind { /// The kind of compiler desugaring. #[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] -pub enum CompilerDesugaringKind { +pub enum DesugaringKind { /// We desugar `if c { i } else { e }` to `match $ExprKind::Use(c) { true => i, _ => e }`. /// However, we do not want to blame `c` for unreachability but rather say that `i` /// is unreachable. This desugaring kind allows us to avoid blaming `c`. @@ -770,16 +770,16 @@ pub enum CompilerDesugaringKind { ForLoop, } -impl CompilerDesugaringKind { - pub fn name(self) -> Symbol { +impl DesugaringKind { + pub fn descr(self) -> Symbol { Symbol::intern(match self { - CompilerDesugaringKind::CondTemporary => "if and while condition", - CompilerDesugaringKind::Async => "async", - CompilerDesugaringKind::Await => "await", - CompilerDesugaringKind::QuestionMark => "?", - CompilerDesugaringKind::TryBlock => "try block", - CompilerDesugaringKind::ExistentialType => "existential type", - CompilerDesugaringKind::ForLoop => "for loop", + DesugaringKind::CondTemporary => "if and while condition", + DesugaringKind::Async => "async", + DesugaringKind::Await => "await", + DesugaringKind::QuestionMark => "?", + DesugaringKind::TryBlock => "try block", + DesugaringKind::ExistentialType => "existential type", + DesugaringKind::ForLoop => "for loop", }) } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 07b9f609320..d4c1958f7e2 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -27,7 +27,7 @@ extern crate serialize as rustc_serialize; // used by deriving pub mod edition; use edition::Edition; pub mod hygiene; -pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind}; +pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind, DesugaringKind}; mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; @@ -403,10 +403,10 @@ impl Span { } /// Checks if this span arises from a compiler desugaring of kind `kind`. - pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool { + pub fn is_desugaring(&self, kind: DesugaringKind) -> bool { match self.ctxt().outer_expn_info() { - Some(info) => match info.format { - ExpnFormat::CompilerDesugaring(k) => k == kind, + Some(info) => match info.kind { + ExpnKind::Desugaring(k) => k == kind, _ => false, }, None => false, @@ -415,10 +415,10 @@ impl Span { /// Returns the compiler desugaring that created this span, or `None` /// if this span is not from a desugaring. - pub fn compiler_desugaring_kind(&self) -> Option { + pub fn desugaring_kind(&self) -> Option { match self.ctxt().outer_expn_info() { - Some(info) => match info.format { - ExpnFormat::CompilerDesugaring(k) => Some(k), + Some(info) => match info.kind { + ExpnKind::Desugaring(k) => Some(k), _ => None }, None => None @@ -441,14 +441,14 @@ impl Span { while let Some(info) = self.ctxt().outer_expn_info() { // Don't print recursive invocations. if !info.call_site.source_equal(&prev_span) { - let (pre, post) = match info.format { - ExpnFormat::MacroAttribute(..) => ("#[", "]"), - ExpnFormat::MacroBang(..) => ("", "!"), - ExpnFormat::CompilerDesugaring(..) => ("desugaring of `", "`"), + let (pre, post) = match info.kind { + ExpnKind::MacroAttribute(..) => ("#[", "]"), + ExpnKind::MacroBang(..) => ("", "!"), + ExpnKind::Desugaring(..) => ("desugaring of `", "`"), }; result.push(MacroBacktrace { call_site: info.call_site, - macro_decl_name: format!("{}{}{}", pre, info.format.name(), post), + macro_decl_name: format!("{}{}{}", pre, info.kind.descr(), post), def_site_span: info.def_site, }); } -- cgit 1.4.1-3-g733a5 From a138e9d625bf83c45d3835b12d7689b730dc4e9a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 29 Jun 2019 02:30:53 +0300 Subject: expand: Get rid of `resolve_macro_path` It was used to choose whether to apply derive markers like `#[rustc_copy_clone_marker]` or not, but it was called before all the data required for resolution is available, so it could work incorrectly in some corner cases (like user-defined derives name `Copy` or `Eq`). Delay the decision about markers until the proper resolution results are available instead. --- src/librustc_resolve/macros.rs | 7 ------- src/libsyntax/ext/base.rs | 3 --- src/libsyntax/ext/expand.rs | 22 +++++++++++----------- 3 files changed, 11 insertions(+), 21 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index a3e00bcb81a..61300e3ee3c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -242,13 +242,6 @@ impl<'a> base::Resolver for Resolver<'a> { Ok(Some(ext)) } - fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Mark, - derives_in_scope: Vec, force: bool) - -> Result, Determinacy> { - let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); - Ok(self.resolve_macro_to_res(path, kind, &parent_scope, false, force)?.1) - } - fn check_unused_macros(&self) { for (&node_id, &span) in self.unused_macros.iter() { self.session.buffer_lint( diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0c986574cec..267046655ff 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -680,9 +680,6 @@ pub trait Resolver { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool) -> Result>, Determinacy>; - fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Mark, - derives_in_scope: Vec, force: bool) - -> Result, Determinacy>; fn check_unused_macros(&self); } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 879069c1418..bb7d7352e05 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -208,6 +208,7 @@ pub enum InvocationKind { Derive { path: Path, item: Annotatable, + item_with_markers: Annotatable, }, } @@ -362,19 +363,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derives.reserve(traits.len()); invocations.reserve(traits.len()); - for path in &traits { + for path in traits { let mark = Mark::fresh(self.cx.current_expansion.mark); derives.push(mark); - let item = match self.cx.resolver.resolve_macro_path( - path, MacroKind::Derive, Mark::root(), Vec::new(), false) { - Ok(ext) => match ext.kind { - SyntaxExtensionKind::LegacyDerive(..) => item_with_markers.clone(), - _ => item.clone(), - }, - _ => item.clone(), - }; invocations.push(Invocation { - kind: InvocationKind::Derive { path: path.clone(), item }, + kind: InvocationKind::Derive { + path, + item: item.clone(), + item_with_markers: item_with_markers.clone(), + }, fragment_kind: invoc.fragment_kind, expansion_data: ExpansionData { mark, @@ -737,7 +734,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ext: &SyntaxExtension) -> Option { let (path, item) = match invoc.kind { - InvocationKind::Derive { path, item } => (path, item), + InvocationKind::Derive { path, item, item_with_markers } => match ext.kind { + SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers), + _ => (path, item), + } _ => unreachable!(), }; if !item.derive_allowed() { -- cgit 1.4.1-3-g733a5 From 3eafaae510a71a76eedcc2909e7c908bd49d5c46 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 30 Jun 2019 03:05:52 +0300 Subject: syntax: Make def-site span mandatory in ExpnInfo/MacroBacktrace/DiagnosticSpanMacroExpansion We have to deal with dummy spans anyway Remove def-site span from expander interfaces. It's not used by the expansion infra, only by specific expanders, which can keep it themselves if they want it. --- src/librustc/hir/lowering.rs | 2 +- src/librustc/lint/mod.rs | 12 ++-- src/librustc/traits/error_reporting.rs | 9 +-- src/librustc_errors/emitter.rs | 64 +++++++++++----------- src/librustc_save_analysis/lib.rs | 5 +- src/libsyntax/ext/base.rs | 4 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 14 ++--- src/libsyntax/json.rs | 9 ++- src/libsyntax_pos/hygiene.rs | 10 ++-- src/libsyntax_pos/lib.rs | 4 +- .../run-pass-fulldeps/auxiliary/plugin-args.rs | 3 +- 12 files changed, 61 insertions(+), 77 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 549c34d961a..c44fd30be85 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -877,7 +877,7 @@ impl<'a> LoweringContext<'a> { ) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo { - def_site: Some(span), + def_site: span, allow_internal_unstable, ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) }); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 2bf4f1d3cfb..9876d6c1fa5 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -888,13 +888,11 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::MacroBang(..) => { - let def_site = match info.def_site { - Some(span) => span, - // no span for the def_site means it's an external macro - None => return true, - }; - - match sess.source_map().span_to_snippet(def_site) { + if info.def_site.is_dummy() { + // dummy span for the def_site means it's an external macro + return true; + } + match sess.source_map().span_to_snippet(info.def_site) { Ok(code) => !code.starts_with("macro_rules"), // no snippet = external macro or compiler-builtin expansion Err(_) => true, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index fb7ed147445..a7dfbd688c1 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -61,12 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. let mut span = error.obligation.cause.span; - if let Some(ExpnInfo { - kind: ExpnKind::Desugaring(_), - def_site: Some(def_span), - .. - }) = span.ctxt().outer_expn_info() { - span = def_span; + if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. }) + = span.ctxt().outer_expn_info() { + span = def_site; } error_map.entry(span).or_default().push( diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 83a0fb486fd..361b5cd9357 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -723,39 +723,37 @@ impl EmitterWriter { for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() { // Only show macro locations that are local // and display them like a span_note - if let Some(def_site) = trace.def_site_span { - if def_site.is_dummy() { - continue; - } - if always_backtrace { - new_labels.push((def_site, - format!("in this expansion of `{}`{}", - trace.macro_decl_name, - if backtrace_len > 2 { - // if backtrace_len == 1 it'll be pointed - // at by "in this macro invocation" - format!(" (#{})", i + 1) - } else { - String::new() - }))); - } - // Check to make sure we're not in any <*macros> - if !sm.span_to_filename(def_site).is_macros() && - !trace.macro_decl_name.starts_with("desugaring of ") && - !trace.macro_decl_name.starts_with("#[") || - always_backtrace { - new_labels.push((trace.call_site, - format!("in this macro invocation{}", - if backtrace_len > 2 && always_backtrace { - // only specify order when the macro - // backtrace is multiple levels deep - format!(" (#{})", i + 1) - } else { - String::new() - }))); - if !always_backtrace { - break; - } + if trace.def_site_span.is_dummy() { + continue; + } + if always_backtrace { + new_labels.push((trace.def_site_span, + format!("in this expansion of `{}`{}", + trace.macro_decl_name, + if backtrace_len > 2 { + // if backtrace_len == 1 it'll be pointed + // at by "in this macro invocation" + format!(" (#{})", i + 1) + } else { + String::new() + }))); + } + // Check to make sure we're not in any <*macros> + if !sm.span_to_filename(trace.def_site_span).is_macros() && + !trace.macro_decl_name.starts_with("desugaring of ") && + !trace.macro_decl_name.starts_with("#[") || + always_backtrace { + new_labels.push((trace.call_site, + format!("in this macro invocation{}", + if backtrace_len > 2 && always_backtrace { + // only specify order when the macro + // backtrace is multiple levels deep + format!(" (#{})", i + 1) + } else { + String::new() + }))); + if !always_backtrace { + break; } } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index fab2537f9d8..aeaee1887b9 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -841,7 +841,6 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callsite = span.source_callsite(); let callsite_span = self.span_from_span(callsite); let callee = span.source_callee()?; - let callee_span = callee.def_site?; // Ignore attribute macros, their spans are usually mangled if let ExpnKind::MacroAttribute(_) = callee.kind { @@ -855,7 +854,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { .sess .imported_macro_spans .borrow() - .get(&callee_span) + .get(&callee.def_site) { let &(ref mac_name, mac_span) = mac; let mac_span = self.span_from_span(mac_span); @@ -866,7 +865,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }); } - let callee_span = self.span_from_span(callee_span); + let callee_span = self.span_from_span(callee.def_site); Some(MacroRef { span: callsite_span, qualname: callee.kind.descr().to_string(), // FIXME: generate the real qualname diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 267046655ff..2f8d6f00ba7 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -219,7 +219,6 @@ pub trait TTMacroExpander { ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, - def_span: Option, ) -> Box; } @@ -236,7 +235,6 @@ impl TTMacroExpander for F ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, - _def_span: Option, ) -> Box { struct AvoidInterpolatedIdents; @@ -654,7 +652,7 @@ impl SyntaxExtension { ExpnInfo { call_site, kind: self.expn_kind(Symbol::intern(descr)), - def_site: Some(self.span), + def_site: self.span, default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), allow_internal_unsafe: self.allow_internal_unsafe, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index bb7d7352e05..06ff2bc655c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -673,7 +673,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { result } SyntaxExtensionKind::LegacyBang(expander) => { - let tok_result = expander.expand(self.cx, span, mac.node.stream(), Some(ext.span)); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); kind.make_from(tok_result) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 665c794422d..5c6438a7ef5 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -88,6 +88,7 @@ impl<'a> ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: ast::Ident, + span: Span, lhses: Vec, rhses: Vec, valid: bool, @@ -99,12 +100,11 @@ impl TTMacroExpander for MacroRulesMacroExpander { cx: &'cx mut ExtCtxt<'_>, sp: Span, input: TokenStream, - def_span: Option, ) -> Box { if !self.valid { return DummyResult::any(sp); } - generic_extension(cx, sp, def_span, self.name, input, &self.lhses, &self.rhses) + generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses) } } @@ -117,7 +117,7 @@ fn trace_macros_note(cx: &mut ExtCtxt<'_>, sp: Span, message: String) { fn generic_extension<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, - def_span: Option, + def_span: Span, name: ast::Ident, arg: TokenStream, lhses: &[quoted::TokenTree], @@ -199,10 +199,8 @@ fn generic_extension<'cx>( let span = token.span.substitute_dummy(sp); let mut err = cx.struct_span_err(span, &parse_failure_msg(&token)); err.span_label(span, label); - if let Some(sp) = def_span { - if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() { - err.span_label(cx.source_map().def_span(sp), "when calling this macro"); - } + if !def_span.is_dummy() && cx.source_map().span_to_filename(def_span).is_real() { + err.span_label(cx.source_map().def_span(def_span), "when calling this macro"); } // Check whether there's a missing comma in this macro call, like `println!("{}" a);` @@ -377,7 +375,7 @@ pub fn compile( } let expander: Box<_> = - Box::new(MacroRulesMacroExpander { name: def.ident, lhses, rhses, valid }); + Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid }); let (default_transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy); diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 767ab74355e..ec0222d90eb 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -170,7 +170,7 @@ struct DiagnosticSpanMacroExpansion { macro_decl_name: String, /// span where macro was defined (if known) - def_site_span: Option, + def_site_span: DiagnosticSpan, } #[derive(RustcEncodable)] @@ -300,14 +300,13 @@ impl DiagnosticSpan { None, backtrace, je); - let def_site_span = bt.def_site_span.map(|sp| { - Self::from_span_full(sp, + let def_site_span = + Self::from_span_full(bt.def_site_span, false, None, None, vec![].into_iter(), - je) - }); + je); Box::new(DiagnosticSpanMacroExpansion { span: call_site, macro_decl_name: bt.macro_decl_name, diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index f8318f54320..63b692ccdcb 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -26,7 +26,7 @@ // trigger runtime aborts. (Fortunately these are obvious and easy to fix.) use crate::GLOBALS; -use crate::Span; +use crate::{Span, DUMMY_SP}; use crate::edition::Edition; use crate::symbol::{kw, Symbol}; @@ -632,11 +632,9 @@ pub struct ExpnInfo { // --- The part specific to the macro/desugaring definition. // --- FIXME: Share it between expansions with the same definition. - /// The span of the macro definition itself. The macro may not - /// have a sensible definition span (e.g., something defined - /// completely inside libsyntax) in which case this is None. + /// The span of the macro definition (possibly dummy). /// This span serves only informational purpose and is not used for resolution. - pub def_site: Option, + pub def_site: Span, /// Transparency used by `apply_mark` for mark with this expansion info by default. pub default_transparency: Transparency, /// List of #[unstable]/feature-gated features that the macro is allowed to use @@ -659,7 +657,7 @@ impl ExpnInfo { ExpnInfo { call_site, kind, - def_site: None, + def_site: DUMMY_SP, default_transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index d4c1958f7e2..1369fca3b4a 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -1363,8 +1363,8 @@ pub struct MacroBacktrace { /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") pub macro_decl_name: String, - /// span where macro was defined (if known) - pub def_site_span: Option, + /// span where macro was defined (possibly dummy) + pub def_site_span: Span, } // _____________________________________________________________________________ diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index 7cbfef52b4a..36cee82893a 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -28,8 +28,7 @@ impl TTMacroExpander for Expander { fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, sp: Span, - _: TokenStream, - _: Option) -> Box { + _: TokenStream) -> Box { let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) .collect::>().join(", "); MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) -- cgit 1.4.1-3-g733a5 From aff9738462e8959c0a3eef57124b08d5f811cdec Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 30 Jun 2019 15:58:56 +0300 Subject: hygiene: Reuse `MacroKind` in `ExpnKind` Orthogonality and reuse are good. --- src/librustc/ich/impls_syntax.rs | 3 +-- src/librustc/lint/mod.rs | 19 ++++++++---------- src/librustc_allocator/expand.rs | 4 ++-- src/librustc_resolve/macros.rs | 38 +++++++++++++++++------------------ src/librustc_save_analysis/lib.rs | 3 ++- src/libsyntax/ext/base.rs | 12 ++--------- src/libsyntax/ext/derive.rs | 9 ++++----- src/libsyntax/std_inject.rs | 5 +++-- src/libsyntax/test.rs | 4 ++-- src/libsyntax_ext/proc_macro_decls.rs | 4 ++-- src/libsyntax_pos/hygiene.rs | 34 +++++++++++++++---------------- src/libsyntax_pos/lib.rs | 9 ++++++--- 12 files changed, 67 insertions(+), 77 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index f679a65c642..69e8c355019 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -408,8 +408,7 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { }); impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { - MacroAttribute(sym), - MacroBang(sym), + Macro(kind, descr), Desugaring(kind) }); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 9876d6c1fa5..3c8b0041a98 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -38,6 +38,7 @@ use syntax::ast; use syntax::source_map::{MultiSpan, ExpnKind, DesugaringKind}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; +use syntax::ext::base::MacroKind; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; @@ -884,10 +885,9 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { }; match info.kind { - ExpnKind::MacroAttribute(..) => true, // definitely a plugin ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, ExpnKind::Desugaring(_) => true, // well, it's "external" - ExpnKind::MacroBang(..) => { + ExpnKind::Macro(MacroKind::Bang, _) => { if info.def_site.is_dummy() { // dummy span for the def_site means it's an external macro return true; @@ -898,19 +898,16 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { Err(_) => true, } } + ExpnKind::Macro(..) => true, // definitely a plugin } } /// Returns whether `span` originates in a derive macro's expansion pub fn in_derive_expansion(span: Span) -> bool { - let info = match span.ctxt().outer_expn_info() { - Some(info) => info, - // no ExpnInfo means this span doesn't come from a macro - None => return false, - }; - - match info.kind { - ExpnKind::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("), - _ => false, + if let Some(info) = span.ctxt().outer_expn_info() { + if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind { + return true; + } } + false } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 18bbb257128..d0eefbb1179 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -11,7 +11,7 @@ use syntax::{ respan, ExpnInfo, ExpnKind, }, ext::{ - base::{ExtCtxt, Resolver}, + base::{ExtCtxt, MacroKind, Resolver}, build::AstBuilder, expand::ExpansionConfig, hygiene::{Mark, SyntaxContext}, @@ -87,7 +87,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { // Create a fresh Mark for the new macro expansion we are about to do let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::MacroAttribute(sym::global_allocator), item.span, self.sess.edition, + ExpnKind::Macro(MacroKind::Attr, sym::global_allocator), item.span, self.sess.edition, &[sym::rustc_attrs], )); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 61300e3ee3c..7f57b0a5052 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -114,17 +114,21 @@ fn sub_namespace_match(candidate: Option, requirement: Option String { - let mut path_str = String::with_capacity(64); - for (i, segment) in path.segments.iter().enumerate() { - if i != 0 { - path_str.push_str("::"); - } - if segment.ident.name != kw::PathRoot { - path_str.push_str(&segment.ident.as_str()) +fn fast_print_path(path: &ast::Path) -> Symbol { + if path.segments.len() == 1 { + return path.segments[0].ident.name + } else { + let mut path_str = String::with_capacity(64); + for (i, segment) in path.segments.iter().enumerate() { + if i != 0 { + path_str.push_str("::"); + } + if segment.ident.name != kw::PathRoot { + path_str.push_str(&segment.ident.as_str()) + } } + Symbol::intern(&path_str) } - path_str } impl<'a> base::Resolver for Resolver<'a> { @@ -219,14 +223,10 @@ impl<'a> base::Resolver for Resolver<'a> { }; let span = invoc.span(); - let path = fast_print_path(path); - let format = match kind { - MacroKind::Derive => format!("derive({})", path), - _ => path.clone(), - }; - invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); + let descr = fast_print_path(path); + invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, descr)); - self.check_stability_and_deprecation(&ext, &path, span); + self.check_stability_and_deprecation(&ext, descr, span); if let Res::Def(_, def_id) = res { if after_derive { @@ -991,7 +991,7 @@ impl<'a> Resolver<'a> { } } - fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) { + fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, descr: Symbol, span: Span) { if let Some(stability) = &ext.stability { if let StabilityLevel::Unstable { reason, issue } = stability.level { let feature = stability.feature; @@ -1000,14 +1000,14 @@ impl<'a> Resolver<'a> { } } if let Some(depr) = &stability.rustc_depr { - let (message, lint) = stability::rustc_deprecation_message(depr, path); + let (message, lint) = stability::rustc_deprecation_message(depr, &descr.as_str()); stability::early_report_deprecation( self.session, &message, depr.suggestion, lint, span ); } } if let Some(depr) = &ext.deprecation { - let (message, lint) = stability::deprecation_message(depr, path); + let (message, lint) = stability::deprecation_message(depr, &descr.as_str()); stability::early_report_deprecation(self.session, &message, None, lint, span); } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index aeaee1887b9..2c8f7a44f5a 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -843,7 +843,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let callee = span.source_callee()?; // Ignore attribute macros, their spans are usually mangled - if let ExpnKind::MacroAttribute(_) = callee.kind { + if let ExpnKind::Macro(MacroKind::Attr, _) | + ExpnKind::Macro(MacroKind::Derive, _) = callee.kind { return None; } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 2f8d6f00ba7..04f124685cb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -640,18 +640,10 @@ impl SyntaxExtension { } } - fn expn_kind(&self, descr: Symbol) -> ExpnKind { - match self.kind { - SyntaxExtensionKind::Bang(..) | - SyntaxExtensionKind::LegacyBang(..) => ExpnKind::MacroBang(descr), - _ => ExpnKind::MacroAttribute(descr), - } - } - - pub fn expn_info(&self, call_site: Span, descr: &str) -> ExpnInfo { + pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo { ExpnInfo { call_site, - kind: self.expn_kind(Symbol::intern(descr)), + kind: ExpnKind::Macro(self.macro_kind(), descr), def_site: self.span, default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 24050be792b..68e7225c3cf 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -1,7 +1,7 @@ use crate::attr::HasAttrs; use crate::ast; use crate::source_map::{ExpnInfo, ExpnKind}; -use crate::ext::base::ExtCtxt; +use crate::ext::base::{ExtCtxt, MacroKind}; use crate::ext::build::AstBuilder; use crate::parse::parser::PathStyle; use crate::symbol::{Symbol, sym}; @@ -46,7 +46,7 @@ pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::Path], item: &mut T) where T: HasAttrs, { - let (mut names, mut pretty_name) = (FxHashSet::default(), "derive(".to_owned()); + let (mut names, mut pretty_name) = (FxHashSet::default(), String::new()); for (i, path) in traits.iter().enumerate() { if i > 0 { pretty_name.push_str(", "); @@ -54,11 +54,10 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P pretty_name.push_str(&path.to_string()); names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); } - pretty_name.push(')'); cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::MacroAttribute(Symbol::intern(&pretty_name)), span, cx.parse_sess.edition, - &[sym::rustc_attrs, sym::structural_match], + ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span, + cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match], )); let span = span.with_ctxt(cx.backtrace()); diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 7ee073117e9..81f9ff9b661 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -1,7 +1,7 @@ use crate::ast; use crate::attr; use crate::edition::Edition; -use crate::ext::hygiene::{Mark, SyntaxContext}; +use crate::ext::hygiene::{Mark, SyntaxContext, MacroKind}; use crate::symbol::{Ident, Symbol, kw, sym}; use crate::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use crate::ptr::P; @@ -17,7 +17,8 @@ use syntax_pos::{DUMMY_SP, Span}; fn ignored_span(sp: Span, edition: Edition) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::MacroAttribute(Symbol::intern("std_inject")), sp, edition, &[sym::prelude_import] + ExpnKind::Macro(MacroKind::Attr, Symbol::intern("std_inject")), sp, edition, + &[sym::prelude_import], )); sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 35a1a552a13..7ec7bb6ff45 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -21,7 +21,7 @@ use crate::entry::{self, EntryPointType}; use crate::ext::base::{ExtCtxt, Resolver}; use crate::ext::build::AstBuilder; use crate::ext::expand::ExpansionConfig; -use crate::ext::hygiene::{self, Mark, SyntaxContext}; +use crate::ext::hygiene::{self, Mark, SyntaxContext, MacroKind}; use crate::mut_visit::{*, ExpectOne}; use crate::feature_gate::Features; use crate::util::map_in_place::MapInPlace; @@ -280,7 +280,7 @@ fn generate_test_harness(sess: &ParseSess, }; mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::MacroAttribute(sym::test_case), DUMMY_SP, sess.edition, + ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, sess.edition, &[sym::main, sym::test, sym::rustc_attrs], )); diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index dee8f4b3eb5..0733a8ec95c 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -5,7 +5,7 @@ use crate::deriving; use syntax::ast::{self, Ident}; use syntax::attr; use syntax::source_map::{ExpnInfo, ExpnKind, respan}; -use syntax::ext::base::ExtCtxt; +use syntax::ext::base::{ExtCtxt, MacroKind}; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::ext::hygiene::Mark; @@ -348,7 +348,7 @@ fn mk_decls( ) -> P { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::MacroAttribute(sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, + ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, &[sym::rustc_attrs, Symbol::intern("proc_macro_internals")], )); let span = DUMMY_SP.apply_mark(mark); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 67dcdabe701..28d452233cc 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -135,11 +135,9 @@ impl Mark { pub fn looks_like_proc_macro_derive(self) -> bool { HygieneData::with(|data| { if data.default_transparency(self) == Transparency::Opaque { - if let Some(expn_info) = &data.marks[self.0 as usize].expn_info { - if let ExpnKind::MacroAttribute(name) = expn_info.kind { - if name.as_str().starts_with("derive(") { - return true; - } + if let Some(expn_info) = data.expn_info(self) { + if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind { + return true; } } } @@ -193,7 +191,7 @@ impl HygieneData { } fn default_transparency(&self, mark: Mark) -> Transparency { - self.marks[mark.0 as usize].expn_info.as_ref().map_or( + self.expn_info(mark).map_or( Transparency::SemiTransparent, |einfo| einfo.default_transparency ) } @@ -613,7 +611,8 @@ impl fmt::Debug for SyntaxContext { } } -/// Extra information for tracking spans of macro and syntax sugar expansion +/// A subset of properties from both macro definition and macro call available through global data. +/// Avoid using this if you have access to the original definition or call structures. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ExpnInfo { // --- The part unique to each expansion. @@ -627,7 +626,7 @@ pub struct ExpnInfo { /// call_site span would have its own ExpnInfo, with the call_site /// pointing to the `foo!` invocation. pub call_site: Span, - /// The format with which the macro was invoked. + /// The kind of this expansion - macro or compiler desugaring. pub kind: ExpnKind, // --- The part specific to the macro/desugaring definition. @@ -675,13 +674,12 @@ impl ExpnInfo { } } -/// The source of expansion. +/// Expansion kind. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub enum ExpnKind { - /// e.g., #[derive(...)] - MacroAttribute(Symbol), - /// e.g., `format!()` - MacroBang(Symbol), + /// Expansion produced by a macro. + /// FIXME: Some code injected by the compiler before HIR lowering also gets this kind. + Macro(MacroKind, Symbol), /// Desugaring done by the compiler during HIR lowering. Desugaring(DesugaringKind) } @@ -689,8 +687,8 @@ pub enum ExpnKind { impl ExpnKind { pub fn descr(&self) -> Symbol { match *self { - ExpnKind::MacroBang(name) | ExpnKind::MacroAttribute(name) => name, - ExpnKind::Desugaring(kind) => kind.descr(), + ExpnKind::Macro(_, descr) => descr, + ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()), } } } @@ -743,8 +741,8 @@ pub enum DesugaringKind { } impl DesugaringKind { - pub fn descr(self) -> Symbol { - Symbol::intern(match self { + pub fn descr(self) -> &'static str { + match self { DesugaringKind::CondTemporary => "if and while condition", DesugaringKind::Async => "async", DesugaringKind::Await => "await", @@ -752,7 +750,7 @@ impl DesugaringKind { DesugaringKind::TryBlock => "try block", DesugaringKind::ExistentialType => "existential type", DesugaringKind::ForLoop => "for loop", - }) + } } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 1369fca3b4a..4fd27ce4f96 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -27,7 +27,7 @@ extern crate serialize as rustc_serialize; // used by deriving pub mod edition; use edition::Edition; pub mod hygiene; -pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind, DesugaringKind}; +pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind, MacroKind, DesugaringKind}; mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; @@ -442,9 +442,12 @@ impl Span { // Don't print recursive invocations. if !info.call_site.source_equal(&prev_span) { let (pre, post) = match info.kind { - ExpnKind::MacroAttribute(..) => ("#[", "]"), - ExpnKind::MacroBang(..) => ("", "!"), ExpnKind::Desugaring(..) => ("desugaring of `", "`"), + ExpnKind::Macro(macro_kind, _) => match macro_kind { + MacroKind::Bang => ("", "!"), + MacroKind::Attr => ("#[", "]"), + MacroKind::Derive => ("#[derive(", ")]"), + } }; result.push(MacroBacktrace { call_site: info.call_site, -- cgit 1.4.1-3-g733a5 From cd0fd630e8170f8770485cb8248ff3d823521523 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Jul 2019 01:44:04 +0300 Subject: resolve: Make proc macro stubs less stubby Create real working and registered (even if dummy) `SyntaxExtension`s for them. This improves error recovery and allows to avoid all special cases for proc macro stubs (except for the error on use, of course). The introduced dummy `SyntaxExtension`s can be used for any other inappropriately resolved macros as well. --- src/librustc_resolve/build_reduced_graph.rs | 18 +---- src/librustc_resolve/lib.rs | 21 ++++-- src/librustc_resolve/macros.rs | 76 +++++++++++++++------- src/libsyntax/ext/base.rs | 22 ++++++- .../ui/proc-macro/macro-namespace-reserved-2.rs | 10 +-- .../proc-macro/macro-namespace-reserved-2.stderr | 66 ++++++++++++------- 6 files changed, 138 insertions(+), 75 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 8515029193e..6fdd0c3ff3e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -46,20 +46,6 @@ use log::debug; type Res = def::Res; -fn proc_macro_stub(item: &Item) -> Option<(Ident, Span)> { - if attr::contains_name(&item.attrs, sym::proc_macro) || - attr::contains_name(&item.attrs, sym::proc_macro_attribute) { - return Some((item.ident, item.span)); - } else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { - if let Some(nested_meta) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { - if let Some(ident) = nested_meta.ident() { - return Some((ident, ident.span)); - } - } - } - None -} - impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { @@ -470,9 +456,7 @@ impl<'a> Resolver<'a> { // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). - if let Some((ident, span)) = proc_macro_stub(item) { - self.define(parent, ident, MacroNS, (res, vis, span, expansion)); - } + self.define_macro(item, expansion, &mut LegacyScope::Empty); } // These items live in the type namespace. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 09d7d8ace6b..b6c26b1a721 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -40,7 +40,7 @@ use rustc_metadata::cstore::CStore; use syntax::source_map::SourceMap; use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext}; use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; -use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; +use syntax::ext::base::SyntaxExtension; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::MacroKind; use syntax::symbol::{Symbol, kw, sym}; @@ -1663,10 +1663,13 @@ pub struct Resolver<'a> { macro_use_prelude: FxHashMap>, pub all_macros: FxHashMap, macro_map: FxHashMap>, + dummy_ext_bang: Lrc, + dummy_ext_derive: Lrc, non_macro_attrs: [Lrc; 2], macro_defs: FxHashMap, local_macro_def_scopes: FxHashMap>, unused_macros: NodeMap, + proc_macro_stubs: NodeSet, /// Maps the `Mark` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -1925,9 +1928,8 @@ impl<'a> Resolver<'a> { macro_defs.insert(Mark::root(), root_def_id); let features = session.features_untracked(); - let non_macro_attr = |mark_used| Lrc::new(SyntaxExtension::default( - SyntaxExtensionKind::NonMacroAttr { mark_used }, session.edition() - )); + let non_macro_attr = + |mark_used| Lrc::new(SyntaxExtension::non_macro_attr(mark_used, session.edition())); Resolver { session, @@ -2002,6 +2004,8 @@ impl<'a> Resolver<'a> { macro_use_prelude: FxHashMap::default(), all_macros: FxHashMap::default(), macro_map: FxHashMap::default(), + dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())), + dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())), non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)], invocations, macro_defs, @@ -2010,6 +2014,7 @@ impl<'a> Resolver<'a> { potentially_unused_imports: Vec::new(), struct_constructors: Default::default(), unused_macros: Default::default(), + proc_macro_stubs: Default::default(), current_type_ascription: Vec::new(), injected_crate: None, active_features: @@ -2027,6 +2032,14 @@ impl<'a> Resolver<'a> { self.non_macro_attrs[mark_used as usize].clone() } + fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc { + match macro_kind { + MacroKind::Bang => self.dummy_ext_bang.clone(), + MacroKind::Derive => self.dummy_ext_derive.clone(), + MacroKind::Attr => self.non_macro_attr(true), + } + } + /// Runs the function on each namespace. fn per_ns(&mut self, mut f: F) { f(self, TypeNS); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 8361bbe45c4..20eb97c15ba 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -11,7 +11,7 @@ use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::DefCollector; use rustc::middle::stability; use rustc::{ty, lint, span_bug}; -use syntax::ast::{self, Ident}; +use syntax::ast::{self, Ident, ItemKind}; use syntax::attr::{self, StabilityLevel}; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; @@ -127,6 +127,21 @@ fn fast_print_path(path: &ast::Path) -> Symbol { } } +fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { + if attr::contains_name(&item.attrs, sym::proc_macro) { + return Some((MacroKind::Bang, item.ident, item.span)); + } else if attr::contains_name(&item.attrs, sym::proc_macro_attribute) { + return Some((MacroKind::Attr, item.ident, item.span)); + } else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) { + if let Some(nested_meta) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { + if let Some(ident) = nested_meta.ident() { + return Some((MacroKind::Derive, ident, ident.span)); + } + } + } + None +} + impl<'a> base::Resolver for Resolver<'a> { fn next_node_id(&mut self) -> ast::NodeId { self.session.next_node_id() @@ -216,10 +231,9 @@ impl<'a> base::Resolver for Resolver<'a> { let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); let (res, ext) = match self.resolve_macro_to_res(path, kind, &parent_scope, true, force) { Ok((res, ext)) => (res, ext), - // Replace unresolved attributes with used inert attributes for better recovery. - Err(Determinacy::Determined) if kind == MacroKind::Attr => - (Res::Err, self.non_macro_attr(true)), - Err(determinacy) => return Err(determinacy), + // Return dummy syntax extensions for unresolved macros for better recovery. + Err(Determinacy::Determined) => (Res::Err, self.dummy_ext(kind)), + Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), }; let span = invoc.span(); @@ -305,13 +319,14 @@ impl<'a> Resolver<'a> { Res::Def(DefKind::Macro(_), def_id) => { if let Some(node_id) = self.definitions.as_local_node_id(def_id) { self.unused_macros.remove(&node_id); + if self.proc_macro_stubs.contains(&node_id) { + self.session.span_err( + path.span, + "can't use a procedural macro from the same crate that defines it", + ); + } } } - Res::Def(DefKind::Fn, _) => { - let msg = "can't use a procedural macro from the same crate that defines it"; - self.session.span_err(path.span, msg); - return Err(Determinacy::Determined); - } Res::NonMacroAttr(attr_kind) => { if kind == MacroKind::Attr { if attr_kind == NonMacroAttrKind::Custom { @@ -1100,19 +1115,32 @@ impl<'a> Resolver<'a> { item: &ast::Item, expansion: Mark, current_legacy_scope: &mut LegacyScope<'a>) { - self.local_macro_def_scopes.insert(item.id, self.current_module); - let ident = item.ident; + let (ext, ident, span, is_legacy) = match &item.node { + ItemKind::MacroDef(def) => { + let ext = Lrc::new(macro_rules::compile( + &self.session.parse_sess, + &self.session.features_untracked(), + item, + self.session.edition(), + )); + (ext, item.ident, item.span, def.legacy) + } + ItemKind::Fn(..) => match proc_macro_stub(item) { + Some((macro_kind, ident, span)) => { + self.proc_macro_stubs.insert(item.id); + (self.dummy_ext(macro_kind), ident, span, false) + } + None => return, + } + _ => unreachable!(), + }; let def_id = self.definitions.local_def_id(item.id); - let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess, - &self.session.features_untracked(), - item, self.session.edition())); - let macro_kind = ext.macro_kind(); - let res = Res::Def(DefKind::Macro(macro_kind), def_id); + let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id); self.macro_map.insert(def_id, ext); + self.local_macro_def_scopes.insert(item.id, self.current_module); - let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() }; - if def.legacy { + if is_legacy { let ident = ident.modern(); self.macro_names.insert(ident); let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export); @@ -1121,7 +1149,7 @@ impl<'a> Resolver<'a> { } else { ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) }; - let binding = (res, vis, item.span, expansion).to_name_binding(self.arenas); + let binding = (res, vis, span, expansion).to_name_binding(self.arenas); self.set_binding_parent_module(binding, self.current_module); let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding { parent_legacy_scope: *current_legacy_scope, binding, ident @@ -1131,18 +1159,18 @@ impl<'a> Resolver<'a> { if is_macro_export { let module = self.graph_root; self.define(module, ident, MacroNS, - (res, vis, item.span, expansion, IsMacroExport)); + (res, vis, span, expansion, IsMacroExport)); } else { self.check_reserved_macro_name(ident, res); - self.unused_macros.insert(item.id, item.span); + self.unused_macros.insert(item.id, span); } } else { let module = self.current_module; let vis = self.resolve_visibility(&item.vis); if vis != ty::Visibility::Public { - self.unused_macros.insert(item.id, item.span); + self.unused_macros.insert(item.id, span); } - self.define(module, ident, MacroNS, (res, vis, item.span, expansion)); + self.define(module, ident, MacroNS, (res, vis, span, expansion)); } } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 04f124685cb..82386b78f1d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -10,7 +10,7 @@ use crate::parse::token; use crate::ptr::P; use crate::symbol::{kw, sym, Ident, Symbol}; use crate::{ThinVec, MACRO_ARGUMENTS}; -use crate::tokenstream::{self, TokenStream}; +use crate::tokenstream::{self, TokenStream, TokenTree}; use errors::{DiagnosticBuilder, DiagnosticId}; use smallvec::{smallvec, SmallVec}; @@ -640,6 +640,26 @@ impl SyntaxExtension { } } + pub fn dummy_bang(edition: Edition) -> SyntaxExtension { + fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree]) + -> Box { + DummyResult::any(span) + } + SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition) + } + + pub fn dummy_derive(edition: Edition) -> SyntaxExtension { + fn expander(_: &mut ExtCtxt<'_>, _: Span, _: &ast::MetaItem, _: Annotatable) + -> Vec { + Vec::new() + } + SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition) + } + + pub fn non_macro_attr(mark_used: bool, edition: Edition) -> SyntaxExtension { + SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition) + } + pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo { ExpnInfo { call_site, diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index 583640aa817..c7b092830a2 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -25,22 +25,24 @@ fn check_bang1() { my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it } fn check_bang2() { - my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines it + my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope } fn check_bang3() { - MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it + MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope } -#[my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it +#[my_macro] //~ ERROR attribute `my_macro` is currently unknown fn check_attr1() {} #[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it fn check_attr2() {} #[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR `MyTrait` is a derive macro fn check_attr3() {} -#[derive(my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines it +#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope struct CheckDerive1; #[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR macro `my_macro_attr` may not be used for derive attributes struct CheckDerive2; #[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it struct CheckDerive3; diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 548f9e3051d..83c77513ec3 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -4,24 +4,6 @@ error: can't use a procedural macro from the same crate that defines it LL | my_macro!(); | ^^^^^^^^ -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:28:5 - | -LL | my_macro_attr!(); - | ^^^^^^^^^^^^^ - -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:31:5 - | -LL | MyTrait!(); - | ^^^^^^^ - -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:34:3 - | -LL | #[my_macro] - | ^^^^^^^^ - error: can't use a procedural macro from the same crate that defines it --> $DIR/macro-namespace-reserved-2.rs:36:3 | @@ -34,23 +16,57 @@ error: can't use a procedural macro from the same crate that defines it LL | #[MyTrait] | ^^^^^^^ -error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:41:10 +error: `MyTrait` is a derive macro + --> $DIR/macro-namespace-reserved-2.rs:38:1 | -LL | #[derive(my_macro)] - | ^^^^^^^^ +LL | #[MyTrait] + | ^^^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:43:10 + --> $DIR/macro-namespace-reserved-2.rs:44:10 + | +LL | #[derive(my_macro_attr)] + | ^^^^^^^^^^^^^ + +error: macro `my_macro_attr` may not be used for derive attributes + --> $DIR/macro-namespace-reserved-2.rs:44:10 | LL | #[derive(my_macro_attr)] | ^^^^^^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:45:10 + --> $DIR/macro-namespace-reserved-2.rs:47:10 | LL | #[derive(MyTrait)] | ^^^^^^^ -error: aborting due to 9 previous errors +error[E0658]: The attribute `my_macro` is currently unknown to the compiler and may have meaning added to it in the future + --> $DIR/macro-namespace-reserved-2.rs:34:3 + | +LL | #[my_macro] + | ^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: cannot find derive macro `my_macro` in this scope + --> $DIR/macro-namespace-reserved-2.rs:42:10 + | +LL | #[derive(my_macro)] + | ^^^^^^^^ + +error: cannot find macro `my_macro_attr!` in this scope + --> $DIR/macro-namespace-reserved-2.rs:28:5 + | +LL | my_macro_attr!(); + | ^^^^^^^^^^^^^ + +error: cannot find macro `MyTrait!` in this scope + --> $DIR/macro-namespace-reserved-2.rs:31:5 + | +LL | MyTrait!(); + | ^^^^^^^ + +error: aborting due to 11 previous errors +For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From f16993d4acaf90285f6c86268a0ec2e7167c2a58 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Jul 2019 11:44:57 +0300 Subject: resolve/expand: `resolve_macro_invocation` no longer returns determinate errors It either returns the indeterminacy error, or valid (but perhaps dummy) `SyntaxExtension`. With this change enum `Determinacy` is no longer used in libsyntax and can be moved to resolve. The regressions in diagnosics are fixed in the next commits. --- src/librustc_resolve/build_reduced_graph.rs | 9 +- src/librustc_resolve/lib.rs | 14 ++- src/librustc_resolve/macros.rs | 66 +++++------- src/librustc_resolve/resolve_imports.rs | 2 +- src/libsyntax/ext/base.rs | 17 +--- src/libsyntax/ext/expand.rs | 111 ++++++++++----------- src/test/ui/macros/macro-path-prelude-fail-4.rs | 2 +- .../ui/macros/macro-path-prelude-fail-4.stderr | 2 +- .../tool-attributes/tool-attributes-misplaced-2.rs | 4 +- .../tool-attributes-misplaced-2.stderr | 4 +- 10 files changed, 108 insertions(+), 123 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 6fdd0c3ff3e..f74d07a3c5e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -9,7 +9,7 @@ use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleIm use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; use crate::{ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; use crate::Namespace::{self, TypeNS, ValueNS, MacroNS}; -use crate::{resolve_error, resolve_struct_error, ResolutionError}; +use crate::{resolve_error, resolve_struct_error, ResolutionError, Determinacy}; use rustc::bug; use rustc::hir::def::{self, *}; @@ -30,7 +30,6 @@ use syntax::attr; use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant}; use syntax::ext::base::SyntaxExtension; -use syntax::ext::base::Determinacy::Undetermined; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; use syntax::feature_gate::is_builtin_attr; @@ -231,9 +230,9 @@ impl<'a> Resolver<'a> { source: source.ident, target: ident, source_bindings: PerNS { - type_ns: Cell::new(Err(Undetermined)), - value_ns: Cell::new(Err(Undetermined)), - macro_ns: Cell::new(Err(Undetermined)), + type_ns: Cell::new(Err(Determinacy::Undetermined)), + value_ns: Cell::new(Err(Determinacy::Undetermined)), + macro_ns: Cell::new(Err(Determinacy::Undetermined)), }, target_bindings: PerNS { type_ns: Cell::new(None), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b6c26b1a721..795ff3faffa 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -15,6 +15,7 @@ pub use rustc::hir::def::{Namespace, PerNS}; +use Determinacy::*; use GenericParameters::*; use RibKind::*; use smallvec::smallvec; @@ -41,7 +42,6 @@ use syntax::source_map::SourceMap; use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext}; use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; use syntax::ext::base::SyntaxExtension; -use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::MacroKind; use syntax::symbol::{Symbol, kw, sym}; use syntax::util::lev_distance::find_best_match_for_name; @@ -93,6 +93,18 @@ enum Weak { No, } +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Determinacy { + Determined, + Undetermined, +} + +impl Determinacy { + fn determined(determined: bool) -> Determinacy { + if determined { Determinacy::Determined } else { Determinacy::Undetermined } + } +} + enum ScopeSet { Import(Namespace), AbsolutePath(Namespace), diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 20eb97c15ba..905b3347a54 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1,4 +1,4 @@ -use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; +use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy}; use crate::{CrateLint, Resolver, ResolutionError, ScopeSet, Weak}; use crate::{Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding}; use crate::{is_known_tool, resolve_error}; @@ -14,7 +14,7 @@ use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident, ItemKind}; use syntax::attr::{self, StabilityLevel}; use syntax::errors::DiagnosticBuilder; -use syntax::ext::base::{self, Determinacy}; +use syntax::ext::base::{self, Indeterminate}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; @@ -216,7 +216,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool) - -> Result>, Determinacy> { + -> Result>, Indeterminate> { let (path, kind, derives_in_scope, after_derive) = match invoc.kind { InvocationKind::Attr { attr: None, .. } => return Ok(None), @@ -229,12 +229,7 @@ impl<'a> base::Resolver for Resolver<'a> { }; let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); - let (res, ext) = match self.resolve_macro_to_res(path, kind, &parent_scope, true, force) { - Ok((res, ext)) => (res, ext), - // Return dummy syntax extensions for unresolved macros for better recovery. - Err(Determinacy::Determined) => (Res::Err, self.dummy_ext(kind)), - Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), - }; + let (res, ext) = self.resolve_macro_to_res(path, kind, &parent_scope, true, force)?; let span = invoc.span(); let descr = fast_print_path(path); @@ -287,7 +282,7 @@ impl<'a> Resolver<'a> { parent_scope: &ParentScope<'a>, trace: bool, force: bool, - ) -> Result<(Res, Lrc), Determinacy> { + ) -> Result<(Res, Lrc), Indeterminate> { let res = self.resolve_macro_to_res_inner(path, kind, parent_scope, trace, force); // Report errors and enforce feature gates for the resolved macro. @@ -313,7 +308,14 @@ impl<'a> Resolver<'a> { } } - let res = res?; + let res = match res { + Err(Determinacy::Undetermined) => return Err(Indeterminate), + Ok(Res::Err) | Err(Determinacy::Determined) => { + // Return dummy syntax extensions for unresolved macros for better recovery. + return Ok((Res::Err, self.dummy_ext(kind))); + } + Ok(res) => res, + }; match res { Res::Def(DefKind::Macro(_), def_id) => { @@ -328,35 +330,23 @@ impl<'a> Resolver<'a> { } } Res::NonMacroAttr(attr_kind) => { - if kind == MacroKind::Attr { - if attr_kind == NonMacroAttrKind::Custom { - assert!(path.segments.len() == 1); - if !features.custom_attribute { - let msg = format!("The attribute `{}` is currently unknown to the \ - compiler and may have meaning added to it in the \ - future", path); - self.report_unknown_attribute( - path.span, - &path.segments[0].ident.as_str(), - &msg, - sym::custom_attribute, - ); - } + if attr_kind == NonMacroAttrKind::Custom { + assert!(path.segments.len() == 1); + if !features.custom_attribute { + let msg = format!("The attribute `{}` is currently unknown to the \ + compiler and may have meaning added to it in the \ + future", path); + self.report_unknown_attribute( + path.span, + &path.segments[0].ident.as_str(), + &msg, + sym::custom_attribute, + ); } - } else { - // Not only attributes, but anything in macro namespace can result in - // `Res::NonMacroAttr` definition (e.g., `inline!()`), so we must report - // an error for those cases. - let msg = format!("expected a macro, found {}", res.descr()); - self.session.span_err(path.span, &msg); - return Err(Determinacy::Determined); } } - Res::Err => { - return Err(Determinacy::Determined); - } _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"), - } + }; Ok((res, self.get_macro(res))) } @@ -608,9 +598,7 @@ impl<'a> Resolver<'a> { result = Ok((binding, Flags::empty())); break; } - Err(Determinacy::Determined) => {} - Err(Determinacy::Undetermined) => - result = Err(Determinacy::Undetermined), + Err(Indeterminate) => result = Err(Determinacy::Undetermined), } } result diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 7de1cd29a9c..5edfe923e68 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -2,6 +2,7 @@ use ImportDirectiveSubclass::*; use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, Weak}; +use crate::Determinacy::{self, *}; use crate::Namespace::{self, TypeNS, MacroNS}; use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use crate::{Resolver, Segment}; @@ -27,7 +28,6 @@ use rustc::util::nodemap::FxHashSet; use rustc::{bug, span_bug}; use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID}; -use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::hygiene::Mark; use syntax::symbol::kw; use syntax::util::lev_distance::find_best_match_for_name; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 82386b78f1d..cb4edee30cd 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -676,6 +676,9 @@ impl SyntaxExtension { pub type NamedSyntaxExtension = (Name, SyntaxExtension); +/// Error type that denotes indeterminacy. +pub struct Indeterminate; + pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; @@ -689,23 +692,11 @@ pub trait Resolver { fn resolve_imports(&mut self); fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool) - -> Result>, Determinacy>; + -> Result>, Indeterminate>; fn check_unused_macros(&self); } -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum Determinacy { - Determined, - Undetermined, -} - -impl Determinacy { - pub fn determined(determined: bool) -> Determinacy { - if determined { Determinacy::Determined } else { Determinacy::Undetermined } - } -} - #[derive(Clone)] pub struct ModuleData { pub mod_path: Vec, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 06ff2bc655c..2f7fb79a7f5 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -313,9 +313,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let scope = if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark }; let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) { - Ok(ext) => Some(ext), - Err(Determinacy::Determined) => None, - Err(Determinacy::Undetermined) => { + Ok(ext) => ext, + Err(Indeterminate) => { undetermined_invocations.push(invoc); continue } @@ -328,65 +327,61 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.current_expansion.mark = scope; // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { - if let Some(ext) = ext { - let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span()); - let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| { - invoc_fragment_kind.dummy(invoc_span).unwrap() - }); - self.collect_invocations(fragment, &[]) - } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { - if !item.derive_allowed() { - let attr = attr::find_by_name(item.attrs(), sym::derive) - .expect("`derive` attribute should exist"); - let span = attr.span; - let mut err = self.cx.mut_span_err(span, - "`derive` may only be applied to \ - structs, enums and unions"); - if let ast::AttrStyle::Inner = attr.style { - let trait_list = traits.iter() - .map(|t| t.to_string()).collect::>(); - let suggestion = format!("#[derive({})]", trait_list.join(", ")); - err.span_suggestion( - span, "try an outer attribute", suggestion, - // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT - Applicability::MaybeIncorrect - ); - } - err.emit(); + let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span()); + let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| { + invoc_fragment_kind.dummy(invoc_span).unwrap() + }); + self.collect_invocations(fragment, &[]) + } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { + if !item.derive_allowed() { + let attr = attr::find_by_name(item.attrs(), sym::derive) + .expect("`derive` attribute should exist"); + let span = attr.span; + let mut err = self.cx.mut_span_err(span, + "`derive` may only be applied to \ + structs, enums and unions"); + if let ast::AttrStyle::Inner = attr.style { + let trait_list = traits.iter() + .map(|t| t.to_string()).collect::>(); + let suggestion = format!("#[derive({})]", trait_list.join(", ")); + err.span_suggestion( + span, "try an outer attribute", suggestion, + // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT + Applicability::MaybeIncorrect + ); } + err.emit(); + } - let mut item = self.fully_configure(item); - item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); - let mut item_with_markers = item.clone(); - add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); - let derives = derives.entry(invoc.expansion_data.mark).or_default(); - - derives.reserve(traits.len()); - invocations.reserve(traits.len()); - for path in traits { - let mark = Mark::fresh(self.cx.current_expansion.mark); - derives.push(mark); - invocations.push(Invocation { - kind: InvocationKind::Derive { - path, - item: item.clone(), - item_with_markers: item_with_markers.clone(), - }, - fragment_kind: invoc.fragment_kind, - expansion_data: ExpansionData { - mark, - ..invoc.expansion_data.clone() - }, - }); - } - let fragment = invoc.fragment_kind - .expect_from_annotatables(::std::iter::once(item_with_markers)); - self.collect_invocations(fragment, derives) - } else { - unreachable!() + let mut item = self.fully_configure(item); + item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive)); + let mut item_with_markers = item.clone(); + add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers); + let derives = derives.entry(invoc.expansion_data.mark).or_default(); + + derives.reserve(traits.len()); + invocations.reserve(traits.len()); + for path in traits { + let mark = Mark::fresh(self.cx.current_expansion.mark); + derives.push(mark); + invocations.push(Invocation { + kind: InvocationKind::Derive { + path, + item: item.clone(), + item_with_markers: item_with_markers.clone(), + }, + fragment_kind: invoc.fragment_kind, + expansion_data: ExpansionData { + mark, + ..invoc.expansion_data.clone() + }, + }); } + let fragment = invoc.fragment_kind + .expect_from_annotatables(::std::iter::once(item_with_markers)); + self.collect_invocations(fragment, derives) } else { - self.collect_invocations(invoc.fragment_kind.dummy(invoc.span()).unwrap(), &[]) + unreachable!() }; if expanded_fragments.len() < depth { diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.rs b/src/test/ui/macros/macro-path-prelude-fail-4.rs index 283427b9ace..44f0f2d7ec0 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.rs +++ b/src/test/ui/macros/macro-path-prelude-fail-4.rs @@ -1,4 +1,4 @@ -#[derive(inline)] //~ ERROR expected a macro, found built-in attribute +#[derive(inline)] //~ ERROR macro `inline` may not be used for derive attributes struct S; fn main() {} diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.stderr b/src/test/ui/macros/macro-path-prelude-fail-4.stderr index f08445e1f77..fdd7bf3235c 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-4.stderr @@ -1,4 +1,4 @@ -error: expected a macro, found built-in attribute +error: macro `inline` may not be used for derive attributes --> $DIR/macro-path-prelude-fail-4.rs:1:10 | LL | #[derive(inline)] diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs index 56b908d94cc..b95791f4e99 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -1,6 +1,6 @@ -#[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute +#[derive(rustfmt::skip)] //~ ERROR macro `rustfmt::skip` may not be used for derive attributes struct S; fn main() { - rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute + rustfmt::skip!(); //~ ERROR `rustfmt::skip` can only be used in attributes } diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr index c5f5f59c32c..8ef27a07b7f 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr @@ -1,10 +1,10 @@ -error: expected a macro, found tool attribute +error: macro `rustfmt::skip` may not be used for derive attributes --> $DIR/tool-attributes-misplaced-2.rs:1:10 | LL | #[derive(rustfmt::skip)] | ^^^^^^^^^^^^^ -error: expected a macro, found tool attribute +error: `rustfmt::skip` can only be used in attributes --> $DIR/tool-attributes-misplaced-2.rs:5:5 | LL | rustfmt::skip!(); -- cgit 1.4.1-3-g733a5 From 3041ec61185d6f9795ff16cc345e8f11b06edbbf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Jul 2019 12:47:24 +0300 Subject: resolve/expand: Catch macro kind mismatches early in resolve This way we are processing all of them in a single point, rather than separately for each syntax extension kind. Also, the standard expected/found wording is used. --- src/librustc_resolve/macros.rs | 13 +++- src/libsyntax/ext/expand.rs | 39 ++--------- .../ui/feature-gates/feature-gate-rustc-attrs.rs | 4 +- .../feature-gates/feature-gate-rustc-attrs.stderr | 12 ++-- src/test/ui/macros/macro-path-prelude-fail-4.rs | 2 +- .../ui/macros/macro-path-prelude-fail-4.stderr | 4 +- .../ui/proc-macro/macro-namespace-reserved-2.rs | 12 +++- .../proc-macro/macro-namespace-reserved-2.stderr | 76 ++++++++++++++++++---- .../tool-attributes/tool-attributes-misplaced-2.rs | 4 +- .../tool-attributes-misplaced-2.stderr | 8 +-- 10 files changed, 106 insertions(+), 68 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 905b3347a54..30969948c4c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -348,7 +348,18 @@ impl<'a> Resolver<'a> { _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"), }; - Ok((res, self.get_macro(res))) + let ext = self.get_macro(res); + Ok(if ext.macro_kind() != kind { + let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() }; + let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path); + self.session.struct_span_err(path.span, &msg) + .span_label(path.span, format!("not {} {}", kind.article(), expected)) + .emit(); + // Return dummy syntax extensions for unexpected macro kinds for better recovery. + (Res::Err, self.dummy_ext(kind)) + } else { + (res, ext) + }) } fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2f7fb79a7f5..2349382eb5e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -323,12 +323,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { progress = true; let ExpansionData { depth, mark, .. } = invoc.expansion_data; self.cx.current_expansion = invoc.expansion_data.clone(); - self.cx.current_expansion.mark = scope; + // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span()); - let fragment = self.expand_invoc(invoc, &*ext).unwrap_or_else(|| { + let fragment = self.expand_invoc(invoc, &ext).unwrap_or_else(|| { invoc_fragment_kind.dummy(invoc_span).unwrap() }); self.collect_invocations(fragment, &[]) @@ -551,17 +551,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.gate_proc_macro_expansion(attr.span, &res); res } - SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => { - self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(attr.span) - } - _ => { - let msg = &format!("macro `{}` may not be used in attributes", attr.path); - self.cx.span_err(attr.span, msg); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(attr.span) - } + _ => unreachable!() } } @@ -671,21 +661,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let tok_result = expander.expand(self.cx, span, mac.node.stream()); kind.make_from(tok_result) } - - SyntaxExtensionKind::Attr(..) | - SyntaxExtensionKind::LegacyAttr(..) | - SyntaxExtensionKind::NonMacroAttr { .. } => { - self.cx.span_err(path.span, - &format!("`{}` can only be used in attributes", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } - - SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => { - self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } + _ => unreachable!() }; if opt_expanded.is_some() { @@ -747,12 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let items = expander.expand(self.cx, span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(items)) } - _ => { - let msg = &format!("macro `{}` may not be used for derive attributes", path); - self.cx.span_err(path.span, msg); - self.cx.trace_macros_diag(); - invoc.fragment_kind.dummy(path.span) - } + _ => unreachable!() } } diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index d3a2e486416..9ce2fb58ab0 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -7,12 +7,12 @@ mod unknown { pub macro rustc() {} } #[rustc::unknown] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler -//~| ERROR macro `rustc::unknown` may not be used in attributes +//~| ERROR expected attribute, found macro `rustc::unknown` fn f() {} #[unknown::rustc] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler -//~| ERROR macro `unknown::rustc` may not be used in attributes +//~| ERROR expected attribute, found macro `unknown::rustc` fn g() {} #[rustc_dummy] diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index f098635c702..7c5aa5381e8 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -7,11 +7,11 @@ LL | #[rustc::unknown] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error: macro `rustc::unknown` may not be used in attributes - --> $DIR/feature-gate-rustc-attrs.rs:8:1 +error: expected attribute, found macro `rustc::unknown` + --> $DIR/feature-gate-rustc-attrs.rs:8:3 | LL | #[rustc::unknown] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not an attribute error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/feature-gate-rustc-attrs.rs:13:12 @@ -22,11 +22,11 @@ LL | #[unknown::rustc] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error: macro `unknown::rustc` may not be used in attributes - --> $DIR/feature-gate-rustc-attrs.rs:13:1 +error: expected attribute, found macro `unknown::rustc` + --> $DIR/feature-gate-rustc-attrs.rs:13:3 | LL | #[unknown::rustc] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not an attribute error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler --> $DIR/feature-gate-rustc-attrs.rs:20:3 diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.rs b/src/test/ui/macros/macro-path-prelude-fail-4.rs index 44f0f2d7ec0..0f93fcdaa5f 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.rs +++ b/src/test/ui/macros/macro-path-prelude-fail-4.rs @@ -1,4 +1,4 @@ -#[derive(inline)] //~ ERROR macro `inline` may not be used for derive attributes +#[derive(inline)] //~ ERROR expected derive macro, found built-in attribute `inline` struct S; fn main() {} diff --git a/src/test/ui/macros/macro-path-prelude-fail-4.stderr b/src/test/ui/macros/macro-path-prelude-fail-4.stderr index fdd7bf3235c..dfd6818b678 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-4.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-4.stderr @@ -1,8 +1,8 @@ -error: macro `inline` may not be used for derive attributes +error: expected derive macro, found built-in attribute `inline` --> $DIR/macro-path-prelude-fail-4.rs:1:10 | LL | #[derive(inline)] - | ^^^^^^ + | ^^^^^^ not a derive macro error: aborting due to previous error diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs index c7b092830a2..7a9e472c6c3 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs @@ -26,23 +26,31 @@ fn check_bang1() { } fn check_bang2() { my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope + crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines + //~| ERROR expected macro, found attribute macro `crate::my_macro_attr` } fn check_bang3() { MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope + crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected macro, found derive macro `crate::MyTrait` } #[my_macro] //~ ERROR attribute `my_macro` is currently unknown +#[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it + //~| ERROR expected attribute, found macro `crate::my_macro` fn check_attr1() {} #[my_macro_attr] //~ ERROR can't use a procedural macro from the same crate that defines it fn check_attr2() {} #[MyTrait] //~ ERROR can't use a procedural macro from the same crate that defines it - //~| ERROR `MyTrait` is a derive macro + //~| ERROR expected attribute, found derive macro `MyTrait` fn check_attr3() {} #[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope +#[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines + //~| ERROR expected derive macro, found macro `crate::my_macro` struct CheckDerive1; #[derive(my_macro_attr)] //~ ERROR can't use a procedural macro from the same crate that defines it - //~| ERROR macro `my_macro_attr` may not be used for derive attributes + //~| ERROR expected derive macro, found attribute macro `my_macro_attr` struct CheckDerive2; #[derive(MyTrait)] //~ ERROR can't use a procedural macro from the same crate that defines it struct CheckDerive3; diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr index 83c77513ec3..a724d388f48 100644 --- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -5,43 +5,79 @@ LL | my_macro!(); | ^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:36:3 + --> $DIR/macro-namespace-reserved-2.rs:29:5 + | +LL | crate::my_macro_attr!(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: expected macro, found attribute macro `crate::my_macro_attr` + --> $DIR/macro-namespace-reserved-2.rs:29:5 + | +LL | crate::my_macro_attr!(); + | ^^^^^^^^^^^^^^^^^^^^ not a macro + +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:34:5 + | +LL | crate::MyTrait!(); + | ^^^^^^^^^^^^^^ + +error: expected macro, found derive macro `crate::MyTrait` + --> $DIR/macro-namespace-reserved-2.rs:34:5 + | +LL | crate::MyTrait!(); + | ^^^^^^^^^^^^^^ not a macro + +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:42:3 | LL | #[my_macro_attr] | ^^^^^^^^^^^^^ error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:38:3 + --> $DIR/macro-namespace-reserved-2.rs:44:3 | LL | #[MyTrait] | ^^^^^^^ -error: `MyTrait` is a derive macro - --> $DIR/macro-namespace-reserved-2.rs:38:1 +error: expected attribute, found derive macro `MyTrait` + --> $DIR/macro-namespace-reserved-2.rs:44:3 | LL | #[MyTrait] - | ^^^^^^^^^^ + | ^^^^^^^ not an attribute error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:44:10 + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ + +error: expected derive macro, found macro `crate::my_macro` + --> $DIR/macro-namespace-reserved-2.rs:49:10 + | +LL | #[derive(crate::my_macro)] + | ^^^^^^^^^^^^^^^ not a derive macro + +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:52:10 | LL | #[derive(my_macro_attr)] | ^^^^^^^^^^^^^ -error: macro `my_macro_attr` may not be used for derive attributes - --> $DIR/macro-namespace-reserved-2.rs:44:10 +error: expected derive macro, found attribute macro `my_macro_attr` + --> $DIR/macro-namespace-reserved-2.rs:52:10 | LL | #[derive(my_macro_attr)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a derive macro error: can't use a procedural macro from the same crate that defines it - --> $DIR/macro-namespace-reserved-2.rs:47:10 + --> $DIR/macro-namespace-reserved-2.rs:55:10 | LL | #[derive(MyTrait)] | ^^^^^^^ error[E0658]: The attribute `my_macro` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/macro-namespace-reserved-2.rs:34:3 + --> $DIR/macro-namespace-reserved-2.rs:38:3 | LL | #[my_macro] | ^^^^^^^^ @@ -49,8 +85,20 @@ LL | #[my_macro] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add #![feature(custom_attribute)] to the crate attributes to enable +error: can't use a procedural macro from the same crate that defines it + --> $DIR/macro-namespace-reserved-2.rs:39:3 + | +LL | #[crate::my_macro] + | ^^^^^^^^^^^^^^^ + +error: expected attribute, found macro `crate::my_macro` + --> $DIR/macro-namespace-reserved-2.rs:39:3 + | +LL | #[crate::my_macro] + | ^^^^^^^^^^^^^^^ not an attribute + error: cannot find derive macro `my_macro` in this scope - --> $DIR/macro-namespace-reserved-2.rs:42:10 + --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] | ^^^^^^^^ @@ -62,11 +110,11 @@ LL | my_macro_attr!(); | ^^^^^^^^^^^^^ error: cannot find macro `MyTrait!` in this scope - --> $DIR/macro-namespace-reserved-2.rs:31:5 + --> $DIR/macro-namespace-reserved-2.rs:33:5 | LL | MyTrait!(); | ^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 19 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs index b95791f4e99..b5666e4ea70 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -1,6 +1,6 @@ -#[derive(rustfmt::skip)] //~ ERROR macro `rustfmt::skip` may not be used for derive attributes +#[derive(rustfmt::skip)] //~ ERROR expected derive macro, found tool attribute `rustfmt::skip` struct S; fn main() { - rustfmt::skip!(); //~ ERROR `rustfmt::skip` can only be used in attributes + rustfmt::skip!(); //~ ERROR expected macro, found tool attribute `rustfmt::skip` } diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr index 8ef27a07b7f..6d0f826e621 100644 --- a/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-2.stderr @@ -1,14 +1,14 @@ -error: macro `rustfmt::skip` may not be used for derive attributes +error: expected derive macro, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-2.rs:1:10 | LL | #[derive(rustfmt::skip)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a derive macro -error: `rustfmt::skip` can only be used in attributes +error: expected macro, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-2.rs:5:5 | LL | rustfmt::skip!(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a macro error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From d1949b1ab01dbd482008f64af54161cc43bb0991 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Jul 2019 20:25:34 +0300 Subject: expand: Do not overwrite existing `ExpnInfo` when injecting derive markers Create a fresh expansion for them instead - this is the usual way to allow unstable features for generated/desugared code. Fixes https://github.com/rust-lang/rust/issues/52363 --- src/libsyntax/ext/derive.rs | 7 ++++--- src/libsyntax_pos/hygiene.rs | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 68e7225c3cf..11c1fceb7e7 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -8,7 +8,7 @@ use crate::symbol::{Symbol, sym}; use crate::errors::Applicability; use syntax_pos::Span; - +use syntax_pos::hygiene::{Mark, SyntaxContext}; use rustc_data_structures::fx::FxHashSet; pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { @@ -55,12 +55,13 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); } - cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable( + let mark = Mark::fresh(cx.current_expansion.mark); + mark.set_expn_info(ExpnInfo::with_unstable( ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span, cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match], )); - let span = span.with_ctxt(cx.backtrace()); + let span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); item.visit_attrs(|attrs| { if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { let meta = cx.meta_word(span, sym::structural_match); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 28d452233cc..ba2b2b7a2dd 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -117,7 +117,11 @@ impl Mark { #[inline] pub fn set_expn_info(self, info: ExpnInfo) { - HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info)) + HygieneData::with(|data| { + let old_info = &mut data.marks[self.0 as usize].expn_info; + assert!(old_info.is_none(), "expansion info is reset for a mark"); + *old_info = Some(info); + }) } pub fn is_descendant_of(self, ancestor: Mark) -> bool { -- cgit 1.4.1-3-g733a5 From 99c7432896bbfdab1f7f70f8d763cab5f3efe64a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Jul 2019 21:02:45 +0300 Subject: hygiene: Introduce a helper method for creating new expansions Creating a fresh expansion and immediately generating a span from it is the most common scenario. Also avoid allocating `allow_internal_unstable` lists for derive markers repeatedly. And rename `ExpnInfo::with_unstable` to `ExpnInfo::allow_unstable`, seems to be a better fitting name. --- src/librustc/hir/lowering.rs | 8 ++--- src/librustc/ty/query/on_disk_cache.rs | 45 +++++++++++++------------- src/librustc_allocator/expand.rs | 12 +++---- src/librustc_resolve/macros.rs | 7 ++-- src/libsyntax/ext/base.rs | 2 ++ src/libsyntax/ext/derive.rs | 7 ++-- src/libsyntax/ext/expand.rs | 4 +-- src/libsyntax/std_inject.rs | 22 ++++--------- src/libsyntax/test.rs | 23 +++---------- src/libsyntax_ext/proc_macro_decls.rs | 6 ++-- src/libsyntax_pos/hygiene.rs | 59 ++++++++++++++-------------------- src/libsyntax_pos/symbol.rs | 2 ++ 12 files changed, 80 insertions(+), 117 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c44fd30be85..7e7bb5f61a3 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -60,7 +60,7 @@ use syntax::attr; use syntax::ast; use syntax::ast::*; use syntax::errors; -use syntax::ext::hygiene::{Mark, SyntaxContext}; +use syntax::ext::hygiene::Mark; use syntax::print::pprust; use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned}; use syntax::std_inject; @@ -875,13 +875,11 @@ impl<'a> LoweringContext<'a> { span: Span, allow_internal_unstable: Option>, ) -> Span { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo { + span.fresh_expansion(Mark::root(), ExpnInfo { def_site: span, allow_internal_unstable, ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) - }); - span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) + }) } fn with_anonymous_lifetime_mode( diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 56c9474170c..d0be13a7111 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -588,41 +588,40 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let expn_info_tag = u8::decode(self)?; - let ctxt = match expn_info_tag { + // FIXME(mw): This method does not restore `MarkData::parent` or + // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things + // don't seem to be used after HIR lowering, so everything should be fine + // as long as incremental compilation does not kick in before that. + let location = || Span::new(lo, hi, SyntaxContext::empty()); + let recover_from_expn_info = |this: &Self, expn_info, pos| { + let span = location().fresh_expansion(Mark::root(), expn_info); + this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); + span + }; + Ok(match expn_info_tag { TAG_NO_EXPANSION_INFO => { - SyntaxContext::empty() + location() } TAG_EXPANSION_INFO_INLINE => { - let pos = AbsoluteBytePos::new(self.opaque.position()); - let expn_info: ExpnInfo = Decodable::decode(self)?; - let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); - ctxt + let expn_info = Decodable::decode(self)?; + recover_from_expn_info( + self, expn_info, AbsoluteBytePos::new(self.opaque.position()) + ) } TAG_EXPANSION_INFO_SHORTHAND => { let pos = AbsoluteBytePos::decode(self)?; - let cached_ctxt = self.synthetic_expansion_infos - .borrow() - .get(&pos) - .cloned(); - - if let Some(ctxt) = cached_ctxt { - ctxt + if let Some(cached_ctxt) = self.synthetic_expansion_infos.borrow().get(&pos) { + Span::new(lo, hi, *cached_ctxt) } else { - let expn_info = self.with_position(pos.to_usize(), |this| { - ExpnInfo::decode(this) - })?; - let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); - ctxt + let expn_info = + self.with_position(pos.to_usize(), |this| ExpnInfo::decode(this))?; + recover_from_expn_info(self, expn_info, pos) } } _ => { unreachable!() } - }; - - Ok(Span::new(lo, hi, ctxt)) + }) } } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index d0eefbb1179..9803ee99f1a 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -14,7 +14,7 @@ use syntax::{ base::{ExtCtxt, MacroKind, Resolver}, build::AstBuilder, expand::ExpansionConfig, - hygiene::{Mark, SyntaxContext}, + hygiene::Mark, }, mut_visit::{self, MutVisitor}, parse::ParseSess, @@ -84,16 +84,12 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { } self.found = true; - // Create a fresh Mark for the new macro expansion we are about to do - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo::with_unstable( + // Create a new expansion for the generated allocator code. + let span = item.span.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::global_allocator), item.span, self.sess.edition, - &[sym::rustc_attrs], + [sym::rustc_attrs][..].into(), )); - // Tie the span to the macro expansion info we just created - let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - // Create an expansion config let ecfg = ExpansionConfig::default(self.crate_name.take().unwrap()); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 7ad54d572f4..6f276e04a5a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -17,7 +17,7 @@ use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Indeterminate}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; -use syntax::ext::hygiene::{self, Mark}; +use syntax::ext::hygiene::{self, Mark, ExpnInfo, ExpnKind}; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; @@ -148,7 +148,10 @@ impl<'a> base::Resolver for Resolver<'a> { } fn get_module_scope(&mut self, id: ast::NodeId) -> Mark { - let mark = Mark::fresh(Mark::root()); + let span = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::default( + ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() + )); + let mark = span.ctxt().outer(); let module = self.module_map[&self.definitions.local_def_id(id)]; self.definitions.set_invocation_parent(mark, module.def_id().unwrap().index); self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cb4edee30cd..37d5885db60 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -721,6 +721,7 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut dyn Resolver, pub current_expansion: ExpansionData, pub expansions: FxHashMap>, + pub allow_derive_markers: Lrc<[Symbol]>, } impl<'a> ExtCtxt<'a> { @@ -740,6 +741,7 @@ impl<'a> ExtCtxt<'a> { directory_ownership: DirectoryOwnership::Owned { relative: None }, }, expansions: FxHashMap::default(), + allow_derive_markers: [sym::rustc_attrs, sym::structural_match][..].into(), } } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 11c1fceb7e7..1c15deab373 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -8,7 +8,6 @@ use crate::symbol::{Symbol, sym}; use crate::errors::Applicability; use syntax_pos::Span; -use syntax_pos::hygiene::{Mark, SyntaxContext}; use rustc_data_structures::fx::FxHashSet; pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { @@ -55,13 +54,11 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); } - let mark = Mark::fresh(cx.current_expansion.mark); - mark.set_expn_info(ExpnInfo::with_unstable( + let span = span.fresh_expansion(cx.current_expansion.mark, ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span, - cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match], + cx.parse_sess.edition, cx.allow_derive_markers.clone(), )); - let span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); item.visit_attrs(|attrs| { if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { let meta = cx.meta_word(span, sym::structural_match); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2349382eb5e..39a8a7af2a3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -362,7 +362,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derives.reserve(traits.len()); invocations.reserve(traits.len()); for path in traits { - let mark = Mark::fresh(self.cx.current_expansion.mark); + let mark = Mark::fresh(self.cx.current_expansion.mark, None); derives.push(mark); invocations.push(Invocation { kind: InvocationKind::Derive { @@ -847,7 +847,7 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { - let mark = Mark::fresh(self.cx.current_expansion.mark); + let mark = Mark::fresh(self.cx.current_expansion.mark, None); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 81f9ff9b661..d86b76f71ec 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -1,7 +1,7 @@ use crate::ast; use crate::attr; use crate::edition::Edition; -use crate::ext::hygiene::{Mark, SyntaxContext, MacroKind}; +use crate::ext::hygiene::{Mark, MacroKind}; use crate::symbol::{Ident, Symbol, kw, sym}; use crate::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use crate::ptr::P; @@ -9,19 +9,7 @@ use crate::tokenstream::TokenStream; use std::cell::Cell; use std::iter; -use syntax_pos::{DUMMY_SP, Span}; - -/// Craft a span that will be ignored by the stability lint's -/// call to source_map's `is_internal` check. -/// The expanded code uses the unstable `#[prelude_import]` attribute. -fn ignored_span(sp: Span, edition: Edition) -> Span { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::Macro(MacroKind::Attr, Symbol::intern("std_inject")), sp, edition, - &[sym::prelude_import], - )); - sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) -} +use syntax_pos::DUMMY_SP; pub fn injected_crate_name() -> Option<&'static str> { INJECTED_CRATE_NAME.with(|name| name.get()) @@ -87,7 +75,11 @@ pub fn maybe_inject_crates_ref( INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name))); - let span = ignored_span(DUMMY_SP, edition); + let span = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( + ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition, + [sym::prelude_import][..].into(), + )); + krate.module.items.insert(0, P(ast::Item { attrs: vec![ast::Attribute { style: ast::AttrStyle::Outer, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 7ec7bb6ff45..799d64a9962 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -43,7 +43,6 @@ struct TestCtxt<'a> { test_cases: Vec, reexport_test_harness_main: Option, is_libtest: bool, - ctxt: SyntaxContext, features: &'a Features, test_runner: Option, @@ -259,8 +258,6 @@ fn generate_test_harness(sess: &ParseSess, let mut cleaner = EntryPointCleaner { depth: 0 }; cleaner.visit_crate(krate); - let mark = Mark::fresh(Mark::root()); - let mut econfig = ExpansionConfig::default("test".to_string()); econfig.features = Some(features); @@ -274,16 +271,10 @@ fn generate_test_harness(sess: &ParseSess, is_libtest: attr::find_crate_name(&krate.attrs) .map(|s| s == sym::test).unwrap_or(false), toplevel_reexport: None, - ctxt: SyntaxContext::empty().apply_mark(mark), features, test_runner }; - mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, sess.edition, - &[sym::main, sym::test, sym::rustc_attrs], - )); - TestHarnessGenerator { cx, tests: Vec::new(), @@ -291,13 +282,6 @@ fn generate_test_harness(sess: &ParseSess, }.visit_crate(krate); } -/// Craft a span that will be ignored by the stability lint's -/// call to source_map's `is_internal` check. -/// The expanded code calls some unstable functions in the test crate. -fn ignored_span(cx: &TestCtxt<'_>, sp: Span) -> Span { - sp.with_ctxt(cx.ctxt) -} - enum HasTestSignature { Yes, No(BadTestSignature), @@ -314,12 +298,15 @@ enum BadTestSignature { /// Creates a function item for use as the main function of a test build. /// This function will call the `test_runner` as specified by the crate attribute fn mk_main(cx: &mut TestCtxt<'_>) -> P { - // Writing this out by hand with 'ignored_span': + // Writing this out by hand: // pub fn main() { // #![main] // test::test_main_static(&[..tests]); // } - let sp = ignored_span(cx, DUMMY_SP); + let sp = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( + ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition, + [sym::main, sym::test, sym::rustc_attrs][..].into(), + )); let ecx = &cx.ext_cx; let test_id = Ident::with_empty_ctxt(sym::test); diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 0733a8ec95c..2f78644dff2 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -346,12 +346,10 @@ fn mk_decls( custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], ) -> P { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo::with_unstable( + let span = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, - &[sym::rustc_attrs, Symbol::intern("proc_macro_internals")], + [sym::rustc_attrs, sym::proc_macro_internals][..].into(), )); - let span = DUMMY_SP.apply_mark(mark); let hidden = cx.meta_list_item_word(span, sym::hidden); let doc = cx.meta_list(span, sym::doc, vec![hidden]); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index ba2b2b7a2dd..f060bf356f6 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -82,11 +82,8 @@ pub enum Transparency { } impl Mark { - pub fn fresh(parent: Mark) -> Self { - HygieneData::with(|data| { - data.marks.push(MarkData { parent, expn_info: None }); - Mark(data.marks.len() as u32 - 1) - }) + pub fn fresh(parent: Mark, expn_info: Option) -> Self { + HygieneData::with(|data| data.fresh_mark(parent, expn_info)) } /// The mark of the theoretical expansion that generates freshly parsed, unexpanded AST. @@ -180,6 +177,11 @@ impl HygieneData { GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } + fn fresh_mark(&mut self, parent: Mark, expn_info: Option) -> Mark { + self.marks.push(MarkData { parent, expn_info }); + Mark(self.marks.len() as u32 - 1) + } + fn expn_info(&self, mark: Mark) -> Option<&ExpnInfo> { self.marks[mark.0 as usize].expn_info.as_ref() } @@ -396,33 +398,6 @@ impl SyntaxContext { SyntaxContext(raw) } - // Allocate a new SyntaxContext with the given ExpnInfo. This is used when - // deserializing Spans from the incr. comp. cache. - // FIXME(mw): This method does not restore MarkData::parent or - // SyntaxContextData::prev_ctxt or SyntaxContextData::opaque. These things - // don't seem to be used after HIR lowering, so everything should be fine - // as long as incremental compilation does not kick in before that. - pub fn allocate_directly(expansion_info: ExpnInfo) -> Self { - HygieneData::with(|data| { - data.marks.push(MarkData { - parent: Mark::root(), - expn_info: Some(expansion_info), - }); - - let mark = Mark(data.marks.len() as u32 - 1); - - data.syntax_contexts.push(SyntaxContextData { - outer_mark: mark, - transparency: Transparency::SemiTransparent, - prev_ctxt: SyntaxContext::empty(), - opaque: SyntaxContext::empty(), - opaque_and_semitransparent: SyntaxContext::empty(), - dollar_crate_name: kw::DollarCrate, - }); - SyntaxContext(data.syntax_contexts.len() as u32 - 1) - }) - } - /// Extend a syntax context with a given mark and default transparency for that mark. pub fn apply_mark(self, mark: Mark) -> SyntaxContext { HygieneData::with(|data| data.apply_mark(self, mark)) @@ -615,6 +590,20 @@ impl fmt::Debug for SyntaxContext { } } +impl Span { + /// Creates a fresh expansion with given properties. + /// Expansions are normally created by macros, but in some cases expansions are created for + /// other compiler-generated code to set per-span properties like allowed unstable features. + /// The returned span belongs to the created expansion and has the new properties, + /// but its location is inherited from the current span. + pub fn fresh_expansion(self, parent: Mark, expn_info: ExpnInfo) -> Span { + HygieneData::with(|data| { + let mark = data.fresh_mark(parent, Some(expn_info)); + self.with_ctxt(data.apply_mark(SyntaxContext::empty(), mark)) + }) + } +} + /// A subset of properties from both macro definition and macro call available through global data. /// Avoid using this if you have access to the original definition or call structures. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] @@ -669,10 +658,10 @@ impl ExpnInfo { } } - pub fn with_unstable(kind: ExpnKind, call_site: Span, edition: Edition, - allow_internal_unstable: &[Symbol]) -> ExpnInfo { + pub fn allow_unstable(kind: ExpnKind, call_site: Span, edition: Edition, + allow_internal_unstable: Lrc<[Symbol]>) -> ExpnInfo { ExpnInfo { - allow_internal_unstable: Some(allow_internal_unstable.into()), + allow_internal_unstable: Some(allow_internal_unstable), ..ExpnInfo::default(kind, call_site, edition) } } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 89fcf3b1f8f..581fd47c4b3 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -508,6 +508,7 @@ symbols! { proc_macro_expr, proc_macro_gen, proc_macro_hygiene, + proc_macro_internals, proc_macro_mod, proc_macro_non_items, proc_macro_path_invoc, @@ -631,6 +632,7 @@ symbols! { static_nobundle, static_recursion, std, + std_inject, str, stringify, stmt, -- cgit 1.4.1-3-g733a5 From eac900ac87828d6a4813f0c4a870bcdb439d1175 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 7 Jul 2019 16:45:41 +0300 Subject: hygiene: Make sure each `Mark` has an associated expansion info The root expansion was missing one. Expansions created for "derive containers" (see one of the next commits for the description) also didn't get expansion info. --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc/lint/mod.rs | 2 +- src/libsyntax/ext/expand.rs | 14 ++++++++++++-- src/libsyntax_pos/hygiene.rs | 20 +++++++++++++++++--- src/libsyntax_pos/lib.rs | 3 ++- 5 files changed, 33 insertions(+), 7 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 69e8c355019..e0e7988a744 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -408,6 +408,7 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { }); impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { + Root, Macro(kind, descr), Desugaring(kind) }); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 3c8b0041a98..e76c2493200 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -885,7 +885,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { }; match info.kind { - ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false, ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { if info.def_site.is_dummy() { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 39a8a7af2a3..9a6252779e0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -5,7 +5,7 @@ use crate::source_map::{dummy_spanned, respan}; use crate::config::StripUnconfigured; use crate::ext::base::*; use crate::ext::derive::{add_derived_markers, collect_derives}; -use crate::ext::hygiene::{Mark, SyntaxContext}; +use crate::ext::hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnKind}; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; use crate::mut_visit::*; @@ -847,7 +847,17 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { - let mark = Mark::fresh(self.cx.current_expansion.mark, None); + // Expansion info for all the collected invocations is set upon their resolution, + // with exception of the "derive container" case which is not resolved and can get + // its expansion info immediately. + let expn_info = match &kind { + InvocationKind::Attr { attr: None, item, .. } => Some(ExpnInfo::default( + ExpnKind::Macro(MacroKind::Attr, sym::derive), + item.span(), self.cx.parse_sess.edition, + )), + _ => None, + }; + let mark = Mark::fresh(self.cx.current_expansion.mark, expn_info); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index b72da042d04..5df14439230 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -59,6 +59,9 @@ pub struct Mark(u32); #[derive(Debug)] struct MarkData { parent: Mark, + /// Each mark should have an associated expansion info, but sometimes there's a delay between + /// creation of a mark and obtaining its info (e.g. macros are collected first and then + /// resolved later), so we use an `Option` here. expn_info: Option, } @@ -155,11 +158,11 @@ crate struct HygieneData { } impl HygieneData { - crate fn new() -> Self { + crate fn new(edition: Edition) -> Self { HygieneData { marks: vec![MarkData { parent: Mark::root(), - expn_info: None, + expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)), }], syntax_contexts: vec![SyntaxContextData { outer_mark: Mark::root(), @@ -183,7 +186,15 @@ impl HygieneData { } fn expn_info(&self, mark: Mark) -> Option<&ExpnInfo> { - self.marks[mark.0 as usize].expn_info.as_ref() + if mark != Mark::root() { + Some(self.marks[mark.0 as usize].expn_info.as_ref() + .expect("no expansion info for a mark")) + } else { + // FIXME: Some code relies on `expn_info().is_none()` meaning "no expansion". + // Introduce a method for checking for "no expansion" instead and always return + // `ExpnInfo` from this function instead of the `Option`. + None + } } fn is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool { @@ -670,6 +681,8 @@ impl ExpnInfo { /// Expansion kind. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub enum ExpnKind { + /// No expansion, aka root expansion. Only `Mark::root()` has this kind. + Root, /// Expansion produced by a macro. /// FIXME: Some code injected by the compiler before HIR lowering also gets this kind. Macro(MacroKind, Symbol), @@ -680,6 +693,7 @@ pub enum ExpnKind { impl ExpnKind { pub fn descr(&self) -> Symbol { match *self { + ExpnKind::Root => kw::PathRoot, ExpnKind::Macro(_, descr) => descr, ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()), } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 9258b71518f..5ccfe5f0b8b 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -60,7 +60,7 @@ impl Globals { Globals { symbol_interner: Lock::new(symbol::Interner::fresh()), span_interner: Lock::new(span_encoding::SpanInterner::default()), - hygiene_data: Lock::new(hygiene::HygieneData::new()), + hygiene_data: Lock::new(hygiene::HygieneData::new(edition)), edition, } } @@ -442,6 +442,7 @@ impl Span { // Don't print recursive invocations. if !info.call_site.source_equal(&prev_span) { let (pre, post) = match info.kind { + ExpnKind::Root => break, ExpnKind::Desugaring(..) => ("desugaring of ", ""), ExpnKind::Macro(macro_kind, _) => match macro_kind { MacroKind::Bang => ("", "!"), -- cgit 1.4.1-3-g733a5 From 374a80a86de4dabae4975fae04fb67cc6e6dc0bb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 7 Jul 2019 18:29:22 +0300 Subject: expand: It's always possible to create a dummy AST fragment Remove a bunch of `Option`s that assumed that dummy fragment creation could fail. The test output changed due to not performing the expansion in `fn expand_invoc` in case of the recursion limit hit. --- src/libsyntax/ext/expand.rs | 83 +++++++++++++-------------- src/test/ui/macros/trace_faulty_macros.stderr | 2 - 2 files changed, 39 insertions(+), 46 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9a6252779e0..85a31b8b7e8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -158,8 +158,8 @@ ast_fragments! { } impl AstFragmentKind { - fn dummy(self, span: Span) -> Option { - self.make_from(DummyResult::any(span)) + fn dummy(self, span: Span) -> AstFragment { + self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment") } fn expect_from_annotatables>(self, items: I) @@ -327,10 +327,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { - let (invoc_fragment_kind, invoc_span) = (invoc.fragment_kind, invoc.span()); - let fragment = self.expand_invoc(invoc, &ext).unwrap_or_else(|| { - invoc_fragment_kind.dummy(invoc_span).unwrap() - }); + let fragment = self.expand_invoc(invoc, &ext); self.collect_invocations(fragment, &[]) } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { if !item.derive_allowed() { @@ -477,7 +474,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option { + fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> AstFragment { if invoc.fragment_kind == AstFragmentKind::ForeignItems && !self.cx.ecfg.macros_in_extern() { if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else { @@ -487,12 +484,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - let result = match invoc.kind { - InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext)?, - InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext)?, - InvocationKind::Derive { .. } => self.expand_derive_invoc(invoc, ext)?, - }; - if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit { let info = self.cx.current_expansion.mark.expn_info().unwrap(); let suggested_limit = self.cx.ecfg.recursion_limit * 2; @@ -507,15 +498,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { FatalError.raise(); } - Some(result) + match invoc.kind { + InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext), + InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext), + InvocationKind::Derive { .. } => self.expand_derive_invoc(invoc, ext), + } } fn expand_attr_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) - -> Option { + -> AstFragment { let (attr, mut item) = match invoc.kind { - InvocationKind::Attr { attr, item, .. } => (attr?, item), + InvocationKind::Attr { attr: Some(attr), item, .. } => (attr, item), _ => unreachable!(), }; @@ -526,13 +521,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { attr::mark_used(&attr); } item.visit_attrs(|attrs| attrs.push(attr)); - Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) + invoc.fragment_kind.expect_from_annotatables(iter::once(item)) } SyntaxExtensionKind::LegacyAttr(expander) => { - let meta = attr.parse_meta(self.cx.parse_sess) - .map_err(|mut e| { e.emit(); }).ok()?; - let item = expander.expand(self.cx, attr.span, &meta, item); - Some(invoc.fragment_kind.expect_from_annotatables(item)) + match attr.parse_meta(self.cx.parse_sess) { + Ok(meta) => { + let item = expander.expand(self.cx, attr.span, &meta, item); + invoc.fragment_kind.expect_from_annotatables(item) + } + Err(mut err) => { + err.emit(); + invoc.fragment_kind.dummy(attr.span) + } + } } SyntaxExtensionKind::Attr(expander) => { self.gate_proc_macro_attr_item(attr.span, &item); @@ -598,14 +599,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ); } - fn gate_proc_macro_expansion(&self, span: Span, fragment: &Option) { + fn gate_proc_macro_expansion(&self, span: Span, fragment: &AstFragment) { if self.cx.ecfg.proc_macro_hygiene() { return } - let fragment = match fragment { - Some(fragment) => fragment, - None => return, - }; fragment.visit_with(&mut DisallowMacros { span, @@ -641,7 +638,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn expand_bang_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) - -> Option { + -> AstFragment { let kind = invoc.fragment_kind; let (mac, span) = match invoc.kind { InvocationKind::Bang { mac, span } => (mac, span), @@ -649,7 +646,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let path = &mac.node.path; - let opt_expanded = match &ext.kind { + match &ext.kind { SyntaxExtensionKind::Bang(expander) => { self.gate_proc_macro_expansion_kind(span, kind); let tok_result = expander.expand(self.cx, span, mac.node.stream()); @@ -659,19 +656,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } SyntaxExtensionKind::LegacyBang(expander) => { let tok_result = expander.expand(self.cx, span, mac.node.stream()); - kind.make_from(tok_result) + if let Some(result) = kind.make_from(tok_result) { + result + } else { + let msg = format!("non-{kind} macro in {kind} position: {name}", + name = path.segments[0].ident.name, kind = kind.name()); + self.cx.span_err(path.span, &msg); + self.cx.trace_macros_diag(); + kind.dummy(span) + } } _ => unreachable!() - }; - - if opt_expanded.is_some() { - opt_expanded - } else { - let msg = format!("non-{kind} macro in {kind} position: {name}", - name = path.segments[0].ident.name, kind = kind.name()); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) } } @@ -703,7 +698,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn expand_derive_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) - -> Option { + -> AstFragment { let (path, item) = match invoc.kind { InvocationKind::Derive { path, item, item_with_markers } => match ext.kind { SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers), @@ -712,7 +707,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => unreachable!(), }; if !item.derive_allowed() { - return None; + return invoc.fragment_kind.dummy(path.span); } match &ext.kind { @@ -721,7 +716,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span: path.span, path }; let span = meta.span.with_ctxt(self.cx.backtrace()); let items = expander.expand(self.cx, span, &meta, item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) + invoc.fragment_kind.expect_from_annotatables(items) } _ => unreachable!() } @@ -732,12 +727,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { kind: AstFragmentKind, path: &Path, span: Span) - -> Option { + -> AstFragment { let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::>()); match parser.parse_ast_fragment(kind, false) { Ok(fragment) => { parser.ensure_complete_parse(path, kind.name(), span); - Some(fragment) + fragment } Err(mut err) => { err.set_span(span); diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 233d3dcfcb6..fc05012377b 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -45,8 +45,6 @@ LL | my_recursive_macro!(); = note: to `my_recursive_macro ! ( ) ;` = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro ! ( ) ;` - = note: expanding `my_recursive_macro! { }` - = note: to `my_recursive_macro ! ( ) ;` error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From b003dd6d9badf0e66b6e90af2052fefef94d4a43 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 7 Jul 2019 18:55:29 +0300 Subject: expand: Merge `expand_{bang,attr,derive}_invoc` into a single function It's more convenient to have all this highly related stuff together on one screen (for future refactorings). The `expand_invoc` function is compact enough now, after all the previous refactorings. --- src/libsyntax/ext/expand.rs | 194 ++++++++++++++-------------------- src/test/ui/macros/macro-error.stderr | 2 +- 2 files changed, 79 insertions(+), 117 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 85a31b8b7e8..f1235e7174f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -327,7 +327,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { - let fragment = self.expand_invoc(invoc, &ext); + let fragment = self.expand_invoc(invoc, &ext.kind); self.collect_invocations(fragment, &[]) } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { if !item.derive_allowed() { @@ -474,12 +474,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> AstFragment { - if invoc.fragment_kind == AstFragmentKind::ForeignItems && - !self.cx.ecfg.macros_in_extern() { - if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else { + fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstFragment { + let (fragment_kind, span) = (invoc.fragment_kind, invoc.span()); + if fragment_kind == AstFragmentKind::ForeignItems && !self.cx.ecfg.macros_in_extern() { + if let SyntaxExtensionKind::NonMacroAttr { .. } = ext {} else { emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern, - invoc.span(), GateIssue::Language, + span, GateIssue::Language, "macro invocations in `extern {}` blocks are experimental"); } } @@ -499,58 +499,84 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } match invoc.kind { - InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext), - InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext), - InvocationKind::Derive { .. } => self.expand_derive_invoc(invoc, ext), - } - } - - fn expand_attr_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> AstFragment { - let (attr, mut item) = match invoc.kind { - InvocationKind::Attr { attr: Some(attr), item, .. } => (attr, item), - _ => unreachable!(), - }; - - match &ext.kind { - SyntaxExtensionKind::NonMacroAttr { mark_used } => { - attr::mark_known(&attr); - if *mark_used { - attr::mark_used(&attr); + InvocationKind::Bang { mac, .. } => match ext { + SyntaxExtensionKind::Bang(expander) => { + self.gate_proc_macro_expansion_kind(span, fragment_kind); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = + self.parse_ast_fragment(tok_result, fragment_kind, &mac.node.path, span); + self.gate_proc_macro_expansion(span, &result); + result + } + SyntaxExtensionKind::LegacyBang(expander) => { + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + if let Some(result) = fragment_kind.make_from(tok_result) { + result + } else { + let msg = format!("non-{kind} macro in {kind} position: {path}", + kind = fragment_kind.name(), path = mac.node.path); + self.cx.span_err(span, &msg); + self.cx.trace_macros_diag(); + fragment_kind.dummy(span) + } } - item.visit_attrs(|attrs| attrs.push(attr)); - invoc.fragment_kind.expect_from_annotatables(iter::once(item)) + _ => unreachable!() } - SyntaxExtensionKind::LegacyAttr(expander) => { - match attr.parse_meta(self.cx.parse_sess) { - Ok(meta) => { - let item = expander.expand(self.cx, attr.span, &meta, item); - invoc.fragment_kind.expect_from_annotatables(item) + InvocationKind::Attr { attr: Some(attr), mut item, .. } => match ext { + SyntaxExtensionKind::Attr(expander) => { + self.gate_proc_macro_attr_item(span, &item); + let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { + Annotatable::Item(item) => token::NtItem(item), + Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()), + Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()), + Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()), + Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), + Annotatable::Expr(expr) => token::NtExpr(expr), + })), DUMMY_SP).into(); + let input = self.extract_proc_macro_attr_input(attr.tokens, span); + let tok_result = expander.expand(self.cx, span, input, item_tok); + let res = self.parse_ast_fragment(tok_result, fragment_kind, &attr.path, span); + self.gate_proc_macro_expansion(span, &res); + res + } + SyntaxExtensionKind::LegacyAttr(expander) => { + match attr.parse_meta(self.cx.parse_sess) { + Ok(meta) => { + let item = expander.expand(self.cx, span, &meta, item); + fragment_kind.expect_from_annotatables(item) + } + Err(mut err) => { + err.emit(); + fragment_kind.dummy(span) + } } - Err(mut err) => { - err.emit(); - invoc.fragment_kind.dummy(attr.span) + } + SyntaxExtensionKind::NonMacroAttr { mark_used } => { + attr::mark_known(&attr); + if *mark_used { + attr::mark_used(&attr); } + item.visit_attrs(|attrs| attrs.push(attr)); + fragment_kind.expect_from_annotatables(iter::once(item)) } + _ => unreachable!() } - SyntaxExtensionKind::Attr(expander) => { - self.gate_proc_macro_attr_item(attr.span, &item); - let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { - Annotatable::Item(item) => token::NtItem(item), - Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()), - Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()), - Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()), - Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), - Annotatable::Expr(expr) => token::NtExpr(expr), - })), DUMMY_SP).into(); - let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span); - let tok_result = expander.expand(self.cx, attr.span, input, item_tok); - let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind, - &attr.path, attr.span); - self.gate_proc_macro_expansion(attr.span, &res); - res + InvocationKind::Derive { path, item, item_with_markers } => match ext { + SyntaxExtensionKind::Derive(expander) | + SyntaxExtensionKind::LegacyDerive(expander) => { + let (path, item) = match ext { + SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers), + _ => (path, item), + }; + if !item.derive_allowed() { + return fragment_kind.dummy(span); + } + let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path }; + let span = span.with_ctxt(self.cx.backtrace()); + let items = expander.expand(self.cx, span, &meta, item); + fragment_kind.expect_from_annotatables(items) + } + _ => unreachable!() } _ => unreachable!() } @@ -634,42 +660,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - /// Expand a macro invocation. Returns the resulting expanded AST fragment. - fn expand_bang_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> AstFragment { - let kind = invoc.fragment_kind; - let (mac, span) = match invoc.kind { - InvocationKind::Bang { mac, span } => (mac, span), - _ => unreachable!(), - }; - let path = &mac.node.path; - - match &ext.kind { - SyntaxExtensionKind::Bang(expander) => { - self.gate_proc_macro_expansion_kind(span, kind); - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - let result = self.parse_ast_fragment(tok_result, kind, path, span); - self.gate_proc_macro_expansion(span, &result); - result - } - SyntaxExtensionKind::LegacyBang(expander) => { - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - if let Some(result) = kind.make_from(tok_result) { - result - } else { - let msg = format!("non-{kind} macro in {kind} position: {name}", - name = path.segments[0].ident.name, kind = kind.name()); - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) - } - } - _ => unreachable!() - } - } - fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) { let kind = match kind { AstFragmentKind::Expr => "expressions", @@ -694,34 +684,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ); } - /// Expand a derive invocation. Returns the resulting expanded AST fragment. - fn expand_derive_invoc(&mut self, - invoc: Invocation, - ext: &SyntaxExtension) - -> AstFragment { - let (path, item) = match invoc.kind { - InvocationKind::Derive { path, item, item_with_markers } => match ext.kind { - SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers), - _ => (path, item), - } - _ => unreachable!(), - }; - if !item.derive_allowed() { - return invoc.fragment_kind.dummy(path.span); - } - - match &ext.kind { - SyntaxExtensionKind::Derive(expander) | - SyntaxExtensionKind::LegacyDerive(expander) => { - let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span: path.span, path }; - let span = meta.span.with_ctxt(self.cx.backtrace()); - let items = expander.expand(self.cx, span, &meta, item); - invoc.fragment_kind.expect_from_annotatables(items) - } - _ => unreachable!() - } - } - fn parse_ast_fragment(&mut self, toks: TokenStream, kind: AstFragmentKind, diff --git a/src/test/ui/macros/macro-error.stderr b/src/test/ui/macros/macro-error.stderr index b3aed8c2cef..2539a6d5156 100644 --- a/src/test/ui/macros/macro-error.stderr +++ b/src/test/ui/macros/macro-error.stderr @@ -8,7 +8,7 @@ error: non-type macro in type position: cfg --> $DIR/macro-error.rs:8:12 | LL | let _: cfg!(foo) = (); - | ^^^ + | ^^^^^^^^^ error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From baddce5155f7358af319818b10c992790dc8c572 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 8 Jul 2019 01:00:43 +0300 Subject: expand: Move "derive containers" into a separate `InvocationKind` variant `InvocationKind::Attr { attr: None, .. }` meaning something entirely different from a regular attribute was confusing as hell. --- src/librustc_resolve/macros.rs | 8 ++++---- src/libsyntax/ext/expand.rs | 39 +++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 6f276e04a5a..fc1becfe309 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -221,14 +221,14 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool) -> Result>, Indeterminate> { let (path, kind, derives_in_scope, after_derive) = match invoc.kind { - InvocationKind::Attr { attr: None, .. } => - return Ok(None), - InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } => - (&attr.path, MacroKind::Attr, traits.clone(), after_derive), + InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => + (&attr.path, MacroKind::Attr, derives.clone(), after_derive), InvocationKind::Bang { ref mac, .. } => (&mac.node.path, MacroKind::Bang, Vec::new(), false), InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive, Vec::new(), false), + InvocationKind::DeriveContainer { .. } => + return Ok(None), }; let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f1235e7174f..7fc62e357c5 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -199,9 +199,10 @@ pub enum InvocationKind { span: Span, }, Attr { - attr: Option, - traits: Vec, + attr: ast::Attribute, item: Annotatable, + // Required for resolving derive helper attributes. + derives: Vec, // We temporarily report errors for attribute macros placed after derives after_derive: bool, }, @@ -210,15 +211,22 @@ pub enum InvocationKind { item: Annotatable, item_with_markers: Annotatable, }, + /// "Invocation" that contains all derives from an item, + /// broken into multiple `Derive` invocations when expanded. + /// FIXME: Find a way to remove it. + DeriveContainer { + derives: Vec, + item: Annotatable, + }, } impl Invocation { pub fn span(&self) -> Span { - match self.kind { - InvocationKind::Bang { span, .. } => span, - InvocationKind::Attr { attr: Some(ref attr), .. } => attr.span, - InvocationKind::Attr { attr: None, .. } => DUMMY_SP, - InvocationKind::Derive { ref path, .. } => path.span, + match &self.kind { + InvocationKind::Bang { span, .. } => *span, + InvocationKind::Attr { attr, .. } => attr.span, + InvocationKind::Derive { path, .. } => path.span, + InvocationKind::DeriveContainer { item, .. } => item.span(), } } } @@ -329,7 +337,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let (expanded_fragment, new_invocations) = if let Some(ext) = ext { let fragment = self.expand_invoc(invoc, &ext.kind); self.collect_invocations(fragment, &[]) - } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind { + } else if let InvocationKind::DeriveContainer { derives: traits, item } = invoc.kind { if !item.derive_allowed() { let attr = attr::find_by_name(item.attrs(), sym::derive) .expect("`derive` attribute should exist"); @@ -522,7 +530,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!() } - InvocationKind::Attr { attr: Some(attr), mut item, .. } => match ext { + InvocationKind::Attr { attr, mut item, .. } => match ext { SyntaxExtensionKind::Attr(expander) => { self.gate_proc_macro_attr_item(span, &item); let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { @@ -578,7 +586,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!() } - _ => unreachable!() + InvocationKind::DeriveContainer { .. } => unreachable!() } } @@ -805,10 +813,10 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { // Expansion info for all the collected invocations is set upon their resolution, - // with exception of the "derive container" case which is not resolved and can get + // with exception of the derive container case which is not resolved and can get // its expansion info immediately. let expn_info = match &kind { - InvocationKind::Attr { attr: None, item, .. } => Some(ExpnInfo::default( + InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default( ExpnKind::Macro(MacroKind::Attr, sym::derive), item.span(), self.cx.parse_sess.edition, )), @@ -833,12 +841,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect_attr(&mut self, attr: Option, - traits: Vec, + derives: Vec, item: Annotatable, kind: AstFragmentKind, after_derive: bool) -> AstFragment { - self.collect(kind, InvocationKind::Attr { attr, traits, item, after_derive }) + self.collect(kind, match attr { + Some(attr) => InvocationKind::Attr { attr, item, derives, after_derive }, + None => InvocationKind::DeriveContainer { derives, item }, + }) } fn find_attr_invoc(&self, attrs: &mut Vec, after_derive: &mut bool) -- cgit 1.4.1-3-g733a5