Skip to content

Commit 356b3b4

Browse files
committed
[Sema] Don't assume member refs have base types
- Add a precondition on `doesDeclRefApplyCurriedSelf` to expect a member decl, and rename it to make the precondition explicit. - Don't assume that not having a base type means this isn't a member reference, as member references to static operators don't have base types. Resolves SR-10843.
1 parent 623a6ad commit 356b3b4

File tree

4 files changed

+28
-13
lines changed

4 files changed

+28
-13
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,18 @@ static Optional<unsigned> scoreParamAndArgNameTypo(StringRef paramName,
100100
return dist;
101101
}
102102

103-
bool constraints::doesDeclRefApplyCurriedSelf(Type baseTy,
104-
const ValueDecl *decl) {
105-
// If this isn't a member reference, there's nothing to apply.
106-
if (!baseTy || baseTy->is<ModuleType>())
107-
return false;
103+
bool constraints::doesMemberRefApplyCurriedSelf(Type baseTy,
104+
const ValueDecl *decl) {
105+
assert(decl->getDeclContext()->isTypeContext() &&
106+
"Expected a member reference");
108107

109108
// For a reference to an instance method on a metatype, we want to keep the
110109
// curried self.
111-
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl))
112-
if (afd->isInstanceMember() && baseTy->is<AnyMetatypeType>())
110+
if (decl->isInstanceMember()) {
111+
assert(baseTy);
112+
if (isa<AbstractFunctionDecl>(decl) && baseTy->is<AnyMetatypeType>())
113113
return false;
114+
}
114115

115116
// Otherwise the reference applies self.
116117
return true;
@@ -157,7 +158,7 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
157158
// the member lookup applying the curried self at the first level. But there
158159
// are cases where we can get an unapplied declaration reference back.
159160
auto hasAppliedSelf =
160-
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
161+
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
161162

162163
auto *fnType = decl->getInterfaceType()->castTo<AnyFunctionType>();
163164
if (hasAppliedSelf) {
@@ -860,7 +861,7 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
860861
// In most cases where we reference a declaration with a curried self
861862
// parameter, it gets dropped from the type of the reference.
862863
bool hasAppliedSelf =
863-
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
864+
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
864865
return std::make_tuple(decl, hasAppliedSelf, argLabels, hasTrailingClosure);
865866
}
866867

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ ConstraintSystem::getTypeOfMemberReference(
12221222

12231223
// Check to see if the self parameter is applied, in which case we'll want to
12241224
// strip it off later.
1225-
auto hasAppliedSelf = doesDeclRefApplyCurriedSelf(baseObjTy, value);
1225+
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseObjTy, value);
12261226

12271227
baseObjTy = baseObjTy->getMetatypeInstanceType();
12281228
FunctionType::Param baseObjParam(baseObjTy);

lib/Sema/ConstraintSystem.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3738,13 +3738,13 @@ matchCallArguments(ConstraintSystem &cs,
37383738
/// subscript, etc.), find the underlying target expression.
37393739
Expr *getArgumentLabelTargetExpr(Expr *fn);
37403740

3741-
/// Returns true if a reference to a declaration on a given base type will
3742-
/// apply its curried self parameter, assuming it has one.
3741+
/// Returns true if a reference to a member on a given base type will apply its
3742+
/// curried self parameter, assuming it has one.
37433743
///
37443744
/// This is true for most member references, however isn't true for things like
37453745
/// an instance member being referenced on a metatype, where the curried self
37463746
/// parameter remains unapplied.
3747-
bool doesDeclRefApplyCurriedSelf(Type baseTy, const ValueDecl *decl);
3747+
bool doesMemberRefApplyCurriedSelf(Type baseTy, const ValueDecl *decl);
37483748

37493749
/// Attempt to prove that arguments with the given labels at the
37503750
/// given parameter depth cannot be used with the given value.

test/Constraints/operator.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,17 @@ func rdar46459603() {
223223
_ = [arr.values] == [[e]]
224224
// expected-error@-1 {{protocol type 'Any' cannot conform to 'Equatable' because only concrete types can conform to protocols}}
225225
}
226+
227+
// SR-10843
228+
infix operator ^^^
229+
func ^^^ (lhs: String, rhs: String) {}
230+
231+
struct SR10843 {
232+
static func ^^^ (lhs: SR10843, rhs: SR10843) {}
233+
}
234+
235+
func sr10843() {
236+
let s = SR10843()
237+
(^^^)(s, s)
238+
_ = (==)(0, 0)
239+
}

0 commit comments

Comments
 (0)