Skip to content

Commit c5fa0cf

Browse files
authored
Merge pull request #40271 from DougGregor/predates-concurrency-abi-c
2 parents dd93538 + 42c71c9 commit c5fa0cf

File tree

13 files changed

+149
-65
lines changed

13 files changed

+149
-65
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ class ASTMangler : public Mangler {
6767
/// If enabled, marker protocols can be encoded in the mangled name.
6868
bool AllowMarkerProtocols = true;
6969

70+
/// Whether the mangling predates concurrency, and therefore shouldn't
71+
/// include concurrency features such as global actors or @Sendable
72+
/// function types.
73+
bool PredatesConcurrency = false;
74+
7075
public:
7176
using SymbolicReferent = llvm::PointerUnion<const NominalTypeDecl *,
7277
const OpaqueTypeDecl *>;

include/swift/AST/Types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,15 @@ class alignas(1 << TypeAlignInBits) TypeBase
11891189
/// types.
11901190
Type lookThroughAllOptionalTypes(SmallVectorImpl<Type> &optionals);
11911191

1192+
/// Remove concurrency-related types and constraints from the given
1193+
/// type
1194+
///
1195+
/// \param recurse Whether to recurse into function types.
1196+
///
1197+
/// \param dropGlobalActor Whether to drop a global actor from a function
1198+
/// type.
1199+
Type stripConcurrency(bool recurse, bool dropGlobalActor);
1200+
11921201
/// Whether this is the AnyObject type.
11931202
bool isAnyObject();
11941203

lib/AST/ASTDumper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3803,6 +3803,10 @@ namespace {
38033803
printFlag(T->isAsync(), "async");
38043804
printFlag(T->isThrowing(), "throws");
38053805

3806+
if (Type globalActor = T->getGlobalActor()) {
3807+
printField("global_actor", globalActor.getString());
3808+
}
3809+
38063810
OS << "\n";
38073811
Indent += 2;
38083812
// [TODO: Improve-Clang-type-printing]
@@ -3815,10 +3819,6 @@ namespace {
38153819
printField("clang_type", os.str());
38163820
}
38173821

3818-
if (Type globalActor = T->getGlobalActor()) {
3819-
printField("global_actor", globalActor.getString());
3820-
}
3821-
38223822
printAnyFunctionParams(T->getParams(), "input");
38233823
Indent -=2;
38243824
printRec("output", T->getResult());

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,6 +2969,13 @@ CanType ASTMangler::getDeclTypeForMangling(
29692969

29702970
Type ty = decl->getInterfaceType()->getReferenceStorageReferent();
29712971

2972+
// If this declaration predates concurrency, adjust its type to not
2973+
// contain type features that were not available pre-concurrency. This
2974+
// cannot alter the ABI in any way.
2975+
if (decl->predatesConcurrency()) {
2976+
ty = ty->stripConcurrency(/*recurse=*/true, /*dropGlobalActor=*/true);
2977+
}
2978+
29722979
auto canTy = ty->getCanonicalType();
29732980

29742981
if (auto gft = dyn_cast<GenericFunctionType>(canTy)) {

lib/AST/Decl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "swift/AST/TypeLoc.h"
4747
#include "swift/AST/SwiftNameTranslation.h"
4848
#include "swift/Basic/Defer.h"
49+
#include "swift/ClangImporter/ClangModule.h"
4950
#include "swift/Parse/Lexer.h" // FIXME: Bad dependency
5051
#include "clang/Lex/MacroInfo.h"
5152
#include "llvm/ADT/SmallPtrSet.h"
@@ -719,7 +720,14 @@ Optional<CustomAttrNominalPair> Decl::getGlobalActorAttr() const {
719720
}
720721

721722
bool Decl::predatesConcurrency() const {
722-
return getAttrs().hasAttribute<PredatesConcurrencyAttr>();
723+
if (getAttrs().hasAttribute<PredatesConcurrencyAttr>())
724+
return true;
725+
726+
// Imported C declarations always predate concurrency.
727+
if (isa<ClangModuleUnit>(getDeclContext()->getModuleScopeContext()))
728+
return true;
729+
730+
return false;
723731
}
724732

725733

lib/AST/Type.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,94 @@ Type TypeBase::lookThroughAllOptionalTypes(SmallVectorImpl<Type> &optionals){
755755
return type;
756756
}
757757

758+
Type TypeBase::stripConcurrency(bool recurse, bool dropGlobalActor) {
759+
// Look through optionals.
760+
if (Type optionalObject = getOptionalObjectType()) {
761+
Type newOptionalObject =
762+
optionalObject->stripConcurrency(recurse, dropGlobalActor);
763+
if (optionalObject->isEqual(newOptionalObject))
764+
return Type(this);
765+
766+
return OptionalType::get(newOptionalObject);
767+
}
768+
769+
// Function types.
770+
if (auto fnType = getAs<AnyFunctionType>()) {
771+
// Strip off Sendable and (possibly) the global actor.
772+
ASTExtInfo extInfo =
773+
fnType->hasExtInfo() ? fnType->getExtInfo() : ASTExtInfo();
774+
extInfo = extInfo.withConcurrent(false);
775+
if (dropGlobalActor)
776+
extInfo = extInfo.withGlobalActor(Type());
777+
778+
ArrayRef<AnyFunctionType::Param> params = fnType->getParams();
779+
Type resultType = fnType->getResult();
780+
781+
SmallVector<AnyFunctionType::Param, 4> newParams;
782+
if (recurse) {
783+
for (unsigned paramIdx : indices(params)) {
784+
const auto &param = params[paramIdx];
785+
Type newParamType = param.getPlainType()->stripConcurrency(
786+
recurse, dropGlobalActor);
787+
788+
if (!newParams.empty()) {
789+
newParams.push_back(param.withType(newParamType));
790+
continue;
791+
}
792+
793+
if (newParamType->isEqual(param.getPlainType()))
794+
continue;
795+
796+
newParams.append(params.begin(), params.begin() + paramIdx);
797+
newParams.push_back(param.withType(newParamType));
798+
}
799+
800+
if (!newParams.empty())
801+
params = newParams;
802+
803+
resultType = resultType->stripConcurrency(recurse, dropGlobalActor);
804+
}
805+
806+
// Drop Sendable requirements.
807+
GenericSignature genericSig;
808+
if (auto genericFnType = dyn_cast<GenericFunctionType>(fnType)) {
809+
auto requirements = genericFnType->getRequirements();
810+
SmallVector<Requirement, 4> newRequirements;
811+
for (unsigned reqIdx : indices(requirements)) {
812+
// If it's a Sendable requirement, skip it.
813+
const auto &req = requirements[reqIdx];
814+
if (req.getKind() == RequirementKind::Conformance &&
815+
req.getSecondType()->castTo<ProtocolType>()->getDecl()
816+
->isSpecificProtocol(KnownProtocolKind::Sendable))
817+
continue;
818+
819+
newRequirements.push_back(req);
820+
}
821+
822+
if (newRequirements.size() == requirements.size()) {
823+
genericSig = genericFnType->getGenericSignature();
824+
} else {
825+
genericSig = GenericSignature::get(
826+
genericFnType->getGenericParams(), newRequirements);
827+
}
828+
}
829+
830+
Type newFnType;
831+
if (genericSig) {
832+
newFnType = GenericFunctionType::get(
833+
genericSig, params, resultType, extInfo);
834+
} else {
835+
newFnType = FunctionType::get(params, resultType, extInfo);
836+
}
837+
if (newFnType->isEqual(this))
838+
return Type(this);
839+
840+
return newFnType;
841+
}
842+
843+
return Type(this);
844+
}
845+
758846
bool TypeBase::isAnyObject() {
759847
auto canTy = getCanonicalType();
760848

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8392,17 +8392,13 @@ SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile(
83928392
return *sourceFile;
83938393
}
83948394

8395-
Optional<bool> swift::importer::isMainActorAttr(
8396-
ASTContext &ctx, const clang::SwiftAttrAttr *swiftAttr) {
8395+
bool swift::importer::isMainActorAttr(const clang::SwiftAttrAttr *swiftAttr) {
83978396
if (swiftAttr->getAttribute() == "@MainActor" ||
8398-
swiftAttr->getAttribute() == "@MainActor(unsafe)" ||
83998397
swiftAttr->getAttribute() == "@UIActor") {
8400-
bool isUnsafe = swiftAttr->getAttribute() == "@MainActor(unsafe)" ||
8401-
!ctx.LangOpts.isSwiftVersionAtLeast(6);
8402-
return isUnsafe;
8398+
return true;
84038399
}
84048400

8405-
return None;
8401+
return false;
84068402
}
84078403

84088404
void
@@ -8430,9 +8426,7 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
84308426
for (auto swiftAttr : ClangDecl->specific_attrs<clang::SwiftAttrAttr>()) {
84318427
// FIXME: Hard-code @MainActor and @UIActor, because we don't have a
84328428
// point at which to do name lookup for imported entities.
8433-
if (auto isMainActor = isMainActorAttr(SwiftContext, swiftAttr)) {
8434-
bool isUnsafe = *isMainActor;
8435-
8429+
if (isMainActorAttr(swiftAttr)) {
84368430
if (SeenMainActorAttr) {
84378431
// Cannot add main actor annotation twice. We'll keep the first
84388432
// one and raise a warning about the duplicate.
@@ -8446,7 +8440,6 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
84468440
if (Type mainActorType = SwiftContext.getMainActorType()) {
84478441
auto typeExpr = TypeExpr::createImplicit(mainActorType, SwiftContext);
84488442
auto attr = CustomAttr::create(SwiftContext, SourceLoc(), typeExpr);
8449-
attr->setArgIsUnsafe(isUnsafe);
84508443
MappedDecl->getAttrs().add(attr);
84518444
SeenMainActorAttr = swiftAttr;
84528445
}

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1726,7 +1726,7 @@ Type ClangImporter::Implementation::applyParamAttributes(
17261726
continue;
17271727

17281728
// Map the main-actor attribute.
1729-
if (isMainActorAttr(SwiftContext, swiftAttr)) {
1729+
if (isMainActorAttr(swiftAttr)) {
17301730
if (Type mainActor = SwiftContext.getMainActorType()) {
17311731
type = applyToFunctionType(type, [&](ASTExtInfo extInfo) {
17321732
return extInfo.withGlobalActor(mainActor);

lib/ClangImporter/ImporterImpl.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,11 +1663,7 @@ class SwiftNameLookupExtension : public clang::ModuleFileExtension {
16631663

16641664
/// Determines whether the given swift_attr attribute describes the main
16651665
/// actor.
1666-
///
1667-
/// \returns None if this is not a main-actor attribute, and a Boolean
1668-
/// indicating whether (unsafe) was provided in the attribute otherwise.
1669-
Optional<bool> isMainActorAttr(
1670-
ASTContext &ctx, const clang::SwiftAttrAttr *swiftAttr);
1666+
bool isMainActorAttr(const clang::SwiftAttrAttr *swiftAttr);
16711667

16721668
}
16731669
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,34 +4037,6 @@ static Type applyUnsafeConcurrencyToParameterType(
40374037
.withGlobalActor(globalActor));
40384038
}
40394039

4040-
/// Strip concurrency from the given type.
4041-
static Type stripConcurrencyFromType(Type type, bool dropGlobalActor) {
4042-
// Look through optionals.
4043-
if (Type optionalObject = type->getOptionalObjectType()) {
4044-
Type newOptionalObject =
4045-
stripConcurrencyFromType(optionalObject, dropGlobalActor);
4046-
if (optionalObject->isEqual(newOptionalObject))
4047-
return type;
4048-
4049-
return OptionalType::get(newOptionalObject);
4050-
}
4051-
4052-
// For function types, strip off Sendable and possibly the global actor.
4053-
if (auto fnType = type->getAs<FunctionType>()) {
4054-
auto extInfo = fnType->getExtInfo().withConcurrent(false);
4055-
if (dropGlobalActor)
4056-
extInfo = extInfo.withGlobalActor(Type());
4057-
auto newFnType = FunctionType::get(
4058-
fnType->getParams(), fnType->getResult(), extInfo);
4059-
if (newFnType->isEqual(type))
4060-
return type;
4061-
4062-
return newFnType;
4063-
}
4064-
4065-
return type;
4066-
}
4067-
40684040
/// Determine whether the given name is that of a DispatchQueue operation that
40694041
/// takes a closure to be executed on the queue.
40704042
bool swift::isDispatchQueueOperationName(StringRef name) {
@@ -4112,7 +4084,7 @@ Type swift::adjustVarTypeForConcurrency(
41124084
isLValue = true;
41134085
}
41144086

4115-
type = stripConcurrencyFromType(type, /*dropGlobalActor=*/true);
4087+
type = type->stripConcurrency(/*recurse=*/false, /*dropGlobalActor=*/true);
41164088

41174089
if (isLValue)
41184090
type = LValueType::get(type);
@@ -4164,8 +4136,8 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41644136
newParamType = applyUnsafeConcurrencyToParameterType(
41654137
param.getPlainType(), addSendable, addMainActor);
41664138
} else if (stripConcurrency) {
4167-
newParamType = stripConcurrencyFromType(
4168-
param.getPlainType(), numApplies == 0);
4139+
newParamType = param.getPlainType()->stripConcurrency(
4140+
/*recurse=*/false, /*dropGlobalActor=*/numApplies == 0);
41694141
}
41704142

41714143
if (!newParamType || newParamType->isEqual(param.getPlainType())) {
@@ -4189,8 +4161,8 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41894161
// Compute the new result type.
41904162
Type newResultType = fnType->getResult();
41914163
if (stripConcurrency) {
4192-
newResultType = stripConcurrencyFromType(
4193-
newResultType, /*dropGlobalActor=*/true);
4164+
newResultType = newResultType->stripConcurrency(
4165+
/*recurse=*/false, /*dropGlobalActor=*/true);
41944166

41954167
if (!newResultType->isEqual(fnType->getResult()) && newTypeParams.empty()) {
41964168
newTypeParams.append(typeParams.begin(), typeParams.end());

0 commit comments

Comments
 (0)