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:
bors 2018-09-16 20:28:21 +00:00
commit cb6d2dfa89
6 changed files with 2 additions and 83 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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() {

View File

@ -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]`
}