https://gcc.gnu.org/g:c5b8c95b82ceb961dcd8a14072c8a1ed0025a043

commit r15-8797-gc5b8c95b82ceb961dcd8a14072c8a1ed0025a043
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Wed Feb 12 17:10:31 2025 +0000

    gccrs: add diagnostic for E0229 no associated type arguments allowed here
    
    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>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.h  |  3 ++-
 gcc/rust/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(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h 
b/gcc/rust/typecheck/rust-hir-type-check-base.h
index e720b9479161..8a1bf6f4cb35 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 327cbb010a44..6a09772d0231 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 3e42427e2ec0..fc35abb6ec41 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 000000000000..9475aef9d71f
--- /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 }
+}

Reply via email to