@@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
237
237
}
238
238
239
239
pub enum OrphanCheckErr < ' tcx > {
240
- NoLocalInputType ,
240
+ NonLocalInputType ( Vec < ( Ty < ' tcx > , bool /* Is this the first input type? */ ) > ) ,
241
241
UncoveredTy ( Ty < ' tcx > ) ,
242
242
}
243
243
@@ -355,7 +355,7 @@ pub fn orphan_check(
355
355
/// Note that this function is never called for types that have both type
356
356
/// parameters and inference variables.
357
357
fn orphan_check_trait_ref < ' tcx > (
358
- tcx : TyCtxt < ' _ > ,
358
+ tcx : TyCtxt < ' tcx > ,
359
359
trait_ref : ty:: TraitRef < ' tcx > ,
360
360
in_crate : InCrate ,
361
361
) -> Result < ( ) , OrphanCheckErr < ' tcx > > {
@@ -378,40 +378,51 @@ fn orphan_check_trait_ref<'tcx>(
378
378
// Let Ti be the first such type.
379
379
// - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
380
380
//
381
- fn uncover_fundamental_ty < ' a > (
382
- tcx : TyCtxt < ' _ > ,
383
- ty : Ty < ' a > ,
381
+ fn uncover_fundamental_ty < ' tcx > (
382
+ tcx : TyCtxt < ' tcx > ,
383
+ ty : Ty < ' tcx > ,
384
384
in_crate : InCrate ,
385
- ) -> Vec < Ty < ' a > > {
386
- if fundamental_ty ( ty) && ! ty_is_local ( tcx, ty, in_crate) {
385
+ ) -> Vec < Ty < ' tcx > > {
386
+ if fundamental_ty ( ty) && ty_is_non_local ( tcx, ty, in_crate) . is_some ( ) {
387
387
ty. walk_shallow ( ) . flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) ) . collect ( )
388
388
} else {
389
389
vec ! [ ty]
390
390
}
391
391
}
392
392
393
- for input_ty in
394
- trait_ref. input_types ( ) . flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) )
393
+ let mut non_local_spans = vec ! [ ] ;
394
+ for ( i, input_ty) in trait_ref
395
+ . input_types ( )
396
+ . flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) )
397
+ . enumerate ( )
395
398
{
396
399
debug ! ( "orphan_check_trait_ref: check ty `{:?}`" , input_ty) ;
397
- if ty_is_local ( tcx, input_ty, in_crate) {
400
+ let non_local_tys = ty_is_non_local ( tcx, input_ty, in_crate) ;
401
+ if non_local_tys. is_none ( ) {
398
402
debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
399
403
return Ok ( ( ) ) ;
400
404
} else if let ty:: Param ( _) = input_ty. kind {
401
405
debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
402
406
return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
403
407
}
408
+ if let Some ( non_local_tys) = non_local_tys {
409
+ for input_ty in non_local_tys {
410
+ non_local_spans. push ( ( input_ty, i == 0 ) ) ;
411
+ }
412
+ }
404
413
}
405
414
// If we exit above loop, never found a local type.
406
415
debug ! ( "orphan_check_trait_ref: no local type" ) ;
407
- Err ( OrphanCheckErr :: NoLocalInputType )
416
+ Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans ) )
408
417
} else {
418
+ let mut non_local_spans = vec ! [ ] ;
409
419
// First, create an ordered iterator over all the type
410
420
// parameters to the trait, with the self type appearing
411
421
// first. Find the first input type that either references a
412
422
// type parameter OR some local type.
413
- for input_ty in trait_ref. input_types ( ) {
414
- if ty_is_local ( tcx, input_ty, in_crate) {
423
+ for ( i, input_ty) in trait_ref. input_types ( ) . enumerate ( ) {
424
+ let non_local_tys = ty_is_non_local ( tcx, input_ty, in_crate) ;
425
+ if non_local_tys. is_none ( ) {
415
426
debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
416
427
417
428
// First local input type. Check that there are no
@@ -438,15 +449,21 @@ fn orphan_check_trait_ref<'tcx>(
438
449
debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
439
450
return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
440
451
}
452
+
453
+ if let Some ( non_local_tys) = non_local_tys {
454
+ for input_ty in non_local_tys {
455
+ non_local_spans. push ( ( input_ty, i == 0 ) ) ;
456
+ }
457
+ }
441
458
}
442
459
// If we exit above loop, never found a local type.
443
460
debug ! ( "orphan_check_trait_ref: no local type" ) ;
444
- Err ( OrphanCheckErr :: NoLocalInputType )
461
+ Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans ) )
445
462
}
446
463
}
447
464
448
- fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ > , ty : Ty < ' tcx > , in_crate : InCrate ) -> Vec < Ty < ' tcx > > {
449
- if ty_is_local_constructor ( tcx, ty, in_crate) {
465
+ fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , in_crate : InCrate ) -> Vec < Ty < ' tcx > > {
466
+ if ty_is_non_local_constructor ( tcx, ty, in_crate) . is_none ( ) {
450
467
vec ! [ ]
451
468
} else if fundamental_ty ( ty) {
452
469
ty. walk_shallow ( )
@@ -464,9 +481,23 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
464
481
}
465
482
}
466
483
467
- fn ty_is_local ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > , in_crate : InCrate ) -> bool {
468
- ty_is_local_constructor ( tcx, ty, in_crate) ||
469
- fundamental_ty ( ty) && ty. walk_shallow ( ) . any ( |t| ty_is_local ( tcx, t, in_crate) )
484
+ fn ty_is_non_local < ' t > ( tcx : TyCtxt < ' t > , ty : Ty < ' t > , in_crate : InCrate ) -> Option < Vec < Ty < ' t > > > {
485
+ match ty_is_non_local_constructor ( tcx, ty, in_crate) {
486
+ Some ( ty) => if !fundamental_ty ( ty) {
487
+ Some ( vec ! [ ty] )
488
+ } else {
489
+ let tys: Vec < _ > = ty. walk_shallow ( )
490
+ . filter_map ( |t| ty_is_non_local ( tcx, t, in_crate) )
491
+ . flat_map ( |i| i)
492
+ . collect ( ) ;
493
+ if tys. is_empty ( ) {
494
+ None
495
+ } else {
496
+ Some ( tys)
497
+ }
498
+ } ,
499
+ None => None ,
500
+ }
470
501
}
471
502
472
503
fn fundamental_ty ( ty : Ty < ' _ > ) -> bool {
@@ -486,8 +517,12 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
486
517
}
487
518
}
488
519
489
- fn ty_is_local_constructor ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > , in_crate : InCrate ) -> bool {
490
- debug ! ( "ty_is_local_constructor({:?})" , ty) ;
520
+ fn ty_is_non_local_constructor < ' tcx > (
521
+ tcx : TyCtxt < ' tcx > ,
522
+ ty : Ty < ' tcx > ,
523
+ in_crate : InCrate ,
524
+ ) -> Option < Ty < ' tcx > > {
525
+ debug ! ( "ty_is_non_local_constructor({:?})" , ty) ;
491
526
492
527
match ty. kind {
493
528
ty:: Bool |
@@ -506,37 +541,49 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
506
541
ty:: Tuple ( ..) |
507
542
ty:: Param ( ..) |
508
543
ty:: Projection ( ..) => {
509
- false
544
+ Some ( ty )
510
545
}
511
546
512
547
ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) => match in_crate {
513
- InCrate :: Local => false ,
548
+ InCrate :: Local => Some ( ty ) ,
514
549
// The inference variable might be unified with a local
515
550
// type in that remote crate.
516
- InCrate :: Remote => true ,
551
+ InCrate :: Remote => None ,
517
552
} ,
518
553
519
- ty:: Adt ( def, _) => def_id_is_local ( def. did , in_crate) ,
520
- ty:: Foreign ( did) => def_id_is_local ( did, in_crate) ,
554
+ ty:: Adt ( def, _) => if def_id_is_local ( def. did , in_crate) {
555
+ None
556
+ } else {
557
+ Some ( ty)
558
+ } ,
559
+ ty:: Foreign ( did) => if def_id_is_local ( did, in_crate) {
560
+ None
561
+ } else {
562
+ Some ( ty)
563
+ } ,
521
564
ty:: Opaque ( did, _) => {
522
565
// Check the underlying type that this opaque
523
566
// type resolves to.
524
567
// This recursion will eventually terminate,
525
568
// since we've already managed to successfully
526
569
// resolve all opaque types by this point
527
570
let real_ty = tcx. type_of ( did) ;
528
- ty_is_local_constructor ( tcx, real_ty, in_crate)
571
+ ty_is_non_local_constructor ( tcx, real_ty, in_crate)
529
572
}
530
573
531
574
ty:: Dynamic ( ref tt, ..) => {
532
575
if let Some ( principal) = tt. principal ( ) {
533
- def_id_is_local ( principal. def_id ( ) , in_crate)
576
+ if def_id_is_local ( principal. def_id ( ) , in_crate) {
577
+ None
578
+ } else {
579
+ Some ( ty)
580
+ }
534
581
} else {
535
- false
582
+ Some ( ty )
536
583
}
537
584
}
538
585
539
- ty:: Error => true ,
586
+ ty:: Error => None ,
540
587
541
588
ty:: UnnormalizedProjection ( ..) |
542
589
ty:: Closure ( ..) |
0 commit comments