[committed,55/88] gccrs: Add general TypeBounds checks

Message ID 20230405140411.3016563-56-arthur.cohen@embecosm.com
State Accepted
Headers
Series [committed,01/88] gccrs: fatal_error_flag: Fix typo in error message |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Arthur Cohen April 5, 2023, 2:03 p.m. UTC
  From: Philip Herron <herron.philip@googlemail.com>

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.
---
 gcc/rust/typecheck/rust-unify.cc              | 11 ++++
 gcc/testsuite/rust/bounds1.rs                 | 19 ++++++
 .../rust/compile/torture/intrinsics-4.rs      | 63 +++++++++++++++++-
 .../rust/compile/torture/intrinsics-5.rs      | 66 ++++++++++++++++++-
 .../rust/execute/torture/atomic_load.rs       | 59 ++++++++++++++++-
 .../rust/execute/torture/atomic_store.rs      | 59 ++++++++++++++++-
 6 files changed, 271 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/bounds1.rs
  

Patch

diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 072f76133bc..415ffcdc6ea 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 00000000000..665836088be
--- /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 243d4460089..4e09f1089b0 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 7fd84dcd635..ffad0bd3a85 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 28ed8ae78f1..6e7383aa7e9 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 9f248b4f823..46960a7a186 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);