diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-07-15 19:42:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-15 19:42:52 +0200 |
| commit | 9b8be2f0e10f68a90ddc1202854869965d44e1d0 (patch) | |
| tree | 9d615b55ec25453726427be63ae156bdd799caaf | |
| parent | e76ae3e4c5bf3c75996811bb9bc04173a1ed5f09 (diff) | |
| parent | 2cfe8ed37d5949a823ad3f0fe1db5e79f9fc9f90 (diff) | |
| download | rust-9b8be2f0e10f68a90ddc1202854869965d44e1d0.tar.gz rust-9b8be2f0e10f68a90ddc1202854869965d44e1d0.zip | |
Rollup merge of #113663 - syvb:non_inherited_unsafe_thir, r=cjgillot
Implement "items do not inherit unsafety" note for THIR unsafeck Implements the "items do not inherit unsafety from separate enclosing items" note from the MIR unsafety checker in the THIR unsafety checker (`-Z thir-unsafeck`) to maintain parity between the two unsafety checkers. The logic to find the separate enclosing item is nearly the same as in the MIR unsafety checker.
| -rw-r--r-- | compiler/rustc_mir_build/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/check_unsafety.rs | 119 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 51 | ||||
| -rw-r--r-- | tests/ui/unsafe/unsafe-not-inherited.mirunsafeck.stderr (renamed from tests/ui/unsafe/unsafe-not-inherited.stderr) | 4 | ||||
| -rw-r--r-- | tests/ui/unsafe/unsafe-not-inherited.rs | 2 | ||||
| -rw-r--r-- | tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr | 24 |
6 files changed, 176 insertions, 26 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 98156840dd8..938f3edd31b 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -312,6 +312,8 @@ mir_build_unreachable_pattern = unreachable pattern .label = unreachable pattern .catchall_label = matches any value +mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items + mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe = borrow of layout constrained field with interior mutability is unsafe and requires unsafe block (error E0133) .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8b4ff9bb868..192bd4a83e3 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -91,7 +91,12 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span); } SafetyContext::Safe => { - kind.emit_requires_unsafe_err(self.tcx, span, unsafe_op_in_unsafe_fn_allowed); + kind.emit_requires_unsafe_err( + self.tcx, + span, + self.hir_context, + unsafe_op_in_unsafe_fn_allowed, + ); } } } @@ -602,98 +607,164 @@ impl UnsafeOpKind { &self, tcx: TyCtxt<'_>, span: Span, + hir_context: hir::HirId, unsafe_op_in_unsafe_fn_allowed: bool, ) { + let note_non_inherited = tcx.hir().parent_iter(hir_context).find(|(id, node)| { + if let hir::Node::Expr(block) = node + && let hir::ExprKind::Block(block, _) = block.kind + && let hir::BlockCheckMode::UnsafeBlock(_) = block.rules + { + true + } + else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + && sig.header.is_unsafe() + { + true + } else { + false + } + }); + let unsafe_not_inherited_note = if let Some((id, _)) = note_non_inherited { + let span = tcx.hir().span(id); + let span = tcx.sess.source_map().guess_head_span(span); + Some(UnsafeNotInheritedNote { span }) + } else { + None + }; + match self { CallToUnsafeFunction(Some(did)) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, + unsafe_not_inherited_note, function: &tcx.def_path_str(*did), }); } CallToUnsafeFunction(Some(did)) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe { span, + unsafe_not_inherited_note, function: &tcx.def_path_str(*did), }); } CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( - CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span }, + CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }, ); } CallToUnsafeFunction(None) => { - tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span }); + tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { + span, + unsafe_not_inherited_note, + }); } UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } UseOfInlineAssembly => { - tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe { span }); + tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe { + span, + unsafe_not_inherited_note, + }); } InitializingTypeWith if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } InitializingTypeWith => { - tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe { span }); + tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe { + span, + unsafe_not_inherited_note, + }); } UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } UseOfMutableStatic => { - tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafe { span }); + tcx.sess + .emit_err(UseOfMutableStaticRequiresUnsafe { span, unsafe_not_inherited_note }); } UseOfExternStatic if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } UseOfExternStatic => { - tcx.sess.emit_err(UseOfExternStaticRequiresUnsafe { span }); + tcx.sess + .emit_err(UseOfExternStaticRequiresUnsafe { span, unsafe_not_inherited_note }); } DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } DerefOfRawPointer => { - tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafe { span }); + tcx.sess + .emit_err(DerefOfRawPointerRequiresUnsafe { span, unsafe_not_inherited_note }); } AccessToUnionField if unsafe_op_in_unsafe_fn_allowed => { - tcx.sess - .emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }); + tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }); } AccessToUnionField => { - tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafe { span }); + tcx.sess + .emit_err(AccessToUnionFieldRequiresUnsafe { span, unsafe_not_inherited_note }); } MutationOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, + unsafe_not_inherited_note, }, ); } MutationOfLayoutConstrainedField => { - tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe { span }); + tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe { + span, + unsafe_not_inherited_note, + }); } BorrowOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( - BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span }, + BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { + span, + unsafe_not_inherited_note, + }, ); } BorrowOfLayoutConstrainedField => { - tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe { span }); + tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe { + span, + unsafe_not_inherited_note, + }); } CallToFunctionWith(did) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, + unsafe_not_inherited_note, function: &tcx.def_path_str(*did), }); } CallToFunctionWith(did) => { tcx.sess.emit_err(CallToFunctionWithRequiresUnsafe { span, + unsafe_not_inherited_note, function: &tcx.def_path_str(*did), }); } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index df00cc75cc7..820ab93851e 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -119,6 +119,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafe<'a> { #[label] pub span: Span, pub function: &'a str, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -128,6 +130,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -138,6 +142,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { #[label] pub span: Span, pub function: &'a str, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -150,6 +156,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -159,6 +167,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -168,6 +178,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -177,6 +189,8 @@ pub struct InitializingTypeWithRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -189,6 +203,8 @@ pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -198,6 +214,8 @@ pub struct UseOfMutableStaticRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -207,6 +225,8 @@ pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -216,6 +236,8 @@ pub struct UseOfExternStaticRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -225,6 +247,8 @@ pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -234,6 +258,8 @@ pub struct DerefOfRawPointerRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -243,6 +269,8 @@ pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -252,6 +280,8 @@ pub struct AccessToUnionFieldRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -261,6 +291,8 @@ pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -270,6 +302,8 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -282,6 +316,8 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllow #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -291,6 +327,8 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -303,6 +341,8 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed #[primary_span] #[label] pub span: Span, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -313,6 +353,8 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> { #[label] pub span: Span, pub function: &'a str, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, } #[derive(Diagnostic)] @@ -323,6 +365,15 @@ pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { #[label] pub span: Span, pub function: &'a str, + #[subdiagnostic] + pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, +} + +#[derive(Subdiagnostic)] +#[label(mir_build_unsafe_not_inherited)] +pub struct UnsafeNotInheritedNote { + #[primary_span] + pub span: Span, } #[derive(LintDiagnostic)] diff --git a/tests/ui/unsafe/unsafe-not-inherited.stderr b/tests/ui/unsafe/unsafe-not-inherited.mirunsafeck.stderr index 3bc5ca5c9d1..5536efbc6f4 100644 --- a/tests/ui/unsafe/unsafe-not-inherited.stderr +++ b/tests/ui/unsafe/unsafe-not-inherited.mirunsafeck.stderr @@ -1,5 +1,5 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/unsafe-not-inherited.rs:6:31 + --> $DIR/unsafe-not-inherited.rs:8:31 | LL | unsafe {static BAR: u64 = FOO;} | ------ ^^^ use of mutable static @@ -9,7 +9,7 @@ LL | unsafe {static BAR: u64 = FOO;} = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/unsafe-not-inherited.rs:18:13 + --> $DIR/unsafe-not-inherited.rs:20:13 | LL | unsafe { | ------ items do not inherit unsafety from separate enclosing items diff --git a/tests/ui/unsafe/unsafe-not-inherited.rs b/tests/ui/unsafe/unsafe-not-inherited.rs index 6d797caa0f9..f9d9a595714 100644 --- a/tests/ui/unsafe/unsafe-not-inherited.rs +++ b/tests/ui/unsafe/unsafe-not-inherited.rs @@ -1,3 +1,5 @@ +// revisions: mirunsafeck thirunsafeck +// [thirunsafeck]compile-flags: -Z thir-unsafeck #![allow(unused, dead_code)] static mut FOO: u64 = 0; diff --git a/tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr b/tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr new file mode 100644 index 00000000000..88ea2e6d1fe --- /dev/null +++ b/tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr @@ -0,0 +1,24 @@ +error[E0133]: use of mutable static is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:8:31 + | +LL | unsafe {static BAR: u64 = FOO;} + | ------ ^^^ use of mutable static + | | + | items do not inherit unsafety from separate enclosing items + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error[E0133]: call to unsafe function `unsafe_call` is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:20:13 + | +LL | unsafe { + | ------ items do not inherit unsafety from separate enclosing items +... +LL | unsafe_call(); + | ^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`. |
