@@ -387,7 +387,10 @@ pub(super) fn check_opaque<'tcx>(
387
387
) {
388
388
check_opaque_for_inheriting_lifetimes ( tcx, def_id, span) ;
389
389
tcx. ensure ( ) . type_of ( def_id) ;
390
- check_opaque_for_cycles ( tcx, def_id, substs, span, origin) ;
390
+ if check_opaque_for_cycles ( tcx, def_id, substs, span, origin) . is_err ( ) {
391
+ return ;
392
+ }
393
+ check_opaque_meets_bounds ( tcx, def_id, substs, span, origin) ;
391
394
}
392
395
393
396
/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
@@ -504,7 +507,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
504
507
substs : SubstsRef < ' tcx > ,
505
508
span : Span ,
506
509
origin : & hir:: OpaqueTyOrigin ,
507
- ) {
510
+ ) -> Result < ( ) , ErrorReported > {
508
511
if let Err ( partially_expanded_type) = tcx. try_expand_impl_trait_type ( def_id. to_def_id ( ) , substs)
509
512
{
510
513
match origin {
@@ -514,7 +517,68 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
514
517
}
515
518
_ => opaque_type_cycle_error ( tcx, def_id, span) ,
516
519
}
520
+ Err ( ErrorReported )
521
+ } else {
522
+ Ok ( ( ) )
523
+ }
524
+ }
525
+
526
+ /// Check that the concrete type behind `impl Trait` actually implements `Trait`.
527
+ fn check_opaque_meets_bounds < ' tcx > (
528
+ tcx : TyCtxt < ' tcx > ,
529
+ def_id : LocalDefId ,
530
+ substs : SubstsRef < ' tcx > ,
531
+ span : Span ,
532
+ origin : & hir:: OpaqueTyOrigin ,
533
+ ) {
534
+ match origin {
535
+ // Checked when type checking the function containing them.
536
+ hir:: OpaqueTyOrigin :: FnReturn | hir:: OpaqueTyOrigin :: AsyncFn => return ,
537
+ // Can have different predicates to their defining use
538
+ hir:: OpaqueTyOrigin :: Binding | hir:: OpaqueTyOrigin :: Misc => { }
517
539
}
540
+
541
+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
542
+ let param_env = tcx. param_env ( def_id) ;
543
+
544
+ tcx. infer_ctxt ( ) . enter ( move |infcx| {
545
+ let inh = Inherited :: new ( infcx, def_id) ;
546
+ let infcx = & inh. infcx ;
547
+ let opaque_ty = tcx. mk_opaque ( def_id. to_def_id ( ) , substs) ;
548
+
549
+ let misc_cause = traits:: ObligationCause :: misc ( span, hir_id) ;
550
+
551
+ let ( _, opaque_type_map) = inh. register_infer_ok_obligations (
552
+ infcx. instantiate_opaque_types ( def_id. to_def_id ( ) , hir_id, param_env, & opaque_ty, span) ,
553
+ ) ;
554
+
555
+ for ( def_id, opaque_defn) in opaque_type_map {
556
+ match infcx
557
+ . at ( & misc_cause, param_env)
558
+ . eq ( opaque_defn. concrete_ty , tcx. type_of ( def_id) . subst ( tcx, opaque_defn. substs ) )
559
+ {
560
+ Ok ( infer_ok) => inh. register_infer_ok_obligations ( infer_ok) ,
561
+ Err ( ty_err) => tcx. sess . delay_span_bug (
562
+ opaque_defn. definition_span ,
563
+ & format ! (
564
+ "could not unify `{}` with revealed type:\n {}" ,
565
+ opaque_defn. concrete_ty, ty_err,
566
+ ) ,
567
+ ) ,
568
+ }
569
+ }
570
+
571
+ // Check that all obligations are satisfied by the implementation's
572
+ // version.
573
+ if let Err ( ref errors) = inh. fulfillment_cx . borrow_mut ( ) . select_all_or_error ( & infcx) {
574
+ infcx. report_fulfillment_errors ( errors, None , false ) ;
575
+ }
576
+
577
+ // Finally, resolve all regions. This catches wily misuses of
578
+ // lifetime parameters.
579
+ let fcx = FnCtxt :: new ( & inh, param_env, hir_id) ;
580
+ fcx. regionck_item ( hir_id, span, & [ ] ) ;
581
+ } ) ;
518
582
}
519
583
520
584
pub fn check_item_type < ' tcx > ( tcx : TyCtxt < ' tcx > , it : & ' tcx hir:: Item < ' tcx > ) {
0 commit comments