@@ -2902,48 +2902,23 @@ CanSILFunctionType swift::getNativeSILFunctionType(
29022902// / Build a generic signature and environment for a re-abstraction thunk.
29032903// /
29042904// / 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.
29142907static CanGenericSignature
29152908buildThunkSignature (SILFunction *fn,
2916- ArrayRef<CanLocalArchetypeType> localArchetypes,
2909+ CanGenericSignature baseGenericSig,
2910+ ArrayRef<GenericEnvironment *> capturedEnvs,
29172911 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 ();
29232914 auto forwardingSubs = fn->getForwardingSubstitutionMap ();
29242915
29252916 // If there are no local archetypes, we just inherit the generic
29262917 // environment from the parent function.
2927- if (localArchetypes.empty ()) {
2928- auto genericSig =
2929- fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
2918+ if (capturedEnvs.empty ()) {
29302919 genericEnv = fn->getGenericEnvironment ();
29312920 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;
29472922 }
29482923
29492924 auto genericSig = buildGenericSignatureWithCapturedEnvironments (
@@ -2952,44 +2927,11 @@ buildThunkSignature(SILFunction *fn,
29522927
29532928 genericEnv = genericSig.getGenericEnvironment ();
29542929
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-
29792930 // Calculate substitutions to map interface types to the caller's archetypes.
29802931 interfaceSubs = buildSubstitutionMapWithCapturedEnvironments (
29812932 forwardingSubs, genericSig, capturedEnvs);
29822933 LLVM_DEBUG (llvm::dbgs () << " Thunk substitution map: " << interfaceSubs << " \n " );
29832934
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-
29932935 return genericSig.getCanonicalSignature ();
29942936}
29952937
@@ -3026,12 +2968,14 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
30262968 extInfoBuilder = extInfoBuilder.withNoEscape (false );
30272969
30282970 // Does the thunk type involve a local archetype type?
3029- SmallVector<CanLocalArchetypeType, 8 > localArchetypes ;
2971+ SmallVector<GenericEnvironment *, 2 > capturedEnvs ;
30302972 auto archetypeVisitor = [&](CanType t) {
30312973 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+ }
30352979 }
30362980 };
30372981
@@ -3043,57 +2987,42 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
30432987 // Use the generic signature from the context if the thunk involves
30442988 // generic parameters.
30452989 CanGenericSignature genericSig;
3046- SubstitutionMap contextSubs;
3047- llvm::DenseMap<ArchetypeType*, Type> contextLocalArchetypes;
2990+ CanGenericSignature baseGenericSig;
30482991
3049- if (!localArchetypes .empty () ||
2992+ if (!capturedEnvs .empty () ||
30502993 expectedType->hasPrimaryArchetype () ||
30512994 sourceType->hasPrimaryArchetype ()) {
2995+ // Get the existing generic signature.
2996+ baseGenericSig = fn->getLoweredFunctionType ()
2997+ ->getInvocationGenericSignature ();
2998+
30522999 genericSig = buildThunkSignature (fn,
3053- localArchetypes,
3000+ baseGenericSig,
3001+ capturedEnvs,
30543002 genericEnv,
3055- contextSubs,
3056- interfaceSubs,
3057- contextLocalArchetypes);
3003+ interfaceSubs);
30583004 }
30593005
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);
30843007 auto substFormalTypeIntoThunkContext =
30853008 [&](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))
30883014 ->getCanonicalType ();
30893015 };
30903016 auto substLoweredTypeIntoThunkContext =
30913017 [&](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 ());
30973026 };
30983027
30993028 sourceType = substLoweredTypeIntoThunkContext (sourceType);
0 commit comments