Skip to content

Commit 0844f54

Browse files
committed
[Type checker] Correctly resolve locators for ".foo" to static/class functions.
When resolving a particular locator for a ".foo" expression that references a static/class function, make sure we pass through the proper locator. Otherwise, when that ".foo" is somehow generic, we won't be able to find the opened type and, therefore, will crash when trying to form the substitution. While I'm here, simplify the "default arguments owner" computation logic to simply retrieve the callee declaration, which is useful for more than just default arguments.
1 parent e086b7d commit 0844f54

File tree

2 files changed

+31
-63
lines changed

2 files changed

+31
-63
lines changed

lib/Sema/CSApply.cpp

Lines changed: 20 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,7 +3690,9 @@ static ConcreteDeclRef
36903690
resolveLocatorToDecl(ConstraintSystem &cs, ConstraintLocator *locator,
36913691
std::function<Optional<SelectedOverload>(ConstraintLocator *)> findOvlChoice,
36923692
std::function<ConcreteDeclRef (ValueDecl *decl,
3693-
Type openedType)> getConcreteDeclRef)
3693+
Type openedType,
3694+
ConstraintLocator *declLocator)>
3695+
getConcreteDeclRef)
36943696
{
36953697
assert(locator && "Null locator");
36963698
if (!locator->getAnchor())
@@ -3755,7 +3757,8 @@ resolveLocatorToDecl(ConstraintSystem &cs, ConstraintLocator *locator,
37553757
if (auto selected = findOvlChoice(anchorLocator)) {
37563758
if (selected->choice.isDecl())
37573759
return getConcreteDeclRef(selected->choice.getDecl(),
3758-
selected->openedType);
3760+
selected->openedType,
3761+
anchorLocator);
37593762
}
37603763
}
37613764

@@ -3766,7 +3769,8 @@ resolveLocatorToDecl(ConstraintSystem &cs, ConstraintLocator *locator,
37663769
if (auto selected = findOvlChoice(anchorLocator)) {
37673770
if (selected->choice.isDecl())
37683771
return getConcreteDeclRef(selected->choice.getDecl(),
3769-
selected->openedType);
3772+
selected->openedType,
3773+
anchorLocator);
37703774
}
37713775
}
37723776

