Skip to content

Commit 0b264e2

Browse files
committed
[Effects] Keep track of whether we looked through a 'self' application
When we look through a "self" application while decomposing a function call in effects checking, keep track of whether we did so. Use this to ensure that we get the right parameter types when looking at the "self" application vs. the outer call. This has always been wrong, but the async/throws effects don't ever matter for the innermost application (i.e., for `x.m`), so the inconsistency didn't come up.
1 parent ee6decc commit 0b264e2

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,18 +335,21 @@ class AbstractFunction {
335335
PolymorphicEffectKind RethrowsKind = PolymorphicEffectKind::None;
336336
PolymorphicEffectKind ReasyncKind = PolymorphicEffectKind::None;
337337
SubstitutionMap Substitutions;
338+
bool AppliedSelf = false;
338339

339340
public:
340341
explicit AbstractFunction(Kind kind, Expr *fn)
341342
: TheKind(kind) {
342343
TheExpr = fn;
343344
}
344345

345-
explicit AbstractFunction(AbstractFunctionDecl *fn, SubstitutionMap subs)
346+
explicit AbstractFunction(AbstractFunctionDecl *fn, SubstitutionMap subs,
347+
bool appliedSelf)
346348
: TheKind(Kind::Function),
347349
RethrowsKind(fn->getPolymorphicEffectKind(EffectKind::Throws)),
348350
ReasyncKind(fn->getPolymorphicEffectKind(EffectKind::Async)),
349-
Substitutions(subs) {
351+
Substitutions(subs),
352+
AppliedSelf(appliedSelf) {
350353
TheFunction = fn;
351354
}
352355

@@ -377,7 +380,7 @@ class AbstractFunction {
377380
case Kind::Opaque: return getOpaqueFunction()->getType();
378381
case Kind::Function: {
379382
auto *AFD = getFunction();
380-
if (AFD->hasImplicitSelfDecl())
383+
if (AFD->hasImplicitSelfDecl() && AppliedSelf)
381384
return AFD->getMethodInterfaceType();
382385
return AFD->getInterfaceType();
383386
}
@@ -398,6 +401,11 @@ class AbstractFunction {
398401
.getParameterType();
399402

400403
case Kind::Function: {
404+
if (getFunction()->hasImplicitSelfDecl() && !AppliedSelf) {
405+
assert(substIndex == 0);
406+
return getFunction()->getImplicitSelfDecl()->getInterfaceType();
407+
}
408+
401409
auto *params = getFunction()->getParameters();
402410
auto origIndex = params->getOrigParamIndex(getSubstitutions(), substIndex);
403411
return params->get(origIndex)->getInterfaceType();
@@ -435,10 +443,13 @@ class AbstractFunction {
435443
static AbstractFunction getAppliedFn(ApplyExpr *apply) {
436444
Expr *fn = apply->getFn()->getValueProvidingExpr();
437445

438-
if (auto *selfCall = dyn_cast<SelfApplyExpr>(fn))
446+
bool appliedSelf = false;
447+
if (auto *selfCall = dyn_cast<SelfApplyExpr>(fn)) {
439448
fn = selfCall->getFn()->getValueProvidingExpr();
449+
appliedSelf = true;
450+
}
440451

441-
return decomposeFunction(fn);
452+
return decomposeFunction(fn, appliedSelf);
442453
}
443454

444455
bool isPreconcurrency() const {
@@ -457,7 +468,7 @@ class AbstractFunction {
457468
}
458469
}
459470

460-
static AbstractFunction decomposeFunction(Expr *fn) {
471+
static AbstractFunction decomposeFunction(Expr *fn, bool appliedSelf) {
461472
assert(fn->getValueProvidingExpr() == fn);
462473

463474
while (true) {
@@ -493,14 +504,16 @@ class AbstractFunction {
493504
// Constructor delegation.
494505
if (auto otherCtorDeclRef = dyn_cast<OtherConstructorDeclRefExpr>(fn)) {
495506
return AbstractFunction(otherCtorDeclRef->getDecl(),
496-
otherCtorDeclRef->getDeclRef().getSubstitutions());
507+
otherCtorDeclRef->getDeclRef().getSubstitutions(),
508+
appliedSelf);
497509
}
498510

499511
// Normal function references.
500512
if (auto DRE = dyn_cast<DeclRefExpr>(fn)) {
501513
ValueDecl *decl = DRE->getDecl();
502514
if (auto fn = dyn_cast<AbstractFunctionDecl>(decl)) {
503-
return AbstractFunction(fn, DRE->getDeclRef().getSubstitutions());
515+
return AbstractFunction(fn, DRE->getDeclRef().getSubstitutions(),
516+
appliedSelf);
504517
} else if (auto param = dyn_cast<ParamDecl>(decl)) {
505518
SubstitutionMap subs;
506519
if (auto genericEnv = param->getDeclContext()->getGenericEnvironmentOfContext())
@@ -2541,7 +2554,8 @@ class ApplyClassifier {
25412554

25422555
// Decompose the function reference, then consider the type
25432556
// of the decomposed function.
2544-
AbstractFunction fn = AbstractFunction::decomposeFunction(arg);
2557+
AbstractFunction fn = AbstractFunction::decomposeFunction(
2558+
arg, /*appliedSelf=*/false);
25452559

25462560
// If it doesn't have function type, we must have invalid code.
25472561
Type argType = fn.getType();

0 commit comments

Comments
 (0)