Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3ce3593

Browse files
committedDec 21, 2023
Auto merge of rust-lang#16178 - Veykril:builtin-fn-callsite, r=Veykril
fix: Fix span marking for builtin fn macros
2 parents 9ee71b4 + 5bdb479 commit 3ce3593

File tree

10 files changed

+151
-55
lines changed

10 files changed

+151
-55
lines changed
 

‎crates/base-db/src/input.rs

+1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ pub enum Edition {
363363

364364
impl Edition {
365365
pub const CURRENT: Edition = Edition::Edition2021;
366+
pub const DEFAULT: Edition = Edition::Edition2015;
366367
}
367368

368369
#[derive(Default, Debug, Clone, PartialEq, Eq)]

‎crates/hir-def/src/db.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ use crate::{
2424
AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId,
2525
EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
2626
FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, InTypeConstLoc, LocalEnumVariantId,
27-
LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, ProcMacroId,
28-
ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId,
29-
TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
27+
LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags,
28+
ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
29+
TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc,
30+
VariantId,
3031
};
3132

3233
#[salsa::query_group(InternDatabaseStorage)]
@@ -338,8 +339,10 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
338339
span: db
339340
.span_map(loc.id.file_id())
340341
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
342+
edition: loc.edition,
341343
}
342344
}
345+
343346
MacroId::MacroRulesId(it) => {
344347
let loc: MacroRulesLoc = it.lookup(db);
345348

@@ -348,11 +351,14 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
348351
MacroDefId {
349352
krate: loc.container.krate,
350353
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
351-
local_inner: loc.local_inner,
352-
allow_internal_unsafe: loc.allow_internal_unsafe,
354+
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
355+
allow_internal_unsafe: loc
356+
.flags
357+
.contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE),
353358
span: db
354359
.span_map(loc.id.file_id())
355360
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
361+
edition: loc.edition,
356362
}
357363
}
358364
MacroId::ProcMacroId(it) => {
@@ -372,6 +378,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
372378
span: db
373379
.span_map(loc.id.file_id())
374380
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
381+
edition: loc.edition,
375382
}
376383
}
377384
}

‎crates/hir-def/src/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use std::{
6363
panic::{RefUnwindSafe, UnwindSafe},
6464
};
6565

