@@ -344,43 +344,68 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt<'_, '_, '_>,
344344 trait_ref) ;
345345 }
346346
347- // First, create an ordered iterator over all the type parameters to the trait, with the self
348- // type appearing first.
349- // Find the first input type that either references a type parameter OR
350- // some local type.
351- for input_ty in trait_ref. input_types ( ) {
352- if ty_is_local ( tcx, input_ty, in_crate) {
353- debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
354-
355- // First local input type. Check that there are no
356- // uncovered type parameters.
357- let uncovered_tys = uncovered_tys ( tcx, input_ty, in_crate) ;
358- for uncovered_ty in uncovered_tys {
359- if let Some ( param) = uncovered_ty. walk ( )
360- . find ( |t| is_possibly_remote_type ( t, in_crate) )
361- {
362- debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
363- return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
364- }
347+ if tcx. features ( ) . re_rebalance_coherence {
348+ // Given impl<P1..=Pn> Trait<T1..=Tn> for T0, an impl is valid only
349+ // if at least one of the following is true:
350+ //
351+ // - Trait is a local trait
352+ // (already checked in orphan_check prior to calling this function)
353+ // - All of
354+ // - At least one of the types T0..=Tn must be a local type.
355+ // Let Ti be the first such type.
356+ // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
357+ //
358+ for input_ty in trait_ref. input_types ( ) {
359+ debug ! ( "orphan_check_trait_ref: check ty `{:?}`" , input_ty) ;
360+ if ty_is_local ( tcx, input_ty, in_crate) {
361+ debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
362+ return Ok ( ( ) ) ;
363+ } else if let ty:: Param ( _) = input_ty. sty {
364+ debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
365+ return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
365366 }
366-
367- // OK, found local type, all prior types upheld invariant.
368- return Ok ( ( ) ) ;
369367 }
368+ // If we exit above loop, never found a local type.
369+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
370+ Err ( OrphanCheckErr :: NoLocalInputType )
371+ } else {
372+ // First, create an ordered iterator over all the type
373+ // parameters to the trait, with the self type appearing
374+ // first. Find the first input type that either references a
375+ // type parameter OR some local type.
376+ for input_ty in trait_ref. input_types ( ) {
377+ if ty_is_local ( tcx, input_ty, in_crate) {
378+ debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
379+
380+ // First local input type. Check that there are no
381+ // uncovered type parameters.
382+ let uncovered_tys = uncovered_tys ( tcx, input_ty, in_crate) ;
383+ for uncovered_ty in uncovered_tys {
384+ if let Some ( param) = uncovered_ty. walk ( )
385+ . find ( |t| is_possibly_remote_type ( t, in_crate) )
386+ {
387+ debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
388+ return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
389+ }
390+ }
370391
371- // Otherwise, enforce invariant that there are no type
372- // parameters reachable.
373- if let Some ( param) = input_ty. walk ( )
374- . find ( |t| is_possibly_remote_type ( t, in_crate) )
375- {
376- debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
377- return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
392+ // OK, found local type, all prior types upheld invariant.
393+ return Ok ( ( ) ) ;
394+ }
395+
396+ // Otherwise, enforce invariant that there are no type
397+ // parameters reachable.
398+ if let Some ( param) = input_ty. walk ( )
399+ . find ( |t| is_possibly_remote_type ( t, in_crate) )
400+ {
401+ debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
402+ return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
403+ }
378404 }
405+ // If we exit above loop, never found a local type.
406+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
407+ Err ( OrphanCheckErr :: NoLocalInputType )
379408 }
380-
381- // If we exit above loop, never found a local type.
382- debug ! ( "orphan_check_trait_ref: no local type" ) ;
383- return Err ( OrphanCheckErr :: NoLocalInputType ) ;
384409}
385410
386411fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments