@@ -371,43 +371,108 @@ 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) ) ;
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 is_uncovered_ty ( input_ty) {
391
+ debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
392
+ return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
393
+ }
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 parameters to the trait, with the self
400
+ // type appearing first.
401
+ // Find the first input type that either references a type parameter OR
402
+ // 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
+ }
391
417
}
418
+
419
+ // OK, found local type, all prior types upheld invariant.
420
+ return Ok ( ( ) ) ;
392
421
}
393
422
394
- // OK, found local type, all prior types upheld invariant.
395
- return Ok ( ( ) ) ;
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
+ }
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 )
435
+ }
436
+ }
437
+
438
+ fn is_uncovered_ty ( ty : Ty < ' _ > ) -> bool {
439
+ match ty. sty {
440
+ ty:: Bool |
441
+ ty:: Char |
442
+ ty:: Int ( ..) |
443
+ ty:: Uint ( ..) |
444
+ ty:: Float ( ..) |
445
+ ty:: Str |
446
+ ty:: FnDef ( ..) |
447
+ ty:: FnPtr ( _) |
448
+ ty:: Array ( ..) |
449
+ ty:: Slice ( ..) |
450
+ ty:: RawPtr ( ..) |
451
+ ty:: Ref ( ..) |
452
+ ty:: Never |
453
+ ty:: Tuple ( ..) |
454
+ ty:: Bound ( ..) |
455
+ ty:: Infer ( ..) |
456
+ ty:: Adt ( ..) |
457
+ ty:: Foreign ( ..) |
458
+ ty:: Dynamic ( ..) |
459
+ ty:: Error |
460
+ ty:: Projection ( ..) => {
461
+ false
462
+ }
463
+
464
+ ty:: Param ( ..) => {
465
+ true
396
466
}
397
467
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) ) ;
468
+ ty:: UnnormalizedProjection ( ..) |
469
+ ty:: Closure ( ..) |
470
+ ty:: Generator ( ..) |
471
+ ty:: GeneratorWitness ( ..) |
472
+ ty:: Opaque ( ..) => {
473
+ bug ! ( "is_uncovered_ty invoked on unexpected type: {:?}" , ty)
405
474
}
406
475
}
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
476
}
412
477
413
478
fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments