Skip to content

Commit 81b7b44

Browse files
authored
Merge pull request swiftlang#79253 from xedin/fix-use-dc-for-constructor-calls
[ConstraintSystem] Store declaration context in which application constraint occurs
2 parents 2bb86e4 + 23ace7d commit 81b7b44

File tree

7 files changed

+264
-75
lines changed

7 files changed

+264
-75
lines changed

include/swift/Sema/Constraint.h

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
380380
/// The kind of function reference, for member references.
381381
unsigned TheFunctionRefInfo : 3;
382382

383-
/// The trailing closure matching for an applicable function constraint,
384-
/// if any. 0 = None, 1 = Forward, 2 = Backward.
385-
unsigned trailingClosureMatching : 2;
386-
387383
union {
388384
struct {
389385
/// The first type.
@@ -439,6 +435,21 @@ class Constraint final : public llvm::ilist_node<Constraint>,
439435
/// Identifies whether result of this node is unused.
440436
bool IsDiscarded;
441437
} SyntacticElement;
438+
439+
struct {
440+
/// The function type that is being applied where parameters
441+
/// represent argument types passed to callee and result type
442+
/// represents result type of the application.
443+
FunctionType *AppliedFn;
444+
/// The type being called, primarily a function type, but could
445+
/// be a metatype, a tuple or a nominal type.
446+
Type Callee;
447+
/// The trailing closure matching for an applicable function constraint,
448+
/// if any. 0 = None, 1 = Forward, 2 = Backward.
449+
unsigned TrailingClosureMatching : 2;
450+
/// The declaration context in which the application appears.
451+
DeclContext *UseDC;
452+
} Apply;
442453
};
443454

444455
/// The locator that describes where in the expression this
@@ -495,6 +506,11 @@ class Constraint final : public llvm::ilist_node<Constraint>,
495506
ConstraintLocator *locator,
496507
SmallPtrSetImpl<TypeVariableType *> &typeVars);
497508

509+
Constraint(FunctionType *appliedFn, Type calleeType,
510+
unsigned trailingClosureMatching, DeclContext *useDC,
511+
ConstraintLocator *locator,
512+
SmallPtrSetImpl<TypeVariableType *> &typeVars);
513+
498514
/// Retrieve the type variables buffer, for internal mutation.
499515
MutableArrayRef<TypeVariableType *> getTypeVariablesBuffer() {
500516
return { getTrailingObjects<TypeVariableType *>(), NumTypeVariables };
@@ -580,9 +596,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
580596

581597
/// Create a new Applicable Function constraint.
582598
static Constraint *createApplicableFunction(
583-
ConstraintSystem &cs, Type argumentFnType, Type calleeType,
599+
ConstraintSystem &cs, FunctionType *argumentFnType, Type calleeType,
584600
std::optional<TrailingClosureMatching> trailingClosureMatching,
585-
ConstraintLocator *locator);
601+
DeclContext *useDC, ConstraintLocator *locator);
586602

587603
static Constraint *createSyntacticElement(ConstraintSystem &cs,
588604
ASTNode node,
@@ -739,6 +755,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
739755
case ConstraintKind::SyntacticElement:
740756
llvm_unreachable("closure body element constraint has no type operands");
741757

758+
case ConstraintKind::ApplicableFunction:
759+
return Apply.AppliedFn;
760+
742761
default:
743762
return Types.First;
744763
}
@@ -758,6 +777,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
758777
case ConstraintKind::ValueWitness:
759778
return Member.Second;
760779

780+
case ConstraintKind::ApplicableFunction:
781+
return Apply.Callee;
782+
761783
default:
762784
return Types.Second;
763785
}
@@ -851,6 +873,21 @@ class Constraint final : public llvm::ilist_node<Constraint>,
851873
return Member.UseDC;
852874
}
853875

876+
FunctionType *getAppliedFunctionType() const {
877+
assert(Kind == ConstraintKind::ApplicableFunction);
878+
return Apply.AppliedFn;
879+
}
880+
881+
Type getCalleeType() const {
882+
assert(Kind == ConstraintKind::ApplicableFunction);
883+
return Apply.Callee;
884+
}
885+
886+
DeclContext *getApplicationDC() const {
887+
assert(Kind == ConstraintKind::ApplicableFunction);
888+
return Apply.UseDC;
889+
}
890+
854891
ASTNode getSyntacticElement() const {
855892
assert(Kind == ConstraintKind::SyntacticElement);
856893
return SyntacticElement.Element;

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3565,6 +3565,11 @@ class ConstraintSystem {
35653565
void addConstraint(Requirement req, ConstraintLocatorBuilder locator,
35663566
bool isFavored = false);
35673567

3568+
void addApplicationConstraint(
3569+
FunctionType *appliedFn, Type calleeType,
3570+
std::optional<TrailingClosureMatching> trailingClosureMatching,
3571+
DeclContext *useDC, ConstraintLocatorBuilder locator);
3572+
35683573
/// Add the appropriate constraint for a contextual conversion.
35693574
void addContextualConversionConstraint(Expr *expr, Type conversionType,
35703575
ContextualTypePurpose purpose,
@@ -4960,8 +4965,9 @@ class ConstraintSystem {
49604965

49614966
/// Attempt to simplify the ApplicableFunction constraint.
49624967
SolutionKind simplifyApplicableFnConstraint(
4963-
Type type1, Type type2,
4968+
FunctionType *appliedFn, Type calleeTy,
49644969
std::optional<TrailingClosureMatching> trailingClosureMatching,
4970+
DeclContext *useDC,
49654971
TypeMatchOptions flags, ConstraintLocatorBuilder locator);
49664972

49674973
/// Attempt to simplify the DynamicCallableApplicableFunction constraint.

lib/Sema/CSGen.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,9 @@ namespace {
395395

396396
// Add the constraint that the index expression's type be convertible
397397
// to the input type of the subscript operator.
398-
CS.addConstraint(ConstraintKind::ApplicableFunction,
399-
FunctionType::get(params, outputTy),
400-
memberTy,
401-
fnLocator);
398+
CS.addApplicationConstraint(FunctionType::get(params, outputTy), memberTy,
399+
/*trailingClosureMatching=*/std::nullopt,
400+
CurDC, fnLocator);
402401

403402
Type fixedOutputType =
404403
CS.getFixedTypeRecursive(outputTy, /*wantRValue=*/false);
@@ -721,9 +720,9 @@ namespace {
721720
CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
722721
TVO_CanBindToNoEscape);
723722

724-
CS.addConstraint(ConstraintKind::ApplicableFunction,
725-
FunctionType::get(params, resultType), memberType,
726-
fnLoc);
723+
CS.addApplicationConstraint(
724+
FunctionType::get(params, resultType), memberType,
725+
/*trailingClosureMatching=*/std::nullopt, CurDC, fnLoc);
727726

728727
if (constr->isFailable())
729728
return OptionalType::get(witnessType);
@@ -2545,10 +2544,10 @@ namespace {
25452544
SmallVector<AnyFunctionType::Param, 8> params;
25462545
getMatchingParams(expr->getArgs(), params);
25472546

2548-
CS.addConstraint(ConstraintKind::ApplicableFunction,
2549-
FunctionType::get(params, resultType, extInfo),
2550-
CS.getType(fnExpr),
2551-
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction));
2547+
CS.addApplicationConstraint(
2548+
FunctionType::get(params, resultType, extInfo), CS.getType(fnExpr),
2549+
/*trailingClosureMatching=*/std::nullopt, CurDC,
2550+
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction));
25522551

25532552
// If we ended up resolving the result type variable to a concrete type,
25542553
// set it as the favored type for this expression.
@@ -3296,10 +3295,11 @@ namespace {
32963295
CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
32973296
TVO_CanBindToNoEscape);
32983297

3299-
CS.addConstraint(
3300-
ConstraintKind::ApplicableFunction,
3298+
CS.addApplicationConstraint(
33013299
FunctionType::get(params, resultType),
33023300
macroRefType,
3301+
/*trailingClosureMatching=*/std::nullopt,
3302+
CurDC,
33033303
CS.getConstraintLocator(
33043304
expr, ConstraintLocator::ApplyFunction));
33053305

lib/Sema/CSSimplify.cpp

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8364,8 +8364,9 @@ ConstraintSystem::simplifyConstructionConstraint(
83648364
paramTypeVar, locator);
83658365
}
83668366

8367-
addConstraint(ConstraintKind::ApplicableFunction, fnType, memberType,
8368-
fnLocator);
8367+
addApplicationConstraint(fnType, memberType,
8368+
/*trailingClosureMatching=*/std::nullopt, useDC,
8369+
fnLocator);
83698370

83708371
return SolutionKind::Solved;
83718372
}
@@ -13106,15 +13107,12 @@ createImplicitRootForCallAsFunction(ConstraintSystem &cs, Type refType,
1310613107
}
1310713108

1310813109
ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
13109-
Type type1, Type type2,
13110+
FunctionType *func1, Type type2,
1311013111
std::optional<TrailingClosureMatching> trailingClosureMatching,
13112+
DeclContext *useDC,
1311113113
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
1311213114
auto &ctx = getASTContext();
1311313115

13114-
// By construction, the left hand side is a type that looks like the
13115-
// following: $T1 -> $T2.
13116-
auto func1 = type1->castTo<FunctionType>();
13117-
1311813116
// Before stripping lvalue-ness and optional types, save the original second
1311913117
// type for handling `func callAsFunction` and `@dynamicCallable`
1312013118
// applications. This supports the following cases:
@@ -13171,7 +13169,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1317113169
auto formUnsolved = [&](bool activate = false) {
1317213170
if (flags.contains(TMF_GenerateConstraints)) {
1317313171
auto *application = Constraint::createApplicableFunction(
13174-
*this, type1, type2, trailingClosureMatching,
13172+
*this, func1, type2, trailingClosureMatching, useDC,
1317513173
getConstraintLocator(locator));
1317613174

1317713175
addUnsolvedConstraint(application);
@@ -13201,7 +13199,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1320113199
// If the types are obviously equivalent, we're done. This optimization
1320213200
// is not valid for operators though, where an inout parameter does not
1320313201
// have an explicit inout argument.
13204-
if (type1.getPointer() == desugar2) {
13202+
if (func1 == desugar2) {
1320513203
// Note that this could throw.
1320613204
recordPotentialThrowSite(
1320713205
PotentialThrowSite::Application, Type(desugar2), outerLocator);
@@ -13232,8 +13230,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1323213230
/*outerAlternatives*/ {}, memberLoc);
1323313231
// Add new applicable function constraint based on the member type
1323413232
// variable.
13235-
addConstraint(ConstraintKind::ApplicableFunction, func1, memberTy,
13236-
locator);
13233+
addApplicationConstraint(func1, memberTy, trailingClosureMatching, useDC,
13234+
locator);
1323713235
return SolutionKind::Solved;
1323813236
}
1323913237

@@ -13348,9 +13346,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1334813346
// Form an unsolved constraint to apply trailing closures to a
1334913347
// callable type produced by `.init`. This constraint would become
1335013348
// active when `callableType` is bound.
13351-
addUnsolvedConstraint(Constraint::create(
13352-
*this, ConstraintKind::ApplicableFunction, callAsFunctionArguments,
13353-
callableType,
13349+
addUnsolvedConstraint(Constraint::createApplicableFunction(
13350+
*this, callAsFunctionArguments, callableType,
13351+
trailingClosureMatching, useDC,
1335413352
getConstraintLocator(implicitRef,
1335513353
ConstraintLocator::ApplyFunction)));
1335613354
break;
@@ -13368,12 +13366,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1336813366

1336913367
auto applyLocator = getConstraintLocator(locator);
1337013368
auto forwardConstraint = Constraint::createApplicableFunction(
13371-
*this, type1, type2, TrailingClosureMatching::Forward, applyLocator);
13369+
*this, func1, type2, TrailingClosureMatching::Forward, useDC,
13370+
applyLocator);
1337213371
auto backwardConstraint = Constraint::createApplicableFunction(
13373-
*this, type1, type2, TrailingClosureMatching::Backward,
13372+
*this, func1, type2, TrailingClosureMatching::Backward, useDC,
1337413373
applyLocator);
13375-
addDisjunctionConstraint(
13376-
{ forwardConstraint, backwardConstraint}, applyLocator);
13374+
addDisjunctionConstraint({forwardConstraint, backwardConstraint},
13375+
applyLocator);
1337713376
break;
1337813377
}
1337913378

@@ -13450,7 +13449,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1345013449
// Construct the instance from the input arguments.
1345113450
auto simplified = simplifyConstructionConstraint(
1345213451
instance2, func1, subflags,
13453-
/*FIXME?*/ DC, FunctionRefInfo::singleBaseNameApply(),
13452+
useDC, FunctionRefInfo::singleBaseNameApply(),
1345413453
getConstraintLocator(outerLocator));
1345513454

1345613455
// Record any fixes we attempted to get to the correct solution.
@@ -13469,7 +13468,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1346913468

1347013469
// Handle applications of @dynamicCallable types.
1347113470
auto result = simplifyDynamicCallableApplicableFnConstraint(
13472-
type1, origType2, subflags, locator);
13471+
func1, origType2, subflags, locator);
1347313472

1347413473
if (shouldAttemptFixes() && result == SolutionKind::Error) {
1347513474
// Skip this fix if the type is not yet resolved or
@@ -15673,15 +15672,6 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1567315672
case ConstraintKind::BridgingConversion:
1567415673
return simplifyBridgingConstraint(first, second, subflags, locator);
1567515674

15676-
case ConstraintKind::ApplicableFunction: {
15677-
// First try to simplify the overload set for the function being applied.
15678-
if (simplifyAppliedOverloads(second, first->castTo<FunctionType>(),
15679-
locator)) {
15680-
return SolutionKind::Error;
15681-
}
15682-
return simplifyApplicableFnConstraint(first, second, std::nullopt, subflags,
15683-
locator);
15684-
}
1568515675
case ConstraintKind::DynamicCallableApplicableFunction:
1568615676
return simplifyDynamicCallableApplicableFnConstraint(first, second,
1568715677
subflags, locator);
@@ -15762,6 +15752,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1576215752
case ConstraintKind::KeyPathApplication:
1576315753
case ConstraintKind::FallbackType:
1576415754
case ConstraintKind::SyntacticElement:
15755+
case ConstraintKind::ApplicableFunction:
1576515756
llvm_unreachable("Use the correct addConstraint()");
1576615757
}
1576715758

@@ -15990,6 +15981,41 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
1599015981
}
1599115982
}
1599215983

15984+
void ConstraintSystem::addApplicationConstraint(
15985+
FunctionType *appliedFn, Type calleeType,
15986+
std::optional<TrailingClosureMatching> trailingClosureMatching,
15987+
DeclContext *useDC,
15988+
ConstraintLocatorBuilder locator) {
15989+
auto recordFailure = [&]() {
15990+
if (shouldRecordFailedConstraint()) {
15991+
auto *c = Constraint::createApplicableFunction(
15992+
*this, appliedFn, calleeType, trailingClosureMatching, useDC,
15993+
getConstraintLocator(locator));
15994+
recordFailedConstraint(c);
15995+
}
15996+
};
15997+
15998+
// First try to simplify the overload set for the function being applied.
15999+
if (simplifyAppliedOverloads(calleeType, appliedFn, locator)) {
16000+
recordFailure();
16001+
return;
16002+
}
16003+
16004+
switch (simplifyApplicableFnConstraint(appliedFn, calleeType,
16005+
trailingClosureMatching, useDC,
16006+
TMF_GenerateConstraints, locator)) {
16007+
case SolutionKind::Error:
16008+
recordFailure();
16009+
break;
16010+
16011+
case SolutionKind::Unsolved:
16012+
llvm_unreachable("should have generated constraints");
16013+
16014+
case SolutionKind::Solved:
16015+
return;
16016+
}
16017+
}
16018+
1599316019
void ConstraintSystem::addContextualConversionConstraint(
1599416020
Expr *expr, Type conversionType, ContextualTypePurpose purpose,
1599516021
ConstraintLocator *locator) {
@@ -16174,8 +16200,9 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1617416200

1617516201
case ConstraintKind::ApplicableFunction:
1617616202
return simplifyApplicableFnConstraint(
16177-
constraint.getFirstType(), constraint.getSecondType(),
16178-
constraint.getTrailingClosureMatching(), std::nullopt,
16203+
constraint.getAppliedFunctionType(), constraint.getCalleeType(),
16204+
constraint.getTrailingClosureMatching(),
16205+
constraint.getApplicationDC(), /*flags=*/std::nullopt,
1617916206
constraint.getLocator());
1618016207

1618116208
case ConstraintKind::DynamicCallableApplicableFunction:

0 commit comments

Comments
 (0)