Skip to content

Commit 0f8b42a

Browse files
authored
Merge pull request #61609 from slavapestov/fix-rdar101098777
Sema: Fix opening an existential argument to a 'try self.init()' delegation
2 parents 6a09b8e + fff224e commit 0f8b42a

File tree

4 files changed

+42
-36
lines changed

4 files changed

+42
-36
lines changed

lib/AST/Expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,13 @@ RebindSelfInConstructorExpr::getCalledConstructor(bool &isChainToSuper) const {
17831783
candidate = injectIntoOptionalExpr->getSubExpr();
17841784
continue;
17851785
}
1786+
1787+
// Look through open existential expressions
1788+
if (auto openExistentialExpr
1789+
= dyn_cast<OpenExistentialExpr>(candidate)) {
1790+
candidate = openExistentialExpr->getSubExpr();
1791+
continue;
1792+
}
17861793
break;
17871794
}
17881795

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,6 @@ namespace {
726726
return inout->getSubExpr();
727727
} else if (auto force = dyn_cast<ForceValueExpr>(expr)) {
728728
return force->getSubExpr();
729-
} else if (auto rebind = dyn_cast<RebindSelfInConstructorExpr>(expr)) {
730-
return rebind->getSubExpr();
731729
} else {
732730
return nullptr;
733731
}
@@ -819,6 +817,11 @@ namespace {
819817
unsigned maxArgCount = member->getNumCurryLevels();
820818
unsigned depth = ExprStack.size() - getArgCount(maxArgCount);
821819

820+
// Invalid case -- direct call of a metatype. Has one less argument
821+
// application because there's no ".init".
822+
if (isa<ApplyExpr>(ExprStack.back()))
823+
depth++;
824+
822825
// Create the opaque opened value. If we started with a
823826
// metatype, it's a metatype.
824827
Type opaqueType = archetype;
@@ -3900,12 +3903,7 @@ namespace {
39003903
expr->setSubExpr(newSubExpr);
39013904
}
39023905

3903-
// We might have opened existentials in the argument list of the
3904-
// constructor call.
3905-
Expr *result = expr;
3906-
closeExistentials(result, cs.getConstraintLocator(expr));
3907-
3908-
return result;
3906+
return expr;
39093907
}
39103908

39113909
Expr *visitTernaryExpr(TernaryExpr *expr) {

lib/Sema/MiscDiagnostics.cpp

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,14 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
108108
SmallPtrSet<DeclRefExpr*, 4> AlreadyDiagnosedBitCasts;
109109

110110
bool IsExprStmt;
111-
unsigned ExprNestingDepth;
112111
bool HasReachedSemanticsProvidingExpr;
113112

114113
ASTContext &Ctx;
115114
const DeclContext *DC;
116115

117116
public:
118117
DiagnoseWalker(const DeclContext *DC, bool isExprStmt)
119-
: IsExprStmt(isExprStmt), ExprNestingDepth(0),
120-
HasReachedSemanticsProvidingExpr(false),
118+
: IsExprStmt(isExprStmt), HasReachedSemanticsProvidingExpr(false),
121119
Ctx(DC->getASTContext()), DC(DC) {}
122120

123121
PreWalkResult<Pattern *> walkToPatternPre(Pattern *P) override {
@@ -133,11 +131,6 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
133131
bool shouldWalkIntoTapExpression() override { return false; }
134132

135133
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
136-
if (isa<OpenExistentialExpr>(E)) {
137-
// Don't increase ExprNestingDepth.
138-
return Action::Continue(E);
139-
}
140-
141134
if (auto collection = dyn_cast<CollectionExpr>(E)) {
142135
if (collection->isTypeDefaulted()) {
143136
// Diagnose type defaulted collection literals in subexpressions as
@@ -282,11 +275,9 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
282275
}
283276

284277
// Diagnose 'self.init' or 'super.init' nested in another expression
285-
// or closure. The ExprNestingDepth thing is to allow this to be nested
286-
// inside of an OpenExistentialExpr that is at the top level.
278+
// or closure.
287279
if (auto *rebindSelfExpr = dyn_cast<RebindSelfInConstructorExpr>(E)) {
288-
if (ExprNestingDepth > 0 || !IsExprStmt ||
289-
DC->getParent()->isLocalContext()) {
280+
if (!Parent.isNull() || !IsExprStmt || DC->getParent()->isLocalContext()) {
290281
bool isChainToSuper;
291282
(void)rebindSelfExpr->getCalledConstructor(isChainToSuper);
292283
Ctx.Diags.diagnose(E->getLoc(), diag::init_delegation_nested,
@@ -357,17 +348,10 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
357348
HasReachedSemanticsProvidingExpr = true;
358349
}
359350

360-
++ExprNestingDepth;
361-
362351
return Action::Continue(E);
363352
}
364353

365354
PostWalkResult<Expr *> walkToExprPost(Expr *E) override {
366-
if (isa<OpenExistentialExpr>(E))
367-
return Action::Continue(E);
368-
369-
assert(ExprNestingDepth != 0);
370-
--ExprNestingDepth;
371355
return Action::Continue(E);
372356
}
373357

@@ -1525,7 +1509,6 @@ static void diagRecursivePropertyAccess(const Expr *E, const DeclContext *DC) {
15251509
};
15261510

15271511
DiagnoseWalker walker(var, fn);
1528-
15291512
const_cast<Expr *>(E)->walk(walker);
15301513
}
15311514

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen %s -disable-availability-checking
22

33
protocol P {}
44
class C {
@@ -7,10 +7,28 @@ class C {
77
convenience init(y: any P) { self.init(x: y) }
88
}
99

10-
// CHECK-LABEL: sil hidden [ossa] @$s37opened_existential_in_init_delegation1CC1yAcA1P_p_tcfC : $@convention(method) (@in any P, @thick C.Type) -> @owned C {
11-
// CHECK: [[OPENED:%.*]] = open_existential_addr immutable_access %0 : $*any P to $*@opened("{{.*}}", any P) Self
12-
// CHECK: [[COPIED:%.*]] = alloc_stack $@opened("{{.*}}", any P) Self
13-
// CHECK: copy_addr [[OPENED]] to [initialization] [[COPIED]] : $*@opened("{{.*}}", any P) Self
14-
// CHECK: [[FN:%.*]] = class_method %1 : $@thick C.Type, #C.init!allocator : (C.Type) -> (some P) -> C, $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @thick C.Type) -> @owned C
15-
// CHECK: apply [[FN]]<@opened("{{.*}}", any P) Self>([[COPIED]], %1) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @thick C.Type) -> @owned C
16-
// CHECK: dealloc_stack [[COPIED]] : $*@opened("{{.*}}", any P) Self
10+
enum E {
11+
init(p: some P, throwing: ()) throws {}
12+
init(p: some P, async: ()) async {}
13+
init?(p: some P, failable: ()) {}
14+
15+
init(p: any P, withTry: ()) throws {
16+
try self.init(p: p, throwing: ())
17+
}
18+
19+
init(p: any P, withForceTry: ()) {
20+
try! self.init(p: p, throwing: ())
21+
}
22+
23+
init(p: any P, withAwait: ()) async {
24+
await self.init(p: p, async: ())
25+
}
26+
27+
init?(p: any P, withFailable: ()) {
28+
self.init(p: p, failable: ())
29+
}
30+
31+
init(p: any P, withForce: ()) {
32+
self.init(p: p, failable: ())!
33+
}
34+
}

0 commit comments

Comments
 (0)