@@ -3832,8 +3836,8 @@ findDefaultArgsOwner(ConstraintSystem &cs, const Solution &solution,
38323836

38333837
return known->second;
38343838
},
3835-
[&](ValueDecl *decl,
3836-
Type openedType) -> ConcreteDeclRef {
3839+
[&](ValueDecl *decl, Type openedType, ConstraintLocator *locator)
3840+
-> ConcreteDeclRef {
38373841
if (decl->getInnermostDeclContext()->isGenericContext()) {
38383842
SmallVector<Substitution, 4> subs;
38393843
solution.computeSubstitutions(
@@ -4039,41 +4043,25 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple,
40394043
SmallVector<TupleTypeElt, 4> fromTupleExprFields(
40404044
fromTuple->getElements().size());
40414045
SmallVector<Expr *, 2> callerDefaultArgs;
4042-
ConcreteDeclRef defaultArgsOwner;
4046+
ConcreteDeclRef defaultArgsOwner =
4047+
findDefaultArgsOwner(cs, solution, cs.getConstraintLocator(locator));
40434048

40444049
for (unsigned i = 0, n = toTuple->getNumElements(); i != n; ++i) {
40454050
const auto &toElt = toTuple->getElement(i);
40464051
auto toEltType = toElt.getType();
40474052

40484053
// If we're default-initializing this member, there's nothing to do.
40494054
if (sources[i] == TupleShuffleExpr::DefaultInitialize) {
4050-
// Dig out the owner of the default arguments.
4051-
ConcreteDeclRef argOwner;
4052-
if (!defaultArgsOwner) {
4053-
argOwner
4054-
= findDefaultArgsOwner(cs, solution,
4055-
cs.getConstraintLocator(locator));
4056-
assert(argOwner && "Missing default arguments owner?");
4057-
} else {
4058-
argOwner = defaultArgsOwner;
4059-
}
4060-
40614055
anythingShuffled = true;
40624056
hasInits = true;
40634057
toSugarFields.push_back(toElt);
40644058

40654059
// Create a caller-side default argument, if we need one.
40664060
if (auto defArg = getCallerDefaultArg(tc, dc, expr->getLoc(),
4067-
argOwner, i).first) {
4061+
defaultArgsOwner, i).first) {
40684062
callerDefaultArgs.push_back(defArg);
40694063
sources[i] = TupleShuffleExpr::CallerDefaultInitialize;
40704064
}
4071-
if (!defaultArgsOwner) {
4072-
defaultArgsOwner = argOwner;
4073-
} else {
4074-
assert(defaultArgsOwner == argOwner &&
4075-
"default args on same func have different owners");
4076-
}
40774065
continue;
40784066
}
40794067

@@ -4311,7 +4299,9 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple,
43114299
SmallVector<int, 4> elements;
43124300
SmallVector<unsigned, 1> variadicArgs;
43134301
SmallVector<Expr*, 4> callerDefaultArgs;
4314-
ConcreteDeclRef defaultArgsOwner = nullptr;
4302+
ConcreteDeclRef defaultArgsOwner =
4303+
findDefaultArgsOwner(cs, solution, cs.getConstraintLocator(locator));
4304+
43154305
i = 0;
43164306
for (auto &field : toTuple->getElements()) {
43174307
if (field.isVararg()) {
@@ -4332,20 +4322,9 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple,
43324322

43334323
assert(field.hasDefaultArg() && "Expected a default argument");
43344324

4335-
ConcreteDeclRef argOwner;
4336-
// Dig out the owner of the default arguments.
4337-
if (!defaultArgsOwner) {
4338-
argOwner
4339-
= findDefaultArgsOwner(cs, solution,
4340-
cs.getConstraintLocator(locator));
4341-
assert(argOwner && "Missing default arguments owner?");
4342-
} else {
4343-
argOwner = defaultArgsOwner;
4344-
}
4345-
43464325
// Create a caller-side default argument, if we need one.
43474326
if (auto defArg = getCallerDefaultArg(tc, dc, expr->getLoc(),
4348-
argOwner, i).first) {
4327+
defaultArgsOwner, i).first) {
43494328
// Record the caller-side default argument expression.
43504329
// FIXME: Do we need to record what this was synthesized from?
43514330
elements.push_back(TupleShuffleExpr::CallerDefaultInitialize);
@@ -4354,13 +4333,6 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple,
43544333
// Record the owner of the default argument.
43554334
elements.push_back(TupleShuffleExpr::DefaultInitialize);
43564335
}
4357-
if (!defaultArgsOwner) {
4358-
defaultArgsOwner = argOwner;
4359-
} else {
4360-
assert(defaultArgsOwner == argOwner &&
4361-
"default args on same func have different owners");
4362-
}
4363-
43644336
++i;
43654337
}
43664338

@@ -4642,7 +4614,8 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, Type paramType,
46424614
SmallVector<Expr*, 4> fromTupleExpr(argTuple? argTuple->getNumElements() : 1);
46434615
SmallVector<unsigned, 4> variadicArgs;
46444616
SmallVector<Expr *, 2> callerDefaultArgs;
4645-
ConcreteDeclRef defaultArgsOwner = nullptr;
4617+
ConcreteDeclRef defaultArgsOwner =
4618+
findDefaultArgsOwner(cs, solution, cs.getConstraintLocator(locator));
46464619
Type sliceType = nullptr;
46474620
SmallVector<int, 4> sources;
46484621
for (unsigned paramIdx = 0, numParams = parameterBindings.size();
@@ -4696,22 +4669,12 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, Type paramType,
46964669

46974670
// If we are using a default argument, handle it now.
46984671
if (parameterBindings[paramIdx].empty()) {
4699-
// Dig out the owner of the default arguments.
4700-
ConcreteDeclRef argOwner;
4701-
if (!defaultArgsOwner) {
4702-
argOwner
4703-
= findDefaultArgsOwner(cs, solution,
4704-
cs.getConstraintLocator(locator));
4705-
assert(argOwner && "Missing default arguments owner?");
4706-
} else {
4707-
argOwner = defaultArgsOwner;
4708-
}
4709-
47104672
// Create a caller-side default argument, if we need one.
47114673
Expr *defArg;
47124674
DefaultArgumentKind defArgKind;
47134675
std::tie(defArg, defArgKind) = getCallerDefaultArg(tc, dc, arg->getLoc(),
4714-
argOwner, paramIdx);
4676+
defaultArgsOwner,
4677+
paramIdx);
47154678

47164679
// Note that we'll be doing a shuffle involving default arguments.
47174680
anythingShuffled = true;
@@ -4730,12 +4693,6 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, Type paramType,
47304693
} else {
47314694
sources.push_back(TupleShuffleExpr::DefaultInitialize);
47324695
}
4733-
if (!defaultArgsOwner) {
4734-
defaultArgsOwner = argOwner;
4735-
} else {
4736-
assert(defaultArgsOwner == argOwner &&
4737-
"default args on same func have different owners");
4738-
}
47394696
continue;
47404697
}
47414698

test/decl/func/default-values.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,14 @@ foo2([].bar { $0 == "c" }!)
111111
// rdar://problem/21643052
112112
let a = ["1", "2"].map { Int($0) }
113113

114+
// Default arguments for static members used via ".foo"
115+
struct X<T> {
116+
static func foo(i: Int, j: Int = 0) -> X {
117+
return X()
118+
}
119+
120+
static var bar: X { return X() }
121+
}
122+
123+
let testXa: X<Int> = .foo(i: 0)
124+
let testXb: X<Int> = .bar

0 commit comments

Comments
 (0)