@@ -1593,6 +1593,58 @@ fn deny_equality_constraints(
15931593 }
15941594 }
15951595 }
1596+
1597+ let mut suggest =
1598+ |poly : & PolyTraitRef , potential_assoc : & PathSegment , predicate : & WhereEqPredicate | {
1599+ if let [ trait_segment] = & poly. trait_ref . path . segments [ ..] {
1600+ let assoc = pprust:: path_to_string ( & ast:: Path :: from_ident ( potential_assoc. ident ) ) ;
1601+ let ty = pprust:: ty_to_string ( & predicate. rhs_ty ) ;
1602+ let ( args, span) = match & trait_segment. args {
1603+ Some ( args) => match args. deref ( ) {
1604+ ast:: GenericArgs :: AngleBracketed ( args) => {
1605+ let Some ( arg) = args. args . last ( ) else {
1606+ return ;
1607+ } ;
1608+ ( format ! ( ", {assoc} = {ty}" ) , arg. span ( ) . shrink_to_hi ( ) )
1609+ }
1610+ _ => return ,
1611+ } ,
1612+ None => ( format ! ( "<{assoc} = {ty}>" ) , trait_segment. span ( ) . shrink_to_hi ( ) ) ,
1613+ } ;
1614+ let removal_span = if generics. where_clause . predicates . len ( ) == 1 {
1615+ // We're removing th eonly where bound left, remove the whole thing.
1616+ generics. where_clause . span
1617+ } else {
1618+ let mut span = predicate. span ;
1619+ let mut prev: Option < Span > = None ;
1620+ let mut preds = generics. where_clause . predicates . iter ( ) . peekable ( ) ;
1621+ // Find the predicate that shouldn't have been in the where bound list.
1622+ while let Some ( pred) = preds. next ( ) {
1623+ if let WherePredicate :: EqPredicate ( pred) = pred
1624+ && pred. span == predicate. span
1625+ {
1626+ if let Some ( next) = preds. peek ( ) {
1627+ // This is the first predicate, remove the trailing comma as well.
1628+ span = span. with_hi ( next. span ( ) . lo ( ) ) ;
1629+ } else if let Some ( prev) = prev {
1630+ // Remove the previous comma as well.
1631+ span = span. with_lo ( prev. hi ( ) ) ;
1632+ }
1633+ }
1634+ prev = Some ( pred. span ( ) ) ;
1635+ }
1636+ span
1637+ } ;
1638+ err. assoc2 = Some ( errors:: AssociatedSuggestion2 {
1639+ span,
1640+ args,
1641+ predicate : removal_span,
1642+ trait_segment : trait_segment. ident ,
1643+ potential_assoc : potential_assoc. ident ,
1644+ } ) ;
1645+ }
1646+ } ;
1647+
15961648 if let TyKind :: Path ( None , full_path) = & predicate. lhs_ty . kind {
15971649 // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
15981650 for bounds in generics. params . iter ( ) . map ( |p| & p. bounds ) . chain (
@@ -1608,37 +1660,9 @@ fn deny_equality_constraints(
16081660 . map ( |segment| segment. ident . name )
16091661 . zip ( poly. trait_ref . path . segments . iter ( ) . map ( |segment| segment. ident . name ) )
16101662 . all ( |( a, b) | a == b)
1663+ && let Some ( potential_assoc) = full_path. segments . iter ( ) . last ( )
16111664 {
1612- let potential_assoc = full_path. segments . iter ( ) . last ( ) . unwrap ( ) ;
1613- // println!("asd");
1614- if let [ trait_segment] = & poly. trait_ref . path . segments [ ..] {
1615- let assoc = pprust:: path_to_string ( & ast:: Path :: from_ident (
1616- potential_assoc. ident ,
1617- ) ) ;
1618- let ty = pprust:: ty_to_string ( & predicate. rhs_ty ) ;
1619- let ( args, span) = match & trait_segment. args {
1620- Some ( args) => match args. deref ( ) {
1621- ast:: GenericArgs :: AngleBracketed ( args) => {
1622- let Some ( arg) = args. args . last ( ) else {
1623- continue ;
1624- } ;
1625- ( format ! ( ", {assoc} = {ty}" ) , arg. span ( ) . shrink_to_hi ( ) )
1626- }
1627- _ => continue ,
1628- } ,
1629- None => (
1630- format ! ( "<{assoc} = {ty}>" ) ,
1631- trait_segment. span ( ) . shrink_to_hi ( ) ,
1632- ) ,
1633- } ;
1634- err. assoc2 = Some ( errors:: AssociatedSuggestion2 {
1635- span,
1636- args,
1637- predicate : predicate. span ,
1638- trait_segment : trait_segment. ident ,
1639- potential_assoc : potential_assoc. ident ,
1640- } ) ;
1641- }
1665+ suggest ( poly, potential_assoc, predicate) ;
16421666 }
16431667 }
16441668 }
@@ -1658,37 +1682,8 @@ fn deny_equality_constraints(
16581682 ) {
16591683 if ident == potential_param. ident {
16601684 for bound in bounds {
1661- if let ast:: GenericBound :: Trait ( trait_ref, TraitBoundModifiers :: NONE ) =
1662- bound
1663- {
1664- if let [ trait_segment] = & trait_ref. trait_ref . path . segments [ ..] {
1665- let assoc = pprust:: path_to_string ( & ast:: Path :: from_ident (
1666- potential_assoc. ident ,
1667- ) ) ;
1668- let ty = pprust:: ty_to_string ( & predicate. rhs_ty ) ;
1669- let ( args, span) = match & trait_segment. args {
1670- Some ( args) => match args. deref ( ) {
1671- ast:: GenericArgs :: AngleBracketed ( args) => {
1672- let Some ( arg) = args. args . last ( ) else {
1673- continue ;
1674- } ;
1675- ( format ! ( ", {assoc} = {ty}" ) , arg. span ( ) . shrink_to_hi ( ) )
1676- }
1677- _ => continue ,
1678- } ,
1679- None => (
1680- format ! ( "<{assoc} = {ty}>" ) ,
1681- trait_segment. span ( ) . shrink_to_hi ( ) ,
1682- ) ,
1683- } ;
1684- err. assoc2 = Some ( errors:: AssociatedSuggestion2 {
1685- span,
1686- args,
1687- predicate : predicate. span ,
1688- trait_segment : trait_segment. ident ,
1689- potential_assoc : potential_assoc. ident ,
1690- } ) ;
1691- }
1685+ if let ast:: GenericBound :: Trait ( poly, TraitBoundModifiers :: NONE ) = bound {
1686+ suggest ( poly, potential_assoc, predicate) ;
16921687 }
16931688 }
16941689 }
0 commit comments