mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
fix: Fix span marking for builtin fn macros
This commit is contained in:
parent
1e1113cf5f
commit
5bdb479131
10 changed files with 153 additions and 57 deletions
|
@ -362,6 +362,7 @@ pub enum Edition {
|
||||||
|
|
||||||
impl Edition {
|
impl Edition {
|
||||||
pub const CURRENT: Edition = Edition::Edition2021;
|
pub const CURRENT: Edition = Edition::Edition2021;
|
||||||
|
pub const DEFAULT: Edition = Edition::Edition2015;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
|
@ -24,9 +24,10 @@ use crate::{
|
||||||
AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId,
|
AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId,
|
||||||
EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
|
EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
|
||||||
FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, InTypeConstLoc, LocalEnumVariantId,
|
FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, InTypeConstLoc, LocalEnumVariantId,
|
||||||
LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, ProcMacroId,
|
LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags,
|
||||||
ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId,
|
ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
|
||||||
TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
|
TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc,
|
||||||
|
VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::query_group(InternDatabaseStorage)]
|
#[salsa::query_group(InternDatabaseStorage)]
|
||||||
|
@ -338,8 +339,10 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
span: db
|
span: db
|
||||||
.span_map(loc.id.file_id())
|
.span_map(loc.id.file_id())
|
||||||
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
||||||
|
edition: loc.edition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroId::MacroRulesId(it) => {
|
MacroId::MacroRulesId(it) => {
|
||||||
let loc: MacroRulesLoc = it.lookup(db);
|
let loc: MacroRulesLoc = it.lookup(db);
|
||||||
|
|
||||||
|
@ -348,11 +351,14 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
MacroDefId {
|
MacroDefId {
|
||||||
krate: loc.container.krate,
|
krate: loc.container.krate,
|
||||||
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
||||||
local_inner: loc.local_inner,
|
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
|
||||||
allow_internal_unsafe: loc.allow_internal_unsafe,
|
allow_internal_unsafe: loc
|
||||||
|
.flags
|
||||||
|
.contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE),
|
||||||
span: db
|
span: db
|
||||||
.span_map(loc.id.file_id())
|
.span_map(loc.id.file_id())
|
||||||
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
||||||
|
edition: loc.edition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MacroId::ProcMacroId(it) => {
|
MacroId::ProcMacroId(it) => {
|
||||||
|
@ -372,6 +378,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
span: db
|
span: db
|
||||||
.span_map(loc.id.file_id())
|
.span_map(loc.id.file_id())
|
||||||
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
|
||||||
|
edition: loc.edition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ use std::{
|
||||||
panic::{RefUnwindSafe, UnwindSafe},
|
panic::{RefUnwindSafe, UnwindSafe},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base_db::{impl_intern_key, salsa, CrateId};
|
use base_db::{impl_intern_key, salsa, CrateId, Edition};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::{AstIdNode, FileAstId},
|
ast_id_map::{AstIdNode, FileAstId},
|
||||||
attrs::{Attr, AttrId, AttrInput},
|
attrs::{Attr, AttrId, AttrInput},
|
||||||
|
@ -369,6 +369,7 @@ pub struct Macro2Loc {
|
||||||
pub id: ItemTreeId<Macro2>,
|
pub id: ItemTreeId<Macro2>,
|
||||||
pub expander: MacroExpander,
|
pub expander: MacroExpander,
|
||||||
pub allow_internal_unsafe: bool,
|
pub allow_internal_unsafe: bool,
|
||||||
|
pub edition: Edition,
|
||||||
}
|
}
|
||||||
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
||||||
|
|
||||||
|
@ -379,11 +380,19 @@ pub struct MacroRulesLoc {
|
||||||
pub container: ModuleId,
|
pub container: ModuleId,
|
||||||
pub id: ItemTreeId<MacroRules>,
|
pub id: ItemTreeId<MacroRules>,
|
||||||
pub expander: MacroExpander,
|
pub expander: MacroExpander,
|
||||||
pub allow_internal_unsafe: bool,
|
pub flags: MacroRulesLocFlags,
|
||||||
pub local_inner: bool,
|
pub edition: Edition,
|
||||||
}
|
}
|
||||||
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct MacroRulesLocFlags: u8 {
|
||||||
|
const ALLOW_INTERNAL_UNSAFE = 1 << 0;
|
||||||
|
const LOCAL_INNER = 1 << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
pub struct ProcMacroId(salsa::InternId);
|
pub struct ProcMacroId(salsa::InternId);
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -392,6 +401,7 @@ pub struct ProcMacroLoc {
|
||||||
pub id: ItemTreeId<Function>,
|
pub id: ItemTreeId<Function>,
|
||||||
pub expander: CustomProcMacroExpander,
|
pub expander: CustomProcMacroExpander,
|
||||||
pub kind: ProcMacroKind,
|
pub kind: ProcMacroKind,
|
||||||
|
pub edition: Edition,
|
||||||
}
|
}
|
||||||
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
||||||
|
|
||||||
|
|
|
@ -163,31 +163,43 @@ fn main() { ""; }
|
||||||
fn test_assert_expand() {
|
fn test_assert_expand() {
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
#[rustc_builtin_macro]
|
//- minicore: assert
|
||||||
macro_rules! assert {
|
|
||||||
($cond:expr) => ({ /* compiler built-in */ });
|
|
||||||
($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
|
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r##"
|
expect![[r#"
|
||||||
#[rustc_builtin_macro]
|
|
||||||
macro_rules! assert {
|
|
||||||
($cond:expr) => ({ /* compiler built-in */ });
|
|
||||||
($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
{
|
{
|
||||||
if !(true ) {
|
if !(true ) {
|
||||||
$crate::panic!("{} {:?}", arg1(a, b, c), arg2);
|
$crate::panic::panic_2021!("{} {:?}", arg1(a, b, c), arg2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
"##]],
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This is the wrong expansion, see FIXME on `builtin_fn_macro::use_panic_2021`
|
||||||
|
#[test]
|
||||||
|
fn test_assert_expand_2015() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: assert
|
||||||
|
//- /main.rs edition:2015
|
||||||
|
fn main() {
|
||||||
|
assert!(true, "{} {:?}", arg1(a, b, c), arg2);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
fn main() {
|
||||||
|
{
|
||||||
|
if !(true ) {
|
||||||
|
$crate::panic::panic_2021!("{} {:?}", arg1(a, b, c), arg2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,9 @@ use crate::{
|
||||||
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
||||||
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
|
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
|
||||||
ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
|
ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
|
||||||
MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
|
MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId,
|
||||||
StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
|
ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc,
|
||||||
|
UnresolvedMacro, UseId, UseLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||||
|
@ -612,9 +613,14 @@ impl DefCollector<'_> {
|
||||||
_ => (CustomProcMacroExpander::dummy(), kind),
|
_ => (CustomProcMacroExpander::dummy(), kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
let proc_macro_id =
|
let proc_macro_id = ProcMacroLoc {
|
||||||
ProcMacroLoc { container: self.def_map.crate_root(), id, expander, kind }
|
container: self.def_map.crate_root(),
|
||||||
.intern(self.db);
|
id,
|
||||||
|
expander,
|
||||||
|
kind,
|
||||||
|
edition: self.def_map.data.edition,
|
||||||
|
}
|
||||||
|
.intern(self.db);
|
||||||
self.define_proc_macro(def.name.clone(), proc_macro_id);
|
self.define_proc_macro(def.name.clone(), proc_macro_id);
|
||||||
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
||||||
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
|
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
|
||||||
|
@ -2136,12 +2142,16 @@ impl ModCollector<'_, '_> {
|
||||||
};
|
};
|
||||||
let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists();
|
let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists();
|
||||||
|
|
||||||
|
let mut flags = MacroRulesLocFlags::empty();
|
||||||
|
flags.set(MacroRulesLocFlags::LOCAL_INNER, local_inner);
|
||||||
|
flags.set(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE, allow_internal_unsafe);
|
||||||
|
|
||||||
let macro_id = MacroRulesLoc {
|
let macro_id = MacroRulesLoc {
|
||||||
container: module,
|
container: module,
|
||||||
id: ItemTreeId::new(self.tree_id, id),
|
id: ItemTreeId::new(self.tree_id, id),
|
||||||
local_inner,
|
flags,
|
||||||
allow_internal_unsafe,
|
|
||||||
expander,
|
expander,
|
||||||
|
edition: self.def_collector.def_map.data.edition,
|
||||||
}
|
}
|
||||||
.intern(self.def_collector.db);
|
.intern(self.def_collector.db);
|
||||||
self.def_collector.define_macro_rules(
|
self.def_collector.define_macro_rules(
|
||||||
|
@ -2207,6 +2217,7 @@ impl ModCollector<'_, '_> {
|
||||||
id: ItemTreeId::new(self.tree_id, id),
|
id: ItemTreeId::new(self.tree_id, id),
|
||||||
expander,
|
expander,
|
||||||
allow_internal_unsafe,
|
allow_internal_unsafe,
|
||||||
|
edition: self.def_collector.def_map.data.edition,
|
||||||
}
|
}
|
||||||
.intern(self.def_collector.db);
|
.intern(self.def_collector.db);
|
||||||
self.def_collector.define_macro_def(
|
self.def_collector.define_macro_def(
|
||||||
|
|
|
@ -13,10 +13,11 @@ use syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
hygiene::span_with_def_site_ctxt,
|
hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
|
||||||
name, quote,
|
name::{self, known},
|
||||||
|
quote,
|
||||||
tt::{self, DelimSpan},
|
tt::{self, DelimSpan},
|
||||||
ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroCallLoc,
|
ExpandError, ExpandResult, HirFileIdExt, MacroCallId,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
|
@ -196,32 +197,38 @@ fn stringify_expand(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_expand(
|
fn assert_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let args = parse_exprs_with_sep(tt, ',', span);
|
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||||
|
let args = parse_exprs_with_sep(tt, ',', call_site_span);
|
||||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||||
let expanded = match &*args {
|
let expanded = match &*args {
|
||||||
[cond, panic_args @ ..] => {
|
[cond, panic_args @ ..] => {
|
||||||
let comma = tt::Subtree {
|
let comma = tt::Subtree {
|
||||||
delimiter: tt::Delimiter::invisible_spanned(span),
|
delimiter: tt::Delimiter::invisible_spanned(call_site_span),
|
||||||
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
|
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
|
||||||
char: ',',
|
char: ',',
|
||||||
spacing: tt::Spacing::Alone,
|
spacing: tt::Spacing::Alone,
|
||||||
span,
|
span: call_site_span,
|
||||||
}))],
|
}))],
|
||||||
};
|
};
|
||||||
let cond = cond.clone();
|
let cond = cond.clone();
|
||||||
let panic_args = itertools::Itertools::intersperse(panic_args.iter().cloned(), comma);
|
let panic_args = itertools::Itertools::intersperse(panic_args.iter().cloned(), comma);
|
||||||
quote! {span =>{
|
let mac = if use_panic_2021(db, span) {
|
||||||
|
quote! {call_site_span => #dollar_crate::panic::panic_2021!(##panic_args) }
|
||||||
|
} else {
|
||||||
|
quote! {call_site_span => #dollar_crate::panic!(##panic_args) }
|
||||||
|
};
|
||||||
|
quote! {call_site_span =>{
|
||||||
if !(#cond) {
|
if !(#cond) {
|
||||||
#dollar_crate::panic!(##panic_args);
|
#mac;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
[] => quote! {span =>{}},
|
[] => quote! {call_site_span =>{}},
|
||||||
};
|
};
|
||||||
|
|
||||||
ExpandResult::ok(expanded)
|
ExpandResult::ok(expanded)
|
||||||
|
@ -337,17 +344,23 @@ fn panic_expand(
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
|
||||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||||
|
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||||
|
|
||||||
|
let mac =
|
||||||
|
if use_panic_2021(db, call_site_span) { known::panic_2021 } else { known::panic_2015 };
|
||||||
|
|
||||||
// Expand to a macro call `$crate::panic::panic_{edition}`
|
// Expand to a macro call `$crate::panic::panic_{edition}`
|
||||||
let mut call = if db.crate_graph()[loc.krate].edition >= Edition::Edition2021 {
|
let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!);
|
||||||
quote!(span =>#dollar_crate::panic::panic_2021!)
|
|
||||||
} else {
|
|
||||||
quote!(span =>#dollar_crate::panic::panic_2015!)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Pass the original arguments
|
// Pass the original arguments
|
||||||
call.token_trees.push(tt::TokenTree::Subtree(tt.clone()));
|
let mut subtree = tt.clone();
|
||||||
|
subtree.delimiter = tt::Delimiter {
|
||||||
|
open: call_site_span,
|
||||||
|
close: call_site_span,
|
||||||
|
kind: tt::DelimiterKind::Parenthesis,
|
||||||
|
};
|
||||||
|
call.token_trees.push(tt::TokenTree::Subtree(subtree));
|
||||||
ExpandResult::ok(call)
|
ExpandResult::ok(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,20 +370,50 @@ fn unreachable_expand(
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
|
||||||
// Expand to a macro call `$crate::panic::unreachable_{edition}`
|
|
||||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||||
let mut call = if db.crate_graph()[loc.krate].edition >= Edition::Edition2021 {
|
let call_site_span = span_with_call_site_ctxt(db, span, id);
|
||||||
quote!(span =>#dollar_crate::panic::unreachable_2021!)
|
|
||||||
|
let mac = if use_panic_2021(db, call_site_span) {
|
||||||
|
known::unreachable_2021
|
||||||
} else {
|
} else {
|
||||||
quote!(span =>#dollar_crate::panic::unreachable_2015!)
|
known::unreachable_2015
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Expand to a macro call `$crate::panic::panic_{edition}`
|
||||||
|
let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!);
|
||||||
|
|
||||||
// Pass the original arguments
|
// Pass the original arguments
|
||||||
call.token_trees.push(tt::TokenTree::Subtree(tt.clone()));
|
let mut subtree = tt.clone();
|
||||||
|
subtree.delimiter = tt::Delimiter {
|
||||||
|
open: call_site_span,
|
||||||
|
close: call_site_span,
|
||||||
|
kind: tt::DelimiterKind::Parenthesis,
|
||||||
|
};
|
||||||
|
call.token_trees.push(tt::TokenTree::Subtree(subtree));
|
||||||
ExpandResult::ok(call)
|
ExpandResult::ok(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool {
|
||||||
|
// To determine the edition, we check the first span up the expansion
|
||||||
|
// stack that does not have #[allow_internal_unstable(edition_panic)].
|
||||||
|
// (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
|
||||||
|
loop {
|
||||||
|
let Some(expn) = db.lookup_intern_syntax_context(span.ctx).outer_expn else {
|
||||||
|
break false;
|
||||||
|
};
|
||||||
|
let expn = db.lookup_intern_macro_call(expn);
|
||||||
|
// FIXME: Record allow_internal_unstable in the macro def (not been done yet because it
|
||||||
|
// would consume quite a bit extra memory for all call locs...)
|
||||||
|
// if let Some(features) = expn.def.allow_internal_unstable {
|
||||||
|
// if features.iter().any(|&f| f == sym::edition_panic) {
|
||||||
|
// span = expn.call_site;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
break expn.def.edition >= Edition::Edition2021;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn unquote_str(lit: &tt::Literal) -> Option<String> {
|
fn unquote_str(lit: &tt::Literal) -> Option<String> {
|
||||||
let lit = ast::make::tokens::literal(&lit.to_string());
|
let lit = ast::make::tokens::literal(&lit.to_string());
|
||||||
let token = ast::String::cast(lit)?;
|
let token = ast::String::cast(lit)?;
|
||||||
|
|
|
@ -28,7 +28,7 @@ use triomphe::Arc;
|
||||||
|
|
||||||
use std::{fmt, hash::Hash};
|
use std::{fmt, hash::Hash};
|
||||||
|
|
||||||
use base_db::{CrateId, FileId};
|
use base_db::{CrateId, Edition, FileId};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use span::{FileRange, HirFileIdRepr, Span, SyntaxContextId};
|
use span::{FileRange, HirFileIdRepr, Span, SyntaxContextId};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
|
@ -176,6 +176,7 @@ pub struct MacroCallLoc {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct MacroDefId {
|
pub struct MacroDefId {
|
||||||
pub krate: CrateId,
|
pub krate: CrateId,
|
||||||
|
pub edition: Edition,
|
||||||
pub kind: MacroDefKind,
|
pub kind: MacroDefKind,
|
||||||
pub local_inner: bool,
|
pub local_inner: bool,
|
||||||
pub allow_internal_unsafe: bool,
|
pub allow_internal_unsafe: bool,
|
||||||
|
|
|
@ -318,6 +318,10 @@ pub mod known {
|
||||||
new_lower_hex,
|
new_lower_hex,
|
||||||
new_upper_hex,
|
new_upper_hex,
|
||||||
from_usize,
|
from_usize,
|
||||||
|
panic_2015,
|
||||||
|
panic_2021,
|
||||||
|
unreachable_2015,
|
||||||
|
unreachable_2021,
|
||||||
// Components of known path (type name)
|
// Components of known path (type name)
|
||||||
Iterator,
|
Iterator,
|
||||||
IntoIterator,
|
IntoIterator,
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use span::Span;
|
use span::Span;
|
||||||
|
|
||||||
|
use crate::name::Name;
|
||||||
|
|
||||||
// A helper macro quote macro
|
// A helper macro quote macro
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// 1. Not all puncts are handled
|
// 1. Not all puncts are handled
|
||||||
|
@ -180,7 +182,7 @@ impl ToTokenTree for crate::tt::Subtree {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_to_to_tokentrees {
|
macro_rules! impl_to_to_tokentrees {
|
||||||
($($span:ident: $ty:ty => $this:ident $im:block);*) => {
|
($($span:ident: $ty:ty => $this:ident $im:block;)*) => {
|
||||||
$(
|
$(
|
||||||
impl ToTokenTree for $ty {
|
impl ToTokenTree for $ty {
|
||||||
fn to_token($this, $span: Span) -> crate::tt::TokenTree {
|
fn to_token($this, $span: Span) -> crate::tt::TokenTree {
|
||||||
|
@ -209,7 +211,8 @@ impl_to_to_tokentrees! {
|
||||||
_span: crate::tt::Ident => self { self };
|
_span: crate::tt::Ident => self { self };
|
||||||
_span: crate::tt::Punct => self { self };
|
_span: crate::tt::Punct => self { self };
|
||||||
span: &str => self { crate::tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), span}};
|
span: &str => self { crate::tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), span}};
|
||||||
span: String => self { crate::tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), span}}
|
span: String => self { crate::tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), span}};
|
||||||
|
span: Name => self { crate::tt::Ident{text: self.to_smol_str(), span}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1381,6 +1381,7 @@ mod macros {
|
||||||
// region:assert
|
// region:assert
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
|
#[allow_internal_unstable(core_panic, edition_panic, generic_assert_internals)]
|
||||||
macro_rules! assert {
|
macro_rules! assert {
|
||||||
($($arg:tt)*) => {
|
($($arg:tt)*) => {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
|
@ -1389,6 +1390,7 @@ mod macros {
|
||||||
// endregion:assert
|
// endregion:assert
|
||||||
|
|
||||||
// region:fmt
|
// region:fmt
|
||||||
|
#[allow_internal_unstable(fmt_internals, const_fmt_arguments_new)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! const_format_args {
|
macro_rules! const_format_args {
|
||||||
|
@ -1396,6 +1398,7 @@ mod macros {
|
||||||
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow_internal_unstable(fmt_internals)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! format_args {
|
macro_rules! format_args {
|
||||||
|
@ -1403,6 +1406,7 @@ mod macros {
|
||||||
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow_internal_unstable(fmt_internals)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
macro_rules! format_args_nl {
|
macro_rules! format_args_nl {
|
||||||
|
|
Loading…
Reference in a new issue