public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Fix bad inherent overlap error
@ 2022-06-08 12:27 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4413bc0cf8b98702e8dd9e88ab5c0e19903e58e7

commit 4413bc0cf8b98702e8dd9e88ab5c0e19903e58e7
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Wed Mar 30 18:13:48 2022 +0100

    Fix bad inherent overlap error
    
    When we examine HIR::ImplBlock's we determine if an impl might overlap
    another impl based on the Self type. So for example you might have a
    generic structure Foo<T>(T), and an associated impl block for Foo<i32>, but
    then go on to define an associated impl of Foo<T> the generic one will
    overlap any associated impl hiding the generic implementation.
    
    In this case we have two generic impl blocks
    
      *const [T]
      *const T
    
    This means the *const T might overlap with the slice one since it is
    generic. As bjorn3 pointed out in #1075, the correct implementation is to
    observe that [T] is constrained by size but untill we have the auto trait
    of Sized we must example the two generic impls and just determine that
    they are not-equal so for now this is the best implementation we can do.
    
    Fixes #1075

Diff:
---
 .../typecheck/rust-hir-inherent-impl-overlap.h     | 25 +++++++++++--
 gcc/rust/typecheck/rust-hir-path-probe.h           |  5 ++-
 gcc/rust/typecheck/rust-tyty-bounds.cc             |  5 ++-
 gcc/rust/typecheck/rust-tyty-cmp.h                 | 26 --------------
 gcc/testsuite/rust/compile/generics7.rs            |  2 +-
 gcc/testsuite/rust/compile/generics8.rs            |  2 +-
 gcc/testsuite/rust/compile/torture/issue-1075.rs   | 42 ++++++++++++++++++++++
 7 files changed, 74 insertions(+), 33 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
index 2908a4b5121..9abf87280ad 100644
--- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
@@ -123,7 +123,26 @@ public:
 	      continue;
 
 	    if (query->can_eq (candidate, false))
-	      possible_collision (it->second, iy->second);
+	      {
+		// we might be in the case that we have:
+		//
+		// *const T vs *const [T]
+		//
+		// so lets use an equality check when the
+		// candidates are both generic to be sure we dont emit a false
+		// positive
+
+		bool a = query->is_concrete ();
+		bool b = candidate->is_concrete ();
+		bool both_generic = !a && !b;
+		if (both_generic)
+		  {
+		    if (!query->is_equal (*candidate))
+		      continue;
+		  }
+
+		possible_collision (it->second, iy->second);
+	      }
 	  }
       }
   }
@@ -152,8 +171,8 @@ public:
   void collision_detected (HIR::ImplItem *query, HIR::ImplItem *dup,
 			   const std::string &name)
   {
-    RichLocation r (query->get_locus ());
-    r.add_range (dup->get_locus ());
+    RichLocation r (dup->get_locus ());
+    r.add_range (query->get_locus ());
     rust_error_at (r, "duplicate definitions with name %s", name.c_str ());
   }
 
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index 3c1858cf554..fda505aa84e 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -284,7 +284,10 @@ protected:
       return;
 
     if (!receiver->can_eq (impl_block_ty, false))
-      return;
+      {
+	if (!impl_block_ty->can_eq (receiver, false))
+	  return;
+      }
 
     // lets visit the impl_item
     item->accept_vis (*this);
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index a7ec42c7a1c..b34db3bd44e 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -41,7 +41,10 @@ TypeBoundsProbe::scan ()
 	return true;
 
       if (!receiver->can_eq (impl_type, false))
-	return true;
+	{
+	  if (!impl_type->can_eq (receiver, false))
+	    return true;
+	}
 
       possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
       return true;
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index afc928da110..34c89639f6f 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -886,8 +886,6 @@ public:
     ok = true;
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const ArrayType *base;
@@ -916,8 +914,6 @@ public:
     ok = true;
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const SliceType *base;
@@ -939,8 +935,6 @@ public:
     ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL;
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const BoolType *base;
@@ -965,8 +959,6 @@ public:
     ok = type.get_int_kind () == base->get_int_kind ();
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const IntType *base;
@@ -991,8 +983,6 @@ public:
     ok = type.get_uint_kind () == base->get_uint_kind ();
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const UintType *base;
@@ -1017,8 +1007,6 @@ public:
     ok = type.get_float_kind () == base->get_float_kind ();
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const FloatType *base;
@@ -1120,8 +1108,6 @@ public:
     ok = true;
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const TupleType *base;
@@ -1143,8 +1129,6 @@ public:
 
   void visit (const USizeType &type) override { ok = true; }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const USizeType *base;
@@ -1166,8 +1150,6 @@ public:
 
   void visit (const ISizeType &type) override { ok = true; }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const ISizeType *base;
@@ -1189,8 +1171,6 @@ public:
 
   void visit (const CharType &type) override { ok = true; }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const CharType *base;
@@ -1365,8 +1345,6 @@ public:
 
   void visit (const StrType &type) override { ok = true; }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const StrType *base;
@@ -1383,8 +1361,6 @@ public:
 
   void visit (const NeverType &type) override { ok = true; }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
   const NeverType *base;
@@ -1478,8 +1454,6 @@ public:
     ok = base->bounds_compatible (type, ref_locus, false);
   }
 
-  void visit (const ParamType &type) override { ok = true; }
-
 private:
   const BaseType *get_base () const override { return base; }
 
diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs
index 78b6149437c..2a41632e693 100644
--- a/gcc/testsuite/rust/compile/generics7.rs
+++ b/gcc/testsuite/rust/compile/generics7.rs
@@ -15,7 +15,7 @@ impl Foo<char> {
 }
 
 impl<T> Foo<T> {
-    fn bar(self) -> T { // { dg-error "duplicate definitions with name bar" }
+    fn bar(self) -> T {
         self.a
     }
 }
diff --git a/gcc/testsuite/rust/compile/generics8.rs b/gcc/testsuite/rust/compile/generics8.rs
index 70bad1a4c1c..ceefc5d2c6a 100644
--- a/gcc/testsuite/rust/compile/generics8.rs
+++ b/gcc/testsuite/rust/compile/generics8.rs
@@ -1,7 +1,7 @@
 struct Foo<A, B>(A, B);
 
 impl<T> Foo<i32, T> {
-    fn test(a: T) -> T { // { dg-error "duplicate definitions with name test" }
+    fn test(a: T) -> T {
         a
     }
 }
diff --git a/gcc/testsuite/rust/compile/torture/issue-1075.rs b/gcc/testsuite/rust/compile/torture/issue-1075.rs
new file mode 100644
index 00000000000..3bd6321a940
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1075.rs
@@ -0,0 +1,42 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        // SAFETY: this is safe because `*const [T]` and `FatPtr<T>` have the same layout.
+        // Only `std` can make this guarantee.
+        let a = unsafe { Repr { rust: self }.raw };
+        a.len
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:27 [gcc/devel/rust/master] Fix bad inherent overlap error Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).