@@ -1328,32 +1328,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
13281328 // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
13291329 // where clauses for `?Sized`.
13301330 for pred in & generics. where_clause . predicates {
1331- if let WherePredicate :: BoundPredicate ( ref bound_pred) = * pred {
1332- ' next_bound: for bound in & bound_pred. bounds {
1333- if let GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) = * bound {
1334- // Check if the where clause type is a plain type parameter.
1335- match self
1336- . resolver
1337- . get_partial_res ( bound_pred. bounded_ty . id )
1338- . map ( |d| ( d. base_res ( ) , d. unresolved_segments ( ) ) )
1339- {
1340- Some ( ( Res :: Def ( DefKind :: TyParam , def_id) , 0 ) )
1341- if bound_pred. bound_generic_params . is_empty ( ) =>
1342- {
1343- for param in & generics. params {
1344- if def_id == self . resolver . local_def_id ( param. id ) . to_def_id ( ) {
1345- continue ' next_bound;
1346- }
1347- }
1348- }
1349- _ => { }
1350- }
1351- self . diagnostic ( ) . span_err (
1352- bound_pred. bounded_ty . span ,
1353- "`?Trait` bounds are only permitted at the \
1354- point where a type parameter is declared",
1355- ) ;
1331+ let bound_pred = match * pred {
1332+ WherePredicate :: BoundPredicate ( ref bound_pred) => bound_pred,
1333+ _ => continue ,
1334+ } ;
1335+ let compute_is_param = || {
1336+ // Check if the where clause type is a plain type parameter.
1337+ match self
1338+ . resolver
1339+ . get_partial_res ( bound_pred. bounded_ty . id )
1340+ . map ( |d| ( d. base_res ( ) , d. unresolved_segments ( ) ) )
1341+ {
1342+ Some ( ( Res :: Def ( DefKind :: TyParam , def_id) , 0 ) )
1343+ if bound_pred. bound_generic_params . is_empty ( ) =>
1344+ {
1345+ generics
1346+ . params
1347+ . iter ( )
1348+ . find ( |p| def_id == self . resolver . local_def_id ( p. id ) . to_def_id ( ) )
1349+ . is_some ( )
13561350 }
1351+ // Either the `bounded_ty` is not a plain type parameter, or
1352+ // it's not found in the generic type parameters list.
1353+ _ => false ,
1354+ }
1355+ } ;
1356+ // We only need to compute this once per `WherePredicate`, but don't
1357+ // need to compute this at all unless there is a Maybe bound.
1358+ let mut is_param: Option < bool > = None ;
1359+ for bound in & bound_pred. bounds {
1360+ if !matches ! ( * bound, GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) ) {
1361+ continue ;
1362+ }
1363+ let is_param = * is_param. get_or_insert_with ( compute_is_param) ;
1364+ if !is_param {
1365+ self . diagnostic ( ) . span_err (
1366+ bound. span ( ) ,
1367+ "`?Trait` bounds are only permitted at the \
1368+ point where a type parameter is declared",
1369+ ) ;
13571370 }
13581371 }
13591372 }
0 commit comments