@@ -371,43 +371,68 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt<'_, '_, '_>,
371371 trait_ref) ;
372372 }
373373
374- // First, create an ordered iterator over all the type parameters to the trait, with the self
375- // type appearing first.
376- // Find the first input type that either references a type parameter OR
377- // some local type.
378- for input_ty in trait_ref. input_types ( ) {
379- if ty_is_local ( tcx, input_ty, in_crate) {
380- debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
381-
382- // First local input type. Check that there are no
383- // uncovered type parameters.
384- let uncovered_tys = uncovered_tys ( tcx, input_ty, in_crate) ;
385- for uncovered_ty in uncovered_tys {
386- if let Some ( param) = uncovered_ty. walk ( )
387- . find ( |t| is_possibly_remote_type ( t, in_crate) )
388- {
389- debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
390- return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
391- }
374+ if tcx. features ( ) . re_rebalance_coherence {
375+ // Given impl<P1..=Pn> Trait<T1..=Tn> for T0, an impl is valid only
376+ // if at least one of the following is true:
377+ //
378+ // - Trait is a local trait
379+ // (already checked in orphan_check prior to calling this function)
380+ // - All of
381+ // - At least one of the types T0..=Tn must be a local type.
382+ // Let Ti be the first such type.
383+ // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
384+ //
385+ for input_ty in trait_ref. input_types ( ) {
386+ debug ! ( "orphan_check_trait_ref: check ty `{:?}`" , input_ty) ;
387+ if ty_is_local ( tcx, input_ty, in_crate) {
388+ debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
389+ return Ok ( ( ) ) ;
390+ } else if let ty:: Param ( _) = input_ty. sty {
391+ debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
392+ return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
392393 }
393-
394- // OK, found local type, all prior types upheld invariant.
395- return Ok ( ( ) ) ;
396394 }
395+ // If we exit above loop, never found a local type.
396+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
397+ Err ( OrphanCheckErr :: NoLocalInputType )
398+ } else {
399+ // First, create an ordered iterator over all the type
400+ // parameters to the trait, with the self type appearing
401+ // first. Find the first input type that either references a
402+ // type parameter OR some local type.
403+ for input_ty in trait_ref. input_types ( ) {
404+ if ty_is_local ( tcx, input_ty, in_crate) {
405+ debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
406+
407+ // First local input type. Check that there are no
408+ // uncovered type parameters.
409+ let uncovered_tys = uncovered_tys ( tcx, input_ty, in_crate) ;
410+ for uncovered_ty in uncovered_tys {
411+ if let Some ( param) = uncovered_ty. walk ( )
412+ . find ( |t| is_possibly_remote_type ( t, in_crate) )
413+ {
414+ debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
415+ return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
416+ }
417+ }
397418
398- // Otherwise, enforce invariant that there are no type
399- // parameters reachable.
400- if let Some ( param) = input_ty. walk ( )
401- . find ( |t| is_possibly_remote_type ( t, in_crate) )
402- {
403- debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
404- return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
419+ // OK, found local type, all prior types upheld invariant.
420+ return Ok ( ( ) ) ;
421+ }
422+
423+ // Otherwise, enforce invariant that there are no type
424+ // parameters reachable.
425+ if let Some ( param) = input_ty. walk ( )
426+ . find ( |t| is_possibly_remote_type ( t, in_crate) )
427+ {
428+ debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
429+ return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
430+ }
405431 }
432+ // If we exit above loop, never found a local type.
433+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
434+ Err ( OrphanCheckErr :: NoLocalInputType )
406435 }
407-
408- // If we exit above loop, never found a local type.
409- debug ! ( "orphan_check_trait_ref: no local type" ) ;
410- return Err ( OrphanCheckErr :: NoLocalInputType ) ;
411436}
412437
413438fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments