From 6b0ea30679d29c1eb94fe269ddec6c4a3a11260a Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 26 Jul 2026 12:42:42 +0200 Subject: [PATCH] Allow UnsafeCell content access without get in invalid ref casting lint --- compiler/rustc_lint/src/dangling.rs | 2 +- compiler/rustc_lint/src/lints.rs | 8 -- compiler/rustc_lint/src/ptr_nulls.rs | 2 +- compiler/rustc_lint/src/reference_casting.rs | 43 ++++----- compiler/rustc_lint/src/utils.rs | 12 +-- library/core/src/cell.rs | 1 - tests/ui/lint/reference_casting.rs | 55 +++++++---- tests/ui/lint/reference_casting.stderr | 98 ++++++++------------ 8 files changed, 100 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index cb5c2adf19aa8..88161e99b1759 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -179,7 +179,7 @@ fn lint_addr_of_local<'a>( expr: &'a Expr<'a>, ) { // peel casts as they do not interest us here, we want the inner expression. - let (inner, _) = super::utils::peel_casts(cx, expr); + let inner = super::utils::peel_casts(cx, expr); if let ExprKind::AddrOf(_, _, inner_of) = inner.kind && let ExprKind::Path(ref qpath) = inner_of.peel_blocks().kind diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index b084b412417c5..f9b006cbb2632 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -993,10 +993,6 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { BorrowAsMut { #[label("casting happened here")] orig_cast: Option, - #[note( - "even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`" - )] - ty_has_interior_mutability: bool, }, #[diag("assigning to `&T` is undefined behavior, consider using an `UnsafeCell`")] #[note( @@ -1005,10 +1001,6 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { AssignToRef { #[label("casting happened here")] orig_cast: Option, - #[note( - "even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`" - )] - ty_has_interior_mutability: bool, }, #[diag( "casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused" diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 34c569232fc0d..e8783db8524a8 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -112,7 +112,7 @@ fn useless_check<'a, 'tcx: 'a>( /// Checks if the given expression is a null pointer (modulo casting) fn is_null_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { - let (expr, _) = peel_casts(cx, expr); + let expr = peel_casts(cx, expr); if let ExprKind::Call(path, []) = expr.kind && let ExprKind::Path(ref qpath) = path.kind diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 6052a16a7f117..becc5f03362c2 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -52,22 +52,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { }; if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) - && let Some(ty_has_interior_mutability) = - is_cast_from_ref_to_mut_ptr(cx, init, &mut peel_casts) + && is_invalid_cast_from_ref_to_mut_ptr(cx, init, &mut peel_casts) { cx.emit_span_lint( INVALID_REFERENCE_CASTING, expr.span, if pat == PatternKind::Assign { - InvalidReferenceCastingDiag::AssignToRef { - orig_cast, - ty_has_interior_mutability, - } + InvalidReferenceCastingDiag::AssignToRef { orig_cast } } else { - InvalidReferenceCastingDiag::BorrowAsMut { - orig_cast, - ty_has_interior_mutability, - } + InvalidReferenceCastingDiag::BorrowAsMut { orig_cast } }, ); } @@ -146,41 +139,43 @@ fn borrow_or_assign<'tcx>( deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e)) } -fn is_cast_from_ref_to_mut_ptr<'tcx>( +fn is_invalid_cast_from_ref_to_mut_ptr<'tcx>( cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>, - mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool), -) -> Option { + mut peel_casts: impl FnMut() -> &'tcx Expr<'tcx>, +) -> bool { let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); // Bail out early if the end type is **not** a mutable pointer. if !matches!(end_ty.kind(), ty::RawPtr(_, Mutability::Mut)) { - return None; + return false; } - let (e, need_check_freeze) = peel_casts(); - + let e = peel_casts(); let start_ty = cx.typeck_results().node_type(e.hir_id); + if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() { - // If an UnsafeCell method is involved, we need to additionally check the - // inner type for the presence of the Freeze trait (ie does NOT contain - // an UnsafeCell), since in that case we would incorrectly lint on valid casts. + // We need to additionally check the inner type for the presence of the Freeze trait + // (ie does NOT contain an UnsafeCell), since in that case we would incorrectly lint + // on valid casts (see https://github.com/rust-lang/unsafe-code-guidelines/issues/281). // // Except on the presence of non concrete skeleton types (ie generics) // since there is no way to make it safe for arbitrary types. + // + // However this does mean we miss out on some cases where the user doesn't go + // through an UnsafeCell but there's an UnsafeCell somewhere else in the type. let inner_ty_has_interior_mutability = !inner_ty.is_freeze(cx.tcx, cx.typing_env()) && inner_ty.has_concrete_skeleton(); - (!need_check_freeze || !inner_ty_has_interior_mutability) - .then_some(inner_ty_has_interior_mutability) + !inner_ty_has_interior_mutability } else { - None + false } } fn is_cast_to_bigger_memory_layout<'tcx>( cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>, - mut peel_casts: impl FnMut() -> (&'tcx Expr<'tcx>, bool), + mut peel_casts: impl FnMut() -> &'tcx Expr<'tcx>, ) -> Option<(TyAndLayout<'tcx>, TyAndLayout<'tcx>, Expr<'tcx>)> { let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); @@ -188,7 +183,7 @@ fn is_cast_to_bigger_memory_layout<'tcx>( return None; }; - let (e, _) = peel_casts(); + let e = peel_casts(); let start_ty = cx.typeck_results().node_type(e.hir_id); let ty::Ref(_, inner_start_ty, _) = start_ty.kind() else { diff --git a/compiler/rustc_lint/src/utils.rs b/compiler/rustc_lint/src/utils.rs index a7295d9c5326c..5854e89d801de 100644 --- a/compiler/rustc_lint/src/utils.rs +++ b/compiler/rustc_lint/src/utils.rs @@ -6,14 +6,11 @@ use crate::LateContext; /// Given an expression, peel all of casts (` as ...`, `.cast{,_mut,_const}()`, /// `ptr::from_ref()`, ...) and init expressions. /// -/// Returns the innermost expression and a boolean representing if one of the casts was -/// `UnsafeCell::raw_get()` +/// Returns the innermost expression. pub(crate) fn peel_casts<'tcx>( cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>, -) -> (&'tcx Expr<'tcx>, bool) { - let mut gone_trough_unsafe_cell_raw_get = false; - +) -> &'tcx Expr<'tcx> { loop { e = e.peel_blocks(); // as ... @@ -37,9 +34,6 @@ pub(crate) fn peel_casts<'tcx>( Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute) ) { - if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) { - gone_trough_unsafe_cell_raw_get = true; - } arg } else { let init = cx.expr_or_init(e); @@ -51,5 +45,5 @@ pub(crate) fn peel_casts<'tcx>( }; } - (e, gone_trough_unsafe_cell_raw_get) + e } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 1145a085931f4..0e18d2bcc8469 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2236,7 +2236,6 @@ impl fmt::Display for RefMut<'_, T> { /// /// # Safety /// /// The caller must not call `get_mut_unchecked` again (on any alias of `ptr`) for the duration /// /// of the lifetime of the returned reference. -/// # #[allow(invalid_reference_casting)] // FIXME should the lint really fire here? /// unsafe fn get_mut_unchecked(ptr: &UnsafeCell) -> &mut T { /// let t = ptr as *const UnsafeCell as *mut T; /// unsafe { &mut *t } diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 87fa42f94775e..4612d266ce2aa 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -37,8 +37,8 @@ unsafe fn ref_to_mut() { let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *std::cell::UnsafeCell::raw_get( - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - num as *const i32 as *const std::cell::UnsafeCell + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + num as *const i32 as *const std::cell::UnsafeCell, ); let deferred = num as *const i32 as *mut i32; @@ -62,10 +62,6 @@ unsafe fn ref_to_mut() { let _num = &mut *num; //~^ ERROR casting `&T` to `&mut T` is undefined behavior - let cell = &std::cell::UnsafeCell::new(0); - let _num = &mut *(cell as *const _ as *mut i32); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - unsafe fn generic_ref_cast_mut(this: &T) -> &mut T { &mut *((this as *const _) as *mut _) //~^ ERROR casting `&T` to `&mut T` is undefined behavior @@ -104,12 +100,10 @@ unsafe fn assign_to_ref() { *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; //~^ ERROR assigning to `&T` is undefined behavior std::ptr::write( - //~^ ERROR assigning to `&T` is undefined behavior + //~^ ERROR assigning to `&T` is undefined behavior std::mem::transmute::<*const i32, *mut i32>(num), -1i32, ); - *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; - //~^ ERROR assigning to `&T` is undefined behavior let value = num as *const i32 as *mut i32; *value = 1; @@ -207,14 +201,16 @@ unsafe fn bigger_layout() { } { - let mut l: [u8; 2] = [0,1]; + let mut l: [u8; 2] = [0, 1]; let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; - let w: *mut [u16] = unsafe {&mut *w}; + let w: *mut [u16] = unsafe { &mut *w }; //~^ ERROR casting references to a bigger memory layout } { - fn foo() -> [i32; 1] { todo!() } + fn foo() -> [i32; 1] { + todo!() + } let num = foo(); let _num = &*(&num as *const i32 as *const i64); @@ -224,7 +220,9 @@ unsafe fn bigger_layout() { } { - fn bar(_a: &[i32; 2]) -> &[i32; 1] { todo!() } + fn bar(_a: &[i32; 2]) -> &[i32; 1] { + todo!() + } let num = bar(&[0, 0]); let _num = &*(num as *const i32 as *const i64); @@ -232,7 +230,9 @@ unsafe fn bigger_layout() { } { - fn foi() -> T { todo!() } + fn foi() -> T { + todo!() + } let num = foi::(); let _num = &*(&num as *const i32 as *const i64); @@ -286,24 +286,41 @@ unsafe fn no_warn() { let value: *const i32 = &mut value; *(value as *const i16 as *mut i16) = 42; *RAW_PTR = 42; // RAW_PTR is defined outside the function body, - // make sure we don't ICE on it when trying to - // determine if we should lint on it or not. + // make sure we don't ICE on it when trying to + // determine if we should lint on it or not. + *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; + let cell = &std::cell::UnsafeCell::new(0); let _num = &mut *(cell.get() as *mut i32); + let _num = &mut *(cell as *const _ as *mut i32); - fn safe_as_mut(x: &std::cell::UnsafeCell) -> &mut T { + unsafe fn get_mut_unchecked(x: &std::cell::UnsafeCell) -> &mut T { unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } } - fn cell_as_mut(x: &std::cell::Cell) -> &mut i32 { + unsafe fn get_mut_unchecked2(ptr: &std::cell::UnsafeCell) -> &mut T { + let t = ptr as *const std::cell::UnsafeCell as *mut T; + unsafe { &mut *t } + } + + unsafe fn cell_as_mut(x: &std::cell::Cell) -> &mut i32 { unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } } + unsafe fn cell_as_mut2(x: &std::cell::Cell) -> &mut i32 { + unsafe { &mut *(x as *const std::cell::Cell as *mut i32) } + } + #[repr(transparent)] struct DoesContainUnsafeCell(std::cell::UnsafeCell); - fn safe_as_mut2(x: &DoesContainUnsafeCell) -> &mut DoesContainUnsafeCell { + + unsafe fn get_mut_unchecked3(x: &DoesContainUnsafeCell) -> &mut DoesContainUnsafeCell { unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } } + + unsafe fn get_mut_unchecked4(x: &DoesContainUnsafeCell) -> &mut DoesContainUnsafeCell { + unsafe { &mut *(x as *const DoesContainUnsafeCell as *mut _) } + } } fn main() {} diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 4205d406b5158..bda5d238daca8 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -93,7 +93,7 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is LL | let _num = &mut *std::cell::UnsafeCell::raw_get( | ________________^ LL | | -LL | | num as *const i32 as *const std::cell::UnsafeCell +LL | | num as *const i32 as *const std::cell::UnsafeCell, LL | | ); | |_____^ | @@ -158,16 +158,7 @@ LL | let _num = &mut *num; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:66:16 - | -LL | let _num = &mut *(cell as *const _ as *mut i32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, visit - = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` - -error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:70:9 + --> $DIR/reference_casting.rs:66:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,7 +166,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:75:18 + --> $DIR/reference_casting.rs:71:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +174,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:80:18 + --> $DIR/reference_casting.rs:76:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +182,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:90:5 + --> $DIR/reference_casting.rs:86:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +190,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:92:5 + --> $DIR/reference_casting.rs:88:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +198,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:94:5 + --> $DIR/reference_casting.rs:90:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -215,7 +206,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:96:5 + --> $DIR/reference_casting.rs:92:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +214,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:98:5 + --> $DIR/reference_casting.rs:94:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +222,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:100:5 + --> $DIR/reference_casting.rs:96:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -239,7 +230,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:102:5 + --> $DIR/reference_casting.rs:98:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +238,7 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:104:5 + --> $DIR/reference_casting.rs:100:5 | LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +246,7 @@ LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:106:5 + --> $DIR/reference_casting.rs:102:5 | LL | / std::ptr::write( LL | | @@ -267,16 +258,7 @@ LL | | ); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:111:5 - | -LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, visit - = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` - -error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:115:5 + --> $DIR/reference_casting.rs:109:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -286,7 +268,7 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:119:5 + --> $DIR/reference_casting.rs:113:5 | LL | let value = value as *mut i32; | ----------------- casting happened here @@ -296,7 +278,7 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:122:5 + --> $DIR/reference_casting.rs:116:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -306,7 +288,7 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:125:5 + --> $DIR/reference_casting.rs:119:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -317,7 +299,7 @@ LL | *value_rebind = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:127:5 + --> $DIR/reference_casting.rs:121:5 | LL | *(num as *const i32).cast::().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +307,7 @@ LL | *(num as *const i32).cast::().cast_mut() = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:129:5 + --> $DIR/reference_casting.rs:123:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -333,7 +315,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:131:5 + --> $DIR/reference_casting.rs:125:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -344,7 +326,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:133:5 + --> $DIR/reference_casting.rs:127:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -355,7 +337,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:135:5 + --> $DIR/reference_casting.rs:129:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happened here @@ -366,7 +348,7 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:139:9 + --> $DIR/reference_casting.rs:133:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -374,7 +356,7 @@ LL | *(this as *const _ as *mut _) = a; = note: for more information, visit error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:161:20 + --> $DIR/reference_casting.rs:155:20 | LL | let num = &mut 3i32; | ---- backing allocation comes from here @@ -385,7 +367,7 @@ LL | let _num = &*(num as *const i32 as *const i64); = note: casting from `i32` (4 bytes) to `i64` (8 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:163:20 + --> $DIR/reference_casting.rs:157:20 | LL | let num = &mut 3i32; | ---- backing allocation comes from here @@ -396,7 +378,7 @@ LL | let _num = &mut *(num as *mut i32 as *mut i64); = note: casting from `i32` (4 bytes) to `i64` (8 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:165:20 + --> $DIR/reference_casting.rs:159:20 | LL | let num = &mut 3i32; | ---- backing allocation comes from here @@ -407,7 +389,7 @@ LL | let _num = &mut *(num as *mut i32 as *mut I64); = note: casting from `i32` (4 bytes) to `I64` (16 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:167:9 + --> $DIR/reference_casting.rs:161:9 | LL | let num = &mut 3i32; | ---- backing allocation comes from here @@ -418,7 +400,7 @@ LL | std::ptr::write(num as *mut i32 as *mut i64, 2); = note: casting from `i32` (4 bytes) to `i64` (8 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:176:20 + --> $DIR/reference_casting.rs:170:20 | LL | let num = &mut [0i32; 3]; | --------- backing allocation comes from here @@ -429,7 +411,7 @@ LL | let _num = &mut *(num as *mut _ as *mut [i64; 2]); = note: casting from `[i32; 3]` (12 bytes) to `[i64; 2]` (16 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:178:9 + --> $DIR/reference_casting.rs:172:9 | LL | let num = &mut [0i32; 3]; | --------- backing allocation comes from here @@ -440,7 +422,7 @@ LL | std::ptr::write_unaligned(num as *mut _ as *mut [i32; 4], [0, 0, 1, = note: casting from `[i32; 3]` (12 bytes) to `[i32; 4]` (16 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:188:20 + --> $DIR/reference_casting.rs:182:20 | LL | let num = &mut [0i32; 3] as &mut [i32]; | --------- backing allocation comes from here @@ -451,7 +433,7 @@ LL | let _num = &mut *(num as *mut _ as *mut i128); = note: casting from `[i32; 3]` (12 bytes) to `i128` (16 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:190:20 + --> $DIR/reference_casting.rs:184:20 | LL | let num = &mut [0i32; 3] as &mut [i32]; | --------- backing allocation comes from here @@ -462,7 +444,7 @@ LL | let _num = &mut *(num as *mut _ as *mut [i64; 4]); = note: casting from `[i32; 3]` (12 bytes) to `[i64; 4]` (32 bytes) error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:200:20 + --> $DIR/reference_casting.rs:194:20 | LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -470,7 +452,7 @@ LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); = note: for more information, visit error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:200:20 + --> $DIR/reference_casting.rs:194:20 | LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); | ^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -480,7 +462,7 @@ LL | let _num = &mut *(&mat3 as *const _ as *mut [[i64; 3]; 3]); = note: casting from `Mat3` (36 bytes) to `[[i64; 3]; 3]` (72 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:203:20 + --> $DIR/reference_casting.rs:197:20 | LL | let _num = &*(&mat3 as *const _ as *mut [[i64; 3]; 3]); | ^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,20 +472,20 @@ LL | let _num = &*(&mat3 as *const _ as *mut [[i64; 3]; 3]); = note: casting from `Mat3` (36 bytes) to `[[i64; 3]; 3]` (72 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:212:37 + --> $DIR/reference_casting.rs:206:38 | LL | let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; | -------------------------------- | | | | | backing allocation comes from here | casting happened here -LL | let w: *mut [u16] = unsafe {&mut *w}; - | ^^^^^^^ +LL | let w: *mut [u16] = unsafe { &mut *w }; + | ^^^^^^^ | = note: casting from `[u8; 2]` (2 bytes) to `[u16; 2]` (4 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:220:20 + --> $DIR/reference_casting.rs:216:20 | LL | let _num = &*(&num as *const i32 as *const i64); | ^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -513,7 +495,7 @@ LL | let _num = &*(&num as *const i32 as *const i64); = note: casting from `[i32; 1]` (4 bytes) to `i64` (8 bytes) error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - --> $DIR/reference_casting.rs:222:20 + --> $DIR/reference_casting.rs:218:20 | LL | let _num = &*(&foo() as *const i32 as *const i64); | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -532,5 +514,5 @@ LL | let _num = &*(&num as *const i32 as *const i64); | = note: casting from `i32` (4 bytes) to `i64` (8 bytes) -error: aborting due to 57 previous errors +error: aborting due to 55 previous errors