@@ -1328,32 +1328,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
1328
1328
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
1329
1329
// where clauses for `?Sized`.
1330
1330
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 ( )
1356
1350
}
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
+ ) ;
1357
1370
}
1358
1371
}
1359
1372
}
0 commit comments