diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 60d3d3e69abbe..8c6f7167083d1 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -5,11 +5,6 @@ mir_build_unconditional_recursion = function cannot return without recursing mir_build_unconditional_recursion_call_site_label = recursive call site mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe = - call to unsafe function `{$function}` is unsafe and requires unsafe block (error E0133) - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless = call to unsafe function is unsafe and requires unsafe block (error E0133) .note = consult the function's documentation for information on how to avoid undefined behavior .label = call to unsafe function @@ -56,7 +51,7 @@ mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_uns .label = borrow of layout constrained field with interior mutability mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = - call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) + call to function with `#[target_feature]` is unsafe and requires unsafe block (error E0133) .note = can only be called if the required target features are available .label = call to function with `#[target_feature]` diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 99e96ff77ced9..efd0f6ebc0bd5 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -525,20 +525,15 @@ impl UnsafeOpKind { span: Span, ) { match self { - CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint( + // The current linting API doesn't allow us to delay calling `def_path_str` + // until the lint is actually emitted, which risks triggering a "good path ICE" + // if the lint gets cancelled (for example, inside an external macro). + // For now, don't include the function name in the diagnostic. + CallToUnsafeFunction(_) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { - span, - function: &tcx.def_path_str(did.unwrap()), - }, - ), - CallToUnsafeFunction(..) => tcx.emit_spanned_lint( - UNSAFE_OP_IN_UNSAFE_FN, - hir_id, - span, - UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span }, + UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { span }, ), UseOfInlineAssembly => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, @@ -588,14 +583,12 @@ impl UnsafeOpKind { span, UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span }, ), - CallToFunctionWith(did) => tcx.emit_spanned_lint( + // We don't use the provided `DefId` for the same reason as `CallToUnsafeFunction` above. + CallToFunctionWith(_) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, - UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { - span, - function: &tcx.def_path_str(*did), - }, + UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { span }, ), } } @@ -607,24 +600,24 @@ impl UnsafeOpKind { unsafe_op_in_unsafe_fn_allowed: bool, ) { match self { - CallToUnsafeFunction(did) if did.is_some() && unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(Some(did)) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(did) if did.is_some() => { + CallToUnsafeFunction(Some(did)) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(..) if unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span }, ); } - CallToUnsafeFunction(..) => { + CallToUnsafeFunction(None) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span }); } UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => { diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 68179001b916d..0757ad783467f 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -20,16 +20,7 @@ pub struct UnconditionalRecursion { #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] #[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> { - #[label] - pub span: Span, - pub function: &'a str, -} - -#[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)] -#[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { +pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { #[label] pub span: Span, } @@ -100,10 +91,9 @@ pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] #[note] -pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { +pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { #[label] pub span: Span, - pub function: &'a str, } #[derive(Diagnostic)] diff --git a/src/test/ui/unsafe/auxiliary/issue-106126.rs b/src/test/ui/unsafe/auxiliary/issue-106126.rs new file mode 100644 index 0000000000000..091a3edb756ad --- /dev/null +++ b/src/test/ui/unsafe/auxiliary/issue-106126.rs @@ -0,0 +1,9 @@ +#[macro_export] +macro_rules! foo { + () => { + unsafe fn __unsf() {} + unsafe fn __foo() { + __unsf(); + } + }; +} diff --git a/src/test/ui/unsafe/issue-106126-good-path-bug.rs b/src/test/ui/unsafe/issue-106126-good-path-bug.rs new file mode 100644 index 0000000000000..93f478ee35802 --- /dev/null +++ b/src/test/ui/unsafe/issue-106126-good-path-bug.rs @@ -0,0 +1,12 @@ +// Regression test for #106126. +// check-pass +// aux-build:issue-106126.rs + +#![deny(unsafe_op_in_unsafe_fn)] + +#[macro_use] +extern crate issue_106126; + +foo!(); + +fn main() {} diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr index 6f005fe895848..d6c831bed51b8 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -12,7 +12,7 @@ LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -20,7 +20,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -28,7 +28,7 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block @@ -40,21 +40,21 @@ LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 | LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 | LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -62,7 +62,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -70,19 +70,19 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:5 | LL | unsafe { unsafe { unsf() } } | ^^^^^^ unnecessary `unsafe` block error[E0133]: call to unsafe function is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -90,7 +90,7 @@ LL | unsf(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:79:9 | LL | unsf(); | ^^^^^^ call to unsafe function diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs index db1e916a36c1f..8223bd8e5a65d 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -10,8 +10,7 @@ static mut VOID: () = (); unsafe fn deny_level() { unsf(); - //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block - //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block + //~^ ERROR call to unsafe function is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); @@ -26,8 +25,7 @@ unsafe fn deny_level() { #[deny(warnings)] unsafe fn warning_level() { unsf(); - //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block - //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block + //~^ ERROR call to unsafe function is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr index 13c080e5b6a80..e19dc3be8dd04 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) +error: call to unsafe function is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 | LL | unsf(); @@ -12,7 +12,7 @@ LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -20,7 +20,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 | LL | VOID = (); | ^^^^ use of mutable static @@ -28,7 +28,7 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block @@ -39,22 +39,22 @@ note: the lint level is defined here LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ -error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 | LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 | LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -62,7 +62,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 | LL | VOID = (); | ^^^^ use of mutable static @@ -70,13 +70,13 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:14 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14 | LL | unsafe { unsafe { unsf() } } | ------ ^^^^^^ unnecessary `unsafe` block @@ -84,7 +84,7 @@ LL | unsafe { unsafe { unsf() } } | because it's nested under this `unsafe` block error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -92,7 +92,7 @@ LL | unsf(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:79:9 | LL | unsf(); | ^^^^^^ call to unsafe function