diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index c6feb550e2e42..b7d8e8dcc6d69 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -37,6 +37,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallBitVector.h" @@ -347,10 +348,11 @@ class alignas(1 << TypeAlignInBits) TypeBase { Flags : NumFlagBits ); - SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+16, + SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+1+16, /// Extra information which affects how the function is called, like /// regparm and the calling convention. ExtInfoBits : NumAFTExtInfoBits, + HasExtInfo : 1, HasClangTypeInfo : 1, : NumPadBits, NumParams : 16 @@ -2919,20 +2921,28 @@ class AnyFunctionType : public TypeBase { /// /// Subclasses are responsible for storing and retrieving the /// ClangTypeInfo value if one is present. - AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext, - Type Output, RecursiveTypeProperties properties, - unsigned NumParams, ExtInfo Info) - : TypeBase(Kind, CanTypeContext, properties), Output(Output) { - Bits.AnyFunctionType.ExtInfoBits = Info.getBits(); - Bits.AnyFunctionType.HasClangTypeInfo = !Info.getClangTypeInfo().empty(); + AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext, Type Output, + RecursiveTypeProperties properties, unsigned NumParams, + Optional Info) + : TypeBase(Kind, CanTypeContext, properties), Output(Output) { + if (Info.hasValue()) { + Bits.AnyFunctionType.HasExtInfo = true; + Bits.AnyFunctionType.ExtInfoBits = Info.getValue().getBits(); + Bits.AnyFunctionType.HasClangTypeInfo = + !Info.getValue().getClangTypeInfo().empty(); + // The use of both assert() and static_assert() is intentional. + assert(Bits.AnyFunctionType.ExtInfoBits == Info.getValue().getBits() && + "Bits were dropped!"); + static_assert( + ASTExtInfoBuilder::NumMaskBits == NumAFTExtInfoBits, + "ExtInfo and AnyFunctionTypeBitfields must agree on bit size"); + } else { + Bits.AnyFunctionType.HasExtInfo = false; + Bits.AnyFunctionType.HasClangTypeInfo = false; + Bits.AnyFunctionType.ExtInfoBits = 0; + } Bits.AnyFunctionType.NumParams = NumParams; assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!"); - // The use of both assert() and static_assert() is intentional. - assert(Bits.AnyFunctionType.ExtInfoBits == Info.getBits() && - "Bits were dropped!"); - static_assert( - ASTExtInfoBuilder::NumMaskBits == NumAFTExtInfoBits, - "ExtInfo and AnyFunctionTypeBitfields must agree on bit size"); } public: @@ -2993,7 +3003,10 @@ class AnyFunctionType : public TypeBase { /// outer function type's mangling doesn't need to duplicate that information. bool hasNonDerivableClangType(); + bool hasExtInfo() const { return Bits.AnyFunctionType.HasExtInfo; } + ExtInfo getExtInfo() const { + assert(hasExtInfo()); return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, getClangTypeInfo()); } @@ -3002,6 +3015,7 @@ class AnyFunctionType : public TypeBase { /// The parameter useClangFunctionType is present only for staging purposes. /// In the future, we will always use the canonical clang function type. ExtInfo getCanonicalExtInfo(bool useClangFunctionType) const { + assert(hasExtInfo()); return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, useClangFunctionType ? getCanonicalClangTypeInfo() : ClangTypeInfo()); @@ -3193,7 +3207,7 @@ BEGIN_CAN_TYPE_WRAPPER(AnyFunctionType, Type) static CanAnyFunctionType get(CanGenericSignature signature, CanParamArrayRef params, CanType result, - ExtInfo info = ExtInfo()); + Optional info = None); CanGenericSignature getOptGenericSignature() const; @@ -3234,7 +3248,7 @@ class FunctionType final public: /// 'Constructor' Factory Function static FunctionType *get(ArrayRef params, Type result, - ExtInfo info = ExtInfo()); + Optional info = None); // Retrieve the input parameters of this function type. ArrayRef getParams() const { @@ -3251,12 +3265,15 @@ class FunctionType final } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getParams(), getResult(), getExtInfo()); + Optional info = None; + if (hasExtInfo()) + info = getExtInfo(); + Profile(ID, getParams(), getResult(), info); } static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef params, Type result, - ExtInfo info); + Optional info); // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { @@ -3264,12 +3281,12 @@ class FunctionType final } private: - FunctionType(ArrayRef params, Type result, ExtInfo info, + FunctionType(ArrayRef params, Type result, Optional info, const ASTContext *ctx, RecursiveTypeProperties properties); }; BEGIN_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType) static CanFunctionType get(CanParamArrayRef params, CanType result, - ExtInfo info = ExtInfo()) { + Optional info = None) { auto fnType = FunctionType::get(params.getOriginalArray(), result, info); return cast(fnType->getCanonicalType()); } @@ -3334,7 +3351,7 @@ class GenericFunctionType final : public AnyFunctionType, GenericFunctionType(GenericSignature sig, ArrayRef params, Type result, - ExtInfo info, + Optional info, const ASTContext *ctx, RecursiveTypeProperties properties); @@ -3343,7 +3360,7 @@ class GenericFunctionType final : public AnyFunctionType, static GenericFunctionType *get(GenericSignature sig, ArrayRef params, Type result, - ExtInfo info = ExtInfo()); + Optional info = None); // Retrieve the input parameters of this function type. ArrayRef getParams() const { @@ -3367,14 +3384,16 @@ class GenericFunctionType final : public AnyFunctionType, FunctionType *substGenericArgs(llvm::function_ref substFn) const; void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getGenericSignature(), getParams(), getResult(), - getExtInfo()); + Optional info = None; + if (hasExtInfo()) + info = getExtInfo(); + Profile(ID, getGenericSignature(), getParams(), getResult(), info); } static void Profile(llvm::FoldingSetNodeID &ID, GenericSignature sig, ArrayRef params, Type result, - ExtInfo info); + Optional info); // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { @@ -3387,11 +3406,11 @@ BEGIN_CAN_TYPE_WRAPPER(GenericFunctionType, AnyFunctionType) static CanGenericFunctionType get(CanGenericSignature sig, CanParamArrayRef params, CanType result, - ExtInfo info = ExtInfo()) { + Optional info = None) { // Knowing that the argument types are independently canonical is // not sufficient to guarantee that the function type will be canonical. - auto fnType = GenericFunctionType::get(sig, params.getOriginalArray(), - result, info); + auto fnType = + GenericFunctionType::get(sig, params.getOriginalArray(), result, info); return cast(fnType->getCanonicalType()); } @@ -3413,7 +3432,7 @@ END_CAN_TYPE_WRAPPER(GenericFunctionType, AnyFunctionType) inline CanAnyFunctionType CanAnyFunctionType::get(CanGenericSignature signature, CanParamArrayRef params, - CanType result, ExtInfo extInfo) { + CanType result, Optional extInfo) { if (signature) { return CanGenericFunctionType::get(signature, params, result, extInfo); } else { diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c67a149a5ab81..da09ed9d436e5 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3245,18 +3245,19 @@ static void profileParams(llvm::FoldingSetNodeID &ID, } void FunctionType::Profile(llvm::FoldingSetNodeID &ID, - ArrayRef params, - Type result, - ExtInfo info) { + ArrayRef params, Type result, + Optional info) { profileParams(ID, params); ID.AddPointer(result.getPointer()); - auto infoKey = info.getFuncAttrKey(); - ID.AddInteger(infoKey.first); - ID.AddPointer(infoKey.second); + if (info.hasValue()) { + auto infoKey = info.getValue().getFuncAttrKey(); + ID.AddInteger(infoKey.first); + ID.AddPointer(infoKey.second); + } } FunctionType *FunctionType::get(ArrayRef params, - Type result, ExtInfo info) { + Type result, Optional info) { auto properties = getFunctionRecursiveProperties(params, result); auto arena = getArena(properties); @@ -3272,10 +3273,15 @@ FunctionType *FunctionType::get(ArrayRef params, return funcTy; } - auto clangTypeInfo = info.getClangTypeInfo(); + ClangTypeInfo clangTypeInfo; + if (info.hasValue()) + clangTypeInfo = info.getValue().getClangTypeInfo(); + + bool hasClangInfo = + info.hasValue() && !info.getValue().getClangTypeInfo().empty(); size_t allocSize = totalSizeToAlloc( - params.size(), clangTypeInfo.empty() ? 0 : 1); + params.size(), hasClangInfo ? 1 : 0); void *mem = ctx.Allocate(allocSize, alignof(FunctionType), arena); bool isCanonical = isFunctionTypeCanonical(params, result); @@ -3294,36 +3300,38 @@ FunctionType *FunctionType::get(ArrayRef params, } // If the input and result types are canonical, then so is the result. -FunctionType::FunctionType(ArrayRef params, - Type output, ExtInfo info, - const ASTContext *ctx, +FunctionType::FunctionType(ArrayRef params, Type output, + Optional info, const ASTContext *ctx, RecursiveTypeProperties properties) - : AnyFunctionType(TypeKind::Function, ctx, - output, properties, params.size(), info) { + : AnyFunctionType(TypeKind::Function, ctx, output, properties, + params.size(), info) { std::uninitialized_copy(params.begin(), params.end(), getTrailingObjects()); - auto clangTypeInfo = info.getClangTypeInfo(); - if (!clangTypeInfo.empty()) - *getTrailingObjects() = clangTypeInfo; + if (info.hasValue()) { + auto clangTypeInfo = info.getValue().getClangTypeInfo(); + if (!clangTypeInfo.empty()) + *getTrailingObjects() = clangTypeInfo; + } } void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID, GenericSignature sig, ArrayRef params, - Type result, - ExtInfo info) { + Type result, Optional info) { ID.AddPointer(sig.getPointer()); profileParams(ID, params); ID.AddPointer(result.getPointer()); - auto infoKey = info.getFuncAttrKey(); - ID.AddInteger(infoKey.first); - ID.AddPointer(infoKey.second); + if (info.hasValue()) { + auto infoKey = info.getValue().getFuncAttrKey(); + ID.AddInteger(infoKey.first); + ID.AddPointer(infoKey.second); + } } GenericFunctionType *GenericFunctionType::get(GenericSignature sig, ArrayRef params, Type result, - ExtInfo info) { + Optional info) { assert(sig && "no generic signature for generic function type?!"); assert(!result->hasTypeVariable()); assert(!result->hasPlaceholder()); @@ -3346,7 +3354,7 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature sig, // point. bool isCanonical = isGenericFunctionTypeCanonical(sig, params, result); - assert(info.getClangTypeInfo().empty() && + assert((!info.hasValue() || info.getValue().getClangTypeInfo().empty()) && "Generic functions do not have Clang types at the moment."); if (auto funcTy @@ -3370,7 +3378,7 @@ GenericFunctionType::GenericFunctionType( GenericSignature sig, ArrayRef params, Type result, - ExtInfo info, + Optional info, const ASTContext *ctx, RecursiveTypeProperties properties) : AnyFunctionType(TypeKind::GenericFunction, ctx, result, diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 12e9658b7842d..306c5f13d0243 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -2846,9 +2846,12 @@ CanType ASTMangler::getDeclTypeForMangling( auto &C = decl->getASTContext(); if (decl->isInvalid()) { - if (isa(decl)) + if (isa(decl)) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; return CanFunctionType::get({AnyFunctionType::Param(C.TheErrorType)}, - C.TheErrorType); + C.TheErrorType, info); + } return C.TheErrorType; } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 62f88fc50afa5..4a9e254d23830 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4474,6 +4474,10 @@ class TypePrinter : public TypeVisitor { } void printFunctionExtInfo(AnyFunctionType *fnType) { + if (!fnType->hasExtInfo()) { + Printer << "@_NO_EXTINFO "; + return; + } auto &ctx = fnType->getASTContext(); auto info = fnType->getExtInfo(); if (Options.SkipAttributes) @@ -4693,13 +4697,15 @@ class TypePrinter : public TypeVisitor { // If we're stripping argument labels from types, do it when printing. visitAnyFunctionTypeParams(T->getParams(), /*printLabels*/false); - if (T->isAsync()) { - Printer << " "; - Printer.printKeyword("async", Options); - } + if (T->hasExtInfo()) { + if (T->isAsync()) { + Printer << " "; + Printer.printKeyword("async", Options); + } - if (T->isThrowing()) - Printer << " " << tok::kw_throws; + if (T->isThrowing()) + Printer << " " << tok::kw_throws; + } Printer << " -> "; @@ -4738,13 +4744,15 @@ class TypePrinter : public TypeVisitor { visitAnyFunctionTypeParams(T->getParams(), /*printLabels*/true); - if (T->isAsync()) { - Printer << " "; - Printer.printKeyword("async", Options); - } + if (T->hasExtInfo()) { + if (T->isAsync()) { + Printer << " "; + Printer.printKeyword("async", Options); + } - if (T->isThrowing()) - Printer << " " << tok::kw_throws; + if (T->isThrowing()) + Printer << " " << tok::kw_throws; + } Printer << " -> "; Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType); diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 6861075f30c54..9c8d6e4c8175a 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -1207,9 +1207,7 @@ static ValueDecl *getAutoDiffApplyDerivativeFunction( SmallVector params; for (auto ¶mGen : fnParamGens) params.push_back(FunctionType::Param(paramGen.build(builder))); - auto innerFunction = - FunctionType::get(params, fnResultGen.build(builder)); - return innerFunction->withExtInfo(extInfo); + return FunctionType::get(params, fnResultGen.build(builder), extInfo); }}; // Eagerly build the type of the first arg, then use that to compute the type // of the result. @@ -1274,8 +1272,10 @@ static ValueDecl *getAutoDiffApplyTransposeFunction( SmallVector params; for (auto ¶mGen : linearFnParamGens) params.push_back(FunctionType::Param(paramGen.build(builder))); - auto innerFunction = FunctionType::get(params, - linearFnResultGen.build(builder)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + auto innerFunction = + FunctionType::get(params, linearFnResultGen.build(builder), info); return innerFunction->withExtInfo(extInfo); } }; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index f6cfb2141362f..491fdaff39930 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -7799,11 +7799,16 @@ Type ConstructorDecl::getInitializerInterfaceType() { // Constructors have an initializer type that takes an instance // instead of a metatype. auto initSelfParam = computeSelfParam(this, /*isInitializingCtor=*/true); + + // FIXME: Verify ExtInfo state is correct, not working by accident. Type initFuncTy; - if (auto sig = getGenericSignature()) - initFuncTy = GenericFunctionType::get(sig, {initSelfParam}, funcTy); - else - initFuncTy = FunctionType::get({initSelfParam}, funcTy); + if (auto sig = getGenericSignature()) { + GenericFunctionType::ExtInfo info; + initFuncTy = GenericFunctionType::get(sig, {initSelfParam}, funcTy, info); + } else { + FunctionType::ExtInfo info; + initFuncTy = FunctionType::get({initSelfParam}, funcTy, info); + } InitializerInterfaceType = initFuncTy; return InitializerInterfaceType; diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 71ebc471f5ff2..4c5911276b006 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -442,9 +442,13 @@ Type TypeBase::addCurriedSelfType(const DeclContext *dc) { auto selfTy = dc->getSelfInterfaceType(); auto selfParam = AnyFunctionType::Param(selfTy); - if (sig) - return GenericFunctionType::get(sig, {selfParam}, type); - return FunctionType::get({selfParam}, type); + // FIXME: Verify ExtInfo state is correct, not working by accident. + if (sig) { + GenericFunctionType::ExtInfo info; + return GenericFunctionType::get(sig, {selfParam}, type, info); + } + FunctionType::ExtInfo info; + return FunctionType::get({selfParam}, type, info); } void TypeBase::getTypeVariables( @@ -1264,7 +1268,9 @@ CanType TypeBase::computeCanonicalType() { getCanonicalParams(funcTy, genericSig, canParams); auto resultTy = funcTy->getResult()->getCanonicalType(genericSig); - auto extInfo = funcTy->getCanonicalExtInfo(useClangTypes(resultTy)); + Optional extInfo = None; + if (funcTy->hasExtInfo()) + extInfo = funcTy->getCanonicalExtInfo(useClangTypes(resultTy)); if (genericSig) { Result = GenericFunctionType::get(genericSig, canParams, resultTy, extInfo); @@ -4755,12 +4761,16 @@ case TypeKind::Id: if (isUnchanged) return *this; auto genericSig = genericFnType->getGenericSignature(); + if (!function->hasExtInfo()) + return GenericFunctionType::get(genericSig, substParams, resultTy); return GenericFunctionType::get(genericSig, substParams, resultTy, function->getExtInfo()); } if (isUnchanged) return *this; + if (!function->hasExtInfo()) + return FunctionType::get(substParams, resultTy); return FunctionType::get(substParams, resultTy, function->getExtInfo()); } @@ -5350,7 +5360,10 @@ AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType( } auto differentialResult = hasInoutDiffParameter ? Type(ctx.TheEmptyTupleType) : resultTanType; - linearMapType = FunctionType::get(differentialParams, differentialResult); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + linearMapType = + FunctionType::get(differentialParams, differentialResult, info); break; } case AutoDiffLinearMapKind::Pullback: { @@ -5399,7 +5412,9 @@ AnyFunctionType::getAutoDiffDerivativeFunctionLinearMapType( auto flags = ParameterTypeFlags().withInOut(hasInoutDiffParameter); auto pullbackParam = AnyFunctionType::Param(resultTanType, Identifier(), flags); - linearMapType = FunctionType::get({pullbackParam}, pullbackResult); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + linearMapType = FunctionType::get({pullbackParam}, pullbackResult, info); break; } } diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index b521ed49b0e5f..79b71d532feda 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -485,8 +485,10 @@ synthesizeEnumRawValueConstructorBody(AbstractFunctionDecl *afd, ConcreteDeclRef concreteDeclRef(reinterpretCast, subMap); auto reinterpretCastRef = new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true); - reinterpretCastRef->setType(FunctionType::get({FunctionType::Param(rawTy)}, - enumTy)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + reinterpretCastRef->setType( + FunctionType::get({FunctionType::Param(rawTy)}, enumTy, info)); auto reinterpreted = CallExpr::createImplicit(ctx, reinterpretCastRef, { paramRef }, { Identifier() }); @@ -564,8 +566,10 @@ synthesizeEnumRawValueGetterBody(AbstractFunctionDecl *afd, void *context) { auto reinterpretCastRef = new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true); - reinterpretCastRef->setType(FunctionType::get({FunctionType::Param(enumTy)}, - rawTy)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + reinterpretCastRef->setType( + FunctionType::get({FunctionType::Param(enumTy)}, rawTy, info)); auto reinterpreted = CallExpr::createImplicit(ctx, reinterpretCastRef, { selfRef }, { Identifier() }); @@ -924,10 +928,11 @@ synthesizeUnionFieldGetterBody(AbstractFunctionDecl *afd, void *context) { auto reinterpretCastRefExpr = new (ctx) DeclRefExpr(reinterpretCastRef, DeclNameLoc(), /*implicit*/ true); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; reinterpretCastRefExpr->setType( - FunctionType::get( - AnyFunctionType::Param(selfDecl->getInterfaceType()), - importedFieldDecl->getInterfaceType())); + FunctionType::get(AnyFunctionType::Param(selfDecl->getInterfaceType()), + importedFieldDecl->getInterfaceType(), info)); auto reinterpreted = CallExpr::createImplicit(ctx, reinterpretCastRefExpr, { selfRef }, @@ -970,12 +975,12 @@ synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) { ArrayRef())); auto addressofFnRefExpr = new (ctx) DeclRefExpr(addressofFnRef, DeclNameLoc(), /*implicit*/ true); - addressofFnRefExpr->setType( - FunctionType::get( - AnyFunctionType::Param(inoutSelfDecl->getInterfaceType(), - Identifier(), + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo addressOfInfo; + addressofFnRefExpr->setType(FunctionType::get( + AnyFunctionType::Param(inoutSelfDecl->getInterfaceType(), Identifier(), ParameterTypeFlags().withInOut(true)), - ctx.TheRawPointerType)); + ctx.TheRawPointerType, addressOfInfo)); auto selfPointer = CallExpr::createImplicit(ctx, addressofFnRefExpr, { inoutSelf }, { Identifier() }); @@ -990,10 +995,12 @@ synthesizeUnionFieldSetterBody(AbstractFunctionDecl *afd, void *context) { ArrayRef())); auto initializeFnRefExpr = new (ctx) DeclRefExpr(initializeFnRef, DeclNameLoc(), /*implicit*/ true); - initializeFnRefExpr->setType( - FunctionType::get({AnyFunctionType::Param(newValueDecl->getInterfaceType()), - AnyFunctionType::Param(ctx.TheRawPointerType)}, - TupleType::getEmpty(ctx))); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo initializeInfo; + initializeFnRefExpr->setType(FunctionType::get( + {AnyFunctionType::Param(newValueDecl->getInterfaceType()), + AnyFunctionType::Param(ctx.TheRawPointerType)}, + TupleType::getEmpty(ctx), initializeInfo)); auto initialize = CallExpr::createImplicit(ctx, initializeFnRefExpr, { newValueRef, selfPointer }, { Identifier(), Identifier() }); @@ -1261,7 +1268,9 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd, ConcreteDeclRef concreteDeclRef(zeroInitializerFunc, subMap); auto zeroInitializerRef = new (ctx) DeclRefExpr(concreteDeclRef, DeclNameLoc(), /*implicit*/ true); - zeroInitializerRef->setType(FunctionType::get({}, selfType)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + zeroInitializerRef->setType(FunctionType::get({}, selfType, info)); auto call = CallExpr::createImplicit(ctx, zeroInitializerRef, {}, {}); call->setType(selfType); diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 0a894ce5f807d..d23383110fa8d 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -660,7 +660,9 @@ namespace { if (!resultTy) return Type(); - return FunctionType::get({}, resultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + return FunctionType::get({}, resultTy, info); } ImportResult VisitParenType(const clang::ParenType *type) { diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp index 8b872e03b95c5..5577b2f740b53 100644 --- a/lib/IDE/ExprContextAnalysis.cpp +++ b/lib/IDE/ExprContextAnalysis.cpp @@ -569,8 +569,10 @@ static void collectPossibleCalleesByQualifiedLookup( Type kpValueTy = kpTy->castTo()->getGenericArgs()[1]; kpTy = BoundGenericType::get(kpDecl, Type(), {baseTy, kpValueTy}); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; Type fnTy = FunctionType::get( - {AnyFunctionType::Param(kpTy, Ctx.Id_keyPath)}, kpValueTy); + {AnyFunctionType::Param(kpTy, Ctx.Id_keyPath)}, kpValueTy, info); candidates.emplace_back(fnTy->castTo(), nullptr); } } diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 8a73f24c7cdc4..d9b38f488c17f 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -2950,10 +2950,14 @@ class EmitTypeMetadataRefForLayout // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return C.TheRawPointerType; - case SILFunctionType::Representation::Thick: + case SILFunctionType::Representation::Thick: { // All function types look like () -> (). // FIXME: It'd be nice not to have to call through the runtime here. - return CanFunctionType::get({}, C.TheEmptyTupleType); + // + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; + return CanFunctionType::get({}, C.TheEmptyTupleType, info); + } case SILFunctionType::Representation::Block: // All block types look like AnyObject. return C.getAnyObjectType(); @@ -3149,10 +3153,13 @@ namespace { // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return emitFromValueWitnessTable(C.TheRawPointerType); - case SILFunctionType::Representation::Thick: + case SILFunctionType::Representation::Thick: { // All function types look like () -> (). + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; return emitFromValueWitnessTable( - CanFunctionType::get({}, C.TheEmptyTupleType)); + CanFunctionType::get({}, C.TheEmptyTupleType, info)); + } case SILFunctionType::Representation::Block: // All block types look like AnyObject. return emitFromValueWitnessTable(C.getAnyObjectType()); diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 916aa7a22eab8..5914bb96170ab 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -2364,7 +2364,9 @@ getCanonicalSignatureOrNull(GenericSignature sig) { /// Get the type of a global variable accessor function, () -> RawPointer. static CanAnyFunctionType getGlobalAccessorType(CanType varType) { ASTContext &C = varType->getASTContext(); - return CanFunctionType::get({}, C.TheRawPointerType); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; + return CanFunctionType::get({}, C.TheRawPointerType, info); } /// Removes @noescape from the given type if it's a function type. Otherwise, @@ -2406,8 +2408,10 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType( } } - return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), - {}, canResultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanAnyFunctionType::ExtInfo info; + return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), {}, + canResultTy, info); } /// Get the type of a stored property initializer, () -> T. @@ -2432,8 +2436,10 @@ static CanAnyFunctionType getStoredPropertyInitializerInterfaceType( auto sig = DC->getGenericSignatureOfContext(); - return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), - {}, resultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanAnyFunctionType::ExtInfo info; + return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), {}, resultTy, + info); } /// Get the type of a property wrapper backing initializer, @@ -2453,8 +2459,10 @@ static CanAnyFunctionType getPropertyWrapperBackingInitializerInterfaceType( AnyFunctionType::Param param( inputType, Identifier(), ParameterTypeFlags().withValueOwnership(ValueOwnership::Owned)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanAnyFunctionType::ExtInfo info; return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), {param}, - resultType); + resultType, info); } static CanAnyFunctionType getPropertyWrapperInitFromProjectedValueInterfaceType(TypeConverter &TC, @@ -2474,8 +2482,10 @@ static CanAnyFunctionType getPropertyWrapperInitFromProjectedValueInterfaceType( AnyFunctionType::Param param( inputType, Identifier(), ParameterTypeFlags().withValueOwnership(ValueOwnership::Owned)); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanAnyFunctionType::ExtInfo info; return CanAnyFunctionType::get(getCanonicalSignatureOrNull(sig), {param}, - resultType); + resultType, info); } /// Get the type of a destructor function. @@ -2502,7 +2512,9 @@ static CanAnyFunctionType getDestructorInterfaceType(DestructorDecl *dd, CanType resultTy = (isDeallocating ? TupleType::getEmpty(C) : C.TheNativeObjectType); - CanType methodTy = CanFunctionType::get({}, resultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; + CanType methodTy = CanFunctionType::get({}, resultTy, info); auto sig = dd->getGenericSignatureOfContext(); FunctionType::Param args[] = {FunctionType::Param(classType)}; diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index c619ddf5f2946..f100615e8f3ac 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -1602,9 +1602,10 @@ class SILGenApply : public Lowering::ExprVisitor { ->getCanonicalType() .getOptionalObjectType()); auto substSelfType = dynamicMemberRef->getBase()->getType()->getCanonicalType(); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; substFormalType = CanFunctionType::get( - {AnyFunctionType::Param(substSelfType)}, - substFormalType); + {AnyFunctionType::Param(substSelfType)}, substFormalType, info); setCallee(Callee::forDynamic(SGF, member, memberRef.getSubstitutions(), @@ -5861,7 +5862,9 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e, FuncDecl *memberFunc; if (auto *VD = dyn_cast(e->getMember().getDecl())) { memberFunc = VD->getOpaqueAccessor(AccessorKind::Get); - memberMethodTy = FunctionType::get({}, memberMethodTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; + memberMethodTy = FunctionType::get({}, memberMethodTy, info); } else memberFunc = cast(e->getMember().getDecl()); auto member = SILDeclRef(memberFunc, SILDeclRef::Kind::Func) @@ -5880,7 +5883,9 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e, // For a computed variable, we want the getter. if (isa(e->getMember().getDecl())) { - methodTy = CanFunctionType::get({}, valueTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; + methodTy = CanFunctionType::get({}, valueTy, info); } else { methodTy = cast(valueTy); } @@ -5891,9 +5896,11 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e, auto foreignMethodTy = getPartialApplyOfDynamicMethodFormalType(SGM, member, e->getMember()); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo info; FunctionType::Param arg(operand->getType().getASTType()); - auto memberFnTy = CanFunctionType::get({arg}, - memberMethodTy->getCanonicalType()); + auto memberFnTy = + CanFunctionType::get({arg}, memberMethodTy->getCanonicalType(), info); auto loweredMethodTy = getDynamicMethodLoweredType(SGM.M, member, memberFnTy); @@ -5984,13 +5991,18 @@ RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e, auto valueTy = e->getType()->getCanonicalType().getOptionalObjectType(); // Objective-C subscripts only ever have a single parameter. + // + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo methodInfo; FunctionType::Param indexArg(e->getIndex()->getType()->getCanonicalType()); - auto methodTy = CanFunctionType::get({indexArg}, valueTy); + auto methodTy = CanFunctionType::get({indexArg}, valueTy, methodInfo); auto foreignMethodTy = getPartialApplyOfDynamicMethodFormalType(SGM, member, e->getMember()); + // FIXME: Verify ExtInfo state is correct, not working by accident. + CanFunctionType::ExtInfo functionInfo; FunctionType::Param baseArg(base->getType().getASTType()); - auto functionTy = CanFunctionType::get({baseArg}, methodTy); + auto functionTy = CanFunctionType::get({baseArg}, methodTy, functionInfo); auto loweredMethodTy = getDynamicMethodLoweredType(SGM.M, member, functionTy); SILValue memberArg = diff --git a/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp b/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp index 38bdd1cb47ba8..e9d53787f4fd3 100644 --- a/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp +++ b/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp @@ -230,13 +230,19 @@ VarDecl *LinearMapInfo::addLinearMapDecl(ApplyInst *ai, SILType linearMapType) { params.push_back( AnyFunctionType::Param(param.getInterfaceType(), Identifier(), flags)); } + AnyFunctionType *astFnTy; - if (auto genSig = silFnTy->getSubstGenericSignature()) + if (auto genSig = silFnTy->getSubstGenericSignature()) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + GenericFunctionType::ExtInfo info; astFnTy = GenericFunctionType::get( - genSig, params, silFnTy->getAllResultsInterfaceType().getASTType()); - else + genSig, params, silFnTy->getAllResultsInterfaceType().getASTType(), + info); + } else { + FunctionType::ExtInfo info; astFnTy = FunctionType::get( - params, silFnTy->getAllResultsInterfaceType().getASTType()); + params, silFnTy->getAllResultsInterfaceType().getASTType(), info); + } auto *origBB = ai->getParent(); auto *linMapStruct = getLinearMapStruct(origBB); diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 8bd7b95cd7dab..4631c1b9b944e 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -1070,7 +1070,10 @@ namespace { args.push_back(paramRef); } - fnRef->setType(FunctionType::get(innerParamTypes, fnType->getResult())); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo fnInfo; + fnRef->setType( + FunctionType::get(innerParamTypes, fnType->getResult(), fnInfo)); cs.cacheType(fnRef); auto *fnCall = CallExpr::createImplicit(context, fnRef, args, argLabels); @@ -1079,7 +1082,11 @@ namespace { cs.cacheType(fnCall->getArg()); auto discriminator = AutoClosureExpr::InvalidDiscriminator; - auto *autoClosureType = FunctionType::get(outerParamTypes, fnType->getResult()); + + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo closureInfo; + auto *autoClosureType = + FunctionType::get(outerParamTypes, fnType->getResult(), closureInfo); auto *autoClosure = new (context) AutoClosureExpr(fnCall, autoClosureType, discriminator, cs.DC); autoClosure->setParameterList(outerParams); @@ -1179,7 +1186,10 @@ namespace { auto *closure = buildPropertyWrapperFnThunk(selfCall, calleeFnType, fnDecl, callee, appliedWrappers); - ref->setType(FunctionType::get(refTy->getParams(), selfCall->getType())); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + ref->setType( + FunctionType::get(refTy->getParams(), selfCall->getType(), info)); cs.cacheType(ref); // FIXME: There's more work to do. @@ -4916,8 +4926,11 @@ namespace { // The inner closure. // // let closure = "{ $0[keyPath: $kp$] }" + // + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo closureInfo; auto closureTy = - FunctionType::get({ FunctionType::Param(baseTy) }, leafTy); + FunctionType::get({FunctionType::Param(baseTy)}, leafTy, closureInfo); auto closure = new (ctx) AutoClosureExpr(/*set body later*/nullptr, leafTy, discriminator, cs.DC); @@ -4932,8 +4945,11 @@ namespace { // The outer closure. // // let outerClosure = "{ $kp$ in \(closure) }" - auto outerClosureTy = - FunctionType::get({ FunctionType::Param(keyPathTy) }, closureTy); + // + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo outerClosureInfo; + auto outerClosureTy = FunctionType::get({FunctionType::Param(keyPathTy)}, + closureTy, outerClosureInfo); auto outerClosure = new (ctx) AutoClosureExpr(/*set body later*/nullptr, closureTy, discriminator, cs.DC); @@ -6761,9 +6777,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, fromEI.intoBuilder() .withDifferentiabilityKind(toEI.getDifferentiabilityKind()) .build(); - fromFunc = FunctionType::get(toFunc->getParams(), fromFunc->getResult()) - ->withExtInfo(newEI) - ->castTo(); + fromFunc = FunctionType::get(toFunc->getParams(), fromFunc->getResult(), + newEI); switch (toEI.getDifferentiabilityKind()) { // TODO: Ban `Normal` and `Forward` cases. case DifferentiabilityKind::Normal: diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 158f0033094f4..a851058db60f6 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -2433,7 +2433,11 @@ namespace { Type outputType = CS.createTypeVariable( CS.getConstraintLocator(locator), TVO_CanBindToNoEscape); - Type functionType = FunctionType::get(params, outputType); + // Equal constraints require ExtInfo comparison. + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + Type functionType = FunctionType::get(params, outputType, info); + // TODO: Convert to FunctionInput/FunctionResult constraints. CS.addConstraint( ConstraintKind::Equal, functionType, memberType, locator.withPathElement(LocatorPathElt::PatternMatch(pattern))); diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index ce11781c4f0e9..7617bc6a85aac 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -1597,7 +1597,9 @@ ConstraintSystem::getTypeOfMemberReference( auto indices = subscript->getInterfaceType() ->castTo()->getParams(); - refType = FunctionType::get(indices, elementTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + refType = FunctionType::get(indices, elementTy, info); } else { refType = getUnopenedTypeOfReference(cast(value), baseTy, useDC, base, @@ -1618,10 +1620,13 @@ ConstraintSystem::getTypeOfMemberReference( // If the storage is generic, add a generic signature. FunctionType::Param selfParam(selfTy, Identifier(), selfFlags); + // FIXME: Verify ExtInfo state is correct, not working by accident. if (auto sig = innerDC->getGenericSignatureOfContext()) { - funcType = GenericFunctionType::get(sig, {selfParam}, refType); + GenericFunctionType::ExtInfo info; + funcType = GenericFunctionType::get(sig, {selfParam}, refType, info); } else { - funcType = FunctionType::get({selfParam}, refType); + FunctionType::ExtInfo info; + funcType = FunctionType::get({selfParam}, refType, info); } } @@ -1697,7 +1702,10 @@ ConstraintSystem::getTypeOfMemberReference( auto *functionType = fullFunctionType->getResult()->getAs(); functionType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind, functionType, locator); - openedType = FunctionType::get(fullFunctionType->getParams(), functionType); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + openedType = + FunctionType::get(fullFunctionType->getParams(), functionType, info); } // Compute the type of the reference. @@ -1864,7 +1872,9 @@ Type ConstraintSystem::getEffectiveOverloadType(const OverloadChoice &overload, auto indices = subscript->getInterfaceType() ->castTo()->getParams(); - type = FunctionType::get(indices, elementTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + type = FunctionType::get(indices, elementTy, info); } else if (auto var = dyn_cast(decl)) { type = var->getValueInterfaceType(); if (doesStorageProduceLValue(var, overload.getBaseType(), useDC)) @@ -1975,7 +1985,9 @@ static std::pair getTypeOfReferenceWithSpecialTypeCheckingSemantics( CS.addConstraint( ConstraintKind::DynamicTypeOf, output, input, CS.getConstraintLocator(locator, ConstraintLocator::DynamicType)); - auto refType = FunctionType::get({inputArg}, output); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + auto refType = FunctionType::get({inputArg}, output, info); return {refType, refType}; } case DeclTypeCheckingSemantics::WithoutActuallyEscaping: { @@ -2644,8 +2656,10 @@ void ConstraintSystem::bindOverloadType( ConstraintLocator::FunctionResult), TVO_CanBindToLValue | TVO_CanBindToNoEscape); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; auto adjustedFnTy = - FunctionType::get(fnType->getParams(), subscriptResultTy); + FunctionType::get(fnType->getParams(), subscriptResultTy, info); ConstraintLocatorBuilder kpLocBuilder(keyPathLoc); addConstraint( @@ -2802,10 +2816,14 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator, FunctionType::Param indices[] = { FunctionType::Param(keyPathIndexTy, getASTContext().Id_keyPath), }; - auto subscriptTy = FunctionType::get(indices, elementTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo subscriptInfo; + auto subscriptTy = FunctionType::get(indices, elementTy, subscriptInfo); FunctionType::Param baseParam(choice.getBaseType()); - auto fullTy = FunctionType::get({baseParam}, subscriptTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo fullInfo; + auto fullTy = FunctionType::get({baseParam}, subscriptTy, fullInfo); openedFullType = fullTy; refType = subscriptTy; diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index f9ad680aff956..f2b86d85450b3 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -3222,14 +3222,18 @@ AttributeChecker::visitImplementationOnlyAttr(ImplementationOnlyAttr *attr) { // into a monomorphic function type. // FIXME: does this actually make sense, though? auto derivedInterfaceFuncTy = derivedInterfaceTy->castTo(); - derivedInterfaceTy = - FunctionType::get(derivedInterfaceFuncTy->getParams(), - derivedInterfaceFuncTy->getResult()); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo derivedInterfaceInfo; + derivedInterfaceTy = FunctionType::get(derivedInterfaceFuncTy->getParams(), + derivedInterfaceFuncTy->getResult(), + derivedInterfaceInfo); auto overrideInterfaceFuncTy = overrideInterfaceTy->castTo(); - overrideInterfaceTy = - FunctionType::get(overrideInterfaceFuncTy->getParams(), - overrideInterfaceFuncTy->getResult()); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo overrideInterfaceInfo; + overrideInterfaceTy = FunctionType::get( + overrideInterfaceFuncTy->getParams(), + overrideInterfaceFuncTy->getResult(), overrideInterfaceInfo); } if (!derivedInterfaceTy->isEqual(overrideInterfaceTy)) { @@ -4062,9 +4066,14 @@ static bool checkFunctionSignature( static AnyFunctionType * makeFunctionType(ArrayRef parameters, Type resultType, GenericSignature genericSignature) { - if (genericSignature) - return GenericFunctionType::get(genericSignature, parameters, resultType); - return FunctionType::get(parameters, resultType); + // FIXME: Verify ExtInfo state is correct, not working by accident. + if (genericSignature) { + GenericFunctionType::ExtInfo info; + return GenericFunctionType::get(genericSignature, parameters, resultType, + info); + } + FunctionType::ExtInfo info; + return FunctionType::get(parameters, resultType, info); } /// Computes the original function type corresponding to the given derivative diff --git a/lib/Sema/TypeCheckCodeCompletion.cpp b/lib/Sema/TypeCheckCodeCompletion.cpp index aedca3b125587..2e6efe8464b8a 100644 --- a/lib/Sema/TypeCheckCodeCompletion.cpp +++ b/lib/Sema/TypeCheckCodeCompletion.cpp @@ -524,7 +524,10 @@ getTypeOfCompletionOperatorImpl(DeclContext *DC, Expr *expr, argTypes.emplace_back(solution.simplifyType(CS.getType(arg))); } - return FunctionType::get(argTypes, solution.simplifyType(CS.getType(expr))); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + return FunctionType::get(argTypes, solution.simplifyType(CS.getType(expr)), + info); } /// Return the type of operator function for specified LHS, or a null diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 8395686ba31c3..020aa61eb5cbe 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -2400,10 +2400,14 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const { if (hasSelf) { // Substitute in our own 'self' parameter. auto selfParam = computeSelfParam(AFD); - if (sig) - funcTy = GenericFunctionType::get(sig, {selfParam}, funcTy); - else - funcTy = FunctionType::get({selfParam}, funcTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + if (sig) { + GenericFunctionType::ExtInfo info; + funcTy = GenericFunctionType::get(sig, {selfParam}, funcTy, info); + } else { + FunctionType::ExtInfo info; + funcTy = FunctionType::get({selfParam}, funcTy, info); + } } return funcTy; @@ -2418,10 +2422,14 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const { SD->getIndices()->getParams(argTy); Type funcTy; - if (auto sig = SD->getGenericSignature()) - funcTy = GenericFunctionType::get(sig, argTy, elementTy); - else - funcTy = FunctionType::get(argTy, elementTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + if (auto sig = SD->getGenericSignature()) { + GenericFunctionType::ExtInfo info; + funcTy = GenericFunctionType::get(sig, argTy, elementTy, info); + } else { + FunctionType::ExtInfo info; + funcTy = FunctionType::get(argTy, elementTy, info); + } return funcTy; } @@ -2441,13 +2449,19 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const { SmallVector argTy; PL->getParams(argTy); - resultTy = FunctionType::get(argTy, resultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + resultTy = FunctionType::get(argTy, resultTy, info); } - if (auto genericSig = ED->getGenericSignature()) - resultTy = GenericFunctionType::get(genericSig, {selfTy}, resultTy); - else - resultTy = FunctionType::get({selfTy}, resultTy); + // FIXME: Verify ExtInfo state is correct, not working by accident. + if (auto genericSig = ED->getGenericSignature()) { + GenericFunctionType::ExtInfo info; + resultTy = GenericFunctionType::get(genericSig, {selfTy}, resultTy, info); + } else { + FunctionType::ExtInfo info; + resultTy = FunctionType::get({selfTy}, resultTy, info); + } return resultTy; } diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 5bc9eb0db8830..2e9455bcdf883 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -95,7 +95,10 @@ Type swift::getMemberTypeForComparison(const ValueDecl *member, // For subscripts, we don't have a 'Self' type, but turn it // into a monomorphic function type. auto funcTy = memberType->castTo(); - memberType = FunctionType::get(funcTy->getParams(), funcTy->getResult()); + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; + memberType = + FunctionType::get(funcTy->getParams(), funcTy->getResult(), info); } else { // For properties, strip off ownership. memberType = memberType->getReferenceStorageReferent(); diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index ac18a1e83e990..fdccb3e4d040a 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -744,22 +744,24 @@ swift::matchWitness( } } - // If the witness is 'async', the requirement must be. - if (witnessFnType->getExtInfo().isAsync() && - !reqFnType->getExtInfo().isAsync()) { - return RequirementMatch(witness, MatchKind::AsyncConflict); - } + if (witnessFnType->hasExtInfo()) { + // If the witness is 'async', the requirement must be. + if (witnessFnType->getExtInfo().isAsync() && + !reqFnType->getExtInfo().isAsync()) { + return RequirementMatch(witness, MatchKind::AsyncConflict); + } - // If witness is sync, the requirement cannot be @objc and 'async' - if (!witnessFnType->getExtInfo().isAsync() && - (req->isObjC() && reqFnType->getExtInfo().isAsync())) { - return RequirementMatch(witness, MatchKind::AsyncConflict); - } + // If witness is sync, the requirement cannot be @objc and 'async' + if (!witnessFnType->getExtInfo().isAsync() && + (req->isObjC() && reqFnType->getExtInfo().isAsync())) { + return RequirementMatch(witness, MatchKind::AsyncConflict); + } - // If the witness is 'throws', the requirement must be. - if (witnessFnType->getExtInfo().isThrowing() && - !reqFnType->getExtInfo().isThrowing()) { - return RequirementMatch(witness, MatchKind::ThrowsConflict); + // If the witness is 'throws', the requirement must be. + if (witnessFnType->getExtInfo().isThrowing() && + !reqFnType->getExtInfo().isThrowing()) { + return RequirementMatch(witness, MatchKind::ThrowsConflict); + } } } else { auto reqTypeIsIUO = req->isImplicitlyUnwrappedOptional(); diff --git a/unittests/AST/TypeMatchTests.cpp b/unittests/AST/TypeMatchTests.cpp index 71154e43a899a..ca6a9059b6da3 100644 --- a/unittests/AST/TypeMatchTests.cpp +++ b/unittests/AST/TypeMatchTests.cpp @@ -46,6 +46,8 @@ TEST(TypeMatch, IdenticalTypes) { } TEST(TypeMatch, UnrelatedTypes) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; TestContext C; auto check = [](Type base, Type derived) { @@ -56,11 +58,11 @@ TEST(TypeMatch, UnrelatedTypes) { EXPECT_FALSE(check(C.Ctx.TheEmptyTupleType, C.Ctx.TheRawPointerType)); EXPECT_FALSE(check(C.Ctx.TheRawPointerType, C.Ctx.TheEmptyTupleType)); - Type voidToVoidFn = FunctionType::get({}, C.Ctx.TheEmptyTupleType); + Type voidToVoidFn = FunctionType::get({}, C.Ctx.TheEmptyTupleType, info); EXPECT_FALSE(check(voidToVoidFn, C.Ctx.TheEmptyTupleType)); EXPECT_FALSE(check(C.Ctx.TheEmptyTupleType, voidToVoidFn)); - Type ptrToPtrFn = FunctionType::get({}, C.Ctx.TheRawPointerType); + Type ptrToPtrFn = FunctionType::get({}, C.Ctx.TheRawPointerType, info); EXPECT_FALSE(check(ptrToPtrFn, voidToVoidFn)); EXPECT_FALSE(check(voidToVoidFn, ptrToPtrFn)); @@ -72,7 +74,7 @@ TEST(TypeMatch, UnrelatedTypes) { EXPECT_FALSE(check(voidToVoidFn, structTy)); Type structToStructFn = FunctionType::get( - FunctionType::Param(structTy), structTy); + FunctionType::Param(structTy), structTy, info); EXPECT_FALSE(check(structToStructFn, structTy)); EXPECT_FALSE(check(structTy, structToStructFn)); EXPECT_FALSE(check(structToStructFn, voidToVoidFn)); @@ -85,13 +87,13 @@ TEST(TypeMatch, UnrelatedTypes) { Type anotherStructToAnotherStructFn = FunctionType::get( FunctionType::Param(anotherStructTy), - anotherStructTy); + anotherStructTy, info); EXPECT_FALSE(check(anotherStructToAnotherStructFn, structToStructFn)); EXPECT_FALSE(check(structToStructFn, anotherStructToAnotherStructFn)); Type S2ASFn = FunctionType::get( FunctionType::Param(structTy), - anotherStructTy); + anotherStructTy, info); EXPECT_FALSE(check(S2ASFn, structToStructFn)); EXPECT_FALSE(check(structToStructFn, S2ASFn)); EXPECT_FALSE(check(S2ASFn, anotherStructToAnotherStructFn)); @@ -99,6 +101,8 @@ TEST(TypeMatch, UnrelatedTypes) { } TEST(TypeMatch, Classes) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; TestContext C; auto check = [](Type base, Type derived) { @@ -125,27 +129,29 @@ TEST(TypeMatch, Classes) { Type baseToVoid = FunctionType::get( FunctionType::Param(baseTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); Type subToVoid = FunctionType::get( FunctionType::Param(subTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); EXPECT_FALSE(check(baseToVoid, subToVoid)); EXPECT_TRUE(check(subToVoid, baseToVoid)); - Type voidToBase = FunctionType::get({}, baseTy); - Type voidToSub = FunctionType::get({}, subTy); + Type voidToBase = FunctionType::get({}, baseTy, info); + Type voidToSub = FunctionType::get({}, subTy, info); EXPECT_FALSE(check(voidToSub, voidToBase)); EXPECT_TRUE(check(voidToBase, voidToSub)); Type baseToBase = FunctionType::get( - FunctionType::Param(baseTy), baseTy); + FunctionType::Param(baseTy), baseTy, info); Type subToSub = FunctionType::get( - FunctionType::Param(subTy), subTy); + FunctionType::Param(subTy), subTy, info); EXPECT_FALSE(check(baseToBase, subToSub)); EXPECT_FALSE(check(subToSub, baseToBase)); } TEST(TypeMatch, Optionals) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; TestContext C{DeclareOptionalTypes}; auto check = [](Type base, Type derived) { @@ -162,29 +168,31 @@ TEST(TypeMatch, Optionals) { Type baseToVoid = FunctionType::get( FunctionType::Param(baseTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); Type optToVoid = FunctionType::get( FunctionType::Param(optTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); EXPECT_TRUE(check(baseToVoid, optToVoid)); EXPECT_FALSE(check(optToVoid, baseToVoid)); - Type voidToBase = FunctionType::get({}, baseTy); - Type voidToOpt = FunctionType::get({}, optTy); + Type voidToBase = FunctionType::get({}, baseTy, info); + Type voidToOpt = FunctionType::get({}, optTy, info); EXPECT_FALSE(check(voidToBase, voidToOpt)); EXPECT_TRUE(check(voidToOpt, voidToBase)); Type baseToBase = FunctionType::get( FunctionType::Param(baseTy), - baseTy); + baseTy, info); Type optToOpt = FunctionType::get( FunctionType::Param(optTy), - optTy); + optTy, info); EXPECT_FALSE(check(baseToBase, optToOpt)); EXPECT_FALSE(check(optToOpt, baseToBase)); } TEST(TypeMatch, OptionalMismatch) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; TestContext C{DeclareOptionalTypes}; auto check = [](Type base, Type derived) { @@ -207,10 +215,10 @@ TEST(TypeMatch, OptionalMismatch) { Type baseToVoid = FunctionType::get( FunctionType::Param(baseTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); Type optToVoid = FunctionType::get( FunctionType::Param(optTy), - C.Ctx.TheEmptyTupleType); + C.Ctx.TheEmptyTupleType, info); EXPECT_TRUE(check(baseToVoid, optToVoid)); EXPECT_TRUE(checkOpt(baseToVoid, optToVoid)); EXPECT_TRUE(checkOptOverride(baseToVoid, optToVoid)); @@ -218,8 +226,8 @@ TEST(TypeMatch, OptionalMismatch) { EXPECT_TRUE(checkOpt(optToVoid, baseToVoid)); EXPECT_TRUE(checkOptOverride(optToVoid, baseToVoid)); - Type voidToBase = FunctionType::get({}, baseTy); - Type voidToOpt = FunctionType::get({}, optTy); + Type voidToBase = FunctionType::get({}, baseTy, info); + Type voidToOpt = FunctionType::get({}, optTy, info); EXPECT_FALSE(check(voidToBase, voidToOpt)); EXPECT_TRUE(checkOpt(voidToBase, voidToOpt)); EXPECT_TRUE(checkOptOverride(voidToBase, voidToOpt)); @@ -229,10 +237,10 @@ TEST(TypeMatch, OptionalMismatch) { Type baseToBase = FunctionType::get( FunctionType::Param(baseTy), - baseTy); + baseTy, info); Type optToOpt = FunctionType::get( FunctionType::Param(optTy), - optTy); + optTy, info); EXPECT_FALSE(check(baseToBase, optToOpt)); EXPECT_TRUE(checkOpt(baseToBase, optToOpt)); EXPECT_TRUE(checkOptOverride(baseToBase, optToOpt)); @@ -348,6 +356,8 @@ TEST(TypeMatch, OptionalMismatchFunctions) { } TEST(TypeMatch, NoEscapeMismatchFunctions) { + // FIXME: Verify ExtInfo state is correct, not working by accident. + FunctionType::ExtInfo info; TestContext C{DeclareOptionalTypes}; // Note the reversed names here: parameters must be contravariant for the @@ -361,7 +371,7 @@ TEST(TypeMatch, NoEscapeMismatchFunctions) { TypeMatchFlags::IgnoreNonEscapingForOptionalFunctionParam); }; - Type voidToVoidFn = FunctionType::get({}, C.Ctx.TheEmptyTupleType); + Type voidToVoidFn = FunctionType::get({}, C.Ctx.TheEmptyTupleType, info); Type nonescapingVoidToVoidFn = FunctionType::get({}, C.Ctx.TheEmptyTupleType, FunctionType::ExtInfo().withNoEscape());