]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: we can't check the bounds involving empty placeholder types
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 14 Jun 2023 11:11:38 +0000 (12:11 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:27 +0000 (18:46 +0100)
We use placeholders for assoicated types on traits but if we are unifying
types against a placeholder its not possible to check the bounds as the
placeholder does not have enough information yet at this point to determine
if bounds will or won't be satisfied. That check will occur when associated
types and generics are setup.

Fixes #2036

gcc/rust/ChangeLog:

* typecheck/rust-unify.cc (UnifyRules::go): dont check bounds on placeholders

gcc/testsuite/ChangeLog:

* rust/compile/issue-2036.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-unify.cc
gcc/testsuite/rust/compile/issue-2036.rs [new file with mode: 0644]

index 42e1095091740222bc325057b055da4d29a7ae3f..0e62a21dc25c94f9f236e080016ed43821ffee83 100644 (file)
@@ -151,7 +151,11 @@ UnifyRules::go ()
              rtype->debug_str ().c_str ());
 
   // check bounds
-  bool should_check_bounds = !ltype->is_equal (*rtype);
+  bool ltype_is_placeholder = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+  bool rtype_is_placeholder = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+  bool types_equal = ltype->is_equal (*rtype);
+  bool should_check_bounds
+    = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
   if (should_check_bounds)
     {
       if (ltype->num_specified_bounds () > 0)
diff --git a/gcc/testsuite/rust/compile/issue-2036.rs b/gcc/testsuite/rust/compile/issue-2036.rs
new file mode 100644 (file)
index 0000000..d145975
--- /dev/null
@@ -0,0 +1,36 @@
+trait Hash<H> {
+    fn hash2(&self, hasher: &H) -> u64;
+}
+
+trait Stream {
+    fn input(&mut self, bytes: &[u8]);
+    fn result(&self) -> u64;
+}
+
+trait StreamHasher {
+    type S: Stream;
+    fn stream(&self) -> Self::S;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+trait StreamHash<H: StreamHasher>: Hash<H> {
+    fn input_stream(&self, stream: &mut H::S);
+}
+
+impl<H: StreamHasher> Hash<H> for u8 {
+    fn hash2(&self, hasher: &H) -> u64 {
+        let mut stream = hasher.stream();
+        self.input_stream(&mut stream);
+        // { dg-error "type annotations needed" "" { target *-*-* } .-1 }
+        Stream::result(&stream)
+    }
+}
+
+impl<H: StreamHasher> StreamHash<H> for u8 {
+    fn input_stream(&self, stream: &mut H::S) {
+        Stream::input(stream, &[*self]);
+    }
+}
+
+fn main() {}