From: Philip Herron <herron.phi...@googlemail.com>

It seems bounds in qualified paths are not allowed to specify associated
type bindings because its going to be associated with the impl block
anyway.

Fixes Rust-GCC#2369

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-base.h: add flag
        * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
        * typecheck/rust-tyty-bounds.cc: new diagnostic

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron <herron.phi...@googlemail.com>
---
 gcc/rust/typecheck/rust-hir-type-check-base.h |  3 ++-
 .../typecheck/rust-hir-type-check-type.cc     |  6 ++++--
 gcc/rust/typecheck/rust-tyty-bounds.cc        | 17 ++++++++++++++-
 gcc/testsuite/rust/compile/issue-2369.rs      | 21 +++++++++++++++++++
 4 files changed, 43 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2369.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h 
b/gcc/rust/typecheck/rust-hir-type-check-base.h
index e720b947916..8a1bf6f4cb3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -40,7 +40,8 @@ protected:
   TyTy::TypeBoundPredicate get_predicate_from_bound (
     HIR::TypePath &path,
     tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
-    BoundPolarity polarity = BoundPolarity::RegularBound);
+    BoundPolarity polarity = BoundPolarity::RegularBound,
+    bool is_qualified_type = false);
 
   bool check_for_unconstrained (
     const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 327cbb010a4..6a09772d023 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -193,8 +193,10 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
     return;
 
   // get the predicate for the bound
-  auto specified_bound = get_predicate_from_bound (qual_path_type.get_trait (),
-                                                  qual_path_type.get_type ());
+  auto specified_bound
+    = get_predicate_from_bound (qual_path_type.get_trait (),
+                               qual_path_type.get_type (),
+                               BoundPolarity::RegularBound, true);
   if (specified_bound.is_error ())
     return;
 
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 3e42427e2ec..fc35abb6ec4 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -196,7 +196,7 @@ TyTy::TypeBoundPredicate
 TypeCheckBase::get_predicate_from_bound (
   HIR::TypePath &type_path,
   tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
-  BoundPolarity polarity)
+  BoundPolarity polarity, bool is_qualified_type_path)
 {
   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
   bool already_resolved
@@ -222,6 +222,21 @@ TypeCheckBase::get_predicate_from_bound (
        if (final_generic_seg.has_generic_args ())
          {
            args = final_generic_seg.get_generic_args ();
+           if (args.get_binding_args ().size () > 0
+               && associated_self.has_value () && is_qualified_type_path)
+             {
+               auto &binding_args = args.get_binding_args ();
+
+               rich_location r (line_table, args.get_locus ());
+               for (auto it = binding_args.begin (); it != binding_args.end ();
+                    it++)
+                 {
+                   auto &arg = *it;
+                   r.add_fixit_remove (arg.get_locus ());
+                 }
+               rust_error_at (r, ErrorCode::E0229,
+                              "associated type bindings are not allowed here");
+             }
          }
       }
       break;
diff --git a/gcc/testsuite/rust/compile/issue-2369.rs 
b/gcc/testsuite/rust/compile/issue-2369.rs
new file mode 100644
index 00000000000..9475aef9d71
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2369.rs
@@ -0,0 +1,21 @@
+#[lang = "sized"]
+trait Sized {}
+
+fn main() {
+    pub trait Foo {
+        type A;
+        fn boo(&self) -> <Self as Foo>::A;
+    }
+
+    struct Bar;
+
+    impl Foo for isize {
+        type A = usize;
+        fn boo(&self) -> usize {
+            42
+        }
+    }
+
+    fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+    // { dg-error "associated type bindings are not allowed here .E0229." "" { 
target *-*-* } .-1 }
+}
-- 
2.45.2

Reply via email to