diff options
-rw-r--r-- | gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h | 25 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cmp.h | 26 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/generics7.rs | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/generics8.rs | 2 | ||||
-rw-r--r-- | 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 2908a4b..9abf872 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 3c1858c..fda505a 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 a7ec42c..b34db3b 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 afc928da..34c8963 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 78b6149..2a41632 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 70bad1a..ceefc5d 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 0000000..3bd6321 --- /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 + } +} |