Add structured suggestions for proc macro use imports

This commit is contained in:
Oliver Schneider 2017-11-16 15:03:25 +01:00
parent a24edb9bce
commit 2c2891b9f5
No known key found for this signature in database
GPG Key ID: A69F8D225B3AD7D9
3 changed files with 42 additions and 6 deletions

View File

@ -1290,6 +1290,8 @@ pub struct Resolver<'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>,
gated_errors: FxHashSet<Span>,
disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
@ -1498,6 +1500,7 @@ impl<'a> Resolver<'a> {
privacy_errors: Vec::new(),
ambiguity_errors: Vec::new(),
use_injections: Vec::new(),
proc_mac_errors: Vec::new(),
gated_errors: FxHashSet(),
disallowed_shadowing: Vec::new(),
@ -3551,6 +3554,7 @@ impl<'a> Resolver<'a> {
fn report_errors(&mut self, krate: &Crate) {
self.report_shadowing_errors();
self.report_with_use_injections(krate);
self.report_proc_macro_import(krate);
let mut reported_spans = FxHashSet();
for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {

View File

@ -83,6 +83,14 @@ pub struct LegacyBinding<'a> {
pub span: Span,
}
pub struct ProcMacError {
crate_name: Symbol,
name: Symbol,
module: ast::NodeId,
use_span: Span,
warn_msg: &'static str,
}
#[derive(Copy, Clone)]
pub enum MacroBinding<'a> {
Legacy(&'a LegacyBinding<'a>),
@ -779,12 +787,37 @@ impl<'a> Resolver<'a> {
_ => return,
};
let crate_name = self.cstore.crate_name_untracked(krate);
let def_id = self.current_module.normal_ancestor_id;
let node_id = self.definitions.as_local_node_id(def_id).unwrap();
self.session.struct_span_err(use_span, warn_msg)
.help(&format!("instead, import the procedural macro like any other item: \
`use {}::{};`", crate_name, name))
.emit();
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(
span,
"instead, import the procedural macro like any other item",
format!("use {}::{};{}", err.crate_name, err.name, found_use),
).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) {

View File

@ -3,7 +3,6 @@ error: the `wait` method cannot be invoked on a trait object
|
24 | arg.wait();
| ^^^^
|
help: another candidate was found in the following trait, perhaps add a `use` for it:
|
11 | use private::Future;