From 6161ac182486f57976e4233aa55af9346cf8a1bf Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Nov 2025 11:26:37 +0100 Subject: [PATCH] Still lint raw pointer to union field if MSRV < 1.92 --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/lib.rs | 2 +- .../src/multiple_unsafe_ops_per_block.rs | 96 ++++++++----- clippy_utils/src/msrvs.rs | 1 + tests/ui/multiple_unsafe_ops_per_block.rs | 10 ++ tests/ui/multiple_unsafe_ops_per_block.stderr | 129 ++++++++++-------- 7 files changed, 154 insertions(+), 86 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 6569bdabf115..d7bad33e62b2 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -892,6 +892,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`mem_replace_option_with_some`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some) * [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default) * [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn) +* [`multiple_unsafe_ops_per_block`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_unsafe_ops_per_block) * [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow) * [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics) * [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 2a042e6c3d85..e04d0a3e4f23 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -781,6 +781,7 @@ define_Conf! { mem_replace_option_with_some, mem_replace_with_default, missing_const_for_fn, + multiple_unsafe_ops_per_block, needless_borrow, non_std_lazy_statics, option_as_ref_deref, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 230d83dacc95..4068b7ab6b89 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -765,7 +765,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |_| Box::new(semicolon_block::SemicolonBlock::new(conf))), Box::new(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse)), Box::new(|_| Box::new(size_of_ref::SizeOfRef)), - Box::new(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock)), + Box::new(move |_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock::new(conf))), Box::new(move |_| Box::new(extra_unused_type_parameters::ExtraUnusedTypeParameters::new(conf))), Box::new(|_| Box::new(no_mangle_with_rust_abi::NoMangleWithRustAbi)), Box::new(|_| Box::new(collection_is_never_read::CollectionIsNeverRead)), diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 80cf081992cc..4ced6afff08f 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -1,5 +1,7 @@ -use clippy_utils::desugar_await; +use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::Msrv; +use clippy_utils::{desugar_await, msrvs}; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; use rustc_ast::{BorrowKind, Mutability}; @@ -7,8 +9,8 @@ use rustc_hir as hir; use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, TyCtxt, TypeckResults}; -use rustc_session::declare_lint_pass; +use rustc_middle::ty::{self, TypeckResults}; +use rustc_session::impl_lint_pass; use rustc_span::{DesugaringKind, Span}; declare_clippy_lint! { @@ -55,19 +57,23 @@ declare_clippy_lint! { /// unsafe { char::from_u32_unchecked(int_value) } /// } /// ``` - /// - /// ### Note - /// - /// Taking a raw pointer to a union field is always safe and will - /// not be considered unsafe by this lint, even when linting code written - /// with a specified Rust version of 1.91 or earlier (which required - /// using an `unsafe` block). #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, "more than one unsafe operation per `unsafe` block" } -declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]); + +pub struct MultipleUnsafeOpsPerBlock { + msrv: Msrv, +} + +impl_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]); + +impl MultipleUnsafeOpsPerBlock { + pub fn new(conf: &Conf) -> Self { + Self { msrv: conf.msrv } + } +} impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { @@ -77,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { { return; } - let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block); + let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block, self.msrv); if unsafe_ops.len() > 1 { span_lint_and_then( cx, @@ -97,28 +103,52 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { } } -struct UnsafeExprCollector<'tcx> { - tcx: TyCtxt<'tcx>, +#[derive(Clone, Copy)] +enum UnderRawPtr { + /// The expression is not located under a raw pointer + No, + /// The expression is located under a raw pointer, MSRV yet unknown + Yes, + /// The expression is located under a raw pointer and MSRV has been determined. + /// `true` means that taking a raw pointer to a union field is a safe operation. + WithSafeMsrv(bool), +} + +struct UnsafeExprCollector<'cx, 'tcx> { + cx: &'cx LateContext<'tcx>, typeck_results: &'tcx TypeckResults<'tcx>, + msrv: Msrv, unsafe_ops: Vec<(&'static str, Span)>, + under_raw_ptr: UnderRawPtr, } -impl<'tcx> UnsafeExprCollector<'tcx> { - fn collect_unsafe_exprs(cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) -> Vec<(&'static str, Span)> { +impl<'cx, 'tcx> UnsafeExprCollector<'cx, 'tcx> { + fn collect_unsafe_exprs( + cx: &'cx LateContext<'tcx>, + block: &'tcx hir::Block<'tcx>, + msrv: Msrv, + ) -> Vec<(&'static str, Span)> { let mut collector = Self { - tcx: cx.tcx, + cx, typeck_results: cx.typeck_results(), + msrv, unsafe_ops: vec![], + under_raw_ptr: UnderRawPtr::No, }; collector.visit_block(block); collector.unsafe_ops } } -impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { +impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { + // `self.under_raw_ptr` is preventively reset, while the current value is + // preserved in `under_raw_ptr`. + let under_raw_ptr = self.under_raw_ptr; + self.under_raw_ptr = UnderRawPtr::No; + match expr.kind { // The `await` itself will desugar to two unsafe calls, but we should ignore those. // Instead, check the expression that is `await`ed @@ -128,17 +158,21 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { ExprKind::InlineAsm(_) => self.unsafe_ops.push(("inline assembly used here", expr.span)), - ExprKind::AddrOf(BorrowKind::Raw, _, mut inner) => { - while let ExprKind::Field(prefix, _) = inner.kind - && self.typeck_results.expr_adjustments(prefix).is_empty() - { - inner = prefix; - } - return self.visit_expr(inner); + ExprKind::AddrOf(BorrowKind::Raw, _, _) => { + self.under_raw_ptr = UnderRawPtr::Yes; }, - ExprKind::Field(e, _) => { - if self.typeck_results.expr_ty(e).is_union() { + ExprKind::Field(e, _) if self.typeck_results.expr_adjustments(e).is_empty() => { + // Restore `self.under_raw_pointer` and determine safety of taking a raw pointer to + // a union field if this is not known already. + self.under_raw_ptr = if matches!(under_raw_ptr, UnderRawPtr::Yes) { + UnderRawPtr::WithSafeMsrv(self.msrv.meets(self.cx, msrvs::SAFE_RAW_PTR_TO_UNION_FIELD)) + } else { + under_raw_ptr + }; + if self.typeck_results.expr_ty(e).is_union() + && matches!(self.under_raw_ptr, UnderRawPtr::No | UnderRawPtr::WithSafeMsrv(false)) + { self.unsafe_ops.push(("union field access occurs here", expr.span)); } }, @@ -167,7 +201,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { ExprKind::Call(path_expr, _) => { let opt_sig = match *self.typeck_results.expr_ty_adjusted(path_expr).kind() { - ty::FnDef(id, _) => Some(self.tcx.fn_sig(id).skip_binder()), + ty::FnDef(id, _) => Some(self.cx.tcx.fn_sig(id).skip_binder()), ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(hdr)), _ => None, }; @@ -180,7 +214,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { let opt_sig = self .typeck_results .type_dependent_def_id(expr.hir_id) - .map(|def_id| self.tcx.fn_sig(def_id)); + .map(|def_id| self.cx.tcx.fn_sig(def_id)); if opt_sig.is_some_and(|sig| sig.skip_binder().safety().is_unsafe()) { self.unsafe_ops.push(("unsafe method call occurs here", expr.span)); } @@ -217,12 +251,12 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { fn visit_body(&mut self, body: &hir::Body<'tcx>) { let saved_typeck_results = self.typeck_results; - self.typeck_results = self.tcx.typeck_body(body.id()); + self.typeck_results = self.cx.tcx.typeck_body(body.id()); walk_body(self, body); self.typeck_results = saved_typeck_results; } fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.tcx + self.cx.tcx } } diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 86d17a8231d5..d1e39375c1e7 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -23,6 +23,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,92,0 { SAFE_RAW_PTR_TO_UNION_FIELD } 1,88,0 { LET_CHAINS } 1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT, UNSIGNED_IS_MULTIPLE_OF, INTEGER_SIGN_CAST } 1,85,0 { UINT_FLOAT_MIDPOINT, CONST_SIZE_OF_VAL } diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index c1512ba3e269..8558899400bb 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,5 +1,6 @@ //@needs-asm-support //@aux-build:proc_macros.rs +#![feature(stmt_expr_attributes)] #![expect( dropping_copy_types, clippy::unnecessary_operation, @@ -227,11 +228,20 @@ fn issue16076() { let u = U { i: 0 }; // Taking a raw pointer to a place is safe since Rust 1.92 + #[clippy::msrv = "1.92"] unsafe { _ = &raw const u.i; _ = &raw const u.i; } + // However it was not the case before Rust 1.92 + #[clippy::msrv = "1.91"] + unsafe { + //~^ multiple_unsafe_ops_per_block + _ = &raw const u.i; + _ = &raw const u.i; + } + // Taking a reference to a union field is not safe unsafe { //~^ multiple_unsafe_ops_per_block diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index 63f7742b734b..63b8eb8d4e00 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -1,5 +1,5 @@ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:38:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:39:5 | LL | / unsafe { LL | | @@ -9,12 +9,12 @@ LL | | } | |_____^ | note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:41:9 | LL | STATIC += 1; | ^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:41:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:42:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | not_very_safe(); = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]` error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:48:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:49:5 | LL | / unsafe { LL | | @@ -32,18 +32,18 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:51:14 | LL | drop(u.u); | ^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:51:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:52:9 | LL | *raw_ptr(); | ^^^^^^^^^^ error: this `unsafe` block contains 3 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:56:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:57:5 | LL | / unsafe { LL | | @@ -54,23 +54,23 @@ LL | | } | |_____^ | note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:58:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 | LL | asm!("nop"); | ^^^^^^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:61:9 | LL | STATIC = 0; | ^^^^^^^^^^ error: this `unsafe` block contains 6 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:66:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:67:5 | LL | / unsafe { LL | | @@ -82,38 +82,38 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14 | LL | drop(u.u); | ^^^ note: access of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:70:14 | LL | drop(STATIC); | ^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9 | LL | *raw_ptr(); | ^^^^^^^^^^ note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:74:9 | LL | asm!("nop"); | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:109:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:110:5 | LL | / unsafe { LL | | @@ -123,35 +123,35 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:111:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:112:9 | LL | f(); | ^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:112:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:113:9 | LL | f(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:118:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:119:9 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 + --> tests/ui/multiple_unsafe_ops_per_block.rs:119:18 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:118:43 + --> tests/ui/multiple_unsafe_ops_per_block.rs:119:43 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:139:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:140:9 | LL | / unsafe { LL | | @@ -161,18 +161,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:141:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:142:13 | LL | x(); | ^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:142:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:143:13 | LL | x(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:151:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:152:13 | LL | / unsafe { LL | | @@ -182,18 +182,18 @@ LL | | } | |_____________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:153:17 + --> tests/ui/multiple_unsafe_ops_per_block.rs:154:17 | LL | T::X(); | ^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:154:17 + --> tests/ui/multiple_unsafe_ops_per_block.rs:155:17 | LL | T::X(); | ^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:162:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:163:9 | LL | / unsafe { LL | | @@ -203,18 +203,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:164:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:165:13 | LL | x.0(); | ^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:165:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:166:13 | LL | x.0(); | ^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:192:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:193:5 | LL | / unsafe { LL | | @@ -225,18 +225,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:196:9 | LL | STATIC += 1; | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:207:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:208:5 | LL | / unsafe { LL | | @@ -246,18 +246,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:209:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:210:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:210:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:211:9 | LL | foo_unchecked().await; | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:214:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:215:5 | LL | / unsafe { LL | | @@ -266,18 +266,39 @@ LL | | } | |_____^ | note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:217:9 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:216:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:217:14 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:236:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:239:5 + | +LL | / unsafe { +LL | | +LL | | _ = &raw const u.i; +LL | | _ = &raw const u.i; +LL | | } + | |_____^ + | +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:241:24 + | +LL | _ = &raw const u.i; + | ^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:242:24 + | +LL | _ = &raw const u.i; + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:246:5 | LL | / unsafe { LL | | @@ -287,18 +308,18 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:238:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:248:14 | LL | _ = &u.i; | ^^^ note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:239:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:249:14 | LL | _ = &u.i; | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:244:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:254:5 | LL | / unsafe { LL | | @@ -308,18 +329,18 @@ LL | | } | |_____^ | note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:246:24 + --> tests/ui/multiple_unsafe_ops_per_block.rs:256:24 | LL | _ = &raw const (*&raw const u).i; | ^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:247:24 + --> tests/ui/multiple_unsafe_ops_per_block.rs:257:24 | LL | _ = &raw const (*&raw const u).i; | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:294:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:304:5 | LL | / unsafe { LL | | @@ -329,18 +350,18 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:296:24 + --> tests/ui/multiple_unsafe_ops_per_block.rs:306:24 | LL | _ = &raw const w.s.i; | ^^^ note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:297:24 + --> tests/ui/multiple_unsafe_ops_per_block.rs:307:24 | LL | _ = &raw const w.s.i; | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:309:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:319:5 | LL | / unsafe { LL | | @@ -349,15 +370,15 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:311:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:321:9 | LL | apply(|| f(0)); | ^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:311:18 + --> tests/ui/multiple_unsafe_ops_per_block.rs:321:18 | LL | apply(|| f(0)); | ^^^^ -error: aborting due to 16 previous errors +error: aborting due to 17 previous errors