Give a specific lint for unsafety not being inherited

This commit is contained in:
clubby789 2022-11-04 12:25:40 +00:00
parent 2efb0cd4b2
commit b7360fa23f

View file

@ -1,3 +1,4 @@
use hir::{BlockCheckMode, ExprKind, Node};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
@ -517,24 +518,49 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() {
let (description, note) = details.description_and_note();
// Report an error.
let unsafe_fn_msg =
if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" };
match kind {
UnsafetyViolationKind::General => {
// once
struct_span_err!(
// Mutable statics always require an unsafe block
let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root)
&& details != UnsafetyViolationDetails::UseOfMutableStatic
{
" function or"
} else {
""
};
let mut err = struct_span_err!(
tcx.sess,
source_info.span,
E0133,
"{} is unsafe and requires unsafe{} block",
description,
unsafe_fn_msg,
)
.span_label(source_info.span, description)
.note(note)
.emit();
);
err.span_label(source_info.span, description).note(note);
let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
if let Node::Expr(block) = node
&& let ExprKind::Block(block, _) = block.kind
&& let 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
}
});
if let Some((id, _)) = note_non_inherited {
let span = tcx.hir().span(id);
err.span_label(
tcx.sess.source_map().guess_head_span(span),
"items do not inherit unsafety from separate enclosing items",
);
}
err.emit();
}
UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
UNSAFE_OP_IN_UNSAFE_FN,