@@ -19,9 +19,8 @@ use rustc_middle::query::Providers;
19
19
use rustc_middle:: traits:: solve:: NoSolution ;
20
20
use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
21
21
use rustc_middle:: ty:: {
22
- self , AdtKind , GenericArgKind , GenericArgs , GenericParamDefKind , Ty , TyCtxt , TypeFlags ,
23
- TypeFoldable , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , TypingMode ,
24
- Upcast ,
22
+ self , AdtKind , GenericArgKind , GenericArgs , GenericParamDefKind , Ty , TyCtxt , TypeFoldable ,
23
+ TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , TypingMode , Upcast ,
25
24
} ;
26
25
use rustc_middle:: { bug, span_bug} ;
27
26
use rustc_session:: parse:: feature_err;
@@ -111,16 +110,17 @@ where
111
110
112
111
let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env } ;
113
112
114
- if !tcx. features ( ) . trivial_bounds ( ) {
115
- wfcx. check_false_global_bounds ( )
116
- }
117
113
f ( & mut wfcx) ?;
118
114
119
115
let errors = wfcx. select_all_or_error ( ) ;
120
116
if !errors. is_empty ( ) {
121
117
return Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ) ;
122
118
}
123
119
120
+ if !tcx. features ( ) . trivial_bounds ( ) {
121
+ wfcx. check_false_global_bounds ( ) ?;
122
+ }
123
+
124
124
let assumed_wf_types = wfcx. ocx . assumed_wf_types_and_report_errors ( param_env, body_def_id) ?;
125
125
debug ! ( ?assumed_wf_types) ;
126
126
@@ -2274,7 +2274,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
2274
2274
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
2275
2275
/// aren't true.
2276
2276
#[ instrument( level = "debug" , skip( self ) ) ]
2277
- fn check_false_global_bounds ( & mut self ) {
2277
+ fn check_false_global_bounds ( & mut self ) -> Result < ( ) , ErrorGuaranteed > {
2278
2278
let tcx = self . ocx . infcx . tcx ;
2279
2279
let mut span = self . span ;
2280
2280
let empty_env = ty:: ParamEnv :: empty ( ) ;
@@ -2283,17 +2283,22 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
2283
2283
// Check elaborated bounds.
2284
2284
let implied_obligations = traits:: elaborate ( tcx, predicates_with_span) ;
2285
2285
2286
+ let mut global_obligations = vec ! [ ] ;
2286
2287
for ( pred, obligation_span) in implied_obligations {
2287
2288
// We lower empty bounds like `Vec<dyn Copy>:` as
2288
2289
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
2289
2290
// regular WF checking
2290
2291
if let ty:: ClauseKind :: WellFormed ( ..) = pred. kind ( ) . skip_binder ( ) {
2291
2292
continue ;
2292
2293
}
2293
- // Match the existing behavior.
2294
- if pred. is_global ( ) && !pred. has_type_flags ( TypeFlags :: HAS_BINDER_VARS ) {
2295
- let pred = self . normalize ( span, None , pred) ;
2296
-
2294
+ // Match the existing behavior. We normalize first to handle where-bounds
2295
+ // like `u32: Trait<Assoc = T>`.
2296
+ let clause = ObligationCause :: misc ( span, self . body_def_id ) ;
2297
+ let Ok ( pred) = self . deeply_normalize ( & clause, self . param_env , pred) else {
2298
+ tcx. dcx ( ) . delayed_bug ( "encountered errors when normalizing where-clauses" ) ;
2299
+ continue ;
2300
+ } ;
2301
+ if pred. is_global ( ) && pred. kind ( ) . bound_vars ( ) . is_empty ( ) {
2297
2302
// only use the span of the predicate clause (#90869)
2298
2303
let hir_node = tcx. hir_node_by_def_id ( self . body_def_id ) ;
2299
2304
if let Some ( hir:: Generics { predicates, .. } ) = hir_node. generics ( ) {
@@ -2315,9 +2320,17 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
2315
2320
empty_env,
2316
2321
pred,
2317
2322
) ;
2318
- self . ocx . register_obligation ( obligation) ;
2323
+ global_obligations . push ( obligation) ;
2319
2324
}
2320
2325
}
2326
+
2327
+ self . register_obligations ( global_obligations) ;
2328
+ let errors = self . select_all_or_error ( ) ;
2329
+ if !errors. is_empty ( ) {
2330
+ Err ( self . infcx . err_ctxt ( ) . report_fulfillment_errors ( errors) )
2331
+ } else {
2332
+ Ok ( ( ) )
2333
+ }
2321
2334
}
2322
2335
}
2323
2336
0 commit comments