diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 8a11e3e71bc81..c3994cef14fd1 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -599,13 +599,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if self.conv == Conv::CCmseNonSecureCall { // This will probably get ignored on all targets but those supporting the TrustZone-M // extension (thumbv8m targets). - unsafe { - llvm::AddCallSiteAttrString( - callsite, - llvm::AttributePlace::Function, - cstr::cstr!("cmse_nonsecure_call"), - ); - } + llvm::AddCallSiteAttrString( + callsite, + llvm::AttributePlace::Function, + cstr::cstr!("cmse_nonsecure_call"), + ); } } } diff --git a/compiler/rustc_middle/src/hir/nested_filter.rs b/compiler/rustc_middle/src/hir/nested_filter.rs index 7cfb20745720d..48efae8045bdd 100644 --- a/compiler/rustc_middle/src/hir/nested_filter.rs +++ b/compiler/rustc_middle/src/hir/nested_filter.rs @@ -3,6 +3,10 @@ use rustc_hir::intravisit::nested_filter::NestedFilter; /// Do not visit nested item-like things, but visit nested things /// that are inside of an item-like. /// +/// Notably, possible occurrences of bodies in non-item-like things +/// include: closures/generators, inline `const {}` blocks, and +/// constant arguments of types, e.g. in `let _: [(); /* HERE */];`. +/// /// **This is the most common choice.** A very common pattern is /// to use `visit_all_item_likes()` as an outer loop, /// and to have the visitor that visits the contents of each item diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 17c77c1bbd891..294c70f24f8b1 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -202,6 +202,77 @@ impl<'a> LintDiagnosticBuilder<'a> { } } +pub fn explain_lint_level_source<'s>( + sess: &'s Session, + lint: &'static Lint, + level: Level, + src: LintLevelSource, + err: &mut DiagnosticBuilder<'s>, +) { + let name = lint.name_lower(); + match src { + LintLevelSource::Default => { + sess.diag_note_once( + err, + DiagnosticMessageId::from(lint), + &format!("`#[{}({})]` on by default", level.as_str(), name), + ); + } + LintLevelSource::CommandLine(lint_flag_val, orig_level) => { + let flag = match orig_level { + Level::Warn => "-W", + Level::Deny => "-D", + Level::Forbid => "-F", + Level::Allow => "-A", + Level::ForceWarn => "--force-warn", + }; + let hyphen_case_lint_name = name.replace('_', "-"); + if lint_flag_val.as_str() == name { + sess.diag_note_once( + err, + DiagnosticMessageId::from(lint), + &format!( + "requested on the command line with `{} {}`", + flag, hyphen_case_lint_name + ), + ); + } else { + let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-"); + sess.diag_note_once( + err, + DiagnosticMessageId::from(lint), + &format!( + "`{} {}` implied by `{} {}`", + flag, hyphen_case_lint_name, flag, hyphen_case_flag_val + ), + ); + } + } + LintLevelSource::Node(lint_attr_name, src, reason) => { + if let Some(rationale) = reason { + err.note(rationale.as_str()); + } + sess.diag_span_note_once( + err, + DiagnosticMessageId::from(lint), + src, + "the lint level is defined here", + ); + if lint_attr_name.as_str() != name { + let level_str = level.as_str(); + sess.diag_note_once( + err, + DiagnosticMessageId::from(lint), + &format!( + "`#[{}({})]` implied by `#[{}({})]`", + level_str, name, level_str, lint_attr_name + ), + ); + } + } + } +} + pub fn struct_lint_level<'s, 'd>( sess: &'s Session, lint: &'static Lint, @@ -277,69 +348,9 @@ pub fn struct_lint_level<'s, 'd>( } } - let name = lint.name_lower(); - match src { - LintLevelSource::Default => { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!("`#[{}({})]` on by default", level.as_str(), name), - ); - } - LintLevelSource::CommandLine(lint_flag_val, orig_level) => { - let flag = match orig_level { - Level::Warn => "-W", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Allow => "-A", - Level::ForceWarn => "--force-warn", - }; - let hyphen_case_lint_name = name.replace('_', "-"); - if lint_flag_val.as_str() == name { - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "requested on the command line with `{} {}`", - flag, hyphen_case_lint_name - ), - ); - } else { - let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-"); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`{} {}` implied by `{} {}`", - flag, hyphen_case_lint_name, flag, hyphen_case_flag_val - ), - ); - } - } - LintLevelSource::Node(lint_attr_name, src, reason) => { - if let Some(rationale) = reason { - err.note(rationale.as_str()); - } - sess.diag_span_note_once( - &mut err, - DiagnosticMessageId::from(lint), - src, - "the lint level is defined here", - ); - if lint_attr_name.as_str() != name { - let level_str = level.as_str(); - sess.diag_note_once( - &mut err, - DiagnosticMessageId::from(lint), - &format!( - "`#[{}({})]` implied by `#[{}({})]`", - level_str, name, level_str, lint_attr_name - ), - ); - } - } - } + explain_lint_level_source(sess, lint, level, src, &mut err); + let name = lint.name_lower(); let is_force_warn = matches!(level, Level::ForceWarn); err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn }); diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index fbd5a2d08a5dc..433f69e8da46c 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -2,7 +2,7 @@ use crate::mir::{Body, Promoted}; use crate::ty::{self, Ty, TyCtxt}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::stable_map::FxHashMap; use rustc_data_structures::vec_map::VecMap; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -114,13 +114,44 @@ pub struct UnsafetyViolation { pub details: UnsafetyViolationDetails, } -#[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)] +#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] +pub enum UnusedUnsafe { + /// `unsafe` block contains no unsafe operations + /// > ``unnecessary `unsafe` block`` + Unused, + /// `unsafe` block nested under another (used) `unsafe` block + /// > ``… because it's nested under this `unsafe` block`` + InUnsafeBlock(hir::HirId), + /// `unsafe` block nested under `unsafe fn` + /// > ``… because it's nested under this `unsafe fn` `` + /// + /// the second HirId here indicates the first usage of the `unsafe` block, + /// which allows retrival of the LintLevelSource for why that operation would + /// have been permitted without the block + InUnsafeFn(hir::HirId, hir::HirId), +} + +#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] +pub enum UsedUnsafeBlockData { + SomeDisallowedInUnsafeFn, + // the HirId here indicates the first usage of the `unsafe` block + // (i.e. the one that's first encountered in the MIR traversal of the unsafety check) + AllAllowedInUnsafeFn(hir::HirId), +} + +#[derive(TyEncodable, TyDecodable, HashStable, Debug)] pub struct UnsafetyCheckResult { /// Violations that are propagated *upwards* from this function. - pub violations: Lrc<[UnsafetyViolation]>, - /// `unsafe` blocks in this function, along with whether they are used. This is - /// used for the "unused_unsafe" lint. - pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>, + pub violations: Vec, + + /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint. + /// + /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether + /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`. + pub used_unsafe_blocks: FxHashMap, + + /// This is `Some` iff the item is not a closure. + pub unused_unsafes: Option>, } rustc_index::newtype_index! { diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index df71379c1d886..f98025f7953f9 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -3,8 +3,6 @@ use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN; -use rustc_session::lint::Level; use rustc_span::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -209,28 +207,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.unit() } - /// If we are changing the safety mode, create a new source scope + /// If we are entering an unsafe block, create a new source scope fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: BlockSafety) { debug!("update_source_scope_for({:?}, {:?})", span, safety_mode); let new_unsafety = match safety_mode { - BlockSafety::Safe => None, - BlockSafety::BuiltinUnsafe => Some(Safety::BuiltinUnsafe), + BlockSafety::Safe => return, + BlockSafety::BuiltinUnsafe => Safety::BuiltinUnsafe, BlockSafety::ExplicitUnsafe(hir_id) => { - match self.in_scope_unsafe { - Safety::Safe => {} - // no longer treat `unsafe fn`s as `unsafe` contexts (see RFC #2585) - Safety::FnUnsafe - if self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, hir_id).0 - != Level::Allow => {} - _ => return, - } self.in_scope_unsafe = Safety::ExplicitUnsafe(hir_id); - Some(Safety::ExplicitUnsafe(hir_id)) + Safety::ExplicitUnsafe(hir_id) } }; - if let Some(unsafety) = new_unsafety { - self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(unsafety)); - } + self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(new_unsafety)); } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 704f0901b9590..eaf3f19bff196 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,17 +1,17 @@ -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; -use rustc_hir::Node; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; -use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{lint, mir::*}; use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; +use std::collections::hash_map; use std::ops::Bound; pub struct UnsafetyChecker<'a, 'tcx> { @@ -21,9 +21,12 @@ pub struct UnsafetyChecker<'a, 'tcx> { source_info: SourceInfo, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - /// Mark an `unsafe` block as used, so we don't lint it. - used_unsafe: FxHashSet, - inherited_blocks: Vec<(hir::HirId, bool)>, + + /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint. + /// + /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether + /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`. + used_unsafe_blocks: FxHashMap, } impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { @@ -40,8 +43,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { source_info: SourceInfo::outermost(body.span), tcx, param_env, - used_unsafe: Default::default(), - inherited_blocks: vec![], + used_unsafe_blocks: Default::default(), } } } @@ -123,9 +125,9 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { } } &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => { - let UnsafetyCheckResult { violations, unsafe_blocks } = + let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = self.tcx.unsafety_check_result(def_id.expect_local()); - self.register_violations(&violations, &unsafe_blocks); + self.register_violations(violations, used_unsafe_blocks); } }, _ => {} @@ -251,61 +253,72 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { .assert_crate_local() .lint_root; self.register_violations( - &[UnsafetyViolation { source_info, lint_root, kind, details }], - &[], + [&UnsafetyViolation { source_info, lint_root, kind, details }], + [], ); } - fn register_violations( + fn register_violations<'a>( &mut self, - violations: &[UnsafetyViolation], - unsafe_blocks: &[(hir::HirId, bool)], + violations: impl IntoIterator, + new_used_unsafe_blocks: impl IntoIterator, ) { + use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn}; + + let update_entry = |this: &mut Self, hir_id, new_usage| { + match this.used_unsafe_blocks.entry(hir_id) { + hash_map::Entry::Occupied(mut entry) => { + if new_usage == SomeDisallowedInUnsafeFn { + *entry.get_mut() = SomeDisallowedInUnsafeFn; + } + } + hash_map::Entry::Vacant(entry) => { + entry.insert(new_usage); + } + }; + }; let safety = self.body.source_scopes[self.source_info.scope] .local_data .as_ref() .assert_crate_local() .safety; - let within_unsafe = match safety { + match safety { // `unsafe` blocks are required in safe code - Safety::Safe => { - for violation in violations { - match violation.kind { - UnsafetyViolationKind::General => {} - UnsafetyViolationKind::UnsafeFn => { - bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context") - } - } - if !self.violations.contains(violation) { - self.violations.push(*violation) + Safety::Safe => violations.into_iter().for_each(|&violation| { + match violation.kind { + UnsafetyViolationKind::General => {} + UnsafetyViolationKind::UnsafeFn => { + bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context") } } - false - } - // With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s - Safety::FnUnsafe => { - for violation in violations { - let mut violation = *violation; - - violation.kind = UnsafetyViolationKind::UnsafeFn; - if !self.violations.contains(&violation) { - self.violations.push(violation) - } + if !self.violations.contains(&violation) { + self.violations.push(violation) } - false - } - Safety::BuiltinUnsafe => true, - Safety::ExplicitUnsafe(hir_id) => { - // mark unsafe block as used if there are any unsafe operations inside - if !violations.is_empty() { - self.used_unsafe.insert(hir_id); + }), + // With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s + Safety::FnUnsafe => violations.into_iter().for_each(|&(mut violation)| { + violation.kind = UnsafetyViolationKind::UnsafeFn; + if !self.violations.contains(&violation) { + self.violations.push(violation) } - true - } + }), + Safety::BuiltinUnsafe => {} + Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|violation| { + update_entry( + self, + hir_id, + match self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, violation.lint_root).0 + { + Level::Allow => AllAllowedInUnsafeFn(violation.lint_root), + _ => SomeDisallowedInUnsafeFn, + }, + ) + }), }; - self.inherited_blocks.extend( - unsafe_blocks.iter().map(|&(hir_id, is_used)| (hir_id, is_used && !within_unsafe)), - ); + + new_used_unsafe_blocks + .into_iter() + .for_each(|(&hir_id, &usage_data)| update_entry(self, hir_id, usage_data)); } fn check_mut_borrowing_layout_constrained_field( &mut self, @@ -387,17 +400,64 @@ pub(crate) fn provide(providers: &mut Providers) { }; } -struct UnusedUnsafeVisitor<'a> { - used_unsafe: &'a FxHashSet, - unsafe_blocks: &'a mut Vec<(hir::HirId, bool)>, +/// Context information for [`UnusedUnsafeVisitor`] traversal, +/// saves (innermost) relevant context +#[derive(Copy, Clone, Debug)] +enum Context { + Safe, + /// in an `unsafe fn` + UnsafeFn(HirId), + /// in a *used* `unsafe` block + /// (i.e. a block without unused-unsafe warning) + UnsafeBlock(HirId), +} + +struct UnusedUnsafeVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + used_unsafe_blocks: &'a FxHashMap, + context: Context, + unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>, } -impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_> { +impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> { fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) { - intravisit::walk_block(self, block); + use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn}; if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules { - self.unsafe_blocks.push((block.hir_id, self.used_unsafe.contains(&block.hir_id))); + let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) { + (Level::Allow, _) => Some(SomeDisallowedInUnsafeFn), + _ => self.used_unsafe_blocks.get(&block.hir_id).copied(), + }; + let unused_unsafe = match (self.context, used) { + (_, None) => UnusedUnsafe::Unused, + (Context::Safe, Some(_)) + | (Context::UnsafeFn(_), Some(SomeDisallowedInUnsafeFn)) => { + let previous_context = self.context; + self.context = Context::UnsafeBlock(block.hir_id); + intravisit::walk_block(self, block); + self.context = previous_context; + return; + } + (Context::UnsafeFn(hir_id), Some(AllAllowedInUnsafeFn(lint_root))) => { + UnusedUnsafe::InUnsafeFn(hir_id, lint_root) + } + (Context::UnsafeBlock(hir_id), Some(_)) => UnusedUnsafe::InUnsafeBlock(hir_id), + }; + self.unused_unsafes.push((block.hir_id, unused_unsafe)); + } + intravisit::walk_block(self, block); + } + + fn visit_fn( + &mut self, + fk: intravisit::FnKind<'tcx>, + _fd: &'tcx hir::FnDecl<'tcx>, + b: hir::BodyId, + _s: rustc_span::Span, + _id: HirId, + ) { + if matches!(fk, intravisit::FnKind::Closure) { + self.visit_body(self.tcx.hir().body(b)) } } } @@ -405,20 +465,38 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_> { fn check_unused_unsafe( tcx: TyCtxt<'_>, def_id: LocalDefId, - used_unsafe: &FxHashSet, - unsafe_blocks: &mut Vec<(hir::HirId, bool)>, -) { - let body_id = tcx.hir().maybe_body_owned_by(tcx.hir().local_def_id_to_hir_id(def_id)); + used_unsafe_blocks: &FxHashMap, +) -> Vec<(HirId, UnusedUnsafe)> { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let body_id = tcx.hir().maybe_body_owned_by(hir_id); let Some(body_id) = body_id else { debug!("check_unused_unsafe({:?}) - no body found", def_id); - return; + return vec![]; }; let body = tcx.hir().body(body_id); - debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})", def_id, body, used_unsafe); - let mut visitor = UnusedUnsafeVisitor { used_unsafe, unsafe_blocks }; + let context = match tcx.hir().fn_sig_by_hir_id(hir_id) { + Some(sig) if sig.header.unsafety == hir::Unsafety::Unsafe => Context::UnsafeFn(hir_id), + _ => Context::Safe, + }; + + debug!( + "check_unused_unsafe({:?}, context={:?}, body={:?}, used_unsafe_blocks={:?})", + def_id, body, context, used_unsafe_blocks + ); + + let mut unused_unsafes = vec![]; + + let mut visitor = UnusedUnsafeVisitor { + tcx, + used_unsafe_blocks, + context, + unused_unsafes: &mut unused_unsafes, + }; intravisit::Visitor::visit_body(&mut visitor, body); + + unused_unsafes } fn unsafety_check_result<'tcx>( @@ -436,56 +514,52 @@ fn unsafety_check_result<'tcx>( let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); checker.visit_body(&body); - check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks); + let unused_unsafes = (!tcx.is_closure(def.did.to_def_id())) + .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks)); tcx.arena.alloc(UnsafetyCheckResult { - violations: checker.violations.into(), - unsafe_blocks: checker.inherited_blocks.into(), + violations: checker.violations, + used_unsafe_blocks: checker.used_unsafe_blocks, + unused_unsafes, }) } -/// Returns the `HirId` for an enclosing scope that is also `unsafe`. -fn is_enclosed( - tcx: TyCtxt<'_>, - used_unsafe: &FxHashSet, - id: hir::HirId, - unsafe_op_in_unsafe_fn_allowed: bool, -) -> Option<(&'static str, hir::HirId)> { - let parent_id = tcx.hir().get_parent_node(id); - if parent_id != id { - if used_unsafe.contains(&parent_id) { - Some(("block", parent_id)) - } else if let Some(Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(ref sig, _, _), .. - })) = tcx.hir().find(parent_id) - { - if sig.header.unsafety == hir::Unsafety::Unsafe && unsafe_op_in_unsafe_fn_allowed { - Some(("fn", parent_id)) - } else { - None - } - } else { - is_enclosed(tcx, used_unsafe, parent_id, unsafe_op_in_unsafe_fn_allowed) - } - } else { - None - } -} - -fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id: hir::HirId) { +fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id)); tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, |lint| { let msg = "unnecessary `unsafe` block"; let mut db = lint.build(msg); db.span_label(span, msg); - if let Some((kind, id)) = - is_enclosed(tcx, used_unsafe, id, unsafe_op_in_unsafe_fn_allowed(tcx, id)) - { - db.span_label( - tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), - format!("because it's nested under this `unsafe` {}", kind), - ); + match kind { + UnusedUnsafe::Unused => {} + UnusedUnsafe::InUnsafeBlock(id) => { + db.span_label( + tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), + format!("because it's nested under this `unsafe` block"), + ); + } + UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => { + db.span_label( + tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), + format!("because it's nested under this `unsafe` fn"), + ) + .note( + "this `unsafe` block does contain unsafe operations, \ + but those are already allowed in an `unsafe fn`", + ); + let (level, source) = + tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root); + assert_eq!(level, Level::Allow); + lint::explain_lint_level_source( + tcx.sess, + UNSAFE_OP_IN_UNSAFE_FN, + Level::Allow, + source, + &mut db, + ); + } } + db.emit(); }); } @@ -498,7 +572,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { return; } - let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id); + let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id); for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { let (description, note) = details.description_and_note(); @@ -539,20 +613,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } - let (mut unsafe_used, mut unsafe_unused): (FxHashSet<_>, Vec<_>) = Default::default(); - for &(block_id, is_used) in unsafe_blocks.iter() { - if is_used { - unsafe_used.insert(block_id); - } else { - unsafe_unused.push(block_id); - } - } - // The unused unsafe blocks might not be in source order; sort them so that the unused unsafe - // error messages are properly aligned and the issue-45107 and lint-unused-unsafe tests pass. - unsafe_unused.sort_by_cached_key(|hir_id| tcx.hir().span(*hir_id)); - - for &block_id in &unsafe_unused { - report_unused_unsafe(tcx, &unsafe_used, block_id); + for &(block_id, kind) in unused_unsafes.as_ref().unwrap() { + report_unused_unsafe(tcx, kind, block_id); } } diff --git a/src/test/ui/span/lint-unused-unsafe-thir.rs b/src/test/ui/span/lint-unused-unsafe-thir.rs new file mode 100644 index 0000000000000..95a537ed28230 --- /dev/null +++ b/src/test/ui/span/lint-unused-unsafe-thir.rs @@ -0,0 +1,61 @@ +// FIXME: This file is tracking old lint behavior that's still unchanged in the +// unstable -Zthir-unsafeck implementation. See lint-unused-unsafe.rs for more details. +// +// Exercise the unused_unsafe attribute in some positive and negative cases + +// compile-flags: -Zthir-unsafeck + +#![allow(dead_code)] +#![deny(unused_unsafe)] + + +mod foo { + extern "C" { + pub fn bar(); + } +} + +fn callback(_f: F) -> T where F: FnOnce() -> T { panic!() } +unsafe fn unsf() {} + +fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block +fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block +unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block +fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block +unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block +fn bad6() { + unsafe { // don't put the warning here + unsafe { //~ ERROR: unnecessary `unsafe` block + unsf() + } + } +} +unsafe fn bad7() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { //~ ERROR: unnecessary `unsafe` block + unsf() + } + } +} + +unsafe fn good0() { unsf() } +fn good1() { unsafe { unsf() } } +fn good2() { + /* bug uncovered when implementing warning about unused unsafe blocks. Be + sure that when purity is inherited that the source of the unsafe-ness + is tracked correctly */ + unsafe { + unsafe fn what() -> Vec { panic!() } + + callback(|| { + what(); + }); + } +} + +unsafe fn good3() { foo::bar() } +fn good4() { unsafe { foo::bar() } } + +#[allow(unused_unsafe)] fn allowed() { unsafe {} } + +fn main() {} diff --git a/src/test/ui/span/lint-unused-unsafe.thir.stderr b/src/test/ui/span/lint-unused-unsafe-thir.stderr similarity index 79% rename from src/test/ui/span/lint-unused-unsafe.thir.stderr rename to src/test/ui/span/lint-unused-unsafe-thir.stderr index dda45c3679ab6..6654910c5cdc3 100644 --- a/src/test/ui/span/lint-unused-unsafe.thir.stderr +++ b/src/test/ui/span/lint-unused-unsafe-thir.stderr @@ -1,23 +1,23 @@ error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:19:13 + --> $DIR/lint-unused-unsafe-thir.rs:21:13 | LL | fn bad1() { unsafe {} } | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/lint-unused-unsafe.rs:7:9 + --> $DIR/lint-unused-unsafe-thir.rs:9:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:20:13 + --> $DIR/lint-unused-unsafe-thir.rs:22:13 | LL | fn bad2() { unsafe { bad1() } } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:21:20 + --> $DIR/lint-unused-unsafe-thir.rs:23:20 | LL | unsafe fn bad3() { unsafe {} } | ---------------- ^^^^^^ unnecessary `unsafe` block @@ -25,13 +25,13 @@ LL | unsafe fn bad3() { unsafe {} } | because it's nested under this `unsafe` fn error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:22:13 + --> $DIR/lint-unused-unsafe-thir.rs:24:13 | LL | fn bad4() { unsafe { callback(||{}) } } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:23:20 + --> $DIR/lint-unused-unsafe-thir.rs:25:20 | LL | unsafe fn bad5() { unsafe { unsf() } } | ---------------- ^^^^^^ unnecessary `unsafe` block @@ -39,7 +39,7 @@ LL | unsafe fn bad5() { unsafe { unsf() } } | because it's nested under this `unsafe` fn error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:26:9 + --> $DIR/lint-unused-unsafe-thir.rs:28:9 | LL | unsafe { // don't put the warning here | ------ because it's nested under this `unsafe` block @@ -47,7 +47,7 @@ LL | unsafe { | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:33:9 + --> $DIR/lint-unused-unsafe-thir.rs:35:9 | LL | unsafe { | ------ because it's nested under this `unsafe` block @@ -55,7 +55,7 @@ LL | unsafe { | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:32:5 + --> $DIR/lint-unused-unsafe-thir.rs:34:5 | LL | unsafe fn bad7() { | ---------------- because it's nested under this `unsafe` fn diff --git a/src/test/ui/span/lint-unused-unsafe.mir.stderr b/src/test/ui/span/lint-unused-unsafe.mir.stderr index c2adb7be7a220..850550a1d8f70 100644 --- a/src/test/ui/span/lint-unused-unsafe.mir.stderr +++ b/src/test/ui/span/lint-unused-unsafe.mir.stderr @@ -1,67 +1,1824 @@ error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:19:13 + --> $DIR/lint-unused-unsafe.rs:26:13 | LL | fn bad1() { unsafe {} } | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/lint-unused-unsafe.rs:7:9 + --> $DIR/lint-unused-unsafe.rs:14:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:20:13 + --> $DIR/lint-unused-unsafe.rs:27:13 | LL | fn bad2() { unsafe { bad1() } } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:21:20 + --> $DIR/lint-unused-unsafe.rs:28:20 | LL | unsafe fn bad3() { unsafe {} } - | ---------------- ^^^^^^ unnecessary `unsafe` block - | | - | because it's nested under this `unsafe` fn + | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:22:13 + --> $DIR/lint-unused-unsafe.rs:29:13 | LL | fn bad4() { unsafe { callback(||{}) } } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:23:20 + --> $DIR/lint-unused-unsafe.rs:30:20 | LL | unsafe fn bad5() { unsafe { unsf() } } | ---------------- ^^^^^^ unnecessary `unsafe` block | | | because it's nested under this `unsafe` fn + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + = note: `#[allow(unsafe_op_in_unsafe_fn)]` on by default error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:26:9 + --> $DIR/lint-unused-unsafe.rs:32:5 | -LL | unsafe { // don't put the warning here - | ------ because it's nested under this `unsafe` block -LL | unsafe { - | ^^^^^^ unnecessary `unsafe` block +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:32:5 + --> $DIR/lint-unused-unsafe.rs:39:5 | -LL | unsafe fn bad7() { - | ---------------- because it's nested under this `unsafe` fn LL | unsafe { | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/lint-unused-unsafe.rs:33:9 + --> $DIR/lint-unused-unsafe.rs:40:9 | LL | unsafe fn bad7() { | ---------------- because it's nested under this `unsafe` fn LL | unsafe { LL | unsafe { | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:74:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:83:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:84:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:85:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:90:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:100:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:101:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:102:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:112:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:110:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:113:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:114:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:124:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:134:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:135:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:136:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:142:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:153:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:154:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:155:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:166:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:164:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:167:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:168:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:178:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:188:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:189:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:190:13 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:196:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:197:13 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +LL | unsafe { +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:194:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:198:13 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:199:13 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:205:9 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:203:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:207:13 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:208:13 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:209:13 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:220:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:218:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:221:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:222:17 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:242:9 + | +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:254:9 + | +LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() { + | ----------------------------------------------- because it's nested under this `unsafe` fn +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:252:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:268:13 + | +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:286:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:295:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:296:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:297:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:302:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:312:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:313:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:314:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:324:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:322:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:325:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:326:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:336:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:346:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:347:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:348:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:354:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:365:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:366:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:367:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:378:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:376:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:379:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:380:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:390:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:400:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:401:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:402:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:408:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:409:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:406:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:410:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:411:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:417:20 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:415:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:419:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:420:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:421:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:432:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:430:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:433:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:434:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:454:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:466:20 + | +LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() { + | ----------------------------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:464:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:480:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:499:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:508:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:509:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:510:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:515:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:525:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsf(); +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:526:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:527:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:537:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:535:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:538:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:539:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:549:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:559:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:560:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:561:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:567:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:578:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsf(); +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:579:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:580:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:591:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:589:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:592:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:593:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:603:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:613:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:614:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:615:24 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:621:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:622:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:619:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:623:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:624:24 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:630:20 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:628:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:632:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:633:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:634:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:645:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:643:20 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:646:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:647:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { let _ = || unsf(); }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:667:20 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:679:20 + | +LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() { + | ----------------------------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:677:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:693:24 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:711:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:721:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:722:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:723:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:729:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:740:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:741:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:742:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:753:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:751:24 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:754:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:755:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:765:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:775:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:776:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:777:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:783:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:784:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:781:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:785:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:786:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:792:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:790:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:794:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:795:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:796:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:807:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:805:24 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:808:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:809:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:829:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:841:24 + | +LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() { + | ----------------------------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:839:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:855:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:869:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:879:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:880:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:881:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:887:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:898:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | unsf(); +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:899:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:900:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:911:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:909:24 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:912:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:913:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:923:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:933:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:934:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:935:28 + | +LL | let _ = || unsafe {}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:941:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:942:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:939:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:943:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:944:28 + | +LL | unsafe fn granularity_2() { + | ------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:950:24 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:948:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:952:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:953:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:954:28 + | +LL | unsafe fn top_level_used_2() { + | ---------------------------- because it's nested under this `unsafe` fn +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:965:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:963:24 + | +LL | #[deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:966:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:967:32 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = || unsafe { unsf() }; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:987:24 + | +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:999:24 + | +LL | unsafe fn granular_disallow_op_in_unsafe_fn_3() { + | ----------------------------------------------- because it's nested under this `unsafe` fn +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:997:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1013:28 + | +LL | let _ = || unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = || unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1044:9 + | +LL | unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() { + | -------------------------------------------------- because it's nested under this `unsafe` fn +LL | unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:1045:21 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1059:29 + | +LL | let _ = async { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1066:33 + | +LL | let _ = async { unsafe { + | ------ because it's nested under this `unsafe` block +LL | let _ = async { unsf() }; +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1067:33 + | +LL | let _ = async { unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1068:33 + | +LL | let _ = async { unsafe { + | ------ because it's nested under this `unsafe` block +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1073:29 + | +LL | let _ = async { unsafe { + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1074:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/lint-unused-unsafe.rs:1071:17 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1075:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1076:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1078:29 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1080:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1081:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1082:33 + | +LL | async unsafe fn async_blocks() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | let _ = async { unsafe { let _ = async { unsf() }; }}; + | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1092:22 + | +LL | let _x: [(); unsafe { 0 }] = []; + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/lint-unused-unsafe.rs:1096:22 + | +LL | let _x: [(); unsafe { unsafe { size() } }] = []; + | ^^^^^^ unnecessary `unsafe` block -error: aborting due to 8 previous errors +error: aborting due to 201 previous errors diff --git a/src/test/ui/span/lint-unused-unsafe.rs b/src/test/ui/span/lint-unused-unsafe.rs index b889cc981cad1..f8d1dff3572be 100644 --- a/src/test/ui/span/lint-unused-unsafe.rs +++ b/src/test/ui/span/lint-unused-unsafe.rs @@ -1,7 +1,14 @@ // Exercise the unused_unsafe attribute in some positive and negative cases -// revisions: mir thir -// [thir]compile-flags: -Zthir-unsafeck + +// edition:2018 + +// revisions: mir + +// FIXME: Adapt -Zthir-unsafeck to behave the same as the mir version after #93678, +// then delete lint-unused-unsafe-thir.rs, and go back to using the settings below +// // revisions: mir thir +// // [thir]compile-flags: -Zthir-unsafeck #![allow(dead_code)] #![deny(unused_unsafe)] @@ -22,8 +29,8 @@ unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block unsafe fn bad5() { unsafe { unsf() } } //~ ERROR: unnecessary `unsafe` block fn bad6() { - unsafe { // don't put the warning here - unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { // don't put the warning here unsf() } } @@ -57,3 +64,1037 @@ fn good4() { unsafe { foo::bar() } } #[allow(unused_unsafe)] fn allowed() { unsafe {} } fn main() {} + +mod additional_tests { + unsafe fn unsf() {} + + // some tests + + fn inner_ignored() { + unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + unsafe { + unsf() + } + } + } + + fn multi_level_unused() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + } + } + + fn granularity() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } + unsafe { unsf() } + unsafe { unsf() } + } + } + + fn top_level_used() { + unsafe { + unsf(); + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + + } + + fn top_level_ignored() { + #[allow(unused_unsafe)] + unsafe { + #[deny(unused_unsafe)] + { + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + } + + } + + // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_1() { + unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + unsafe { + unsf() + } + } + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_1() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + } + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_1() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } + unsafe { unsf() } + unsafe { unsf() } + } + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_1() { + unsafe { + unsf(); + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_1() { + #[allow(unused_unsafe)] + unsafe { + #[deny(unused_unsafe)] + { + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + } + } + + // same tests, but unsafe_op_in_unsafe_fn allowed, + // so that *all* unsafe blocks are unused + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_2() { + unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + unsafe { + unsf() + } + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_2() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + unsafe {} //~ ERROR: unnecessary `unsafe` block + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_2() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_2() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_2() { + #[allow(unused_unsafe)] + unsafe { + #[deny(unused_unsafe)] + { + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block + } + } + } + + // additional tests when using unsafe_op_in_unsafe_fn + // in more complex ways + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_2() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + } + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_3() { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + } + unsf(); + } + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_4() { + unsafe { + unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + } + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + } + } +} + +// the same set of tests, with closures everywhere +mod additional_tests_closures { + unsafe fn unsf() {} + + // some tests + + fn inner_ignored() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + fn multi_level_unused() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + fn granularity() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + }; + } + + fn top_level_used() { + let _ = || unsafe { + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + fn top_level_ignored() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + + } + + // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_1() { + let _ = || unsafe { + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_1() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // same tests, but unsafe_op_in_unsafe_fn allowed, + // so that *all* unsafe blocks are unused + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_2() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // additional tests when using unsafe_op_in_unsafe_fn + // in more complex ways + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_3() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + unsf(); + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_4() { + let _ = || unsafe { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + }; + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } +} + +// the same set of tests, with closures everywhere +// and closures on the unsafe fn calls +mod additional_tests_even_more_closures { + unsafe fn unsf() {} + + // some tests + + fn inner_ignored() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + let _ = || unsf(); + }; + }; + } + + fn multi_level_unused() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + fn granularity() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; + let _ = || unsafe { let _ = || unsf(); }; + let _ = || unsafe { let _ = || unsf(); }; + }; + } + + fn top_level_used() { + let _ = || unsafe { + let _ = || unsf(); + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + fn top_level_ignored() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + } + }; + + } + + // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + let _ = || unsf(); + }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; + let _ = || unsafe { let _ = || unsf(); }; + let _ = || unsafe { let _ = || unsf(); }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_1() { + let _ = || unsafe { + let _ = || unsf(); + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_1() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // same tests, but unsafe_op_in_unsafe_fn allowed, + // so that *all* unsafe blocks are unused + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + let _ = || unsf(); + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsf(); + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_2() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // additional tests when using unsafe_op_in_unsafe_fn + // in more complex ways + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + let _ = || unsf(); + } + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + let _ = || unsf(); + } + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_3() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + let _ = || unsf(); + } + }; + let _ = || unsf(); + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_4() { + let _ = || unsafe { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsf(); + }; + #[deny(unsafe_op_in_unsafe_fn)] + { + let _ = || unsf(); + } + }; + } +} + +mod item_likes { + unsafe fn unsf() {} + + struct S; + impl S { + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_1() { + let _ = || unsafe { + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_1() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // same tests, but unsafe_op_in_unsafe_fn allowed, + // so that *all* unsafe blocks are unused + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_2() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // additional tests when using unsafe_op_in_unsafe_fn + // in more complex ways + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_3() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + unsf(); + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_4() { + let _ = || unsafe { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + }; + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } + } + + trait T { + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_1() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + let _ = || unsafe { unsf() }; + }; + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_1() { + let _ = || unsafe { + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[deny(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_1() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // same tests, but unsafe_op_in_unsafe_fn allowed, + // so that *all* unsafe blocks are unused + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn inner_ignored_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unused_unsafe)] + let _ = || unsafe { + unsf() + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn multi_level_unused_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granularity_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_used_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + }; + + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn top_level_ignored_2() { + #[allow(unused_unsafe)] + let _ = || unsafe { + #[deny(unused_unsafe)] + { + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block + } + }; + } + + // additional tests when using unsafe_op_in_unsafe_fn + // in more complex ways + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_2() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_3() { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = || unsafe { + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + unsf(); + }; + } + + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn_4() { + let _ = || unsafe { + let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block + unsf(); + }; + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + } + } +} + +mod additional_tests_extra { + unsafe fn unsf() {} + + // multiple uses with different `unsafe_op_in_unsafe_fn` in the same closure + #[allow(unsafe_op_in_unsafe_fn)] + unsafe fn granular_disallow_op_in_unsafe_fn() { + let _ = || unsafe { + let _ = || { + unsf(); + #[deny(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + }; + }; + } + + #[warn(unsafe_op_in_unsafe_fn)] + unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() { + unsafe { //~ ERROR: unnecessary `unsafe` block + #[allow(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + #[allow(unsafe_op_in_unsafe_fn)] + { + unsf(); + } + } + } + + async unsafe fn async_blocks() { + #[deny(unsafe_op_in_unsafe_fn)] + { + let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; + let _ = async { unsafe { let _ = async { unsf() }; }}; + let _ = async { unsafe { let _ = async { unsf() }; }}; + }}; + let _ = async { unsafe { + let _ = async { unsf() }; + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + }}; + } + #[allow(unsafe_op_in_unsafe_fn)] + { + let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + }}; + let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block + let _ = async { unsf() }; + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block + }}; + } + } + + fn used_unsafe_in_const() { + let _x: [(); unsafe { size() }] = []; + } + + fn unused_unsafe_in_const_1() { + let _x: [(); unsafe { 0 }] = []; //~ ERROR: unnecessary `unsafe` block + } + + fn unused_unsafe_in_const_2() { + let _x: [(); unsafe { unsafe { size() } }] = []; //~ ERROR: unnecessary `unsafe` block + } + + const unsafe fn size() -> usize { 0 } +} 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 9a522fac65fad..163c101772c47 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 @@ -76,12 +76,10 @@ LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:5 | LL | unsafe { unsafe { unsf() } } - | ------ ^^^^^^ unnecessary `unsafe` block - | | - | because it's nested under this `unsafe` block + | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5 @@ -91,6 +89,13 @@ LL | unsafe fn allow_level() { ... LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:9 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: unnecessary `unsafe` block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9 @@ -100,6 +105,13 @@ LL | unsafe fn nested_allow_level() { ... LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block + | + = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:63:13 + | +LL | #[allow(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0133]: call to unsafe function is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5