From 77b19d9f4e70402f36742d7818c437d23b740b83 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 2 Nov 2023 12:04:14 +0000 Subject: [PATCH] Stabilize THIR unsafeck --- compiler/rustc_interface/src/passes.rs | 9 +- compiler/rustc_interface/src/tests.rs | 1 - compiler/rustc_middle/src/arena.rs | 1 - compiler/rustc_middle/src/mir/mod.rs | 19 +- compiler/rustc_middle/src/query/mod.rs | 11 +- compiler/rustc_middle/src/ty/codec.rs | 1 - compiler/rustc_mir_build/src/build/block.rs | 36 +- .../rustc_mir_build/src/build/custom/mod.rs | 5 +- .../src/build/expr/as_rvalue.rs | 14 +- .../rustc_mir_build/src/build/expr/into.rs | 7 +- .../rustc_mir_build/src/build/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 52 +- compiler/rustc_mir_build/src/build/scope.rs | 18 +- .../rustc_mir_build/src/check_unsafety.rs | 7 +- compiler/rustc_mir_build/src/lib.rs | 2 +- compiler/rustc_mir_transform/messages.ftl | 28 - .../rustc_mir_transform/src/check_unsafety.rs | 596 ------------------ compiler/rustc_mir_transform/src/errors.rs | 139 +--- compiler/rustc_mir_transform/src/lib.rs | 7 - compiler/rustc_session/src/options.rs | 2 - src/tools/tidy/src/ui_tests.rs | 2 +- .../async-unsafe-fn-call-in-safe.rs | 8 +- .../async-unsafe-fn-call-in-safe.stderr | 8 +- .../binding/issue-53114-safety-checks.stderr | 144 ++--- ...rce-unsafe-closure-to-unsafe-fn-ptr.stderr | 2 +- .../const-extern-fn-requires-unsafe.rs | 4 +- .../const-extern-fn-requires-unsafe.stderr | 4 +- tests/ui/consts/issue-16538.stderr | 18 +- .../issue-45729-unsafe-in-coroutine.stderr | 2 +- tests/ui/error-codes/E0133.stderr | 2 +- tests/ui/extern/issue-28324.stderr | 4 +- tests/ui/inline-const/expr-unsafe-err.stderr | 2 +- .../intrinsics/unchecked_math_unsafe.stderr | 6 +- tests/ui/issues/issue-28776.stderr | 2 +- tests/ui/issues/issue-5844.stderr | 2 +- .../ui/lifetimes/issue-76168-hr-outlives-3.rs | 5 +- .../issue-76168-hr-outlives-3.stderr | 25 +- tests/ui/pattern/usefulness/issue-57472.rs | 12 +- .../ui/pattern/usefulness/issue-57472.stderr | 6 +- .../rfc-2396-target_feature-11/safe-calls.rs | 20 +- .../safe-calls.stderr | 20 +- .../ui/static/safe-extern-statics-mut.stderr | 8 +- tests/ui/static/safe-extern-statics.stderr | 8 +- .../static-mut-foreign-requires-unsafe.stderr | 4 +- .../static/static-mut-requires-unsafe.stderr | 4 +- .../thread-local/thread-local-static.stderr | 16 +- tests/ui/threads-sendsync/issue-43733.rs | 4 +- tests/ui/threads-sendsync/issue-43733.stderr | 4 +- tests/ui/traits/safety-fn-body.stderr | 2 +- .../self-in-enum-definition.stderr | 5 - tests/ui/union/union-unsafe.stderr | 12 +- .../edition-2024-unsafe_op_in_unsafe_fn.rs | 2 +- ...edition-2024-unsafe_op_in_unsafe_fn.stderr | 2 +- tests/ui/unsafe/foreign-unsafe-fn-called.rs | 2 +- .../ui/unsafe/foreign-unsafe-fn-called.stderr | 2 +- tests/ui/unsafe/issue-3080.stderr | 2 +- .../issue-45087-unreachable-unsafe.stderr | 6 +- ...45107-unnecessary-unsafe-in-closure.stderr | 6 +- tests/ui/unsafe/ranged_ints2_const.stderr | 16 +- tests/ui/unsafe/ranged_ints3_const.stderr | 16 +- .../unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs | 8 +- .../rfc-2585-unsafe_op_in_unsafe_fn.stderr | 12 +- tests/ui/unsafe/union-assignop.stderr | 2 +- tests/ui/unsafe/union.rs | 9 +- tests/ui/unsafe/union.stderr | 27 +- tests/ui/unsafe/union_destructure.rs | 12 +- tests/ui/unsafe/union_destructure.stderr | 16 - tests/ui/unsafe/unsafe-const-fn.stderr | 2 +- .../unsafe/unsafe-fn-assign-deref-ptr.stderr | 2 +- tests/ui/unsafe/unsafe-fn-called-from-safe.rs | 2 +- .../unsafe/unsafe-fn-called-from-safe.stderr | 2 +- tests/ui/unsafe/unsafe-fn-used-as-value.rs | 2 +- .../ui/unsafe/unsafe-fn-used-as-value.stderr | 2 +- tests/ui/unsafe/unsafe-not-inherited.stderr | 2 +- .../unsafe/wrapping-unsafe-block-sugg.fixed | 8 +- tests/ui/unsafe/wrapping-unsafe-block-sugg.rs | 8 +- .../unsafe/wrapping-unsafe-block-sugg.stderr | 8 +- 77 files changed, 299 insertions(+), 1201 deletions(-) delete mode 100644 compiler/rustc_mir_transform/src/check_unsafety.rs delete mode 100644 tests/ui/unsafe/union_destructure.stderr diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 7d14d088e595e..bb06f0efb20c3 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -742,18 +742,15 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { sess.time("MIR_borrow_checking", || { tcx.hir().par_body_owners(|def_id| { - // Run THIR unsafety check because it's responsible for stealing - // and deallocating THIR when enabled. - tcx.ensure().thir_check_unsafety(def_id); + // Run unsafety check because it's responsible for stealing and + // deallocating THIR. + tcx.ensure().check_unsafety(def_id); tcx.ensure().mir_borrowck(def_id) }); }); sess.time("MIR_effect_checking", || { for def_id in tcx.hir().body_owners() { - if !tcx.sess.opts.unstable_opts.thir_unsafeck { - rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id); - } tcx.ensure().has_ffi_unwind_calls(def_id); // If we need to codegen, ensure that we emit all errors from diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8e66083a390fc..d06ddbec365ff 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -819,7 +819,6 @@ fn test_unstable_options_tracking_hash() { tracked!(stack_protector, StackProtector::All); tracked!(teach, true); tracked!(thinlto, Some(true)); - tracked!(thir_unsafeck, true); tracked!(tiny_const_eval_limit, true); tracked!(tls_model, Some(TlsModel::GeneralDynamic)); tracked!(trait_solver, TraitSolver::NextCoherence); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index dd761b4e31203..599d39a9caf35 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -42,7 +42,6 @@ macro_rules! arena_types { [] output_filenames: std::sync::Arc, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, - [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, [decode] code_region: rustc_middle::mir::coverage::CodeRegion, [] const_allocs: rustc_middle::mir::interpret::Allocation, [] region_scope_tree: rustc_middle::middle::region::ScopeTree, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7054cede2d87c..2a176e98ea8b1 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -614,17 +614,6 @@ impl<'tcx> Body<'tcx> { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)] -pub enum Safety { - Safe, - /// Unsafe because of compiler-generated unsafe code, like `await` desugaring - BuiltinUnsafe, - /// Unsafe because of an unsafe fn - FnUnsafe, - /// Unsafe because of an `unsafe` block - ExplicitUnsafe(hir::HirId), -} - impl<'tcx> Index for Body<'tcx> { type Output = BasicBlockData<'tcx>; @@ -720,7 +709,7 @@ pub struct SourceInfo { pub span: Span, /// The source scope, keeping track of which bindings can be - /// seen by debuginfo, active lint levels, `unsafe {...}`, etc. + /// seen by debuginfo, active lint levels, etc. pub scope: SourceScope, } @@ -940,7 +929,7 @@ pub struct LocalDecl<'tcx> { /// Extra information about a some locals that's used for diagnostics and for /// classifying variables into local variables, statics, etc, which is needed e.g. -/// for unsafety checking. +/// for borrow checking. /// /// Not used for non-StaticRef temporaries, the return place, or anonymous /// function parameters. @@ -1374,8 +1363,6 @@ pub struct SourceScopeData<'tcx> { pub struct SourceScopeLocalData { /// An `HirId` with lint levels equivalent to this scope's lint levels. pub lint_root: hir::HirId, - /// The unsafe block that contains this node. - pub safety: Safety, } /// A collection of projections into user types. @@ -1631,7 +1618,7 @@ mod size_asserts { // tidy-alphabetical-start static_assert_size!(BasicBlockData<'_>, 136); static_assert_size!(LocalDecl<'_>, 40); - static_assert_size!(SourceScopeData<'_>, 72); + static_assert_size!(SourceScopeData<'_>, 64); static_assert_size!(Statement<'_>, 32); static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 104); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f9ec368361c59..312a50b4ac8db 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -867,15 +867,8 @@ rustc_queries! { desc { |tcx| "collecting all inherent impls for `{:?}`", key } } - /// The result of unsafety-checking this `LocalDefId`. - query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } - } - - /// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be - /// used with `-Zthir-unsafeck`. - query thir_check_unsafety(key: LocalDefId) { + /// Unsafety-check this `LocalDefId`. + query check_unsafety(key: LocalDefId) { desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 8b67e39667b8d..1f5d2eb9e82a2 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -431,7 +431,6 @@ impl_decodable_via_ref! { &'tcx ty::List>, &'tcx traits::ImplSource<'tcx, ()>, &'tcx mir::Body<'tcx>, - &'tcx mir::UnsafetyCheckResult, &'tcx mir::BorrowCheckResult<'tcx>, &'tcx mir::coverage::CodeRegion, &'tcx ty::List, diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index ab4cd24881f6a..d4e53eb285871 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ref stmts, expr, targeted_by_break, - safety_mode, + safety_mode: _, } = self.thir[ast_block]; let expr = expr.map(|expr| &self.thir[expr]); self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| { @@ -33,20 +33,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span, &stmts, expr, - safety_mode, region_scope, )) }) } else { - this.ast_block_stmts( - destination, - block, - span, - &stmts, - expr, - safety_mode, - region_scope, - ) + this.ast_block_stmts(destination, block, span, &stmts, expr, region_scope) } }) }) @@ -59,7 +50,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span: Span, stmts: &[StmtId], expr: Option<&Expr<'tcx>>, - safety_mode: BlockSafety, region_scope: Scope, ) -> BlockAnd<()> { let this = self; @@ -82,13 +72,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // First we build all the statements in the block. let mut let_scope_stack = Vec::with_capacity(8); let outer_source_scope = this.source_scope; - let outer_in_scope_unsafe = this.in_scope_unsafe; // This scope information is kept for breaking out of the parent remainder scope in case // one let-else pattern matching fails. // By doing so, we can be sure that even temporaries that receive extended lifetime // assignments are dropped, too. let mut last_remainder_scope = region_scope; - this.update_source_scope_for_safety_mode(span, safety_mode); let source_info = this.source_info(span); for stmt in stmts { @@ -217,7 +205,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let_scope_stack.push(remainder_scope); let visibility_scope = - Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None)); + Some(this.new_source_scope(remainder_span, LintLevel::Inherited)); let init = &this.thir[*initializer]; let initializer_span = init.span; @@ -292,7 +280,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree); let visibility_scope = - Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None)); + Some(this.new_source_scope(remainder_span, LintLevel::Inherited)); // Evaluate the initializer, if present. if let Some(init) = initializer { @@ -390,22 +378,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Restore the original source scope. this.source_scope = outer_source_scope; - this.in_scope_unsafe = outer_in_scope_unsafe; block.unit() } - - /// 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 => return, - BlockSafety::BuiltinUnsafe => Safety::BuiltinUnsafe, - BlockSafety::ExplicitUnsafe(hir_id) => { - self.in_scope_unsafe = Safety::ExplicitUnsafe(hir_id); - Safety::ExplicitUnsafe(hir_id) - } - }; - - self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(new_unsafety)); - } } diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 3de2f45ad9a83..28159b119707d 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -70,10 +70,7 @@ pub(super) fn build_custom_mir<'tcx>( parent_scope: None, inlined: None, inlined_parent_scope: None, - local_data: ClearCrossCrate::Set(SourceScopeLocalData { - lint_root: hir_id, - safety: Safety::Safe, - }), + local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }), }); body.injection_phase = Some(parse_attribute(attr)); diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index eece8684e3601..eb1179cabc95b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -131,18 +131,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let value = &this.thir[value]; let tcx = this.tcx; - // `exchange_malloc` is unsafe but box is safe, so need a new scope. - let synth_scope = this.new_source_scope( - expr_span, - LintLevel::Inherited, - Some(Safety::BuiltinUnsafe), - ); - let synth_info = SourceInfo { span: expr_span, scope: synth_scope }; - let size = this.temp(tcx.types.usize, expr_span); this.cfg.push_assign( block, - synth_info, + source_info, size, Rvalue::NullaryOp(NullOp::SizeOf, value.ty), ); @@ -150,7 +142,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let align = this.temp(tcx.types.usize, expr_span); this.cfg.push_assign( block, - synth_info, + source_info, align, Rvalue::NullaryOp(NullOp::AlignOf, value.ty), ); @@ -166,7 +158,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let success = this.cfg.start_new_block(); this.cfg.terminate( block, - synth_info, + source_info, TerminatorKind::Call { func: exchange_malloc, args: vec![Operand::Move(size), Operand::Move(align)], diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 054661cf2373b..f24a5cba98df5 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -62,11 +62,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { LintLevel::Inherited, |this| { let source_info = if this.is_let(cond) { - let variable_scope = this.new_source_scope( - then_expr.span, - LintLevel::Inherited, - None, - ); + let variable_scope = + this.new_source_scope(then_expr.span, LintLevel::Inherited); this.source_scope = variable_scope; SourceInfo { span: then_expr.span, scope: variable_scope } } else { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index a43aae6f44942..0460d1faaf857 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -705,7 +705,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut |this, mutability, name, mode, var, span, ty, user_ty| { if visibility_scope.is_none() { visibility_scope = - Some(this.new_source_scope(scope_span, LintLevel::Inherited, None)); + Some(this.new_source_scope(scope_span, LintLevel::Inherited)); } let source_info = SourceInfo { span, scope: this.source_scope }; let visibility_scope = visibility_scope.unwrap(); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 7c729016521b0..b30e49ee58ba8 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -73,17 +73,10 @@ fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { // maybe move the check to a MIR pass? tcx.ensure().check_liveness(def); - if tcx.sess.opts.unstable_opts.thir_unsafeck { - // Don't steal here if THIR unsafeck is being used. Instead - // steal in unsafeck. This is so that pattern inline constants - // can be evaluated as part of building the THIR of the parent - // function without a cycle. - build_mir(&thir.borrow()) - } else { - // We ran all queries that depended on THIR at the beginning - // of `mir_build`, so now we can steal it - build_mir(&thir.steal()) - } + // Don't steal here, instead steal in unsafeck. This is so that + // pattern inline constants can be evaluated as part of building the + // THIR of the parent function without a cycle. + build_mir(&thir.borrow()) } }; @@ -197,9 +190,6 @@ struct Builder<'a, 'tcx> { /// `{ STMTS; EXPR1 } + EXPR2`. block_context: BlockContext, - /// The current unsafe block in scope - in_scope_unsafe: Safety, - /// The vector of all scopes that we have created thus far; /// we track this for debuginfo later. source_scopes: IndexVec>, @@ -468,11 +458,6 @@ fn construct_fn<'tcx>( .output .span(); - let safety = match fn_sig.unsafety { - hir::Unsafety::Normal => Safety::Safe, - hir::Unsafety::Unsafe => Safety::FnUnsafe, - }; - let mut abi = fn_sig.abi; if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, @@ -520,7 +505,6 @@ fn construct_fn<'tcx>( fn_id, span_with_body, arguments.len(), - safety, return_ty, return_ty_span, coroutine_kind, @@ -592,18 +576,8 @@ fn construct_const<'a, 'tcx>( }; let infcx = tcx.infer_ctxt().build(); - let mut builder = Builder::new( - thir, - infcx, - def, - hir_id, - span, - 0, - Safety::Safe, - const_ty, - const_ty_span, - None, - ); + let mut builder = + Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None); let mut block = START_BLOCK; unpack!(block = builder.expr_into_dest(Place::return_place(), block, &thir[expr])); @@ -684,10 +658,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - parent_scope: None, inlined: None, inlined_parent_scope: None, - local_data: ClearCrossCrate::Set(SourceScopeLocalData { - lint_root: hir_id, - safety: Safety::Safe, - }), + local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }), }); cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable); @@ -718,7 +689,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { hir_id: hir::HirId, span: Span, arg_count: usize, - safety: Safety, return_ty: Ty<'tcx>, return_span: Span, coroutine_kind: Option, @@ -758,7 +728,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_scopes: IndexVec::new(), source_scope: OUTERMOST_SOURCE_SCOPE, guard_context: vec![], - in_scope_unsafe: safety, local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1), canonical_user_type_annotations: IndexVec::new(), upvars: CaptureMap::new(), @@ -769,10 +738,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; assert_eq!(builder.cfg.start_new_block(), START_BLOCK); - assert_eq!( - builder.new_source_scope(span, lint_level, Some(safety)), - OUTERMOST_SOURCE_SCOPE - ); + assert_eq!(builder.new_source_scope(span, lint_level), OUTERMOST_SOURCE_SCOPE); builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None; builder @@ -978,7 +944,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .as_ref() .assert_crate_local() .lint_root; - self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id); + self.maybe_new_source_scope(pattern_span, arg_hir_id, parent_id); } fn get_unit_temp(&mut self) -> Place<'tcx> { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index b3d3863b5db77..55864f56b8fab 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -573,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let LintLevel::Explicit(current_hir_id) = lint_level { let parent_id = self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root; - self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id); + self.maybe_new_source_scope(region_scope.1.span, current_hir_id, parent_id); } self.push_scope(region_scope); let mut block; @@ -754,7 +754,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub(crate) fn maybe_new_source_scope( &mut self, span: Span, - safety: Option, current_id: HirId, parent_id: HirId, ) { @@ -784,7 +783,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if current_root != parent_root { let lint_level = LintLevel::Explicit(current_root); - self.source_scope = self.new_source_scope(span, lint_level, safety); + self.source_scope = self.new_source_scope(span, lint_level); } } @@ -833,18 +832,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Creates a new source scope, nested in the current one. - pub(crate) fn new_source_scope( - &mut self, - span: Span, - lint_level: LintLevel, - safety: Option, - ) -> SourceScope { + pub(crate) fn new_source_scope(&mut self, span: Span, lint_level: LintLevel) -> SourceScope { let parent = self.source_scope; debug!( - "new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}", + "new_source_scope({:?}, {:?}) - parent({:?})={:?}", span, lint_level, - safety, parent, self.source_scopes.get(parent) ); @@ -854,9 +847,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root }, - safety: safety.unwrap_or_else(|| { - self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety - }), }; self.source_scopes.push(SourceScopeData { span, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 3d895c131a85c..dc7d44fed99b9 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -839,12 +839,7 @@ impl UnsafeOpKind { } } -pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { - // THIR unsafeck is gated under `-Z thir-unsafeck` - if !tcx.sess.opts.unstable_opts.thir_unsafeck { - return; - } - +pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { // Closures and inline consts are handled by their owner, if it has a body if tcx.is_typeck_child(def.to_def_id()) { return; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 745c3046d22c2..ae39813723d8f 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -35,7 +35,7 @@ pub fn provide(providers: &mut Providers) { providers.mir_built = build::mir_built; providers.closure_saved_names_of_captured_variables = build::closure_saved_names_of_captured_variables; - providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; + providers.check_unsafety = check_unsafety::check_unsafety; providers.thir_body = thir::cx::thir_body; providers.thir_tree = thir::print::thir_tree; providers.thir_flat = thir::print::thir_flat; diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index 5a99afc45b020..39b83b92c8179 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -1,6 +1,4 @@ mir_transform_arithmetic_overflow = this arithmetic operation will overflow -mir_transform_call_to_unsafe_label = call to unsafe function -mir_transform_call_to_unsafe_note = consult the function's documentation for information on how to avoid undefined behavior mir_transform_const_defined_here = `const` item defined here mir_transform_const_modify = attempting to modify a `const` item @@ -35,33 +33,7 @@ mir_transform_mutation_layout_constrained_borrow_note = references to fields of mir_transform_mutation_layout_constrained_label = mutation of layout constrained field mir_transform_mutation_layout_constrained_note = mutating layout constrained fields cannot statically be checked for valid values mir_transform_operation_will_panic = this operation will panic at runtime - -mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in_unsafe_fn_allowed -> - [true] function or block - *[false] block - } - .not_inherited = items do not inherit unsafety from separate enclosing items - -mir_transform_target_feature_call_label = call to function with `#[target_feature]` -mir_transform_target_feature_call_note = can only be called if the required target features are available - mir_transform_unaligned_packed_ref = reference to packed field is unaligned .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -mir_transform_union_access_label = access to union field -mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior -mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133) - .suggestion = consider wrapping the function body in an unsafe block - .note = an unsafe function restricts its caller, but its body is safe by default - -mir_transform_unused_unsafe = unnecessary `unsafe` block - .label = because it's nested under this `unsafe` block - -mir_transform_use_of_asm_label = use of inline assembly -mir_transform_use_of_asm_note = inline assembly is entirely unchecked and can cause undefined behavior -mir_transform_use_of_extern_static_label = use of extern static -mir_transform_use_of_extern_static_note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -mir_transform_use_of_static_mut_label = use of mutable static -mir_transform_use_of_static_mut_note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs deleted file mode 100644 index 8872f9a97d746..0000000000000 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ /dev/null @@ -1,596 +0,0 @@ -use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet}; -use rustc_hir as hir; -use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::hir_id::HirId; -use rustc_hir::intravisit; -use rustc_hir::{BlockCheckMode, ExprKind, Node}; -use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; -use rustc_middle::mir::*; -use rustc_middle::query::Providers; -use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; -use rustc_session::lint::Level; - -use std::ops::Bound; - -use crate::errors; - -pub struct UnsafetyChecker<'a, 'tcx> { - body: &'a Body<'tcx>, - body_did: LocalDefId, - violations: Vec, - source_info: SourceInfo, - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - - /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint. - used_unsafe_blocks: UnordSet, -} - -impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { - fn new( - body: &'a Body<'tcx>, - body_did: LocalDefId, - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { - Self { - body, - body_did, - violations: vec![], - source_info: SourceInfo::outermost(body.span), - tcx, - param_env, - used_unsafe_blocks: Default::default(), - } - } -} - -impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { - fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - self.source_info = terminator.source_info; - match terminator.kind { - TerminatorKind::Goto { .. } - | TerminatorKind::SwitchInt { .. } - | TerminatorKind::Drop { .. } - | TerminatorKind::Yield { .. } - | TerminatorKind::Assert { .. } - | TerminatorKind::CoroutineDrop - | TerminatorKind::UnwindResume - | TerminatorKind::UnwindTerminate(_) - | TerminatorKind::Return - | TerminatorKind::Unreachable - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } => { - // safe (at least as emitted during MIR construction) - } - - TerminatorKind::Call { ref func, .. } => { - let func_ty = func.ty(self.body, self.tcx); - let func_id = - if let ty::FnDef(func_id, _) = func_ty.kind() { Some(func_id) } else { None }; - let sig = func_ty.fn_sig(self.tcx); - if let hir::Unsafety::Unsafe = sig.unsafety() { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::CallToUnsafeFunction, - ) - } - - if let Some(func_id) = func_id { - self.check_target_features(*func_id); - } - } - - TerminatorKind::InlineAsm { .. } => self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfInlineAssembly, - ), - } - self.super_terminator(terminator, location); - } - - fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - self.source_info = statement.source_info; - match statement.kind { - StatementKind::Assign(..) - | StatementKind::FakeRead(..) - | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) - | StatementKind::StorageLive(..) - | StatementKind::StorageDead(..) - | StatementKind::Retag { .. } - | StatementKind::PlaceMention(..) - | StatementKind::Coverage(..) - | StatementKind::Intrinsic(..) - | StatementKind::ConstEvalCounter - | StatementKind::Nop => { - // safe (at least as emitted during MIR construction) - } - // `AscribeUserType` just exists to help MIR borrowck. - // It has no semantics, and everything is already reported by `PlaceMention`. - StatementKind::AscribeUserType(..) => return, - } - self.super_statement(statement, location); - } - - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - match rvalue { - Rvalue::Aggregate(box ref aggregate, _) => match aggregate { - &AggregateKind::Array(..) | &AggregateKind::Tuple => {} - &AggregateKind::Adt(adt_did, ..) => { - match self.tcx.layout_scalar_valid_range(adt_did) { - (Bound::Unbounded, Bound::Unbounded) => {} - _ => self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::InitializingTypeWith, - ), - } - } - &AggregateKind::Closure(def_id, _) | &AggregateKind::Coroutine(def_id, _, _) => { - let def_id = def_id.expect_local(); - let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = - self.tcx.unsafety_check_result(def_id); - self.register_violations(violations, used_unsafe_blocks.items().copied()); - } - }, - _ => {} - } - self.super_rvalue(rvalue, location); - } - - fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { - if let Operand::Constant(constant) = op { - let maybe_uneval = match constant.const_ { - Const::Val(..) | Const::Ty(_) => None, - Const::Unevaluated(uv, _) => Some(uv), - }; - - if let Some(uv) = maybe_uneval { - if uv.promoted.is_none() { - let def_id = uv.def; - if self.tcx.def_kind(def_id) == DefKind::InlineConst { - let local_def_id = def_id.expect_local(); - let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = - self.tcx.unsafety_check_result(local_def_id); - self.register_violations(violations, used_unsafe_blocks.items().copied()); - } - } - } - } - self.super_operand(op, location); - } - - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - // On types with `scalar_valid_range`, prevent - // * `&mut x.field` - // * `x.field = y;` - // * `&x.field` if `field`'s type has interior mutability - // because either of these would allow modifying the layout constrained field and - // insert values that violate the layout constraints. - if context.is_mutating_use() || context.is_borrow() { - self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use()); - } - - // Some checks below need the extra meta info of the local declaration. - let decl = &self.body.local_decls[place.local]; - - // Check the base local: it might be an unsafe-to-access static. We only check derefs of the - // temporary holding the static pointer to avoid duplicate errors - // . - if place.projection.first() == Some(&ProjectionElem::Deref) { - // If the projection root is an artificial local that we introduced when - // desugaring `static`, give a more specific error message - // (avoid the general "raw pointer" clause below, that would only be confusing). - if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() { - if self.tcx.is_mutable_static(def_id) { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfMutableStatic, - ); - return; - } else if self.tcx.is_foreign_item(def_id) { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfExternStatic, - ); - return; - } - } - } - - // Check for raw pointer `Deref`. - for (base, proj) in place.iter_projections() { - if proj == ProjectionElem::Deref { - let base_ty = base.ty(self.body, self.tcx).ty; - if base_ty.is_unsafe_ptr() { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::DerefOfRawPointer, - ) - } - } - } - - // Check for union fields. For this we traverse right-to-left, as the last `Deref` changes - // whether we *read* the union field or potentially *write* to it (if this place is being assigned to). - let mut saw_deref = false; - for (base, proj) in place.iter_projections().rev() { - if proj == ProjectionElem::Deref { - saw_deref = true; - continue; - } - - let base_ty = base.ty(self.body, self.tcx).ty; - if base_ty.is_union() { - // If we did not hit a `Deref` yet and the overall place use is an assignment, the - // rules are different. - let assign_to_field = !saw_deref - && matches!( - context, - PlaceContext::MutatingUse( - MutatingUseContext::Store - | MutatingUseContext::Drop - | MutatingUseContext::AsmOutput - ) - ); - // If this is just an assignment, determine if the assigned type needs dropping. - if assign_to_field { - // We have to check the actual type of the assignment, as that determines if the - // old value is being dropped. - let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty; - if assigned_ty.needs_drop(self.tcx, self.param_env) { - // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.sess.delay_span_bug( - self.source_info.span, - format!("union fields that need dropping should be impossible: {assigned_ty}") - ); - } - } else { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::AccessToUnionField, - ) - } - } - } - } -} - -impl<'tcx> UnsafetyChecker<'_, 'tcx> { - fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) { - // Violations can turn out to be `UnsafeFn` during analysis, but they should not start out as such. - assert_ne!(kind, UnsafetyViolationKind::UnsafeFn); - - let source_info = self.source_info; - let lint_root = self.body.source_scopes[self.source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root; - self.register_violations( - [&UnsafetyViolation { source_info, lint_root, kind, details }], - UnordItems::empty(), - ); - } - - fn register_violations<'a>( - &mut self, - violations: impl IntoIterator, - new_used_unsafe_blocks: UnordItems>, - ) { - let safety = self.body.source_scopes[self.source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .safety; - match safety { - // `unsafe` blocks are required in safe code - Safety::Safe => violations.into_iter().for_each(|&violation| { - match violation.kind { - UnsafetyViolationKind::General => {} - UnsafetyViolationKind::UnsafeFn => { - bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context") - } - } - if !self.violations.contains(&violation) { - self.violations.push(violation) - } - }), - // 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) - } - }), - Safety::BuiltinUnsafe => {} - Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| { - self.used_unsafe_blocks.insert(hir_id); - }), - }; - - self.used_unsafe_blocks.extend_unord(new_used_unsafe_blocks); - } - fn check_mut_borrowing_layout_constrained_field( - &mut self, - place: Place<'tcx>, - is_mut_use: bool, - ) { - for (place_base, elem) in place.iter_projections().rev() { - match elem { - // Modifications behind a dereference don't affect the value of - // the pointer. - ProjectionElem::Deref => return, - ProjectionElem::Field(..) => { - let ty = place_base.ty(&self.body.local_decls, self.tcx).ty; - if let ty::Adt(def, _) = ty.kind() { - if self.tcx.layout_scalar_valid_range(def.did()) - != (Bound::Unbounded, Bound::Unbounded) - { - let details = if is_mut_use { - UnsafetyViolationDetails::MutationOfLayoutConstrainedField - - // Check `is_freeze` as late as possible to avoid cycle errors - // with opaque types. - } else if !place - .ty(self.body, self.tcx) - .ty - .is_freeze(self.tcx, self.param_env) - { - UnsafetyViolationDetails::BorrowOfLayoutConstrainedField - } else { - continue; - }; - self.require_unsafe(UnsafetyViolationKind::General, details); - } - } - } - _ => {} - } - } - } - - /// Checks whether calling `func_did` needs an `unsafe` context or not, i.e. whether - /// the called function has target features the calling function hasn't. - fn check_target_features(&mut self, func_did: DefId) { - // Unsafety isn't required on wasm targets. For more information see - // the corresponding check in typeck/src/collect.rs - if self.tcx.sess.target.options.is_like_wasm { - return; - } - - let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features; - // The body might be a constant, so it doesn't have codegen attributes. - let self_features = &self.tcx.body_codegen_attrs(self.body_did.to_def_id()).target_features; - - // Is `callee_features` a subset of `calling_features`? - if !callee_features.iter().all(|feature| self_features.contains(feature)) { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::CallToFunctionWith, - ) - } - } -} - -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { unsafety_check_result, ..*providers }; -} - -/// 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 UnordSet, - context: Context, - unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>, -} - -impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> { - fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) { - if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules { - let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) { - (Level::Allow, _) => true, - _ => self.used_unsafe_blocks.contains(&block.hir_id), - }; - let unused_unsafe = match (self.context, used) { - (_, false) => UnusedUnsafe::Unused, - (Context::Safe, true) | (Context::UnsafeFn(_), true) => { - let previous_context = self.context; - self.context = Context::UnsafeBlock(block.hir_id); - intravisit::walk_block(self, block); - self.context = previous_context; - return; - } - (Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id), - }; - self.unused_unsafes.push((block.hir_id, unused_unsafe)); - } - intravisit::walk_block(self, block); - } - - fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) { - self.visit_body(self.tcx.hir().body(c.body)) - } - - fn visit_fn( - &mut self, - fk: intravisit::FnKind<'tcx>, - _fd: &'tcx hir::FnDecl<'tcx>, - b: hir::BodyId, - _s: rustc_span::Span, - _id: LocalDefId, - ) { - if matches!(fk, intravisit::FnKind::Closure) { - self.visit_body(self.tcx.hir().body(b)) - } - } -} - -fn check_unused_unsafe( - tcx: TyCtxt<'_>, - def_id: LocalDefId, - used_unsafe_blocks: &UnordSet, -) -> Vec<(HirId, UnusedUnsafe)> { - let body_id = tcx.hir().maybe_body_owned_by(def_id); - - let Some(body_id) = body_id else { - debug!("check_unused_unsafe({:?}) - no body found", def_id); - return vec![]; - }; - - let body = tcx.hir().body(body_id); - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - 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: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult { - debug!("unsafety_violations({:?})", def); - - // N.B., this borrow is valid because all the consumers of - // `mir_built` force this. - let body = &tcx.mir_built(def).borrow(); - - if body.is_custom_mir() || body.tainted_by_errors.is_some() { - return tcx.arena.alloc(UnsafetyCheckResult { - violations: Vec::new(), - used_unsafe_blocks: Default::default(), - unused_unsafes: Some(Vec::new()), - }); - } - - let param_env = tcx.param_env(def); - - let mut checker = UnsafetyChecker::new(body, def, tcx, param_env); - checker.visit_body(&body); - - let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id())) - .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks)); - - tcx.arena.alloc(UnsafetyCheckResult { - violations: checker.violations, - used_unsafe_blocks: checker.used_unsafe_blocks, - unused_unsafes, - }) -} - -fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { - let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id)); - let nested_parent = if let UnusedUnsafe::InUnsafeBlock(id) = kind { - Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id))) - } else { - None - }; - tcx.emit_spanned_lint(UNUSED_UNSAFE, id, span, errors::UnusedUnsafe { span, nested_parent }); -} - -pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { - debug!("check_unsafety({:?})", def_id); - - // closures and inline consts are handled by their parent fn. - if tcx.is_typeck_child(def_id.to_def_id()) { - return; - } - - let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id); - // Only suggest wrapping the entire function body in an unsafe block once - let mut suggest_unsafe_block = true; - - for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { - let details = errors::RequiresUnsafeDetail { violation: details, span: source_info.span }; - - match kind { - UnsafetyViolationKind::General => { - let op_in_unsafe_fn_allowed = unsafe_op_in_unsafe_fn_allowed(tcx, lint_root); - let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| { - if let Node::Expr(block) = node - && let ExprKind::Block(block, _) = block.kind - && let BlockCheckMode::UnsafeBlock(_) = block.rules - { - true - } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) - && sig.header.is_unsafe() - { - true - } else { - false - } - }); - let enclosing = if let Some((id, _)) = note_non_inherited { - Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id))) - } else { - None - }; - tcx.sess.emit_err(errors::RequiresUnsafe { - span: source_info.span, - enclosing, - details, - op_in_unsafe_fn_allowed, - }); - } - UnsafetyViolationKind::UnsafeFn => { - tcx.emit_spanned_lint( - UNSAFE_OP_IN_UNSAFE_FN, - lint_root, - source_info.span, - errors::UnsafeOpInUnsafeFn { - details, - suggest_unsafe_block: suggest_unsafe_block.then(|| { - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let fn_sig = tcx - .hir() - .fn_sig_by_hir_id(hir_id) - .expect("this violation only occurs in fn"); - let body = tcx.hir().body_owned_by(def_id); - let body_span = tcx.hir().body(body).value.span; - let start = tcx.sess.source_map().start_point(body_span).shrink_to_hi(); - let end = tcx.sess.source_map().end_point(body_span).shrink_to_lo(); - (start, end, fn_sig.span) - }), - }, - ); - suggest_unsafe_block = false; - } - } - } - - for &(block_id, kind) in unused_unsafes.as_ref().unwrap() { - report_unused_unsafe(tcx, kind, block_id); - } -} - -fn unsafe_op_in_unsafe_fn_allowed(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, id).0 == Level::Allow -} diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 5879a803946d6..c78ebd8587de4 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,9 +1,6 @@ -use rustc_errors::{ - Applicability, DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, - IntoDiagnostic, -}; +use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; -use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; +use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; use rustc_session::lint::{self, Lint}; use rustc_span::def_id::DefId; @@ -38,138 +35,6 @@ pub(crate) struct UnalignedPackedRef { pub span: Span, } -#[derive(LintDiagnostic)] -#[diag(mir_transform_unused_unsafe)] -pub(crate) struct UnusedUnsafe { - #[label(mir_transform_unused_unsafe)] - pub span: Span, - #[label] - pub nested_parent: Option, -} - -pub(crate) struct RequiresUnsafe { - pub span: Span, - pub details: RequiresUnsafeDetail, - pub enclosing: Option, - pub op_in_unsafe_fn_allowed: bool, -} - -// The primary message for this diagnostic should be '{$label} is unsafe and...', -// so we need to eagerly translate the label here, which isn't supported by the derive API -// We could also exhaustively list out the primary messages for all unsafe violations, -// but this would result in a lot of duplication. -impl<'sess, G: EmissionGuarantee> IntoDiagnostic<'sess, G> for RequiresUnsafe { - #[track_caller] - fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, G> { - let mut diag = - handler.struct_diagnostic(crate::fluent_generated::mir_transform_requires_unsafe); - diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string())); - diag.set_span(self.span); - diag.span_label(self.span, self.details.label()); - diag.note(self.details.note()); - let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); - diag.set_arg("details", desc); - diag.set_arg("op_in_unsafe_fn_allowed", self.op_in_unsafe_fn_allowed); - if let Some(sp) = self.enclosing { - diag.span_label(sp, crate::fluent_generated::mir_transform_not_inherited); - } - diag - } -} - -#[derive(Copy, Clone)] -pub(crate) struct RequiresUnsafeDetail { - pub span: Span, - pub violation: UnsafetyViolationDetails, -} - -impl RequiresUnsafeDetail { - fn note(self) -> DiagnosticMessage { - use UnsafetyViolationDetails::*; - match self.violation { - CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_note, - UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_note, - InitializingTypeWith => { - crate::fluent_generated::mir_transform_initializing_valid_range_note - } - CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_note, - UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_note, - UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_note, - DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_note, - AccessToUnionField => crate::fluent_generated::mir_transform_union_access_note, - MutationOfLayoutConstrainedField => { - crate::fluent_generated::mir_transform_mutation_layout_constrained_note - } - BorrowOfLayoutConstrainedField => { - crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_note - } - CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_note, - } - } - - fn label(self) -> DiagnosticMessage { - use UnsafetyViolationDetails::*; - match self.violation { - CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_label, - UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_label, - InitializingTypeWith => { - crate::fluent_generated::mir_transform_initializing_valid_range_label - } - CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_label, - UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_label, - UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_label, - DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_label, - AccessToUnionField => crate::fluent_generated::mir_transform_union_access_label, - MutationOfLayoutConstrainedField => { - crate::fluent_generated::mir_transform_mutation_layout_constrained_label - } - BorrowOfLayoutConstrainedField => { - crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_label - } - CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_label, - } - } -} - -pub(crate) struct UnsafeOpInUnsafeFn { - pub details: RequiresUnsafeDetail, - - /// These spans point to: - /// 1. the start of the function body - /// 2. the end of the function body - /// 3. the function signature - pub suggest_unsafe_block: Option<(Span, Span, Span)>, -} - -impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { - #[track_caller] - fn decorate_lint<'b>( - self, - diag: &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()> { - let handler = diag.handler().expect("lint should not yet be emitted"); - let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); - diag.set_arg("details", desc); - diag.span_label(self.details.span, self.details.label()); - diag.note(self.details.note()); - - if let Some((start, end, fn_sig)) = self.suggest_unsafe_block { - diag.span_note(fn_sig, crate::fluent_generated::mir_transform_note); - diag.tool_only_multipart_suggestion( - crate::fluent_generated::mir_transform_suggestion, - vec![(start, " unsafe {".into()), (end, "}".into())], - Applicability::MaybeIncorrect, - ); - } - - diag - } - - fn msg(&self) -> DiagnosticMessage { - crate::fluent_generated::mir_transform_unsafe_op_in_unsafe_fn - } -} - pub(crate) enum AssertLint

{ ArithmeticOverflow(Span, AssertKind

), UnconditionalPanic(Span, AssertKind

), diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index bf5f0ca7cbd23..b9a2a2f07c8b6 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -53,7 +53,6 @@ mod add_moves_for_packed_drops; mod add_retag; mod check_const_item_mutation; mod check_packed_ref; -pub mod check_unsafety; mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup mod add_subtyping_projections; @@ -124,7 +123,6 @@ use rustc_fluent_macro::fluent_messages; fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { - check_unsafety::provide(providers); coverage::query::provide(providers); ffi_unwind_calls::provide(providers); shim::provide(providers); @@ -287,11 +285,6 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { /// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query). /// We used to have this for pre-miri MIR based const eval. fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { - // Unsafety check uses the raw mir, so make sure it is run. - if !tcx.sess.opts.unstable_opts.thir_unsafeck { - tcx.ensure_with_value().unsafety_check_result(def); - } - // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. tcx.ensure_with_value().has_ffi_unwind_calls(def); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7510a41485af6..3601fb7c6426a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1831,8 +1831,6 @@ written to standard error output)"), #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")] thinlto: Option = (None, parse_opt_bool, [TRACKED], "enable ThinLTO when possible"), - thir_unsafeck: bool = (false, parse_bool, [TRACKED], - "use the THIR unsafety checker (default: no)"), /// We default to 1 here since we want to behave like /// a sequential compiler for now. This'll likely be adjusted /// in the future. Note that -Zthreads=0 is the way to get diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 7e24793adee0e..9f9633791ad3b 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: usize = 1854; +const ISSUES_ENTRY_LIMIT: usize = 1851; const ROOT_ENTRY_LIMIT: usize = 867; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ diff --git a/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs b/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs index f7e9e96bff700..7695853000d79 100644 --- a/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs +++ b/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -10,14 +10,14 @@ async unsafe fn f() {} async fn g() { S::f(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `S::f` is unsafe f(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `f` is unsafe } fn main() { S::f(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `S::f` is unsafe f(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `f` is unsafe } diff --git a/tests/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/tests/ui/async-await/async-unsafe-fn-call-in-safe.stderr index 89c496c598d1c..b25794c089235 100644 --- a/tests/ui/async-await/async-unsafe-fn-call-in-safe.stderr +++ b/tests/ui/async-await/async-unsafe-fn-call-in-safe.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block --> $DIR/async-unsafe-fn-call-in-safe.rs:12:5 | LL | S::f(); @@ -6,7 +6,7 @@ LL | S::f(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 | LL | f(); @@ -14,7 +14,7 @@ LL | f(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5 | LL | S::f(); @@ -22,7 +22,7 @@ LL | S::f(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/async-unsafe-fn-call-in-safe.rs:21:5 | LL | f(); diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index 349c4639a9e2d..b7d805d91718b 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -1,63 +1,3 @@ -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:23:13 - | -LL | let _ = &p.b; - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:28:17 - | -LL | let (_,) = (&p.b,); - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:37:16 - | -LL | let _: _ = &p.b; - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:42:20 - | -LL | let (_,): _ = (&p.b,); - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:51:11 - | -LL | match &p.b { _ => { } } - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - -error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:56:12 - | -LL | match (&p.b,) { (_,) => { } } - | ^^^^ - | - = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses - = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:24:13 | @@ -67,10 +7,10 @@ LL | let _ = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:25:13 + --> $DIR/issue-53114-safety-checks.rs:25:14 | LL | let _ = &u2.a; - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior @@ -83,13 +23,33 @@ LL | let (_,) = (u1.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:30:17 + --> $DIR/issue-53114-safety-checks.rs:30:18 | LL | let (_,) = (&u2.a,); - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:23:13 + | +LL | let _ = &p.b; + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:28:17 + | +LL | let (_,) = (&p.b,); + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:38:16 | @@ -99,10 +59,10 @@ LL | let _: _ = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:39:16 + --> $DIR/issue-53114-safety-checks.rs:39:17 | LL | let _: _ = &u2.a; - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior @@ -115,13 +75,33 @@ LL | let (_,): _ = (u1.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:44:20 + --> $DIR/issue-53114-safety-checks.rs:44:21 | LL | let (_,): _ = (&u2.a,); - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:37:16 + | +LL | let _: _ = &p.b; + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:42:20 + | +LL | let (_,): _ = (&p.b,); + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:52:11 | @@ -131,10 +111,10 @@ LL | match u1.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:53:11 + --> $DIR/issue-53114-safety-checks.rs:53:12 | LL | match &u2.a { _ => { } } - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior @@ -147,13 +127,33 @@ LL | match (u1.a,) { (_,) => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:58:12 + --> $DIR/issue-53114-safety-checks.rs:58:13 | LL | match (&u2.a,) { (_,) => { } } - | ^^^^^ access to union field + | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:51:11 + | +LL | match &p.b { _ => { } } + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:56:12 + | +LL | match (&p.b,) { (_,) => { } } + | ^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + error: aborting due to 18 previous errors Some errors have detailed explanations: E0133, E0793. diff --git a/tests/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr b/tests/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr index a1fb1c02e4622..ecd15b134f8c7 100644 --- a/tests/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr +++ b/tests/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `Pin::

::new_unchecked` is unsafe and requires unsafe function or block --> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:2:31 | LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); }; diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs index 896d4b376fdae..eacdb80d440dc 100644 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs +++ b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs @@ -4,7 +4,7 @@ const unsafe extern "C" fn foo() -> usize { 5 } fn main() { let a: [u8; foo()]; - //~^ call to unsafe function is unsafe and requires unsafe function or block + //~^ call to unsafe function `foo` is unsafe and requires unsafe function or block foo(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //~^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block } diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr index 5196b8ee0a21d..63712faec659b 100644 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr +++ b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block --> $DIR/const-extern-fn-requires-unsafe.rs:8:5 | LL | foo(); @@ -6,7 +6,7 @@ LL | foo(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block --> $DIR/const-extern-fn-requires-unsafe.rs:6:17 | LL | let a: [u8; foo()]; diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index afb344f5e857b..834ffa8d3a0ee 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -1,11 +1,10 @@ -error[E0015]: cannot call non-const fn `Y::foo` in statics - --> $DIR/issue-16538.rs:11:23 +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-16538.rs:11:22 | LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/issue-16538.rs:11:30 @@ -15,13 +14,14 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); | = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior -error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-16538.rs:11:21 +error[E0015]: cannot call non-const fn `Y::foo` in statics + --> $DIR/issue-16538.rs:11:23 | LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell error: aborting due to 3 previous errors diff --git a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr index 3d8b4a621ed77..358281320e3a1 100644 --- a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr +++ b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr @@ -2,7 +2,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/issue-45729-unsafe-in-coroutine.rs:5:9 | LL | *(1 as *mut u32) = 42; - | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer + | ^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior diff --git a/tests/ui/error-codes/E0133.stderr b/tests/ui/error-codes/E0133.stderr index 1eb696506f345..17749a075c2f4 100644 --- a/tests/ui/error-codes/E0133.stderr +++ b/tests/ui/error-codes/E0133.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/E0133.rs:4:5 | LL | f(); diff --git a/tests/ui/extern/issue-28324.stderr b/tests/ui/extern/issue-28324.stderr index d7dad99215204..52dc4155fc79b 100644 --- a/tests/ui/extern/issue-28324.stderr +++ b/tests/ui/extern/issue-28324.stderr @@ -1,8 +1,8 @@ error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/issue-28324.rs:5:24 + --> $DIR/issue-28324.rs:5:25 | LL | pub static BAZ: u32 = *&error_message_count; - | ^^^^^^^^^^^^^^^^^^^^ use of extern static + | ^^^^^^^^^^^^^^^^^^^ use of extern static | = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior diff --git a/tests/ui/inline-const/expr-unsafe-err.stderr b/tests/ui/inline-const/expr-unsafe-err.stderr index 1bec41e2efa01..c971e8afb3577 100644 --- a/tests/ui/inline-const/expr-unsafe-err.stderr +++ b/tests/ui/inline-const/expr-unsafe-err.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block --> $DIR/expr-unsafe-err.rs:8:9 | LL | require_unsafe(); diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.stderr b/tests/ui/intrinsics/unchecked_math_unsafe.stderr index 4066cf8efb8c1..31da1a86ca135 100644 --- a/tests/ui/intrinsics/unchecked_math_unsafe.stderr +++ b/tests/ui/intrinsics/unchecked_math_unsafe.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_add` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:5:15 | LL | let add = std::intrinsics::unchecked_add(x, y); @@ -6,7 +6,7 @@ LL | let add = std::intrinsics::unchecked_add(x, y); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_sub` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:6:15 | LL | let sub = std::intrinsics::unchecked_sub(x, y); @@ -14,7 +14,7 @@ LL | let sub = std::intrinsics::unchecked_sub(x, y); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_mul` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:7:15 | LL | let mul = std::intrinsics::unchecked_mul(x, y); diff --git a/tests/ui/issues/issue-28776.stderr b/tests/ui/issues/issue-28776.stderr index 7faac88e26a23..7b4bf69a3acb7 100644 --- a/tests/ui/issues/issue-28776.stderr +++ b/tests/ui/issues/issue-28776.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block --> $DIR/issue-28776.rs:4:5 | LL | (&ptr::write)(1 as *mut _, 42); diff --git a/tests/ui/issues/issue-5844.stderr b/tests/ui/issues/issue-5844.stderr index ed5a3dc6b1e1e..58ed47427df81 100644 --- a/tests/ui/issues/issue-5844.stderr +++ b/tests/ui/issues/issue-5844.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `rand` is unsafe and requires unsafe function or block --> $DIR/issue-5844.rs:6:5 | LL | issue_5844_aux::rand(); diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index b0b6b318d8f78..782c38200a06f 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -6,10 +6,9 @@ use std::future::Future; async fn wrapper(f: F) //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` where - F:, - for<'a> >::Output: Future + 'a, +F:, +for<'a> >::Output: Future + 'a, { //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` let mut i = 41; diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 5b77051dc8872..89ebdb57f3c31 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -4,11 +4,10 @@ error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` LL | / async fn wrapper(f: F) LL | | LL | | -LL | | LL | | where -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |______________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | | F:, +LL | | for<'a> >::Output: Future + 'a, + | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` @@ -21,7 +20,7 @@ LL | async fn wrapper(f: F) = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:13:1 + --> $DIR/issue-76168-hr-outlives-3.rs:12:1 | LL | / { LL | | @@ -32,20 +31,6 @@ LL | | } | = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:1 - | -LL | / async fn wrapper(f: F) -LL | | -LL | | -LL | | -LL | | where -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |______________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/pattern/usefulness/issue-57472.rs b/tests/ui/pattern/usefulness/issue-57472.rs index 1131006374c64..17c252de2be09 100644 --- a/tests/ui/pattern/usefulness/issue-57472.rs +++ b/tests/ui/pattern/usefulness/issue-57472.rs @@ -1,4 +1,4 @@ -#![crate_type="lib"] +#![crate_type = "lib"] #![deny(unreachable_patterns)] mod test_struct { @@ -26,10 +26,12 @@ mod test_union { } pub fn test(punned: Punned) { - match punned { - Punned { foo: [_] } => println!("foo"), - Punned { bar: [_] } => println!("bar"), - //~^ ERROR unreachable pattern [unreachable_patterns] + unsafe { + match punned { + Punned { foo: [_] } => println!("foo"), + Punned { bar: [_] } => println!("bar"), + //~^ ERROR unreachable pattern [unreachable_patterns] + } } } } diff --git a/tests/ui/pattern/usefulness/issue-57472.stderr b/tests/ui/pattern/usefulness/issue-57472.stderr index 26efdf6dbaf34..c814eaec0d19e 100644 --- a/tests/ui/pattern/usefulness/issue-57472.stderr +++ b/tests/ui/pattern/usefulness/issue-57472.stderr @@ -11,10 +11,10 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/issue-57472.rs:31:13 + --> $DIR/issue-57472.rs:32:17 | -LL | Punned { bar: [_] } => println!("bar"), - | ^^^^^^^^^^^^^^^^^^^ +LL | Punned { bar: [_] } => println!("bar"), + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs index 21fdda1a871b0..c1d13ba0f6afd 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs @@ -19,39 +19,39 @@ impl Quux { fn foo() { sse2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe Quux.avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "sse2")] fn bar() { avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe Quux.avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "avx")] fn baz() { sse2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe Quux.avx_bmi2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "avx")] #[target_feature(enable = "bmi2")] fn qux() { sse2(); - //~^ ERROR call to function with `#[target_feature]` is unsafe + //~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe } const name: () = sse2(); -//~^ ERROR call to function with `#[target_feature]` is unsafe +//~^ ERROR call to function `sse2` with `#[target_feature]` is unsafe fn main() {} diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr index db466b414fb1e..676637b723b81 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:21:5 | LL | sse2(); @@ -6,7 +6,7 @@ LL | sse2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:23:5 | LL | avx_bmi2(); @@ -14,7 +14,7 @@ LL | avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:25:5 | LL | Quux.avx_bmi2(); @@ -22,7 +22,7 @@ LL | Quux.avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:31:5 | LL | avx_bmi2(); @@ -30,7 +30,7 @@ LL | avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:33:5 | LL | Quux.avx_bmi2(); @@ -38,7 +38,7 @@ LL | Quux.avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:39:5 | LL | sse2(); @@ -46,7 +46,7 @@ LL | sse2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:41:5 | LL | avx_bmi2(); @@ -54,7 +54,7 @@ LL | avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:43:5 | LL | Quux.avx_bmi2(); @@ -62,7 +62,7 @@ LL | Quux.avx_bmi2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:50:5 | LL | sse2(); @@ -70,7 +70,7 @@ LL | sse2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:54:18 | LL | const name: () = sse2(); diff --git a/tests/ui/static/safe-extern-statics-mut.stderr b/tests/ui/static/safe-extern-statics-mut.stderr index 3880388341445..e390625f20a98 100644 --- a/tests/ui/static/safe-extern-statics-mut.stderr +++ b/tests/ui/static/safe-extern-statics-mut.stderr @@ -7,10 +7,10 @@ LL | let b = B; = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/safe-extern-statics-mut.rs:12:14 + --> $DIR/safe-extern-statics-mut.rs:12:15 | LL | let rb = &B; - | ^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -23,10 +23,10 @@ LL | let xb = XB; = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/safe-extern-statics-mut.rs:14:15 + --> $DIR/safe-extern-statics-mut.rs:14:16 | LL | let xrb = &XB; - | ^^^ use of mutable static + | ^^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/tests/ui/static/safe-extern-statics.stderr b/tests/ui/static/safe-extern-statics.stderr index b42572ea3eeb5..6be6c074c2611 100644 --- a/tests/ui/static/safe-extern-statics.stderr +++ b/tests/ui/static/safe-extern-statics.stderr @@ -7,10 +7,10 @@ LL | let a = A; = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/safe-extern-statics.rs:12:14 + --> $DIR/safe-extern-statics.rs:12:15 | LL | let ra = &A; - | ^^ use of extern static + | ^ use of extern static | = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior @@ -23,10 +23,10 @@ LL | let xa = XA; = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/safe-extern-statics.rs:14:15 + --> $DIR/safe-extern-statics.rs:14:16 | LL | let xra = &XA; - | ^^^ use of extern static + | ^^ use of extern static | = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior diff --git a/tests/ui/static/static-mut-foreign-requires-unsafe.stderr b/tests/ui/static/static-mut-foreign-requires-unsafe.stderr index e7ed0b710b2f3..022f7e9fb1655 100644 --- a/tests/ui/static/static-mut-foreign-requires-unsafe.stderr +++ b/tests/ui/static/static-mut-foreign-requires-unsafe.stderr @@ -2,7 +2,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-foreign-requires-unsafe.rs:6:5 | LL | a += 3; - | ^^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -10,7 +10,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-foreign-requires-unsafe.rs:7:5 | LL | a = 4; - | ^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/tests/ui/static/static-mut-requires-unsafe.stderr b/tests/ui/static/static-mut-requires-unsafe.stderr index 85e468b333c28..30be0220cf65a 100644 --- a/tests/ui/static/static-mut-requires-unsafe.stderr +++ b/tests/ui/static/static-mut-requires-unsafe.stderr @@ -2,7 +2,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-requires-unsafe.rs:4:5 | LL | a += 3; - | ^^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -10,7 +10,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-requires-unsafe.rs:5:5 | LL | a = 4; - | ^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index f37fd9db36d6e..c1777dd60db68 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -1,3 +1,11 @@ +error[E0133]: use of mutable static is unsafe and requires unsafe function or block + --> $DIR/thread-local-static.rs:10:28 + | +LL | std::mem::swap(x, &mut STATIC_VAR_2) + | ^^^^^^^^^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + error[E0658]: mutable references are not allowed in constant functions --> $DIR/thread-local-static.rs:8:12 | @@ -30,14 +38,6 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/thread-local-static.rs:10:23 - | -LL | std::mem::swap(x, &mut STATIC_VAR_2) - | ^^^^^^^^^^^^^^^^^ use of mutable static - | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - error: aborting due to 5 previous errors Some errors have detailed explanations: E0013, E0133, E0625, E0658. diff --git a/tests/ui/threads-sendsync/issue-43733.rs b/tests/ui/threads-sendsync/issue-43733.rs index 996abb4809a4a..671b45e777f84 100644 --- a/tests/ui/threads-sendsync/issue-43733.rs +++ b/tests/ui/threads-sendsync/issue-43733.rs @@ -15,11 +15,11 @@ static __KEY: std::thread::local_impl::Key = std::thread::local_impl::Key:: fn __getit(_: Option<&mut Option>>) -> std::option::Option<&'static Foo> { __KEY.get(Default::default) - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `Key::::get` is unsafe } static FOO: std::thread::LocalKey = std::thread::LocalKey::new(__getit); -//~^ ERROR call to unsafe function is unsafe +//~^ ERROR call to unsafe function `LocalKey::::new` is unsafe fn main() { FOO.with(|foo| println!("{}", foo.borrow())); diff --git a/tests/ui/threads-sendsync/issue-43733.stderr b/tests/ui/threads-sendsync/issue-43733.stderr index 9090fd0a4a6fd..9b13646a22852 100644 --- a/tests/ui/threads-sendsync/issue-43733.stderr +++ b/tests/ui/threads-sendsync/issue-43733.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `Key::::get` is unsafe and requires unsafe function or block --> $DIR/issue-43733.rs:17:5 | LL | __KEY.get(Default::default) @@ -6,7 +6,7 @@ LL | __KEY.get(Default::default) | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `LocalKey::::new` is unsafe and requires unsafe function or block --> $DIR/issue-43733.rs:21:42 | LL | static FOO: std::thread::LocalKey = std::thread::LocalKey::new(__getit); diff --git a/tests/ui/traits/safety-fn-body.stderr b/tests/ui/traits/safety-fn-body.stderr index 0aeb186828eea..58c2c8d03c86e 100644 --- a/tests/ui/traits/safety-fn-body.stderr +++ b/tests/ui/traits/safety-fn-body.stderr @@ -2,7 +2,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/safety-fn-body.rs:11:9 | LL | *self += 1; - | ^^^^^^^^^^ dereference of raw pointer + | ^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr index aa79b1a57c4c8..760bd747e1cce 100644 --- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -44,11 +44,6 @@ note: ...which requires preparing `Alpha::V3::{constant#0}` for borrow checking. | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `Alpha::V3::{constant#0}`... - --> $DIR/self-in-enum-definition.rs:5:10 - | -LL | V3 = Self::V1 {} as u8 + 2, - | ^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `Alpha::V3::{constant#0}`... --> $DIR/self-in-enum-definition.rs:5:10 | diff --git a/tests/ui/union/union-unsafe.stderr b/tests/ui/union/union-unsafe.stderr index 4d3408a89af29..82b3f897167c7 100644 --- a/tests/ui/union/union-unsafe.stderr +++ b/tests/ui/union/union-unsafe.stderr @@ -1,8 +1,8 @@ error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:31:5 + --> $DIR/union-unsafe.rs:31:6 | LL | *(u.p) = 13; - | ^^^^^^^^^^^ access to union field + | ^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior @@ -39,18 +39,18 @@ LL | let U1 { a } = u1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:61:12 + --> $DIR/union-unsafe.rs:61:20 | LL | if let U1 { a: 12 } = u1 {} - | ^^^^^^^^^^^^ access to union field + | ^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:62:12 + --> $DIR/union-unsafe.rs:62:25 | LL | if let Some(U1 { a: 13 }) = Some(u1) {} - | ^^^^^^^^^^^^^^^^^^ access to union field + | ^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs index 9e150326f0bb3..f84f12c8301d7 100644 --- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs @@ -8,7 +8,7 @@ unsafe fn unsf() {} unsafe fn foo() { unsf(); - //~^ WARN call to unsafe function is unsafe and requires unsafe block + //~^ WARN call to unsafe function `unsf` is unsafe and requires unsafe block // no unused_unsafe unsafe { diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr index 9ca10b0509032..1187c2d80f388 100644 --- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr @@ -1,4 +1,4 @@ -warning: call to unsafe function is unsafe and requires unsafe block (error E0133) +warning: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:10:5 | LL | unsf(); diff --git a/tests/ui/unsafe/foreign-unsafe-fn-called.rs b/tests/ui/unsafe/foreign-unsafe-fn-called.rs index abbe462021ed7..b5065beb5fcb8 100644 --- a/tests/ui/unsafe/foreign-unsafe-fn-called.rs +++ b/tests/ui/unsafe/foreign-unsafe-fn-called.rs @@ -6,5 +6,5 @@ mod test { fn main() { test::free(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `test::free` is unsafe } diff --git a/tests/ui/unsafe/foreign-unsafe-fn-called.stderr b/tests/ui/unsafe/foreign-unsafe-fn-called.stderr index afc9632de7cf8..9d34e153edd3e 100644 --- a/tests/ui/unsafe/foreign-unsafe-fn-called.stderr +++ b/tests/ui/unsafe/foreign-unsafe-fn-called.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `test::free` is unsafe and requires unsafe function or block --> $DIR/foreign-unsafe-fn-called.rs:8:5 | LL | test::free(); diff --git a/tests/ui/unsafe/issue-3080.stderr b/tests/ui/unsafe/issue-3080.stderr index 138d6df679fc4..459b02b5aa64f 100644 --- a/tests/ui/unsafe/issue-3080.stderr +++ b/tests/ui/unsafe/issue-3080.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `X::with` is unsafe and requires unsafe function or block --> $DIR/issue-3080.rs:7:5 | LL | X(()).with(); diff --git a/tests/ui/unsafe/issue-45087-unreachable-unsafe.stderr b/tests/ui/unsafe/issue-45087-unreachable-unsafe.stderr index cc1e73bb93288..d6cc5fd2e0831 100644 --- a/tests/ui/unsafe/issue-45087-unreachable-unsafe.stderr +++ b/tests/ui/unsafe/issue-45087-unreachable-unsafe.stderr @@ -2,7 +2,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/issue-45087-unreachable-unsafe.rs:5:5 | LL | *(1 as *mut u32) = 42; - | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer + | ^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior @@ -10,7 +10,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/issue-45087-unreachable-unsafe.rs:15:5 | LL | *a = 1; - | ^^^^^^ dereference of raw pointer + | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior @@ -18,7 +18,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/issue-45087-unreachable-unsafe.rs:27:5 | LL | *b = 1; - | ^^^^^^ dereference of raw pointer + | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior diff --git a/tests/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.stderr b/tests/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.stderr index 321698e763696..b23c002dc6532 100644 --- a/tests/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.stderr +++ b/tests/ui/unsafe/issue-45107-unnecessary-unsafe-in-closure.stderr @@ -16,9 +16,9 @@ LL | #[deny(unused_unsafe)] error: unnecessary `unsafe` block --> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:9:38 | -LL | unsafe { - | ------ because it's nested under this `unsafe` block -... +LL | unsafe { + | ------ because it's nested under this `unsafe` block +LL | v.set_len(24); LL | |w: &mut Vec| { unsafe { | ^^^^^^ unnecessary `unsafe` block diff --git a/tests/ui/unsafe/ranged_ints2_const.stderr b/tests/ui/unsafe/ranged_ints2_const.stderr index a0dc950e76dd1..f267dc6e23e48 100644 --- a/tests/ui/unsafe/ranged_ints2_const.stderr +++ b/tests/ui/unsafe/ranged_ints2_const.stderr @@ -1,3 +1,11 @@ +error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block + --> $DIR/ranged_ints2_const.rs:11:13 + | +LL | let y = &mut x.0; + | ^^^^^^^^ mutation of layout constrained field + | + = note: mutating layout constrained fields cannot statically be checked for valid values + error[E0658]: mutable references are not allowed in constant functions --> $DIR/ranged_ints2_const.rs:11:13 | @@ -25,14 +33,6 @@ LL | unsafe { let y = &mut x.0; } = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block - --> $DIR/ranged_ints2_const.rs:11:13 - | -LL | let y = &mut x.0; - | ^^^^^^^^ mutation of layout constrained field - | - = note: mutating layout constrained fields cannot statically be checked for valid values - error: aborting due to 4 previous errors Some errors have detailed explanations: E0133, E0658. diff --git a/tests/ui/unsafe/ranged_ints3_const.stderr b/tests/ui/unsafe/ranged_ints3_const.stderr index 215005571f6d7..75b36cdf94bf9 100644 --- a/tests/ui/unsafe/ranged_ints3_const.stderr +++ b/tests/ui/unsafe/ranged_ints3_const.stderr @@ -1,3 +1,11 @@ +error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block + --> $DIR/ranged_ints3_const.rs:12:13 + | +LL | let y = &x.0; + | ^^^^ borrow of layout constrained field with interior mutability + | + = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values + error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability --> $DIR/ranged_ints3_const.rs:12:13 | @@ -16,14 +24,6 @@ LL | let y = unsafe { &x.0 }; = note: see issue #80384 for more information = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable -error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - --> $DIR/ranged_ints3_const.rs:12:13 - | -LL | let y = &x.0; - | ^^^^ borrow of layout constrained field with interior mutability - | - = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - error: aborting due to 3 previous errors Some errors have detailed explanations: E0133, E0658. diff --git a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs index eceac115eddd2..658d14da829dc 100644 --- a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs +++ b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -7,7 +7,7 @@ static mut VOID: () = (); unsafe fn deny_level() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); @@ -22,7 +22,7 @@ unsafe fn deny_level() { #[deny(warnings)] unsafe fn warning_level() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); @@ -69,10 +69,10 @@ unsafe fn nested_allow_level() { fn main() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block #[allow(unsafe_op_in_unsafe_fn)] { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //~^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe function or block } } diff --git a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr index d61d87cd00146..ea0659b2e104d 100644 --- a/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr +++ b/tests/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5 | LL | unsf(); @@ -28,7 +28,7 @@ error: use of mutable static is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5 | LL | VOID = (); - | ^^^^^^^^^ use of mutable static + | ^^^^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -44,7 +44,7 @@ note: the lint level is defined here LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5 | LL | unsf(); @@ -75,7 +75,7 @@ error: use of mutable static is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 | LL | VOID = (); - | ^^^^^^^^^ use of mutable static + | ^^^^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -91,7 +91,7 @@ error: unnecessary `unsafe` block LL | unsafe { unsafe { unsf() } } | ^^^^^^ unnecessary `unsafe` block -error[E0133]: call to unsafe function is unsafe and requires unsafe block +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:71:5 | LL | unsf(); @@ -99,7 +99,7 @@ LL | unsf(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:75:9 | LL | unsf(); diff --git a/tests/ui/unsafe/union-assignop.stderr b/tests/ui/unsafe/union-assignop.stderr index e3a673ee1ff8e..6b2ebfb509961 100644 --- a/tests/ui/unsafe/union-assignop.stderr +++ b/tests/ui/unsafe/union-assignop.stderr @@ -2,7 +2,7 @@ error[E0133]: access to union field is unsafe and requires unsafe function or bl --> $DIR/union-assignop.rs:16:5 | LL | foo.a += 5; - | ^^^^^^^^^^ access to union field + | ^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior diff --git a/tests/ui/unsafe/union.rs b/tests/ui/unsafe/union.rs index 83ec1c3cd6cdf..15e143e6106b9 100644 --- a/tests/ui/unsafe/union.rs +++ b/tests/ui/unsafe/union.rs @@ -26,20 +26,19 @@ pub fn main() { match foo { Foo { bar: _a } => {}, //~ ERROR access to union field is unsafe } - match foo { //~ ERROR access to union field is unsafe + match foo { Foo { - pizza: Pizza { + pizza: Pizza { //~ ERROR access to union field is unsafe topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None } } => {}, } - // MIR unsafeck incorrectly thinks that no unsafe block is needed to do these match foo { - Foo { zst: () } => {}, + Foo { zst: () } => {}, //~ ERROR access to union field is unsafe } match foo { - Foo { pizza: Pizza { .. } } => {}, + Foo { pizza: Pizza { .. } } => {}, //~ ERROR access to union field is unsafe } // binding to wildcard is okay diff --git a/tests/ui/unsafe/union.stderr b/tests/ui/unsafe/union.stderr index fe8144624123e..151e64ae6130d 100644 --- a/tests/ui/unsafe/union.stderr +++ b/tests/ui/unsafe/union.stderr @@ -7,13 +7,32 @@ LL | Foo { bar: _a } => {}, = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union.rs:29:11 + --> $DIR/union.rs:31:20 | -LL | match foo { - | ^^^ access to union field +LL | pizza: Pizza { + | ____________________^ +LL | | topping: Some(PizzaTopping::Cheese) | Some(PizzaTopping::Pineapple) | None +LL | | } + | |_____________^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 2 previous errors +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:38:20 + | +LL | Foo { zst: () } => {}, + | ^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union.rs:41:22 + | +LL | Foo { pizza: Pizza { .. } } => {}, + | ^^^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/union_destructure.rs b/tests/ui/unsafe/union_destructure.rs index 85fd54c814574..d0cf8640eaa22 100644 --- a/tests/ui/unsafe/union_destructure.rs +++ b/tests/ui/unsafe/union_destructure.rs @@ -10,7 +10,7 @@ struct Pie { union Foo { #[allow(dead_code)] bar: i8, - baz: Pie + baz: Pie, } fn main() { @@ -30,20 +30,20 @@ fn main() { }; let u = Foo { bar: 9 }; - unsafe { //~ WARNING unnecessary `unsafe` block + unsafe { match u { - Foo { baz: Pie { .. } } => {}, + Foo { baz: Pie { .. } } => {} }; } let u = Foo { bar: 10 }; - unsafe { //~ WARNING unnecessary `unsafe` block + unsafe { match u { - Foo { baz: Pie { slices: _, size: _ } } => {}, + Foo { baz: Pie { slices: _, size: _ } } => {} }; } let u = Foo { bar: 11 }; match u { - Foo { baz: _ } => {}, + Foo { baz: _ } => {} }; } diff --git a/tests/ui/unsafe/union_destructure.stderr b/tests/ui/unsafe/union_destructure.stderr deleted file mode 100644 index 431521472e832..0000000000000 --- a/tests/ui/unsafe/union_destructure.stderr +++ /dev/null @@ -1,16 +0,0 @@ -warning: unnecessary `unsafe` block - --> $DIR/union_destructure.rs:33:5 - | -LL | unsafe { - | ^^^^^^ unnecessary `unsafe` block - | - = note: `#[warn(unused_unsafe)]` on by default - -warning: unnecessary `unsafe` block - --> $DIR/union_destructure.rs:39:5 - | -LL | unsafe { - | ^^^^^^ unnecessary `unsafe` block - -warning: 2 warnings emitted - diff --git a/tests/ui/unsafe/unsafe-const-fn.stderr b/tests/ui/unsafe/unsafe-const-fn.stderr index 370e1e673cf32..cdde7a7d94cc8 100644 --- a/tests/ui/unsafe/unsafe-const-fn.stderr +++ b/tests/ui/unsafe/unsafe-const-fn.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `dummy` is unsafe and requires unsafe function or block --> $DIR/unsafe-const-fn.rs:7:18 | LL | const VAL: u32 = dummy(0xFFFF); diff --git a/tests/ui/unsafe/unsafe-fn-assign-deref-ptr.stderr b/tests/ui/unsafe/unsafe-fn-assign-deref-ptr.stderr index b2a30f81e058a..077564d515c33 100644 --- a/tests/ui/unsafe/unsafe-fn-assign-deref-ptr.stderr +++ b/tests/ui/unsafe/unsafe-fn-assign-deref-ptr.stderr @@ -2,7 +2,7 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function --> $DIR/unsafe-fn-assign-deref-ptr.rs:2:5 | LL | *p = 0; - | ^^^^^^ dereference of raw pointer + | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior diff --git a/tests/ui/unsafe/unsafe-fn-called-from-safe.rs b/tests/ui/unsafe/unsafe-fn-called-from-safe.rs index 1836629958add..e985bab3f8473 100644 --- a/tests/ui/unsafe/unsafe-fn-called-from-safe.rs +++ b/tests/ui/unsafe/unsafe-fn-called-from-safe.rs @@ -2,5 +2,5 @@ unsafe fn f() { return; } fn main() { f(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `f` is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-called-from-safe.stderr b/tests/ui/unsafe/unsafe-fn-called-from-safe.stderr index 80d2c6ced24c8..cf29dc5cba87e 100644 --- a/tests/ui/unsafe/unsafe-fn-called-from-safe.stderr +++ b/tests/ui/unsafe/unsafe-fn-called-from-safe.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/unsafe-fn-called-from-safe.rs:4:5 | LL | f(); diff --git a/tests/ui/unsafe/unsafe-fn-used-as-value.rs b/tests/ui/unsafe/unsafe-fn-used-as-value.rs index a47189d265fcf..f3dff1ae09974 100644 --- a/tests/ui/unsafe/unsafe-fn-used-as-value.rs +++ b/tests/ui/unsafe/unsafe-fn-used-as-value.rs @@ -3,5 +3,5 @@ unsafe fn f() { return; } fn main() { let x = f; x(); - //~^ ERROR call to unsafe function is unsafe + //~^ ERROR call to unsafe function `f` is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-used-as-value.stderr b/tests/ui/unsafe/unsafe-fn-used-as-value.stderr index a7b73ec53429b..39a36916dda3f 100644 --- a/tests/ui/unsafe/unsafe-fn-used-as-value.stderr +++ b/tests/ui/unsafe/unsafe-fn-used-as-value.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/unsafe-fn-used-as-value.rs:5:5 | LL | x(); diff --git a/tests/ui/unsafe/unsafe-not-inherited.stderr b/tests/ui/unsafe/unsafe-not-inherited.stderr index 3bc5ca5c9d151..8b6991273129a 100644 --- a/tests/ui/unsafe/unsafe-not-inherited.stderr +++ b/tests/ui/unsafe/unsafe-not-inherited.stderr @@ -8,7 +8,7 @@ LL | unsafe {static BAR: u64 = FOO;} | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unsafe_call` is unsafe and requires unsafe function or block --> $DIR/unsafe-not-inherited.rs:18:13 | LL | unsafe { diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed b/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed index f776cffed5932..20f4fe847daca 100644 --- a/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.fixed @@ -10,10 +10,10 @@ unsafe fn unsf() {} pub unsafe fn foo() { unsafe { //~^ NOTE an unsafe function restricts its caller, but its body is safe by default - unsf(); //~ ERROR call to unsafe function is unsafe + unsf(); //~ ERROR call to unsafe function `unsf` is unsafe //~^ NOTE //~| NOTE - unsf(); //~ ERROR call to unsafe function is unsafe + unsf(); //~ ERROR call to unsafe function `unsf` is unsafe //~^ NOTE //~| NOTE }} @@ -40,10 +40,10 @@ pub unsafe fn baz() -> i32 { unsafe { }} macro_rules! unsafe_macro { () => (unsf()) } -//~^ ERROR call to unsafe function is unsafe +//~^ ERROR call to unsafe function `unsf` is unsafe //~| NOTE //~| NOTE -//~| ERROR call to unsafe function is unsafe +//~| ERROR call to unsafe function `unsf` is unsafe //~| NOTE //~| NOTE diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs b/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs index 13ab51ef4325a..13a446d2d2480 100644 --- a/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.rs @@ -10,10 +10,10 @@ unsafe fn unsf() {} pub unsafe fn foo() { //~^ NOTE an unsafe function restricts its caller, but its body is safe by default - unsf(); //~ ERROR call to unsafe function is unsafe + unsf(); //~ ERROR call to unsafe function `unsf` is unsafe //~^ NOTE //~| NOTE - unsf(); //~ ERROR call to unsafe function is unsafe + unsf(); //~ ERROR call to unsafe function `unsf` is unsafe //~^ NOTE //~| NOTE } @@ -40,10 +40,10 @@ pub unsafe fn baz() -> i32 { } macro_rules! unsafe_macro { () => (unsf()) } -//~^ ERROR call to unsafe function is unsafe +//~^ ERROR call to unsafe function `unsf` is unsafe //~| NOTE //~| NOTE -//~| ERROR call to unsafe function is unsafe +//~| ERROR call to unsafe function `unsf` is unsafe //~| NOTE //~| NOTE diff --git a/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr b/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr index 9ae238d5a7973..84b58bc028858 100644 --- a/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr +++ b/tests/ui/unsafe/wrapping-unsafe-block-sugg.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/wrapping-unsafe-block-sugg.rs:13:5 | LL | unsf(); @@ -16,7 +16,7 @@ note: the lint level is defined here LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/wrapping-unsafe-block-sugg.rs:16:5 | LL | unsf(); @@ -66,7 +66,7 @@ LL | y + BAZ | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/wrapping-unsafe-block-sugg.rs:42:36 | LL | macro_rules! unsafe_macro { () => (unsf()) } @@ -83,7 +83,7 @@ LL | pub unsafe fn unsafe_in_macro() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `unsafe_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/wrapping-unsafe-block-sugg.rs:42:36 | LL | macro_rules! unsafe_macro { () => (unsf()) }