Auto merge of #17859 - Veykril:rustc_deprecated_safe_2024, r=Veykril
fix: Correctly support `#[rustc_deprecated_safe_2024]` Fixes https://github.com/rust-lang/rust-analyzer/issues/17852
This commit is contained in:
commit
757b0a5ace
@ -158,7 +158,7 @@ pub(crate) fn body_with_source_map_query(
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
is_async_fn = data.has_async_kw();
|
is_async_fn = data.is_async();
|
||||||
src.map(|it| it.body().map(ast::Expr::from))
|
src.map(|it| it.body().map(ast::Expr::from))
|
||||||
}
|
}
|
||||||
DefWithBodyId::ConstId(c) => {
|
DefWithBodyId::ConstId(c) => {
|
||||||
|
@ -94,6 +94,12 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
|
|||||||
.filter(|it| !it.is_empty())
|
.filter(|it| !it.is_empty())
|
||||||
.map(Box::new);
|
.map(Box::new);
|
||||||
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
|
let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
|
||||||
|
if flags.contains(FnFlags::HAS_UNSAFE_KW)
|
||||||
|
&& !crate_graph[krate].edition.at_least_2024()
|
||||||
|
&& attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
|
||||||
|
{
|
||||||
|
flags.remove(FnFlags::HAS_UNSAFE_KW);
|
||||||
|
}
|
||||||
|
|
||||||
Arc::new(FunctionData {
|
Arc::new(FunctionData {
|
||||||
name: func.name.clone(),
|
name: func.name.clone(),
|
||||||
@ -126,19 +132,19 @@ pub fn has_self_param(&self) -> bool {
|
|||||||
self.flags.contains(FnFlags::HAS_SELF_PARAM)
|
self.flags.contains(FnFlags::HAS_SELF_PARAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_default_kw(&self) -> bool {
|
pub fn is_default(&self) -> bool {
|
||||||
self.flags.contains(FnFlags::HAS_DEFAULT_KW)
|
self.flags.contains(FnFlags::HAS_DEFAULT_KW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_const_kw(&self) -> bool {
|
pub fn is_const(&self) -> bool {
|
||||||
self.flags.contains(FnFlags::HAS_CONST_KW)
|
self.flags.contains(FnFlags::HAS_CONST_KW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_async_kw(&self) -> bool {
|
pub fn is_async(&self) -> bool {
|
||||||
self.flags.contains(FnFlags::HAS_ASYNC_KW)
|
self.flags.contains(FnFlags::HAS_ASYNC_KW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_unsafe_kw(&self) -> bool {
|
pub fn is_unsafe(&self) -> bool {
|
||||||
self.flags.contains(FnFlags::HAS_UNSAFE_KW)
|
self.flags.contains(FnFlags::HAS_UNSAFE_KW)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> Vec<ExprId> {
|
|||||||
|
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
let is_unsafe = match def {
|
let is_unsafe = match def {
|
||||||
DefWithBodyId::FunctionId(it) => db.function_data(it).has_unsafe_kw(),
|
DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe(),
|
||||||
DefWithBodyId::StaticId(_)
|
DefWithBodyId::StaticId(_)
|
||||||
| DefWithBodyId::ConstId(_)
|
| DefWithBodyId::ConstId(_)
|
||||||
| DefWithBodyId::VariantId(_)
|
| DefWithBodyId::VariantId(_)
|
||||||
|
@ -1857,7 +1857,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
|||||||
params,
|
params,
|
||||||
ret,
|
ret,
|
||||||
data.is_varargs(),
|
data.is_varargs(),
|
||||||
if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe },
|
if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
|
||||||
data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
|
data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
|
||||||
);
|
);
|
||||||
make_binders(db, &generics, sig)
|
make_binders(db, &generics, sig)
|
||||||
|
@ -253,12 +253,7 @@ pub(crate) fn sig_ty(&self) -> &'a Ty {
|
|||||||
|
|
||||||
pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
|
pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
|
||||||
let data = db.function_data(func);
|
let data = db.function_data(func);
|
||||||
if data.has_unsafe_kw() {
|
if data.is_unsafe() {
|
||||||
// Functions that are `#[rustc_deprecated_safe_2024]` are safe to call before 2024.
|
|
||||||
if db.attrs(func.into()).by_key(&sym::rustc_deprecated_safe_2024).exists() {
|
|
||||||
// FIXME: Properly check the caller span and mark it as unsafe after 2024.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +69,13 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
|||||||
|
|
||||||
write_visibility(module_id, self.visibility(db), f)?;
|
write_visibility(module_id, self.visibility(db), f)?;
|
||||||
|
|
||||||
if data.has_default_kw() {
|
if data.is_default() {
|
||||||
f.write_str("default ")?;
|
f.write_str("default ")?;
|
||||||
}
|
}
|
||||||
if data.has_const_kw() {
|
if data.is_const() {
|
||||||
f.write_str("const ")?;
|
f.write_str("const ")?;
|
||||||
}
|
}
|
||||||
if data.has_async_kw() {
|
if data.is_async() {
|
||||||
f.write_str("async ")?;
|
f.write_str("async ")?;
|
||||||
}
|
}
|
||||||
if self.is_unsafe_to_call(db) {
|
if self.is_unsafe_to_call(db) {
|
||||||
@ -125,7 +125,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
|||||||
// `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
|
// `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
|
||||||
// Use ugly pattern match to strip the Future trait.
|
// Use ugly pattern match to strip the Future trait.
|
||||||
// Better way?
|
// Better way?
|
||||||
let ret_type = if !data.has_async_kw() {
|
let ret_type = if !data.is_async() {
|
||||||
&data.ret_type
|
&data.ret_type
|
||||||
} else {
|
} else {
|
||||||
match &*data.ret_type {
|
match &*data.ret_type {
|
||||||
|
@ -2189,11 +2189,11 @@ pub fn params_without_self_with_args(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_const(self, db: &dyn HirDatabase) -> bool {
|
pub fn is_const(self, db: &dyn HirDatabase) -> bool {
|
||||||
db.function_data(self.id).has_const_kw()
|
db.function_data(self.id).is_const()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_async(self, db: &dyn HirDatabase) -> bool {
|
pub fn is_async(self, db: &dyn HirDatabase) -> bool {
|
||||||
db.function_data(self.id).has_async_kw()
|
db.function_data(self.id).is_async()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does this function have `#[test]` attribute?
|
/// Does this function have `#[test]` attribute?
|
||||||
|
@ -483,6 +483,30 @@ unsafe fn foo() -> u8 {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = format!("foo: {}", foo$0());
|
let x = format!("foo: {}", foo$0());
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rustc_deprecated_safe_2024() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- /ed2021.rs crate:ed2021 edition:2021
|
||||||
|
#[rustc_deprecated_safe_2024]
|
||||||
|
unsafe fn safe() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
//- /ed2024.rs crate:ed2024 edition:2024
|
||||||
|
#[rustc_deprecated_safe_2024]
|
||||||
|
unsafe fn not_safe() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
//- /main.rs crate:main deps:ed2021,ed2024
|
||||||
|
fn main() {
|
||||||
|
ed2021::safe();
|
||||||
|
ed2024::not_safe();
|
||||||
|
//^^^^^^^^^^^^^^^^^^💡 error: this operation is unsafe and requires an unsafe function or block
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user