Skip to content

Commit b978713

Browse files
authored
Revert "Allow implicit self in escaping closures when self usage is unlikely to cause cycle (#23934)"
This reverts commit 71697c3.
1 parent 4062012 commit b978713

22 files changed

+193
-720
lines changed

include/swift/AST/ASTScope.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,6 @@ class ASTScopeImpl {
479479
/// asked.
480480
virtual Optional<NullablePtr<DeclContext>> computeSelfDCForParent() const;
481481

482-
/// Returns the context that should be used when a nested scope (e.g. a
483-
/// closure) captures self explicitly.
484-
virtual NullablePtr<DeclContext> capturedSelfDC() const;
485-
486482
protected:
487483
/// Find either locals or members (no scope has both)
488484
/// \param history The scopes visited since the start of lookup (including
@@ -696,15 +692,6 @@ class Portion {
696692
/// to compute the selfDC from the history.
697693
static NullablePtr<DeclContext>
698694
computeSelfDC(ArrayRef<const ASTScopeImpl *> history);
699-
700-
/// If we find a lookup result that requires the dynamic implict self value,
701-
/// we need to check the nested scopes to see if any closures explicitly
702-
/// captured \c self. In that case, the appropriate selfDC is that of the
703-
/// innermost closure which captures a \c self value from one of this type's
704-
/// methods.
705-
static NullablePtr<DeclContext>
706-
checkNestedScopesForSelfCapture(ArrayRef<const ASTScopeImpl *> history,
707-
size_t start);
708695
};
709696

710697
/// Behavior specific to representing the trailing where clause of a
@@ -1462,13 +1449,6 @@ class ClosureParametersScope final : public AbstractClosureScope {
14621449
std::string getClassName() const override;
14631450
SourceRange
14641451
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1465-
1466-
/// Since explicit captures of \c self by closures enable the use of implicit
1467-
/// \c self, we need to make sure that the appropriate \c self is used as the
1468-
/// base decl for these uses (otherwise, the capture would be marked as
1469-
/// unused. \c ClosureParametersScope::capturedSelfDC() checks if we have such
1470-
/// a capture of self.
1471-
NullablePtr<DeclContext> capturedSelfDC() const override;
14721452

14731453
protected:
14741454
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;

include/swift/AST/Decl.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,15 +334,12 @@ class alignas(1 << DeclAlignInBits) Decl {
334334
IsStatic : 1
335335
);
336336

337-
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+1+1+1+1+1+1,
337+
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+1+1+1+1+1,
338338
/// Encodes whether this is a 'let' binding.
339339
Introducer : 1,
340340

341341
/// Whether this declaration was an element of a capture list.
342342
IsCaptureList : 1,
343-
344-
/// Whether this declaration captures the 'self' param under the same name.
345-
IsSelfParamCapture : 1,
346343

347344
/// Whether this vardecl has an initial value bound to it in a way
348345
/// that isn't represented in the AST with an initializer in the pattern
@@ -5029,12 +5026,6 @@ class VarDecl : public AbstractStorageDecl {
50295026

50305027
/// Is this an element in a capture list?
50315028
bool isCaptureList() const { return Bits.VarDecl.IsCaptureList; }
5032-
5033-
/// Is this a capture of the self param?
5034-
bool isSelfParamCapture() const { return Bits.VarDecl.IsSelfParamCapture; }
5035-
void setIsSelfParamCapture(bool IsSelfParamCapture = true) {
5036-
Bits.VarDecl.IsSelfParamCapture = IsSelfParamCapture;
5037-
}
50385029

50395030
/// Return true if this vardecl has an initial value bound to it in a way
50405031
/// that isn't represented in the AST with an initializer in the pattern

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3244,20 +3244,11 @@ ERROR(self_assignment_var,none,
32443244
ERROR(self_assignment_prop,none,
32453245
"assigning a property to itself", ())
32463246
ERROR(property_use_in_closure_without_explicit_self,none,
3247-
"reference to property %0 in closure requires explicit use of 'self' to"
3248-
" make capture semantics explicit", (Identifier))
3247+
"reference to property %0 in closure requires explicit 'self.' to make"
3248+
" capture semantics explicit", (Identifier))
32493249
ERROR(method_call_in_closure_without_explicit_self,none,
3250-
"call to method %0 in closure requires explicit use of 'self' to make"
3250+
"call to method %0 in closure requires explicit 'self.' to make"
32513251
" capture semantics explicit", (Identifier))
3252-
NOTE(note_capture_self_explicitly,none,
3253-
"capture 'self' explicitly to enable implicit 'self' in this closure", ())
3254-
NOTE(note_reference_self_explicitly,none,
3255-
"reference 'self.' explicitly", ())
3256-
NOTE(note_other_self_capture,none,
3257-
"variable other than 'self' captured here under the name 'self' does not "
3258-
"enable implicit 'self'", ())
3259-
NOTE(note_self_captured_weakly,none,
3260-
"weak capture of 'self' here does not enable implicit 'self'", ())
32613252
ERROR(implicit_use_of_self_in_closure,none,
32623253
"implicit use of 'self' in closure; use 'self.' to make"
32633254
" capture semantics explicit", ())

include/swift/AST/Expr.h

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ namespace swift {
6565
class EnumElementDecl;
6666
class CallExpr;
6767
class KeyPathExpr;
68-
class CaptureListExpr;
6968

7069
enum class ExprKind : uint8_t {
7170
#define EXPR(Id, Parent) Id,
@@ -3589,18 +3588,6 @@ class SerializedAbstractClosureExpr : public SerializedLocalDeclContext {
35893588
/// \endcode
35903589
class ClosureExpr : public AbstractClosureExpr {
35913590

3592-
/// The range of the brackets of the capture list, if present.
3593-
SourceRange BracketRange;
3594-
3595-
/// The (possibly null) VarDecl captured by this closure with the literal name
3596-
/// "self". In order to recover this information at the time of name lookup,
3597-
/// we must be able to access it from the associated DeclContext.
3598-
/// Because the DeclContext inside a closure is the closure itself (and not
3599-
/// the CaptureListExpr which would normally maintain this sort of
3600-
/// information about captured variables), we need to have some way to access
3601-
/// this information directly on the ClosureExpr.
3602-
VarDecl *CapturedSelfDecl;
3603-
36043591
/// The location of the "throws", if present.
36053592
SourceLoc ThrowsLoc;
36063593

@@ -3617,16 +3604,16 @@ class ClosureExpr : public AbstractClosureExpr {
36173604
/// The body of the closure, along with a bit indicating whether it
36183605
/// was originally just a single expression.
36193606
llvm::PointerIntPair<BraceStmt *, 1, bool> Body;
3607+
36203608
public:
3621-
ClosureExpr(SourceRange bracketRange, VarDecl *capturedSelfDecl,
3622-
ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
3609+
ClosureExpr(ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
36233610
SourceLoc inLoc, TypeLoc explicitResultType,
36243611
unsigned discriminator, DeclContext *parent)
36253612
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
36263613
discriminator, parent),
3627-
BracketRange(bracketRange), CapturedSelfDecl(capturedSelfDecl),
36283614
ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
3629-
ExplicitResultType(explicitResultType), Body(nullptr) {
3615+
ExplicitResultType(explicitResultType),
3616+
Body(nullptr) {
36303617
setParameterList(params);
36313618
Bits.ClosureExpr.HasAnonymousClosureVars = false;
36323619
}
@@ -3658,8 +3645,6 @@ class ClosureExpr : public AbstractClosureExpr {
36583645
/// explicitly-specified result type.
36593646
bool hasExplicitResultType() const { return ArrowLoc.isValid(); }
36603647

3661-
/// Retrieve the range of the \c '[' and \c ']' that enclose the capture list.
3662-
SourceRange getBracketRange() const { return BracketRange; }
36633648

36643649
/// Retrieve the location of the \c '->' for closures with an
36653650
/// explicit result type.
@@ -3725,14 +3710,6 @@ class ClosureExpr : public AbstractClosureExpr {
37253710
/// Is this a completely empty closure?
37263711
bool hasEmptyBody() const;
37273712

3728-
/// VarDecl captured by this closure under the literal name \c self , if any.
3729-
VarDecl *getCapturedSelfDecl() const { return CapturedSelfDecl; }
3730-
3731-
/// Whether this closure captures the \c self param in its body in such a
3732-
/// way that implicit \c self is enabled within its body (i.e. \c self is
3733-
/// captured non-weakly).
3734-
bool capturesSelfEnablingImplictSelf() const;
3735-
37363713
static bool classof(const Expr *E) {
37373714
return E->getKind() == ExprKind::Closure;
37383715
}
@@ -3817,8 +3794,6 @@ struct CaptureListEntry {
38173794
CaptureListEntry(VarDecl *Var, PatternBindingDecl *Init)
38183795
: Var(Var), Init(Init) {
38193796
}
3820-
3821-
bool isSimpleSelfCapture() const;
38223797
};
38233798

38243799
/// CaptureListExpr - This expression represents the capture list on an explicit

include/swift/AST/NameLookup.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,13 @@ struct LookupResultEntry {
7070
/// When finding \c bar() from the function body of \c foo(), \c BaseDC is
7171
/// the method \c foo().
7272
///
73-
/// \c BaseDC will be the type if \c self is not needed for the lookup. If
74-
/// \c self is needed, \c baseDC will be either the method or a closure
75-
/// which explicitly captured \c self.
76-
/// In other words: If \c baseDC is a method or a closure, it means you
77-
/// found an instance member and you should add an implicit 'self.' (Each
78-
/// method has its own implicit self decl.) There's one other kind of
79-
/// non-method, non-closure context that has a 'self.' -- a lazy property
80-
/// initializer, which unlike a non-lazy property can reference \c self.
81-
/// \code
73+
/// \c BaseDC will be the method if \c self is needed for the lookup,
74+
/// and will be the type if not.
75+
/// In other words: If \c baseDC is a method, it means you found an instance
76+
/// member and you should add an implicit 'self.' (Each method has its own
77+
/// implicit self decl.) There's one other kind of non-method context that
78+
/// has a 'self.' -- a lazy property initializer, which unlike a non-lazy
79+
/// property can reference \c self) Hence: \code
8280
/// class Outer {
8381
///   static func s()
8482
///   func i()

include/swift/Parse/Lexer.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -293,17 +293,7 @@ class Lexer {
293293
/// resides.
294294
///
295295
/// \param Loc The source location of the beginning of a token.
296-
///
297-
/// \param CRM How comments should be treated by the lexer. Default is to
298-
/// return the comments as tokens. This is needed in situations where
299-
/// detecting the next semantically meaningful token is required, such as
300-
/// the 'implicit self' diagnostic determining whether a capture list is
301-
/// empty (i.e., the opening bracket is immediately followed by a closing
302-
/// bracket, possibly with comments in between) in order to insert the
303-
/// appropriate fix-it.
304-
static Token getTokenAtLocation(
305-
const SourceManager &SM, SourceLoc Loc,
306-
CommentRetentionMode CRM = CommentRetentionMode::ReturnAsTokens);
296+
static Token getTokenAtLocation(const SourceManager &SM, SourceLoc Loc);
307297

308298

309299
/// Retrieve the source location that points just past the

include/swift/Parse/Parser.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,8 +1522,6 @@ class Parser {
15221522
/// identifier (',' identifier)* func-signature-result? 'in'
15231523
/// \endverbatim
15241524
///
1525-
/// \param bracketRange The range of the brackets enclosing a capture list, if
1526-
/// present. Needed to offer fix-its for inserting 'self' into a capture list.
15271525
/// \param captureList The entries in the capture list.
15281526
/// \param params The parsed parameter list, or null if none was provided.
15291527
/// \param arrowLoc The location of the arrow, if present.
@@ -1532,14 +1530,12 @@ class Parser {
15321530
///
15331531
/// \returns true if an error occurred, false otherwise.
15341532
bool parseClosureSignatureIfPresent(
1535-
SourceRange &bracketRange,
1536-
SmallVectorImpl<CaptureListEntry> &captureList,
1537-
VarDecl *&capturedSelfParamDecl,
1538-
ParameterList *&params,
1539-
SourceLoc &throwsLoc,
1540-
SourceLoc &arrowLoc,
1541-
TypeRepr *&explicitResultType,
1542-
SourceLoc &inLoc);
1533+
SmallVectorImpl<CaptureListEntry> &captureList,
1534+
ParameterList *&params,
1535+
SourceLoc &throwsLoc,
1536+
SourceLoc &arrowLoc,
1537+
TypeRepr *&explicitResultType,
1538+
SourceLoc &inLoc);
15431539

15441540
Expr *parseExprAnonClosureArg();
15451541
ParserResult<Expr> parseExprList(tok LeftTok, tok RightTok,

lib/AST/ASTScopeLookup.cpp

Lines changed: 2 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -517,59 +517,12 @@ GenericTypeOrExtensionWhereOrBodyPortion::computeSelfDC(
517517
while (i != 0) {
518518
Optional<NullablePtr<DeclContext>> maybeSelfDC =
519519
history[--i]->computeSelfDCForParent();
520-
if (maybeSelfDC) {
521-
// If we've found a selfDC, we'll definitely be returning something.
522-
// However, we may have captured 'self' somewhere down the tree, so we
523-
// can't return outright without checking the nested scopes.
524-
NullablePtr<DeclContext> nestedCapturedSelfDC =
525-
checkNestedScopesForSelfCapture(history, i);
526-
return nestedCapturedSelfDC ? nestedCapturedSelfDC : *maybeSelfDC;
527-
}
520+
if (maybeSelfDC)
521+
return *maybeSelfDC;
528522
}
529523
return nullptr;
530524
}
531525

532-
#pragma mark checkNestedScopesForSelfCapture
533-
534-
NullablePtr<DeclContext>
535-
GenericTypeOrExtensionWhereOrBodyPortion::checkNestedScopesForSelfCapture(
536-
ArrayRef<const ASTScopeImpl *> history, size_t start) {
537-
NullablePtr<DeclContext> innerCapturedSelfDC;
538-
// Start with the next scope down the tree.
539-
size_t j = start;
540-
541-
// Note: even though having this loop nested inside the while loop from
542-
// GenericTypeOrExtensionWhereOrBodyPortion::computeSelfDC may appear to
543-
// result in quadratic blowup, complexity actually remains linear with respect
544-
// to the size of history. This relies on the fact that
545-
// GenericTypeOrExtensionScope::computeSelfDCForParent returns a null pointer,
546-
// which will cause this method to bail out of the search early. Thus, this
547-
// method is called once per type body in the lookup history, and will not
548-
// end up re-checking the bodies of nested types that have already been
549-
// covered by earlier calls, so the total impact of this method across all
550-
// calls in a single lookup is O(n).
551-
while (j != 0) {
552-
auto *entry = history[--j];
553-
Optional<NullablePtr<DeclContext>> selfDCForParent =
554-
entry->computeSelfDCForParent();
555-
556-
// If we encounter a scope that should cause us to forget the self
557-
// context (such as a nested type), bail out and use whatever the
558-
// the last inner captured context was.
559-
if (selfDCForParent && (*selfDCForParent).isNull())
560-
break;
561-
562-
// Otherwise, if we have a captured self context for this scope, then
563-
// remember it since it is now the innermost scope we have encountered.
564-
NullablePtr<DeclContext> capturedSelfDC = entry->capturedSelfDC();
565-
if (!capturedSelfDC.isNull())
566-
innerCapturedSelfDC = entry->capturedSelfDC();
567-
568-
// Continue searching in the next scope down.
569-
}
570-
return innerCapturedSelfDC;
571-
}
572-
573526
#pragma mark compute isCascadingUse
574527

575528
Optional<bool> ASTScopeImpl::computeIsCascadingUse(
@@ -678,23 +631,6 @@ MethodBodyScope::computeSelfDCForParent() const {
678631
return NullablePtr<DeclContext>(decl);
679632
}
680633

681-
#pragma mark capturedSelfDC
682-
683-
// Closures may explicitly capture the self param, in which case the lookup
684-
// should use the closure as the context for implicit self lookups.
685-
686-
// By default, there is no such context to return.
687-
NullablePtr<DeclContext> ASTScopeImpl::capturedSelfDC() const {
688-
return NullablePtr<DeclContext>();
689-
}
690-
691-
// Closures track this information explicitly.
692-
NullablePtr<DeclContext> ClosureParametersScope::capturedSelfDC() const {
693-
if (closureExpr->capturesSelfEnablingImplictSelf())
694-
return NullablePtr<DeclContext>(closureExpr);
695-
return NullablePtr<DeclContext>();
696-
}
697-
698634
#pragma mark ifUnknownIsCascadingUseAccordingTo
699635

700636
static bool isCascadingUseAccordingTo(const DeclContext *const dc) {

lib/AST/Decl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5257,7 +5257,6 @@ VarDecl::VarDecl(DeclKind kind, bool isStatic, VarDecl::Introducer introducer,
52575257
{
52585258
Bits.VarDecl.Introducer = unsigned(introducer);
52595259
Bits.VarDecl.IsCaptureList = isCaptureList;
5260-
Bits.VarDecl.IsSelfParamCapture = false;
52615260
Bits.VarDecl.IsDebuggerVar = false;
52625261
Bits.VarDecl.IsLazyStorageProperty = false;
52635262
Bits.VarDecl.HasNonPatternBindingInit = false;

lib/AST/Expr.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,17 +1173,6 @@ UnresolvedSpecializeExpr *UnresolvedSpecializeExpr::create(ASTContext &ctx,
11731173
UnresolvedParams, RAngleLoc);
11741174
}
11751175

1176-
bool CaptureListEntry::isSimpleSelfCapture() const {
1177-
if (Init->getPatternList().size() != 1)
1178-
return false;
1179-
if (auto *DRE = dyn_cast<DeclRefExpr>(Init->getInit(0)))
1180-
if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1181-
return (VD->isSelfParameter() || VD->isSelfParamCapture())
1182-
&& VD->getName() == Var->getName();
1183-
}
1184-
return false;
1185-
}
1186-
11871176
CaptureListExpr *CaptureListExpr::create(ASTContext &ctx,
11881177
ArrayRef<CaptureListEntry> captureList,
11891178
ClosureExpr *closureBody) {
@@ -1818,12 +1807,6 @@ bool ClosureExpr::hasEmptyBody() const {
18181807
return getBody()->empty();
18191808
}
18201809

1821-
bool ClosureExpr::capturesSelfEnablingImplictSelf() const {
1822-
if (auto *VD = getCapturedSelfDecl())
1823-
return VD->isSelfParamCapture() && !VD->getType()->is<WeakStorageType>();
1824-
return false;
1825-
}
1826-
18271810
FORWARD_SOURCE_LOCS_TO(AutoClosureExpr, Body)
18281811

18291812
void AutoClosureExpr::setBody(Expr *E) {

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ ValueDecl *LookupResultEntry::getBaseDecl() const {
6060
return selfDecl;
6161
}
6262

63-
if (auto *CE = dyn_cast<ClosureExpr>(BaseDC)) {
64-
auto *selfDecl = CE->getCapturedSelfDecl();
65-
assert(selfDecl);
66-
assert(selfDecl->isSelfParamCapture());
67-
return selfDecl;
68-
}
69-
7063
auto *nominalDecl = BaseDC->getSelfNominalTypeDecl();
7164
assert(nominalDecl);
7265
return nominalDecl;

0 commit comments

Comments
 (0)