@@ -401,12 +401,12 @@ fn resolve_negative_obligation<'tcx>(
401
401
infcx. resolve_regions ( & outlives_env) . is_empty ( )
402
402
}
403
403
404
+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
404
405
pub fn trait_ref_is_knowable < ' tcx > (
405
406
tcx : TyCtxt < ' tcx > ,
406
407
trait_ref : ty:: TraitRef < ' tcx > ,
407
408
) -> 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 ( ) {
410
410
// A downstream or cousin crate is allowed to implement some
411
411
// substitution of this trait-ref.
412
412
return Err ( Conflict :: Downstream ) ;
@@ -429,11 +429,9 @@ pub fn trait_ref_is_knowable<'tcx>(
429
429
// and if we are an intermediate owner, then we don't care
430
430
// about future-compatibility, which means that we're OK if
431
431
// 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 ( ) {
434
433
Ok ( ( ) )
435
434
} else {
436
- debug ! ( "trait_ref_is_knowable: nonlocal, nonfundamental, unowned" ) ;
437
435
Err ( Conflict :: Upstream )
438
436
}
439
437
}
@@ -445,6 +443,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
445
443
trait_ref. def_id . krate == LOCAL_CRATE || tcx. has_attr ( trait_ref. def_id , sym:: fundamental)
446
444
}
447
445
446
+ #[ derive( Debug ) ]
448
447
pub enum OrphanCheckErr < ' tcx > {
449
448
NonLocalInputType ( Vec < ( Ty < ' tcx > , bool /* Is this the first input type? */ ) > ) ,
450
449
UncoveredTy ( Ty < ' tcx > , Option < Ty < ' tcx > > ) ,
@@ -456,21 +455,20 @@ pub enum OrphanCheckErr<'tcx> {
456
455
///
457
456
/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
458
457
/// 2. Some local type must appear in `Self`.
458
+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
459
459
pub fn orphan_check ( tcx : TyCtxt < ' _ > , impl_def_id : DefId ) -> Result < ( ) , OrphanCheckErr < ' _ > > {
460
- debug ! ( "orphan_check({:?})" , impl_def_id) ;
461
-
462
460
// We only except this routine to be invoked on implementations
463
461
// of a trait, not inherent implementations.
464
462
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) ;
466
464
467
465
// If the *trait* is local to the crate, ok.
468
466
if trait_ref. def_id . is_local ( ) {
469
467
debug ! ( "trait {:?} is local to current crate" , trait_ref. def_id) ;
470
468
return Ok ( ( ) ) ;
471
469
}
472
470
473
- orphan_check_trait_ref ( tcx , trait_ref, InCrate :: Local )
471
+ orphan_check_trait_ref ( trait_ref, InCrate :: Local )
474
472
}
475
473
476
474
/// 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
559
557
///
560
558
/// Note that this function is never called for types that have both type
561
559
/// parameters and inference variables.
560
+ #[ instrument( level = "trace" , ret) ]
562
561
fn orphan_check_trait_ref < ' tcx > (
563
- tcx : TyCtxt < ' tcx > ,
564
562
trait_ref : ty:: TraitRef < ' tcx > ,
565
563
in_crate : InCrate ,
566
564
) -> Result < ( ) , OrphanCheckErr < ' tcx > > {
567
- debug ! ( "orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})" , trait_ref, in_crate) ;
568
-
569
565
if trait_ref. needs_infer ( ) && trait_ref. needs_subst ( ) {
570
566
bug ! (
571
567
"can't orphan check a trait ref with both params and inference variables {:?}" ,
572
568
trait_ref
573
569
) ;
574
570
}
575
571
576
- let mut checker = OrphanChecker :: new ( tcx , in_crate) ;
572
+ let mut checker = OrphanChecker :: new ( in_crate) ;
577
573
match trait_ref. visit_with ( & mut checker) {
578
574
ControlFlow :: Continue ( ( ) ) => Err ( OrphanCheckErr :: NonLocalInputType ( checker. non_local_tys ) ) ,
579
575
ControlFlow :: Break ( OrphanCheckEarlyExit :: ParamTy ( ty) ) => {
@@ -592,7 +588,6 @@ fn orphan_check_trait_ref<'tcx>(
592
588
}
593
589
594
590
struct OrphanChecker < ' tcx > {
595
- tcx : TyCtxt < ' tcx > ,
596
591
in_crate : InCrate ,
597
592
in_self_ty : bool ,
598
593
/// Ignore orphan check failures and exclusively search for the first
@@ -602,9 +597,8 @@ struct OrphanChecker<'tcx> {
602
597
}
603
598
604
599
impl < ' tcx > OrphanChecker < ' tcx > {
605
- fn new ( tcx : TyCtxt < ' tcx > , in_crate : InCrate ) -> Self {
600
+ fn new ( in_crate : InCrate ) -> Self {
606
601
OrphanChecker {
607
- tcx,
608
602
in_crate,
609
603
in_self_ty : true ,
610
604
search_first_local_ty : false ,
@@ -697,13 +691,17 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
697
691
}
698
692
}
699
693
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
+ }
706
700
}
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) ) ,
707
705
ty:: Alias ( ty:: Opaque , ..) => {
708
706
// This merits some explanation.
709
707
// Normally, opaque types are not involved when performing
0 commit comments