Auto merge of #53461 - petrochenkov:pmu, r=alexcrichton
resolve: Do not error on access to proc macros imported with `#[macro_use]` This error is artificial, but previously, when `#[macro_use] extern crate x;` was stable, but non-derive proc macros were not, it worked like kind of a feature gate. Now both features are stable, so the error is no longer necessary. This PR simplifies how `#[macro_use] extern crate x;` works - it takes all items from macro namespace of `x`'s root and puts them into macro prelude from which they all can now be accessed.
This commit is contained in:
commit
cb6d2dfa89
@ -1429,8 +1429,6 @@ pub struct Resolver<'a, 'b: 'a> {
|
||||
ambiguity_errors: Vec<AmbiguityError<'a>>,
|
||||
/// `use` injections are delayed for better placement and deduplication
|
||||
use_injections: Vec<UseError<'a>>,
|
||||
/// `use` injections for proc macros wrongly imported with #[macro_use]
|
||||
proc_mac_errors: Vec<macros::ProcMacError>,
|
||||
/// crate-local macro expanded `macro_export` referred to by a module-relative path
|
||||
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
|
||||
|
||||
@ -1458,9 +1456,6 @@ pub struct Resolver<'a, 'b: 'a> {
|
||||
/// Avoid duplicated errors for "name already defined".
|
||||
name_already_seen: FxHashMap<Name, Span>,
|
||||
|
||||
/// A set of procedural macros imported by `#[macro_use]` that have already been warned about
|
||||
warned_proc_macros: FxHashSet<Name>,
|
||||
|
||||
potentially_unused_imports: Vec<&'a ImportDirective<'a>>,
|
||||
|
||||
/// This table maps struct IDs into struct constructor IDs,
|
||||
@ -1744,7 +1739,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
privacy_errors: Vec::new(),
|
||||
ambiguity_errors: Vec::new(),
|
||||
use_injections: Vec::new(),
|
||||
proc_mac_errors: Vec::new(),
|
||||
macro_expanded_macro_export_errors: BTreeSet::new(),
|
||||
|
||||
arenas,
|
||||
@ -1766,7 +1760,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
local_macro_def_scopes: FxHashMap(),
|
||||
name_already_seen: FxHashMap(),
|
||||
whitelisted_legacy_custom_derives: Vec::new(),
|
||||
warned_proc_macros: FxHashSet(),
|
||||
potentially_unused_imports: Vec::new(),
|
||||
struct_constructors: DefIdMap(),
|
||||
found_unresolved_macro: false,
|
||||
@ -4602,7 +4595,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
|
||||
fn report_errors(&mut self, krate: &Crate) {
|
||||
self.report_with_use_injections(krate);
|
||||
self.report_proc_macro_import(krate);
|
||||
let mut reported_spans = FxHashSet();
|
||||
|
||||
for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
|
||||
|
@ -19,7 +19,6 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, DefIndex,
|
||||
use rustc::hir::def::{Def, NonMacroAttrKind};
|
||||
use rustc::hir::map::{self, DefCollector};
|
||||
use rustc::{ty, lint};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use syntax::ast::{self, Name, Ident};
|
||||
use syntax::attr;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
@ -110,14 +109,6 @@ pub struct ParentScope<'a> {
|
||||
crate derives: Vec<ast::Path>,
|
||||
}
|
||||
|
||||
pub struct ProcMacError {
|
||||
crate_name: Symbol,
|
||||
name: Symbol,
|
||||
module: ast::NodeId,
|
||||
use_span: Span,
|
||||
warn_msg: &'static str,
|
||||
}
|
||||
|
||||
// Macro namespace is separated into two sub-namespaces, one for bang macros and
|
||||
// one for attribute-like macros (attributes, derives).
|
||||
// We ignore resolutions from one sub-namespace when searching names in scope for another.
|
||||
@ -980,7 +971,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
check_consistency(self, binding.def_ignoring_ambiguity());
|
||||
if from_prelude {
|
||||
self.record_use(ident, MacroNS, binding);
|
||||
self.err_if_macro_use_proc_macro(ident.name, span, binding);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1132,69 +1122,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Error if `ext` is a Macros 1.1 procedural macro being imported by `#[macro_use]`
|
||||
fn err_if_macro_use_proc_macro(&mut self, name: Name, use_span: Span,
|
||||
binding: &NameBinding<'a>) {
|
||||
let krate = match binding.def() {
|
||||
Def::NonMacroAttr(..) | Def::Err => return,
|
||||
Def::Macro(def_id, _) => def_id.krate,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
// Plugin-based syntax extensions are exempt from this check
|
||||
if krate == CrateNum::BuiltinMacros { return; }
|
||||
|
||||
let ext = binding.get_macro(self);
|
||||
|
||||
match *ext {
|
||||
// If `ext` is a procedural macro, check if we've already warned about it
|
||||
SyntaxExtension::AttrProcMacro(..) | SyntaxExtension::ProcMacro { .. } =>
|
||||
if !self.warned_proc_macros.insert(name) { return; },
|
||||
_ => return,
|
||||
}
|
||||
|
||||
let warn_msg = match *ext {
|
||||
SyntaxExtension::AttrProcMacro(..) =>
|
||||
"attribute procedural macros cannot be imported with `#[macro_use]`",
|
||||
SyntaxExtension::ProcMacro { .. } =>
|
||||
"procedural macros cannot be imported with `#[macro_use]`",
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let def_id = self.current_module.normal_ancestor_id;
|
||||
let node_id = self.definitions.as_local_node_id(def_id).unwrap();
|
||||
|
||||
self.proc_mac_errors.push(ProcMacError {
|
||||
crate_name: self.cstore.crate_name_untracked(krate),
|
||||
name,
|
||||
module: node_id,
|
||||
use_span,
|
||||
warn_msg,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn report_proc_macro_import(&mut self, krate: &ast::Crate) {
|
||||
for err in self.proc_mac_errors.drain(..) {
|
||||
let (span, found_use) = ::UsePlacementFinder::check(krate, err.module);
|
||||
|
||||
if let Some(span) = span {
|
||||
let found_use = if found_use { "" } else { "\n" };
|
||||
self.session.struct_span_err(err.use_span, err.warn_msg)
|
||||
.span_suggestion_with_applicability(
|
||||
span,
|
||||
"instead, import the procedural macro like any other item",
|
||||
format!("use {}::{};{}", err.crate_name, err.name, found_use),
|
||||
Applicability::MachineApplicable
|
||||
).emit();
|
||||
} else {
|
||||
self.session.struct_span_err(err.use_span, err.warn_msg)
|
||||
.help(&format!("instead, import the procedural macro like any other item: \
|
||||
`use {}::{};`", err.crate_name, err.name))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {
|
||||
if !self.session.features_untracked().custom_derive {
|
||||
let sess = &self.session.parse_sess;
|
||||
|
@ -8,12 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-pass
|
||||
// aux-build:attr_proc_macro.rs
|
||||
|
||||
#[macro_use] extern crate attr_proc_macro;
|
||||
|
||||
#[attr_proc_macro]
|
||||
//~^ ERROR: attribute procedural macros cannot be imported with `#[macro_use]`
|
||||
struct Foo;
|
||||
|
||||
fn main() {
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-pass
|
||||
// aux-build:bang_proc_macro.rs
|
||||
|
||||
#![feature(proc_macro_non_items)]
|
||||
@ -17,5 +18,4 @@ extern crate bang_proc_macro;
|
||||
|
||||
fn main() {
|
||||
bang_proc_macro!(println!("Hello, world!"));
|
||||
//~^ ERROR: procedural macros cannot be imported with `#[macro_use]`
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user