@@ -344,43 +344,108 @@ 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) ) ;
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 is_uncovered_ty ( input_ty) {
364+ debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
365+ return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
366+ }
367+ }
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 parameters to the trait, with the self
373+ // type appearing first.
374+ // Find the first input type that either references a type parameter OR
375+ // 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+ }
364390 }
391+
392+ // OK, found local type, all prior types upheld invariant.
393+ return Ok ( ( ) ) ;
365394 }
366395
367- // OK, found local type, all prior types upheld invariant.
368- return Ok ( ( ) ) ;
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+ }
404+ }
405+ // If we exit above loop, never found a local type.
406+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
407+ Err ( OrphanCheckErr :: NoLocalInputType )
408+ }
409+ }
410+
411+ fn is_uncovered_ty ( ty : Ty < ' _ > ) -> bool {
412+ match ty. sty {
413+ ty:: Bool |
414+ ty:: Char |
415+ ty:: Int ( ..) |
416+ ty:: Uint ( ..) |
417+ ty:: Float ( ..) |
418+ ty:: Str |
419+ ty:: FnDef ( ..) |
420+ ty:: FnPtr ( _) |
421+ ty:: Array ( ..) |
422+ ty:: Slice ( ..) |
423+ ty:: RawPtr ( ..) |
424+ ty:: Ref ( ..) |
425+ ty:: Never |
426+ ty:: Tuple ( ..) |
427+ ty:: Bound ( ..) |
428+ ty:: Infer ( ..) |
429+ ty:: Adt ( ..) |
430+ ty:: Foreign ( ..) |
431+ ty:: Dynamic ( ..) |
432+ ty:: Error |
433+ ty:: Projection ( ..) => {
434+ false
435+ }
436+
437+ ty:: Param ( ..) => {
438+ true
369439 }
370440
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) ) ;
441+ ty:: UnnormalizedProjection ( ..) |
442+ ty:: Closure ( ..) |
443+ ty:: Generator ( ..) |
444+ ty:: GeneratorWitness ( ..) |
445+ ty:: Opaque ( ..) => {
446+ bug ! ( "is_uncovered_ty invoked on unexpected type: {:?}" , ty)
378447 }
379448 }
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 ) ;
384449}
385450
386451fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments