Skip to content

Commit fd98026

Browse files
authored
Merge pull request #2924 from swiftwasm/main
[pull] swiftwasm from main
2 parents 8eb9da2 + 717a132 commit fd98026

File tree

147 files changed

+2414
-3324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+2414
-3324
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,10 @@ class ASTContext final {
738738
/// compiler for the target platform.
739739
AvailabilityContext getSwift54Availability();
740740

741+
/// Get the runtime availability of features introduced in the Swift 5.5
742+
/// compiler for the target platform.
743+
AvailabilityContext getSwift55Availability();
744+
741745
/// Get the runtime availability of features that have been introduced in the
742746
/// Swift compiler for future versions of the target platform.
743747
AvailabilityContext getSwiftFutureAvailability();

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,9 @@ WARNING(implicit_bridging_header_imported_from_module,none,
8383
"is deprecated and will be removed in a later version of Swift",
8484
(StringRef, Identifier))
8585

86+
WARNING(import_multiple_mainactor_attr,none,
87+
"this attribute for global actor '%0' is invalid; the declaration already has attribute for global actor '%1'",
88+
(StringRef, StringRef))
89+
8690
#define UNDEFINE_DIAGNOSTIC_MACROS
8791
#include "DefineDiagnosticMacros.h"

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4394,9 +4394,6 @@ ERROR(actor_isolated_from_concurrent_function,none,
43944394
ERROR(actor_isolated_from_async_let,none,
43954395
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from 'async let' initializer",
43964396
(DescriptiveDeclKind, DeclName, unsigned))
4397-
ERROR(actor_isolated_from_escaping_closure,none,
4398-
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from an '@escaping' closure",
4399-
(DescriptiveDeclKind, DeclName, unsigned))
44004397
ERROR(actor_isolated_keypath_component,none,
44014398
"cannot form key path to actor-isolated %0 %1",
44024399
(DescriptiveDeclKind, DeclName))

lib/AST/Availability.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ ASTContext::getIntermodulePrespecializedGenericMetadataAvailability() {
324324
}
325325

326326
AvailabilityContext ASTContext::getConcurrencyAvailability() {
327-
return getSwiftFutureAvailability();
327+
return getSwift55Availability();
328328
}
329329

330330
AvailabilityContext ASTContext::getDifferentiationAvailability() {
@@ -409,6 +409,11 @@ AvailabilityContext ASTContext::getSwift54Availability() {
409409
}
410410
}
411411

412+
AvailabilityContext ASTContext::getSwift55Availability() {
413+
return getSwiftFutureAvailability();
414+
}
415+
416+
412417
AvailabilityContext ASTContext::getSwiftFutureAvailability() {
413418
auto target = LangOpts.Target;
414419

lib/AST/Type.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,9 +1834,6 @@ class IsBindableVisitor
18341834
if (nom->getDecl() != substNom->getDecl())
18351835
return CanType();
18361836

1837-
if (nom->getDecl()->isInvalid())
1838-
return CanType();
1839-
18401837
// Same decl should always either have or not have a parent.
18411838
assert((bool)nom->getParent() == (bool)substNom->getParent());
18421839

@@ -2078,8 +2075,6 @@ class IsBindableVisitor
20782075
return CanType();
20792076

20802077
auto *decl = bgt->getDecl();
2081-
if (decl->isInvalid())
2082-
return CanType();
20832078

20842079
auto *moduleDecl = decl->getParentModule();
20852080
auto origSubMap = bgt->getContextSubstitutionMap(
@@ -2139,6 +2134,12 @@ class IsBindableVisitor
21392134
if (req.getKind() != RequirementKind::Conformance) continue;
21402135

21412136
auto canTy = req.getFirstType()->getCanonicalType();
2137+
2138+
// If the substituted type is an interface type, we can't verify the
2139+
// generic requirements.
2140+
if (canTy.subst(substSubMap)->isTypeParameter())
2141+
continue;
2142+
21422143
auto *proto = req.getProtocolDecl();
21432144
auto origConf = origSubMap.lookupConformance(canTy, proto);
21442145
auto substConf = substSubMap.lookupConformance(canTy, proto);

lib/ClangImporter/ImportDecl.cpp

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4590,7 +4590,27 @@ namespace {
45904590
if (auto Known = Impl.importDeclCached(decl, getVersion()))
45914591
return Known;
45924592

4593-
return importObjCMethodDecl(decl, dc, None);
4593+
ImportedName importedName;
4594+
Optional<ImportedName> correctSwiftName; // TODO: not sure if we need this.
4595+
importedName = importFullName(decl, correctSwiftName);
4596+
if (!importedName)
4597+
return nullptr;
4598+
4599+
// some ObjC method decls are imported as computed properties.
4600+
switch(importedName.getAccessorKind()) {
4601+
case ImportedAccessorKind::PropertyGetter:
4602+
if (importedName.getAsyncInfo())
4603+
return importObjCMethodAsEffectfulProp(decl, dc, importedName);
4604+
4605+
// if there is no valid async info, then fall-back to method import.
4606+
LLVM_FALLTHROUGH;
4607+
4608+
case ImportedAccessorKind::PropertySetter:
4609+
case ImportedAccessorKind::SubscriptGetter:
4610+
case ImportedAccessorKind::SubscriptSetter:
4611+
case ImportedAccessorKind::None:
4612+
return importObjCMethodDecl(decl, dc, None);
4613+
}
45944614
}
45954615

45964616
/// Check whether we have already imported a method with the given
@@ -4666,6 +4686,78 @@ namespace {
46664686
return (accessor && accessor->getAccessorKind() == accessorInfo->Kind);
46674687
}
46684688

4689+
/// Creates a fresh VarDecl with a single 'get' accessor to represent
4690+
/// an ObjC method that takes no arguments other than a completion-handler
4691+
/// (where the handler may have an NSError argument).
4692+
Decl *importObjCMethodAsEffectfulProp(const clang::ObjCMethodDecl *decl,
4693+
DeclContext *dc,
4694+
ImportedName name) {
4695+
assert(name.getAsyncInfo() && "expected to be for an effectful prop!");
4696+
4697+
if (name.getAccessorKind() != ImportedAccessorKind::PropertyGetter) {
4698+
assert(false && "unexpected accessor kind as a computed prop");
4699+
// NOTE: to handle setters, we would need to search for an existing
4700+
// VarDecl corresponding to the one we might have already created
4701+
// for the 'get' accessor, and tack this accessor onto it.
4702+
return nullptr;
4703+
}
4704+
4705+
auto importedType = Impl.importEffectfulPropertyType(decl, dc, name,
4706+
isInSystemModule(dc));
4707+
if (!importedType)
4708+
return nullptr;
4709+
4710+
auto type = importedType.getType();
4711+
const auto access = getOverridableAccessLevel(dc);
4712+
auto ident = name.getDeclName().getBaseIdentifier();
4713+
auto propDecl = Impl.createDeclWithClangNode<VarDecl>(decl, access,
4714+
/*IsStatic*/decl->isClassMethod(), VarDecl::Introducer::Var,
4715+
Impl.importSourceLoc(decl->getLocation()), ident, dc);
4716+
propDecl->setInterfaceType(type);
4717+
Impl.recordImplicitUnwrapForDecl(propDecl,
4718+
importedType.isImplicitlyUnwrapped());
4719+
4720+
////
4721+
// Build the getter
4722+
AccessorInfo info{propDecl, AccessorKind::Get};
4723+
auto *getter = cast_or_null<AccessorDecl>(
4724+
importObjCMethodDecl(decl, dc, info));
4725+
if (!getter)
4726+
return nullptr;
4727+
4728+
Impl.importAttributes(decl, getter);
4729+
4730+
////
4731+
// Combine the getter and the VarDecl into a computed property.
4732+
4733+
// NOTE: since it's an ObjC method we're turning into a Swift computed
4734+
// property, we infer that it has no ObjC 'atomic' guarantees.
4735+
auto inferredObjCPropertyAttrs =
4736+
static_cast<clang::ObjCPropertyAttribute::Kind>
4737+
( clang::ObjCPropertyAttribute::Kind::kind_readonly
4738+
| clang::ObjCPropertyAttribute::Kind::kind_nonatomic
4739+
| (decl->isInstanceMethod()
4740+
? clang::ObjCPropertyAttribute::Kind::kind_class
4741+
: clang::ObjCPropertyAttribute::Kind::kind_noattr)
4742+
);
4743+
4744+
// FIXME: Fake locations for '{' and '}'?
4745+
propDecl->setIsSetterMutating(false);
4746+
makeComputed(propDecl, getter, /*setter=*/nullptr);
4747+
addObjCAttribute(propDecl, Impl.importIdentifier(decl->getIdentifier()));
4748+
applyPropertyOwnership(propDecl, inferredObjCPropertyAttrs);
4749+
4750+
////
4751+
// Check correctness
4752+
4753+
if (getter->getParameters()->size() != 0) {
4754+
assert(false && "this should not happen!");
4755+
return nullptr;
4756+
}
4757+
4758+
return propDecl;
4759+
}
4760+
46694761
Decl *importObjCMethodDecl(const clang::ObjCMethodDecl *decl,
46704762
DeclContext *dc,
46714763
bool forceClassMethod,
@@ -4797,11 +4889,16 @@ namespace {
47974889
prop = nullptr;
47984890
}
47994891

4800-
// If we have an accessor-import request but didn't find a property,
4801-
// reject the import request.
4802-
if (accessorInfo && !prop) {
4892+
const bool nameImportIsGetter =
4893+
importedName.getAccessorKind() == ImportedAccessorKind::PropertyGetter;
4894+
4895+
const bool needAccessorDecl = prop || nameImportIsGetter;
4896+
4897+
// If we have an accessor-import request, but didn't find a property
4898+
// or it's ImportedName doesn't indicate a getter,
4899+
// then reject the import request.
4900+
if (accessorInfo && !needAccessorDecl)
48034901
return nullptr;
4804-
}
48054902

48064903
// Import the parameter list and result type.
48074904
ParameterList *bodyParams = nullptr;
@@ -4854,7 +4951,7 @@ namespace {
48544951

48554952
// If the method has a related result type that is representable
48564953
// in Swift as DynamicSelf, do so.
4857-
if (!prop && decl->hasRelatedResultType()) {
4954+
if (!needAccessorDecl && decl->hasRelatedResultType()) {
48584955
resultTy = dc->getSelfInterfaceType();
48594956
if (dc->getSelfClassDecl())
48604957
resultTy = DynamicSelfType::get(resultTy, Impl.SwiftContext);
@@ -5020,7 +5117,7 @@ namespace {
50205117
FuncDecl *setter);
50215118

50225119
/// Import the accessor and its attributes.
5023-
AccessorDecl *importAccessor(clang::ObjCMethodDecl *clangAccessor,
5120+
AccessorDecl *importAccessor(const clang::ObjCMethodDecl *clangAccessor,
50245121
AbstractStorageDecl *storage,
50255122
AccessorKind accessorKind,
50265123
DeclContext *dc);
@@ -7389,7 +7486,7 @@ SwiftDeclConverter::importSubscript(Decl *decl,
73897486
}
73907487

73917488
AccessorDecl *
7392-
SwiftDeclConverter::importAccessor(clang::ObjCMethodDecl *clangAccessor,
7489+
SwiftDeclConverter::importAccessor(const clang::ObjCMethodDecl *clangAccessor,
73937490
AbstractStorageDecl *storage,
73947491
AccessorKind accessorKind,
73957492
DeclContext *dc) {
@@ -8353,6 +8450,7 @@ void ClangImporter::Implementation::importAttributes(
83538450
// Scan through Clang attributes and map them onto Swift
83548451
// equivalents.
83558452
PatternBindingInitializer *initContext = nullptr;
8453+
Optional<const clang::SwiftAttrAttr *> SeenMainActorAttr;
83568454
bool AnyUnavailable = MappedDecl->getAttrs().isUnavailable(C);
83578455
for (clang::NamedDecl::attr_iterator AI = ClangDecl->attr_begin(),
83588456
AE = ClangDecl->attr_end(); AI != AE; ++AI) {
@@ -8496,15 +8594,32 @@ void ClangImporter::Implementation::importAttributes(
84968594
// __attribute__((swift_attr("attribute")))
84978595
//
84988596
if (auto swiftAttr = dyn_cast<clang::SwiftAttrAttr>(*AI)) {
8499-
// FIXME: Hard-core @MainActor and @UIActor, because we don't have a
8597+
// FIXME: Hard-code @MainActor and @UIActor, because we don't have a
85008598
// point at which to do name lookup for imported entities.
85018599
if (auto isMainActor = isMainActorAttr(SwiftContext, swiftAttr)) {
85028600
bool isUnsafe = *isMainActor;
8601+
8602+
if (SeenMainActorAttr) {
8603+
// Cannot add main actor annotation twice. We'll keep the first
8604+
// one and raise a warning about the duplicate.
8605+
auto &clangSrcMgr = getClangASTContext().getSourceManager();
8606+
ClangSourceBufferImporter &bufferImporter =
8607+
getBufferImporterForDiagnostics();
8608+
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
8609+
clangSrcMgr, swiftAttr->getLocation());
8610+
8611+
diagnose(attrLoc, diag::import_multiple_mainactor_attr,
8612+
swiftAttr->getAttribute(),
8613+
SeenMainActorAttr.getValue()->getAttribute());
8614+
continue;
8615+
}
8616+
85038617
if (Type mainActorType = SwiftContext.getMainActorType()) {
85048618
auto typeExpr = TypeExpr::createImplicit(mainActorType, SwiftContext);
85058619
auto attr = CustomAttr::create(SwiftContext, SourceLoc(), typeExpr);
85068620
attr->setArgIsUnsafe(isUnsafe);
85078621
MappedDecl->getAttrs().add(attr);
8622+
SeenMainActorAttr = swiftAttr;
85088623
}
85098624

85108625
continue;

lib/ClangImporter/ImportName.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,8 +1618,12 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
16181618
else if (parsedName.IsSetter)
16191619
result.info.accessorKind = ImportedAccessorKind::PropertySetter;
16201620

1621-
if (method && parsedName.IsFunctionName &&
1622-
result.info.accessorKind == ImportedAccessorKind::None) {
1621+
// only allow effectful property imports if through `swift_async_name`
1622+
const bool effectfulProperty = parsedName.IsGetter && nameAttr->isAsync
1623+
&& swiftCtx.LangOpts.EnableExperimentalConcurrency;
1624+
1625+
// Consider throws and async imports.
1626+
if (method && (parsedName.IsFunctionName || effectfulProperty)) {
16231627
// Get the parameters.
16241628
ArrayRef<const clang::ParmVarDecl *> params{method->param_begin(),
16251629
method->param_end()};

lib/ClangImporter/ImportType.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,49 @@ static Type decomposeCompletionHandlerType(
22032203
}
22042204
}
22052205

2206+
ImportedType ClangImporter::Implementation::importEffectfulPropertyType(
2207+
const clang::ObjCMethodDecl *decl,
2208+
DeclContext *dc,
2209+
importer::ImportedName name,
2210+
bool isFromSystemModule) {
2211+
// here we expect a method that is being imported as an effectful property.
2212+
// thus, we currently require async info.
2213+
if (!name.getAsyncInfo())
2214+
return ImportedType();
2215+
2216+
// a variadic method doesn't make sense here
2217+
if (decl->isVariadic())
2218+
return ImportedType();
2219+
2220+
// Our strategy here is to determine what the return type of the method would
2221+
// be, had we imported it as a method.
2222+
2223+
Optional<ForeignAsyncConvention> asyncConvention;
2224+
Optional<ForeignErrorConvention> errorConvention;
2225+
2226+
const auto kind = SpecialMethodKind::Regular;
2227+
2228+
// Import the parameter list and result type.
2229+
ParameterList *bodyParams = nullptr;
2230+
ImportedType importedType;
2231+
2232+
auto methodReturnType = importMethodParamsAndReturnType(
2233+
dc, decl, decl->parameters(), false,
2234+
isFromSystemModule, &bodyParams, name,
2235+
asyncConvention, errorConvention, kind);
2236+
2237+
// getter mustn't have any parameters!
2238+
if (bodyParams->size() != 0) {
2239+
return ImportedType();
2240+
}
2241+
2242+
// We expect that the method, after import, will have only an async convention
2243+
if (!asyncConvention || errorConvention)
2244+
return ImportedType();
2245+
2246+
return methodReturnType;
2247+
}
2248+
22062249
ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
22072250
const DeclContext *dc, const clang::ObjCMethodDecl *clangDecl,
22082251
ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,

lib/ClangImporter/ImporterImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,13 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
11991199
ImportedType importPropertyType(const clang::ObjCPropertyDecl *clangDecl,
12001200
bool isFromSystemModule);
12011201

1202+
/// Determines what the type of an effectful, computed read-only property
1203+
/// would be, if the given method were imported as such a property.
1204+
ImportedType importEffectfulPropertyType(const clang::ObjCMethodDecl *decl,
1205+
DeclContext *dc,
1206+
importer::ImportedName name,
1207+
bool isFromSystemModule);
1208+
12021209
/// Attempt to infer a default argument for a parameter with the
12031210
/// given Clang \c type, \c baseName, and optionality.
12041211
static DefaultArgumentKind

lib/IRGen/GenCall.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4803,12 +4803,13 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
48034803
auto &nativeSchema =
48044804
IGM.getTypeInfo(funcResultTypeInContext).nativeReturnValueSchema(IGM);
48054805
if (result.empty() && !nativeSchema.empty()) {
4806-
// When we throw, we set the return values to undef.
4807-
nativeSchema.enumerateComponents([&](clang::CharUnits begin,
4808-
clang::CharUnits end,
4809-
llvm::Type *componentTy) {
4810-
nativeResultsStorage.push_back(llvm::UndefValue::get(componentTy));
4811-
});
4806+
if (!nativeSchema.requiresIndirect())
4807+
// When we throw, we set the return values to undef.
4808+
nativeSchema.enumerateComponents([&](clang::CharUnits begin,
4809+
clang::CharUnits end,
4810+
llvm::Type *componentTy) {
4811+
nativeResultsStorage.push_back(llvm::UndefValue::get(componentTy));
4812+
});
48124813
if (!error.empty())
48134814
nativeResultsStorage.push_back(error.claimNext());
48144815
nativeResults = nativeResultsStorage;

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2684,7 +2684,12 @@ void IRGenModule::createReplaceableProlog(IRGenFunction &IGF, SILFunction *f) {
26842684
FunctionPointer(silFunctionType, realReplFn, authInfo, signature)
26852685
.getAsFunction(IGF),
26862686
forwardedArgs);
2687-
Res->setTailCall();
2687+
if (Res->getCallingConv() == llvm::CallingConv::SwiftTail &&
2688+
Res->getCaller()->getCallingConv() == llvm::CallingConv::SwiftTail) {
2689+
Res->setTailCallKind(IGF.IGM.AsyncTailCallKind);
2690+
} else {
2691+
Res->setTailCall();
2692+
}
26882693
if (IGF.CurFn->getReturnType()->isVoidTy())
26892694
IGF.Builder.CreateRetVoid();
26902695
else

0 commit comments

Comments
 (0)