@@ -237,7 +237,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
237237}
238238
239239pub enum OrphanCheckErr < ' tcx > {
240- NonLocalInputType ( Vec < ( Ty < ' tcx > , usize ) > ) ,
240+ NonLocalInputType ( Vec < ( Ty < ' tcx > , bool ) > ) ,
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 > > {
@@ -397,14 +397,19 @@ fn orphan_check_trait_ref<'tcx>(
397397 . enumerate ( )
398398 {
399399 debug ! ( "orphan_check_trait_ref: check ty `{:?}`" , input_ty) ;
400- 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 ( ) {
401402 debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
402403 return Ok ( ( ) ) ;
403404 } else if let ty:: Param ( _) = input_ty. kind {
404405 debug ! ( "orphan_check_trait_ref: uncovered ty: `{:?}`" , input_ty) ;
405406 return Err ( OrphanCheckErr :: UncoveredTy ( input_ty) )
406407 }
407- non_local_spans. push ( ( input_ty, i) ) ;
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+ }
408413 }
409414 // If we exit above loop, never found a local type.
410415 debug ! ( "orphan_check_trait_ref: no local type" ) ;
@@ -416,7 +421,8 @@ fn orphan_check_trait_ref<'tcx>(
416421 // first. Find the first input type that either references a
417422 // type parameter OR some local type.
418423 for ( i, input_ty) in trait_ref. input_types ( ) . enumerate ( ) {
419- if ty_is_local ( tcx, input_ty, in_crate) {
424+ let non_local_tys = ty_is_non_local ( tcx, input_ty, in_crate) ;
425+ if non_local_tys. is_none ( ) {
420426 debug ! ( "orphan_check_trait_ref: ty_is_local `{:?}`" , input_ty) ;
421427
422428 // First local input type. Check that there are no
@@ -444,16 +450,20 @@ fn orphan_check_trait_ref<'tcx>(
444450 return Err ( OrphanCheckErr :: UncoveredTy ( param) ) ;
445451 }
446452
447- non_local_spans. push ( ( input_ty, i) ) ;
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+ }
448458 }
449459 // If we exit above loop, never found a local type.
450460 debug ! ( "orphan_check_trait_ref: no local type" ) ;
451461 Err ( OrphanCheckErr :: NonLocalInputType ( non_local_spans) )
452462 }
453463}
454464
455- fn uncovered_tys < ' tcx > ( tcx : TyCtxt < ' _ > , ty : Ty < ' tcx > , in_crate : InCrate ) -> Vec < Ty < ' tcx > > {
456- 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 ( ) {
457467 vec ! [ ]
458468 } else if fundamental_ty ( ty) {
459469 ty. walk_shallow ( )
@@ -471,9 +481,23 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
471481 }
472482}
473483
474- fn ty_is_local ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > , in_crate : InCrate ) -> bool {
475- ty_is_local_constructor ( tcx, ty, in_crate) ||
476- 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+ }
477501}
478502
479503fn fundamental_ty ( ty : Ty < ' _ > ) -> bool {
@@ -493,8 +517,12 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool {
493517 }
494518}
495519
496- fn ty_is_local_constructor ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > , in_crate : InCrate ) -> bool {
497- 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) ;
498526
499527 match ty. kind {
500528 ty:: Bool |
@@ -513,37 +541,49 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
513541 ty:: Tuple ( ..) |
514542 ty:: Param ( ..) |
515543 ty:: Projection ( ..) => {
516- false
544+ Some ( ty )
517545 }
518546
519547 ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) => match in_crate {
520- InCrate :: Local => false ,
548+ InCrate :: Local => Some ( ty ) ,
521549 // The inference variable might be unified with a local
522550 // type in that remote crate.
523- InCrate :: Remote => true ,
551+ InCrate :: Remote => None ,
524552 } ,
525553
526- ty:: Adt ( def, _) => def_id_is_local ( def. did , in_crate) ,
527- 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+ } ,
528564 ty:: Opaque ( did, _) => {
529565 // Check the underlying type that this opaque
530566 // type resolves to.
531567 // This recursion will eventually terminate,
532568 // since we've already managed to successfully
533569 // resolve all opaque types by this point
534570 let real_ty = tcx. type_of ( did) ;
535- ty_is_local_constructor ( tcx, real_ty, in_crate)
571+ ty_is_non_local_constructor ( tcx, real_ty, in_crate)
536572 }
537573
538574 ty:: Dynamic ( ref tt, ..) => {
539575 if let Some ( principal) = tt. principal ( ) {
540- 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+ }
541581 } else {
542- false
582+ Some ( ty )
543583 }
544584 }
545585
546- ty:: Error => true ,
586+ ty:: Error => None ,
547587
548588 ty:: UnnormalizedProjection ( ..) |
549589 ty:: Closure ( ..) |
0 commit comments