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> ¶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