@@ -618,19 +618,20 @@ fn try_prove_negated_where_clause<'tcx>(
618
618
/// This both checks whether any downstream or sibling crates could
619
619
/// implement it and whether an upstream crate can add this impl
620
620
/// without breaking backwards compatibility.
621
- #[ instrument( level = "debug" , skip( tcx , lazily_normalize_ty) , ret) ]
621
+ #[ instrument( level = "debug" , skip( infcx , lazily_normalize_ty) , ret) ]
622
622
pub fn trait_ref_is_knowable < ' tcx , E : Debug > (
623
- tcx : TyCtxt < ' tcx > ,
623
+ infcx : & InferCtxt < ' tcx > ,
624
624
trait_ref : ty:: TraitRef < ' tcx > ,
625
625
mut lazily_normalize_ty : impl FnMut ( Ty < ' tcx > ) -> Result < Ty < ' tcx > , E > ,
626
626
) -> Result < Result < ( ) , Conflict > , E > {
627
- if orphan_check_trait_ref ( trait_ref, InCrate :: Remote , & mut lazily_normalize_ty) ?. is_ok ( ) {
627
+ if orphan_check_trait_ref ( infcx, trait_ref, InCrate :: Remote , & mut lazily_normalize_ty) ?. is_ok ( )
628
+ {
628
629
// A downstream or cousin crate is allowed to implement some
629
630
// generic parameters of this trait-ref.
630
631
return Ok ( Err ( Conflict :: Downstream ) ) ;
631
632
}
632
633
633
- if trait_ref_is_local_or_fundamental ( tcx, trait_ref) {
634
+ if trait_ref_is_local_or_fundamental ( infcx . tcx , trait_ref) {
634
635
// This is a local or fundamental trait, so future-compatibility
635
636
// is no concern. We know that downstream/cousin crates are not
636
637
// allowed to implement a generic parameter of this trait ref,
@@ -648,6 +649,7 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>(
648
649
// about future-compatibility, which means that we're OK if
649
650
// we are an owner.
650
651
if orphan_check_trait_ref (
652
+ infcx,
651
653
trait_ref,
652
654
InCrate :: Local { mode : OrphanCheckMode :: Proper } ,
653
655
& mut lazily_normalize_ty,
@@ -786,46 +788,41 @@ pub struct UncoveredTyParams<'tcx, T> {
786
788
///
787
789
/// Note that this function is never called for types that have both type
788
790
/// parameters and inference variables.
789
- #[ instrument( level = "trace" , skip( lazily_normalize_ty) , ret) ]
791
+ #[ instrument( level = "trace" , skip( infcx , lazily_normalize_ty) , ret) ]
790
792
pub fn orphan_check_trait_ref < ' tcx , E : Debug > (
793
+ infcx : & InferCtxt < ' tcx > ,
791
794
trait_ref : ty:: TraitRef < ' tcx > ,
792
795
in_crate : InCrate ,
793
796
lazily_normalize_ty : impl FnMut ( Ty < ' tcx > ) -> Result < Ty < ' tcx > , E > ,
794
797
) -> Result < Result < ( ) , OrphanCheckErr < ' tcx , Ty < ' tcx > > > , E > {
795
- if trait_ref. has_infer ( ) && trait_ref. has_param ( ) {
796
- bug ! (
797
- "can't orphan check a trait ref with both params and inference variables {:?}" ,
798
- trait_ref
799
- ) ;
798
+ if trait_ref. has_param ( ) {
799
+ bug ! ( "orphan check only expects inference variables: {trait_ref:?}" ) ;
800
800
}
801
801
802
- let mut checker = OrphanChecker :: new ( in_crate, lazily_normalize_ty) ;
803
-
804
- // Does there exist some local type after the `ParamTy`.
805
- let search_first_local_ty = |checker : & mut OrphanChecker < ' tcx , _ > | {
806
- checker. search_first_local_ty = true ;
807
- match trait_ref. visit_with ( checker) . break_value ( ) {
808
- Some ( OrphanCheckEarlyExit :: LocalTy ( local_ty) ) => Some ( local_ty) ,
809
- _ => None ,
810
- }
811
- } ;
812
-
802
+ let mut checker = OrphanChecker :: new ( infcx, in_crate, lazily_normalize_ty) ;
813
803
Ok ( match trait_ref. visit_with ( & mut checker) {
814
804
ControlFlow :: Continue ( ( ) ) => Err ( OrphanCheckErr :: NonLocalInputType ( checker. non_local_tys ) ) ,
815
805
ControlFlow :: Break ( residual) => match residual {
816
806
OrphanCheckEarlyExit :: NormalizationFailure ( err) => return Err ( err) ,
817
807
OrphanCheckEarlyExit :: UncoveredTyParam ( ty) => {
808
+ // Does there exist some local type after the `ParamTy`.
809
+ checker. search_first_local_ty = true ;
810
+ let local_ty = match trait_ref. visit_with ( & mut checker) . break_value ( ) {
811
+ Some ( OrphanCheckEarlyExit :: LocalTy ( local_ty) ) => Some ( local_ty) ,
812
+ _ => None ,
813
+ } ;
818
814
Err ( OrphanCheckErr :: UncoveredTyParams ( UncoveredTyParams {
819
815
uncovered : ty,
820
- local_ty : search_first_local_ty ( & mut checker ) ,
816
+ local_ty,
821
817
} ) )
822
818
}
823
819
OrphanCheckEarlyExit :: LocalTy ( _) => Ok ( ( ) ) ,
824
820
} ,
825
821
} )
826
822
}
827
823
828
- struct OrphanChecker < ' tcx , F > {
824
+ struct OrphanChecker < ' a , ' tcx , F > {
825
+ infcx : & ' a InferCtxt < ' tcx > ,
829
826
in_crate : InCrate ,
830
827
in_self_ty : bool ,
831
828
lazily_normalize_ty : F ,
@@ -834,12 +831,13 @@ struct OrphanChecker<'tcx, F> {
834
831
non_local_tys : Vec < ( Ty < ' tcx > , IsFirstInputType ) > ,
835
832
}
836
833
837
- impl < ' tcx , F , E > OrphanChecker < ' tcx , F >
834
+ impl < ' a , ' tcx , F , E > OrphanChecker < ' a , ' tcx , F >
838
835
where
839
836
F : FnOnce ( Ty < ' tcx > ) -> Result < Ty < ' tcx > , E > ,
840
837
{
841
- fn new ( in_crate : InCrate , lazily_normalize_ty : F ) -> Self {
838
+ fn new ( infcx : & ' a InferCtxt < ' tcx > , in_crate : InCrate , lazily_normalize_ty : F ) -> Self {
842
839
OrphanChecker {
840
+ infcx,
843
841
in_crate,
844
842
in_self_ty : true ,
845
843
lazily_normalize_ty,
@@ -878,7 +876,7 @@ enum OrphanCheckEarlyExit<'tcx, E> {
878
876
LocalTy ( Ty < ' tcx > ) ,
879
877
}
880
878
881
- impl < ' tcx , F , E > TypeVisitor < TyCtxt < ' tcx > > for OrphanChecker < ' tcx , F >
879
+ impl < ' a , ' tcx , F , E > TypeVisitor < TyCtxt < ' tcx > > for OrphanChecker < ' a , ' tcx , F >
882
880
where
883
881
F : FnMut ( Ty < ' tcx > ) -> Result < Ty < ' tcx > , E > ,
884
882
{
@@ -889,6 +887,7 @@ where
889
887
}
890
888
891
889
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> Self :: Result {
890
+ let ty = self . infcx . shallow_resolve ( ty) ;
892
891
let ty = match ( self . lazily_normalize_ty ) ( ty) {
893
892
Ok ( norm_ty) if norm_ty. is_ty_var ( ) => ty,
894
893
Ok ( norm_ty) => norm_ty,
@@ -1149,7 +1148,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
1149
1148
} ;
1150
1149
1151
1150
infcx. probe ( |_| {
1152
- match trait_ref_is_knowable ( infcx. tcx , trait_ref, lazily_normalize_ty) {
1151
+ match trait_ref_is_knowable ( infcx, trait_ref, lazily_normalize_ty) {
1153
1152
Err ( ( ) ) => { }
1154
1153
Ok ( Ok ( ( ) ) ) => warn ! ( "expected an unknowable trait ref: {trait_ref:?}" ) ,
1155
1154
Ok ( Err ( conflict) ) => {
0 commit comments