Skip to content

Commit 64ab350

Browse files
authored
Merge pull request #3663 from swiftwasm/main
[pull] swiftwasm from main
2 parents 0bee03d + fb8ec6f commit 64ab350

34 files changed

+533
-132
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4339,6 +4339,10 @@ NOTE(note_add_globalactor_to_function,none,
43394339
"add '@%0' to make %1 %2 part of global actor %3",
43404340
(StringRef, DescriptiveDeclKind, DeclName, Type))
43414341
FIXIT(insert_globalactor_attr, "@%0 ", (Type))
4342+
4343+
ERROR(main_function_must_be_mainActor,none,
4344+
"main() must be '@MainActor'", ())
4345+
43424346
ERROR(not_objc_function_async,none,
43434347
"'async' %0 cannot be represented in Objective-C", (DescriptiveDeclKind))
43444348
NOTE(not_objc_function_type_async,none,

include/swift/Sema/ConstraintSystem.h

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ using OpenedTypeMap =
908908
/// within a constraint system.
909909
struct ContextualTypeInfo {
910910
TypeLoc typeLoc;
911+
911912
ContextualTypePurpose purpose;
912913

913914
ContextualTypeInfo() : typeLoc(TypeLoc()), purpose(CTP_Unused) {}
@@ -2343,8 +2344,10 @@ class ConstraintSystem {
23432344
solutionApplicationTargets;
23442345

23452346
/// Contextual type information for expressions that are part of this
2346-
/// constraint system.
2347-
llvm::MapVector<ASTNode, ContextualTypeInfo> contextualTypes;
2347+
/// constraint system. The second type, if valid, contains the type as it
2348+
/// should appear in actual constraint. This will have unbound generic types
2349+
/// opened, placeholder types converted to type variables, etc.
2350+
llvm::MapVector<ASTNode, std::pair<ContextualTypeInfo, Type>> contextualTypes;
23482351

23492352
/// Information about each case label item tracked by the constraint system.
23502353
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4>
@@ -3184,21 +3187,47 @@ class ConstraintSystem {
31843187
assert(bool(node) && "Expected non-null expression!");
31853188
assert(contextualTypes.count(node) == 0 &&
31863189
"Already set this contextual type");
3187-
contextualTypes[node] = {T, purpose};
3190+
contextualTypes[node] = {{T, purpose}, Type()};
31883191
}
31893192

31903193
Optional<ContextualTypeInfo> getContextualTypeInfo(ASTNode node) const {
31913194
auto known = contextualTypes.find(node);
31923195
if (known == contextualTypes.end())
31933196
return None;
3194-
return known->second;
3195-
}
3196-
3197-
Type getContextualType(ASTNode node) const {
3198-
auto result = getContextualTypeInfo(node);
3199-
if (result)
3200-
return result->typeLoc.getType();
3201-
return Type();
3197+
return known->second.first;
3198+
}
3199+
3200+
/// Gets the contextual type recorded for an AST node. When fetching a type
3201+
/// for use in constraint solving, \c forConstraint should be set to \c true,
3202+
/// which will ensure that unbound generics have been opened and placeholder
3203+
/// types have been converted to type variables, etc.
3204+
Type getContextualType(ASTNode node, bool forConstraint = false) {
3205+
if (forConstraint) {
3206+
auto known = contextualTypes.find(node);
3207+
if (known == contextualTypes.end())
3208+
return Type();
3209+
3210+
// If we've already computed a type for use in the constraint system,
3211+
// use that.
3212+
if (known->second.second)
3213+
return known->second.second;
3214+
3215+
// Otherwise, compute a type that can be used in a constraint and record
3216+
// it.
3217+
auto info = known->second.first;
3218+
3219+
auto *locator = getConstraintLocator(
3220+
node, LocatorPathElt::ContextualType(info.purpose));
3221+
known->second.second = replaceInferableTypesWithTypeVars(info.getType(),
3222+
locator);
3223+
3224+
return known->second.second;
3225+
} else {
3226+
auto result = getContextualTypeInfo(node);
3227+
if (result)
3228+
return result->getType();
3229+
return Type();
3230+
}
32023231
}
32033232

32043233
TypeLoc getContextualTypeLoc(ASTNode node) const {

include/swift/Sema/OverloadChoice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ class OverloadChoice {
274274
return BaseAndDeclKind.getInt() == IsFallbackDeclViaUnwrappedOptional;
275275
}
276276

277+
/// Whether this choice is for any kind of dynamic member lookup.
278+
bool isAnyDynamicMemberLookup() const {
279+
return getKind() == OverloadChoiceKind::DynamicMemberLookup ||
280+
isKeyPathDynamicMemberLookup();
281+
}
282+
277283
/// Get the name of the overload choice.
278284
DeclName getName() const;
279285

lib/SILGen/SILGenBuilder.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,16 @@ void SILGenBuilder::emitDestructureValueOperation(
869869
}
870870
}
871871

872+
void SILGenBuilder::emitDestructureValueOperation(
873+
SILLocation loc, ManagedValue value,
874+
SmallVectorImpl<ManagedValue> &destructuredValues) {
875+
CleanupCloner cloner(*this, value);
876+
emitDestructureValueOperation(
877+
loc, value.forward(SGF), [&](unsigned index, SILValue subValue) {
878+
destructuredValues.push_back(cloner.clone(subValue));
879+
});
880+
}
881+
872882
ManagedValue SILGenBuilder::createProjectBox(SILLocation loc, ManagedValue mv,
873883
unsigned index) {
874884
auto *pbi = createProjectBox(loc, mv.getValue(), index);

lib/SILGen/SILGenBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,9 @@ class SILGenBuilder : public SILBuilder {
389389
void emitDestructureValueOperation(
390390
SILLocation loc, ManagedValue value,
391391
function_ref<void(unsigned, ManagedValue)> func);
392+
void emitDestructureValueOperation(
393+
SILLocation loc, ManagedValue value,
394+
SmallVectorImpl<ManagedValue> &destructuredValues);
392395

393396
using SILBuilder::createProjectBox;
394397
ManagedValue createProjectBox(SILLocation loc, ManagedValue mv,

lib/SILGen/SILGenDecl.cpp

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,50 +39,42 @@ using namespace Lowering;
3939
void Initialization::_anchor() {}
4040
void SILDebuggerClient::anchor() {}
4141

42-
static void copyOrInitValueIntoHelper(
43-
SILGenFunction &SGF, SILLocation loc, ManagedValue value, bool isInit,
44-
ArrayRef<InitializationPtr> subInitializations,
45-
llvm::function_ref<ManagedValue(ManagedValue, unsigned, SILType)> func) {
46-
auto sourceType = value.getType().castTo<TupleType>();
47-
auto sourceSILType = value.getType();
48-
for (unsigned i = 0, e = sourceType->getNumElements(); i != e; ++i) {
49-
SILType fieldTy = sourceSILType.getTupleElementType(i);
50-
ManagedValue elt = func(value, i, fieldTy);
51-
subInitializations[i]->copyOrInitValueInto(SGF, loc, elt, isInit);
52-
subInitializations[i]->finishInitialization(SGF);
53-
}
54-
}
55-
5642
void TupleInitialization::copyOrInitValueInto(SILGenFunction &SGF,
5743
SILLocation loc,
5844
ManagedValue value, bool isInit) {
45+
// Process all values before initialization all at once to ensure all cleanups
46+
// are setup on all tuple elements before a potential early exit.
47+
SmallVector<ManagedValue, 8> destructuredValues;
48+
5949
// In the object case, emit a destructure operation and return.
6050
if (value.getType().isObject()) {
61-
return SGF.B.emitDestructureValueOperation(
62-
loc, value, [&](unsigned i, ManagedValue subValue) {
63-
auto &subInit = SubInitializations[i];
64-
subInit->copyOrInitValueInto(SGF, loc, subValue, isInit);
65-
subInit->finishInitialization(SGF);
66-
});
67-
}
68-
69-
// In the address case, we forward the underlying value and store it
70-
// into memory and then create a +1 cleanup. since we assume here
71-
// that we have a +1 value since we are forwarding into memory.
72-
assert(value.isPlusOne(SGF) && "Can not store a +0 value into memory?!");
73-
value = ManagedValue::forUnmanaged(value.forward(SGF));
74-
return copyOrInitValueIntoHelper(
75-
SGF, loc, value, isInit, SubInitializations,
76-
[&](ManagedValue aggregate, unsigned i,
77-
SILType fieldType) -> ManagedValue {
78-
ManagedValue elt =
79-
SGF.B.createTupleElementAddr(loc, value, i, fieldType);
80-
if (!fieldType.isAddressOnly(SGF.F)) {
81-
return SGF.B.createLoadTake(loc, elt);
82-
}
51+
SGF.B.emitDestructureValueOperation(loc, value, destructuredValues);
52+
} else {
53+
// In the address case, we forward the underlying value and store it
54+
// into memory and then create a +1 cleanup. since we assume here
55+
// that we have a +1 value since we are forwarding into memory.
56+
assert(value.isPlusOne(SGF) && "Can not store a +0 value into memory?!");
57+
CleanupCloner cloner(SGF, value);
58+
SILValue v = value.forward(SGF);
59+
60+
auto sourceType = value.getType().castTo<TupleType>();
61+
auto sourceSILType = value.getType();
62+
for (unsigned i : range(sourceType->getNumElements())) {
63+
SILType fieldTy = sourceSILType.getTupleElementType(i);
64+
SILValue elt = SGF.B.createTupleElementAddr(loc, v, i, fieldTy);
65+
if (!fieldTy.isAddressOnly(SGF.F)) {
66+
elt = SGF.B.emitLoadValueOperation(loc, elt,
67+
LoadOwnershipQualifier::Take);
68+
}
69+
destructuredValues.push_back(cloner.clone(elt));
70+
}
71+
}
8372

84-
return SGF.emitManagedRValueWithCleanup(elt.getValue());
85-
});
73+
for (unsigned i : indices(destructuredValues)) {
74+
SubInitializations[i]->copyOrInitValueInto(SGF, loc, destructuredValues[i],
75+
isInit);
76+
SubInitializations[i]->finishInitialization(SGF);
77+
}
8678
}
8779

8880
void TupleInitialization::finishUninitialized(SILGenFunction &SGF) {

lib/Sema/BuilderTransform.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,14 @@ class BuilderClosureRewriter
14621462
return nullptr;
14631463
}
14641464

1465+
// Setup the types of our case body var decls.
1466+
for (auto *expected : caseStmt->getCaseBodyVariablesOrEmptyArray()) {
1467+
assert(expected->hasName());
1468+
auto prev = expected->getParentVarDecl();
1469+
auto type = solution.resolveInterfaceType(solution.getType(prev));
1470+
expected->setInterfaceType(type);
1471+
}
1472+
14651473
// Transform the body of the case.
14661474
auto body = cast<BraceStmt>(caseStmt->getBody());
14671475
auto captured = takeCapturedStmt(body);
@@ -1721,7 +1729,16 @@ Optional<BraceStmt *> TypeChecker::applyResultBuilderBodyTransform(
17211729
solutions.front(),
17221730
SolutionApplicationTarget(func))) {
17231731
performSyntacticDiagnosticsForTarget(*result, /*isExprStmt*/ false);
1724-
return result->getFunctionBody();
1732+
auto *body = result->getFunctionBody();
1733+
1734+
if (cs.isDebugMode()) {
1735+
auto &log = llvm::errs();
1736+
log << "--- Type-checked function body ---\n";
1737+
body->dump(log);
1738+
log << '\n';
1739+
}
1740+
1741+
return body;
17251742
}
17261743

17271744
return nullptr;

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,10 +3314,7 @@ namespace {
33143314
}
33153315

33163316
Type getTypeOfDynamicMemberIndex(const SelectedOverload &overload) {
3317-
assert(overload.choice.getKind() ==
3318-
OverloadChoiceKind::DynamicMemberLookup ||
3319-
overload.choice.getKind() ==
3320-
OverloadChoiceKind::KeyPathDynamicMemberLookup);
3317+
assert(overload.choice.isAnyDynamicMemberLookup());
33213318

33223319
auto declTy = solution.simplifyType(overload.openedFullType);
33233320
auto subscriptTy = declTy->castTo<FunctionType>()->getResult();
@@ -3438,8 +3435,7 @@ namespace {
34383435
return nullptr;
34393436
}
34403437

3441-
if (overload->choice.getKind() ==
3442-
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
3438+
if (overload->choice.isKeyPathDynamicMemberLookup()) {
34433439
return buildDynamicMemberLookupRef(
34443440
expr, expr->getBase(), expr->getArgs()->getStartLoc(), SourceLoc(),
34453441
*overload, memberLocator);
@@ -4803,11 +4799,7 @@ namespace {
48034799
continue;
48044800
}
48054801

4806-
isDynamicMember =
4807-
foundDecl->choice.getKind() ==
4808-
OverloadChoiceKind::DynamicMemberLookup ||
4809-
foundDecl->choice.getKind() ==
4810-
OverloadChoiceKind::KeyPathDynamicMemberLookup;
4802+
isDynamicMember = foundDecl->choice.isAnyDynamicMemberLookup();
48114803

48124804
// If this was a @dynamicMemberLookup property, then we actually
48134805
// form a subscript reference, so switch the kind.
@@ -5087,17 +5079,10 @@ namespace {
50875079
// through the subscript(dynamicMember:) member, restore the
50885080
// openedType and origComponent to its full reference as if the user
50895081
// wrote out the subscript manually.
5090-
bool forDynamicLookup =
5091-
overload.choice.getKind() ==
5092-
OverloadChoiceKind::DynamicMemberLookup ||
5093-
overload.choice.getKind() ==
5094-
OverloadChoiceKind::KeyPathDynamicMemberLookup;
5095-
5096-
if (forDynamicLookup) {
5082+
if (overload.choice.isAnyDynamicMemberLookup()) {
50975083
auto indexType = getTypeOfDynamicMemberIndex(overload);
50985084
Expr *argExpr = nullptr;
5099-
if (overload.choice.getKind() ==
5100-
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
5085+
if (overload.choice.isKeyPathDynamicMemberLookup()) {
51015086
argExpr = buildKeyPathDynamicMemberArgExpr(
51025087
indexType->castTo<BoundGenericType>(), componentLoc, memberLoc);
51035088
} else {
@@ -5150,7 +5135,7 @@ namespace {
51505135
ctx, ref, args, resolvedTy, ctx.AllocateCopy(conformances));
51515136
components.push_back(comp);
51525137

5153-
if (shouldForceUnwrapResult(overload.choice, locator))
5138+
if (shouldForceUnwrapResult(overload.choice, memberLoc))
51545139
buildKeyPathOptionalForceComponent(components);
51555140
}
51565141

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,13 +1614,13 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
16141614
}
16151615
}
16161616

1617-
if (auto resolvedOverload = getOverloadChoiceIfAvailable(getLocator())) {
1617+
if (auto resolvedOverload =
1618+
getCalleeOverloadChoiceIfAvailable(getLocator())) {
16181619
if (resolvedOverload->choice.getKind() ==
16191620
OverloadChoiceKind::DynamicMemberLookup)
16201621
subElementDiagID = diag::assignment_dynamic_property_has_immutable_base;
16211622

1622-
if (resolvedOverload->choice.getKind() ==
1623-
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
1623+
if (resolvedOverload->choice.isKeyPathDynamicMemberLookup()) {
16241624
if (!getType(member->getBase(), /*wantRValue=*/false)->hasLValueType())
16251625
subElementDiagID =
16261626
diag::assignment_dynamic_property_has_immutable_base;

lib/Sema/CSGen.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,9 +1731,12 @@ namespace {
17311731
};
17321732

17331733
// If a contextual type exists for this expression, apply it directly.
1734-
Optional<Type> arrayElementType;
1735-
if (contextualType &&
1736-
(arrayElementType = ConstraintSystem::isArrayType(contextualType))) {
1734+
if (contextualType && ConstraintSystem::isArrayType(contextualType)) {
1735+
// Now that we know we're actually going to use the type, get the
1736+
// version for use in a constraint.
1737+
contextualType = CS.getContextualType(expr, /*forConstraint=*/true);
1738+
Optional<Type> arrayElementType =
1739+
ConstraintSystem::isArrayType(contextualType);
17371740
CS.addConstraint(ConstraintKind::LiteralConformsTo, contextualType,
17381741
arrayProto->getDeclaredInterfaceType(),
17391742
locator);
@@ -1836,14 +1839,19 @@ namespace {
18361839
auto locator = CS.getConstraintLocator(expr);
18371840
auto contextualType = CS.getContextualType(expr);
18381841
auto contextualPurpose = CS.getContextualTypePurpose(expr);
1839-
auto openedType =
1840-
CS.openOpaqueType(contextualType, contextualPurpose, locator);
18411842

18421843
// If a contextual type exists for this expression and is a dictionary
18431844
// type, apply it directly.
1844-
Optional<std::pair<Type, Type>> dictionaryKeyValue;
1845-
if (openedType && (dictionaryKeyValue =
1846-
ConstraintSystem::isDictionaryType(openedType))) {
1845+
if (contextualType && ConstraintSystem::isDictionaryType(contextualType)) {
1846+
// Now that we know we're actually going to use the type, get the
1847+
// version for use in a constraint.
1848+
contextualType = CS.getContextualType(expr, /*forConstraint=*/true);
1849+
auto openedType =
1850+
CS.openOpaqueType(contextualType, contextualPurpose, locator);
1851+
openedType = CS.replaceInferableTypesWithTypeVars(
1852+
openedType, CS.getConstraintLocator(expr));
1853+
auto dictionaryKeyValue =
1854+
ConstraintSystem::isDictionaryType(openedType);
18471855
Type contextualDictionaryKeyType;
18481856
Type contextualDictionaryValueType;
18491857
std::tie(contextualDictionaryKeyType,

0 commit comments

Comments
 (0)