1717//! require name resolution or type checking, or other kinds of complex analysis.
1818
1919use std:: mem;
20- use std:: ops:: { Deref , DerefMut } ;
2120use std:: str:: FromStr ;
2221
2322use itertools:: { Either , Itertools } ;
@@ -37,7 +36,6 @@ use rustc_session::lint::builtin::{
3736} ;
3837use rustc_span:: { Ident , Span , kw, sym} ;
3938use rustc_target:: spec:: { AbiMap , AbiMapping } ;
40- use thin_vec:: thin_vec;
4139
4240use crate :: diagnostics:: { self , TildeConstReason } ;
4341
@@ -1593,14 +1591,8 @@ impl Visitor<'_> for AstValidator<'_> {
15931591 }
15941592
15951593 validate_generic_param_order ( self . dcx ( ) , & generics. params , generics. span ) ;
1596-
1597- for predicate in & generics. where_clause . predicates {
1598- let span = predicate. span ;
1599- if let WherePredicateKind :: EqPredicate ( predicate) = & predicate. kind {
1600- deny_equality_constraints ( self , predicate, span, generics) ;
1601- }
1602- }
16031594 walk_list ! ( self , visit_generic_param, & generics. params) ;
1595+
16041596 for predicate in & generics. where_clause . predicates {
16051597 match & predicate. kind {
16061598 WherePredicateKind :: BoundPredicate ( bound_pred) => {
@@ -1625,7 +1617,7 @@ impl Visitor<'_> for AstValidator<'_> {
16251617 }
16261618 }
16271619 }
1628- _ => { }
1620+ WherePredicateKind :: RegionPredicate ( _ ) => { }
16291621 }
16301622 self . visit_where_predicate ( predicate) ;
16311623 }
@@ -1962,170 +1954,6 @@ impl Visitor<'_> for AstValidator<'_> {
19621954 }
19631955}
19641956
1965- /// When encountering an equality constraint in a `where` clause, emit an error. If the code seems
1966- /// like it's setting an associated type, provide an appropriate suggestion.
1967- fn deny_equality_constraints (
1968- this : & AstValidator < ' _ > ,
1969- predicate : & WhereEqPredicate ,
1970- predicate_span : Span ,
1971- generics : & Generics ,
1972- ) {
1973- let mut err = diagnostics:: EqualityInWhere { span : predicate_span, assoc : None , assoc2 : None } ;
1974-
1975- // Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
1976- if let TyKind :: Path ( Some ( qself) , full_path) = & predicate. lhs_ty . kind
1977- && let TyKind :: Path ( None , path) = & qself. ty . kind
1978- && let [ PathSegment { ident, args : None , .. } ] = & path. segments [ ..]
1979- {
1980- for param in & generics. params {
1981- if param. ident == * ident
1982- && let [ PathSegment { ident, args, .. } ] = & full_path. segments [ qself. position ..]
1983- {
1984- // Make a new `Path` from `foo::Bar` to `Foo<Bar = RhsTy>`.
1985- let mut assoc_path = full_path. clone ( ) ;
1986- // Remove `Bar` from `Foo::Bar`.
1987- assoc_path. segments . pop ( ) ;
1988- let len = assoc_path. segments . len ( ) - 1 ;
1989- let gen_args = args. as_deref ( ) . cloned ( ) ;
1990- // Build `<Bar = RhsTy>`.
1991- let arg = AngleBracketedArg :: Constraint ( AssocItemConstraint {
1992- id : rustc_ast:: node_id:: DUMMY_NODE_ID ,
1993- ident : * ident,
1994- gen_args,
1995- kind : AssocItemConstraintKind :: Equality {
1996- term : predicate. rhs_ty . clone ( ) . into ( ) ,
1997- } ,
1998- span : ident. span ,
1999- } ) ;
2000- // Add `<Bar = RhsTy>` to `Foo`.
2001- match & mut assoc_path. segments [ len] . args {
2002- Some ( args) => match args. deref_mut ( ) {
2003- GenericArgs :: Parenthesized ( _) | GenericArgs :: ParenthesizedElided ( ..) => {
2004- continue ;
2005- }
2006- GenericArgs :: AngleBracketed ( args) => {
2007- args. args . push ( arg) ;
2008- }
2009- } ,
2010- empty_args => {
2011- * empty_args = Some (
2012- AngleBracketedArgs { span : ident. span , args : thin_vec ! [ arg] } . into ( ) ,
2013- ) ;
2014- }
2015- }
2016- err. assoc = Some ( diagnostics:: AssociatedSuggestion {
2017- span : predicate_span,
2018- ident : * ident,
2019- param : param. ident ,
2020- path : pprust:: path_to_string ( & assoc_path) ,
2021- } )
2022- }
2023- }
2024- }
2025-
2026- let mut suggest =
2027- |poly : & PolyTraitRef , potential_assoc : & PathSegment , predicate : & WhereEqPredicate | {
2028- if let [ trait_segment] = & poly. trait_ref . path . segments [ ..] {
2029- let assoc = pprust:: path_to_string ( & ast:: Path :: from_ident ( potential_assoc. ident ) ) ;
2030- let ty = pprust:: ty_to_string ( & predicate. rhs_ty ) ;
2031- let ( args, span) = match & trait_segment. args {
2032- Some ( args) => match args. deref ( ) {
2033- ast:: GenericArgs :: AngleBracketed ( args) => {
2034- let Some ( arg) = args. args . last ( ) else {
2035- return ;
2036- } ;
2037- ( format ! ( ", {assoc} = {ty}" ) , arg. span ( ) . shrink_to_hi ( ) )
2038- }
2039- _ => return ,
2040- } ,
2041- None => ( format ! ( "<{assoc} = {ty}>" ) , trait_segment. span ( ) . shrink_to_hi ( ) ) ,
2042- } ;
2043- let removal_span = if generics. where_clause . predicates . len ( ) == 1 {
2044- // We're removing th eonly where bound left, remove the whole thing.
2045- generics. where_clause . span
2046- } else {
2047- let mut span = predicate_span;
2048- let mut prev_span: Option < Span > = None ;
2049- let mut preds = generics. where_clause . predicates . iter ( ) . peekable ( ) ;
2050- // Find the predicate that shouldn't have been in the where bound list.
2051- while let Some ( pred) = preds. next ( ) {
2052- if let WherePredicateKind :: EqPredicate ( _) = pred. kind
2053- && pred. span == predicate_span
2054- {
2055- if let Some ( next) = preds. peek ( ) {
2056- // This is the first predicate, remove the trailing comma as well.
2057- span = span. with_hi ( next. span . lo ( ) ) ;
2058- } else if let Some ( prev_span) = prev_span {
2059- // Remove the previous comma as well.
2060- span = span. with_lo ( prev_span. hi ( ) ) ;
2061- }
2062- }
2063- prev_span = Some ( pred. span ) ;
2064- }
2065- span
2066- } ;
2067- err. assoc2 = Some ( diagnostics:: AssociatedSuggestion2 {
2068- span,
2069- args,
2070- predicate : removal_span,
2071- trait_segment : trait_segment. ident ,
2072- potential_assoc : potential_assoc. ident ,
2073- } ) ;
2074- }
2075- } ;
2076-
2077- if let TyKind :: Path ( None , full_path) = & predicate. lhs_ty . kind {
2078- // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
2079- for bounds in generics. params . iter ( ) . map ( |p| & p. bounds ) . chain (
2080- generics. where_clause . predicates . iter ( ) . filter_map ( |pred| match & pred. kind {
2081- WherePredicateKind :: BoundPredicate ( p) => Some ( & p. bounds ) ,
2082- _ => None ,
2083- } ) ,
2084- ) {
2085- for bound in bounds {
2086- if let GenericBound :: Trait ( poly) = bound
2087- && poly. modifiers == TraitBoundModifiers :: NONE
2088- {
2089- if full_path. segments [ ..full_path. segments . len ( ) - 1 ]
2090- . iter ( )
2091- . map ( |segment| segment. ident . name )
2092- . zip ( poly. trait_ref . path . segments . iter ( ) . map ( |segment| segment. ident . name ) )
2093- . all ( |( a, b) | a == b)
2094- && let Some ( potential_assoc) = full_path. segments . last ( )
2095- {
2096- suggest ( poly, potential_assoc, predicate) ;
2097- }
2098- }
2099- }
2100- }
2101- // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
2102- if let [ potential_param, potential_assoc] = & full_path. segments [ ..] {
2103- for ( ident, bounds) in generics. params . iter ( ) . map ( |p| ( p. ident , & p. bounds ) ) . chain (
2104- generics. where_clause . predicates . iter ( ) . filter_map ( |pred| match & pred. kind {
2105- WherePredicateKind :: BoundPredicate ( p)
2106- if let ast:: TyKind :: Path ( None , path) = & p. bounded_ty . kind
2107- && let [ segment] = & path. segments [ ..] =>
2108- {
2109- Some ( ( segment. ident , & p. bounds ) )
2110- }
2111- _ => None ,
2112- } ) ,
2113- ) {
2114- if ident == potential_param. ident {
2115- for bound in bounds {
2116- if let ast:: GenericBound :: Trait ( poly) = bound
2117- && poly. modifiers == TraitBoundModifiers :: NONE
2118- {
2119- suggest ( poly, potential_assoc, predicate) ;
2120- }
2121- }
2122- }
2123- }
2124- }
2125- }
2126- this. dcx ( ) . emit_err ( err) ;
2127- }
2128-
21291957pub fn check_crate (
21301958 sess : & Session ,
21311959 features : & Features ,
0 commit comments