33//! hand, though we've recently added some macros (e.g.,
44//! `BraceStructLiftImpl!`) to help with the tedium.
55
6+ use crate :: hir;
67use crate :: mir:: ProjectionKind ;
78use crate :: mir:: interpret:: ConstValue ;
89use crate :: ty:: { self , Lift , Ty , TyCtxt } ;
@@ -12,6 +13,7 @@ use smallvec::SmallVec;
1213use crate :: mir:: interpret;
1314
1415use std:: rc:: Rc ;
16+ use std:: iter;
1517
1618///////////////////////////////////////////////////////////////////////////
1719// Atomic structs
@@ -764,16 +766,24 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
764766 ty:: RawPtr ( tm) => ty:: RawPtr ( tm. fold_with ( folder) ?) ,
765767 ty:: Array ( typ, sz) => ty:: Array ( typ. fold_with ( folder) ?, sz. fold_with ( folder) ?) ,
766768 ty:: Slice ( typ) => ty:: Slice ( typ. fold_with ( folder) ?) ,
767- ty:: Adt ( tid, substs) => ty:: Adt ( tid, substs. fold_with ( folder) ?) ,
768- ty:: Dynamic ( ref trait_ty, ref region) =>
769- ty:: Dynamic ( trait_ty. fold_with ( folder) ?, region. fold_with ( folder) ?) ,
769+ ty:: Adt ( tid, substs) => {
770+ ty:: Adt ( tid, folder. fold_item_substs ( tid. did , substs) ?)
771+ }
772+ ty:: Dynamic ( ref trait_ty, ref region) => {
773+ let principal = trait_ty. fold_with ( folder) ?;
774+ let region_bound = folder. fold_with_variance ( ty:: Contravariant , region) ?;
775+ ty:: Dynamic ( principal, region_bound)
776+ }
770777 ty:: Tuple ( ts) => ty:: Tuple ( ts. fold_with ( folder) ?) ,
771778 ty:: FnDef ( def_id, substs) => {
772- ty:: FnDef ( def_id, substs . fold_with ( folder ) ?)
779+ ty:: FnDef ( def_id, folder . fold_item_substs ( def_id , substs ) ?)
773780 }
774781 ty:: FnPtr ( f) => ty:: FnPtr ( f. fold_with ( folder) ?) ,
775782 ty:: Ref ( ref r, ty, mutbl) => {
776- ty:: Ref ( r. fold_with ( folder) ?, ty. fold_with ( folder) ?, mutbl)
783+ let r = folder. fold_with_variance ( ty:: Contravariant , r) ?;
784+ // Fold the type as a TypeAndMut to get the correct variance.
785+ let mt = ty:: TypeAndMut { ty, mutbl } . fold_with ( folder) ?;
786+ ty:: Ref ( r, mt. ty , mt. mutbl )
777787 }
778788 ty:: Generator ( did, substs, movability) => {
779789 ty:: Generator (
@@ -858,9 +868,31 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
858868 }
859869}
860870
861- BraceStructTypeFoldableImpl ! {
862- impl <' tcx> TypeFoldable <' tcx> for ty:: TypeAndMut <' tcx> {
863- ty, mutbl
871+
872+
873+ impl < ' tcx > TypeFoldable < ' tcx > for ty:: TypeAndMut < ' tcx > {
874+ fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F )
875+ -> Result < Self , F :: Error >
876+ {
877+ let ty:: TypeAndMut { ty, mutbl } = self ;
878+ let variance = match mutbl {
879+ hir:: Mutability :: MutImmutable => ty:: Covariant ,
880+ hir:: Mutability :: MutMutable => ty:: Invariant ,
881+ } ;
882+
883+ Ok ( ty:: TypeAndMut {
884+ ty : folder. fold_with_variance ( variance, ty) ?,
885+ mutbl : mutbl. fold_with ( folder) ?,
886+ } )
887+ }
888+
889+ fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V )
890+ -> Result < ( ) , V :: Error >
891+ {
892+ let ty:: TypeAndMut { ty, mutbl } = self ;
893+
894+ ty. visit_with ( visitor) ?;
895+ mutbl. visit_with ( visitor)
864896 }
865897}
866898
@@ -870,9 +902,45 @@ BraceStructTypeFoldableImpl! {
870902 }
871903}
872904
873- BraceStructTypeFoldableImpl ! {
874- impl <' tcx> TypeFoldable <' tcx> for ty:: FnSig <' tcx> {
875- inputs_and_output, variadic, unsafety, abi
905+ impl < ' tcx > TypeFoldable < ' tcx > for ty:: FnSig < ' tcx > {
906+ fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F )
907+ -> Result < Self , F :: Error >
908+ {
909+ let ty:: FnSig { inputs_and_output, variadic, unsafety, abi } = self ;
910+
911+ let inputs_and_output = if folder. use_variances ( ) {
912+ let inputs_and_output = self . inputs ( ) . iter ( ) . cloned ( )
913+ . map ( |x| ( x, false ) )
914+ . chain ( iter:: once ( ( self . output ( ) , true ) ) )
915+ . map ( |( a, is_output) | {
916+ if is_output {
917+ a. fold_with ( folder)
918+ } else {
919+ folder. fold_with_variance ( ty:: Contravariant , & a)
920+ }
921+ } ) . collect :: < Result < SmallVec < [ _ ; 8 ] > , _ > > ( ) ?;
922+ folder. tcx ( ) . intern_type_list ( & inputs_and_output)
923+ } else {
924+ folder. fold_with_variance ( ty:: Invariant , inputs_and_output) ?
925+ } ;
926+
927+ Ok ( ty:: FnSig {
928+ inputs_and_output,
929+ variadic : * variadic,
930+ unsafety : * unsafety,
931+ abi : * abi,
932+ } )
933+ }
934+
935+ fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V )
936+ -> Result < ( ) , V :: Error >
937+ {
938+ let ty:: FnSig { inputs_and_output, variadic, unsafety, abi } = self ;
939+
940+ inputs_and_output. visit_with ( visitor) ?;
941+ variadic. visit_with ( visitor) ?;
942+ unsafety. visit_with ( visitor) ?;
943+ abi. visit_with ( visitor)
876944 }
877945}
878946
0 commit comments