]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: introduce new types_compatable
authorPhilip Herron <herron.philip@googlemail.com>
Sat, 10 Jun 2023 20:07:27 +0000 (21:07 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:27 +0000 (18:46 +0100)
This is an initiative to begin getting rid of the can_eq interface.

Addresses #2019

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItemWithTrait::visit):
use new interface
* typecheck/rust-type-util.cc (types_compatable): implementation of new interface
* typecheck/rust-type-util.h (types_compatable): prototype
* typecheck/rust-unify.cc (UnifyRules::expect_placeholder):
It is allow for unification against placeholders

gcc/testsuite/ChangeLog:

* rust/compile/traits2.rs: update error message
* rust/compile/traits3.rs: update error message

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-hir-type-check-implitem.cc
gcc/rust/typecheck/rust-type-util.cc
gcc/rust/typecheck/rust-type-util.h
gcc/rust/typecheck/rust-unify.cc
gcc/testsuite/rust/compile/traits2.rs
gcc/testsuite/rust/compile/traits3.rs

index b42b034d7dfe52429e579908416e2b0e3b52bfec..130f4a51cbd21b39b91caf892f254befe8666fbc 100644 (file)
@@ -411,7 +411,9 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
 
   // check the types are compatible
   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
-  if (!trait_item_type->can_eq (lookup, true))
+  if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
+                        TyTy::TyWithLocation (lookup), constant.get_locus (),
+                        true /*emit_errors*/))
     {
       RichLocation r (constant.get_locus ());
       r.add_range (resolved_trait_item.get_locus ());
@@ -460,7 +462,9 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
 
   // check the types are compatible
   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
-  if (!trait_item_type->can_eq (lookup, true))
+  if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
+                        TyTy::TyWithLocation (lookup), type.get_locus (),
+                        true /*emit_errors*/))
     {
       RichLocation r (type.get_locus ());
       r.add_range (resolved_trait_item.get_locus ());
@@ -519,7 +523,9 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
 
   // check the types are compatible
   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
-  if (!trait_item_type->can_eq (lookup, true))
+  if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
+                        TyTy::TyWithLocation (lookup), function.get_locus (),
+                        true /*emit_errors*/))
     {
       RichLocation r (function.get_locus ());
       r.add_range (resolved_trait_item.get_locus ());
index eea97ed4fef5a039288bcbd1cd52e864cee1dce1..8e8871cab4deae622a05c5b341fc0f324d12ffbe 100644 (file)
@@ -123,6 +123,16 @@ query_type (HirId reference, TyTy::BaseType **result)
   return false;
 }
 
+bool
+types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
+                 Location unify_locus, bool emit_errors)
+{
+  TyTy::BaseType *result
+    = unify_site_and (UNKNOWN_HIRID, lhs, rhs, unify_locus, emit_errors,
+                     false /*commit*/, true /*infer*/, true /*cleanup*/);
+  return result->get_kind () != TyTy::TypeKind::ERROR;
+}
+
 TyTy::BaseType *
 unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
            Location unify_locus)
index 85906d7d1850d402559074ec79370e5850e92e6f..938f410296a6f98390d278c78173533facc63299 100644 (file)
@@ -28,6 +28,10 @@ namespace Resolver {
 bool
 query_type (HirId reference, TyTy::BaseType **result);
 
+bool
+types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
+                 Location unify_locus, bool emit_errors);
+
 TyTy::BaseType *
 unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
            Location unify_locus);
index dc809e0090ff0fd66b09fa53797279e9fb88ec8e..42e1095091740222bc325057b055da4d29a7ae3f 100644 (file)
@@ -1576,17 +1576,8 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
       }
       break;
 
-      case TyTy::PLACEHOLDER: {
-       TyTy::PlaceholderType &type
-         = *static_cast<TyTy::PlaceholderType *> (rtype);
-       bool symbol_match
-         = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
-       if (symbol_match)
-         {
-           return type.clone ();
-         }
-      }
-      break;
+    case TyTy::PLACEHOLDER:
+      return ltype->clone ();
 
     case TyTy::PROJECTION:
     case TyTy::DYNAMIC:
@@ -1609,6 +1600,10 @@ UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
     case TyTy::USIZE:
     case TyTy::ISIZE:
     case TyTy::NEVER:
+      if (infer_flag)
+       return rtype->clone ();
+      gcc_fallthrough ();
+
     case TyTy::ERROR:
       return new TyTy::ErrorType (0);
     }
index 7357c22f7d67ed4963386cfe521c45f61ce146d6..376b3c9cc7f6cf6745fc6760c259f6452622d061 100644 (file)
@@ -7,7 +7,7 @@ struct Baz;
 
 impl Foo for Baz {
     fn Bar() {}
-    // { dg-error "expected .i32. got .()." "" { target *-*-* } .-1 }
+    // { dg-error "expected" "" { target *-*-* } .-1 }
     // { dg-error "method .Bar. has an incompatible type for trait .Foo." "" { target *-*-* } .-2 }
 }
 
index fd3fa457cc8789b4d9ffc0539bbb428174517a14..d6d081487b965904fc4c38789103a9de78fb339e 100644 (file)
@@ -10,9 +10,9 @@ impl<T> Foo for Bar<T> {
     type A = i32;
 
     fn baz(a: f32) -> f32 {
-        // { dg-error "method .baz. has an incompatible type for trait .Foo." "" { target *-*-* } .-1 }
+        // { dg-error "expected" "" { target *-*-* } .-1 }
+        // { dg-error "method .baz. has an incompatible type for trait .Foo." "" { target *-*-* } .-2 }
         a
-        // { dg-error "expected .i32. got .f32." "" { target *-*-* } .-1 }
     }
 }