aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc6
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc21
-rw-r--r--gcc/testsuite/rust/compile/issue-3032-1.rs58
-rw-r--r--gcc/testsuite/rust/compile/issue-3032-2.rs49
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude4
6 files changed, 134 insertions, 6 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h
index bdfd987..4197033 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -246,6 +246,8 @@ public:
HIR::ImplBlock *get_impl_block ();
+ location_t get_locus () const;
+
TyTy::BaseType *get_self ();
const TyTy::BaseType *get_self () const;
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index ec331cf..91842df 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -669,6 +669,12 @@ AssociatedImplTrait::reset_associated_types ()
trait->clear_associated_types ();
}
+location_t
+AssociatedImplTrait::get_locus () const
+{
+ return impl->get_locus ();
+}
+
Analysis::NodeMapping
TraitItemReference::get_parent_trait_mappings () const
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index ba22eaf..dfdf85a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1822,10 +1822,20 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
HIR::ImplBlock *parent = impl_item.first;
HIR::Function *fn = impl_item.second;
- if (parent->has_trait_ref ()
- && fn->get_function_name ().as_string ().compare (
- associated_item_name)
- == 0)
+ bool is_deref = lang_item_type == LangItem::Kind::DEREF
+ || lang_item_type == LangItem::Kind::DEREF_MUT;
+ bool is_deref_match = fn->get_function_name ().as_string ().compare (
+ LangItem::ToString (LangItem::Kind::DEREF))
+ == 0
+ || fn->get_function_name ().as_string ().compare (
+ LangItem::ToString (LangItem::Kind::DEREF_MUT))
+ == 0;
+
+ bool is_recursive_op
+ = fn->get_function_name ().as_string ().compare (associated_item_name)
+ == 0
+ || (is_deref && is_deref_match);
+ if (parent->has_trait_ref () && is_recursive_op)
{
TraitReference *trait_reference
= TraitResolver::Lookup (*parent->get_trait_ref ().get ());
@@ -1842,7 +1852,8 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type,
bool is_lang_item_impl
= trait_reference->get_mappings ().get_defid ()
- == respective_lang_item_id;
+ == respective_lang_item_id
+ || (is_deref && is_deref_match);
bool self_is_lang_item_self
= fntype->get_self_type ()->is_equal (*adjusted_self);
bool recursive_operator_overload
diff --git a/gcc/testsuite/rust/compile/issue-3032-1.rs b/gcc/testsuite/rust/compile/issue-3032-1.rs
new file mode 100644
index 0000000..e9eb027
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3032-1.rs
@@ -0,0 +1,58 @@
+#![feature(negative_impls)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T: ?Sized> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+// this is added because of #3030
+extern "C" {
+ fn never() -> !;
+}
+
+impl<T: ?Sized> !DerefMut for &T {
+ fn deref_mut(&mut self) -> &mut T {
+ unsafe { never() }
+ }
+}
+
+impl<T: ?Sized> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+ /// Mutably dereferences the value.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T: ?Sized> DerefMut for &mut T {
+ fn deref_mut(&mut self) -> &mut T {
+ *self
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3032-2.rs b/gcc/testsuite/rust/compile/issue-3032-2.rs
new file mode 100644
index 0000000..9e09d41
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3032-2.rs
@@ -0,0 +1,49 @@
+#![feature(negative_impls)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ // #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T: ?Sized> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+impl<T: ?Sized> !DerefMut for &T {}
+
+impl<T: ?Sized> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ *self
+ }
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+ /// Mutably dereferences the value.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T: ?Sized> DerefMut for &mut T {
+ fn deref_mut(&mut self) -> &mut T {
+ *self
+ }
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index ecef6d2..383950c 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -234,4 +234,6 @@ issue-3139-3.rs
issue-3036.rs
issue-2951.rs
issue-2203.rs
-issue-2499.rs \ No newline at end of file
+issue-2499.rs
+issue-3032-1.rs
+issue-3032-2.rs \ No newline at end of file