Skip to content

Commit

Permalink
Suggest moving if non-found macro_rules! is defined later
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Feb 19, 2024
1 parent eb1f279 commit 75a4fa1
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 1 deletion.
7 changes: 7 additions & 0 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 87,10 @@ resolve_consider_declaring_with_pub =
resolve_consider_marking_as_pub =
consider marking `{$ident}` as `pub` in the imported module
resolve_consider_move_macro_position =
consider moving the definition of `{$ident}` before this call
resolve_const_not_member_of_trait =
const `{$const_}` is not a member of trait `{$trait_}`
.label = not a member of trait `{$trait_}`
Expand Down Expand Up @@ -186,6 190,9 @@ resolve_lowercase_self =
attempt to use a non-constant value in a constant
.suggestion = try using `Self`
resolve_macro_defined_later =
a macro with the same name exists, but it appears later at here
resolve_macro_expected_found =
expected {$expected}, found {$found} `{$macro_path}`
Expand Down
23 changes: 22 additions & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 30,10 @@ use rustc_span::{BytePos, Span, SyntaxContext};
use thin_vec::{thin_vec, ThinVec};

use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion};
use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName};
use crate::errors::{
ConsiderAddingADerive, ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition,
MaybeMissingMacroRulesName,
};
use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::{errors as errs, BindingKey};
Expand Down Expand Up @@ -1442,6 1445,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return;
}

let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident))| {
if unused_ident.name == ident.name {
Some((def_id.clone(), unused_ident.clone()))
} else {
None
}
});

if let Some((def_id, unused_ident)) = unused_macro {
let scope = self.local_macro_def_scopes[&def_id];
let parent_nearest = parent_scope.module.nearest_parent_mod();
if Some(parent_nearest) == scope.opt_def_id() {
err.subdiagnostic(self.dcx(), MacroDefinedLater { span: unused_ident.span });
err.subdiagnostic(self.dcx(), MacroSuggMovePosition { span: ident.span, ident });
return;
}
}

if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
err.subdiagnostic(self.dcx(), AddedMacroUse);
return;
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 685,21 @@ pub(crate) struct ExplicitUnsafeTraits {
pub(crate) ident: Ident,
}

#[derive(Subdiagnostic)]
#[note(resolve_macro_defined_later)]
pub(crate) struct MacroDefinedLater {
#[primary_span]
pub(crate) span: Span,
}

#[derive(Subdiagnostic)]
#[label(resolve_consider_move_macro_position)]
pub(crate) struct MacroSuggMovePosition {
#[primary_span]
pub(crate) span: Span,
pub(crate) ident: Ident,
}

#[derive(Subdiagnostic)]
#[note(resolve_missing_macro_rules_name)]
pub(crate) struct MaybeMissingMacroRulesName {
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/macros/issue-121061-defined-later-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 1,13 @@
mod demo {
fn hello() {
something_later!(); //~ ERROR cannot find macro `something_later` in this scope
}

macro_rules! something_later {
() => {
println!("successfully expanded!");
};
}
}

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/macros/issue-121061-defined-later-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 1,14 @@
error: cannot find macro `something_later` in this scope
--> $DIR/issue-121061-defined-later-2.rs:3:9
|
LL | something_later!();
| ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
|
note: a macro with the same name exists, but it appears later at here
--> $DIR/issue-121061-defined-later-2.rs:6:18
|
LL | macro_rules! something_later {
| ^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

9 changes: 9 additions & 0 deletions tests/ui/macros/issue-121061-defined-later.rs
Original file line number Diff line number Diff line change
@@ -0,0 1,9 @@
fn main() {
something_later!(); //~ ERROR cannot find macro `something_later` in this scope
}

macro_rules! something_later {
() => {
println!("successfully expanded!");
};
}
14 changes: 14 additions & 0 deletions tests/ui/macros/issue-121061-defined-later.stderr
Original file line number Diff line number Diff line change
@@ -0,0 1,14 @@
error: cannot find macro `something_later` in this scope
--> $DIR/issue-121061-defined-later.rs:2:5
|
LL | something_later!();
| ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
|
note: a macro with the same name exists, but it appears later at here
--> $DIR/issue-121061-defined-later.rs:5:14
|
LL | macro_rules! something_later {
| ^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

0 comments on commit 75a4fa1

Please sign in to comment.