@@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
237237}
238238
239239pub enum OrphanCheckErr < ' tcx > {
240- NoLocalInputType ,
240+ NonLocalInputType ( Vec < ( Ty < ' tcx > , bool /* Is this the first input type? */ ) > ) ,
241241 UncoveredTy ( Ty < ' tcx > ) ,
242242}
243243
@@ -355,7 +355,7 @@ pub fn orphan_check(
355355/// Note that this function is never called for types that have both type
356356/// parameters and inference variables.
357357fn orphan_check_trait_ref < ' tcx > (
358- tcx : TyCtxt < ' _ > ,
358+ tcx : TyCtxt < ' tcx > ,
359359 trait_ref : ty:: TraitRef < ' tcx > ,
360360 in_crate : InCrate ,
361361) -> Result < ( ) , OrphanCheckErr < ' tcx > > {
@@ -378,40 +378,51 @@ fn orphan_check_trait_ref<'tcx>(
378378 // Let Ti be the first such type.
379379 // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
380380 //
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 > ,
384384 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 ( ) {
387387 ty. walk_shallow ( ) . flat_map ( |ty| uncover_fundamental_ty ( tcx, ty, in_crate) ) . collect ( )
388388 } else {
389389 vec ! [ ty]
390390 }
391391 }
392392
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 ( )
395398 {
396399 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 ( ) {
398402 debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
399403 return Ok ( ( ) ) ;
400404 } else if let ty:: Param ( _) = input_ty. kind {
401405 debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
402406 return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
403407 }
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+ }
404413 }
405414 // If we exit above loop, never found a local type.
406415 debug ! ( "orphan_check_trait_ref: no local type" ) ;
407- Err ( OrphanCheckErr :: NoLocalInputType )
416+ Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans ) )
408417 } else {
418+ let mut non_local_spans = vec ! [ ] ;
409419 // First, create an ordered iterator over all the type
410420 // parameters to the trait, with the self type appearing
411421 // first. Find the first input type that either references a
412422 // 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 ( ) {
415426 debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
416427
417428 // First local input type. Check that there are no
@@ -438,15 +449,21 @@ fn orphan_check_trait_ref<'tcx>(
438449 debug ! ( "orphan_check_trait_ref: uncovered type `{:?}`" , param) ;
439450 return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
440451 }
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+ }
441458 }
442459 // If we exit above loop, never found a local type.
443460 debug ! ( "orphan_check_trait_ref: no local type" ) ;
444- Err ( OrphanCheckErr :: NoLocalInputType )
461+ Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans ) )
445462 }
446463}
447464
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 ( ) {
450467 vec ! [ ]
451468 } else if fundamental_ty ( ty) {
452469 ty. walk_shallow ( )
@@ -464,9 +481,23 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
464481 }
465482}
466483
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+ }
470501}
471502
472503fn fundamental_ty ( ty : Ty < ' _ > ) -> bool {
@@ -486,8 +517,12 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
486517 }
487518}
488519
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) ;
491526
492527 match ty. kind {
493528 ty:: Bool |
@@ -506,37 +541,49 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
506541 ty:: Tuple ( ..) |
507542 ty:: Param ( ..) |
508543 ty:: Projection ( ..) => {
509- false
544+ Some ( ty )
510545 }
511546
512547 ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) => match in_crate {
513- InCrate :: Local => false ,
548+ InCrate :: Local => Some ( ty ) ,
514549 // The inference variable might be unified with a local
515550 // type in that remote crate.
516- InCrate :: Remote => true ,
551+ InCrate :: Remote => None ,
517552 } ,
518553
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+ } ,
521564 ty:: Opaque ( did, _) => {
522565 // Check the underlying type that this opaque
523566 // type resolves to.
524567 // This recursion will eventually terminate,
525568 // since we've already managed to successfully
526569 // resolve all opaque types by this point
527570 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)
529572 }
530573
531574 ty:: Dynamic ( ref tt, ..) => {
532575 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+ }
534581 } else {
535- false
582+ Some ( ty )
536583 }
537584 }
538585
539- ty:: Error => true ,
586+ ty:: Error => None ,
540587
541588 ty:: UnnormalizedProjection ( ..) |
542589 ty:: Closure ( ..) |
0 commit comments