diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index 2594a3393e9f2..cfa67d6d80ab4 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -583,10 +583,12 @@ mangled in to disambiguate. :: impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_' - impl-function-type ::= type* generic-signature 'I' PSEUDO-GENERIC? FUNC-ATTRIBUTES '_' + impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_' - FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)? + FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)? + PATTERN-SUBS ::= 's' // has pattern substitutions + INVOCATION-SUB ::= 'I' // has invocation substitutions PSEUDO-GENERIC ::= 'P' CALLEE-ESCAPE ::= 'e' // @escaping (inverse of SIL @noescape) diff --git a/docs/SIL.rst b/docs/SIL.rst index bddf188c65c18..61b063c5c097b 100644 --- a/docs/SIL.rst +++ b/docs/SIL.rst @@ -592,6 +592,46 @@ autorelease in the callee. importer only imports non-native methods and types as ``throws`` when it is possible to do this automatically. +- SIL function types may provide a pattern signature and substitutions + to express that values of the type use a particular generic abstraction + pattern. Both must be provided together. If a pattern signature is + present, the component types (parameters, yields, and results) must be + expressed in terms of the generic parameters of that signature. + The pattern substitutions should be expressed in terms of the generic + parameters of the overall generic signature, if any, or else + the enclosing generic context, if any. + + A pattern signature follows the ``@substituted`` attribute, which + must be the final attribute preceding the function type. Pattern + substitutions follow the function type, preceded by the ``for`` + keyword. For example:: + + @substituted (@in T) -> @out T.Element for Array + + The low-level representation of a value of this type may not match + the representation of a value of the substituted-through version of it:: + + (@in Array) -> @out Int + + Substitution differences at the outermost level of a function value + may be adjusted using the ``convert_function`` instruction. Note that + this only works at the outermost level and not in nested positions. + For example, a function which takes a parameter of the first type above + cannot be converted by ``convert_function`` to a function which takes + a parameter of the second type; such a conversion must be done with a + thunk. + + Type substitution on a function type with a pattern signature and + substitutions only substitutes into the substitutions; the component + types are preserved with their exact original structure. + +- In the implementation, a SIL function type may also carry substitutions + for its generic signature. This is a convenience for working with + applied generic types and is not generally a formal part of the SIL + language; in particular, values should not have such types. Such a + type behaves like a non-generic type, as if the substitutions were + actually applied to the underlying function type. + Coroutine Types ``````````````` diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index d9630eaf6d9e0..bf67f039719e1 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -828,6 +828,14 @@ ERROR(sil_function_subst_expected_l_angle,none, "expected '<' to begin SIL function type substitution list after 'for'", ()) ERROR(sil_function_subst_expected_r_angle,none, "expected '>' to end SIL function type substitution list after 'for <...'", ()) +ERROR(sil_function_subst_expected_generics,none, + "expected '<' to begin substituted parameter list after '@substituted'", ()) +ERROR(sil_function_subst_expected_function,none, + "expected function type after '@substituted'", ()) +ERROR(sil_function_subst_expected_subs,none, + "expected 'for' to begin substitutions after '@substituted' function type", ()) +ERROR(sil_function_subs_without_generics,none, + "unexpected 'for' to begin substitutions after non-generic function type", ()) // Opaque types ERROR(opaque_mid_composition,none, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index e8bca6bd79ce7..3f4792086ca49 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -4019,6 +4019,8 @@ ERROR(sil_non_coro_yields,PointsToFirstBadToken, ERROR(sil_function_repeat_convention,PointsToFirstBadToken, "repeated %select{parameter|result|callee}0 convention attribute", (unsigned)) +ERROR(ast_subst_function_type,none, + "substitutions cannot be provided on a formal function type", ()) ERROR(sil_function_multiple_error_results,PointsToFirstBadToken, "SIL function types cannot have multiple @error results", ()) ERROR(unsupported_sil_convention,none, diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h index 56e4995aad08c..d72b3290e4765 100644 --- a/include/swift/AST/TypeRepr.h +++ b/include/swift/AST/TypeRepr.h @@ -472,12 +472,15 @@ inline IdentTypeRepr::ComponentRange IdentTypeRepr::getComponentRange() { /// (x: Foo, y: Bar) -> Baz /// \endcode class FunctionTypeRepr : public TypeRepr { - // These fields are only used in SIL mode, which is the only time - // we can have polymorphic and substituted function values. + // The generic params / environment / substitutions fields are only used + // in SIL mode, which is the only time we can have polymorphic and + // substituted function values. GenericParamList *GenericParams; GenericEnvironment *GenericEnv; - bool GenericParamsAreImplied; - ArrayRef GenericSubs; + ArrayRef InvocationSubs; + GenericParamList *PatternGenericParams; + GenericEnvironment *PatternGenericEnv; + ArrayRef PatternSubs; TupleTypeRepr *ArgsTy; TypeRepr *RetTy; @@ -487,21 +490,37 @@ class FunctionTypeRepr : public TypeRepr { public: FunctionTypeRepr(GenericParamList *genericParams, TupleTypeRepr *argsTy, SourceLoc throwsLoc, SourceLoc arrowLoc, TypeRepr *retTy, - bool GenericParamsAreImplied = false, - ArrayRef GenericSubs = {}) + GenericParamList *patternGenericParams = nullptr, + ArrayRef patternSubs = {}, + ArrayRef invocationSubs = {}) : TypeRepr(TypeReprKind::Function), - GenericParams(genericParams), - GenericEnv(nullptr), - GenericParamsAreImplied(GenericParamsAreImplied), - GenericSubs(GenericSubs), + GenericParams(genericParams), GenericEnv(nullptr), + InvocationSubs(invocationSubs), + PatternGenericParams(patternGenericParams), PatternGenericEnv(nullptr), + PatternSubs(patternSubs), ArgsTy(argsTy), RetTy(retTy), ArrowLoc(arrowLoc), ThrowsLoc(throwsLoc) { } GenericParamList *getGenericParams() const { return GenericParams; } GenericEnvironment *getGenericEnvironment() const { return GenericEnv; } - bool areGenericParamsImplied() const { return GenericParamsAreImplied; } - ArrayRef getSubstitutions() const { return GenericSubs; } + + GenericParamList *getPatternGenericParams() const { + return PatternGenericParams; + } + GenericEnvironment *getPatternGenericEnvironment() const { + return PatternGenericEnv; + } + + ArrayRef getPatternSubstitutions() const { return PatternSubs; } + ArrayRef getInvocationSubstitutions() const { + return InvocationSubs; + } + + void setPatternGenericEnvironment(GenericEnvironment *genericEnv) { + assert(PatternGenericEnv == nullptr); + PatternGenericEnv = genericEnv; + } void setGenericEnvironment(GenericEnvironment *genericEnv) { assert(GenericEnv == nullptr); diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 32769d030acfd..2a419e0c93ee6 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -363,12 +363,14 @@ class alignas(1 << TypeAlignInBits) TypeBase { ID : 32 ); - SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+1+3+1+2, + SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+1+3+1+2+1+1, ExtInfoBits : NumSILExtInfoBits, HasUncommonInfo : 1, CalleeConvention : 3, HasErrorResult : 1, - CoroutineKind : 2 + CoroutineKind : 2, + HasInvocationSubs : 1, + HasPatternSubs : 1 ); SWIFT_INLINE_BITFIELD(AnyMetatypeType, TypeBase, 2, @@ -3842,6 +3844,11 @@ class SILParameterInfo { return getWithInterfaceType(fn(getInterfaceType())); } + SILParameterInfo mapTypeOutOfContext() const { + return getWithInterfaceType(getInterfaceType()->mapTypeOutOfContext() + ->getCanonicalType()); + } + void profile(llvm::FoldingSetNodeID &id) { id.AddPointer(getInterfaceType().getPointer()); id.AddInteger((unsigned)getConvention()); @@ -3964,6 +3971,11 @@ class SILResultInfo { return getWithInterfaceType(fn(getInterfaceType())); } + SILResultInfo mapTypeOutOfContext() const { + return getWithInterfaceType(getInterfaceType()->mapTypeOutOfContext() + ->getCanonicalType()); + } + void profile(llvm::FoldingSetNodeID &id) { id.AddPointer(TypeAndConvention.getOpaqueValue()); } @@ -4008,6 +4020,11 @@ class SILYieldInfo : public SILParameterInfo { SILYieldInfo map(const F &fn) const { return getWithInterfaceType(fn(getInterfaceType())); } + + SILYieldInfo mapTypeOutOfContext() const { + return getWithInterfaceType(getInterfaceType()->mapTypeOutOfContext() + ->getCanonicalType()); + } }; /// SILCoroutineKind - What kind of coroutine is this SILFunction? @@ -4046,7 +4063,8 @@ namespace Lowering { /// function parameter and result types. class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, private llvm::TrailingObjects { + SILResultInfo, SILYieldInfo, + SubstitutionMap, CanType> { friend TrailingObjects; size_t numTrailingObjects(OverloadToken) const { @@ -4065,6 +4083,11 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, return hasResultCache() ? 2 : 0; } + size_t numTrailingObjects(OverloadToken) const { + return size_t(hasPatternSubstitutions()) + + size_t(hasInvocationSubstitutions()); + } + public: using Language = SILFunctionLanguage; using Representation = SILFunctionTypeRepresentation; @@ -4249,12 +4272,12 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, // SILResultInfo[isCoroutine() ? 0 : NumAnyResults] // SILResultInfo? // if hasErrorResult() // SILYieldInfo[isCoroutine() ? NumAnyResults : 0] + // SubstitutionMap[HasPatternSubs + HasInvocationSubs] // CanType? // if !isCoro && NumAnyResults > 1, formal result cache // CanType? // if !isCoro && NumAnyResults > 1, all result cache - llvm::PointerIntPair GenericSigAndIsImplied; + CanGenericSignature InvocationGenericSig; ProtocolConformanceRef WitnessMethodConformance; - SubstitutionMap Substitutions; MutableArrayRef getMutableParameters() { return {getTrailingObjects(), NumParameters}; @@ -4273,6 +4296,17 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, return *(getTrailingObjects() + getNumResults()); } + SubstitutionMap &getMutablePatternSubs() { + assert(hasPatternSubstitutions()); + return *getTrailingObjects(); + } + + SubstitutionMap &getMutableInvocationSubs() { + assert(hasInvocationSubstitutions()); + return *(getTrailingObjects() + + unsigned(hasPatternSubstitutions())); + } + /// Do we have slots for caches of the normal-result tuple type? bool hasResultCache() const { return NumAnyResults > 1 && !isCoroutine(); @@ -4296,7 +4330,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, ArrayRef yieldResults, ArrayRef normalResults, Optional errorResult, - SubstitutionMap substitutions, bool genericSigIsImplied, + SubstitutionMap patternSubs, + SubstitutionMap invocationSubs, const ASTContext &ctx, RecursiveTypeProperties properties, ProtocolConformanceRef witnessMethodConformance); @@ -4308,7 +4343,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, ArrayRef interfaceYields, ArrayRef interfaceResults, Optional interfaceErrorResult, - SubstitutionMap substitutions, bool genericSigIsImplied, + SubstitutionMap patternSubs, SubstitutionMap invocationSubs, const ASTContext &ctx, ProtocolConformanceRef witnessMethodConformance = ProtocolConformanceRef()); @@ -4500,28 +4535,93 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, return llvm::count_if(getParameters(), IndirectMutatingParameterFilter()); } - /// Get the generic signature used to apply the substitutions of a substituted function type + /// Get the generic signature that the component types are specified + /// in terms of, if any. CanGenericSignature getSubstGenericSignature() const { - return GenericSigAndIsImplied.getPointer(); + if (hasPatternSubstitutions()) + return getPatternGenericSignature(); + return getInvocationGenericSignature(); + } + + /// Return the combined substitutions that need to be applied to the + /// component types to render their expected types in the context. + SubstitutionMap getCombinedSubstitutions() const { + if (hasPatternSubstitutions()) { + auto subs = getPatternSubstitutions(); + if (hasInvocationSubstitutions()) + subs = subs.subst(getInvocationSubstitutions()); + return subs; + } + return getInvocationSubstitutions(); } + /// Get the generic signature used by callers to invoke the function. CanGenericSignature getInvocationGenericSignature() const { - if (isGenericSignatureImplied()) { - return CanGenericSignature(); - } else { - return getSubstGenericSignature(); - } + return InvocationGenericSig; } - - bool isGenericSignatureImplied() const { - return GenericSigAndIsImplied.getInt(); + + bool hasInvocationSubstitutions() const { + return Bits.SILFunctionType.HasInvocationSubs; } - SubstitutionMap getSubstitutions() const { - return Substitutions; + + /// Return the invocation substitutions. The presence of invocation + /// substitutions means that this is an applied or contextualized generic + /// function type. + SubstitutionMap getInvocationSubstitutions() const { + return hasInvocationSubstitutions() + ? const_cast(this)->getMutableInvocationSubs() + : SubstitutionMap(); + } + + bool hasPatternSubstitutions() const { + return Bits.SILFunctionType.HasPatternSubs; + } + + /// Return the generic signature which expresses the fine-grained + /// abstraction of this function. See the explanation for + /// `getPatternSubstitutions`. + /// + /// The exact structure of this signature is an implementation detail + /// for many function types, and tools must be careful not to expose + /// it in ways that must be kept stable. For example, ptrauth + /// discrimination does not distinguish between different generic + /// parameter types in this signature. + CanGenericSignature getPatternGenericSignature() const { + return hasPatternSubstitutions() + ? CanGenericSignature( + getPatternSubstitutions().getGenericSignature()) + : CanGenericSignature(); + } + + /// Return the "pattern" substitutions. The presence of pattern + /// substitutions means that the component types of this type are + /// abstracted in some additional way. + /// + /// For example, in the function: + /// + /// ``` + /// func consume(producer: () -> T) + /// ``` + /// + /// the argument function `producer` is abstracted differently from + /// a function of type `() -> Int`, even when `T` is concretely `Int`. + /// + /// Similarly, a protocol witness function that returns an `Int` might + /// return it differently if original requirement is abstract about its + /// return type. + /// + /// The most important abstraction differences are accounted for in + /// the structure and conventions of the function's component types, + /// but more subtle differences, like ptrauth discrimination, may + /// require more precise information. + SubstitutionMap getPatternSubstitutions() const { + return hasPatternSubstitutions() + ? const_cast(this)->getMutablePatternSubs() + : SubstitutionMap(); } bool isPolymorphic() const { - return !getInvocationGenericSignature().isNull(); + return getInvocationGenericSignature() && !getInvocationSubstitutions(); } CanType getSelfInstanceType(SILModule &M) const; @@ -4723,9 +4823,18 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, bool isNoReturnFunction(SILModule &M) const; // Defined in SILType.cpp - /// Create a SILFunctionType with the same parameters, results, and attributes as this one, but with - /// a different set of substitutions. - CanSILFunctionType withSubstitutions(SubstitutionMap subs) const; + /// Create a SILFunctionType with the same structure as this one, + /// but with a different (or new) set of invocation substitutions. + /// The substitutions must have the same generic signature as this. + CanSILFunctionType + withInvocationSubstitutions(SubstitutionMap subs) const; + + /// Create a SILFunctionType with the same structure as this one, + /// but with a different set of pattern substitutions. + /// This type must already have pattern substitutions, and they + /// must have the same signature as the new substitutions. + CanSILFunctionType + withPatternSubstitutions(SubstitutionMap subs) const; class ABICompatibilityCheckResult { friend class SILFunctionType; @@ -4789,18 +4898,19 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, CanSILFunctionType getUnsubstitutedType(SILModule &M) const; void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getSubstGenericSignature(), getExtInfo(), getCoroutineKind(), - getCalleeConvention(), getParameters(), getYields(), getResults(), + Profile(ID, getInvocationGenericSignature(), + getExtInfo(), getCoroutineKind(), getCalleeConvention(), + getParameters(), getYields(), getResults(), getOptionalErrorResult(), getWitnessMethodConformanceOrInvalid(), - isGenericSignatureImplied(), getSubstitutions()); + getPatternSubstitutions(), getInvocationSubstitutions()); } static void Profile(llvm::FoldingSetNodeID &ID, GenericSignature genericSig, ExtInfo info, SILCoroutineKind coroutineKind, ParameterConvention calleeConvention, ArrayRef params, ArrayRef yields, ArrayRef results, Optional errorResult, - ProtocolConformanceRef conformance, bool isGenericSigImplied, - SubstitutionMap substitutions); + ProtocolConformanceRef conformance, + SubstitutionMap patternSub, SubstitutionMap invocationSubs); // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 31312b0ceca0f..4f11bec456290 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -113,10 +113,10 @@ NODE(ImplEscaping) NODE(ImplConvention) NODE(ImplFunctionAttribute) NODE(ImplFunctionType) -NODE(ImplImpliedSubstitutions) -NODE(ImplSubstitutions) +NODE(ImplInvocationSubstitutions) CONTEXT_NODE(ImplicitClosure) NODE(ImplParameter) +NODE(ImplPatternSubstitutions) NODE(ImplResult) NODE(ImplYield) NODE(ImplErrorResult) diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index 4e15caf4c932f..707308c01a58b 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -532,6 +532,11 @@ class SILType { /// Returns a SILType with any archetypes mapped out of context. SILType mapTypeOutOfContext() const; + /// Given a lowered type (but without any particular value category), + /// map it out of its current context. Equivalent to + /// SILType::getPrimitiveObjectType(type).mapTypeOutOfContext().getASTType(). + static CanType mapTypeOutOfContext(CanType type); + /// Given two SIL types which are representations of the same type, /// check whether they have an abstraction difference. bool hasAbstractionDifference(SILFunctionTypeRepresentation rep, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index a0e3ce76366ca..376ed1aa137d8 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3186,8 +3186,8 @@ void SILFunctionType::Profile( ArrayRef results, Optional errorResult, ProtocolConformanceRef conformance, - bool isGenericSignatureImplied, - SubstitutionMap substitutions) { + SubstitutionMap patternSubs, + SubstitutionMap invocationSubs) { id.AddPointer(genericParams.getPointer()); auto infoKey = info.getFuncAttrKey(); id.AddInteger(infoKey.first); @@ -3207,8 +3207,8 @@ void SILFunctionType::Profile( // Just allow the profile length to implicitly distinguish the // presence of an error result. if (errorResult) errorResult->profile(id); - id.AddBoolean(isGenericSignatureImplied); - substitutions.profile(id); + patternSubs.profile(id); + invocationSubs.profile(id); id.AddBoolean((bool)conformance); if (conformance) id.AddPointer(conformance.getRequirement()); @@ -3223,20 +3223,20 @@ SILFunctionType::SILFunctionType( ArrayRef yields, ArrayRef normalResults, Optional errorResult, - SubstitutionMap substitutions, - bool genericSigIsImplied, + SubstitutionMap patternSubs, + SubstitutionMap invocationSubs, const ASTContext &ctx, RecursiveTypeProperties properties, ProtocolConformanceRef witnessMethodConformance) : TypeBase(TypeKind::SILFunction, &ctx, properties), - GenericSigAndIsImplied(CanGenericSignature(genericSig), - genericSigIsImplied), - WitnessMethodConformance(witnessMethodConformance), - Substitutions(substitutions) { + InvocationGenericSig(CanGenericSignature(genericSig)), + WitnessMethodConformance(witnessMethodConformance) { Bits.SILFunctionType.HasErrorResult = errorResult.hasValue(); Bits.SILFunctionType.ExtInfoBits = ext.Bits; Bits.SILFunctionType.HasUncommonInfo = false; + Bits.SILFunctionType.HasPatternSubs = (bool) patternSubs; + Bits.SILFunctionType.HasInvocationSubs = (bool) invocationSubs; // The use of both assert() and static_assert() below is intentional. assert(Bits.SILFunctionType.ExtInfoBits == ext.Bits && "Bits were dropped!"); static_assert(ExtInfo::NumMaskBits == NumSILExtInfoBits, @@ -3269,6 +3269,11 @@ SILFunctionType::SILFunctionType( if (errorResult) getMutableErrorResult() = *errorResult; + if (patternSubs) + getMutablePatternSubs() = patternSubs; + if (invocationSubs) + getMutableInvocationSubs() = invocationSubs; + if (hasResultCache()) { getMutableFormalResultsCache() = CanType(); getMutableAllResultsCache() = CanType(); @@ -3282,14 +3287,11 @@ SILFunctionType::SILFunctionType( "non-witness_method SIL function with a conformance"); // Make sure the type follows invariants. - assert((!substitutions || genericSig) + assert((!invocationSubs || genericSig) && "can only have substitutions with a generic signature"); - assert((!genericSigIsImplied || substitutions) - && "genericSigIsImplied should only be set for a type with generic " - "types and substitutions"); - if (substitutions) { - assert(substitutions.getGenericSignature().getCanonicalSignature() == + if (invocationSubs) { + assert(invocationSubs.getGenericSignature().getCanonicalSignature() == genericSig.getCanonicalSignature() && "substitutions must match generic signature"); } @@ -3303,7 +3305,9 @@ SILFunctionType::SILFunctionType( (void)gparam; assert(gparam->isCanonical() && "generic signature is not canonicalized"); } + } + if (genericSig || patternSubs) { for (auto param : getParameters()) { (void)param; assert(!param.getInterfaceType()->hasError() @@ -3331,6 +3335,11 @@ SILFunctionType::SILFunctionType( assert(!getErrorResult().getInterfaceType()->hasArchetype() && "interface type of result should not contain context archetypes"); } + + if (genericSig && patternSubs) { + assert(!patternSubs.hasArchetypes() + && "pattern substitutions should not contain context archetypes"); + } } for (auto result : getResults()) { (void)result; @@ -3373,21 +3382,22 @@ CanSILFunctionType SILFunctionType::get( ArrayRef yields, ArrayRef normalResults, Optional errorResult, - SubstitutionMap substitutions, - bool genericSigIsImplied, + SubstitutionMap patternSubs, + SubstitutionMap invocationSubs, const ASTContext &ctx, ProtocolConformanceRef witnessMethodConformance) { assert(coroutineKind == SILCoroutineKind::None || normalResults.empty()); assert(coroutineKind != SILCoroutineKind::None || yields.empty()); assert(!ext.isPseudogeneric() || genericSig); - substitutions = substitutions.getCanonical(); + patternSubs = patternSubs.getCanonical(); + invocationSubs = invocationSubs.getCanonical(); llvm::FoldingSetNodeID id; SILFunctionType::Profile(id, genericSig, ext, coroutineKind, callee, params, yields, normalResults, errorResult, - witnessMethodConformance, genericSigIsImplied, - substitutions); + witnessMethodConformance, + patternSubs, invocationSubs); // Do we already have this generic function type? void *insertPos; @@ -3400,9 +3410,11 @@ CanSILFunctionType SILFunctionType::get( // See [SILFunctionType-layout] bool hasResultCache = normalResults.size() > 1; size_t bytes = - totalSizeToAlloc( + totalSizeToAlloc( params.size(), normalResults.size() + (errorResult ? 1 : 0), - yields.size(), hasResultCache ? 2 : 0); + yields.size(), (patternSubs ? 1 : 0) + (invocationSubs ? 1 : 0), + hasResultCache ? 2 : 0); void *mem = ctx.Allocate(bytes, alignof(SILFunctionType)); @@ -3420,19 +3432,20 @@ CanSILFunctionType SILFunctionType::get( // FIXME: If we ever have first-class polymorphic values, we'll need to // revisit this. - if (genericSig) { + if (genericSig || patternSubs) { properties.removeHasTypeParameter(); properties.removeHasDependentMember(); } - for (auto replacement : substitutions.getReplacementTypes()) { + auto outerSubs = genericSig ? invocationSubs : patternSubs; + for (auto replacement : outerSubs.getReplacementTypes()) { properties |= replacement->getRecursiveProperties(); } auto fnType = new (mem) SILFunctionType(genericSig, ext, coroutineKind, callee, params, yields, normalResults, errorResult, - substitutions, genericSigIsImplied, + patternSubs, invocationSubs, ctx, properties, witnessMethodConformance); assert(fnType->hasResultCache() == hasResultCache); diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 7be40882ef5b2..1b91a213bbb60 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -519,7 +519,7 @@ Type ASTBuilder::createImplFunctionType( return SILFunctionType::get(genericSig, einfo, funcCoroutineKind, funcCalleeConvention, funcParams, funcYields, funcResults, funcErrorResult, - SubstitutionMap(), false, Ctx); + SubstitutionMap(), SubstitutionMap(), Ctx); } Type ASTBuilder::createProtocolCompositionType( diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index a7c0548068a37..d5392a8cf78b6 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -357,8 +357,8 @@ std::string ASTMangler::mangleReabstractionThunkHelper( Type SelfType, ModuleDecl *Module) { Mod = Module; - assert(ThunkType->getSubstitutions().empty() && "not implemented"); - GenericSignature GenSig = ThunkType->getSubstGenericSignature(); + assert(ThunkType->getPatternSubstitutions().empty() && "not implemented"); + GenericSignature GenSig = ThunkType->getInvocationGenericSignature(); if (GenSig) CurGenericSignature = GenSig.getCanonicalSignature(); @@ -1456,11 +1456,11 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) { llvm::SmallVector OpArgs; - if (fn->getSubstitutions()) { + if (fn->getPatternSubstitutions()) { OpArgs.push_back('s'); - if (!fn->isGenericSignatureImplied()) { - OpArgs.push_back('i'); - } + } + if (fn->getInvocationSubstitutions()) { + OpArgs.push_back('I'); } if (fn->isPolymorphic() && fn->isPseudogeneric()) @@ -1538,10 +1538,15 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) { OpArgs.push_back(getResultConvention(error.getConvention())); appendType(error.getInterfaceType()); } - if (auto sig = fn->getSubstGenericSignature()) { + if (auto sig = fn->getInvocationGenericSignature()) { appendGenericSignature(sig); } - if (auto subs = fn->getSubstitutions()) { + if (auto subs = fn->getInvocationSubstitutions()) { + appendFlatGenericArgs(subs); + appendRetroactiveConformances(subs, Mod); + } + if (auto subs = fn->getPatternSubstitutions()) { + appendGenericSignature(subs.getGenericSignature()); appendFlatGenericArgs(subs); appendRetroactiveConformances(subs, Mod); } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index ff382bbba98f2..0cfdcae3b5e8b 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4166,6 +4166,13 @@ class TypePrinter : public TypeVisitor { printFunctionExtInfo(T->getASTContext(), T->getExtInfo(), T->getWitnessMethodConformanceOrInvalid()); printCalleeConvention(T->getCalleeConvention()); + + if (auto sig = T->getInvocationGenericSignature()) { + printGenericSignature(sig, + PrintAST::PrintParams | + PrintAST::PrintRequirements); + Printer << " "; + } // If this is a substituted function type, then its generic signature is // independent of the enclosing context, and defines the parameters active @@ -4178,25 +4185,21 @@ class TypePrinter : public TypeVisitor { TypePrinter *sub = this; Optional subBuffer; PrintOptions subOptions = Options; - if (T->getSubstitutions()) { + if (auto substitutions = T->getPatternSubstitutions()) { subOptions.GenericEnv = nullptr; subBuffer.emplace(Printer, subOptions); sub = &*subBuffer; + + sub->Printer << "@substituted "; + sub->printGenericSignature(substitutions.getGenericSignature(), + PrintAST::PrintParams | + PrintAST::PrintRequirements); + sub->Printer << " "; } // Capture list used here to ensure we don't print anything using `this` // printer, but only the sub-Printer. - [T, sub, &subOptions]{ - if (auto sig = T->getSubstGenericSignature()) { - sub->printGenericSignature(sig, - PrintAST::PrintParams | - PrintAST::PrintRequirements); - sub->Printer << " "; - if (T->isGenericSignatureImplied()) { - sub->Printer << "in "; - } - } - + [T, sub, &subOptions] { sub->Printer << "("; bool first = true; for (auto param : T->getParameters()) { @@ -4235,9 +4238,15 @@ class TypePrinter : public TypeVisitor { if (totalResults != 1) sub->Printer << ")"; }(); - - // The substitution types are always in terms of the outer environment. - if (auto substitutions = T->getSubstitutions()) { + + // Both the pattern and invocation substitution types are always in + // terms of the outer environment. But this wouldn't necessarily be + // true with higher-rank polymorphism. + if (auto substitutions = T->getPatternSubstitutions()) { + Printer << " for"; + printSubstitutions(substitutions); + } + if (auto substitutions = T->getInvocationSubstitutions()) { Printer << " for"; printSubstitutions(substitutions); } diff --git a/lib/AST/AutoDiff.cpp b/lib/AST/AutoDiff.cpp index 0f36636810687..1b8dfbb59fbaa 100644 --- a/lib/AST/AutoDiff.cpp +++ b/lib/AST/AutoDiff.cpp @@ -143,7 +143,7 @@ GenericSignature autodiff::getConstrainedDerivativeGenericSignature( GenericSignature derivativeGenSig, LookupConformanceFn lookupConformance, bool isTranspose) { if (!derivativeGenSig) - derivativeGenSig = originalFnTy->getSubstGenericSignature(); + derivativeGenSig = originalFnTy->getInvocationGenericSignature(); if (!derivativeGenSig) return nullptr; auto &ctx = originalFnTy->getASTContext(); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 1b1e4521b297a..bd5b74fe46c48 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1769,21 +1769,48 @@ class IsBindableVisitor if (auto substFunc = dyn_cast(subst)) { if (func->getExtInfo() != substFunc->getExtInfo()) return CanType(); - + + if (func->getInvocationGenericSignature() + || substFunc->getInvocationGenericSignature()) { + auto sig = func->getInvocationGenericSignature(); + if (sig != substFunc->getInvocationGenericSignature()) + return CanType(); + + auto origSubs = func->getPatternSubstitutions(); + auto substSubs = substFunc->getPatternSubstitutions(); + + if ((bool) origSubs != (bool) substSubs) + return CanType(); + + for (unsigned i : indices(origSubs.getReplacementTypes())) { + auto origType = + origSubs.getReplacementTypes()[i]->getCanonicalType(sig); + auto substType = + substSubs.getReplacementTypes()[i]->getCanonicalType(sig); + + auto newType = visit(origType, substType, nullptr, {}); + + if (!newType) + return CanType(); + + // We can test SILFunctionTypes for bindability, but we can't + // transform them. + assert(newType == substType + && "cannot transform SILFunctionTypes"); + } + } + // Compare substituted function types. - if (func->getSubstGenericSignature() - || substFunc->getSubstGenericSignature()) { - if (func->getSubstGenericSignature() - != substFunc->getSubstGenericSignature()) + if (func->getPatternGenericSignature() + || substFunc->getPatternGenericSignature()) { + if (func->getPatternGenericSignature() + != substFunc->getPatternGenericSignature()) return CanType(); - auto sig = func->getSubstGenericSignature(); - - auto origSubs = func->getSubstitutions(); - auto substSubs = substFunc->getSubstitutions(); + auto sig = func->getPatternGenericSignature(); - if (!origSubs || !substSubs) - return CanType(); + auto origSubs = func->getPatternSubstitutions(); + auto substSubs = substFunc->getPatternSubstitutions(); for (unsigned i : indices(origSubs.getReplacementTypes())) { auto origType = @@ -3655,10 +3682,17 @@ static Type substType(Type derivedType, } if (auto silFnTy = dyn_cast(type)) { - if (auto subs = silFnTy->getSubstitutions()) { + if (silFnTy->isPolymorphic()) + return None; + if (auto subs = silFnTy->getInvocationSubstitutions()) { auto newSubs = subs.subst(substitutions, lookupConformances, options); - return silFnTy->withSubstitutions(newSubs); + return silFnTy->withInvocationSubstitutions(newSubs); } + if (auto subs = silFnTy->getPatternSubstitutions()) { + auto newSubs = subs.subst(substitutions, lookupConformances, options); + return silFnTy->withPatternSubstitutions(newSubs); + } + return None; } // Special-case TypeAliasType; we need to substitute conformances. @@ -4180,13 +4214,13 @@ case TypeKind::Id: case TypeKind::SILFunction: { auto fnTy = cast(base); bool changed = false; - - if (auto subs = fnTy->getSubstitutions()) { + + auto updateSubs = [&](SubstitutionMap &subs) -> bool { // This interface isn't suitable for updating the substitution map in a // substituted SILFunctionType. // TODO(SILFunctionType): Is it suitable for any SILFunctionType?? SmallVector newReplacements; - for (Type type : fnTy->getSubstitutions().getReplacementTypes()) { + for (Type type : subs.getReplacementTypes()) { auto transformed = type.transformRec(fn); assert((type->isEqual(transformed) || (type->hasTypeParameter() && transformed->hasTypeParameter())) @@ -4195,12 +4229,29 @@ case TypeKind::Id: if (!type->isEqual(transformed)) changed = true; } - + if (changed) { - auto newSubs = SubstitutionMap::get(fnTy->getSubstitutions().getGenericSignature(), - newReplacements, - fnTy->getSubstitutions().getConformances()); - return fnTy->withSubstitutions(newSubs); + subs = SubstitutionMap::get(subs.getGenericSignature(), + newReplacements, + subs.getConformances()); + } + + return changed; + }; + + if (fnTy->isPolymorphic()) + return fnTy; + + if (auto subs = fnTy->getInvocationSubstitutions()) { + if (updateSubs(subs)) { + return fnTy->withInvocationSubstitutions(subs); + } + return fnTy; + } + + if (auto subs = fnTy->getPatternSubstitutions()) { + if (updateSubs(subs)) { + return fnTy->withPatternSubstitutions(subs); } return fnTy; } @@ -4233,7 +4284,7 @@ case TypeKind::Id: if (!changed) return *this; return SILFunctionType::get( - fnTy->getSubstGenericSignature(), + fnTy->getInvocationGenericSignature(), fnTy->getExtInfo(), fnTy->getCoroutineKind(), fnTy->getCalleeConvention(), @@ -4242,7 +4293,7 @@ case TypeKind::Id: transInterfaceResults, transErrorResult, SubstitutionMap(), - /*genericSigIsImplied*/ false, + SubstitutionMap(), Ptr->getASTContext(), fnTy->getWitnessMethodConformanceOrInvalid()); } @@ -5168,13 +5219,37 @@ AnyFunctionType *AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType( } CanSILFunctionType -SILFunctionType::withSubstitutions(SubstitutionMap subs) const { - return SILFunctionType::get(getSubstGenericSignature(), +SILFunctionType::withInvocationSubstitutions(SubstitutionMap subs) const { + subs = subs.getCanonical(); + if (subs == getInvocationSubstitutions()) + return CanSILFunctionType(const_cast(this)); + + assert(!subs || CanGenericSignature(subs.getGenericSignature()) + == getInvocationGenericSignature()); + return SILFunctionType::get(getInvocationGenericSignature(), + getExtInfo(), getCoroutineKind(), + getCalleeConvention(), + getParameters(), getYields(), getResults(), + getOptionalErrorResult(), + getPatternSubstitutions(), subs, + const_cast(this)->getASTContext(), + getWitnessMethodConformanceOrInvalid()); +} + +CanSILFunctionType +SILFunctionType::withPatternSubstitutions(SubstitutionMap subs) const { + subs = subs.getCanonical(); + if (subs == getPatternSubstitutions()) + return CanSILFunctionType(const_cast(this)); + + assert(!subs || CanGenericSignature(subs.getGenericSignature()) + == getPatternGenericSignature()); + return SILFunctionType::get(getInvocationGenericSignature(), getExtInfo(), getCoroutineKind(), getCalleeConvention(), getParameters(), getYields(), getResults(), getOptionalErrorResult(), - subs.getCanonical(), isGenericSignatureImplied(), + subs, getInvocationSubstitutions(), const_cast(this)->getASTContext(), getWitnessMethodConformanceOrInvalid()); } diff --git a/lib/AST/TypeWalker.cpp b/lib/AST/TypeWalker.cpp index 3491055221da7..aed203667230e 100644 --- a/lib/AST/TypeWalker.cpp +++ b/lib/AST/TypeWalker.cpp @@ -118,12 +118,20 @@ class Traversal : public TypeVisitor bool visitSILFunctionType(SILFunctionType *ty) { // TODO: Should this be the only kind of walk we allow? - if (auto subs = ty->getSubstitutions()) { + if (auto subs = ty->getInvocationSubstitutions()) { for (auto paramTy : subs.getReplacementTypes()) { if (doIt(paramTy)) return true; } - + + return false; + } + if (auto subs = ty->getPatternSubstitutions()) { + for (auto paramTy : subs.getReplacementTypes()) { + if (doIt(paramTy)) + return true; + } + return false; } diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index 66242cbb22787..42dc1b29685a3 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1738,12 +1738,27 @@ NodePointer Demangler::demangleImplFunctionType() { NodePointer SubstitutionRetroConformances; if (!demangleBoundGenerics(Substitutions, SubstitutionRetroConformances)) return nullptr; - - bool isImplied = !nextIf('i'); - - auto subsNode = createNode(isImplied - ? Node::Kind::ImplImpliedSubstitutions - : Node::Kind::ImplSubstitutions); + + NodePointer sig = popNode(Node::Kind::DependentGenericSignature); + if (!sig) + return nullptr; + + auto subsNode = createNode(Node::Kind::ImplPatternSubstitutions); + subsNode->addChild(sig, *this); + assert(Substitutions.size() == 1); + subsNode->addChild(Substitutions[0], *this); + if (SubstitutionRetroConformances) + subsNode->addChild(SubstitutionRetroConformances, *this); + type->addChild(subsNode, *this); + } + + if (nextIf('I')) { + Vector Substitutions; + NodePointer SubstitutionRetroConformances; + if (!demangleBoundGenerics(Substitutions, SubstitutionRetroConformances)) + return nullptr; + + auto subsNode = createNode(Node::Kind::ImplInvocationSubstitutions); assert(Substitutions.size() == 1); subsNode->addChild(Substitutions[0], *this); if (SubstitutionRetroConformances) diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index e008abbb0eb11..f45a5bd2de6f2 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -390,8 +390,8 @@ class NodePrinter { case Node::Kind::ImplConvention: case Node::Kind::ImplFunctionAttribute: case Node::Kind::ImplFunctionType: - case Node::Kind::ImplImpliedSubstitutions: - case Node::Kind::ImplSubstitutions: + case Node::Kind::ImplInvocationSubstitutions: + case Node::Kind::ImplPatternSubstitutions: case Node::Kind::ImplicitClosure: case Node::Kind::ImplParameter: case Node::Kind::ImplResult: @@ -748,12 +748,21 @@ class NodePrinter { } void printImplFunctionType(NodePointer fn) { + NodePointer patternSubs = nullptr; + NodePointer invocationSubs = nullptr; enum State { Attrs, Inputs, Results } curState = Attrs; auto transitionTo = [&](State newState) { assert(newState >= curState); for (; curState != newState; curState = State(curState + 1)) { switch (curState) { - case Attrs: Printer << '('; continue; + case Attrs: + if (patternSubs) { + Printer << "@substituted "; + print(patternSubs->getChild(0)); + Printer << ' '; + } + Printer << '('; + continue; case Inputs: Printer << ") -> ("; continue; case Results: printer_unreachable("no state after Results"); } @@ -772,6 +781,10 @@ class NodePrinter { if (curState == Results) Printer << ", "; transitionTo(Results); print(child); + } else if (child->getKind() == Node::Kind::ImplPatternSubstitutions) { + patternSubs = child; + } else if (child->getKind() == Node::Kind::ImplInvocationSubstitutions) { + invocationSubs = child; } else { assert(curState == Attrs); print(child); @@ -780,6 +793,17 @@ class NodePrinter { } transitionTo(Results); Printer << ')'; + + if (patternSubs) { + Printer << " for <"; + printChildren(patternSubs->getChild(1)); + Printer << '>'; + } + if (invocationSubs) { + Printer << " for <"; + printChildren(invocationSubs->getChild(0)); + Printer << '>'; + } } void printFunctionSigSpecializationParams(NodePointer Node); @@ -2025,13 +2049,17 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) { case Node::Kind::ImplFunctionType: printImplFunctionType(Node); return nullptr; - case Node::Kind::ImplSubstitutions: - case Node::Kind::ImplImpliedSubstitutions: + case Node::Kind::ImplInvocationSubstitutions: Printer << "for <"; printChildren(Node->getChild(0), ", "); Printer << '>'; - if (kind == Node::Kind::ImplImpliedSubstitutions) - Printer << " in"; + return nullptr; + case Node::Kind::ImplPatternSubstitutions: + Printer << "@substituted "; + print(Node->getChild(0)); + Printer << " for <"; + printChildren(Node->getChild(1), ", "); + Printer << '>'; return nullptr; case Node::Kind::ErrorType: Printer << ""; diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index e23136837db40..9f1fda4a99f90 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -1262,11 +1262,11 @@ void Remangler::mangleImplEscaping(Node *node) { // The old mangler does not encode escaping. } -void Remangler::mangleImplSubstitutions(Node *node) { +void Remangler::mangleImplPatternSubstitutions(Node *node) { // The old mangler does not encode substituted function types. } -void Remangler::mangleImplImpliedSubstitutions(Node *node) { +void Remangler::mangleImplInvocationSubstitutions(Node *node) { // The old mangler does not encode substituted function types. } diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index a8b660e773bf6..cb9b6e97e27e2 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -1396,19 +1396,19 @@ void Remangler::mangleImplFunctionAttribute(Node *node) { unreachable("handled inline"); } -void Remangler::mangleImplSubstitutions(Node *node) { +void Remangler::mangleImplInvocationSubstitutions(Node *node) { unreachable("handled inline"); } -void Remangler::mangleImplImpliedSubstitutions(Node *node) { +void Remangler::mangleImplPatternSubstitutions(Node *node) { unreachable("handled inline"); } void Remangler::mangleImplFunctionType(Node *node) { const char *PseudoGeneric = ""; Node *GenSig = nullptr; - Node *GenSubs = nullptr; - bool isImplied; + Node *PatternSubs = nullptr; + Node *InvocationSubs = nullptr; for (NodePointer Child : *node) { switch (auto kind = Child->getKind()) { case Node::Kind::ImplParameter: @@ -1423,10 +1423,11 @@ void Remangler::mangleImplFunctionType(Node *node) { case Node::Kind::DependentGenericSignature: GenSig = Child; break; - case Node::Kind::ImplSubstitutions: - case Node::Kind::ImplImpliedSubstitutions: - GenSubs = Child; - isImplied = kind == Node::Kind::ImplImpliedSubstitutions; + case Node::Kind::ImplPatternSubstitutions: + PatternSubs = Child; + break; + case Node::Kind::ImplInvocationSubstitutions: + InvocationSubs = Child; break; default: break; @@ -1434,20 +1435,26 @@ void Remangler::mangleImplFunctionType(Node *node) { } if (GenSig) mangle(GenSig); - if (GenSubs) { + if (InvocationSubs) { + Buffer << 'y'; + mangleChildNodes(InvocationSubs->getChild(0)); + if (InvocationSubs->getNumChildren() >= 2) + mangleRetroactiveConformance(InvocationSubs->getChild(1)); + } + if (PatternSubs) { + mangle(PatternSubs->getChild(0)); Buffer << 'y'; - mangleChildNodes(GenSubs->getChild(0)); - if (GenSubs->getNumChildren() >= 2) - mangleRetroactiveConformance(GenSubs->getChild(1)); + mangleChildNodes(PatternSubs->getChild(1)); + if (PatternSubs->getNumChildren() >= 3) + mangleRetroactiveConformance(PatternSubs->getChild(2)); } Buffer << 'I'; - if (GenSubs) { + if (PatternSubs) Buffer << 's'; - if (!isImplied) - Buffer << 'i'; - } + if (InvocationSubs) + Buffer << 'I'; Buffer << PseudoGeneric; for (NodePointer Child : *node) { diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index e29f60a352f83..aebcafd6d04a8 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -3060,7 +3060,8 @@ GenericTypeRequirements::GenericTypeRequirements(IRGenModule &IGM, /*callee*/ ParameterConvention::Direct_Unowned, /*params*/ {}, /*yields*/ {}, /*results*/ {}, /*error*/ None, - /*subs*/ SubstitutionMap(), /*implied*/ false, + /*pattern subs*/ SubstitutionMap(), + /*invocation subs*/ SubstitutionMap(), IGM.Context); // Figure out what we're actually still required to pass diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp index cf74cb3113856..afdf4fe5e1ab8 100644 --- a/lib/IRGen/GenReflection.cpp +++ b/lib/IRGen/GenReflection.cpp @@ -1156,7 +1156,7 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder { B.addInt32(Layout.getBindings().size()); auto sig = - OrigCalleeType->getSubstGenericSignature().getCanonicalSignature(); + OrigCalleeType->getInvocationGenericSignature().getCanonicalSignature(); // Now add typerefs of all of the captures. for (auto CaptureType : CaptureTypes) { diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp index 05fb06bbd7e47..933a7d1b78f36 100644 --- a/lib/IRGen/LoadableByAddress.cpp +++ b/lib/IRGen/LoadableByAddress.cpp @@ -150,7 +150,7 @@ bool LargeSILTypeMapper::shouldTransformFunctionType(GenericEnvironment *env, irgen::IRGenModule &IGM) { // Map substituted function types according to their substituted generic // signature. - if (fnType->getSubstitutions()) { + if (fnType->getPatternSubstitutions()) { env = getSubstGenericEnvironment(fnType); } @@ -287,7 +287,7 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env, // Map substituted function types according to their substituted generic // signature. - if (fnType->getSubstitutions()) { + if (fnType->getPatternSubstitutions()) { env = getSubstGenericEnvironment(fnType); } @@ -295,7 +295,7 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env, auto newYields = getNewYields(env, fnType, IGM); auto newResults = getNewResults(env, fnType, IGM); auto newFnType = SILFunctionType::get( - fnType->getSubstGenericSignature(), + fnType->getInvocationGenericSignature(), fnType->getExtInfo(), fnType->getCoroutineKind(), fnType->getCalleeConvention(), @@ -303,8 +303,8 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env, newYields, newResults, fnType->getOptionalErrorResult(), - fnType->getSubstitutions(), - fnType->isGenericSignatureImplied(), + fnType->getPatternSubstitutions(), + fnType->getInvocationSubstitutions(), fnType->getASTContext(), fnType->getWitnessMethodConformanceOrInvalid()); return newFnType; @@ -2359,7 +2359,8 @@ static bool rewriteFunctionReturn(StructLoweringState &pass) { loweredTy->getParameters(), loweredTy->getYields(), newSILResultInfo, loweredTy->getOptionalErrorResult(), - loweredTy->getSubstitutions(), loweredTy->isGenericSignatureImplied(), + loweredTy->getPatternSubstitutions(), + loweredTy->getInvocationSubstitutions(), F->getModule().getASTContext(), loweredTy->getWitnessMethodConformanceOrInvalid()); F->rewriteLoweredTypeUnsafe(NewTy); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index b0f08d6c71a0f..e89c35f27daa5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3236,6 +3236,10 @@ bool Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier, SyntaxParsingContext AttrListCtx(SyntaxContext, SyntaxKind::AttributeList); while (Tok.is(tok::at_sign)) { + // Ignore @substituted in SIL mode and leave it for the type parser. + if (isInSILMode() && peekToken().getText() == "substituted") + return false; + if (Attributes.AtLoc.isInvalid()) Attributes.AtLoc = Tok.getLoc(); SyntaxParsingContext AttrCtx(SyntaxContext, SyntaxKind::Attribute); diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index 897661f4c93d2..4e5c98472bec2 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -371,10 +371,12 @@ ParserResult Parser::parseType(Diag<> MessageID, parseTypeAttributeList(specifier, specifierLoc, attrs); Optional GenericsScope; + Optional patternGenericsScope; // Parse generic parameters in SIL mode. GenericParamList *generics = nullptr; - bool isImplied = false; + SourceLoc substitutedLoc; + GenericParamList *patternGenerics = nullptr; if (isInSILMode()) { // If this is part of a sil function decl, generic parameters are visible in // the function body; otherwise, they are visible when parsing the type. @@ -382,11 +384,24 @@ ParserResult Parser::parseType(Diag<> MessageID, GenericsScope.emplace(this, ScopeKind::Generics); generics = maybeParseGenericParams().getPtrOrNull(); - isImplied = consumeIf(tok::kw_in); + if (Tok.is(tok::at_sign) && peekToken().getText() == "substituted") { + consumeToken(tok::at_sign); + substitutedLoc = consumeToken(tok::identifier); + patternGenericsScope.emplace(this, ScopeKind::Generics); + patternGenerics = maybeParseGenericParams().getPtrOrNull(); + if (!patternGenerics) { + diagnose(Tok.getLoc(), diag::sil_function_subst_expected_generics); + patternGenericsScope.reset(); + } + } } // In SIL mode, parse box types { ... }. if (isInSILMode() && Tok.is(tok::l_brace)) { + if (patternGenerics) { + diagnose(Tok.getLoc(), diag::sil_function_subst_expected_function); + patternGenericsScope.reset(); + } return parseSILBoxType(generics, attrs, GenericsScope); } @@ -482,45 +497,81 @@ ParserResult Parser::parseType(Diag<> MessageID, } // Parse substitutions for substituted SIL types. - SourceLoc SubsLAngleLoc, SubsRAngleLoc; - MutableArrayRef SubsTypes; - if (isInSILMode() && consumeIf(tok::kw_for)) { - if (!startsWithLess(Tok)) { - diagnose(Tok, diag::sil_function_subst_expected_l_angle); - return makeParserError(); - } - - SubsLAngleLoc = consumeStartingLess(); + MutableArrayRef invocationSubsTypes; + MutableArrayRef patternSubsTypes; + if (isInSILMode()) { + auto parseSubstitutions = + [&](MutableArrayRef &subs) -> Optional { + if (!consumeIf(tok::kw_for)) return None; + + if (!startsWithLess(Tok)) { + diagnose(Tok, diag::sil_function_subst_expected_l_angle); + return false; + } + + consumeStartingLess(); + + SmallVector SubsTypesVec; + for (;;) { + auto argTy = parseType(); + if (!argTy.getPtrOrNull()) + return false; + SubsTypesVec.push_back(argTy.get()); + if (consumeIf(tok::comma)) + continue; + break; + } + if (!startsWithGreater(Tok)) { + diagnose(Tok, diag::sil_function_subst_expected_r_angle); + return false; + } + consumeStartingGreater(); - SmallVector SubsTypesVec; - for (;;) { - auto argTy = parseType(); - if (!argTy.getPtrOrNull()) + subs = Context.AllocateCopy(SubsTypesVec); + return true; + }; + + // Parse pattern substitutions. These must exist if we had pattern + // generics above. + if (patternGenerics) { + // These substitutions are outside of the scope of the + // pattern generics. + patternGenericsScope.reset(); + + auto result = parseSubstitutions(patternSubsTypes); + if (!result || patternSubsTypes.empty()) { + diagnose(Tok, diag::sil_function_subst_expected_subs); + patternGenerics = nullptr; + } else if (!*result) { return makeParserError(); - SubsTypesVec.push_back(argTy.get()); - if (consumeIf(tok::comma)) - continue; - break; + } } - if (!startsWithGreater(Tok)) { - diagnose(Tok, diag::sil_function_subst_expected_r_angle); - return makeParserError(); + + if (generics) { + // These substitutions are outside of the scope of the + // invocation generics. + GenericsScope.reset(); + + if (auto result = parseSubstitutions(invocationSubsTypes)) + if (!*result) return makeParserError(); } - - SubsRAngleLoc = consumeStartingGreater(); - SubsTypes = Context.AllocateCopy(SubsTypesVec); + if (Tok.is(tok::kw_for)) { + diagnose(Tok, diag::sil_function_subs_without_generics); + return makeParserError(); + } } tyR = new (Context) FunctionTypeRepr(generics, argsTyR, throwsLoc, arrowLoc, SecondHalf.get(), - isImplied, - SubsTypes); - } else if (generics) { + patternGenerics, patternSubsTypes, + invocationSubsTypes); + } else if (auto firstGenerics = generics ? generics : patternGenerics) { // Only function types may be generic. - auto brackets = generics->getSourceRange(); + auto brackets = firstGenerics->getSourceRange(); diagnose(brackets.Start, diag::generic_non_function); GenericsScope.reset(); + patternGenericsScope.reset(); // Forget any generic parameters we saw in the type. class EraseTypeParamWalker : public ASTWalker { diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp index 4a5fa989a702a..1dd46e0a5a7db 100644 --- a/lib/ParseSIL/ParseSIL.cpp +++ b/lib/ParseSIL/ParseSIL.cpp @@ -1222,6 +1222,10 @@ bool SILParser::parseSILType(SILType &Result, auto env = handleSILGenericParams(generics, SF); fnType->setGenericEnvironment(env); } + if (auto generics = fnType->getPatternGenericParams()) { + auto env = handleSILGenericParams(generics, SF); + fnType->setPatternGenericEnvironment(env); + } } if (auto boxType = dyn_cast(T)) { if (auto generics = boxType->getGenericParams()) { @@ -1237,9 +1241,8 @@ bool SILParser::parseSILType(SILType &Result, // Save the top-level function generic environment if there was one. if (auto fnType = dyn_cast(TyR.get())) - if (!fnType->areGenericParamsImplied()) - if (auto env = fnType->getGenericEnvironment()) - ParsedGenericEnv = env; + if (auto env = fnType->getGenericEnvironment()) + ParsedGenericEnv = env; // Apply attributes to the type. TypeLoc Ty = P.applyAttributeToType(TyR.get(), attrs, specifier, specifierLoc); @@ -2071,6 +2074,12 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired) { genericEnv = handleSILGenericParams(generics, &P.SF); fnType->setGenericEnvironment(genericEnv); } + if (auto generics = fnType->getPatternGenericParams()) { + assert(!Ty.wasValidated() && Ty.getType().isNull()); + + genericEnv = handleSILGenericParams(generics, &P.SF); + fnType->setPatternGenericEnvironment(genericEnv); + } } if (performTypeLocChecking(Ty, /*IsSILType=*/ false, genericEnv)) diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp index dced2ce800f5f..07ba5ff5d2b5a 100644 --- a/lib/SIL/SILBuilder.cpp +++ b/lib/SIL/SILBuilder.cpp @@ -97,9 +97,12 @@ SILType SILBuilder::getPartialApplyResultType( needsSubstFunctionType |= yield.getInterfaceType()->hasTypeParameter(); } - auto appliedFnType = SILFunctionType::get(needsSubstFunctionType - ? FTI->getSubstGenericSignature() - : nullptr, + SubstitutionMap appliedSubs; + if (needsSubstFunctionType) { + appliedSubs = FTI->getCombinedSubstitutions(); + } + + auto appliedFnType = SILFunctionType::get(nullptr, extInfo, FTI->getCoroutineKind(), calleeConvention, @@ -107,12 +110,8 @@ SILType SILBuilder::getPartialApplyResultType( FTI->getYields(), results, FTI->getOptionalErrorResult(), - needsSubstFunctionType - ? FTI->getSubstitutions() - : SubstitutionMap(), - needsSubstFunctionType - ? FTI->isGenericSignatureImplied() - : false, + appliedSubs, + SubstitutionMap(), M.getASTContext()); return SILType::getPrimitiveObjectType(appliedFnType); diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp index d1a553ee92356..678dc1cb43872 100644 --- a/lib/SIL/SILFunctionType.cpp +++ b/lib/SIL/SILFunctionType.cpp @@ -43,50 +43,60 @@ using namespace swift::Lowering; SILType SILFunctionType::substInterfaceType(SILModule &M, SILType interfaceType) const { - if (getSubstitutions().empty()) - return interfaceType; - - return interfaceType.subst(M, getSubstitutions()); + // Apply pattern substitutions first, then invocation substitutions. + if (auto subs = getPatternSubstitutions()) + interfaceType = interfaceType.subst(M, subs); + if (auto subs = getInvocationSubstitutions()) + interfaceType = interfaceType.subst(M, subs); + return interfaceType; } CanSILFunctionType SILFunctionType::getUnsubstitutedType(SILModule &M) const { auto mutableThis = const_cast(this); - if (!getSubstitutions()) + + // If we have no substitutions, there's nothing to do. + if (!hasPatternSubstitutions() && !hasInvocationSubstitutions()) return CanSILFunctionType(mutableThis); - - if (!isGenericSignatureImplied()) - return withSubstitutions(SubstitutionMap()); - + + // Otherwise, substitute the component types. + SmallVector params; SmallVector yields; SmallVector results; Optional errorResult; + + auto subs = getCombinedSubstitutions(); + auto substComponentType = [&](CanType type) { + if (!type->hasTypeParameter()) return type; + return SILType::getPrimitiveObjectType(type) + .subst(M, subs).getASTType(); + }; for (auto param : getParameters()) { - params.push_back( - param.getWithInterfaceType(param.getArgumentType(M, this))); + params.push_back(param.map(substComponentType)); } for (auto yield : getYields()) { - yields.push_back( - yield.getWithInterfaceType(yield.getArgumentType(M, this))); + yields.push_back(yield.map(substComponentType)); } for (auto result : getResults()) { - results.push_back( - result.getWithInterfaceType(result.getReturnValueType(M, this))); + results.push_back(result.map(substComponentType)); } if (auto error = getOptionalErrorResult()) { - errorResult = - error->getWithInterfaceType(error->getReturnValueType(M, this)); + errorResult = error->map(substComponentType); } - - return SILFunctionType::get(GenericSignature(), getExtInfo(), + + auto signature = isPolymorphic() ? getInvocationGenericSignature() + : CanGenericSignature(); + return SILFunctionType::get(signature, + getExtInfo(), getCoroutineKind(), getCalleeConvention(), params, yields, results, errorResult, - SubstitutionMap(), false, + SubstitutionMap(), + SubstitutionMap(), mutableThis->getASTContext(), getWitnessMethodConformanceOrInvalid()); } @@ -219,10 +229,10 @@ SILFunctionType::getWithDifferentiability(DifferentiabilityKind kind, : SILParameterDifferentiability::NotDifferentiable)); } auto newExtInfo = getExtInfo().withDifferentiabilityKind(kind); - return get(getSubstGenericSignature(), newExtInfo, getCoroutineKind(), + return get(getInvocationGenericSignature(), newExtInfo, getCoroutineKind(), getCalleeConvention(), newParameters, getYields(), getResults(), - getOptionalErrorResult(), getSubstitutions(), - isGenericSignatureImplied(), getASTContext(), + getOptionalErrorResult(), getPatternSubstitutions(), + getInvocationSubstitutions(), getASTContext(), getWitnessMethodConformanceOrInvalid()); } @@ -235,11 +245,13 @@ CanSILFunctionType SILFunctionType::getWithoutDifferentiability() { for (auto ¶m : getParameters()) newParams.push_back(param.getWithDifferentiability( SILParameterDifferentiability::DifferentiableOrNotApplicable)); - return SILFunctionType::get(getSubstGenericSignature(), nondiffExtInfo, + return SILFunctionType::get(getInvocationGenericSignature(), nondiffExtInfo, getCoroutineKind(), getCalleeConvention(), newParams, getYields(), getResults(), - getOptionalErrorResult(), getSubstitutions(), - isGenericSignatureImplied(), getASTContext()); + getOptionalErrorResult(), + getPatternSubstitutions(), + getInvocationSubstitutions(), + getASTContext()); } CanSILFunctionType SILFunctionType::getAutoDiffDerivativeFunctionType( @@ -366,8 +378,8 @@ CanSILFunctionType SILFunctionType::getAutoDiffDerivativeFunctionType( closureType = SILFunctionType::get( /*genericSignature*/ nullptr, ExtInfo(), SILCoroutineKind::None, ParameterConvention::Direct_Guaranteed, differentialParams, {}, - differentialResults, None, getSubstitutions(), - isGenericSignatureImplied(), ctx); + differentialResults, None, getCombinedSubstitutions(), + SubstitutionMap(), ctx); break; } case AutoDiffDerivativeFunctionKind::VJP: { @@ -402,7 +414,7 @@ CanSILFunctionType SILFunctionType::getAutoDiffDerivativeFunctionType( closureType = SILFunctionType::get( /*genericSignature*/ nullptr, ExtInfo(), SILCoroutineKind::None, ParameterConvention::Direct_Guaranteed, pullbackParams, {}, - pullbackResults, {}, getSubstitutions(), isGenericSignatureImplied(), + pullbackResults, {}, getCombinedSubstitutions(), SubstitutionMap(), ctx); break; } @@ -440,7 +452,7 @@ CanSILFunctionType SILFunctionType::getAutoDiffDerivativeFunctionType( cachedResult = SILFunctionType::get( canGenSig, extInfo, getCoroutineKind(), getCalleeConvention(), newParameters, getYields(), newResults, getOptionalErrorResult(), - getSubstitutions(), isGenericSignatureImplied(), ctx, + getPatternSubstitutions(), getInvocationSubstitutions(), ctx, getWitnessMethodConformanceOrInvalid()); return cachedResult; } @@ -528,7 +540,7 @@ CanSILFunctionType SILFunctionType::getAutoDiffTransposeFunctionType( return SILFunctionType::get( canGenSig, getExtInfo(), getCoroutineKind(), getCalleeConvention(), newParameters, getYields(), newResults, getOptionalErrorResult(), - getSubstitutions(), isGenericSignatureImplied(), getASTContext()); + getPatternSubstitutions(), getInvocationSubstitutions(), getASTContext()); } static CanType getKnownType(Optional &cacheSlot, ASTContext &C, @@ -599,13 +611,13 @@ Lowering::adjustFunctionType(CanSILFunctionType type, type->getWitnessMethodConformanceOrInvalid() == witnessMethodConformance) return type; - return SILFunctionType::get(type->getSubstGenericSignature(), + return SILFunctionType::get(type->getInvocationGenericSignature(), extInfo, type->getCoroutineKind(), callee, type->getParameters(), type->getYields(), type->getResults(), type->getOptionalErrorResult(), - type->getSubstitutions(), - type->isGenericSignatureImplied(), + type->getPatternSubstitutions(), + type->getInvocationSubstitutions(), type->getASTContext(), witnessMethodConformance); } @@ -627,10 +639,10 @@ CanSILFunctionType SILFunctionType::getWithExtInfo(ExtInfo newExt) { : Lowering::DefaultThickCalleeConvention) : ParameterConvention::Direct_Unowned); - return get(getSubstGenericSignature(), newExt, getCoroutineKind(), + return get(getInvocationGenericSignature(), newExt, getCoroutineKind(), calleeConvention, getParameters(), getYields(), getResults(), - getOptionalErrorResult(), getSubstitutions(), - isGenericSignatureImplied(), getASTContext(), + getOptionalErrorResult(), getPatternSubstitutions(), + getInvocationSubstitutions(), getASTContext(), getWitnessMethodConformanceOrInvalid()); } @@ -1476,6 +1488,17 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function, } } +static AccessorDecl *getAsCoroutineAccessor(Optional constant) { + if (!constant || !constant->hasDecl()) + return nullptr;; + + auto accessor = dyn_cast(constant->getDecl()); + if (!accessor || !accessor->isCoroutine()) + return nullptr; + + return accessor; +} + static void destructureYieldsForReadAccessor(TypeConverter &TC, TypeExpansionContext expansion, AbstractionPattern origType, @@ -1525,11 +1548,8 @@ static void destructureYieldsForCoroutine(TypeConverter &TC, assert(coroutineKind == SILCoroutineKind::None); assert(yields.empty()); - if (!constant || !constant->hasDecl()) - return; - - auto accessor = dyn_cast(constant->getDecl()); - if (!accessor || !accessor->isCoroutine()) + auto accessor = getAsCoroutineAccessor(constant); + if (!accessor) return; auto origAccessor = cast(origConstant->getDecl()); @@ -1653,21 +1673,27 @@ static CanSILFunctionType getSILFunctionType( substFormalResultType); } - - SubstFunctionTypeCollector subst(TC, - expansionContext, - TC.Context.LangOpts.EnableSubstSILFunctionTypesForFunctionValues + bool shouldBuildSubstFunctionType = [&]{ + if (!TC.Context.LangOpts.EnableSubstSILFunctionTypesForFunctionValues) + return false; + // We don't currently use substituted function types for generic function // type lowering, though we should for generic methods on classes and // protocols. - && !genericSig + if (genericSig) + return false; + // We only currently use substituted function types for function values, // which will have standard thin or thick representation. (Per the previous // comment, it would be useful to do so for generic methods on classes and // protocols too.) - && (extInfo.getSILRepresentation() == SILFunctionTypeRepresentation::Thick - || extInfo.getSILRepresentation() == SILFunctionTypeRepresentation::Thin - )); + auto rep = extInfo.getSILRepresentation(); + return (rep == SILFunctionTypeRepresentation::Thick || + rep == SILFunctionTypeRepresentation::Thin); + }(); + + SubstFunctionTypeCollector subst(TC, expansionContext, + shouldBuildSubstFunctionType); // Destructure the input tuple type. SmallVector inputs; @@ -1719,24 +1745,22 @@ static CanSILFunctionType getSILFunctionType( .withDifferentiabilityKind(extInfo.getDifferentiabilityKind()); // Build the substituted generic signature we extracted. - bool impliedSignature = false; SubstitutionMap substitutions; if (subst.Enabled) { if (!subst.substGenericParams.empty()) { - genericSig = GenericSignature::get(subst.substGenericParams, - subst.substRequirements) + auto subSig = GenericSignature::get(subst.substGenericParams, + subst.substRequirements) .getCanonicalSignature(); - substitutions = SubstitutionMap::get(genericSig, + substitutions = SubstitutionMap::get(subSig, llvm::makeArrayRef(subst.substReplacements), llvm::makeArrayRef(subst.substConformances)); - impliedSignature = true; } } return SILFunctionType::get(genericSig, silExtInfo, coroutineKind, calleeConvention, inputs, yields, results, errorResult, - substitutions, impliedSignature, + substitutions, SubstitutionMap(), TC.Context, witnessMethodConformance); } @@ -3081,42 +3105,157 @@ class SILTypeSubstituter : // When a function appears inside of another type, we only perform // substitutions if it is not polymorphic. CanSILFunctionType visitSILFunctionType(CanSILFunctionType origType) { - if (origType->isPolymorphic()) - return origType; - - return substSILFunctionType(origType); + return substSILFunctionType(origType, false); } - // Entry point for use by SILType::substGenericArgs(). - CanSILFunctionType substSILFunctionType(CanSILFunctionType origType) { - if (auto subs = origType->getSubstitutions()) { - // Substitute the substitutions. - SubstOptions options = None; - if (shouldSubstituteOpaqueArchetypes) - options |= SubstFlags::SubstituteOpaqueArchetypes; - - // Expand substituted type according to the expansion context. - auto newSubs = subs.subst(Subst, Conformances, options); - - // If we need to look through opaque types in this context, re-substitute - // according to the expansion context. - if (typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes()) { - newSubs = newSubs.subst([&](SubstitutableType *s) -> Type { - return substOpaqueTypesWithUnderlyingTypes(s->getCanonicalType(), - typeExpansionContext); - }, [&](CanType dependentType, - Type conformingReplacementType, - ProtocolDecl *conformedProtocol) -> ProtocolConformanceRef { - return substOpaqueTypesWithUnderlyingTypes( - ProtocolConformanceRef(conformedProtocol), - conformingReplacementType->getCanonicalType(), - typeExpansionContext); - }, SubstFlags::SubstituteOpaqueArchetypes); + SubstitutionMap substSubstitutions(SubstitutionMap subs) { + // Substitute the substitutions. + SubstOptions options = None; + if (shouldSubstituteOpaqueArchetypes) + options |= SubstFlags::SubstituteOpaqueArchetypes; + + // Expand substituted type according to the expansion context. + auto newSubs = subs.subst(Subst, Conformances, options); + + // If we need to look through opaque types in this context, re-substitute + // according to the expansion context. + newSubs = substOpaqueTypes(newSubs); + + return newSubs; + } + + SubstitutionMap substOpaqueTypes(SubstitutionMap subs) { + if (!typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes()) + return subs; + + return subs.subst([&](SubstitutableType *s) -> Type { + return substOpaqueTypesWithUnderlyingTypes(s->getCanonicalType(), + typeExpansionContext); + }, [&](CanType dependentType, + Type conformingReplacementType, + ProtocolDecl *conformedProtocol) -> ProtocolConformanceRef { + return substOpaqueTypesWithUnderlyingTypes( + ProtocolConformanceRef(conformedProtocol), + conformingReplacementType->getCanonicalType(), + typeExpansionContext); + }, SubstFlags::SubstituteOpaqueArchetypes); + } + + // Substitute a function type. + CanSILFunctionType substSILFunctionType(CanSILFunctionType origType, + bool isGenericApplication) { + assert((!isGenericApplication || origType->isPolymorphic()) && + "generic application without invocation signature or with " + "existing arguments"); + assert((!isGenericApplication || !shouldSubstituteOpaqueArchetypes) && + "generic application while substituting opaque archetypes"); + + // The general substitution rule is that we should only substitute + // into the free components of the type, i.e. the components that + // aren't inside a generic signature. That rule would say: + // + // - If there are invocation substitutions, just substitute those; + // the other components are necessarily inside the invocation + // generic signature. + // + // - Otherwise, if there's an invocation generic signature, + // substitute nothing. If we are applying generic arguments, + // add the appropriate invocation substitutions. + // + // - Otherwise, if there are pattern substitutions, just substitute + // those; the other components are inside the patttern generic + // signature. + // + // - Otherwise, substitute the basic components. + // + // There are two caveats here. The first is that we haven't yet + // written all the code that would be necessary in order to handle + // invocation substitutions everywhere, so we only build those if + // there are pattern substitutions on a polymorphic type, which is + // something that we only currently generate in narrow cases. + // Instead we substitute the generic arguments into the components + // and build a type with no invocation signature. + // + // The second is that this function is also used when substituting + // opaque archetypes. In this case, we may need to substitute + // into component types even within generic signatures. This is + // safe because the substitutions used in this case don't change + // generics, they just narrowly look through certain opaque archetypes. + // If substitutions are present, we still don't substitute into + // the basic components, in order to maintain the information about + // what was abstracted there. + + auto patternSubs = origType->getPatternSubstitutions(); + + // If we have an invocation signatture, we generally shouldn't + // substitute into the pattern substitutions and component types. + if (auto sig = origType->getInvocationGenericSignature()) { + // Substitute the invocation substitutions if present. + if (auto invocationSubs = origType->getInvocationSubstitutions()) { + assert(!isGenericApplication); + invocationSubs = substSubstitutions(invocationSubs); + auto substType = + origType->withInvocationSubstitutions(invocationSubs); + + // Also do opaque-type substitutions on the pattern substitutions + // if requested and applicable. + if (patternSubs) { + patternSubs = substOpaqueTypes(patternSubs); + substType = substType->withPatternSubstitutions(patternSubs); + } + + return substType; } - - return origType->withSubstitutions(newSubs); + + // Otherwise, we shouldn't substitute any components except + // when substituting opaque archetypes. + + // If we're substituting opaque archetypes, and there are pattern + // substitutions present, just substitute those and preserve the + // basic structure in the component types. Otherwise, fall through + // to substitute the component types. + if (shouldSubstituteOpaqueArchetypes) { + if (patternSubs) { + patternSubs = substOpaqueTypes(patternSubs); + return origType->withPatternSubstitutions(patternSubs); + } + // else fall down to component substitution + + // If we're doing a generic application, and there are pattern + // substitutions, build invocation substitutions and substitute + // opaque types in the pattern subs. Otherwise, fall through + // to substitue the component types as discussed above. + } else if (isGenericApplication) { + if (patternSubs) { + patternSubs = substOpaqueTypes(patternSubs); + auto substType = origType->withPatternSubstitutions(patternSubs); + + auto invocationSubs = SubstitutionMap::get(sig, Subst, Conformances); + substType = substType->withInvocationSubstitutions(invocationSubs); + + return substType; + } + // else fall down to component substitution + + // Otherwise, don't try to substitute bound components. + } else { + auto substType = origType; + if (patternSubs) { + patternSubs = substOpaqueTypes(patternSubs); + substType = substType->withPatternSubstitutions(patternSubs); + } + return substType; + } + + // Otherwise, if there are pattern substitutions, just substitute + // into those and don't touch the component types. + } else if (patternSubs) { + patternSubs = substSubstitutions(patternSubs); + return origType->withPatternSubstitutions(patternSubs); } + // Otherwise, we need to substitute component types. + SmallVector substResults; substResults.reserve(origType->getNumResults()); for (auto origResult : origType->getResults()) { @@ -3144,17 +3283,7 @@ class SILTypeSubstituter : if (auto conformance = origType->getWitnessMethodConformanceOrInvalid()) { assert(origType->getExtInfo().hasSelfParam()); auto selfType = origType->getSelfParameter().getInterfaceType(); - - // Apply substitutions using ourselves, because we're inside the - // implementation of SILType::subst here. - if (origType->getSubstitutions()) { - llvm::SaveAndRestore OldSubst(Subst, - QuerySubstitutionMap{origType->getSubstitutions()}); - llvm::SaveAndRestore OldConformances(Conformances, - LookUpConformanceInSubstitutionMap(origType->getSubstitutions())); - selfType = visit(selfType); - } - + // The Self type can be nested in a few layers of metatypes (etc.). while (auto metatypeType = dyn_cast(selfType)) { auto next = metatypeType.getInstanceType(); @@ -3186,15 +3315,14 @@ class SILTypeSubstituter : extInfo = extInfo.withIsPseudogeneric(false); auto genericSig = shouldSubstituteOpaqueArchetypes - ? origType->getSubstGenericSignature() - : nullptr; + ? origType->getInvocationGenericSignature() + : nullptr; return SILFunctionType::get(genericSig, extInfo, origType->getCoroutineKind(), origType->getCalleeConvention(), substParams, substYields, substResults, substErrorResult, - origType->getSubstitutions(), - origType->isGenericSignatureImplied(), + SubstitutionMap(), SubstitutionMap(), TC.Context, witnessMethodConformance); } @@ -3345,7 +3473,7 @@ SILFunctionType::substGenericArgs(SILModule &silModule, SILTypeSubstituter substituter(silModule.Types, context, subs, conformances, getSubstGenericSignature(), /*shouldSubstituteOpaqueTypes*/ false); - return substituter.substSILFunctionType(CanSILFunctionType(this)); + return substituter.substSILFunctionType(CanSILFunctionType(this), true); } CanSILFunctionType @@ -3363,7 +3491,7 @@ SILFunctionType::substituteOpaqueArchetypes(TypeConverter &TC, getSubstGenericSignature(), /*shouldSubstituteOpaqueTypes*/ true); auto resTy = - substituter.substSILFunctionType(CanSILFunctionType(this)); + substituter.substSILFunctionType(CanSILFunctionType(this), false); return resTy; } diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 17302665529ff..a326c9a0cc87b 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -445,7 +445,8 @@ static void printSILFunctionNameAndType( llvm::DenseMap &sugaredTypeNames) { function->printName(OS); OS << " : $"; - auto genSig = function->getLoweredFunctionType()->getSubstGenericSignature(); + auto genSig = + function->getLoweredFunctionType()->getInvocationGenericSignature(); auto *genEnv = function->getGenericEnvironment(); // If `genSig` and `genEnv` are both defined, get sugared names of generic // parameter types for printing. diff --git a/lib/SIL/SILType.cpp b/lib/SIL/SILType.cpp index 99df4598d9fcb..748c495b15286 100644 --- a/lib/SIL/SILType.cpp +++ b/lib/SIL/SILType.cpp @@ -389,11 +389,14 @@ SILType::canUseExistentialRepresentation(ExistentialRepresentation repr, } SILType SILType::mapTypeOutOfContext() const { - return SILType::getPrimitiveType(getASTType()->mapTypeOutOfContext() - ->getCanonicalType(), + return SILType::getPrimitiveType(mapTypeOutOfContext(getASTType()), getCategory()); } +CanType SILType::mapTypeOutOfContext(CanType type) { + return type->mapTypeOutOfContext()->getCanonicalType(); +} + CanType swift::getSILBoxFieldLoweredType(TypeExpansionContext context, SILBoxType *type, TypeConverter &TC, unsigned index) { @@ -661,11 +664,13 @@ TypeBase::replaceSubstitutedSILFunctionTypesWithUnsubstituted(SILModule &M) cons if (!didChange) return sft; - return SILFunctionType::get(sft->getSubstGenericSignature(), + return SILFunctionType::get(sft->getInvocationGenericSignature(), sft->getExtInfo(), sft->getCoroutineKind(), sft->getCalleeConvention(), newParams, newYields, newResults, - newErrorResult, SubstitutionMap(), false, + newErrorResult, + SubstitutionMap(), + SubstitutionMap(), M.getASTContext()); } return t; diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp index e6e01351d3276..71e06f244e542 100644 --- a/lib/SIL/SILVerifier.cpp +++ b/lib/SIL/SILVerifier.cpp @@ -2957,7 +2957,7 @@ class SILVerifier : public SILVerifierBase { methodTy->getYields(), dynResults, methodTy->getOptionalErrorResult(), - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), F.getASTContext()); return SILType::getPrimitiveObjectType(fnTy); } diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index f5e80b018c416..3b94c33d7d73e 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -434,7 +434,8 @@ SILGenModule::getKeyPathProjectionCoroutine(bool isReadAccess, yields, /*results*/ {}, /*error result*/ {}, - SubstitutionMap(), false, + SubstitutionMap(), + SubstitutionMap(), getASTContext()); auto env = sig->getGenericEnvironment(); @@ -495,7 +496,7 @@ SILFunction *SILGenModule::emitTopLevelFunction(SILLocation Loc) { SILResultInfo(Int32Ty, ResultConvention::Unowned), None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), C); SILGenFunctionBuilder builder(*this); diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 0eb946aef1e42..beca848414c0d 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -577,7 +577,8 @@ ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc, genericSig, extInfo, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, blockInterfaceTy->getResults(), - blockInterfaceTy->getOptionalErrorResult(), SubstitutionMap(), false, + blockInterfaceTy->getOptionalErrorResult(), + SubstitutionMap(), SubstitutionMap(), getASTContext()); // Create the invoke function. Borrow the mangling scheme from reabstraction diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index e3df8b3b98a41..c43126ea39395 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2715,7 +2715,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, result, None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), SGM.getASTContext()); }(); @@ -2864,7 +2864,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, {}, None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), SGM.getASTContext()); }(); @@ -3046,7 +3046,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), C); // Mangle the name of the thunk to see if we already created it. @@ -3220,7 +3220,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, None, - SubstitutionMap(), false, C); + SubstitutionMap(), SubstitutionMap(), C); // Mangle the name of the thunk to see if we already created it. SmallString<64> nameBuf; diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 71e29ea3f89e2..53b9621c685bf 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -588,7 +588,7 @@ void SILGenFunction::emitArtificialTopLevel(ClassDecl *mainClass) { SILResultInfo(OptNSStringTy, ResultConvention::Autoreleased), /*error result*/ None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), ctx); auto NSStringFromClassFn = builder.getOrCreateFunction( mainClass, "NSStringFromClass", SILLinkage::PublicExternal, @@ -675,7 +675,7 @@ void SILGenFunction::emitArtificialTopLevel(ClassDecl *mainClass) { SILResultInfo(argc->getType().getASTType(), ResultConvention::Unowned), /*error result*/ None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), getASTContext()); SILGenFunctionBuilder builder(SGM); diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 66f58155f7870..af797a963d19b 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -3042,8 +3042,10 @@ CanSILFunctionType SILGenFunction::buildThunkType( bool withoutActuallyEscaping) { // We shouldn't be thunking generic types here, and substituted function types // ought to have their substitutions applied before we get here. - assert(!expectedType->isPolymorphic() && !expectedType->getSubstitutions()); - assert(!sourceType->isPolymorphic() && !sourceType->getSubstitutions()); + assert(!expectedType->isPolymorphic() && + !expectedType->getCombinedSubstitutions()); + assert(!sourceType->isPolymorphic() && + !sourceType->getCombinedSubstitutions()); // Can't build a thunk without context, so we require ownership semantics // on the result type. @@ -3093,36 +3095,40 @@ CanSILFunctionType SILGenFunction::buildThunkType( newArchetype); } + auto substTypeHelper = [&](SubstitutableType *type) -> Type { + if (CanType(type) == openedExistential) + return newArchetype; + return Type(type).subst(contextSubs); + }; + auto substConformanceHelper = + LookUpConformanceInSubstitutionMap(contextSubs); + // Utility function to apply contextSubs, and also replace the // opened existential with the new archetype. - auto substIntoThunkContext = [&](CanType t) -> CanType { - return t.subst( - [&](SubstitutableType *type) -> Type { - if (CanType(type) == openedExistential) - return newArchetype; - return Type(type).subst(contextSubs); - }, - LookUpConformanceInSubstitutionMap(contextSubs), - SubstFlags::AllowLoweredTypes) - ->getCanonicalType(); + auto substFormalTypeIntoThunkContext = + [&](CanType t) -> CanType { + return t.subst(substTypeHelper, substConformanceHelper) + ->getCanonicalType(); + }; + auto substLoweredTypeIntoThunkContext = + [&](CanSILFunctionType t) -> CanSILFunctionType { + return SILType::getPrimitiveObjectType(t) + .subst(SGM.M, substTypeHelper, substConformanceHelper) + .castTo(); }; - sourceType = cast( - substIntoThunkContext(sourceType)); - expectedType = cast( - substIntoThunkContext(expectedType)); + sourceType = substLoweredTypeIntoThunkContext(sourceType); + expectedType = substLoweredTypeIntoThunkContext(expectedType); bool hasDynamicSelf = false; if (inputSubstType) { - inputSubstType = cast( - substIntoThunkContext(inputSubstType)); + inputSubstType = substFormalTypeIntoThunkContext(inputSubstType); hasDynamicSelf |= inputSubstType->hasDynamicSelfType(); } if (outputSubstType) { - outputSubstType = cast( - substIntoThunkContext(outputSubstType)); + outputSubstType = substFormalTypeIntoThunkContext(outputSubstType); hasDynamicSelf |= outputSubstType->hasDynamicSelfType(); } @@ -3159,40 +3165,35 @@ CanSILFunctionType SILGenFunction::buildThunkType( params.push_back({dynamicSelfType, ParameterConvention::Direct_Unowned}); } + auto mapTypeOutOfContext = [&](CanType type) -> CanType { + return type->mapTypeOutOfContext()->getCanonicalType(genericSig); + }; + // Map the parameter and expected types out of context to get the interface // type of the thunk. SmallVector interfaceParams; interfaceParams.reserve(params.size()); for (auto ¶m : params) { - auto paramIfaceTy = param.getInterfaceType()->mapTypeOutOfContext(); - interfaceParams.push_back( - SILParameterInfo(paramIfaceTy->getCanonicalType(genericSig), - param.getConvention())); + auto interfaceParam = param.map(mapTypeOutOfContext); + interfaceParams.push_back(interfaceParam); } SmallVector interfaceYields; for (auto &yield : expectedType->getYields()) { - auto yieldIfaceTy = yield.getInterfaceType()->mapTypeOutOfContext(); - auto interfaceYield = - yield.getWithInterfaceType(yieldIfaceTy->getCanonicalType(genericSig)); + auto interfaceYield = yield.map(mapTypeOutOfContext); interfaceYields.push_back(interfaceYield); } SmallVector interfaceResults; for (auto &result : expectedType->getResults()) { - auto resultIfaceTy = result.getInterfaceType()->mapTypeOutOfContext(); - auto interfaceResult = - result.getWithInterfaceType(resultIfaceTy->getCanonicalType(genericSig)); + auto interfaceResult = result.map(mapTypeOutOfContext); interfaceResults.push_back(interfaceResult); } Optional interfaceErrorResult; if (expectedType->hasErrorResult()) { auto errorResult = expectedType->getErrorResult(); - auto errorIfaceTy = errorResult.getInterfaceType()->mapTypeOutOfContext(); - interfaceErrorResult = SILResultInfo( - errorIfaceTy->getCanonicalType(genericSig), - expectedType->getErrorResult().getConvention()); + interfaceErrorResult = errorResult.map(mapTypeOutOfContext);; } // The type of the thunk function. @@ -3201,8 +3202,8 @@ CanSILFunctionType SILGenFunction::buildThunkType( ParameterConvention::Direct_Unowned, interfaceParams, interfaceYields, interfaceResults, interfaceErrorResult, - expectedType->getSubstitutions(), - expectedType->isGenericSignatureImplied(), + expectedType->getPatternSubstitutions(), + SubstitutionMap(), getASTContext()); } @@ -3243,7 +3244,7 @@ static ManagedValue createThunk(SILGenFunction &SGF, // Apply substitutions in the source and destination types, since the thunk // doesn't change because of different function representations. CanSILFunctionType sourceType; - if (substSourceType->getSubstitutions()) { + if (substSourceType->getPatternSubstitutions()) { sourceType = substSourceType->getUnsubstitutedType(SGF.SGM.M); fn = SGF.B.createConvertFunction(loc, fn, SILType::getPrimitiveObjectType(sourceType)); diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp index 108a2545e1f60..20d9f13dca4ca 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp @@ -381,7 +381,7 @@ ExistentialTransform::createExistentialSpecializedFunctionType() { NewGenericSig, ExtInfo, FTy->getCoroutineKind(), FTy->getCalleeConvention(), InterfaceParams, FTy->getYields(), FTy->getResults(), InterfaceErrorResult, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), Ctx, witnessMethodConformance); } diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 92e6036afb92d..909b9fbd80956 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -204,15 +204,26 @@ static bool usesGenerics(SILFunction *F, ArrayRef InterfaceParams, ArrayRef InterfaceResults) { CanSILFunctionType FTy = F->getLoweredFunctionType(); - auto HasGenericSignature = FTy->getSubstGenericSignature() != nullptr; + auto HasGenericSignature = FTy->getInvocationGenericSignature() != nullptr; if (!HasGenericSignature) return false; bool UsesGenerics = false; - auto FindArchetypesAndGenericTypes = [&UsesGenerics](Type Ty) { - if (Ty.findIf([](Type Ty) -> bool { - return (Ty->hasTypeParameter() || Ty->hasArchetype()); + auto FindArchetypesAndGenericTypes = [FTy, &UsesGenerics](Type Ty) { + if (Ty.findIf([FTy](Type Ty) -> bool { + // Assume archetypes are always a problem. + // TODO: This can ignore non-contextual archetypes. + if (Ty->hasArchetype()) return true; + + // Assume type parameters are always a problem. However, this + // can ignore types that would substitute to concrete types. + if (Ty->isTypeParameter()) { + auto subs = FTy->getPatternSubstitutions(); + return (!subs || Ty.subst(subs)->isTypeParameter()); + } + + return false; })) UsesGenerics = true; }; @@ -394,12 +405,12 @@ FunctionSignatureTransformDescriptor::createOptimizedSILFunctionType() { mapInterfaceTypes(F, InterfaceParams, InterfaceResults, InterfaceErrorResult); GenericSignature GenericSig = - UsesGenerics ? FTy->getSubstGenericSignature() : nullptr; + UsesGenerics ? FTy->getInvocationGenericSignature() : nullptr; return SILFunctionType::get( GenericSig, ExtInfo, FTy->getCoroutineKind(), FTy->getCalleeConvention(), InterfaceParams, InterfaceYields, InterfaceResults, InterfaceErrorResult, - FTy->getSubstitutions(), FTy->isGenericSignatureImplied(), + FTy->getPatternSubstitutions(), SubstitutionMap(), F->getModule().getASTContext(), witnessMethodConformance); } @@ -499,7 +510,7 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() { auto NewFTy = TransformDescriptor.createOptimizedSILFunctionType(); GenericEnvironment *NewFGenericEnv; - if (NewFTy->getSubstGenericSignature()) { + if (NewFTy->getInvocationGenericSignature()) { NewFGenericEnv = F->getGenericEnvironment(); } else { NewFGenericEnv = nullptr; diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp index 2bb212748025c..6c8245e71f5a0 100644 --- a/lib/SILOptimizer/IPO/CapturePromotion.cpp +++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp @@ -429,7 +429,7 @@ ClosureCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, OrigFTI->getInvocationGenericSignature(), OrigFTI->getExtInfo(), OrigFTI->getCoroutineKind(), OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys, OrigFTI->getYields(), OrigFTI->getResults(), - OrigFTI->getOptionalErrorResult(), SubstitutionMap(), false, + OrigFTI->getOptionalErrorResult(), SubstitutionMap(), SubstitutionMap(), M.getASTContext(), OrigFTI->getWitnessMethodConformanceOrInvalid()); assert((Orig->isTransparent() || Orig->isBare() || Orig->getLocation()) diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index 6adcf3bd88da2..2330cddf381ff 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -665,13 +665,13 @@ ClosureSpecCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, ExtInfo = ExtInfo.withRepresentation(SILFunctionTypeRepresentation::Thin); auto ClonedTy = SILFunctionType::get( - ClosureUserFunTy->getSubstGenericSignature(), ExtInfo, + ClosureUserFunTy->getInvocationGenericSignature(), ExtInfo, ClosureUserFunTy->getCoroutineKind(), ClosureUserFunTy->getCalleeConvention(), NewParameterInfoList, ClosureUserFunTy->getYields(), ClosureUserFunTy->getResults(), ClosureUserFunTy->getOptionalErrorResult(), - ClosureUserFunTy->getSubstitutions(), - ClosureUserFunTy->isGenericSignatureImplied(), + ClosureUserFunTy->getPatternSubstitutions(), + ClosureUserFunTy->getInvocationSubstitutions(), M.getASTContext()); // We make this function bare so we don't have to worry about decls in the diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index d70e8c7305d79..8b35bfbc95a6d 100644 --- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -620,11 +620,11 @@ SILFunction *PromotedParamCloner::initCloned(SILOptFunctionBuilder &FuncBuilder, // Create the new function type for the cloned function with some of // the parameters promoted. auto ClonedTy = SILFunctionType::get( - OrigFTI->getSubstGenericSignature(), OrigFTI->getExtInfo(), + OrigFTI->getInvocationGenericSignature(), OrigFTI->getExtInfo(), OrigFTI->getCoroutineKind(), OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys, OrigFTI->getYields(), OrigFTI->getResults(), - OrigFTI->getOptionalErrorResult(), OrigFTI->getSubstitutions(), - OrigFTI->isGenericSignatureImplied(), M.getASTContext(), + OrigFTI->getOptionalErrorResult(), OrigFTI->getPatternSubstitutions(), + OrigFTI->getInvocationSubstitutions(), M.getASTContext(), OrigFTI->getWitnessMethodConformanceOrInvalid()); assert((Orig->isTransparent() || Orig->isBare() || Orig->getLocation()) diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp index a0a827199a37c..45d864e52f3a7 100644 --- a/lib/SILOptimizer/Transforms/Outliner.cpp +++ b/lib/SILOptimizer/Transforms/Outliner.cpp @@ -304,7 +304,7 @@ CanSILFunctionType BridgedProperty::getOutlinedFunctionType(SILModule &M) { nullptr, ExtInfo, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, Parameters, /*yields*/ {}, Results, None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), M.getASTContext()); return FunctionType; } @@ -1189,7 +1189,7 @@ CanSILFunctionType ObjCMethodCall::getOutlinedFunctionType(SILModule &M) { nullptr, ExtInfo, SILCoroutineKind::None, ParameterConvention::Direct_Unowned, Parameters, {}, Results, None, - SubstitutionMap(), false, + SubstitutionMap(), SubstitutionMap(), M.getASTContext()); return FunctionType; } diff --git a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp index c01d47a8ff74b..aa187b7d15815 100644 --- a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp +++ b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp @@ -90,7 +90,7 @@ class BugReducerTester : public SILFunctionTransform { nullptr /*clangFunctionType*/), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, ArrayRef(), ArrayRef(), ResultInfoArray, - None, SubstitutionMap(), false, + None, SubstitutionMap(), SubstitutionMap(), getFunction()->getModule().getASTContext()); SILOptFunctionBuilder FunctionBuilder(*this); diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index ad1b97c2b480d..e5b62586ea301 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -758,8 +758,9 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF, // First substitute concrete types into the existing function type. CanSILFunctionType FnTy; { - FnTy = OrigF->getLoweredFunctionType()->substGenericArgs( - M, SubstMap, getResilienceExpansion()); + FnTy = OrigF->getLoweredFunctionType() + ->substGenericArgs(M, SubstMap, getResilienceExpansion()) + ->getUnsubstitutedType(M); // FIXME: Some of the added new requirements may not have been taken into // account by the substGenericArgs. So, canonicalize in the context of the // specialized signature. @@ -777,8 +778,9 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF, auto NewFnTy = SILFunctionType::get( CanSpecializedGenericSig, FnTy->getExtInfo(), FnTy->getCoroutineKind(), FnTy->getCalleeConvention(), FnTy->getParameters(), FnTy->getYields(), - FnTy->getResults(), FnTy->getOptionalErrorResult(), SubstitutionMap(), - false, M.getASTContext(), FnTy->getWitnessMethodConformanceOrInvalid()); + FnTy->getResults(), FnTy->getOptionalErrorResult(), + FnTy->getPatternSubstitutions(), SubstitutionMap(), M.getASTContext(), + FnTy->getWitnessMethodConformanceOrInvalid()); // This is an interface type. It should not have any archetypes. assert(!NewFnTy->hasArchetype()); @@ -838,11 +840,15 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const { // For now, always just use the original, substituted parameter info. SpecializedYields.push_back(YI); } + + auto Signature = SubstFTy->isPolymorphic() + ? SubstFTy->getInvocationGenericSignature() + : CanGenericSignature(); return SILFunctionType::get( - SubstFTy->getInvocationGenericSignature(), SubstFTy->getExtInfo(), + Signature, SubstFTy->getExtInfo(), SubstFTy->getCoroutineKind(), SubstFTy->getCalleeConvention(), SpecializedParams, SpecializedYields, SpecializedResults, - SubstFTy->getOptionalErrorResult(), SubstitutionMap(), false, + SubstFTy->getOptionalErrorResult(), SubstitutionMap(), SubstitutionMap(), M.getASTContext(), SubstFTy->getWitnessMethodConformanceOrInvalid()); } diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index f315fae69d82a..b592597eb7e8d 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2683,6 +2683,16 @@ Type TypeResolver::resolveASTFunctionType( auto extInfo = incompleteExtInfo.withRepresentation(representation) .withClangFunctionType(clangFnType); + // Diagnose a couple of things that we can parse in SIL mode but we don't + // allow in formal types. + if (auto patternParams = repr->getPatternGenericParams()) { + diagnose(patternParams->getLAngleLoc(), + diag::ast_subst_function_type); + } else if (!repr->getInvocationSubstitutions().empty()) { + diagnose(repr->getInvocationSubstitutions()[0]->getStartLoc(), + diag::ast_subst_function_type); + } + // SIL uses polymorphic function types to resolve overloaded member functions. if (auto genericEnv = repr->getGenericEnvironment()) { outputTy = outputTy->mapTypeOutOfContext(); @@ -2794,14 +2804,22 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, SmallVector yields; SmallVector results; Optional errorResult; + + // Resolve generic params in the pattern environment, if present, or + // else the function's generic environment, if it has one. + GenericEnvironment *genericEnv = repr->getGenericEnvironment(); + GenericEnvironment *componentTypeEnv = + repr->getPatternGenericEnvironment() + ? repr->getPatternGenericEnvironment() + : genericEnv; + { Optional resolveSILFunctionGenericParams; Optional> useSILFunctionGenericEnv; - - // Resolve generic params using the function's generic environment, if it - // has one. - if (auto env = repr->getGenericEnvironment()) { - resolveSILFunctionGenericParams = TypeResolution::forContextual(DC, env); + + if (componentTypeEnv) { + resolveSILFunctionGenericParams = + TypeResolution::forContextual(DC, componentTypeEnv); useSILFunctionGenericEnv.emplace(resolution, *resolveSILFunctionGenericParams); } @@ -2843,37 +2861,60 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, } } } // restore generic type resolution - - // Resolve substitutions if we have them. - SubstitutionMap subs; - if (!repr->getSubstitutions().empty()) { - auto sig = repr->getGenericEnvironment() - ->getGenericSignature() - .getCanonicalSignature(); + + auto resolveSubstitutions = [&](GenericEnvironment *env, + ArrayRef args) { + auto sig = env->getGenericSignature().getCanonicalSignature(); TypeSubstitutionMap subsMap; auto params = sig->getGenericParams(); - for (unsigned i : indices(repr->getSubstitutions())) { - auto resolved = resolveType(repr->getSubstitutions()[i], options); + for (unsigned i : indices(args)) { + auto resolved = resolveType(args[i], options); subsMap.insert({params[i], resolved->getCanonicalType()}); } - subs = SubstitutionMap::get(sig, QueryTypeSubstitutionMap{subsMap}, + return SubstitutionMap::get(sig, QueryTypeSubstitutionMap{subsMap}, TypeChecker::LookUpConformance(DC)) .getCanonical(); + }; + + // Resolve pattern substitutions in the invocation environment, if + // applicable. + SubstitutionMap patternSubs; + if (!repr->getPatternSubstitutions().empty()) { + Optional resolveSILFunctionGenericParams; + Optional> useSILFunctionGenericEnv; + if (genericEnv) { + resolveSILFunctionGenericParams = + TypeResolution::forContextual(DC, genericEnv); + useSILFunctionGenericEnv.emplace(resolution, + *resolveSILFunctionGenericParams); + } + + patternSubs = resolveSubstitutions(repr->getPatternGenericEnvironment(), + repr->getPatternSubstitutions()); + } + + // Resolve invocation substitutions if we have them. + SubstitutionMap invocationSubs; + if (!repr->getInvocationSubstitutions().empty()) { + invocationSubs = resolveSubstitutions(repr->getGenericEnvironment(), + repr->getInvocationSubstitutions()); } if (hasError) { return ErrorType::get(Context); } + CanGenericSignature genericSig = + genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature() + : CanGenericSignature(); + + // FIXME: Remap the parsed context types to interface types. - CanGenericSignature genericSig; SmallVector interfaceParams; SmallVector interfaceYields; SmallVector interfaceResults; Optional interfaceErrorResult; - if (auto *genericEnv = repr->getGenericEnvironment()) { - genericSig = genericEnv->getGenericSignature().getCanonicalSignature(); - + if (componentTypeEnv) { for (auto ¶m : params) { auto transParamType = param.getInterfaceType()->mapTypeOutOfContext() ->getCanonicalType(); @@ -2903,6 +2944,13 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, interfaceResults = results; interfaceErrorResult = errorResult; } + + SubstitutionMap interfacePatternSubs = patternSubs; + if (interfacePatternSubs && repr->getGenericEnvironment()) { + interfacePatternSubs = + interfacePatternSubs.mapReplacementTypesOutOfContext(); + } + ProtocolConformanceRef witnessMethodConformance; if (witnessMethodProtocol) { auto resolved = resolveType(witnessMethodProtocol, options); @@ -2914,8 +2962,8 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, return ErrorType::get(Context); Type selfType = params.back().getInterfaceType(); - if (subs) { - selfType = selfType.subst(subs); + if (invocationSubs) { + selfType = selfType.subst(invocationSubs); } // The Self type can be nested in a few layers of metatypes (etc.). @@ -2936,8 +2984,7 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, callee, interfaceParams, interfaceYields, interfaceResults, interfaceErrorResult, - subs, - repr->areGenericParamsImplied(), + interfacePatternSubs, invocationSubs, Context, witnessMethodConformance); } diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index badadd70e1d77..3daed88e91baf 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -5190,9 +5190,9 @@ class TypeDeserializer { unsigned numParams; unsigned numYields; unsigned numResults; - bool isGenericSignatureImplied; - GenericSignatureID rawGenericSig; - SubstitutionMapID rawSubs; + GenericSignatureID rawInvocationGenericSig; + SubstitutionMapID rawInvocationSubs; + SubstitutionMapID rawPatternSubs; ArrayRef variableData; ClangTypeID clangFunctionTypeID; @@ -5207,9 +5207,9 @@ class TypeDeserializer { numParams, numYields, numResults, - isGenericSignatureImplied, - rawGenericSig, - rawSubs, + rawInvocationGenericSig, + rawInvocationSubs, + rawPatternSubs, clangFunctionTypeID, variableData); @@ -5355,14 +5355,18 @@ class TypeDeserializer { witnessMethodConformance = MF.readConformance(MF.DeclTypeCursor); } - GenericSignature genericSig = MF.getGenericSignature(rawGenericSig); - SubstitutionMap subs = MF.getSubstitutionMap(rawSubs).getCanonical(); - - return SILFunctionType::get(genericSig, extInfo, coroutineKind.getValue(), + GenericSignature invocationSig = + MF.getGenericSignature(rawInvocationGenericSig); + SubstitutionMap invocationSubs = + MF.getSubstitutionMap(rawInvocationSubs).getCanonical(); + SubstitutionMap patternSubs = + MF.getSubstitutionMap(rawPatternSubs).getCanonical(); + + return SILFunctionType::get(invocationSig, extInfo, coroutineKind.getValue(), calleeConvention.getValue(), allParams, allYields, allResults, errorResult, - subs, isGenericSignatureImplied, + patternSubs, invocationSubs, ctx, witnessMethodConformance); } diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 986dfcabd2110..838835a93c7d9 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -55,7 +55,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 544; // TypeEraser +const uint16_t SWIFTMODULE_VERSION_MINOR = 545; // SILFunctionType pattern sigs/subs /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1027,9 +1027,9 @@ namespace decls_block { BCVBR<6>, // number of parameters BCVBR<5>, // number of yields BCVBR<5>, // number of results - BCFixed<1>, // generic signature implied - GenericSignatureIDField, // generic signature - SubstitutionMapIDField, // substitutions + GenericSignatureIDField, // invocation generic signature + SubstitutionMapIDField, // invocation substitutions + SubstitutionMapIDField, // pattern substitutions ClangTypeIDField, // clang function type, for foreign conventions BCArray // parameter types/conventions, alternating // followed by result types/conventions, alternating diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index b555f52dc38e2..a5bc682619f95 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4201,8 +4201,12 @@ class Serializer::TypeSerializer : public TypeVisitor { variableData.push_back(TypeID(conv)); } - auto sigID = S.addGenericSignatureRef(fnTy->getSubstGenericSignature()); - auto substMapID = S.addSubstitutionMapRef(fnTy->getSubstitutions()); + auto invocationSigID = + S.addGenericSignatureRef(fnTy->getInvocationGenericSignature()); + auto invocationSubstMapID = + S.addSubstitutionMapRef(fnTy->getInvocationSubstitutions()); + auto patternSubstMapID = + S.addSubstitutionMapRef(fnTy->getPatternSubstitutions()); auto clangTypeID = S.addClangTypeRef(fnTy->getClangFunctionType()); auto stableCoroutineKind = @@ -4221,8 +4225,8 @@ class Serializer::TypeSerializer : public TypeVisitor { stableRepresentation, fnTy->isPseudogeneric(), fnTy->isNoEscape(), stableDiffKind, fnTy->hasErrorResult(), fnTy->getParameters().size(), fnTy->getNumYields(), fnTy->getNumResults(), - fnTy->isGenericSignatureImplied(), - sigID, substMapID, clangTypeID, variableData); + invocationSigID, invocationSubstMapID, patternSubstMapID, + clangTypeID, variableData); if (auto conformance = fnTy->getWitnessMethodConformanceOrInvalid()) S.writeConformance(conformance, S.DeclTypeAbbrCodes); diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil index 50f8778141b42..4d567054f1614 100644 --- a/test/IRGen/keypaths.sil +++ b/test/IRGen/keypaths.sil @@ -338,8 +338,8 @@ entry: %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int) %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter.1, getter @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed in () -> @out A for <()>, setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for <()>, @inout S) -> ()) - %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed in () -> @out A for <()>, setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for <()>, @inout C2) -> ()) + %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) + %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_T0]] to i8*), i8* undef) %t0 = keypath $KeyPath, (root $T; stored_property #T.a : $(Int, String); tuple_element #0 : $Int) @@ -366,18 +366,18 @@ bb0(%0 : $*Int, %1 : $*C): unreachable } -sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed in () -> @out A for <()> { -bb0(%0 : $*@callee_guaranteed in () -> @out A for <()>, %1 : $*S): +sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { +bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for <()>, @inout S) -> () { -bb0(%0 : $*@callee_guaranteed in () -> @out A for <()>, %1 : $*S): +sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { +bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed in () -> @out A for <()> -sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for <()>, @inout C2) -> () +sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> +sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () struct Gen { var x: T diff --git a/test/IRGen/lowered_optional_self_metadata.sil b/test/IRGen/lowered_optional_self_metadata.sil index 99e33c0a18628..d8db59cd3a2d3 100644 --- a/test/IRGen/lowered_optional_self_metadata.sil +++ b/test/IRGen/lowered_optional_self_metadata.sil @@ -15,8 +15,8 @@ public protocol Protocol { sil @optional_method : $@convention(method) (@in_guaranteed Optional) -> () -sil @call_optional_method_with_lowered_function : $@convention(thin) (@in_guaranteed Optional<@callee_guaranteed in () -> @out T for <()>>) -> () { -entry(%x : $*Optional<@callee_guaranteed in () -> @out T for <()>>): +sil @call_optional_method_with_lowered_function : $@convention(thin) (@in_guaranteed Optional<@callee_guaranteed @substituted () -> @out T for <()>>) -> () { +entry(%x : $*Optional<@callee_guaranteed @substituted () -> @out T for <()>>): %f = function_ref @optional_method : $@convention(method) (@in_guaranteed Optional) -> () apply %f<() -> ()>(%x) : $@convention(method) (@in_guaranteed Optional) -> () %p = partial_apply [callee_guaranteed] %f<() -> ()>() : $@convention(method) (@in_guaranteed Optional) -> () diff --git a/test/IRGen/property_descriptor.sil b/test/IRGen/property_descriptor.sil index 375f2bb3bba4c..c15e4945c91f5 100644 --- a/test/IRGen/property_descriptor.sil +++ b/test/IRGen/property_descriptor.sil @@ -121,8 +121,8 @@ sil_property #ExternalReabstractions.ro ( sil_property #ExternalReabstractions.reabstracted ( settable_property $() -> (), id ##ExternalReabstractions.reabstracted, - getter @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed in () -> @out U for <()>, - setter @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out U for <()>, @inout ExternalReabstractions) -> ()) + getter @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()>, + setter @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> ()) // All trivial descriptors should share a definition by aliasing to the common // definition @@ -148,5 +148,5 @@ sil @set_computed_generic : $@convention(thin) (@in_guaranteed T sil @get_computed_generic_subscript : $@convention(thin) (@in_guaranteed ExternalGeneric, UnsafeRawPointer) -> @out T sil @set_computed_generic_subscript : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric, UnsafeRawPointer) -> () -sil @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed in () -> @out U for <()> -sil @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out U for <()>, @inout ExternalReabstractions) -> () +sil @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()> +sil @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> () diff --git a/test/Reflection/capture_descriptors.sil b/test/Reflection/capture_descriptors.sil index a878422b803e7..09d782b1462c9 100644 --- a/test/Reflection/capture_descriptors.sil +++ b/test/Reflection/capture_descriptors.sil @@ -96,9 +96,9 @@ bb0(%t : $*T): sil [ossa] @generic_caller3 : $@convention(thin) () -> @owned @callee_guaranteed () -> () { bb0: %f = function_ref @generic_callee3 : $@convention(thin) (@in_guaranteed T) -> () - %t = alloc_stack $Optional<@callee_guaranteed in (@in_guaranteed X) -> @out Y for > + %t = alloc_stack $Optional<@callee_guaranteed @substituted (@in_guaranteed X) -> @out Y for > %c = partial_apply [callee_guaranteed] %f B>, (B, (C) -> Int)>(%t) : $@convention(thin) (@in_guaranteed T) -> () - dealloc_stack %t : $*Optional<@callee_guaranteed in (@in_guaranteed X) -> @out Y for > + dealloc_stack %t : $*Optional<@callee_guaranteed @substituted (@in_guaranteed X) -> @out Y for > return %c : $@callee_guaranteed () -> () } diff --git a/test/SIL/Parser/apply_with_substitution.sil b/test/SIL/Parser/apply_with_substitution.sil index 53be16d71f86a..ccc5dc9176887 100644 --- a/test/SIL/Parser/apply_with_substitution.sil +++ b/test/SIL/Parser/apply_with_substitution.sil @@ -6,46 +6,46 @@ sil_stage raw import Builtin import Swift -// CHECK-LABEL: sil @_TF4test3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>>) -> () -sil @_TF4test3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed in () -> @out A for <()>>) -> () { -bb0(%0 : $Optional<@callee_guaranteed in () -> @out A for <()>>): - %1 = alloc_box $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>> // var f // users: %2, %6, %32 - %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>>, 0 - store %0 to %1a : $*Optional<@callee_guaranteed in () -> @out A for <()>> // id: %2 +// CHECK-LABEL: sil @_TF4test3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>>) -> () +sil @_TF4test3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed @substituted () -> @out A for <()>>) -> () { +bb0(%0 : $Optional<@callee_guaranteed @substituted () -> @out A for <()>>): + %1 = alloc_box $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>> // var f // users: %2, %6, %32 + %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>>, 0 + store %0 to %1a : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> // id: %2 %3 = alloc_stack $Optional<()> // users: %22, %28, %30, %31 %4 = alloc_stack $() // users: %12, %22, %25 - %5 = alloc_stack $Optional<@callee_guaranteed in () -> @out A for <()>> // users: %6, %8, %10, %11, %16, %24 - copy_addr %1a to [initialization] %5 : $*Optional<@callee_guaranteed in () -> @out A for <()>> // id: %6 + %5 = alloc_stack $Optional<@callee_guaranteed @substituted () -> @out A for <()>> // users: %6, %8, %10, %11, %16, %24 + copy_addr %1a to [initialization] %5 : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> // id: %6 %7 = function_ref @_TFs22_doesOptionalHaveValueU__FT1vRGSqQ___Bi1_ : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // user: %8 %8 = apply %7<() -> ()>(%5) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // user: %9 br bb2 // id: %13 bb2: // Preds: bb0 %14 = function_ref @_TFs17_getOptionalValueU__FT1vGSqQ___Q_ : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> @out τ_0_0 // user: %16 - %15 = alloc_stack $@callee_guaranteed in () -> @out A for <()> // users: %16, %17, %23 + %15 = alloc_stack $@callee_guaranteed @substituted () -> @out A for <()> // users: %16, %17, %23 // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}, %{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> @out τ_0_0 %16 = apply %14<() -> ()>(%15, %5) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> @out τ_0_0 - %17 = load %15 : $*@callee_guaranteed in () -> @out A for <()> // user: %19 - %18 = function_ref @_TTRXFo_iT__iT__XFo__dT__ : $@convention(thin) (@guaranteed @callee_guaranteed in () -> @out A for <()>) -> () // user: %19 - %19 = partial_apply [callee_guaranteed] %18(%17) : $@convention(thin) (@guaranteed @callee_guaranteed in () -> @out A for <()>) -> () // user: %20 + %17 = load %15 : $*@callee_guaranteed @substituted () -> @out A for <()> // user: %19 + %18 = function_ref @_TTRXFo_iT__iT__XFo__dT__ : $@convention(thin) (@guaranteed @callee_guaranteed @substituted () -> @out A for <()>) -> () // user: %19 + %19 = partial_apply [callee_guaranteed] %18(%17) : $@convention(thin) (@guaranteed @callee_guaranteed @substituted () -> @out A for <()>) -> () // user: %20 %20 = apply %19() : $@callee_guaranteed () -> () %21 = function_ref @_TFs24_injectValueIntoOptionalU__FT1vQ__GSqQ__ : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0> // user: %22 // CHECK: apply %{{[0-9]+}}<()>(%{{[0-9]+}}, %{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0> %22 = apply %21<()>(%3, %4) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0> - dealloc_stack %15 : $*@callee_guaranteed in () -> @out A for <()> // id: %23 - dealloc_stack %5 : $*Optional<@callee_guaranteed in () -> @out A for <()>> // id: %24 + dealloc_stack %15 : $*@callee_guaranteed @substituted () -> @out A for <()> // id: %23 + dealloc_stack %5 : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> // id: %24 dealloc_stack %4 : $*() // id: %25 br bb4 // id: %26 bb4: // Preds: bb2 bb3 %30 = load %3 : $*Optional<()> dealloc_stack %3 : $*Optional<()> // id: %31 - strong_release %1 : $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>> + strong_release %1 : $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>> %33 = tuple () // user: %34 return %33 : $() // id: %34 } sil [transparent] @_TFs22_doesOptionalHaveValueU__FT1vRGSqQ___Bi1_ : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 sil [transparent] @_TFs17_getOptionalValueU__FT1vGSqQ___Q_ : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> @out τ_0_0 -sil [transparent] @_TTRXFo_iT__iT__XFo__dT__ : $@convention(thin) (@guaranteed @callee_guaranteed in () -> @out A for <()>) -> () +sil [transparent] @_TTRXFo_iT__iT__XFo__dT__ : $@convention(thin) (@guaranteed @callee_guaranteed @substituted () -> @out A for <()>) -> () sil [transparent] @_TFs24_injectValueIntoOptionalU__FT1vQ__GSqQ__ : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0> diff --git a/test/SIL/Parser/bound_generic.sil b/test/SIL/Parser/bound_generic.sil index d1bc784e063e0..37abbf9783b43 100644 --- a/test/SIL/Parser/bound_generic.sil +++ b/test/SIL/Parser/bound_generic.sil @@ -6,16 +6,16 @@ sil_stage raw import Builtin import Swift -// CHECK-LABEL: sil @_TF9optional3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>>) -> () -sil @_TF9optional3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed in () -> @out A for <()>>) -> () { -bb0(%0 : $Optional<@callee_guaranteed in () -> @out A for <()>>): - %1 = alloc_box $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>> - %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>>, 0 - store %0 to %1a : $*Optional<@callee_guaranteed in () -> @out A for <()>> +// CHECK-LABEL: sil @_TF9optional3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>>) -> () +sil @_TF9optional3fooFT1fGSqFT_T___T_ : $@convention(thin) (@guaranteed Optional<@callee_guaranteed @substituted () -> @out A for <()>>) -> () { +bb0(%0 : $Optional<@callee_guaranteed @substituted () -> @out A for <()>>): + %1 = alloc_box $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>> + %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>>, 0 + store %0 to %1a : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> %3 = alloc_stack $Optional<()> %4 = alloc_stack $() - %5 = alloc_stack $Optional<@callee_guaranteed in () -> @out A for <()>> - copy_addr %1a to [initialization] %5 : $*Optional<@callee_guaranteed in () -> @out A for <()>> + %5 = alloc_stack $Optional<@callee_guaranteed @substituted () -> @out A for <()>> + copy_addr %1a to [initialization] %5 : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> // function_ref Swift._doesOptionalHaveValue (v : @inout Swift.Optional) -> Builtin.Int1 %7 = function_ref @_TFs22_doesOptionalHaveValueU__FT1vRGSqQ___Bi1_ : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 @@ -23,8 +23,8 @@ bb0(%0 : $Optional<@callee_guaranteed in () -> @out A for <()>>): br bb1 bb1: - destroy_addr %5 : $*Optional<@callee_guaranteed in () -> @out A for <()>> - dealloc_stack %5 : $*Optional<@callee_guaranteed in () -> @out A for <()>> + destroy_addr %5 : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> + dealloc_stack %5 : $*Optional<@callee_guaranteed @substituted () -> @out A for <()>> dealloc_stack %4 : $*() br bb3 @@ -37,7 +37,7 @@ bb3: bb4: %30 = load %3 : $*Optional<()> dealloc_stack %3 : $*Optional<()> - release_value %1 : $<τ_0_0> { var τ_0_0 } in () -> @out A for <()>>> + release_value %1 : $<τ_0_0> { var τ_0_0 } () -> @out A for <()>>> %33 = tuple () return %33 : $() } diff --git a/test/SIL/Parser/errors.sil b/test/SIL/Parser/errors.sil index a0a1c331d24ab..72b780fa6e250 100644 --- a/test/SIL/Parser/errors.sil +++ b/test/SIL/Parser/errors.sil @@ -50,3 +50,9 @@ sil [ossa] @missing_type : $@convention(thin) (Int) -> () { bb0(%0 : $Int): br bb3(%0) // expected-error {{expected ':' before type in SIL value reference}} } + +sil @test_formal_substituted_type : $@convention(thin) (@owned Array<@substituted (Z) -> (Z) for >) -> () { +// expected-error@-1 {{substitutions cannot be provided on a formal function type}} +entry(%0 : $Array): + return undef : $() +} diff --git a/test/SIL/Parser/keypath.sil b/test/SIL/Parser/keypath.sil index 011cbc6420f23..5efc15982474e 100644 --- a/test/SIL/Parser/keypath.sil +++ b/test/SIL/Parser/keypath.sil @@ -96,8 +96,8 @@ sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed in (@in_guaranteed A) -> @out B for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for ) -> () +sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for +sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> () sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool @@ -115,13 +115,13 @@ entry: %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, ( root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), - getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed in (@in_guaranteed A) -> @out B for , - setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed in (@in_guaranteed A) -> @out B for ) -> ()) + getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , + setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> ()) // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) diff --git a/test/SIL/Parser/subst_function_type.sil b/test/SIL/Parser/subst_function_type.sil index 06052212b4e7b..1b9bb329b7f07 100644 --- a/test/SIL/Parser/subst_function_type.sil +++ b/test/SIL/Parser/subst_function_type.sil @@ -4,14 +4,20 @@ sil_stage raw import Swift -// CHECK-LABEL: sil @test : $@convention(thin) (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in τ_0_0, @in τ_0_1) -> () for ) -> () -sil @test : $@convention(thin) (@guaranteed @callee_guaranteed in (@in A, @in B) -> () for ) -> () { -entry(%0 : $@callee_guaranteed in (@in C, @in D) -> () for ): +// CHECK-LABEL: sil @test : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () +sil @test : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { +entry(%0 : $@callee_guaranteed @substituted (@in C, @in D) -> () for ): return undef : $() } -// CHECK-LABEL: sil @test_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in τ_0_0, @in τ_0_1) -> () for ) -> () -sil @test_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed in (@in A, @in B) -> () for ) -> () { -entry(%0 : $@callee_guaranteed in (@in C, @in D) -> () for ): +// CHECK-LABEL: sil @test_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () +sil @test_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { +entry(%0 : $@callee_guaranteed @substituted (@in C, @in D) -> () for ): + return undef : $() +} + +sil @test_substituted_generic : $@convention(thin) @substituted (@in Z) -> (@out Z) for <(X, Y)> { +entry(%0 : $*(X, Y), %1 : $*(X, Y)): + copy_addr [take] %1 to [initialization] %0 : $*(X,Y) return undef : $() } diff --git a/test/SIL/Serialization/basic.sil b/test/SIL/Serialization/basic.sil index b4ad226fd01ae..8c7f8fcb4c5b9 100644 --- a/test/SIL/Serialization/basic.sil +++ b/test/SIL/Serialization/basic.sil @@ -38,9 +38,9 @@ struct Int32 { var x: Builtin.Int32 } -// CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in τ_0_0, @in τ_0_1) -> () for ) -> () -sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed in (@in A, @in B) -> () for ) -> () { -entry(%0 : @guaranteed $@callee_guaranteed in (@in C, @in D) -> () for ): +// CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () +sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { +entry(%0 : @guaranteed $@callee_guaranteed @substituted (@in C, @in D) -> () for ): return undef : $() } @@ -52,9 +52,9 @@ bb0(%0 : @owned $(Builtin.NativeObject, Builtin.Int32), %1 : @owned $TestArray2) return %7 : $(Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Int32, TestArrayStorage) } -// CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in τ_0_0, @in τ_0_1) -> () for ) -> () -sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed in (@in A, @in B) -> () for ) -> () { -entry(%0 : @guaranteed $@callee_guaranteed in (@in C, @in D) -> () for ): +// CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () +sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { +entry(%0 : @guaranteed $@callee_guaranteed @substituted (@in C, @in D) -> () for ): return undef : $() } diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil index 87d9f749a0eae..60a65f10a9d6c 100644 --- a/test/SIL/Serialization/keypath.sil +++ b/test/SIL/Serialization/keypath.sil @@ -135,8 +135,8 @@ sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for +sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool @@ -153,8 +153,8 @@ entry: %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) - %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) diff --git a/test/SILGen/addressors.swift b/test/SILGen/addressors.swift index 9f99ab9ce7c0b..465b14ccb71c2 100644 --- a/test/SILGen/addressors.swift +++ b/test/SILGen/addressors.swift @@ -175,7 +175,7 @@ func test_carray(_ array: inout CArray<(Int32) -> Int32>) -> Int32 { // CHECK: [[T0:%.*]] = function_ref @$s10addressors6CArrayVyxSiciau : // CHECK: [[T1:%.*]] = apply [[T0]]<(Int32) -> Int32>({{%.*}}, [[WRITE]]) // CHECK: [[T2:%.*]] = struct_extract [[T1]] : $UnsafeMutablePointer<(Int32) -> Int32>, #UnsafeMutablePointer._rawValue -// CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to [strict] $*@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for +// CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[T3]] // CHECK: store {{%.*}} to [[ACCESS]] : array[0] = id_int @@ -185,7 +185,7 @@ func test_carray(_ array: inout CArray<(Int32) -> Int32>) -> Int32 { // CHECK: [[T1:%.*]] = function_ref @$s10addressors6CArrayVyxSicilu : // CHECK: [[T2:%.*]] = apply [[T1]]<(Int32) -> Int32>({{%.*}}, [[T0]]) // CHECK: [[T3:%.*]] = struct_extract [[T2]] : $UnsafePointer<(Int32) -> Int32>, #UnsafePointer._rawValue -// CHECK: [[T4:%.*]] = pointer_to_address [[T3]] : $Builtin.RawPointer to [strict] $*@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for +// CHECK: [[T4:%.*]] = pointer_to_address [[T3]] : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: [[ACCESS:%.*]] = begin_access [read] [unsafe] [[T4]] // CHECK: [[T5:%.*]] = load [[ACCESS]] return array[1](5) diff --git a/test/SILGen/apply_abstraction_nested.swift b/test/SILGen/apply_abstraction_nested.swift index bd275b486028b..67446026a790f 100644 --- a/test/SILGen/apply_abstraction_nested.swift +++ b/test/SILGen/apply_abstraction_nested.swift @@ -19,8 +19,8 @@ struct X : P {} var a = X() (a~>bar)(()) -// CHECK: [[CHAINED_FUNC:%.*]] = apply {{%.*}}({{%.*}}, {{%.*}}) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P> (@inout τ_0_0, @noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@inout τ_0_0) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_1, τ_0_2> for <τ_0_0, τ_0_1, τ_0_2>) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_1, τ_0_2> -// CHECK: [[CHAINED_FUNC_CONV:%.*]] = convert_function [[CHAINED_FUNC]] : $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <(), ()> to $@callee_guaranteed (@in_guaranteed ()) -> @out () +// CHECK: [[CHAINED_FUNC:%.*]] = apply {{%.*}}({{%.*}}, {{%.*}}) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P> (@inout τ_0_0, @noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@inout τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_1, τ_0_2> for <τ_0_0, τ_0_1, τ_0_2>) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_1, τ_0_2> +// CHECK: [[CHAINED_FUNC_CONV:%.*]] = convert_function [[CHAINED_FUNC]] : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <(), ()> to $@callee_guaranteed (@in_guaranteed ()) -> @out () // CHECK: [[REABSTRACT:%.*]] = function_ref @$sytytIegnr_Ieg_TR // CHECK: [[CHAINED_FUNC_REABSTRACTED:%.*]] = partial_apply [callee_guaranteed] [[REABSTRACT]]([[CHAINED_FUNC_CONV]]) // CHECK: [[BORROW:%.*]] = begin_borrow [[CHAINED_FUNC_REABSTRACTED]] diff --git a/test/SILGen/array_literal_abstraction.swift b/test/SILGen/array_literal_abstraction.swift index beca7cc09eee7..2b7b3e5a1379b 100644 --- a/test/SILGen/array_literal_abstraction.swift +++ b/test/SILGen/array_literal_abstraction.swift @@ -5,13 +5,13 @@ // // CHECK-LABEL: sil hidden [ossa] @$s25array_literal_abstraction0A9_of_funcsSayyycGyF -// CHECK: pointer_to_address {{.*}} $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()> +// CHECK: pointer_to_address {{.*}} $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()> func array_of_funcs() -> [(() -> ())] { return [{}, {}] } // CHECK-LABEL: sil hidden [ossa] @$s25array_literal_abstraction13dict_of_funcsSDySiyycGyF -// CHECK: pointer_to_address {{.*}} $*(Int, @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>) +// CHECK: pointer_to_address {{.*}} $*(Int, @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>) func dict_of_funcs() -> Dictionary ()> { return [0: {}, 1: {}] } @@ -19,7 +19,7 @@ func dict_of_funcs() -> Dictionary ()> { func vararg_funcs(_ fs: (() -> ())...) {} // CHECK-LABEL: sil hidden [ossa] @$s25array_literal_abstraction17call_vararg_funcsyyF -// CHECK: pointer_to_address {{.*}} $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()> +// CHECK: pointer_to_address {{.*}} $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()> func call_vararg_funcs() { vararg_funcs({}, {}) } diff --git a/test/SILGen/capture_typed_boxes.swift b/test/SILGen/capture_typed_boxes.swift index 11a11df774bd5..e7cfe9a10ab1a 100644 --- a/test/SILGen/capture_typed_boxes.swift +++ b/test/SILGen/capture_typed_boxes.swift @@ -27,6 +27,6 @@ func closure_generic(_ f: @escaping (T) -> T, x: T) -> T { return bar(x) } -// CHECK-LABEL: sil private [ossa] @$s19capture_typed_boxes15closure_generic{{.*}} : $@convention(thin) (@in_guaranteed T, @guaranteed <τ_0_0> { var @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_0> } ) -> @out T { -// CHECK-LABEL: bb0(%0 : $*T, %1 : $*T, %2 : @guaranteed $<τ_0_0> { var @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_0> } ): +// CHECK-LABEL: sil private [ossa] @$s19capture_typed_boxes15closure_generic{{.*}} : $@convention(thin) (@in_guaranteed T, @guaranteed <τ_0_0> { var @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_0> } ) -> @out T { +// CHECK-LABEL: bb0(%0 : $*T, %1 : $*T, %2 : @guaranteed $<τ_0_0> { var @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_0> } ): diff --git a/test/SILGen/closures.swift b/test/SILGen/closures.swift index 0acac2812ce70..33ab5c1747db4 100644 --- a/test/SILGen/closures.swift +++ b/test/SILGen/closures.swift @@ -7,7 +7,7 @@ import Swift var zero = 0 // -// CHECK-LABEL: sil hidden [ossa] @$s8closures46return_local_generic_function_without_captures{{[_0-9a-zA-Z]*}}F : $@convention(thin) () -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for { +// CHECK-LABEL: sil hidden [ossa] @$s8closures46return_local_generic_function_without_captures{{[_0-9a-zA-Z]*}}F : $@convention(thin) () -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for { func return_local_generic_function_without_captures() -> (A) -> R { func f(_: A) -> R { diff --git a/test/SILGen/default_arguments.swift b/test/SILGen/default_arguments.swift index 48c5870970832..8fc06fb8ed67a 100644 --- a/test/SILGen/default_arguments.swift +++ b/test/SILGen/default_arguments.swift @@ -236,8 +236,8 @@ class ReabstractDefaultArgument { // CHECK-LABEL: sil hidden [ossa] @$s17default_arguments32testDefaultArgumentReabstractionyyF // function_ref default_arguments.ReabstractDefaultArgument.__allocating_init (default_arguments.ReabstractDefaultArgument.Type)(a : (A, A) -> Swift.Bool) -> default_arguments.ReabstractDefaultArgument -// CHECK: [[FN:%.*]] = function_ref @$s17default_arguments25ReabstractDefaultArgument{{.*}} : $@convention(thin) <τ_0_0> () -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Bool for <τ_0_0, τ_0_0> -// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]() : $@convention(thin) <τ_0_0> () -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Bool for <τ_0_0, τ_0_0> +// CHECK: [[FN:%.*]] = function_ref @$s17default_arguments25ReabstractDefaultArgument{{.*}} : $@convention(thin) <τ_0_0> () -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Bool for <τ_0_0, τ_0_0> +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]() : $@convention(thin) <τ_0_0> () -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> Bool for <τ_0_0, τ_0_0> // CHECK-NEXT: [[RESULT_CONV:%.*]] = convert_function [[RESULT]] // CHECK-NEXT: function_ref reabstraction thunk helper from @escaping @callee_guaranteed (@in_guaranteed Swift.Int, @in_guaranteed Swift.Int) -> (@unowned Swift.Bool) to @escaping @callee_guaranteed (@unowned Swift.Int, @unowned Swift.Int) -> (@unowned Swift.Bool) // CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sS2iSbIegnnd_S2iSbIegyyd_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Int, @in_guaranteed Int) -> Bool) -> Bool diff --git a/test/SILGen/dependent_member_lowering.swift b/test/SILGen/dependent_member_lowering.swift index c56c5bb527101..741d3abed47d1 100644 --- a/test/SILGen/dependent_member_lowering.swift +++ b/test/SILGen/dependent_member_lowering.swift @@ -17,6 +17,6 @@ struct Bar: P { typealias A = (Int) -> T func f(_ t: @escaping (Int) -> T) {} - // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s25dependent_member_lowering3BarVyxGAA1PA2aEP1fyy1AQzFTW : $@convention(witness_method: P) <τ_0_0> (@in_guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed Bar<τ_0_0>) -> () - // CHECK: bb0(%0 : $*@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , %1 : $*Bar<τ_0_0>): + // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s25dependent_member_lowering3BarVyxGAA1PA2aEP1fyy1AQzFTW : $@convention(witness_method: P) <τ_0_0> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed Bar<τ_0_0>) -> () + // CHECK: bb0(%0 : $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , %1 : $*Bar<τ_0_0>): } diff --git a/test/SILGen/downcast_reabstraction.swift b/test/SILGen/downcast_reabstraction.swift index e1e46f0e3c0d3..9d240f8555adc 100644 --- a/test/SILGen/downcast_reabstraction.swift +++ b/test/SILGen/downcast_reabstraction.swift @@ -2,7 +2,7 @@ // RUN: %target-swift-emit-silgen -module-name downcast_reabstraction %s | %FileCheck %s // CHECK-LABEL: sil hidden [ossa] @$s22downcast_reabstraction19condFunctionFromAnyyyypF -// CHECK: checked_cast_addr_br take_always Any in [[IN:%.*]] : $*Any to () -> () in [[OUT:%.*]] : $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] +// CHECK: checked_cast_addr_br take_always Any in [[IN:%.*]] : $*Any to () -> () in [[OUT:%.*]] : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] // CHECK: [[YES]]: // CHECK: [[ORIG_VAL:%.*]] = load [take] [[OUT]] // CHECK: [[CONV_VAL:%.*]] = convert_function [[ORIG_VAL]] @@ -16,7 +16,7 @@ func condFunctionFromAny(_ x: Any) { } // CHECK-LABEL: sil hidden [ossa] @$s22downcast_reabstraction21uncondFunctionFromAnyyyypF : $@convention(thin) (@in_guaranteed Any) -> () { -// CHECK: unconditional_checked_cast_addr Any in [[IN:%.*]] : $*Any to () -> () in [[OUT:%.*]] : $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()> +// CHECK: unconditional_checked_cast_addr Any in [[IN:%.*]] : $*Any to () -> () in [[OUT:%.*]] : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()> // CHECK: [[ORIG_VAL:%.*]] = load [take] [[OUT]] // CHECK: [[CONV_VAL:%.*]] = convert_function [[ORIG_VAL]] // CHECK: [[REABSTRACT:%.*]] = function_ref @$sytIegr_Ieg_TR diff --git a/test/SILGen/enum_curry_thunks.swift b/test/SILGen/enum_curry_thunks.swift index b239c50cd4e03..7325745b24f1f 100644 --- a/test/SILGen/enum_curry_thunks.swift +++ b/test/SILGen/enum_curry_thunks.swift @@ -35,17 +35,17 @@ func partialApplyEnumCases(_ x: S, y: C) { _ = PartialApplyEnumPayload.autoclosure } -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4leftyACyxq_GxcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { +// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4leftyACyxq_GxcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { // CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4leftyACyxq_GxcAEmr0_lF : $@convention(method) (@in T, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4bothyACyxq_Gx_q_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3> in (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { +// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4bothyACyxq_Gx_q_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { // CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4bothyACyxq_Gx_q_tcAEmr0_lF : $@convention(method) (@in T, @in U, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13leftWithLabelyACyxq_Gx_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { +// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13leftWithLabelyACyxq_Gx_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { // CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13leftWithLabelyACyxq_Gx_tcAEmr0_lF : $@convention(method) (@in T, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14tupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3> in (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { +// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14tupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { // CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14tupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lF : $@convention(method) (@in T, @in U, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11autoclosureyACyxq_GyyXAcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@guaranteed @callee_guaranteed () -> ()) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1> for { +// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11autoclosureyACyxq_GyyXAcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@guaranteed @callee_guaranteed () -> ()) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1> for { // CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11autoclosureyACyxq_GyyXAcAEmr0_lF : $@convention(method) (@owned @callee_guaranteed () -> (), @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift index e00d8f06ed936..c658b84712938 100644 --- a/test/SILGen/function_conversion.swift +++ b/test/SILGen/function_conversion.swift @@ -349,7 +349,7 @@ func convFuncExistential(_ f1: @escaping (Any) -> (Int) -> Int) { // CHECK-NEXT: partial_apply // CHECK-NEXT: convert_function // CHECK-NEXT: init_existential_addr %0 : $*Any, $(Int) -> Int -// CHECK-NEXT: store {{.*}} to {{.*}} : $*@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for +// CHECK-NEXT: store {{.*}} to {{.*}} : $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: return // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sS2iIegyd_S2iIegnr_TR : $@convention(thin) (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> Int) -> @out Int @@ -440,8 +440,8 @@ func convTupleToOptionalDirect(_ f: @escaping (Int) -> (Int, Int)) -> (Int) -> ( return f } -// CHECK-LABEL: sil hidden [ossa] @$s19function_conversion27convTupleToOptionalIndirectyx_xtSgxcx_xtxclF : $@convention(thin) (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> (@out τ_0_1, @out τ_0_2) for ) -> @owned @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> @out Optional<(τ_0_1, τ_0_2)> for -// CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> (@out τ_0_1, @out τ_0_2) for ): +// CHECK-LABEL: sil hidden [ossa] @$s19function_conversion27convTupleToOptionalIndirectyx_xtSgxcx_xtxclF : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_1, @out τ_0_2) for ) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @out Optional<(τ_0_1, τ_0_2)> for +// CHECK: bb0([[ARG:%.*]] : @guaranteed $@callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> (@out τ_0_1, @out τ_0_2) for ): // CHECK: [[FN:%.*]] = copy_value [[ARG]] // CHECK-NEXT: [[FN_CONV:%.*]] = convert_function [[FN]] // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxxxIegnrr_xx_xtSgIegnr_lTR diff --git a/test/SILGen/function_type_conversion.swift b/test/SILGen/function_type_conversion.swift index 3e2aab4fbbdca..5bd4898377eb8 100644 --- a/test/SILGen/function_type_conversion.swift +++ b/test/SILGen/function_type_conversion.swift @@ -4,7 +4,7 @@ func generic(_ f: @escaping (T) -> U) -> (T) -> U { return f } // CHECK-LABEL: sil {{.*}}4main{{.*}}11sameGeneric func sameGeneric(_: X, _: Y, _ f: @escaping (Z) -> Z) -> (Z) -> Z { -// CHECK: bb0({{.*}}, [[F:%[0-9]+]] : @guaranteed $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for +// CHECK: bb0({{.*}}, [[F:%[0-9]+]] : @guaranteed $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // Similarly generic types should be directly substitutable // CHECK: [[GENERIC:%.*]] = function_ref @{{.*}}4main{{.*}}7generic // CHECK: [[RET:%.*]] = apply [[GENERIC]]([[F]]) @@ -18,7 +18,7 @@ func concreteIndirect(_ f: @escaping (Any) -> Any) -> (Any) -> Any { // Any is passed indirectly, but is a concrete type, so we need to convert // to the generic abstraction level // CHECK: [[F2:%.*]] = copy_value [[F]] - // CHECK: [[GENERIC_F:%.*]] = convert_function [[F2]] : {{.*}} to $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for + // CHECK: [[GENERIC_F:%.*]] = convert_function [[F2]] : {{.*}} to $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: [[GENERIC:%.*]] = function_ref @{{.*}}4main{{.*}}7generic // CHECK: [[GENERIC_RET:%.*]] = apply [[GENERIC]]([[GENERIC_F]]) // CHECK: [[RET:%.*]] = convert_function [[GENERIC_RET]] : {{.*}} @@ -33,7 +33,7 @@ func concreteDirect(_ f: @escaping (Int) -> String) -> (Int) -> String { // thunking and conversion to the substituted form // CHECK: [[F2:%.*]] = copy_value [[F]] // CHECK: [[REABSTRACT_F:%.*]] = partial_apply {{.*}}([[F2]]) - // CHECK: [[GENERIC_F:%.*]] = convert_function [[REABSTRACT_F]] : {{.*}} to $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for + // CHECK: [[GENERIC_F:%.*]] = convert_function [[REABSTRACT_F]] : {{.*}} to $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: [[GENERIC:%.*]] = function_ref @{{.*}}4main{{.*}}7generic // CHECK: [[GENERIC_RET:%.*]] = apply [[GENERIC]]([[GENERIC_F]]) // CHECK: [[REABSTRACT_RET:%.*]] = convert_function [[GENERIC_RET]] : {{.*}} diff --git a/test/SILGen/function_type_lowering.swift b/test/SILGen/function_type_lowering.swift index 0b348af345d67..3a9eadbb1c06a 100644 --- a/test/SILGen/function_type_lowering.swift +++ b/test/SILGen/function_type_lowering.swift @@ -4,19 +4,19 @@ // Similarly-abstract generic signatures should share an unsubstituted type // even in different generic contexts -// CHECK-LABEL: sil {{.*}}1a{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1a{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func a(_ x: (T) -> U) {} -// CHECK-LABEL: sil {{.*}}1b{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1b{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func b(_ x: (U) -> T) {} -// CHECK-LABEL: sil {{.*}}1c{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed U) -> () +// CHECK-LABEL: sil {{.*}}1c{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed U) -> () func c(_ x: (V) -> T, _: U) {} -// CHECK-LABEL: sil {{.*}}003Hca{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}003Hca{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func ç(_ x: (T) -> T) {} -// CHECK-LABEL: sil {{.*}}returnsThrowing{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for <τ_0_1, τ_0_2> for ) -> () +// CHECK-LABEL: sil {{.*}}returnsThrowing{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for <τ_0_1, τ_0_2> for ) -> () func returnsThrowing(_ x: (T) -> (U) throws -> V) {} @@ -26,26 +26,26 @@ protocol P { associatedtype A } -// CHECK-LABEL: sil {{.*}}1d{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1d{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func d(_ x: (T) -> T.A) {} -// CHECK-LABEL: sil {{.*}}1e{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1e{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func e(_ x: (T.A) -> T) {} // Preserve class constraints, because they're less abstract for layout and // calling convention purposes than unconstrained types -// CHECK-LABEL: sil {{.*}}1f{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1f{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func f(_ x: (T) -> U) {} -// CHECK-LABEL: sil {{.*}}1g{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1g{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func g(_ x: (U) -> T) {} -// CHECK-LABEL: sil {{.*}}1h{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1h{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func h(_ x: (T) -> U) {} -// CHECK-LABEL: sil {{.*}}1i{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1i{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func i(_ x: (U) -> T) {} @@ -53,19 +53,19 @@ func i(_ x: (U) -> T) {} protocol PC: AnyObject { } -// CHECK-LABEL: sil {{.*}}1j{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1j{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func j(_ x: (T) -> U) {} -// CHECK-LABEL: sil {{.*}}1k{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1k{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func k(_ x: (U) -> T) {} -// CHECK-LABEL: sil {{.*}}1l{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1l{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func l(_ x: (T) -> U) {} -// CHECK-LABEL: sil {{.*}}1m{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1m{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func m(_ x: (U) -> T) {} -// CHECK-LABEL: sil {{.*}}1n{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1n{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func n(_ x: (T) -> T.A) {} @@ -73,7 +73,7 @@ func n(_ x: (T) -> T.A) {} class Base {} -// CHECK-LABEL: sil {{.*}}1o{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1o{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func o (_ x: (T) -> U) {} @@ -91,11 +91,11 @@ protocol PCAC: AnyObject { associatedtype A: AnyObject } -// CHECK-LABEL: sil {{.*}}1p{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1p{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for ) -> () func p (_ x: (T) -> T.A) {} -// CHECK-LABEL: sil {{.*}}1q{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1q{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> (@in_guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func q (_ x: (T) -> T.A) {} -// CHECK-LABEL: sil {{.*}}1r{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () +// CHECK-LABEL: sil {{.*}}1r{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ) -> () func r (_ x: (T) -> T.A) {} @@ -112,35 +112,35 @@ struct S { } } -// CHECK-LABEL: sil {{.*}}1t{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (S<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for ) -> () +// CHECK-LABEL: sil {{.*}}1t{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> (S<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for ) -> () func t(_: (S) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t2{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_4 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.Nested<τ_0_2>) -> (@out τ_0_3, @owned τ_0_4) for ) -> () +// CHECK-LABEL: sil {{.*}}2t2{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_4 : _RefCountedObject> (S<τ_0_0, τ_0_1>.Nested<τ_0_2>) -> (@out τ_0_3, @owned τ_0_4) for ) -> () func t2(_: (S.Nested) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t3{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4, τ_0_5 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_5 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.Nested<τ_0_2>.NesNestedted<τ_0_3>) -> (@out τ_0_4, @owned τ_0_5) for ) -> () +// CHECK-LABEL: sil {{.*}}2t3{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4, τ_0_5 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_5 : _RefCountedObject> (S<τ_0_0, τ_0_1>.Nested<τ_0_2>.NesNestedted<τ_0_3>) -> (@out τ_0_4, @owned τ_0_5) for ) -> () func t3(_: (S.Nested.NesNestedted) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t4{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_4 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.Nested<τ_0_2>.NestedNonGeneric) -> (@out τ_0_3, @owned τ_0_4) for ) -> () +// CHECK-LABEL: sil {{.*}}2t4{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_2 : _RefCountedObject, τ_0_4 : _RefCountedObject> (S<τ_0_0, τ_0_1>.Nested<τ_0_2>.NestedNonGeneric) -> (@out τ_0_3, @owned τ_0_4) for ) -> () func t4(_: (S.Nested.NestedNonGeneric) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t5{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.NestedNonGeneric) -> (@out τ_0_2, @owned τ_0_3) for ) -> () +// CHECK-LABEL: sil {{.*}}2t5{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> (S<τ_0_0, τ_0_1>.NestedNonGeneric) -> (@out τ_0_2, @owned τ_0_3) for ) -> () func t5(_: (S.NestedNonGeneric) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t6{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_4 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.NestedNonGeneric.NesNestedted<τ_0_2>) -> (@out τ_0_3, @owned τ_0_4) for ) -> () +// CHECK-LABEL: sil {{.*}}2t6{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3, τ_0_4 where τ_0_1 : _RefCountedObject, τ_0_4 : _RefCountedObject> (S<τ_0_0, τ_0_1>.NestedNonGeneric.NesNestedted<τ_0_2>) -> (@out τ_0_3, @owned τ_0_4) for ) -> () func t6(_: (S.NestedNonGeneric.NesNestedted) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}2t7{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (S<τ_0_0, τ_0_1>.NestedNonGeneric.NestedNonGeneric) -> (@out τ_0_2, @owned τ_0_3) for ) -> () +// CHECK-LABEL: sil {{.*}}2t7{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> (S<τ_0_0, τ_0_1>.NestedNonGeneric.NestedNonGeneric) -> (@out τ_0_2, @owned τ_0_3) for ) -> () func t7(_: (S.NestedNonGeneric.NestedNonGeneric) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}1u{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (S<τ_0_0, τ_0_1>) -> @out τ_0_2 for ) -> () +// CHECK-LABEL: sil {{.*}}1u{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (S<τ_0_0, τ_0_1>) -> @out τ_0_2 for ) -> () func u(_: (S) -> T) {} class C {} -// CHECK-LABEL: sil {{.*}}1v{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (@guaranteed C<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for ) -> () +// CHECK-LABEL: sil {{.*}}1v{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : _RefCountedObject, τ_0_3 : _RefCountedObject> (@guaranteed C<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for ) -> () func v(_: (C) -> (T, U)) {} -// CHECK-LABEL: sil {{.*}}1w{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@guaranteed C<τ_0_0, τ_0_1>) -> @out τ_0_2 for ) -> () +// CHECK-LABEL: sil {{.*}}1w{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@guaranteed C<τ_0_0, τ_0_1>) -> @out τ_0_2 for ) -> () func w(_: (C) -> T) {} -// CHECK-LABEL: sil {{.*}}1x{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> () for ) -> () +// CHECK-LABEL: sil {{.*}}1x{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed @substituted <τ_0_0 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> () for ) -> () func x>(_: (V) -> Void) {} // We can't generally lower away protocol constraints @@ -151,17 +151,17 @@ func x>(_: (V) -> Void) {} struct SP { var x: T.A } class CP { } -// CHECK-LABEL: sil {{.*}}1z{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : P> in (@in_guaranteed SP<τ_0_0>) -> () for ) -> () +// CHECK-LABEL: sil {{.*}}1z{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0 where τ_0_0 : P> (@in_guaranteed SP<τ_0_0>) -> () for ) -> () func z(_: (SP) -> Void) {} struct SCP> {} -// CHECK-LABEL: sil {{.*}}2z2{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : CP, τ_0_1 : _NativeClass> in (SCP<τ_0_0, τ_0_1>) -> () for ) -> () +// CHECK-LABEL: sil {{.*}}2z2{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : CP, τ_0_1 : _NativeClass> (SCP<τ_0_0, τ_0_1>) -> () for ) -> () func z2>(_: (SCP) -> Void) {} -// CHECK-LABEL: sil {{.*}}3z2a{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_0 : P, τ_0_1 : CP, τ_0_1 : _NativeClass> in (SCP<τ_0_0, τ_0_1>) -> () for ) -> () +// CHECK-LABEL: sil {{.*}}3z2a{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_0 : P, τ_0_1 : CP, τ_0_1 : _NativeClass> (SCP<τ_0_0, τ_0_1>) -> () for ) -> () func z2a>(_: (SCP) -> Void) {} -// CHECK-LABEL: sil {{.*}}2z3{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (S<τ_0_0, τ_0_1>) -> () for ) -> () +// CHECK-LABEL: sil {{.*}}2z3{{.*}} : $@convention(thin) > (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (S<τ_0_0, τ_0_1>) -> () for ) -> () func z3>(_: (S) -> Void) {} // Opaque types should not be extracted as substituted arguments because they diff --git a/test/SILGen/function_type_lowering_objc.swift b/test/SILGen/function_type_lowering_objc.swift index 8f12566fdac81..ffb5c23dac232 100644 --- a/test/SILGen/function_type_lowering_objc.swift +++ b/test/SILGen/function_type_lowering_objc.swift @@ -6,7 +6,7 @@ import Foundation -// CHECK-LABEL: sil {{.*}}3foo{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> () +// CHECK-LABEL: sil {{.*}}3foo{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> () func foo(f: (T) -> ()) {} -// CHECK-LABEL: sil {{.*}}3bar{{.*}} : $@convention(thin) (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : _RefCountedObject> in (@guaranteed Optional<τ_0_0>) -> () +// CHECK-LABEL: sil {{.*}}3bar{{.*}} : $@convention(thin) (@noescape @callee_guaranteed @substituted <τ_0_0 where τ_0_0 : _RefCountedObject> (@guaranteed Optional<τ_0_0>) -> () func bar(f: (T?) -> ()) {} diff --git a/test/SILGen/generic_closures.swift b/test/SILGen/generic_closures.swift index a09f142dd0be7..d208874ecaf8a 100644 --- a/test/SILGen/generic_closures.swift +++ b/test/SILGen/generic_closures.swift @@ -208,7 +208,7 @@ class Class {} protocol HasClassAssoc { associatedtype Assoc : Class } // CHECK-LABEL: sil hidden [ossa] @$s16generic_closures027captures_class_constrained_A0_1fyx_5AssocQzAEctAA08HasClassF0RzlF -// CHECK: bb0([[ARG1:%.*]] : $*T, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for ): +// CHECK: bb0([[ARG1:%.*]] : $*T, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> (@guaranteed τ_0_0) -> @owned τ_0_1 for ): // CHECK: [[GENERIC_FN:%.*]] = function_ref @$s16generic_closures027captures_class_constrained_A0_1fyx_5AssocQzAEctAA08HasClassF0RzlFA2EcycfU_ // CHECK: [[ARG2_COPY:%.*]] = copy_value [[ARG2]] // CHECK: [[CONCRETE_FN:%.*]] = partial_apply [callee_guaranteed] [[GENERIC_FN]]([[ARG2_COPY]]) diff --git a/test/SILGen/guaranteed_normal_args_curry_thunks.swift b/test/SILGen/guaranteed_normal_args_curry_thunks.swift index b0f767c17c153..484efb026e713 100644 --- a/test/SILGen/guaranteed_normal_args_curry_thunks.swift +++ b/test/SILGen/guaranteed_normal_args_curry_thunks.swift @@ -170,7 +170,7 @@ func testLoadableStructInitLoadable() { // extra thunk. // // CHECK-LABEL: sil hidden [ossa] @$ss37testAddrOnlyStructInitGenericConcreteyyF : $@convention(thin) () -> () { -// CHECK: [[THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> +// CHECK: [[THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> // CHECK: [[CURRY_THUNK:%.*]] = apply [[THUNK_REF]]( // CHECK: [[CURRY_THUNK_CONV:%.*]] = convert_function [[CURRY_THUNK]] // CHECK: [[CANONICAL_THUNK_REF:%.*]] = function_ref @$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric) -> @owned AddrOnlyStructInitGeneric @@ -184,7 +184,7 @@ func testLoadableStructInitLoadable() { // Curry thunk // -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) (@thin AddrOnlyStructInitGeneric.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for { +// CHECK-LABEL: sil shared [thunk] [ossa] @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) (@thin AddrOnlyStructInitGeneric.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for { // CHECK: [[ALLOCATING_INIT_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @out AddrOnlyStructInitGeneric<τ_0_0> // CHECK: [[ALLOCATING_INIT:%.*]] = partial_apply [callee_guaranteed] [[ALLOCATING_INIT_REF]]( // CHECK: [[THUNK_REF:%.*]] = function_ref @$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_0>) -> @out AddrOnlyStructInitGeneric<τ_0_0> @@ -217,7 +217,7 @@ func testAddrOnlyStructInitGenericConcrete() { } // CHECK-LABEL: sil hidden [ossa] @$ss029testAddrOnlyStructInitGenericbC01tyx_ts08Protocole7AddressC0RzlF : $@convention(thin) (@in_guaranteed T) -> () { -// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> +// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> // CHECK: [[CURRY_THUNK:%.*]] = apply [[CURRY_THUNK_REF]]( // CHECK: [[Y:%.*]] = alloc_stack $AddrOnlyStructInitGeneric, let, name "y" // CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[CURRY_THUNK]] @@ -234,7 +234,7 @@ func testAddrOnlyStructInitGenericAddrOnly(t: T) { } // CHECK-LABEL: sil hidden [ossa] @$ss20testGenericInitClass1tyx_ts08ProtocolC8LoadableRzlF : $@convention(thin) (@in_guaranteed T) -> () { -// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@thick τ_0_0.Type) -> @owned @callee_guaranteed <τ_0_0> in (@guaranteed Klass) -> @out τ_0_0 for <τ_0_0> +// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@thick τ_0_0.Type) -> @owned @callee_guaranteed @substituted <τ_0_0> (@guaranteed Klass) -> @out τ_0_0 for <τ_0_0> // CHECK: [[CURRY_THUNK:%.*]] = apply [[CURRY_THUNK_REF]]( // CHECK: [[Y:%.*]] = alloc_stack $T, let, name "y" // CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[CURRY_THUNK]] @@ -247,7 +247,7 @@ func testAddrOnlyStructInitGenericAddrOnly(t: T) { // Curry thunk. // -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) (@thick Self.Type) -> @owned @callee_guaranteed <τ_0_0> in (@guaranteed Klass) -> @out τ_0_0 for { +// CHECK-LABEL: sil shared [thunk] [ossa] @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) (@thick Self.Type) -> @owned @callee_guaranteed @substituted <τ_0_0> (@guaranteed Klass) -> @out τ_0_0 for { // CHECK: [[WITNESS_METHOD_REF:%.*]] = witness_method $Self, #ProtocolInitLoadable.init!allocator.1 : (Self.Type) -> (Klass) -> Self : $@convention(witness_method: ProtocolInitLoadable) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@owned Klass, @thick τ_0_0.Type) -> @out τ_0_0 // CHECK: [[WITNESS_METHOD:%.*]] = partial_apply [callee_guaranteed] [[WITNESS_METHOD_REF]]( // CHECK: [[CANONICAL_THUNK_REF:%.*]] = function_ref @$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out τ_0_0) -> @out τ_0_0 diff --git a/test/SILGen/keypath_application.swift b/test/SILGen/keypath_application.swift index 514d070a3a74e..7fc83b8c0f318 100644 --- a/test/SILGen/keypath_application.swift +++ b/test/SILGen/keypath_application.swift @@ -200,12 +200,12 @@ func writebackNesting(x: inout Int, // -- get 'b' // CHECK: function_ref @$sSi19keypath_applicationE1bSivg // -- apply keypath y - // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath : + // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath : $@yield_once @convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @guaranteed WritableKeyPath<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 // CHECK: ([[Y_ADDR:%.*]], [[Y_TOKEN:%.*]]) = begin_apply [[PROJECT_FN]] // -- get 'u' // CHECK: function_ref @$sSi19keypath_applicationE1uSivg // -- apply keypath z - // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath : + // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath : $@yield_once @convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @guaranteed WritableKeyPath<τ_0_0, τ_0_1>) -> @yields @inout τ_0_1 // CHECK: ([[Z_ADDR:%.*]], [[Z_TOKEN:%.*]]) = begin_apply [[PROJECT_FN]] // -- set 'tt' diff --git a/test/SILGen/keypaths.swift b/test/SILGen/keypaths.swift index 4a83001d2d3a3..5629ec01e14cf 100644 --- a/test/SILGen/keypaths.swift +++ b/test/SILGen/keypaths.swift @@ -111,8 +111,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##C.reabstracted, - // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.reabstracted @@ -140,8 +140,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $S<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##S.reabstracted, - // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () // CHECK-SAME: ) _ = \S.reabstracted diff --git a/test/SILGen/modify.swift b/test/SILGen/modify.swift index 00aa7621023c9..328819da93f7d 100644 --- a/test/SILGen/modify.swift +++ b/test/SILGen/modify.swift @@ -64,7 +64,7 @@ extension Derived : Abstractable {} // CHECK-NEXT: [[SELF:%.*]] = upcast [[T0]] : $Derived to $Base // CHECK-NEXT: [[FN:%.*]] = class_method [[SELF]] : $Base, #Base.storedFunction!modify.1 // CHECK-NEXT: ([[SUPER_ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[FN]]([[SELF]]) -// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK-NEXT: [[SUPER_FN:%.*]] = load [take] [[SUPER_ADDR]] // CHECK-NEXT: // function_ref // CHECK-NEXT: [[REABSTRACTOR:%.*]] = function_ref @$sSiIegd_SiIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int) -> @out Int @@ -92,7 +92,7 @@ extension Derived : Abstractable {} // CHECK-NEXT: // function_ref // CHECK-NEXT: [[FN:%.*]] = function_ref @$s6modify4BaseC19finalStoredFunctionSiycvM // CHECK-NEXT: ([[SUPER_ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[FN]]([[SELF]]) -// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK-NEXT: [[SUPER_FN:%.*]] = load [take] [[SUPER_ADDR]] // CHECK-NEXT: function_ref // CHECK-NEXT: [[REABSTRACTOR:%.*]] = function_ref @$sSiIegd_SiIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int) -> @out Int @@ -119,7 +119,7 @@ extension Derived : Abstractable {} // CHECK-NEXT: // function_ref // CHECK-NEXT: [[FN:%.*]] = function_ref @$s6modify4BaseC14staticFunctionSiycvMZ // CHECK-NEXT: ([[SUPER_ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[FN]]([[SELF]]) -// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK-NEXT: [[SUB_ADDR:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK-NEXT: [[SUPER_FN:%.*]] = load [take] [[SUPER_ADDR]] // CHECK-NEXT: function_ref // CHECK-NEXT: [[REABSTRACTOR:%.*]] = function_ref @$sSiIegd_SiIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int) -> @out Int diff --git a/test/SILGen/modify_objc.swift b/test/SILGen/modify_objc.swift index bf178d58cc311..b36bbab724ea6 100644 --- a/test/SILGen/modify_objc.swift +++ b/test/SILGen/modify_objc.swift @@ -35,7 +35,7 @@ extension ClassWithBlockProperty : ProtocolWithBlockProperty {} // CHECK-NEXT: // function_ref // CHECK-NEXT: [[FN:%.*]] = function_ref @$sSo22ClassWithBlockPropertyC09dependentC0ySSSgcSgvM // CHECK-NEXT: ([[YIELD_ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[FN]]([[SELF]]) -// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Optional<@callee_guaranteed <τ_0_0> in (@in_guaranteed τ_0_0) -> () for >> +// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for >> // CHECK-NEXT: [[IN_FUNCTION:%.*]] = load [take] [[YIELD_ADDR]] // CHECK: {{^}}bb3([[OUT_FUNCTION:%.*]] : // CHECK-NEXT: store [[OUT_FUNCTION]] to [init] [[TEMP]] : diff --git a/test/SILGen/nested_generics.swift b/test/SILGen/nested_generics.swift index f752e3bab4554..a4b4b88663a5d 100644 --- a/test/SILGen/nested_generics.swift +++ b/test/SILGen/nested_generics.swift @@ -48,7 +48,7 @@ struct Lunch where T.Topping : CuredMeat { // CHECK-LABEL: sil private [ossa] @$s15nested_generics5LunchV6DinnerV15coolCombination1t1uy7ToppingQz_AA4DeliC7MustardOyAA6PepperV_GtF0A7GenericL_1x1yqd0___qd0_0_tqd0___qd0_0_tAA5PizzaRzAA6HotDogRd__AA9CuredMeatAJRQAQ9CondimentRtd__r__0_lF : $@convention(thin) .Mustard> (@in_guaranteed X, @in_guaranteed Y) -> (@out X, @out Y) // CHECK-LABEL: // nested_generics.Lunch.Dinner.init(firstCourse: A, secondCourse: Swift.Optional, leftovers: A, transformation: (A) -> A1) -> nested_generics.Lunch.Dinner -// CHECK-LABEL: sil hidden [ossa] @$s15nested_generics5LunchV6DinnerV11firstCourse06secondF09leftovers14transformationAEyx_qd__Gx_qd__Sgxqd__xctcfC : $@convention(method) .Mustard> (@owned T, @in Optional, @owned T, @owned @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for , @thin Lunch.Dinner.Type) -> @out Lunch.Dinner +// CHECK-LABEL: sil hidden [ossa] @$s15nested_generics5LunchV6DinnerV11firstCourse06secondF09leftovers14transformationAEyx_qd__Gx_qd__Sgxqd__xctcfC : $@convention(method) .Mustard> (@owned T, @in Optional, @owned T, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> @out τ_0_1 for , @thin Lunch.Dinner.Type) -> @out Lunch.Dinner // Non-generic nested inside generic diff --git a/test/SILGen/objc_bridging_any.swift b/test/SILGen/objc_bridging_any.swift index 56477d559ca40..3fee4b8be0b28 100644 --- a/test/SILGen/objc_bridging_any.swift +++ b/test/SILGen/objc_bridging_any.swift @@ -664,7 +664,7 @@ class AnyHashableClass : NSObject { // CHECK: [[BRIDGE:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF // CHECK: [[FN:%.*]] = function_ref @$sIeg_ytIegr_TR // CHECK: partial_apply [callee_guaranteed] [[FN]] -// CHECK: [[SELF:%.*]] = alloc_stack $Optional<@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>> +// CHECK: [[SELF:%.*]] = alloc_stack $Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>> // CHECK: apply [[BRIDGE]]<() -> ()>([[SELF]]) func bridgeOptionalFunctionToAnyObject(fn: (() -> ())?) -> AnyObject { return fn as AnyObject diff --git a/test/SILGen/optional.swift b/test/SILGen/optional.swift index 316257a7fabcf..d6cd08fb27514 100644 --- a/test/SILGen/optional.swift +++ b/test/SILGen/optional.swift @@ -30,8 +30,8 @@ func testAddrOnlyCallResult(_ f: (() -> T)?) { var x = f?() } // CHECK-LABEL: sil hidden [ossa] @{{.*}}testAddrOnlyCallResult{{.*}} : -// CHECK: bb0([[T0:%.*]] : @guaranteed $Optional<@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for >): -// CHECK: [[F:%.*]] = alloc_box $<τ_0_0> { var Optional<@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <τ_0_0>> } , var, name "f" +// CHECK: bb0([[T0:%.*]] : @guaranteed $Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for >): +// CHECK: [[F:%.*]] = alloc_box $<τ_0_0> { var Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>> } , var, name "f" // CHECK-NEXT: [[PBF:%.*]] = project_box [[F]] // CHECK: [[T0_COPY:%.*]] = copy_value [[T0]] // CHECK: store [[T0_COPY]] to [init] [[PBF]] diff --git a/test/SILGen/partial_apply_protocol.swift b/test/SILGen/partial_apply_protocol.swift index 9c6443962e8ee..af84fdbdae632 100644 --- a/test/SILGen/partial_apply_protocol.swift +++ b/test/SILGen/partial_apply_protocol.swift @@ -86,7 +86,7 @@ func testClonable(c: Clonable) { // CHECK-NEXT: [[OUTER_RESULT:%.*]] = init_existential_metatype [[INNER_RESULT]] // CHECK-NEXT: return [[OUTER_RESULT]] -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxlyxIsegr_Iego_22partial_apply_protocol8Clonable_pIegr_Iego_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @owned @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <τ_0_0>) -> @owned @callee_guaranteed () -> @out Clonable +// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxlyxIsegr_Iego_22partial_apply_protocol8Clonable_pIegr_Iego_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>) -> @owned @callee_guaranteed () -> @out Clonable // CHECK: bb0(%0 : // CHECK-NEXT: [[INNER_RESULT:%.*]] = apply %0() // CHECK-NEXT: [[INNER_RESULT_CONV:%.*]] = convert_function [[INNER_RESULT]] @@ -144,8 +144,8 @@ func testClonableInGenericContext(c: Clonable, t: T) { // CHECK-NEXT: dealloc_stack [[INNER_RESULT]] // CHECK-NEXT: return [[EMPTY]] -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxxlyqd__Isegr_Iegno_x22partial_apply_protocol8Clonable_pIegr_Iegno_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <τ_1_0>) -> @owned @callee_guaranteed () -> @out Clonable { -// CHECK: bb0(%0 : $*τ_0_0, %1 : @guaranteed $@callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <τ_1_0>): +// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxxlyqd__Isegr_Iegno_x22partial_apply_protocol8Clonable_pIegr_Iegno_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_1_0>) -> @owned @callee_guaranteed () -> @out Clonable { +// CHECK: bb0(%0 : $*τ_0_0, %1 : @guaranteed $@callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_1_0>): // CHECK-NEXT: [[RES:%.*]] = apply %1(%0) // CHECK-NEXT: [[RES_CONV:%.*]] = convert_function [[RES]] // CHECK: [[THUNK_FN:%.*]] = function_ref @$sqd__Iegr_22partial_apply_protocol8Clonable_pIegr_AaBRd__r__lTR diff --git a/test/SILGen/pointer_conversion.swift b/test/SILGen/pointer_conversion.swift index ae5e29b4bb3d9..2bd148cd4537f 100644 --- a/test/SILGen/pointer_conversion.swift +++ b/test/SILGen/pointer_conversion.swift @@ -268,7 +268,7 @@ func functionInoutToPointer() { // CHECK: [[BOX:%.*]] = alloc_box ${ var @callee_guaranteed () -> () } var f: () -> () = {} - // CHECK: [[REABSTRACT_BUF:%.*]] = alloc_stack $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()> + // CHECK: [[REABSTRACT_BUF:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()> // CHECK: address_to_pointer [[REABSTRACT_BUF]] takesMutableVoidPointer(&f) } diff --git a/test/SILGen/property_abstraction.swift b/test/SILGen/property_abstraction.swift index 592326a7d9ee7..fd3971750636b 100644 --- a/test/SILGen/property_abstraction.swift +++ b/test/SILGen/property_abstraction.swift @@ -120,7 +120,7 @@ struct T20341012 { private var options: ArrayLike { get {} set {} } // CHECK-LABEL: sil hidden [ossa] @$s20property_abstraction9T20341012V1t{{[_0-9a-zA-Z]*}}F - // CHECK: [[TMP1:%.*]] = alloc_stack $(title: (), action: @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>) + // CHECK: [[TMP1:%.*]] = alloc_stack $(title: (), action: @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>) // CHECK: apply {{.*}}<(title: (), action: () -> ())>([[TMP1]], mutating func t() { _ = self.options[()].title diff --git a/test/SILGen/reabstract-tuple.swift b/test/SILGen/reabstract-tuple.swift index 30de079aeb690..a28b58d90f8db 100644 --- a/test/SILGen/reabstract-tuple.swift +++ b/test/SILGen/reabstract-tuple.swift @@ -21,14 +21,14 @@ class Box { // CHECK: [[THUNK1:%.*]] = function_ref @$sIeg_ytIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out () // CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK1]]([[ELTA_1]]) : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> @out () // CHECK: [[PA_CONV:%.*]] = convert_function [[PA]] -// CHECK: [[TUPLEB:%.*]] = tuple ([[ELTA_0]] : $Int, [[PA_CONV]] : $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>) +// CHECK: [[TUPLEB:%.*]] = tuple ([[ELTA_0]] : $Int, [[PA_CONV]] : $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>) // CHECK: ([[TUPLEB_0:%.*]], [[TUPLEB_1:%.*]]) = destructure_tuple [[TUPLEB]] // CHECK: // function_ref Box.__allocating_init(_:) // CHECK: [[INIT_F:%.*]] = function_ref @$s4main3BoxCyACyxGxcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thick Box<τ_0_0>.Type) -> @owned Box<τ_0_0> // CHECK: [[CALL:%.*]] = apply [[INIT_F]]<(Int, () -> ())>(%{{.*}}, %{{.*}}) : $@convention(method) <τ_0_0> (@in τ_0_0, @thick Box<τ_0_0>.Type) -> @owned Box<τ_0_0> // CHECK: [[BORROW_CALL:%.*]] = begin_borrow [[CALL]] : $Box<(Int, () -> ())> // CHECK: [[REF:%.*]] = ref_element_addr [[BORROW_CALL]] : $Box<(Int, () -> ())>, #Box.value -// CHECK: [[TUPLEC:%.*]] = load [copy] [[REF]] : $*(Int, @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>) +// CHECK: [[TUPLEC:%.*]] = load [copy] [[REF]] : $*(Int, @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>) // CHECK: ([[TUPLEC_0:%.*]], [[TUPLEC_1:%.*]]) = destructure_tuple [[TUPLEC]] // CHECK: [[TUPLEC_1_CONV:%.*]] = convert_function [[TUPLEC_1]] // CHECK: [[THUNK2:%.*]] = function_ref @$sytIegr_Ieg_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> @out ()) -> () diff --git a/test/SILGen/reabstract_lvalue.swift b/test/SILGen/reabstract_lvalue.swift index 0e863d5ef07a6..f1e39e74a9780 100644 --- a/test/SILGen/reabstract_lvalue.swift +++ b/test/SILGen/reabstract_lvalue.swift @@ -19,7 +19,7 @@ func reabstractFunctionInOut() { // CHECK: [[THICK_ARG:%.*]] = thin_to_thick_function [[ARG]] // CHECK: store [[THICK_ARG:%.*]] to [init] [[PB]] // CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] [[PB]] : $*@callee_guaranteed (Int) -> Double - // CHECK: [[ABSTRACTED_BOX:%.*]] = alloc_stack $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for + // CHECK: [[ABSTRACTED_BOX:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for // CHECK: [[THICK_ARG:%.*]] = load [copy] [[WRITE]] // CHECK: [[THUNK1:%.*]] = function_ref @$sSiSdIegyd_SiSdIegnr_TR // CHECK: [[ABSTRACTED_ARG:%.*]] = partial_apply [callee_guaranteed] [[THUNK1]]([[THICK_ARG]]) diff --git a/test/SILGen/tuple_attribute_reabstraction.swift b/test/SILGen/tuple_attribute_reabstraction.swift index 234b1645e7af6..9ed293475a7cd 100644 --- a/test/SILGen/tuple_attribute_reabstraction.swift +++ b/test/SILGen/tuple_attribute_reabstraction.swift @@ -16,7 +16,7 @@ public func f() { // We shouldn't have @autoclosure and @escaping attributes in the lowered tuple type: -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIg_Ieg_Iegyg_xlyytIsgr_xlyytIsegr_ytIegnnr_TR : $@convention(thin) (@in_guaranteed @noescape @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, @in_guaranteed @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for <()>, @guaranteed @callee_guaranteed (@noescape @callee_guaranteed () -> (), @guaranteed @callee_guaranteed () -> ()) -> ()) -> @out () +// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sIg_Ieg_Iegyg_xlyytIsgr_xlyytIsegr_ytIegnnr_TR : $@convention(thin) (@in_guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @guaranteed @callee_guaranteed (@noescape @callee_guaranteed () -> (), @guaranteed @callee_guaranteed () -> ()) -> ()) -> @out () // The one-element vararg tuple ([Int]...) should be exploded and not treated as opaque, // even though its materializable: diff --git a/test/SILOptimizer/OSLogPrototypeCompileTest.sil b/test/SILOptimizer/OSLogPrototypeCompileTest.sil index bb7209eee437c..f50dcb7e20548 100644 --- a/test/SILOptimizer/OSLogPrototypeCompileTest.sil +++ b/test/SILOptimizer/OSLogPrototypeCompileTest.sil @@ -834,15 +834,15 @@ bb0(%0 : $Builtin.Int1): %3 = apply %2<() -> Int32>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) %4 = tuple_extract %3 : $(Array<() -> Int32>, Builtin.RawPointer), 0 %5 = tuple_extract %3 : $(Array<() -> Int32>, Builtin.RawPointer), 1 - %6 = pointer_to_address %5 : $Builtin.RawPointer to [strict] $*@callee_guaranteed in () -> @out A for + %6 = pointer_to_address %5 : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted () -> @out A for %7 = integer_literal $Builtin.Int32, 81 %8 = struct $Int32 (%7 : $Builtin.Int32) %9 = function_ref @closure1 : $@convention(thin) (Int32) -> Int32 %10 = partial_apply [callee_guaranteed] %9(%8) : $@convention(thin) (Int32) -> Int32 %11 = function_ref @$ss5Int32VIegd_ABIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int32) -> @out Int32 %12 = partial_apply [callee_guaranteed] %11(%10) : $@convention(thin) (@guaranteed @callee_guaranteed () -> Int32) -> @out Int32 - %13 = convert_function %12 : $@callee_guaranteed () -> @out Int32 to $@callee_guaranteed in () -> @out A for - store %13 to %6 : $*@callee_guaranteed in () -> @out A for + %13 = convert_function %12 : $@callee_guaranteed () -> @out Int32 to $@callee_guaranteed @substituted () -> @out A for + store %13 to %6 : $*@callee_guaranteed @substituted () -> @out A for // Create an instance of OSLogMessageClosureArrayStub using the above array // of closures. diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift index 6a95a2c40d117..5228ae8131173 100644 --- a/test/SILOptimizer/access_marker_verify.swift +++ b/test/SILOptimizer/access_marker_verify.swift @@ -558,7 +558,7 @@ enum OptionalWithMap { } } } -// CHECK-LABEL: sil hidden [ossa] @$s20access_marker_verify15OptionalWithMapO3mapyqd__Sgqd__xKXEKlF : $@convention(method) (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , @in_guaranteed OptionalWithMap) -> (@out Optional, @error Error) +// CHECK-LABEL: sil hidden [ossa] @$s20access_marker_verify15OptionalWithMapO3mapyqd__Sgqd__xKXEKlF : $@convention(method) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , @in_guaranteed OptionalWithMap) -> (@out Optional, @error Error) // CHECK: [[STK:%.]] = alloc_stack $OptionalWithMap // CHECK-NOT: begin_access // CHECK: copy_addr %2 to [initialization] [[STK]] : $*OptionalWithMap diff --git a/test/SILOptimizer/capture_promotion_generic_context.sil b/test/SILOptimizer/capture_promotion_generic_context.sil index 952695f0f7898..eba5c4bf18682 100644 --- a/test/SILOptimizer/capture_promotion_generic_context.sil +++ b/test/SILOptimizer/capture_promotion_generic_context.sil @@ -92,9 +92,9 @@ entry(%0: $*R, %1 : $*Int, %b : $<τ_0_0> { var E< (R<τ_0_0>)->Int > } ): %e = load %a : $*E<(R)->Int> switch_enum %e : $E<(R)->Int>, case #E.Some!enumelt.1 : bb1, default bb2 -bb1(%f : $@callee_guaranteed in (@in_guaranteed A) -> @out B for , Int>): +bb1(%f : $@callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , Int>): %t = tuple () - apply %f(%1, %0) : $@callee_guaranteed in (@in_guaranteed A) -> @out B for , Int> + apply %f(%1, %0) : $@callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , Int> br exit bb2: br exit diff --git a/test/SILOptimizer/capture_promotion_generic_context_ownership.sil b/test/SILOptimizer/capture_promotion_generic_context_ownership.sil index 2a9e93ece6065..4b03d6a0462c9 100644 --- a/test/SILOptimizer/capture_promotion_generic_context_ownership.sil +++ b/test/SILOptimizer/capture_promotion_generic_context_ownership.sil @@ -94,11 +94,11 @@ entry(%0 : $*R, %1 : $*Int, %b : @owned $<τ_0_0> { var E<(R<τ_0_0>)->Int> } %e = load [copy] %a : $*E<(R)->Int> switch_enum %e : $E<(R)->Int>, case #E.Some!enumelt.1 : bb1, default bb2 -bb1(%f : @owned $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int>): - %bf = begin_borrow %f : $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> - apply %bf(%1, %0) : $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> - end_borrow %bf : $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> - destroy_value %f : $@callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> +bb1(%f : @owned $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int>): + %bf = begin_borrow %f : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> + apply %bf(%1, %0) : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> + end_borrow %bf : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> + destroy_value %f : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , Int> br exit bb2(%original : @owned $E<(R)->Int>): diff --git a/test/SILOptimizer/for_each_loop_unroll_test.sil b/test/SILOptimizer/for_each_loop_unroll_test.sil index 5557a8ea4fafd..8930a7f112a65 100644 --- a/test/SILOptimizer/for_each_loop_unroll_test.sil +++ b/test/SILOptimizer/for_each_loop_unroll_test.sil @@ -74,25 +74,25 @@ bb2(%39 : @owned $Error): // CHECK: dealloc_stack [[STACK]] // CHECK: unreachable -sil @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error +sil @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error -sil hidden [ossa] @nonTrivialForEachLoopUnrollTest : $@convention(thin) (@owned @callee_guaranteed in () -> @out A for , @owned @callee_guaranteed in () -> @out A for ) -> () { -bb0(%0: @owned $@callee_guaranteed in () -> @out A for , %1: @owned $@callee_guaranteed in () -> @out A for ): +sil hidden [ossa] @nonTrivialForEachLoopUnrollTest : $@convention(thin) (@owned @callee_guaranteed @substituted () -> @out A for , @owned @callee_guaranteed @substituted () -> @out A for ) -> () { +bb0(%0: @owned $@callee_guaranteed @substituted () -> @out A for , %1: @owned $@callee_guaranteed @substituted () -> @out A for ): %2 = integer_literal $Builtin.Word, 2 %3 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) %4 = apply %3<() -> Int>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) (%5, %6) = destructure_tuple %4 : $(Array<()->Int>, Builtin.RawPointer) - %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*@callee_guaranteed in () -> @out A for - store %0 to [init] %7 : $*@callee_guaranteed in () -> @out A for + %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted () -> @out A for + store %0 to [init] %7 : $*@callee_guaranteed @substituted () -> @out A for %12 = integer_literal $Builtin.Word, 1 - %13 = index_addr %7 : $*@callee_guaranteed in () -> @out A for , %12 : $Builtin.Word - store %1 to [init] %13 : $*@callee_guaranteed in () -> @out A for + %13 = index_addr %7 : $*@callee_guaranteed @substituted () -> @out A for , %12 : $Builtin.Word + store %1 to [init] %13 : $*@callee_guaranteed @substituted () -> @out A for %21 = begin_borrow %5 : $Array<()->Int> %22 = alloc_stack $Array<()->Int> %23 = store_borrow %21 to %22 : $*Array<()->Int> - %24 = function_ref @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error - %25 = convert_function %24 : $@convention(thin) (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error to $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error - %26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error to $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed in () -> @out A for ) -> @error Error + %24 = function_ref @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error + %25 = convert_function %24 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error to $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error + %26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error to $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted () -> @out A for ) -> @error Error // A stub for Sequence.forEach(_:) %30 = function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error try_apply %30<[() -> Int]>(%26, %22) : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error, normal bb1, error bb2 @@ -109,16 +109,16 @@ bb2(%39 : @owned $Error): } // CHECK-LABEL: nonTrivialForEachLoopUnrollTest // CHECK: [[ELEM1:%[0-9]+]] = copy_value %0 -// CHECK-NEXT: store %0 to [init] %{{.*}} : $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK-NEXT: store %0 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK: [[ELEM2:%[0-9]+]] = copy_value %1 -// CHECK-NEXT: store %1 to [init] %{{.*}} : $*@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK-NEXT: store %1 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function // CHECK-NOT: forEach -// CHECK: [[STACK:%[0-9]+]] = alloc_stack $@callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for +// CHECK: [[STACK:%[0-9]+]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for // CHECK: [[ELEM1BORROW:%[0-9]+]] = begin_borrow [[ELEM1]] // CHECK: store_borrow [[ELEM1BORROW]] to [[STACK]] // CHECK: end_borrow [[ELEM1BORROW]] -// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for ) -> @error Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] +// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for ) -> @error Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] // CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $Error): // CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $Error) @@ -127,7 +127,7 @@ bb2(%39 : @owned $Error): // CHECK: [[ELEM2BORROW:%[0-9]+]] = begin_borrow [[ELEM2]] // CHECK: store_borrow [[ELEM2BORROW]] to [[STACK]] // CHECK: end_borrow [[ELEM2BORROW]] -// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed <τ_0_0> in () -> @out τ_0_0 for ) -> @error Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]] +// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for ) -> @error Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]] // CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $Error): // CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $Error) diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index 890cfba8d02a8..ad673d269d351 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -3670,9 +3670,9 @@ bb0(%0 : $@thin T.Type): // CHECK: apply %0 sil @convert_function_substitution : $@convention(thin) (@guaranteed @callee_guaranteed () -> @out ()) -> () { bb0(%0 : $@callee_guaranteed () -> @out ()): - %1 = convert_function %0 : $@callee_guaranteed () -> @out () to $@callee_guaranteed in () -> @out A for <()> + %1 = convert_function %0 : $@callee_guaranteed () -> @out () to $@callee_guaranteed @substituted () -> @out A for <()> %2 = alloc_stack $() - apply %1(%2) : $@callee_guaranteed in () -> @out A for <()> + apply %1(%2) : $@callee_guaranteed @substituted () -> @out A for <()> dealloc_stack %2 : $*() return undef : $() } @@ -3680,10 +3680,10 @@ bb0(%0 : $@callee_guaranteed () -> @out ()): // CHECK-LABEL: sil @convert_function_substitution_pa : sil @convert_function_substitution_pa : $@convention(thin) (@guaranteed @callee_guaranteed (@in Int, @in Int) -> @out (), @in Int) -> @owned @callee_guaranteed () -> @out () { bb0(%0 : $@callee_guaranteed (@in Int, @in Int) -> @out (), %1 : $*Int): - %2 = convert_function %0 : $@callee_guaranteed (@in Int, @in Int) -> @out () to $@callee_guaranteed in (@in A, @in B) -> @out C for - %3 = partial_apply [callee_guaranteed] %2(%1) : $@callee_guaranteed in (@in A, @in B) -> @out C for - %4 = partial_apply [callee_guaranteed] %3(%1) : $@callee_guaranteed in (@in A) -> @out C for - %5 = convert_function %4 : $@callee_guaranteed in () -> @out C for to $@callee_guaranteed () -> @out () + %2 = convert_function %0 : $@callee_guaranteed (@in Int, @in Int) -> @out () to $@callee_guaranteed @substituted (@in A, @in B) -> @out C for + %3 = partial_apply [callee_guaranteed] %2(%1) : $@callee_guaranteed @substituted (@in A, @in B) -> @out C for + %4 = partial_apply [callee_guaranteed] %3(%1) : $@callee_guaranteed @substituted (@in A) -> @out C for + %5 = convert_function %4 : $@callee_guaranteed @substituted () -> @out C for to $@callee_guaranteed () -> @out () return %5 : $@callee_guaranteed () -> @out () } diff --git a/test/SILOptimizer/temp_rvalue_opt.sil b/test/SILOptimizer/temp_rvalue_opt.sil index fb336341725a6..921626f164d61 100644 --- a/test/SILOptimizer/temp_rvalue_opt.sil +++ b/test/SILOptimizer/temp_rvalue_opt.sil @@ -324,11 +324,11 @@ bb1: %6 = alloc_stack $UnfoldSequence copy_addr %1 to [initialization] %6 : $*UnfoldSequence %8 = struct_element_addr %6 : $*UnfoldSequence, #UnfoldSequence._next - %9 = load %8 : $*@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for + %9 = load %8 : $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for %10 = alloc_stack $Optional %11 = struct_element_addr %1 : $*UnfoldSequence, #UnfoldSequence._state - strong_retain %9 : $@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for - %13 = apply %9(%10, %11) : $@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for + strong_retain %9 : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for + %13 = apply %9(%10, %11) : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for switch_enum_addr %10 : $*Optional, case #Optional.some!enumelt.1: bb3, case #Optional.none!enumelt: bb2 bb2: diff --git a/test/SILOptimizer/temp_rvalue_opt_ossa.sil b/test/SILOptimizer/temp_rvalue_opt_ossa.sil index 5c15490bf2600..6c3342edb3c59 100644 --- a/test/SILOptimizer/temp_rvalue_opt_ossa.sil +++ b/test/SILOptimizer/temp_rvalue_opt_ossa.sil @@ -328,11 +328,11 @@ bb1: %6 = alloc_stack $UnfoldSequence copy_addr %1 to [initialization] %6 : $*UnfoldSequence %8 = struct_element_addr %6 : $*UnfoldSequence, #UnfoldSequence._next - %9 = load [copy] %8 : $*@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for + %9 = load [copy] %8 : $*@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for %10 = alloc_stack $Optional %11 = struct_element_addr %1 : $*UnfoldSequence, #UnfoldSequence._state - %13 = apply %9(%10, %11) : $@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for - destroy_value %9 : $@callee_guaranteed <τ_0_0, τ_0_1> in (@inout τ_0_0) -> @out Optional<τ_0_1> for + %13 = apply %9(%10, %11) : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for + destroy_value %9 : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@inout τ_0_0) -> @out Optional<τ_0_1> for switch_enum_addr %10 : $*Optional, case #Optional.some!enumelt.1: bb3, case #Optional.none!enumelt: bb2 bb2: diff --git a/test/Sema/fixed_ambiguities/rdar35623181.swift b/test/Sema/fixed_ambiguities/rdar35623181.swift index eee6a869205f2..7470b0a7477df 100644 --- a/test/Sema/fixed_ambiguities/rdar35623181.swift +++ b/test/Sema/fixed_ambiguities/rdar35623181.swift @@ -2,7 +2,7 @@ extension Sequence where Element == String { func record() -> String { - // CHECK: function_ref @$ss20LazySequenceProtocolPsE3mapys0a3MapB0Vy8ElementsQzqd__Gqd__7ElementQzclF : $@convention(method) <τ_0_0 where τ_0_0 : LazySequenceProtocol><τ_1_0> (@guaranteed @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0.Element, τ_1_0>, @in_guaranteed τ_0_0) -> @out LazyMapSequence<τ_0_0.Elements, τ_1_0 + // CHECK: function_ref @$ss20LazySequenceProtocolPsE3mapys0a3MapB0Vy8ElementsQzqd__Gqd__7ElementQzclF : $@convention(method) <τ_0_0 where τ_0_0 : LazySequenceProtocol><τ_1_0> (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0.Element, τ_1_0>, @in_guaranteed τ_0_0) -> @out LazyMapSequence<τ_0_0.Elements, τ_1_0 return lazy.map({ $0 }).joined(separator: ",") } } diff --git a/test/stdlib/unmanaged_rc.swift b/test/stdlib/unmanaged_rc.swift index 9736b81ad8038..7f2616d5367b3 100644 --- a/test/stdlib/unmanaged_rc.swift +++ b/test/stdlib/unmanaged_rc.swift @@ -14,12 +14,12 @@ public func myPrint(_ k: Klass) { print(k) } // Check the codegen of _withUnsafeGuaranteedRef // -// CHECK-LABEL: sil public_external [transparent] [serialized] @$ss9UnmanagedV24_withUnsafeGuaranteedRefyqd__qd__xKXEKlF : $@convention(method) (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , Unmanaged) -> (@out Result, @error Error) { -// CHECK: bb0([[RESULT:%.*]] : $*Result, [[FUNC:%.*]] : $@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , [[UNMANAGED:%.*]] : $Unmanaged): +// CHECK-LABEL: sil public_external [transparent] [serialized] @$ss9UnmanagedV24_withUnsafeGuaranteedRefyqd__qd__xKXEKlF : $@convention(method) (@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , Unmanaged) -> (@out Result, @error Error) { +// CHECK: bb0([[RESULT:%.*]] : $*Result, [[FUNC:%.*]] : $@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , [[UNMANAGED:%.*]] : $Unmanaged): // CHECK: [[UNMANAGED_REF:%.*]] = struct_extract [[UNMANAGED]] // CHECK: [[REF:%.*]] = unmanaged_to_ref [[UNMANAGED_REF]] // CHECK: [[REF_MARK_DEP:%.*]] = mark_dependence [[REF]] -// CHECK: try_apply {{%.*}}([[RESULT]], [[REF_MARK_DEP]]) : $@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , normal bb2, error bb1 +// CHECK: try_apply {{%.*}}([[RESULT]], [[REF_MARK_DEP]]) : $@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> (@guaranteed τ_0_0) -> (@out τ_0_1, @error Error) for , normal bb2, error bb1 // CHECK-NOT: destroy_value // CHECK: } // end sil function '$ss9UnmanagedV24_withUnsafeGuaranteedRefyqd__qd__xKXEKlF'