diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-02-04 22:53:48 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2023-02-05 00:10:49 +0000 |
commit | 6d7a7b22882433d46bf4e4efe8c43343892c91eb (patch) | |
tree | 61ffb34ee7ae6c32d2545dd27146fab5a8e44833 /gcc | |
parent | 1b0794c172c4e60ee4cd7f2fd3a2426997b1d0a1 (diff) | |
download | gcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.zip gcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.tar.gz gcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.tar.bz2 |
gccrs: Add general TypeBounds checks
Existing tests are updated to use libcore copy and clone implementation.
Addresses #1725
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/ChangeLog:
* typecheck/rust-unify.cc (UnifyRules::go): ensure the bounds are checked
gcc/testsuite/ChangeLog:
* rust/compile/torture/intrinsics-4.rs: implement Copy trait
* rust/compile/torture/intrinsics-5.rs: likewise
* rust/execute/torture/atomic_load.rs: likewise
* rust/execute/torture/atomic_store.rs: likewise
* rust/bounds1.rs: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-unify.cc | 11 | ||||
-rw-r--r-- | gcc/testsuite/rust/bounds1.rs | 19 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/intrinsics-4.rs | 63 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/intrinsics-5.rs | 66 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/atomic_load.rs | 59 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/atomic_store.rs | 59 |
6 files changed, 271 insertions, 6 deletions
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc index 072f761..415ffcd 100644 --- a/gcc/rust/typecheck/rust-unify.cc +++ b/gcc/rust/typecheck/rust-unify.cc @@ -124,6 +124,17 @@ UnifyRules::go () rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (), rtype->debug_str ().c_str ()); + // check bounds + if (ltype->num_specified_bounds () > 0) + { + if (!ltype->bounds_compatible (*rtype, locus, true)) + { + // already emitted an error + emit_error = false; + return new TyTy::ErrorType (0); + } + } + switch (ltype->get_kind ()) { case TyTy::INFER: diff --git a/gcc/testsuite/rust/bounds1.rs b/gcc/testsuite/rust/bounds1.rs new file mode 100644 index 0000000..6658360 --- /dev/null +++ b/gcc/testsuite/rust/bounds1.rs @@ -0,0 +1,19 @@ +mod core { + mod ops { + #[lang = "add"] + pub trait Add<Rhs = Self> { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; + } + } +} + +pub fn foo<T: core::ops::Add<Output = i32>>(a: T) -> i32 { + // { dg-error "bounds not satisfied for f32 .Add. is not satisfied" "" { target *-*-* } .-1 } + a + a +} + +pub fn main() { + foo(123f32); +} diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs index 243d446..4e09f10 100644 --- a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs +++ b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs @@ -1,10 +1,67 @@ -trait Copy {} +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +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 + } +} extern "rust-intrinsic" { pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T); pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T); pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T); - // pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T); + pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T); } fn main() { @@ -15,6 +72,6 @@ fn main() { atomic_store_seqcst(&mut dst, new_value); atomic_store_release(&mut dst, new_value); atomic_store_relaxed(&mut dst, new_value); - // atomic_store_unordered(&mut dst, new_value); + atomic_store_unordered(&mut dst, new_value); } } diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs index 7fd84dc..ffad0bd 100644 --- a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs +++ b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs @@ -1,4 +1,61 @@ -trait Copy {} +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +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 + } +} extern "rust-intrinsic" { pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, value: T); @@ -24,6 +81,13 @@ impl VeryLargeType { } } +impl Clone for VeryLargeType { + fn clone(&self) -> Self { + *self + } +} +impl Copy for VeryLargeType {} + fn main() { let mut dst = VeryLargeType::new(0); let mut b = false; diff --git a/gcc/testsuite/rust/execute/torture/atomic_load.rs b/gcc/testsuite/rust/execute/torture/atomic_load.rs index 28ed8ae..6e7383a 100644 --- a/gcc/testsuite/rust/execute/torture/atomic_load.rs +++ b/gcc/testsuite/rust/execute/torture/atomic_load.rs @@ -1,4 +1,61 @@ -trait Copy {} +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +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 + } +} extern "rust-intrinsic" { pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T; diff --git a/gcc/testsuite/rust/execute/torture/atomic_store.rs b/gcc/testsuite/rust/execute/torture/atomic_store.rs index 9f248b4..46960a7 100644 --- a/gcc/testsuite/rust/execute/torture/atomic_store.rs +++ b/gcc/testsuite/rust/execute/torture/atomic_store.rs @@ -1,4 +1,61 @@ -trait Copy {} +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +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 + } +} extern "rust-intrinsic" { pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T); |