@@ -2902,48 +2902,23 @@ CanSILFunctionType swift::getNativeSILFunctionType(
2902
2902
// / Build a generic signature and environment for a re-abstraction thunk.
2903
2903
// /
2904
2904
// / Most thunks share the generic environment with their original function.
2905
- // / The one exception is if the thunk type involves an open existential,
2906
- // / in which case we "promote" the opened existential to a new generic parameter.
2907
- // /
2908
- // / \param localArchetypes - the list of local archetypes to promote
2909
- // / into the signature, if any
2910
- // / \param genericEnv - the new generic environment
2911
- // / \param contextSubs - map non-local archetypes from the original function
2912
- // / to archetypes in the thunk
2913
- // / \param interfaceSubs - map interface types to old archetypes
2905
+ // / The one exception is if the thunk type involves local archetypes,
2906
+ // / in which case we "promote" the local archetypes to new generic parameters.
2914
2907
static CanGenericSignature
2915
2908
buildThunkSignature (SILFunction *fn,
2916
- ArrayRef<CanLocalArchetypeType> localArchetypes,
2909
+ CanGenericSignature baseGenericSig,
2910
+ ArrayRef<GenericEnvironment *> capturedEnvs,
2917
2911
GenericEnvironment *&genericEnv,
2918
- SubstitutionMap &contextSubs,
2919
- SubstitutionMap &interfaceSubs,
2920
- llvm::DenseMap<ArchetypeType*, Type> &contextLocalArchetypes) {
2921
- auto *mod = fn->getModule ().getSwiftModule ();
2922
- auto &ctx = mod->getASTContext ();
2912
+ SubstitutionMap &interfaceSubs) {
2913
+ auto &ctx = fn->getASTContext ();
2923
2914
auto forwardingSubs = fn->getForwardingSubstitutionMap ();
2924
2915
2925
2916
// If there are no local archetypes, we just inherit the generic
2926
2917
// environment from the parent function.
2927
- if (localArchetypes.empty ()) {
2928
- auto genericSig =
2929
- fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
2918
+ if (capturedEnvs.empty ()) {
2930
2919
genericEnv = fn->getGenericEnvironment ();
2931
2920
interfaceSubs = forwardingSubs;
2932
- contextSubs = interfaceSubs;
2933
- return genericSig;
2934
- }
2935
-
2936
- // Get the existing generic signature.
2937
- auto baseGenericSig =
2938
- fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
2939
-
2940
- SmallVector<GenericEnvironment *, 2 > capturedEnvs;
2941
- for (auto archetype : localArchetypes) {
2942
- auto *genericEnv = archetype->getGenericEnvironment ();
2943
- if (std::find (capturedEnvs.begin (), capturedEnvs.end (), genericEnv)
2944
- == capturedEnvs.end ()) {
2945
- capturedEnvs.push_back (genericEnv);
2946
- }
2921
+ return baseGenericSig;
2947
2922
}
2948
2923
2949
2924
auto genericSig = buildGenericSignatureWithCapturedEnvironments (
@@ -2952,44 +2927,11 @@ buildThunkSignature(SILFunction *fn,
2952
2927
2953
2928
genericEnv = genericSig.getGenericEnvironment ();
2954
2929
2955
- MapLocalArchetypesOutOfContext mapOutOfContext (baseGenericSig, capturedEnvs);
2956
-
2957
- // Map the local archetypes to their new parameter types.
2958
- for (auto localArchetype : localArchetypes) {
2959
- auto thunkInterfaceType = Type (localArchetype).subst (
2960
- mapOutOfContext,
2961
- MakeAbstractConformanceForGenericType (),
2962
- SubstFlags::PreservePackExpansionLevel |
2963
- SubstFlags::SubstituteLocalArchetypes);
2964
- auto thunkArchetype = genericEnv->mapTypeIntoContext (
2965
- thunkInterfaceType);
2966
- contextLocalArchetypes.insert (std::make_pair (localArchetype,
2967
- thunkArchetype));
2968
- }
2969
-
2970
- // Calculate substitutions to map the caller's archetypes to the thunk's
2971
- // archetypes.
2972
- if (auto calleeGenericSig = fn->getLoweredFunctionType ()
2973
- ->getInvocationGenericSignature ()) {
2974
- contextSubs = SubstitutionMap::get (
2975
- calleeGenericSig,
2976
- genericEnv->getForwardingSubstitutionMap ());
2977
- }
2978
-
2979
2930
// Calculate substitutions to map interface types to the caller's archetypes.
2980
2931
interfaceSubs = buildSubstitutionMapWithCapturedEnvironments (
2981
2932
forwardingSubs, genericSig, capturedEnvs);
2982
2933
LLVM_DEBUG (llvm::dbgs () << " Thunk substitution map: " << interfaceSubs << " \n " );
2983
2934
2984
- for (auto pair : contextLocalArchetypes) {
2985
- auto substArchetype = Type (pair.second ).subst (interfaceSubs);
2986
- if (!pair.first ->isEqual (substArchetype)) {
2987
- llvm::errs () << " Expected: " ; pair.first ->dump (llvm::errs ());
2988
- llvm::errs () << " Got: " ; substArchetype->dump (llvm::errs ());
2989
- abort ();
2990
- }
2991
- }
2992
-
2993
2935
return genericSig.getCanonicalSignature ();
2994
2936
}
2995
2937
@@ -3026,12 +2968,14 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
3026
2968
extInfoBuilder = extInfoBuilder.withNoEscape (false );
3027
2969
3028
2970
// Does the thunk type involve a local archetype type?
3029
- SmallVector<CanLocalArchetypeType, 8 > localArchetypes ;
2971
+ SmallVector<GenericEnvironment *, 2 > capturedEnvs ;
3030
2972
auto archetypeVisitor = [&](CanType t) {
3031
2973
if (auto local = dyn_cast<LocalArchetypeType>(t)) {
3032
- auto root = local.getRoot ();
3033
- if (llvm::find (localArchetypes, root) == localArchetypes.end ())
3034
- localArchetypes.push_back (root);
2974
+ auto *genericEnv = local->getGenericEnvironment ();
2975
+ if (std::find (capturedEnvs.begin (), capturedEnvs.end (), genericEnv)
2976
+ == capturedEnvs.end ()) {
2977
+ capturedEnvs.push_back (genericEnv);
2978
+ }
3035
2979
}
3036
2980
};
3037
2981
@@ -3043,57 +2987,42 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
3043
2987
// Use the generic signature from the context if the thunk involves
3044
2988
// generic parameters.
3045
2989
CanGenericSignature genericSig;
3046
- SubstitutionMap contextSubs;
3047
- llvm::DenseMap<ArchetypeType*, Type> contextLocalArchetypes;
2990
+ CanGenericSignature baseGenericSig;
3048
2991
3049
- if (!localArchetypes .empty () ||
2992
+ if (!capturedEnvs .empty () ||
3050
2993
expectedType->hasPrimaryArchetype () ||
3051
2994
sourceType->hasPrimaryArchetype ()) {
2995
+ // Get the existing generic signature.
2996
+ baseGenericSig = fn->getLoweredFunctionType ()
2997
+ ->getInvocationGenericSignature ();
2998
+
3052
2999
genericSig = buildThunkSignature (fn,
3053
- localArchetypes,
3000
+ baseGenericSig,
3001
+ capturedEnvs,
3054
3002
genericEnv,
3055
- contextSubs,
3056
- interfaceSubs,
3057
- contextLocalArchetypes);
3003
+ interfaceSubs);
3058
3004
}
3059
3005
3060
- auto substTypeHelper = [&](SubstitutableType *type) -> Type {
3061
- // If it's a local archetype, do an ad-hoc mapping through the
3062
- // map produced by buildThunkSignature.
3063
- if (auto *archetype = dyn_cast<LocalArchetypeType>(type)) {
3064
- assert (!contextLocalArchetypes.empty ());
3065
-
3066
- // Decline to map non-root archetypes; subst() will come back
3067
- // to us later and ask about the root.
3068
- if (!archetype->isRoot ())
3069
- return Type ();
3070
-
3071
- auto it = contextLocalArchetypes.find (archetype);
3072
- assert (it != contextLocalArchetypes.end ());
3073
- return it->second ;
3074
- }
3075
-
3076
- // Otherwise, use the context substitutions.
3077
- return Type (type).subst (contextSubs);
3078
- };
3079
- auto substConformanceHelper =
3080
- LookUpConformanceInSubstitutionMap (contextSubs);
3081
-
3082
- // Utility function to apply contextSubs, and also replace the
3083
- // opened existential with the new archetype.
3006
+ MapLocalArchetypesOutOfContext mapOutOfContext (baseGenericSig, capturedEnvs);
3084
3007
auto substFormalTypeIntoThunkContext =
3085
3008
[&](CanType t) -> CanType {
3086
- return t.subst (substTypeHelper, substConformanceHelper,
3087
- SubstFlags::SubstituteLocalArchetypes)
3009
+ return genericEnv->mapTypeIntoContext (
3010
+ t.subst (mapOutOfContext,
3011
+ MakeAbstractConformanceForGenericType (),
3012
+ SubstFlags::PreservePackExpansionLevel |
3013
+ SubstFlags::SubstituteLocalArchetypes))
3088
3014
->getCanonicalType ();
3089
3015
};
3090
3016
auto substLoweredTypeIntoThunkContext =
3091
3017
[&](CanSILFunctionType t) -> CanSILFunctionType {
3092
- return SILType::getPrimitiveObjectType (t)
3093
- .subst (fn->getModule (), substTypeHelper, substConformanceHelper,
3094
- CanGenericSignature (),
3095
- SubstFlags::SubstituteLocalArchetypes)
3096
- .castTo <SILFunctionType>();
3018
+ return cast<SILFunctionType>(
3019
+ genericEnv->mapTypeIntoContext (
3020
+ Type (t).subst (mapOutOfContext,
3021
+ MakeAbstractConformanceForGenericType (),
3022
+ SubstFlags::PreservePackExpansionLevel |
3023
+ SubstFlags::SubstituteLocalArchetypes |
3024
+ SubstFlags::AllowLoweredTypes))
3025
+ ->getCanonicalType ());
3097
3026
};
3098
3027
3099
3028
sourceType = substLoweredTypeIntoThunkContext (sourceType);
0 commit comments