Skip to content

Commit 2c2891b

Browse files
committed
Add structured suggestions for proc macro use imports
1 parent a24edb9 commit 2c2891b

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

src/librustc_resolve/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,8 @@ pub struct Resolver<'a> {
12901290
ambiguity_errors: Vec<AmbiguityError<'a>>,
12911291
/// `use` injections are delayed for better placement and deduplication
12921292
use_injections: Vec<UseError<'a>>,
1293+
/// `use` injections for proc macros wrongly imported with #[macro_use]
1294+
proc_mac_errors: Vec<macros::ProcMacError>,
12931295

12941296
gated_errors: FxHashSet<Span>,
12951297
disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
@@ -1498,6 +1500,7 @@ impl<'a> Resolver<'a> {
14981500
privacy_errors: Vec::new(),
14991501
ambiguity_errors: Vec::new(),
15001502
use_injections: Vec::new(),
1503+
proc_mac_errors: Vec::new(),
15011504
gated_errors: FxHashSet(),
15021505
disallowed_shadowing: Vec::new(),
15031506

@@ -3551,6 +3554,7 @@ impl<'a> Resolver<'a> {
35513554
fn report_errors(&mut self, krate: &Crate) {
35523555
self.report_shadowing_errors();
35533556
self.report_with_use_injections(krate);
3557+
self.report_proc_macro_import(krate);
35543558
let mut reported_spans = FxHashSet();
35553559

35563560
for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {

src/librustc_resolve/macros.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ pub struct LegacyBinding<'a> {
8383
pub span: Span,
8484
}
8585

86+
pub struct ProcMacError {
87+
crate_name: Symbol,
88+
name: Symbol,
89+
module: ast::NodeId,
90+
use_span: Span,
91+
warn_msg: &'static str,
92+
}
93+
8694
#[derive(Copy, Clone)]
8795
pub enum MacroBinding<'a> {
8896
Legacy(&'a LegacyBinding<'a>),
@@ -779,12 +787,37 @@ impl<'a> Resolver<'a> {
779787
_ => return,
780788
};
781789

782-
let crate_name = self.cstore.crate_name_untracked(krate);
790+
let def_id = self.current_module.normal_ancestor_id;
791+
let node_id = self.definitions.as_local_node_id(def_id).unwrap();
792+
793+
self.proc_mac_errors.push(ProcMacError {
794+
crate_name: self.cstore.crate_name_untracked(krate),
795+
name,
796+
module: node_id,
797+
use_span,
798+
warn_msg,
799+
});
800+
}
801+
802+
pub fn report_proc_macro_import(&mut self, krate: &ast::Crate) {
803+
for err in self.proc_mac_errors.drain(..) {
804+
let (span, found_use) = ::UsePlacementFinder::check(krate, err.module);
783805

784-
self.session.struct_span_err(use_span, warn_msg)
785-
.help(&format!("instead, import the procedural macro like any other item: \
786-
`use {}::{};`", crate_name, name))
787-
.emit();
806+
if let Some(span) = span {
807+
let found_use = if found_use { "" } else { "\n" };
808+
self.session.struct_span_err(err.use_span, err.warn_msg)
809+
.span_suggestion(
810+
span,
811+
"instead, import the procedural macro like any other item",
812+
format!("use {}::{};{}", err.crate_name, err.name, found_use),
813+
).emit();
814+
} else {
815+
self.session.struct_span_err(err.use_span, err.warn_msg)
816+
.help(&format!("instead, import the procedural macro like any other item: \
817+
`use {}::{};`", err.crate_name, err.name))
818+
.emit();
819+
}
820+
}
788821
}
789822

790823
fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {

src/test/ui/issue-35976.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ error: the `wait` method cannot be invoked on a trait object
33
|
44
24 | arg.wait();
55
| ^^^^
6-
|
76
help: another candidate was found in the following trait, perhaps add a `use` for it:
87
|
98
11 | use private::Future;

0 commit comments

Comments
 (0)