66-
use base_db::{impl_intern_key, salsa, CrateId};
66+
use base_db::{impl_intern_key, salsa, CrateId, Edition};
6767
use hir_expand::{
6868
ast_id_map::{AstIdNode, FileAstId},
6969
attrs::{Attr, AttrId, AttrInput},
@@ -369,6 +369,7 @@ pub struct Macro2Loc {
369369
pub id: ItemTreeId<Macro2>,
370370
pub expander: MacroExpander,
371371
pub allow_internal_unsafe: bool,
372+
pub edition: Edition,
372373
}
373374
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
374375

@@ -379,11 +380,19 @@ pub struct MacroRulesLoc {
379380
pub container: ModuleId,
380381
pub id: ItemTreeId<MacroRules>,
381382
pub expander: MacroExpander,
382-
pub allow_internal_unsafe: bool,
383-
pub local_inner: bool,
383+
pub flags: MacroRulesLocFlags,
384+
pub edition: Edition,
384385
}
385386
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
386387

388+
bitflags::bitflags! {
389+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
390+
pub struct MacroRulesLocFlags: u8 {
391+
const ALLOW_INTERNAL_UNSAFE = 1 << 0;
392+
const LOCAL_INNER = 1 << 1;
393+
}
394+
}
395+
387396
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
388397
pub struct ProcMacroId(salsa::InternId);
389398
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -392,6 +401,7 @@ pub struct ProcMacroLoc {
392401
pub id: ItemTreeId<Function>,
393402
pub expander: CustomProcMacroExpander,
394403
pub kind: ProcMacroKind,
404+
pub edition: Edition,
395405
}
396406
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
397407

‎crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -163,31 +163,43 @@ fn main() { ""; }
163163
fn test_assert_expand() {
164164
check(
165165
r#"
166-
#[rustc_builtin_macro]
167-
macro_rules! assert {
168-
($cond:expr) => ({ /* compiler built-in */ });
169-
($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ })
170-
}
171-
166+
//- minicore: assert
172167
fn main() {
173168
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
174169
}
175170
"#,
176-
expect![[r##"
177-
#[rustc_builtin_macro]
178-
macro_rules! assert {
179-
($cond:expr) => ({ /* compiler built-in */ });
180-
($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ })
171+
expect![[r#"
172+
fn main() {
173+
{
174+
if !(true ) {
175+
$crate::panic::panic_2021!("{} {:?}", arg1(a, b, c), arg2);
176+
}
177+
};
178+
}
179+
"#]],
180+
);
181181
}
182182

183+
// FIXME: This is the wrong expansion, see FIXME on `builtin_fn_macro::use_panic_2021`
184+
#[test]
185+
fn test_assert_expand_2015() {
186+
check(
187+
r#"
188+
//- minicore: assert
189+
//- /main.rs edition:2015
190+
fn main() {
191+
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
192+
}
193+
"#,
194+
expect![[r#"
183195
fn main() {
184196
{
185197
if !(true ) {
186-
$crate::panic!("{} {:?}", arg1(a, b, c), arg2);
198+
$crate::panic::panic_2021!("{} {:?}", arg1(a, b, c), arg2);
187199
}
188200
};
189201
}
190-
"##]],
202+
"#]],
191203
);
192204
}
193205

‎crates/hir-def/src/nameres/collector.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ use crate::{
5454
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
5555
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
5656
ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
57-
MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
58-
StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
57+
MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId,
58+
ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc,
59+
UnresolvedMacro, UseId, UseLoc,
5960
};
6061

6162
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@@ -614,9 +615,14 @@ impl DefCollector<'_> {
614615
_ => (CustomProcMacroExpander::dummy(), kind),
615616
};
616617

617-
let proc_macro_id =
618-
ProcMacroLoc { container: self.def_map.crate_root(), id, expander, kind }
619-
.intern(self.db);
618+
let proc_macro_id = ProcMacroLoc {
619+
container: self.def_map.crate_root(),
620+
id,
621+
expander,
622+
kind,
623+
edition: self.def_map.data.edition,
624+
}
625+
.intern(self.db);
620626
self.define_proc_macro(def.name.clone(), proc_macro_id);
621627
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
622628
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
@@ -2138,12 +2144,16 @@ impl ModCollector<'_, '_> {
21382144
};
21392145
let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists();
21402146

2147+
let mut flags = MacroRulesLocFlags::empty();
2148+
flags.set(MacroRulesLocFlags::LOCAL_INNER, local_inner);
2149+
flags.set(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE, allow_internal_unsafe);
2150+
21412151
let macro_id = MacroRulesLoc {
21422152
container: module,
21432153
id: ItemTreeId::new(self.tree_id, id),
2144-
local_inner,
2145-
allow_internal_unsafe,
2154+
flags,
21462155
expander,
2156+
edition: self.def_collector.def_map.data.edition,
21472157
}
21482158
.intern(self.def_collector.db);
21492159
self.def_collector.define_macro_rules(
@@ -2209,6 +2219,7 @@ impl ModCollector<'_, '_> {
22092219
id: ItemTreeId::new(self.tree_id, id),
22102220
expander,
22112221
allow_internal_unsafe,
2222+
edition: self.def_collector.def_map.data.edition,
22122223
}
22132224
.intern(self.def_collector.db);
22142225
self.def_collector.define_macro_def(

‎crates/hir-expand/src/builtin_fn_macro.rs

+67-24
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ use syntax::{
1313

1414
use crate::{
1515
db::ExpandDatabase,
16-
hygiene::span_with_def_site_ctxt,
17-
name, quote,
16+
hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
17+
name::{self, known},
18+
quote,
1819
tt::{self, DelimSpan},
19-
ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroCallLoc,
20+
ExpandError, ExpandResult, HirFileIdExt, MacroCallId,
2021
};
2122

2223
macro_rules! register_builtin {
@@ -196,32 +197,38 @@ fn stringify_expand(
196197
}
197198

198199
fn assert_expand(
199-
_db: &dyn ExpandDatabase,
200-
_id: MacroCallId,
200+
db: &dyn ExpandDatabase,
201+
id: MacroCallId,
201202
tt: &tt::Subtree,
202203
span: Span,
203204
) -> ExpandResult<tt::Subtree> {
204-
let args = parse_exprs_with_sep(tt, ',', span);
205+
let call_site_span = span_with_call_site_ctxt(db, span, id);
206+
let args = parse_exprs_with_sep(tt, ',', call_site_span);
205207
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
206208
let expanded = match &*args {
207209
[cond, panic_args @ ..] => {
208210
let comma = tt::Subtree {
209-
delimiter: tt::Delimiter::invisible_spanned(span),
211+
delimiter: tt::Delimiter::invisible_spanned(call_site_span),
210212
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
211213
char: ',',
212214
spacing: tt::Spacing::Alone,
213-
span,
215+
span: call_site_span,
214216
}))],
215217
};
216218
let cond = cond.clone();
217219
let panic_args = itertools::Itertools::intersperse(panic_args.iter().cloned(), comma);
218-
quote! {span =>{
220+
let mac = if use_panic_2021(db, span) {
221+
quote! {call_site_span => #dollar_crate::panic::panic_2021!(##panic_args) }
222+
} else {
223+
quote! {call_site_span => #dollar_crate::panic!(##panic_args) }
224+
};
225+
quote! {call_site_span =>{
219226
if !(#cond) {
220-
#dollar_crate::panic!(##panic_args);
227+
#mac;
221228
}
222229
}}
223230
}
224-
[] => quote! {span =>{}},
231+
[] => quote! {call_site_span =>{}},
225232
};
226233

227234
ExpandResult::ok(expanded)
@@ -337,17 +344,23 @@ fn panic_expand(
337344
tt: &tt::Subtree,
338345
span: Span,
339346
) -> ExpandResult<tt::Subtree> {
340-
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
341347
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
348+
let call_site_span = span_with_call_site_ctxt(db, span, id);
349+
350+
let mac =
351+
if use_panic_2021(db, call_site_span) { known::panic_2021 } else { known::panic_2015 };
352+
342353
// Expand to a macro call `$crate::panic::panic_{edition}`
343-
let mut call = if db.crate_graph()[loc.krate].edition >= Edition::Edition2021 {
344-
quote!(span =>#dollar_crate::panic::panic_2021!)
345-
} else {
346-
quote!(span =>#dollar_crate::panic::panic_2015!)
347-
};
354+
let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!);
348355

349356
// Pass the original arguments
350-
call.token_trees.push(tt::TokenTree::Subtree(tt.clone()));
357+
let mut subtree = tt.clone();
358+
subtree.delimiter = tt::Delimiter {
359+
open: call_site_span,
360+
close: call_site_span,
361+
kind: tt::DelimiterKind::Parenthesis,
362+
};
363+
call.token_trees.push(tt::TokenTree::Subtree(subtree));
351364
ExpandResult::ok(call)
352365
}
353366

@@ -357,20 +370,50 @@ fn unreachable_expand(
357370
tt: &tt::Subtree,
358371
span: Span,
359372
) -> ExpandResult<tt::Subtree> {
360-
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
361-
// Expand to a macro call `$crate::panic::unreachable_{edition}`
362373
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
363-
let mut call = if db.crate_graph()[loc.krate].edition >= Edition::Edition2021 {
364-
quote!(span =>#dollar_crate::panic::unreachable_2021!)
374+
let call_site_span = span_with_call_site_ctxt(db, span, id);
375+
376+
let mac = if use_panic_2021(db, call_site_span) {
377+
known::unreachable_2021
365378
} else {
366-
quote!(span =>#dollar_crate::panic::unreachable_2015!)
379+
known::unreachable_2015
367380
};
368381

382+
// Expand to a macro call `$crate::panic::panic_{edition}`
383+
let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!);
384+
369385
// Pass the original arguments
370-
call.token_trees.push(tt::TokenTree::Subtree(tt.clone()));
386+
let mut subtree = tt.clone();
387+
subtree.delimiter = tt::Delimiter {
388+
open: call_site_span,
389+
close: call_site_span,
390+
kind: tt::DelimiterKind::Parenthesis,
391+
};
392+
call.token_trees.push(tt::TokenTree::Subtree(subtree));
371393
ExpandResult::ok(call)
372394
}
373395

396+
fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool {
397+
// To determine the edition, we check the first span up the expansion
398+
// stack that does not have #[allow_internal_unstable(edition_panic)].
399+
// (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
400+
loop {
401+
let Some(expn) = db.lookup_intern_syntax_context(span.ctx).outer_expn else {
402+
break false;
403+
};
404+
let expn = db.lookup_intern_macro_call(expn);
405+
// FIXME: Record allow_internal_unstable in the macro def (not been done yet because it
406+
// would consume quite a bit extra memory for all call locs...)
407+
// if let Some(features) = expn.def.allow_internal_unstable {
408+
// if features.iter().any(|&f| f == sym::edition_panic) {
409+
// span = expn.call_site;
410+
// continue;
411+
// }
412+
// }
413+
break expn.def.edition >= Edition::Edition2021;
414+
}
415+
}
416+
374417
fn unquote_str(lit: &tt::Literal) -> Option<String> {
375418
let lit = ast::make::tokens::literal(&lit.to_string());
376419
let token = ast::String::cast(lit)?;

‎crates/hir-expand/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use triomphe::Arc;
2828

2929
use std::{fmt, hash::Hash};
3030

31-
use base_db::{CrateId, FileId};
31+
use base_db::{CrateId, Edition, FileId};
3232
use either::Either;
3333
use span::{FileRange, HirFileIdRepr, Span, SyntaxContextId};
3434
use syntax::{
@@ -176,6 +176,7 @@ pub struct MacroCallLoc {
176176
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
177177
pub struct MacroDefId {
178178
pub krate: CrateId,
179+
pub edition: Edition,
179180
pub kind: MacroDefKind,
180181
pub local_inner: bool,
181182
pub allow_internal_unsafe: bool,

‎crates/hir-expand/src/name.rs

+4
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ pub mod known {
318318
new_lower_hex,
319319
new_upper_hex,
320320
from_usize,
321+
panic_2015,
322+
panic_2021,
323+
unreachable_2015,
324+
unreachable_2021,
321325
// Components of known path (type name)
322326
Iterator,
323327
IntoIterator,
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.