@@ -344,43 +344,108 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt<'_, '_, '_>,
344
344
trait_ref) ;
345
345
}
346
346
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
+ }
364
390
}
391
+
392
+ // OK, found local type, all prior types upheld invariant.
393
+ return Ok ( ( ) ) ;
365
394
}
366
395
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
369
439
}
370
440
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)
378
447
}
379
448
}
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 ) ;
384
449
}
385
450
386
451
fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ty : Ty < ' tcx > , in_crate : InCrate )
0 commit comments