From eb4a61ac1babffaa03d837d32a1107ea93e85e48 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Sat, 4 Feb 2023 22:53:48 +0000 Subject: [PATCH] gccrs: Add general TypeBounds checks Existing tests are updated to use libcore copy and clone implementation. Addresses #1725 Signed-off-by: Philip Herron 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. --- gcc/rust/typecheck/rust-unify.cc | 11 ++++ gcc/testsuite/rust/bounds1.rs | 19 +++++++ gcc/testsuite/rust/compile/torture/intrinsics-4.rs | 63 ++++++++++++++++++++- gcc/testsuite/rust/compile/torture/intrinsics-5.rs | 66 +++++++++++++++++++++- gcc/testsuite/rust/execute/torture/atomic_load.rs | 59 ++++++++++++++++++- gcc/testsuite/rust/execute/torture/atomic_store.rs | 59 ++++++++++++++++++- 6 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/rust/bounds1.rs 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 { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; + } + } +} + +pub fn foo>(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(dst: *mut T, val: T); pub fn atomic_store_release(dst: *mut T, val: T); pub fn atomic_store_relaxed(dst: *mut T, val: T); - // pub fn atomic_store_unordered(dst: *mut T, val: T); + pub fn atomic_store_unordered(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(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(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(dst: *mut T, val: T); -- 2.7.4