@@ -1356,32 +1356,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
13561356 // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
13571357 // where clauses for `?Sized`.
13581358 for pred in & generics. where_clause . predicates {
1359- if let WherePredicate :: BoundPredicate ( ref bound_pred) = * pred {
1360- ' next_bound: for bound in & bound_pred. bounds {
1361- if let GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) = * bound {
1362- // Check if the where clause type is a plain type parameter.
1363- match self
1364- . resolver
1365- . get_partial_res ( bound_pred. bounded_ty . id )
1366- . map ( |d| ( d. base_res ( ) , d. unresolved_segments ( ) ) )
1367- {
1368- Some ( ( Res :: Def ( DefKind :: TyParam , def_id) , 0 ) )
1369- if bound_pred. bound_generic_params . is_empty ( ) =>
1370- {
1371- for param in & generics. params {
1372- if def_id == self . resolver . local_def_id ( param. id ) . to_def_id ( ) {
1373- continue ' next_bound;
1374- }
1375- }
1376- }
1377- _ => { }
1378- }
1379- self . diagnostic ( ) . span_err (
1380- bound_pred. bounded_ty . span ,
1381- "`?Trait` bounds are only permitted at the \
1382- point where a type parameter is declared",
1383- ) ;
1359+ let bound_pred = match * pred {
1360+ WherePredicate :: BoundPredicate ( ref bound_pred) => bound_pred,
1361+ _ => continue ,
1362+ } ;
1363+ let compute_is_param = || {
1364+ // Check if the where clause type is a plain type parameter.
1365+ match self
1366+ . resolver
1367+ . get_partial_res ( bound_pred. bounded_ty . id )
1368+ . map ( |d| ( d. base_res ( ) , d. unresolved_segments ( ) ) )
1369+ {
1370+ Some ( ( Res :: Def ( DefKind :: TyParam , def_id) , 0 ) )
1371+ if bound_pred. bound_generic_params . is_empty ( ) =>
1372+ {
1373+ generics
1374+ . params
1375+ . iter ( )
1376+ . find ( |p| def_id == self . resolver . local_def_id ( p. id ) . to_def_id ( ) )
1377+ . is_some ( )
13841378 }
1379+ // Either the `bounded_ty` is not a plain type parameter, or
1380+ // it's not found in the generic type parameters list.
1381+ _ => false ,
1382+ }
1383+ } ;
1384+ // We only need to compute this once per `WherePredicate`, but don't
1385+ // need to compute this at all unless there is a Maybe bound.
1386+ let mut is_param: Option < bool > = None ;
1387+ for bound in & bound_pred. bounds {
1388+ if !matches ! ( * bound, GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) ) {
1389+ continue ;
1390+ }
1391+ let is_param = * is_param. get_or_insert_with ( compute_is_param) ;
1392+ if !is_param {
1393+ self . diagnostic ( ) . span_err (
1394+ bound. span ( ) ,
1395+ "`?Trait` bounds are only permitted at the \
1396+ point where a type parameter is declared",
1397+ ) ;
13851398 }
13861399 }
13871400 }
0 commit comments