@@ -401,12 +401,12 @@ fn resolve_negative_obligation<'tcx>(
401401 infcx. resolve_regions ( & outlives_env) . is_empty ( )
402402}
403403
404+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
404405pub fn trait_ref_is_knowable < ' tcx > (
405406 tcx : TyCtxt < ' tcx > ,
406407 trait_ref : ty:: TraitRef < ' tcx > ,
407408) -> Result < ( ) , Conflict > {
408- debug ! ( "trait_ref_is_knowable(trait_ref={:?})" , trait_ref) ;
409- if orphan_check_trait_ref ( tcx, trait_ref, InCrate :: Remote ) . is_ok ( ) {
409+ if orphan_check_trait_ref ( trait_ref, InCrate :: Remote ) . is_ok ( ) {
410410 // A downstream or cousin crate is allowed to implement some
411411 // substitution of this trait-ref.
412412 return Err ( Conflict :: Downstream ) ;
@@ -429,11 +429,9 @@ pub fn trait_ref_is_knowable<'tcx>(
429429 // and if we are an intermediate owner, then we don't care
430430 // about future-compatibility, which means that we're OK if
431431 // we are an owner.
432- if orphan_check_trait_ref ( tcx, trait_ref, InCrate :: Local ) . is_ok ( ) {
433- debug ! ( "trait_ref_is_knowable: orphan check passed" ) ;
432+ if orphan_check_trait_ref ( trait_ref, InCrate :: Local ) . is_ok ( ) {
434433 Ok ( ( ) )
435434 } else {
436- debug ! ( "trait_ref_is_knowable: nonlocal, nonfundamental, unowned" ) ;
437435 Err ( Conflict :: Upstream )
438436 }
439437}
@@ -445,6 +443,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
445443 trait_ref. def_id . krate == LOCAL_CRATE || tcx. has_attr ( trait_ref. def_id , sym:: fundamental)
446444}
447445
446+ #[ derive( Debug ) ]
448447pub enum OrphanCheckErr < ' tcx > {
449448 NonLocalInputType ( Vec < ( Ty < ' tcx > , bool /* Is this the first input type? */ ) > ) ,
450449 UncoveredTy ( Ty < ' tcx > , Option < Ty < ' tcx > > ) ,
@@ -456,21 +455,20 @@ pub enum OrphanCheckErr<'tcx> {
456455///
457456/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
458457/// 2. Some local type must appear in `Self`.
458+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
459459pub fn orphan_check ( tcx : TyCtxt < ' _ > , impl_def_id : DefId ) -> Result < ( ) , OrphanCheckErr < ' _ > > {
460- debug ! ( "orphan_check({:?})" , impl_def_id) ;
461-
462460 // We only except this routine to be invoked on implementations
463461 // of a trait, not inherent implementations.
464462 let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . subst_identity ( ) ;
465- debug ! ( "orphan_check: trait_ref={:?}" , trait_ref) ;
463+ debug ! ( ? trait_ref) ;
466464
467465 // If the *trait* is local to the crate, ok.
468466 if trait_ref. def_id . is_local ( ) {
469467 debug ! ( "trait {:?} is local to current crate" , trait_ref. def_id) ;
470468 return Ok ( ( ) ) ;
471469 }
472470
473- orphan_check_trait_ref ( tcx , trait_ref, InCrate :: Local )
471+ orphan_check_trait_ref ( trait_ref, InCrate :: Local )
474472}
475473
476474/// Checks whether a trait-ref is potentially implementable by a crate.
@@ -559,21 +557,19 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
559557///
560558/// Note that this function is never called for types that have both type
561559/// parameters and inference variables.
560+ #[ instrument( level = "trace" , ret) ]
562561fn orphan_check_trait_ref < ' tcx > (
563- tcx : TyCtxt < ' tcx > ,
564562 trait_ref : ty:: TraitRef < ' tcx > ,
565563 in_crate : InCrate ,
566564) -> Result < ( ) , OrphanCheckErr < ' tcx > > {
567- debug ! ( "orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})" , trait_ref, in_crate) ;
568-
569565 if trait_ref. needs_infer ( ) && trait_ref. needs_subst ( ) {
570566 bug ! (
571567 "can't orphan check a trait ref with both params and inference variables {:?}" ,
572568 trait_ref
573569 ) ;
574570 }
575571
576- let mut checker = OrphanChecker :: new ( tcx , in_crate) ;
572+ let mut checker = OrphanChecker :: new ( in_crate) ;
577573 match trait_ref. visit_with ( & mut checker) {
578574 ControlFlow :: Continue ( ( ) ) => Err ( OrphanCheckErr :: NonLocalInputType ( checker. non_local_tys ) ) ,
579575 ControlFlow :: Break ( OrphanCheckEarlyExit :: ParamTy ( ty) ) => {
@@ -592,7 +588,6 @@ fn orphan_check_trait_ref<'tcx>(
592588}
593589
594590struct OrphanChecker < ' tcx > {
595- tcx : TyCtxt < ' tcx > ,
596591 in_crate : InCrate ,
597592 in_self_ty : bool ,
598593 /// Ignore orphan check failures and exclusively search for the first
@@ -602,9 +597,8 @@ struct OrphanChecker<'tcx> {
602597}
603598
604599impl < ' tcx > OrphanChecker < ' tcx > {
605- fn new ( tcx : TyCtxt < ' tcx > , in_crate : InCrate ) -> Self {
600+ fn new ( in_crate : InCrate ) -> Self {
606601 OrphanChecker {
607- tcx,
608602 in_crate,
609603 in_self_ty : true ,
610604 search_first_local_ty : false ,
@@ -697,13 +691,17 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
697691 }
698692 }
699693 ty:: Error ( _) => ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty) ) ,
700- ty:: Closure ( ..) | ty:: Generator ( .. ) | ty :: GeneratorWitness ( ..) => {
701- self . tcx . sess . delay_span_bug (
702- DUMMY_SP ,
703- format ! ( "ty_is_local invoked on closure or generator: {:?}" , ty ) ,
704- ) ;
705- ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty ) )
694+ ty:: Closure ( did , ..) | ty:: Generator ( did , ..) => {
695+ if self . def_id_is_local ( did ) {
696+ ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty ) )
697+ } else {
698+ self . found_non_local_ty ( ty )
699+ }
706700 }
701+ // This should only be created when checking whether we have to check whether some
702+ // auto trait impl applies. There will never be multiple impls, so we can just
703+ // act as if it were a local type here.
704+ ty:: GeneratorWitness ( _) => ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty) ) ,
707705 ty:: Alias ( ty:: Opaque , ..) => {
708706 // This merits some explanation.
709707 // Normally, opaque types are not involved when performing
0 commit comments