Skip to content

Commit d2a31ac

Browse files
committed
Fix macro expansion expression parenthesis wrapping
1 parent efa6729 commit d2a31ac

File tree

18 files changed

+218
-64
lines changed

18 files changed

+218
-64
lines changed

crates/base-db/src/span.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,25 @@ pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId =
1414

1515
pub type SpanData = tt::SpanData<SpanAnchor, SyntaxContextId>;
1616

17-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1818
pub struct SyntaxContextId(InternId);
19+
20+
impl fmt::Debug for SyntaxContextId {
21+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22+
if *self == Self::SELF_REF {
23+
f.debug_tuple("SyntaxContextId")
24+
.field(&{
25+
#[derive(Debug)]
26+
#[allow(non_camel_case_types)]
27+
struct SELF_REF;
28+
SELF_REF
29+
})
30+
.finish()
31+
} else {
32+
f.debug_tuple("SyntaxContextId").field(&self.0).finish()
33+
}
34+
}
35+
}
1936
crate::impl_intern_key!(SyntaxContextId);
2037

2138
impl fmt::Display for SyntaxContextId {
@@ -30,7 +47,7 @@ impl SyntaxContext for SyntaxContextId {
3047
// inherent trait impls please tyvm
3148
impl SyntaxContextId {
3249
pub const ROOT: Self = SyntaxContextId(unsafe { InternId::new_unchecked(0) });
33-
// veykril(HACK): salsa doesn't allow us fetching the id of the current input to be allocated so
50+
// veykril(HACK): FIXME salsa doesn't allow us fetching the id of the current input to be allocated so
3451
// we need a special value that behaves as the current context.
3552
pub const SELF_REF: Self =
3653
SyntaxContextId(unsafe { InternId::new_unchecked(InternId::MAX - 1) });
@@ -107,7 +124,7 @@ pub struct MacroFileId {
107124

108125
/// `MacroCallId` identifies a particular macro invocation, like
109126
/// `println!("Hello, {}", world)`.
110-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
127+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
111128
pub struct MacroCallId(salsa::InternId);
112129
crate::impl_intern_key!(MacroCallId);
113130

crates/hir-def/src/body/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ impl ExprCollector<'_> {
10251025

10261026
let id = collector(self, Some(expansion.tree()));
10271027
self.ast_id_map = prev_ast_id_map;
1028-
self.expander.exit(self.db, mark);
1028+
self.expander.exit(mark);
10291029
id
10301030
}
10311031
None => collector(self, None),

crates/hir-def/src/body/tests.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod block;
22

33
use base_db::{fixture::WithFixture, SourceDatabase};
44
use expect_test::{expect, Expect};
5+
use hir_expand::db::ExpandDatabase;
56

67
use crate::{test_db::TestDB, ModuleDefId};
78

@@ -143,7 +144,6 @@ mod m {
143144

144145
#[test]
145146
fn desugar_builtin_format_args() {
146-
// Regression test for a path resolution bug introduced with inner item handling.
147147
let (db, body, def) = lower(
148148
r#"
149149
//- minicore: fmt
@@ -221,3 +221,70 @@ fn main() {
221221
}"#]]
222222
.assert_eq(&body.pretty_print(&db, def))
223223
}
224+
225+
#[test]
226+
fn test_macro_hygiene() {
227+
let (db, body, def) = lower(
228+
r##"
229+
//- minicore: fmt, from
230+
//- /main.rs
231+
mod error;
232+
233+
use crate::error::error;
234+
235+
fn main() {
236+
// _ = forces body expansion instead of block def map expansion
237+
_ = error!("Failed to resolve path `{}`", node.text());
238+
}
239+
//- /error.rs
240+
macro_rules! _error {
241+
($fmt:expr, $($arg:tt)+) => {$crate::error::intermediate!(format_args!($fmt, $($arg)+))}
242+
}
243+
pub(crate) use _error as error;
244+
macro_rules! _intermediate {
245+
($arg:expr) => {$crate::error::SsrError::new($arg)}
246+
}
247+
pub(crate) use _intermediate as intermediate;
248+
249+
pub struct SsrError(pub(crate) core::fmt::Arguments);
250+
251+
impl SsrError {
252+
pub(crate) fn new(message: impl Into<core::fmt::Arguments>) -> SsrError {
253+
SsrError(message.into())
254+
}
255+
}
256+
"##,
257+
);
258+
println!("{}", db.dump_syntax_contexts());
259+
260+
assert_eq!(db.body_with_source_map(def.into()).1.diagnostics(), &[]);
261+
expect![[r#"
262+
fn main() {
263+
_ = $crate::error::SsrError::new(
264+
builtin#lang(Arguments::new_v1_formatted)(
265+
&[
266+
"\"Failed to resolve path `", "`\"",
267+
],
268+
&[
269+
builtin#lang(Argument::new_display)(
270+
&node.text(),
271+
),
272+
],
273+
&[
274+
builtin#lang(Placeholder::new)(
275+
0usize,
276+
' ',
277+
builtin#lang(Alignment::Unknown),
278+
0u32,
279+
builtin#lang(Count::Implied),
280+
builtin#lang(Count::Implied),
281+
),
282+
],
283+
unsafe {
284+
builtin#lang(UnsafeArg::new)()
285+
},
286+
),
287+
);
288+
}"#]]
289+
.assert_eq(&body.pretty_print(&db, def))
290+
}

crates/hir-def/src/data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ impl<'a> AssocItemCollector<'a> {
794794

795795
self.collect(&item_tree, tree_id, &iter);
796796

797-
self.expander.exit(self.db, mark);
797+
self.expander.exit(mark);
798798
}
799799
}
800800

crates/hir-def/src/expander.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ impl Expander {
9494
ExpandResult { value: Some(InFile::new(macro_file.into(), value.0)), err: error.or(err) }
9595
}
9696

97-
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
98-
self.span_map = db.span_map(mark.file_id);
97+
pub fn exit(&mut self, mut mark: Mark) {
98+
self.span_map = mark.span_map;
9999
self.current_file_id = mark.file_id;
100100
if self.recursion_depth == u32::MAX {
101101
// Recursion limit has been reached somewhere in the macro expansion tree. Reset the
@@ -174,10 +174,11 @@ impl Expander {
174174
let parse = value.cast::<T>()?;
175175

176176
self.recursion_depth += 1;
177-
self.span_map = db.span_map(file_id);
177+
let old_span_map = std::mem::replace(&mut self.span_map, db.span_map(file_id));
178178
let old_file_id = std::mem::replace(&mut self.current_file_id, file_id);
179179
let mark = Mark {
180180
file_id: old_file_id,
181+
span_map: old_span_map,
181182
bomb: DropBomb::new("expansion mark dropped"),
182183
};
183184
Some((mark, parse))
@@ -190,5 +191,6 @@ impl Expander {
190191
#[derive(Debug)]
191192
pub struct Mark {
192193
file_id: HirFileId,
194+
span_map: SpanMap,
193195
bomb: DropBomb,
194196
}

crates/hir-def/src/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ impl GenericParams {
439439
let ctx = expander.ctx(db);
440440
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
441441
self.fill_implicit_impl_trait_args(db, &mut *exp, &type_ref);
442-
exp.1.exit(db, mark);
442+
exp.1.exit(mark);
443443
}
444444
}
445445
});

crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -997,9 +997,9 @@ macro_rules! vec {
997997
fn f() {
998998
{
999999
let mut v = Vec::new();
1000-
v.push((1));
1001-
v.push((2));
1002-
v.push((3));
1000+
v.push(1);
1001+
v.push(2);
1002+
v.push(3);
10031003
v
10041004
};
10051005
}
@@ -1468,8 +1468,8 @@ macro_rules! matches {
14681468
};
14691469
}
14701470
fn main() {
1471-
match (0) {
1472-
0|1 if (true )=>true , _=>false
1471+
match 0 {
1472+
0|1 if true =>true , _=>false
14731473
};
14741474
}
14751475
"#]],

crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ macro_rules !implement_methods {
6262
struct Foo;
6363
impl Foo {
6464
fn alpha() -> &'static[u32] {
65-
&[(1), (2), (3)]
65+
&[1, 2, 3]
6666
}
6767
fn beta() -> &'static[u32] {
68-
&[(1), (2), (3)]
68+
&[1, 2, 3]
6969
}
7070
}
7171
"#]],

crates/hir-def/src/macro_expansion_tests/mbe/regression.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ fn main() {
3939
};
4040
{
4141
let mut v = Vec::new();
42-
v.push((1u32));
43-
v.push((2));
42+
v.push(1u32);
43+
v.push(2);
4444
v
4545
};
4646
}

crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ macro_rules! constant {
192192
($e:expr ;) => {$e};
193193
}
194194
195-
const _: () = (0.0);
196-
const _: () = (0.);
197-
const _: () = (0e0);
195+
const _: () = 0.0;
196+
const _: () = 0.;
197+
const _: () = 0e0;
198198
"#]],
199199
);
200200
}

0 commit comments

Comments
 (0)