diff --git a/gcc/testsuite/rust/compile/issue-3033.rs b/gcc/testsuite/rust/compile/issue-3033.rs new file mode 100644 index 00000000000..9085b7616c0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3033.rs @@ -0,0 +1,144 @@ +#![feature(negative_impls)] + +#[lang = "copy"] +trait Copy {} + +mod copy_impls { + use super::Copy; + + macro_rules! impl_copy { + ($($t:ty)*) => { + $( + impl Copy for $t {} + )* + } + } + + impl_copy! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[repr(transparent)] +#[repr(no_niche)] // rust-lang/rust#68303. +pub struct UnsafeCell { + value: T, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +impl UnsafeCell { + /// Gets a mutable pointer to the wrapped value. + /// + /// This can be cast to a pointer of any kind. + /// Ensure that the access is unique (no active references, mutable or not) + /// when casting to `&mut T`, and ensure that there are no mutations + /// or mutable aliases going on when casting to `&T` + /// + /// # Examples + /// + /// + /// use std::cell::UnsafeCell; + /// + /// let uc = UnsafeCell::new(5); + /// + /// let five = uc.get(); + /// + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] + pub const fn get(&self) -> *mut T { + // We can just cast the pointer from `UnsafeCell` to `T` because of + // #[repr(transparent)]. This exploits libstd's special status, there is + // no guarantee for user code that this will work in future versions of the compiler! + self as *const UnsafeCell as *const T as *mut T + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[repr(transparent)] +pub struct Cell { + value: UnsafeCell, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +impl Cell { + /// Returns a copy of the contained value. + /// + /// # Examples + /// + /// + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let five = c.get(); + /// + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> T { + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. + unsafe { *self.value.get() } + } +} + +#[lang = "sized"] +trait Sized {} + +#[lang = "deref"] +pub trait Deref { + /// The resulting type after dereferencing. + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_target"] + type Target: ?Sized; + + /// Dereferences the value. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_method"] + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +// this is added because of #3030 +extern "C" { + fn never() -> !; +} + +impl !DerefMut for &T { + fn deref_mut(&mut self) -> &mut T { + unsafe { never() } + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +#[inline] +pub fn new<'b>(borrow: &'b Cell) { + let b = borrow.get(); + // { dg-warning "unused name" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index b4799edd4f5..ceada8bc51a 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -220,4 +220,5 @@ issue-3032-2.rs # https://github.com/Rust-GCC/gccrs/issues/3189 if_let_expr_simple.rs iflet.rs +issue-3033.rs # please don't delete the trailing newline