From: Philip Herron <[email protected]>
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 <[email protected]>
---
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> ¶ms_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