@@ -17,11 +17,10 @@ use rustc_lint_defs::builtin::{
17
17
use rustc_middle:: hir:: nested_filter;
18
18
use rustc_middle:: middle:: resolve_bound_vars:: ResolvedArg ;
19
19
use rustc_middle:: middle:: stability:: EvalResult ;
20
- use rustc_middle:: ty:: error:: TypeErrorToStringExt ;
21
20
use rustc_middle:: ty:: layout:: { LayoutError , MAX_SIMD_LANES } ;
22
21
use rustc_middle:: ty:: util:: { Discr , IntTypeExt } ;
23
22
use rustc_middle:: ty:: {
24
- AdtDef , BottomUpFolder , GenericArgKind , RegionKind , TypeFoldable , TypeSuperVisitable ,
23
+ AdtDef , GenericArgKind , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeSuperVisitable ,
25
24
TypeVisitable , TypeVisitableExt , fold_regions,
26
25
} ;
27
26
use rustc_session:: lint:: builtin:: UNINHABITED_STATIC ;
@@ -30,7 +29,6 @@ use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplem
30
29
use rustc_trait_selection:: traits;
31
30
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
32
31
use tracing:: { debug, instrument} ;
33
- use ty:: TypingMode ;
34
32
use { rustc_attr_parsing as attr, rustc_hir as hir} ;
35
33
36
34
use super :: compare_impl_item:: check_type_bounds;
@@ -254,14 +252,18 @@ fn check_opaque_meets_bounds<'tcx>(
254
252
| hir:: OpaqueTyOrigin :: AsyncFn { parent, .. }
255
253
| hir:: OpaqueTyOrigin :: TyAlias { parent, .. } => parent,
256
254
} ;
255
+
256
+ let misc_cause = ObligationCause :: misc ( span, def_id) ;
257
+
258
+ // FIXME: We should reveal the TAITs that end up in where clauses here, otherwise we
259
+ // will not be able to match param-env candidates in the old solver, since we don't
260
+ // have eq-modulo-normalization. This is less of a problem than it seems, since this
261
+ // only matters if we have TAITs in where clauses, which isn't achievable with RPIT
262
+ // anyways.
257
263
let param_env = tcx. param_env ( defining_use_anchor) ;
258
264
259
- // FIXME(#132279): Once `PostBorrowckAnalysis` is supported in the old solver, this branch should be removed.
260
- let infcx = tcx. infer_ctxt ( ) . build ( if tcx. next_trait_solver_globally ( ) {
261
- TypingMode :: post_borrowck_analysis ( tcx, defining_use_anchor)
262
- } else {
263
- TypingMode :: analysis_in_body ( tcx, defining_use_anchor)
264
- } ) ;
265
+ let infcx =
266
+ tcx. infer_ctxt ( ) . build ( TypingMode :: post_borrowck_analysis ( tcx, defining_use_anchor) ) ;
265
267
let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
266
268
267
269
let args = match origin {
@@ -275,33 +277,25 @@ fn check_opaque_meets_bounds<'tcx>(
275
277
} ) ,
276
278
} ;
277
279
278
- let opaque_ty = Ty :: new_opaque ( tcx, def_id. to_def_id ( ) , args) ;
279
-
280
280
// `ReErased` regions appear in the "parent_args" of closures/coroutines.
281
281
// We're ignoring them here and replacing them with fresh region variables.
282
282
// See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
283
283
//
284
284
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
285
285
// here rather than using ReErased.
286
+ let opaque_ty = Ty :: new_opaque ( tcx, def_id. to_def_id ( ) , args) ;
286
287
let hidden_ty = tcx. type_of ( def_id. to_def_id ( ) ) . instantiate ( tcx, args) ;
287
288
let hidden_ty = fold_regions ( tcx, hidden_ty, |re, _dbi| match re. kind ( ) {
288
289
ty:: ReErased => infcx. next_region_var ( RegionVariableOrigin :: MiscVariable ( span) ) ,
289
290
_ => re,
290
291
} ) ;
291
292
292
- // HACK: We eagerly instantiate some bounds to report better errors for them...
293
- // This isn't necessary for correctness, since we register these bounds when
294
- // equating the opaque below, but we should clean this up in the new solver.
293
+ // NOTE: We elaborate the explicit item bounds for better spans.
295
294
for ( predicate, pred_span) in
296
295
tcx. explicit_item_bounds ( def_id) . iter_instantiated_copied ( tcx, args)
297
296
{
298
- let predicate = predicate. fold_with ( & mut BottomUpFolder {
299
- tcx,
300
- ty_op : |ty| if ty == opaque_ty { hidden_ty } else { ty } ,
301
- lt_op : |lt| lt,
302
- ct_op : |ct| ct,
303
- } ) ;
304
-
297
+ let predicate = predicate. fold_with ( & mut ReplaceOpaques { tcx, opaque_ty, hidden_ty } ) ;
298
+ let predicate = ocx. normalize ( & misc_cause, param_env, predicate) ;
305
299
ocx. register_obligation ( Obligation :: new (
306
300
tcx,
307
301
ObligationCause :: new (
@@ -314,24 +308,24 @@ fn check_opaque_meets_bounds<'tcx>(
314
308
) ) ;
315
309
}
316
310
317
- let misc_cause = ObligationCause :: misc ( span, def_id) ;
318
- // FIXME: We should just register the item bounds here, rather than equating.
319
- // FIXME(const_trait_impl): When we do that, please make sure to also register
320
- // the `~const` bounds.
321
- match ocx. eq ( & misc_cause, param_env, opaque_ty, hidden_ty) {
322
- Ok ( ( ) ) => { }
323
- Err ( ty_err) => {
324
- // Some types may be left "stranded" if they can't be reached
325
- // from a lowered rustc_middle bound but they're mentioned in the HIR.
326
- // This will happen, e.g., when a nested opaque is inside of a non-
327
- // existent associated type, like `impl Trait<Missing = impl Trait>`.
328
- // See <tests/ui/impl-trait/stranded-opaque.rs>.
329
- let ty_err = ty_err. to_string ( tcx) ;
330
- let guar = tcx. dcx ( ) . span_delayed_bug (
331
- span,
332
- format ! ( "could not unify `{hidden_ty}` with revealed type:\n {ty_err}" ) ,
311
+ // And check the `~const` bounds for an RPIT.
312
+ if tcx. is_conditionally_const ( def_id) {
313
+ for ( predicate, pred_span) in tcx. const_conditions ( def_id) . instantiate ( tcx, args) {
314
+ let predicate = ocx. normalize (
315
+ & misc_cause,
316
+ param_env,
317
+ predicate. to_host_effect_clause ( tcx, ty:: BoundConstness :: Maybe ) ,
333
318
) ;
334
- return Err ( guar) ;
319
+ ocx. register_obligation ( Obligation :: new (
320
+ tcx,
321
+ ObligationCause :: new (
322
+ span,
323
+ def_id,
324
+ ObligationCauseCode :: OpaqueTypeBound ( pred_span, definition_def_id) ,
325
+ ) ,
326
+ param_env,
327
+ predicate,
328
+ ) ) ;
335
329
}
336
330
}
337
331
@@ -353,26 +347,28 @@ fn check_opaque_meets_bounds<'tcx>(
353
347
let wf_tys = ocx. assumed_wf_types_and_report_errors ( param_env, defining_use_anchor) ?;
354
348
ocx. resolve_regions_and_report_errors ( defining_use_anchor, param_env, wf_tys) ?;
355
349
356
- if infcx. next_trait_solver ( ) {
357
- Ok ( ( ) )
358
- } else if let hir:: OpaqueTyOrigin :: FnReturn { .. } | hir:: OpaqueTyOrigin :: AsyncFn { .. } =
359
- origin
360
- {
361
- // HACK: this should also fall through to the hidden type check below, but the original
362
- // implementation had a bug where equivalent lifetimes are not identical. This caused us
363
- // to reject existing stable code that is otherwise completely fine. The real fix is to
364
- // compare the hidden types via our type equivalence/relation infra instead of doing an
365
- // identity check.
366
- let _ = infcx. take_opaque_types ( ) ;
367
- Ok ( ( ) )
368
- } else {
369
- // Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
370
- for ( mut key, mut ty) in infcx. take_opaque_types ( ) {
371
- ty. ty = infcx. resolve_vars_if_possible ( ty. ty ) ;
372
- key = infcx. resolve_vars_if_possible ( key) ;
373
- sanity_check_found_hidden_type ( tcx, key, ty) ?;
350
+ Ok ( ( ) )
351
+ }
352
+
353
+ struct ReplaceOpaques < ' tcx > {
354
+ tcx : TyCtxt < ' tcx > ,
355
+ opaque_ty : Ty < ' tcx > ,
356
+ hidden_ty : Ty < ' tcx > ,
357
+ }
358
+
359
+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ReplaceOpaques < ' tcx > {
360
+ fn cx ( & self ) -> TyCtxt < ' tcx > {
361
+ self . tcx
362
+ }
363
+
364
+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
365
+ if ty == self . opaque_ty {
366
+ self . hidden_ty
367
+ } else if ty. has_opaque_types ( ) {
368
+ ty. super_fold_with ( self )
369
+ } else {
370
+ ty
374
371
}
375
- Ok ( ( ) )
376
372
}
377
373
}
378
374
@@ -461,50 +457,6 @@ fn best_definition_site_of_opaque<'tcx>(
461
457
}
462
458
}
463
459
464
- fn sanity_check_found_hidden_type < ' tcx > (
465
- tcx : TyCtxt < ' tcx > ,
466
- key : ty:: OpaqueTypeKey < ' tcx > ,
467
- mut ty : ty:: OpaqueHiddenType < ' tcx > ,
468
- ) -> Result < ( ) , ErrorGuaranteed > {
469
- if ty. ty . is_ty_var ( ) {
470
- // Nothing was actually constrained.
471
- return Ok ( ( ) ) ;
472
- }
473
- if let ty:: Alias ( ty:: Opaque , alias) = ty. ty . kind ( ) {
474
- if alias. def_id == key. def_id . to_def_id ( ) && alias. args == key. args {
475
- // Nothing was actually constrained, this is an opaque usage that was
476
- // only discovered to be opaque after inference vars resolved.
477
- return Ok ( ( ) ) ;
478
- }
479
- }
480
- let strip_vars = |ty : Ty < ' tcx > | {
481
- ty. fold_with ( & mut BottomUpFolder {
482
- tcx,
483
- ty_op : |t| t,
484
- ct_op : |c| c,
485
- lt_op : |l| match l. kind ( ) {
486
- RegionKind :: ReVar ( _) => tcx. lifetimes . re_erased ,
487
- _ => l,
488
- } ,
489
- } )
490
- } ;
491
- // Closures frequently end up containing erased lifetimes in their final representation.
492
- // These correspond to lifetime variables that never got resolved, so we patch this up here.
493
- ty. ty = strip_vars ( ty. ty ) ;
494
- // Get the hidden type.
495
- let hidden_ty = tcx. type_of ( key. def_id ) . instantiate ( tcx, key. args ) ;
496
- let hidden_ty = strip_vars ( hidden_ty) ;
497
-
498
- // If the hidden types differ, emit a type mismatch diagnostic.
499
- if hidden_ty == ty. ty {
500
- Ok ( ( ) )
501
- } else {
502
- let span = tcx. def_span ( key. def_id ) ;
503
- let other = ty:: OpaqueHiddenType { ty : hidden_ty, span } ;
504
- Err ( ty. build_mismatch_error ( & other, tcx) ?. emit ( ) )
505
- }
506
- }
507
-
508
460
/// Check that the opaque's precise captures list is valid (if present).
509
461
/// We check this for regular `impl Trait`s and also RPITITs, even though the latter
510
462
/// are technically GATs.
@@ -1801,11 +1753,7 @@ pub(super) fn check_coroutine_obligations(
1801
1753
1802
1754
debug ! ( ?typeck_results. coroutine_stalled_predicates) ;
1803
1755
1804
- let mode = if tcx. next_trait_solver_globally ( ) {
1805
- TypingMode :: post_borrowck_analysis ( tcx, def_id)
1806
- } else {
1807
- TypingMode :: analysis_in_body ( tcx, def_id)
1808
- } ;
1756
+ let mode = TypingMode :: post_borrowck_analysis ( tcx, def_id) ;
1809
1757
1810
1758
let infcx = tcx
1811
1759
. infer_ctxt ( )
@@ -1825,15 +1773,5 @@ pub(super) fn check_coroutine_obligations(
1825
1773
return Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ) ;
1826
1774
}
1827
1775
1828
- if !tcx. next_trait_solver_globally ( ) {
1829
- // Check that any hidden types found when checking these stalled coroutine obligations
1830
- // are valid.
1831
- for ( key, ty) in infcx. take_opaque_types ( ) {
1832
- let hidden_type = infcx. resolve_vars_if_possible ( ty) ;
1833
- let key = infcx. resolve_vars_if_possible ( key) ;
1834
- sanity_check_found_hidden_type ( tcx, key, hidden_type) ?;
1835
- }
1836
- }
1837
-
1838
1776
Ok ( ( ) )
1839
1777
}
0 commit comments