mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Fix #[rustc_const_panic_str] functions not actually being hooked
This commit is contained in:
parent
5df690e13f
commit
a9140e197c
3 changed files with 26 additions and 18 deletions
|
@ -318,18 +318,20 @@ fn f() {
|
||||||
|
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fn f() {
|
fn f() {
|
||||||
$crate::panicking::panic_fmt(
|
{
|
||||||
builtin#lang(Arguments::new_v1_formatted)(
|
$crate::panicking::panic_fmt(
|
||||||
&[
|
builtin#lang(Arguments::new_v1_formatted)(
|
||||||
"cc",
|
&[
|
||||||
],
|
"cc",
|
||||||
&[],
|
],
|
||||||
&[],
|
&[],
|
||||||
unsafe {
|
&[],
|
||||||
builtin#lang(UnsafeArg::new)()
|
unsafe {
|
||||||
},
|
builtin#lang(UnsafeArg::new)()
|
||||||
),
|
},
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
}"#]]
|
}"#]]
|
||||||
.assert_eq(&body.pretty_print(&db, def))
|
.assert_eq(&body.pretty_print(&db, def))
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ impl Evaluator<'_> {
|
||||||
if self.not_special_fn_cache.borrow().contains(&def) {
|
if self.not_special_fn_cache.borrow().contains(&def) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let function_data = self.db.function_data(def);
|
let function_data = self.db.function_data(def);
|
||||||
let is_intrinsic = match &function_data.abi {
|
let is_intrinsic = match &function_data.abi {
|
||||||
Some(abi) => *abi == Interned::new_str("rust-intrinsic"),
|
Some(abi) => *abi == Interned::new_str("rust-intrinsic"),
|
||||||
|
@ -311,16 +312,20 @@ impl Evaluator<'_> {
|
||||||
|
|
||||||
fn detect_lang_function(&self, def: FunctionId) -> Option<LangItem> {
|
fn detect_lang_function(&self, def: FunctionId) -> Option<LangItem> {
|
||||||
use LangItem::*;
|
use LangItem::*;
|
||||||
let candidate = self.db.lang_attr(def.into())?;
|
let attrs = self.db.attrs(def.into());
|
||||||
|
|
||||||
|
if attrs.by_key("rustc_const_panic_str").exists() {
|
||||||
|
// `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE.
|
||||||
|
return Some(LangItem::BeginPanic);
|
||||||
|
}
|
||||||
|
|
||||||
|
let candidate = attrs.by_key("lang").string_value().and_then(LangItem::from_str)?;
|
||||||
// We want to execute these functions with special logic
|
// We want to execute these functions with special logic
|
||||||
// `PanicFmt` is not detected here as it's redirected later.
|
// `PanicFmt` is not detected here as it's redirected later.
|
||||||
if [BeginPanic, SliceLen, DropInPlace].contains(&candidate) {
|
if [BeginPanic, SliceLen, DropInPlace].contains(&candidate) {
|
||||||
return Some(candidate);
|
return Some(candidate);
|
||||||
}
|
}
|
||||||
if self.db.attrs(def.into()).by_key("rustc_const_panic_str").exists() {
|
|
||||||
// `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE.
|
|
||||||
return Some(LangItem::BeginPanic);
|
|
||||||
}
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1378,8 +1378,9 @@ mod panic {
|
||||||
// Special-case the single-argument case for const_panic.
|
// Special-case the single-argument case for const_panic.
|
||||||
("{}", $arg:expr $(,)?) => ({
|
("{}", $arg:expr $(,)?) => ({
|
||||||
#[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval
|
#[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval
|
||||||
|
#[rustc_do_not_const_check] // hooked by const-eval
|
||||||
const fn panic_cold_display<T: $crate::fmt::Display>(arg: &T) -> ! {
|
const fn panic_cold_display<T: $crate::fmt::Display>(arg: &T) -> ! {
|
||||||
loop {}
|
$crate::panicking::panic_display(arg)
|
||||||
}
|
}
|
||||||
panic_cold_display(&$arg);
|
panic_cold_display(&$arg);
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue