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
@@ -770,16 +772,24 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
770772 ty:: RawPtr ( tm) => ty:: RawPtr ( tm. fold_with ( folder) ?) ,
771773 ty:: Array ( typ, sz) => ty:: Array ( typ. fold_with ( folder) ?, sz. fold_with ( folder) ?) ,
772774 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+ }
776783 ty:: Tuple ( ts) => ty:: Tuple ( ts. fold_with ( folder) ?) ,
777784 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 ) ?)
779786 }
780787 ty:: FnPtr ( f) => ty:: FnPtr ( f. fold_with ( folder) ?) ,
781788 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 )
783793 }
784794 ty:: Generator ( did, substs, movability) => {
785795 ty:: Generator (
@@ -864,9 +874,31 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
864874 }
865875}
866876
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)
870902 }
871903}
872904
@@ -876,9 +908,45 @@ BraceStructTypeFoldableImpl! {
876908 }
877909}
878910
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)
882950 }
883951}
884952
0 commit comments