3
3
//! hand, though we've recently added some macros (e.g.,
4
4
//! `BraceStructLiftImpl!`) to help with the tedium.
5
5
6
+ use crate :: hir;
6
7
use crate :: mir:: ProjectionKind ;
7
8
use crate :: mir:: interpret:: ConstValue ;
8
9
use crate :: ty:: { self , Lift , Ty , TyCtxt } ;
@@ -12,6 +13,7 @@ use smallvec::SmallVec;
12
13
use crate :: mir:: interpret;
13
14
14
15
use std:: rc:: Rc ;
16
+ use std:: iter;
15
17
16
18
///////////////////////////////////////////////////////////////////////////
17
19
// Atomic structs
@@ -770,16 +772,24 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
770
772
ty:: RawPtr ( tm) => ty:: RawPtr ( tm. fold_with ( folder) ?) ,
771
773
ty:: Array ( typ, sz) => ty:: Array ( typ. fold_with ( folder) ?, sz. fold_with ( folder) ?) ,
772
774
ty:: Slice ( typ) => ty:: Slice ( typ. fold_with ( folder) ?) ,
773
- ty:: Adt ( tid, substs) => ty:: Adt ( tid, substs. fold_with ( folder) ?) ,
774
- ty:: Dynamic ( ref trait_ty, ref region) =>
775
- ty:: Dynamic ( trait_ty. fold_with ( folder) ?, region. fold_with ( folder) ?) ,
775
+ ty:: Adt ( tid, substs) => {
776
+ ty:: Adt ( tid, folder. fold_item_substs ( tid. did , substs) ?)
777
+ }
778
+ ty:: Dynamic ( ref trait_ty, ref region) => {
779
+ let principal = trait_ty. fold_with ( folder) ?;
780
+ let region_bound = folder. fold_with_variance ( ty:: Contravariant , region) ?;
781
+ ty:: Dynamic ( principal, region_bound)
782
+ }
776
783
ty:: Tuple ( ts) => ty:: Tuple ( ts. fold_with ( folder) ?) ,
777
784
ty:: FnDef ( def_id, substs) => {
778
- ty:: FnDef ( def_id, substs . fold_with ( folder ) ?)
785
+ ty:: FnDef ( def_id, folder . fold_item_substs ( def_id , substs ) ?)
779
786
}
780
787
ty:: FnPtr ( f) => ty:: FnPtr ( f. fold_with ( folder) ?) ,
781
788
ty:: Ref ( ref r, ty, mutbl) => {
782
- ty:: Ref ( r. fold_with ( folder) ?, ty. fold_with ( folder) ?, mutbl)
789
+ let r = folder. fold_with_variance ( ty:: Contravariant , r) ?;
790
+ // Fold the type as a TypeAndMut to get the correct variance.
791
+ let mt = ty:: TypeAndMut { ty, mutbl } . fold_with ( folder) ?;
792
+ ty:: Ref ( r, mt. ty , mt. mutbl )
783
793
}
784
794
ty:: Generator ( did, substs, movability) => {
785
795
ty:: Generator (
@@ -864,9 +874,31 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
864
874
}
865
875
}
866
876
867
- BraceStructTypeFoldableImpl ! {
868
- impl <' tcx> TypeFoldable <' tcx> for ty:: TypeAndMut <' tcx> {
869
- ty, mutbl
877
+
878
+
879
+ impl < ' tcx > TypeFoldable < ' tcx > for ty:: TypeAndMut < ' tcx > {
880
+ fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F )
881
+ -> Result < Self , F :: Error >
882
+ {
883
+ let ty:: TypeAndMut { ty, mutbl } = self ;
884
+ let variance = match mutbl {
885
+ hir:: Mutability :: MutImmutable => ty:: Covariant ,
886
+ hir:: Mutability :: MutMutable => ty:: Invariant ,
887
+ } ;
888
+
889
+ Ok ( ty:: TypeAndMut {
890
+ ty : folder. fold_with_variance ( variance, ty) ?,
891
+ mutbl : mutbl. fold_with ( folder) ?,
892
+ } )
893
+ }
894
+
895
+ fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V )
896
+ -> Result < ( ) , V :: Error >
897
+ {
898
+ let ty:: TypeAndMut { ty, mutbl } = self ;
899
+
900
+ ty. visit_with ( visitor) ?;
901
+ mutbl. visit_with ( visitor)
870
902
}
871
903
}
872
904
@@ -876,9 +908,45 @@ BraceStructTypeFoldableImpl! {
876
908
}
877
909
}
878
910
879
- BraceStructTypeFoldableImpl ! {
880
- impl <' tcx> TypeFoldable <' tcx> for ty:: FnSig <' tcx> {
881
- inputs_and_output, c_variadic, unsafety, abi
911
+ impl < ' tcx > TypeFoldable < ' tcx > for ty:: FnSig < ' tcx > {
912
+ fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F )
913
+ -> Result < Self , F :: Error >
914
+ {
915
+ let ty:: FnSig { inputs_and_output, c_variadic, unsafety, abi } = self ;
916
+
917
+ let inputs_and_output = if folder. use_variances ( ) {
918
+ let inputs_and_output = self . inputs ( ) . iter ( ) . cloned ( )
919
+ . map ( |x| ( x, false ) )
920
+ . chain ( iter:: once ( ( self . output ( ) , true ) ) )
921
+ . map ( |( a, is_output) | {
922
+ if is_output {
923
+ a. fold_with ( folder)
924
+ } else {
925
+ folder. fold_with_variance ( ty:: Contravariant , & a)
926
+ }
927
+ } ) . collect :: < Result < SmallVec < [ _ ; 8 ] > , _ > > ( ) ?;
928
+ folder. tcx ( ) . intern_type_list ( & inputs_and_output)
929
+ } else {
930
+ folder. fold_with_variance ( ty:: Invariant , inputs_and_output) ?
931
+ } ;
932
+
933
+ Ok ( ty:: FnSig {
934
+ inputs_and_output,
935
+ c_variadic : * c_variadic,
936
+ unsafety : * unsafety,
937
+ abi : * abi,
938
+ } )
939
+ }
940
+
941
+ fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V )
942
+ -> Result < ( ) , V :: Error >
943
+ {
944
+ let ty:: FnSig { inputs_and_output, c_variadic, unsafety, abi } = self ;
945
+
946
+ inputs_and_output. visit_with ( visitor) ?;
947
+ c_variadic. visit_with ( visitor) ?;
948
+ unsafety. visit_with ( visitor) ?;
949
+ abi. visit_with ( visitor)
882
950
}
883
951
}
884
952
0 commit comments