Skip to content

Commit b2e98da

Browse files
committed
Allow to customize // TODO: comment for deprecated safe autofix
Relevant for the deprecation of `CommandExt::before_exit` in #125970.
1 parent cb12b52 commit b2e98da

File tree

6 files changed

+31
-10
lines changed

6 files changed

+31
-10
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
644644
through unstable paths"
645645
),
646646
rustc_attr!(
647-
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
648-
EncodeCrossCrate::Yes,
647+
rustc_deprecated_safe_2024, Normal, template!(List: r#"todo = "...""#),
648+
ErrorFollowing, EncodeCrossCrate::Yes,
649649
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
650650
),
651651

compiler/rustc_mir_build/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ mir_build_call_to_deprecated_safe_fn_requires_unsafe =
3232
call to deprecated safe function `{$function}` is unsafe and requires unsafe block
3333
.note = consult the function's documentation for information on how to avoid undefined behavior
3434
.label = call to unsafe function
35-
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
35+
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee its unsafe preconditions
3636
3737
mir_build_call_to_fn_with_requires_unsafe =
3838
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block

compiler/rustc_mir_build/src/check_unsafety.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::build::ExprCategory;
22
use crate::errors::*;
33

4+
use rustc_ast::Attribute;
45
use rustc_errors::DiagArgValue;
56
use rustc_hir::def::DefKind;
67
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
@@ -90,14 +91,33 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
9091
}
9192

9293
fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool {
94+
fn parse_rustc_deprecated_safe_2024_attr(attr: &Attribute) -> Option<Symbol> {
95+
for item in attr.meta_item_list().unwrap_or_default() {
96+
if item.has_name(sym::todo) {
97+
return Some(item.value_str().expect("`#[rustc_deprecated_safe_2024(todo)]` must have a string value"));
98+
}
99+
}
100+
None
101+
}
102+
93103
match kind {
94104
// Allow calls to deprecated-safe unsafe functions if the caller is
95105
// from an edition before 2024.
96106
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
97107
if !span.at_least_rust_2024()
98108
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
99109
{
110+
let attr = self.tcx.get_attr(id, sym::rustc_deprecated_safe_2024).unwrap();
111+
let suggestion = parse_rustc_deprecated_safe_2024_attr(attr);
112+
100113
let sm = self.tcx.sess.source_map();
114+
let suggestion = suggestion.and_then(|suggestion| {
115+
sm.indentation_before(span).map(|indent| {
116+
format!("{}// TODO: {}\n", indent, suggestion)
117+
})
118+
})
119+
.unwrap_or_default();
120+
101121
self.tcx.emit_node_span_lint(
102122
DEPRECATED_SAFE,
103123
self.hir_context,
@@ -106,7 +126,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
106126
span,
107127
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
108128
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
109-
indent: sm.indentation_before(span).unwrap_or_default(),
129+
start_of_line_suggestion: suggestion,
110130
start_of_line: sm.span_extend_to_line(span).shrink_to_lo(),
111131
left: span.shrink_to_lo(),
112132
right: span.shrink_to_hi(),

compiler/rustc_mir_build/src/errors.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
3333
#[derive(Subdiagnostic)]
3434
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
3535
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
36-
pub(crate) indent: String,
37-
#[suggestion_part(
38-
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
39-
)]
36+
pub(crate) start_of_line_suggestion: String,
37+
#[suggestion_part(code = "{start_of_line_suggestion}")]
4038
pub(crate) start_of_line: Span,
4139
#[suggestion_part(code = "unsafe {{ ")]
4240
pub(crate) left: Span,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1888,6 +1888,7 @@ symbols! {
18881888
to_string,
18891889
to_string_method,
18901890
to_vec,
1891+
todo,
18911892
todo_macro,
18921893
tool_attributes,
18931894
tool_lints,

library/std/src/env.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,8 @@ impl Error for VarError {
357357
/// }
358358
/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
359359
/// ```
360-
#[rustc_deprecated_safe_2024]
360+
#[cfg_attr(bootstrap, rustc_deprecated_safe_2024)]
361+
#[cfg_attr(not(bootstrap), rustc_deprecated_safe_2024(todo = "Audit that the environment access only happens in single-threaded code."))]
361362
#[stable(feature = "env", since = "1.0.0")]
362363
pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
363364
let (key, value) = (key.as_ref(), value.as_ref());
@@ -421,7 +422,8 @@ pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
421422
/// }
422423
/// assert!(env::var(key).is_err());
423424
/// ```
424-
#[rustc_deprecated_safe_2024]
425+
#[cfg_attr(bootstrap, rustc_deprecated_safe_2024)]
426+
#[cfg_attr(not(bootstrap), rustc_deprecated_safe_2024(todo = "Audit that the environment access only happens in single-threaded code."))]
425427
#[stable(feature = "env", since = "1.0.0")]
426428
pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
427429
let key = key.as_ref();

0 commit comments

Comments
 (0)