@@ -371,43 +371,68 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt<'_, '_, '_>,
371
371
trait_ref) ;
372
372
}
373
373
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) )
392
393
}
393
-
394
- // OK, found local type, all prior types upheld invariant.
395
- return Ok ( ( ) ) ;
396
394
}
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
+ }
397
418
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
+ }
405
431
}
432
+ // If we exit above loop, never found a local type.
433
+ debug ! ( "orphan_check_trait_ref: no local type" ) ;
434
+ Err ( OrphanCheckErr :: NoLocalInputType )
406
435
}
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 ) ;
411
436
}
412
437
413
438
fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments