Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,7 @@ fn deny_equality_constraints(

// Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind
&& qself.position > 0 // `<T>::AssocTy` is handled further down
&& let TyKind::Path(None, path) = &qself.ty.kind
&& let [PathSegment { ident, args: None, .. }] = &path.segments[..]
{
Expand Down Expand Up @@ -1987,6 +1988,35 @@ fn deny_equality_constraints(
}
}
}
// Given `A: Foo, <A>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind
&& qself.position == 0
&& let TyKind::Path(None, path) = &qself.ty.kind
&& let [potential_param] = &path.segments[..]
&& let [potential_assoc] = &full_path.segments[..]
{
for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain(
generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind {
WherePredicateKind::BoundPredicate(p)
if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind
&& let [segment] = &path.segments[..] =>
{
Some((segment.ident, &p.bounds))
}
_ => None,
}),
) {
if ident == potential_param.ident {
for bound in bounds {
if let ast::GenericBound::Trait(poly) = bound
&& poly.modifiers == TraitBoundModifiers::NONE
{
suggest(poly, potential_assoc, predicate);
}
}
}
}
}
this.dcx().emit_err(err);
}

Expand Down
12 changes: 12 additions & 0 deletions tests/ui/where-clauses/equality-constraint-with-bare-qself.rs
Comment thread
lapla-cogito marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// issue: <https://github.com/rust-lang/rust/issues/152338>

use std::iter::Iterator;

struct Ty<T>
//~^ ERROR type parameter `T` is never used
where
T: Iterator,
<T>::Item = i32, {}
//~^ ERROR equality constraints are not yet supported in `where` clauses

fn main() {}
25 changes: 25 additions & 0 deletions tests/ui/where-clauses/equality-constraint-with-bare-qself.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
error: equality constraints are not yet supported in `where` clauses
--> $DIR/equality-constraint-with-bare-qself.rs:9:5
|
LL | <T>::Item = i32, {}
| ^^^^^^^^^^^^^^^ not supported
|
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
LL - T: Iterator,
LL - <T>::Item = i32, {}
LL + T: Iterator<Item = i32>, {}
|

error[E0392]: type parameter `T` is never used
--> $DIR/equality-constraint-with-bare-qself.rs:5:11
|
LL | struct Ty<T>
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0392`.
Loading