Fix #[rustc_deprecated_safe_2024]

It should be considered by the edition of the caller, not the callee.

Technically we still don't do it correctly - we need the span of the method name (if it comes from a macro), but we don't keep it and this is good enough for now.
This commit is contained in:
Chayim Refael Friedman 2025-01-27 14:34:33 +02:00
parent 6862329068
commit 55c63abc59
16 changed files with 274 additions and 100 deletions

View file

@ -95,10 +95,10 @@ impl FunctionData {
.map(Box::new);
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);
flags.insert(FnFlags::DEPRECATED_SAFE_2024);
}
if attrs.by_key(&sym::target_feature).exists() {
@ -152,6 +152,10 @@ impl FunctionData {
self.flags.contains(FnFlags::HAS_UNSAFE_KW)
}
pub fn is_deprecated_safe_2024(&self) -> bool {
self.flags.contains(FnFlags::DEPRECATED_SAFE_2024)
}
pub fn is_safe(&self) -> bool {
self.flags.contains(FnFlags::HAS_SAFE_KW)
}

View file

@ -2238,17 +2238,27 @@ impl ExprCollector<'_> {
let unsafe_arg_new = self.alloc_expr_desugared(Expr::Path(unsafe_arg_new));
let unsafe_arg_new =
self.alloc_expr_desugared(Expr::Call { callee: unsafe_arg_new, args: Box::default() });
let unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe {
let mut unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe {
id: None,
// We collect the unused expressions here so that we still infer them instead of
// dropping them out of the expression tree
statements: fmt
.orphans
.into_iter()
.map(|expr| Statement::Expr { expr, has_semi: true })
.collect(),
statements: Box::new([]),
tail: Some(unsafe_arg_new),
});
if !fmt.orphans.is_empty() {
unsafe_arg_new = self.alloc_expr_desugared(Expr::Block {
id: None,
// We collect the unused expressions here so that we still infer them instead of
// dropping them out of the expression tree. We cannot store them in the `Unsafe`
// block because then unsafe blocks within them will get a false "unused unsafe"
// diagnostic (rustc has a notion of builtin unsafe blocks, but we don't).
statements: fmt
.orphans
.into_iter()
.map(|expr| Statement::Expr { expr, has_semi: true })
.collect(),
tail: Some(unsafe_arg_new),
label: None,
});
}
let idx = self.alloc_expr(
Expr::Call {

View file

@ -951,6 +951,7 @@ bitflags::bitflags! {
/// only very few functions with it. So we only encode its existence here, and lookup
/// it if needed.
const HAS_TARGET_FEATURE = 1 << 8;
const DEPRECATED_SAFE_2024 = 1 << 9;
}
}