Implement "items do not inherit unsafety" for THIR unsafeck
This commit is contained in:
parent
ad963232d9
commit
2cfe8ed37d
@ -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
|
||||
|
@ -91,7 +91,12 @@ fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
|
||||
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 @@ pub fn emit_requires_unsafe_err(
|
||||
&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),
|
||||
});
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
|
@ -1,3 +1,5 @@
|
||||
// revisions: mirunsafeck thirunsafeck
|
||||
// [thirunsafeck]compile-flags: -Z thir-unsafeck
|
||||
#![allow(unused, dead_code)]
|
||||
|
||||
static mut FOO: u64 = 0;
|
||||
|
24
tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr
Normal file
24
tests/ui/unsafe/unsafe-not-inherited.thirunsafeck.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user