24
24
#include " swift/AST/DiagnosticsSIL.h"
25
25
#include " swift/AST/ForeignInfo.h"
26
26
#include " swift/AST/GenericEnvironment.h"
27
+ #include " swift/AST/LocalArchetypeRequirementCollector.h"
27
28
#include " swift/AST/Module.h"
28
29
#include " swift/AST/ModuleLoader.h"
29
30
#include " swift/AST/TypeCheckRequests.h"
@@ -2871,148 +2872,6 @@ CanSILFunctionType swift::getNativeSILFunctionType(
2871
2872
substConstant, reqtSubs, witnessMethodConformance);
2872
2873
}
2873
2874
2874
- namespace {
2875
- struct LocalArchetypeRequirementCollector {
2876
- const ASTContext &Context;
2877
- unsigned Depth;
2878
-
2879
- // / The lists of new parameters and requirements to add to the signature.
2880
- SmallVector<GenericTypeParamType *, 2 > Params;
2881
- SmallVector<Requirement, 2 > Requirements;
2882
-
2883
- // / The list of contextual types from the original function to use as
2884
- // / substitutions for the new parameters; parallel to Params.
2885
- SmallVector<Type, 4 > ParamSubs;
2886
-
2887
- // / A mapping of local archetypes to the corresponding type parameters
2888
- // / created for them.
2889
- llvm::DenseMap<CanType, Type> ParamsForLocalArchetypes;
2890
-
2891
- // / The set of element environments we've processed.
2892
- llvm::SmallPtrSet<GenericEnvironment*, 4 > ElementEnvs;
2893
-
2894
- LocalArchetypeRequirementCollector (const ASTContext &ctx, unsigned depth)
2895
- : Context(ctx), Depth(depth) {}
2896
-
2897
- void collect (CanLocalArchetypeType archetype) {
2898
- if (auto openedExistential = dyn_cast<OpenedArchetypeType>(archetype)) {
2899
- collect (openedExistential);
2900
- } else {
2901
- collect (cast<ElementArchetypeType>(archetype));
2902
- }
2903
- }
2904
-
2905
- void collect (CanOpenedArchetypeType archetype) {
2906
- auto param = addParameter (archetype);
2907
-
2908
- assert (archetype->isRoot ());
2909
- auto constraint = archetype->getExistentialType ();
2910
- if (auto existential = constraint->getAs <ExistentialType>())
2911
- constraint = existential->getConstraintType ();
2912
-
2913
- addRequirement (RequirementKind::Conformance, param, constraint);
2914
- }
2915
-
2916
- void collect (CanElementArchetypeType archetype) {
2917
- size_t startingIndex = Params.size ();
2918
-
2919
- // Check whether we've already handled this environment.
2920
- // This can happen with opened-element environments because
2921
- // they can open multiple archetypes.
2922
- auto env = archetype->getGenericEnvironment ();
2923
- if (!ElementEnvs.insert (env).second ) return ;
2924
-
2925
- // Add a parameter for each of the opened elements in this environment.
2926
- auto sig = env->getGenericSignature ();
2927
- auto elementParams = sig.getInnermostGenericParams ();
2928
- #ifndef NDEBUG
2929
- unsigned nextIndex = 0 ;
2930
- #endif
2931
- for (auto elementParam : elementParams) {
2932
- assert (elementParam->getIndex () == nextIndex++);
2933
- auto elementArchetype = env->mapTypeIntoContext (elementParam);
2934
- addParameter (cast<LocalArchetypeType>(CanType (elementArchetype)));
2935
- }
2936
-
2937
- // Clone the element requirements.
2938
-
2939
- // The element parameters should all have the same depth, and their
2940
- // index values are dense and in order from 0..<N in that depth.
2941
- // We asserted that above, and we'll use it below to map them to
2942
- // their new parameters in Params.
2943
- auto elementDepth = elementParams.front ()->getDepth ();
2944
-
2945
- // Helper function: does the given type refer to an opened element
2946
- // parameter from the opened element generic signature?
2947
- auto refersToElementType = [=](Type type) {
2948
- return type.findIf ([&](Type t) {
2949
- if (auto *param = t->getAs <GenericTypeParamType>())
2950
- return (param->getDepth () == elementDepth);
2951
- return false ;
2952
- });
2953
- };
2954
- // Helper function: replace references to opened element parameters
2955
- // with one of the type parameters we just created for this
2956
- // environment.
2957
- auto rewriteElementType = [=](Type type) {
2958
- return type.transformRec ([&](Type t) -> std::optional<Type> {
2959
- if (auto *param = t->getAs <GenericTypeParamType>()) {
2960
- if (param->getDepth () == elementDepth)
2961
- return Type (Params[startingIndex + param->getIndex ()]);
2962
- }
2963
- return std::nullopt;
2964
- });
2965
- };
2966
-
2967
- for (auto req : sig.getRequirements ()) {
2968
- switch (req.getKind ()) {
2969
- case RequirementKind::SameShape:
2970
- // These never involve element types.
2971
- break ;
2972
- case RequirementKind::Conformance:
2973
- if (refersToElementType (req.getFirstType ())) {
2974
- addRequirement (RequirementKind::Conformance,
2975
- rewriteElementType (req.getFirstType ()),
2976
- req.getSecondType ());
2977
- }
2978
- break ;
2979
- case RequirementKind::Superclass:
2980
- case RequirementKind::SameType:
2981
- if (refersToElementType (req.getFirstType ()) ||
2982
- refersToElementType (req.getSecondType ())) {
2983
- addRequirement (req.getKind (),
2984
- rewriteElementType (req.getFirstType ()),
2985
- rewriteElementType (req.getSecondType ()));
2986
- }
2987
- break ;
2988
- break ;
2989
- case RequirementKind::Layout:
2990
- if (refersToElementType (req.getFirstType ())) {
2991
- addRequirement (RequirementKind::Layout,
2992
- rewriteElementType (req.getFirstType ()),
2993
- req.getLayoutConstraint ());
2994
- }
2995
- break ;
2996
- }
2997
- }
2998
- }
2999
-
3000
- GenericTypeParamType *addParameter (CanLocalArchetypeType localArchetype) {
3001
- auto *param = GenericTypeParamType::get (/* pack*/ false , Depth,
3002
- Params.size (), Context);
3003
- Params.push_back (param);
3004
- ParamSubs.push_back (localArchetype);
3005
- ParamsForLocalArchetypes.insert (std::make_pair (localArchetype, param));
3006
- return param;
3007
- }
3008
-
3009
- template <class ... Args>
3010
- void addRequirement (Args &&... args) {
3011
- Requirements.emplace_back (std::forward<Args>(args)...);
3012
- }
3013
- };
3014
- } // end anonymous namespace
3015
-
3016
2875
// / Build a generic signature and environment for a re-abstraction thunk.
3017
2876
// /
3018
2877
// / Most thunks share the generic environment with their original function.
@@ -3047,33 +2906,35 @@ buildThunkSignature(SILFunction *fn,
3047
2906
return genericSig;
3048
2907
}
3049
2908
3050
- // Add the existing generic signature.
3051
- unsigned depth = 0 ;
3052
- GenericSignature baseGenericSig;
3053
- if (auto genericSig =
3054
- fn->getLoweredFunctionType ()->getInvocationGenericSignature ()) {
3055
- baseGenericSig = genericSig;
3056
- depth = genericSig.getGenericParams ().back ()->getDepth () + 1 ;
3057
- }
3058
-
3059
- // Add new generic parameters to replace the local archetypes.
3060
- LocalArchetypeRequirementCollector collector (ctx, depth);
2909
+ // Get the existing generic signature.
2910
+ auto baseGenericSig =
2911
+ fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
3061
2912
2913
+ SmallVector<GenericEnvironment *, 2 > capturedEnvs;
3062
2914
for (auto archetype : localArchetypes) {
3063
- collector.collect (archetype);
2915
+ auto *genericEnv = archetype->getGenericEnvironment ();
2916
+ if (std::find (capturedEnvs.begin (), capturedEnvs.end (), genericEnv)
2917
+ == capturedEnvs.end ()) {
2918
+ capturedEnvs.push_back (genericEnv);
2919
+ }
3064
2920
}
3065
2921
3066
- auto genericSig = buildGenericSignature (ctx, baseGenericSig,
3067
- collector. Params ,
3068
- collector. Requirements ,
3069
- /* allowInverses= */ false );
2922
+ auto genericSig = buildGenericSignatureWithCapturedEnvironments (
2923
+ ctx, baseGenericSig, capturedEnvs);
2924
+ LLVM_DEBUG ( llvm::dbgs () << " Thunk generic signature: " << genericSig << " \n " );
2925
+
3070
2926
genericEnv = genericSig.getGenericEnvironment ();
3071
2927
2928
+ MapLocalArchetypesOutOfContext mapOutOfContext (baseGenericSig, capturedEnvs);
2929
+
3072
2930
// Map the local archetypes to their new parameter types.
3073
2931
for (auto localArchetype : localArchetypes) {
3074
- auto param =
3075
- collector.ParamsForLocalArchetypes .find (localArchetype)->second ;
3076
- auto thunkArchetype = genericEnv->mapTypeIntoContext (param);
2932
+ auto thunkInterfaceType = Type (localArchetype).subst (
2933
+ mapOutOfContext,
2934
+ MakeAbstractConformanceForGenericType (),
2935
+ SubstFlags::PreservePackExpansionLevel);
2936
+ auto thunkArchetype = genericEnv->mapTypeIntoContext (
2937
+ thunkInterfaceType);
3077
2938
contextLocalArchetypes.insert (std::make_pair (localArchetype,
3078
2939
thunkArchetype));
3079
2940
}
@@ -3088,18 +2949,18 @@ buildThunkSignature(SILFunction *fn,
3088
2949
}
3089
2950
3090
2951
// Calculate substitutions to map interface types to the caller's archetypes.
3091
-
3092
- interfaceSubs = SubstitutionMap::get (
3093
- genericSig,
3094
- [&](SubstitutableType *type) -> Type {
3095
- if (auto param = dyn_cast<GenericTypeParamType>(type) ) {
3096
- if (param-> getDepth () == depth) {
3097
- return collector. ParamSubs [param-> getIndex ()];
3098
- }
3099
- }
3100
- return Type (type). subst (forwardingSubs );
3101
- },
3102
- MakeAbstractConformanceForGenericType ());
2952
+ interfaceSubs = buildSubstitutionMapWithCapturedEnvironments (
2953
+ forwardingSubs, genericSig, capturedEnvs);
2954
+ LLVM_DEBUG ( llvm::dbgs () << " Thunk substitution map: " << interfaceSubs << " \n " );
2955
+
2956
+ for (auto pair : contextLocalArchetypes ) {
2957
+ auto substArchetype = Type (pair. second ). subst (interfaceSubs);
2958
+ if (!pair. first -> isEqual (substArchetype)) {
2959
+ llvm::errs () << " Expected: " ; pair. first -> dump ( llvm::errs ());
2960
+ llvm::errs () << " Got: " ; substArchetype-> dump ( llvm::errs ());
2961
+ abort ( );
2962
+ }
2963
+ }
3103
2964
3104
2965
return genericSig.getCanonicalSignature ();
3105
2966
}
0 commit comments