Implement RFC 3525.
This commit is contained in:
parent
748c54848d
commit
7eb4cfeace
25 changed files with 512 additions and 28 deletions
|
@ -125,6 +125,17 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
|
|||
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
|
||||
.label = initializing type with `rustc_layout_scalar_valid_range` attr
|
||||
|
||||
mir_build_initializing_type_with_target_feature_requires_unsafe =
|
||||
initializing type with `target_feature` attr is unsafe and requires unsafe block
|
||||
.note = this struct can only be constructed if the corresponding `target_feature`s are available
|
||||
.label = initializing type with `target_feature` attr
|
||||
|
||||
mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
|
||||
initializing type with `target_feature` attr is unsafe and requires unsafe function or block
|
||||
.note = this struct can only be constructed if the corresponding `target_feature`s are available
|
||||
.label = initializing type with `target_feature` attr
|
||||
|
||||
|
||||
mir_build_inline_assembly_requires_unsafe =
|
||||
use of inline assembly is unsafe and requires unsafe block
|
||||
.note = inline assembly is entirely unchecked and can cause undefined behavior
|
||||
|
@ -387,6 +398,11 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
|
|||
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
|
||||
.label = initializing type with `rustc_layout_scalar_valid_range` attr
|
||||
|
||||
mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe =
|
||||
initializing type with `target_feature` attr is unsafe and requires unsafe block
|
||||
.note = this struct can only be constructed if the corresponding `target_feature`s are available
|
||||
.label = initializing type with `target_feature` attr
|
||||
|
||||
mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
|
||||
use of inline assembly is unsafe and requires unsafe block
|
||||
.note = inline assembly is entirely unchecked and can cause undefined behavior
|
||||
|
|
|
@ -461,14 +461,18 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
};
|
||||
self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
|
||||
} else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
|
||||
// If the called function has target features the calling function hasn't,
|
||||
// If the called function has explicit target features the calling function hasn't,
|
||||
// the call requires `unsafe`. Don't check this on wasm
|
||||
// targets, though. For more information on wasm see the
|
||||
// is_like_wasm check in hir_analysis/src/collect.rs
|
||||
// Implicit target features are OK because they are either a consequence of some
|
||||
// explicit target feature (which is checked to be present in the caller) or
|
||||
// come from a witness argument.
|
||||
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
|
||||
if !self.tcx.sess.target.options.is_like_wasm
|
||||
&& !callee_features.iter().all(|feature| {
|
||||
self.body_target_features.iter().any(|f| f.name == feature.name)
|
||||
feature.implied
|
||||
|| self.body_target_features.iter().any(|f| f.name == feature.name)
|
||||
})
|
||||
{
|
||||
let missing: Vec<_> = callee_features
|
||||
|
@ -542,10 +546,16 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
user_ty: _,
|
||||
fields: _,
|
||||
base: _,
|
||||
}) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
|
||||
(Bound::Unbounded, Bound::Unbounded) => {}
|
||||
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
|
||||
},
|
||||
}) => {
|
||||
match self.tcx.layout_scalar_valid_range(adt_def.did()) {
|
||||
(Bound::Unbounded, Bound::Unbounded) => {}
|
||||
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
|
||||
}
|
||||
if !self.tcx.struct_target_features(adt_def.did()).is_empty() {
|
||||
self.requires_unsafe(expr.span, ConstructingTargetFeaturesType)
|
||||
}
|
||||
}
|
||||
|
||||
ExprKind::Closure(box ClosureExpr {
|
||||
closure_id,
|
||||
args: _,
|
||||
|
@ -647,6 +657,7 @@ enum UnsafeOpKind {
|
|||
CallToUnsafeFunction(Option<DefId>),
|
||||
UseOfInlineAssembly,
|
||||
InitializingTypeWith,
|
||||
ConstructingTargetFeaturesType,
|
||||
UseOfMutableStatic,
|
||||
UseOfExternStatic,
|
||||
DerefOfRawPointer,
|
||||
|
@ -728,6 +739,15 @@ impl UnsafeOpKind {
|
|||
unsafe_not_inherited_note,
|
||||
},
|
||||
),
|
||||
ConstructingTargetFeaturesType => tcx.emit_node_span_lint(
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
hir_id,
|
||||
span,
|
||||
UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
|
||||
span,
|
||||
unsafe_not_inherited_note,
|
||||
},
|
||||
),
|
||||
UseOfMutableStatic => tcx.emit_node_span_lint(
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
hir_id,
|
||||
|
@ -885,6 +905,20 @@ impl UnsafeOpKind {
|
|||
unsafe_not_inherited_note,
|
||||
});
|
||||
}
|
||||
ConstructingTargetFeaturesType if unsafe_op_in_unsafe_fn_allowed => {
|
||||
dcx.emit_err(
|
||||
InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
||||
span,
|
||||
unsafe_not_inherited_note,
|
||||
},
|
||||
);
|
||||
}
|
||||
ConstructingTargetFeaturesType => {
|
||||
dcx.emit_err(InitializingTypeWithTargetFeatureRequiresUnsafe {
|
||||
span,
|
||||
unsafe_not_inherited_note,
|
||||
});
|
||||
}
|
||||
UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
|
||||
dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
||||
span,
|
||||
|
|
|
@ -86,6 +86,16 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
|
|||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
|
||||
#[note]
|
||||
pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
|
||||
#[note]
|
||||
|
@ -250,6 +260,17 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe {
|
|||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
|
||||
#[note]
|
||||
pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafe {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
|
||||
|
@ -264,6 +285,20 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(
|
||||
mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
|
||||
code = E0133
|
||||
)]
|
||||
#[note]
|
||||
pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
|
||||
#[note]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue