Skip to content

Commit 15d8f0c

Browse files
bors[bot]Jonas Schievink
and
Jonas Schievink
authored
Merge #11354
11354: fix: More correct `$crate` handling in eager macros r=jonas-schievink a=jonas-schievink Fixes a few of the additional bugs in #10300, but not yet that issue itself. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents e149a15 + 6c0fcb5 commit 15d8f0c

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

crates/hir_def/src/nameres/tests/macros.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,7 @@ struct B;
10861086

10871087
#[test]
10881088
fn eager_macro_correctly_resolves_dollar_crate() {
1089+
// MBE -> eager -> $crate::mbe
10891090
check(
10901091
r#"
10911092
//- /lib.rs
@@ -1108,9 +1109,37 @@ struct A;
11081109
"#,
11091110
expect![[r#"
11101111
crate
1112+
A: t v
11111113
inner: m
11121114
"#]],
11131115
);
1116+
// eager -> MBE -> $crate::mbe
1117+
check(
1118+
r#"
1119+
//- /lib.rs
1120+
#[rustc_builtin_macro]
1121+
macro_rules! include { () => {} }
1122+
1123+
#[macro_export]
1124+
macro_rules! inner {
1125+
() => { "inc.rs" };
1126+
}
11141127
1115-
// FIXME: This currently fails. The result should contain `A: t v`.
1128+
macro_rules! n {
1129+
() => {
1130+
$crate::inner!()
1131+
};
1132+
}
1133+
1134+
include!(n!());
1135+
1136+
//- /inc.rs
1137+
struct A;
1138+
"#,
1139+
expect![[r#"
1140+
crate
1141+
A: t v
1142+
inner: m
1143+
"#]],
1144+
);
11161145
}

crates/hir_expand/src/eager.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub fn expand_eager_macro(
104104
resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
105105
diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
106106
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
107+
let hygiene = Hygiene::new(db, macro_call.file_id);
107108
let parsed_args = macro_call
108109
.value
109110
.token_tree()
@@ -131,6 +132,7 @@ pub fn expand_eager_macro(
131132
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, mbe::TopEntryPoint::Expr).0;
132133
let result = match eager_macro_recur(
133134
db,
135+
&hygiene,
134136
InFile::new(arg_id.as_file(), parsed_args.syntax_node()),
135137
krate,
136138
resolver,
@@ -193,12 +195,12 @@ fn lazy_expand(
193195

194196
fn eager_macro_recur(
195197
db: &dyn AstDatabase,
198+
hygiene: &Hygiene,
196199
curr: InFile<SyntaxNode>,
197200
krate: CrateId,
198201
macro_resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
199202
mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
200203
) -> Result<Result<SyntaxNode, ErrorEmitted>, UnresolvedMacro> {
201-
let hygiene = Hygiene::new(db, curr.file_id);
202204
let original = curr.value.clone_for_update();
203205

204206
let children = original.descendants().filter_map(ast::MacroCall::cast);
@@ -243,7 +245,8 @@ fn eager_macro_recur(
243245
};
244246

245247
// replace macro inside
246-
match eager_macro_recur(db, val, krate, macro_resolver, diagnostic_sink) {
248+
let hygiene = Hygiene::new(db, val.file_id);
249+
match eager_macro_recur(db, &hygiene, val, krate, macro_resolver, diagnostic_sink) {
247250
Ok(Ok(it)) => it,
248251
Ok(Err(err)) => return Ok(Err(err)),
249252
Err(err) => return Err(err),

crates/ide_diagnostics/src/handlers/macro_error.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,45 @@ macro_rules! compile_error { () => {} }
3838
);
3939
}
4040

41+
#[test]
42+
fn eager_macro_concat() {
43+
// FIXME: this is incorrectly handling `$crate`, resulting in a wrong diagnostic.
44+
// See: https://github.com/rust-analyzer/rust-analyzer/issues/10300
45+
46+
check_diagnostics(
47+
r#"
48+
//- /lib.rs crate:lib deps:core
49+
use core::{panic, concat};
50+
51+
mod private {
52+
pub use core::concat;
53+
}
54+
55+
macro_rules! m {
56+
() => {
57+
panic!(concat!($crate::private::concat!("")));
58+
};
59+
}
60+
61+
fn f() {
62+
m!();
63+
//^^^^ error: unresolved macro `$crate::private::concat!`
64+
}
65+
66+
//- /core.rs crate:core
67+
#[macro_export]
68+
#[rustc_builtin_macro]
69+
macro_rules! concat { () => {} }
70+
71+
pub macro panic {
72+
($msg:expr) => (
73+
$crate::panicking::panic_str($msg)
74+
),
75+
}
76+
"#,
77+
);
78+
}
79+
4180
#[test]
4281
fn include_macro_should_allow_empty_content() {
4382
let mut config = DiagnosticsConfig::default();

0 commit comments

Comments
 (0)