Skip to content

Commit 1a82712

Browse files
committed
Sema: Remove incorrect and incomplete forward capture analysis
Sema does not have enough information to diagnose these problems correctly. Also, there was an unimplemented case in the analysis; if a closure did not yet have computed captures, we'd add it to the ForwardCapturedFuncs list, but nothing ever looked at that list.
1 parent 70356c9 commit 1a82712

File tree

5 files changed

+0
-216
lines changed

5 files changed

+0
-216
lines changed

Diff for: include/swift/AST/DiagnosticsSema.def

-8
Original file line numberDiff line numberDiff line change
@@ -3016,14 +3016,6 @@ ERROR(method_call_in_closure_without_explicit_self,none,
30163016
ERROR(implicit_use_of_self_in_closure,none,
30173017
"implicit use of 'self' in closure; use 'self.' to make"
30183018
" capture semantics explicit", ())
3019-
ERROR(capture_before_declaration,none,
3020-
"cannot capture %0 before it is declared", (Identifier))
3021-
ERROR(transitive_capture_before_declaration,none,
3022-
"cannot capture %0, which would use %1 before it is declared",
3023-
(Identifier, Identifier))
3024-
NOTE(transitive_capture_through_here,none,
3025-
"%0, declared here, captures %1",
3026-
(Identifier, Identifier))
30273019

30283020
WARNING(recursive_accessor_reference,none,
30293021
"attempting to %select{access|modify}1 %0 within its own "

Diff for: lib/Sema/TypeCheckCaptures.cpp

-68
Original file line numberDiff line numberDiff line change
@@ -300,74 +300,6 @@ class FindCapturedVars : public ASTWalker {
300300
if (!isa<VarDecl>(D) && !DC->isLocalContext())
301301
return { false, DRE };
302302

303-
// Can only capture a variable that is declared before the capturing
304-
// entity.
305-
llvm::DenseSet<ValueDecl *> checkedCaptures;
306-
llvm::SmallVector<FuncDecl *, 2> capturePath;
307-
308-
std::function<bool (ValueDecl *)>
309-
validateForwardCapture = [&](ValueDecl *capturedDecl) -> bool {
310-
if (!checkedCaptures.insert(capturedDecl).second)
311-
return true;
312-
313-
// Captures at nonlocal scope are order-invariant.
314-
if (!capturedDecl->getDeclContext()->isLocalContext())
315-
return true;
316-
317-
// Assume implicit decl captures are OK.
318-
if (!CaptureLoc.isValid() || !capturedDecl->getLoc().isValid())
319-
return true;
320-
321-
// Check the order of the declarations.
322-
if (!TC.Context.SourceMgr.isBeforeInBuffer(CaptureLoc,
323-
capturedDecl->getLoc()))
324-
return true;
325-
326-
// Forward captures of functions are OK, if the function doesn't
327-
// transitively capture variables ahead of the original function.
328-
if (auto func = dyn_cast<FuncDecl>(capturedDecl)) {
329-
if (!func->getCaptureInfo().hasBeenComputed()) {
330-
// Check later.
331-
TC.ForwardCapturedFuncs[func].push_back(AFR);
332-
return true;
333-
}
334-
// Recursively check the transitive captures.
335-
capturePath.push_back(func);
336-
SWIFT_DEFER { capturePath.pop_back(); };
337-
for (auto capture : func->getCaptureInfo().getCaptures())
338-
if (!validateForwardCapture(capture.getDecl()))
339-
return false;
340-
return true;
341-
}
342-
343-
// Diagnose the improper forward capture.
344-
if (Diagnosed.insert(capturedDecl).second) {
345-
if (capturedDecl == DRE->getDecl()) {
346-
TC.diagnose(DRE->getLoc(), diag::capture_before_declaration,
347-
capturedDecl->getBaseName().getIdentifier());
348-
} else {
349-
TC.diagnose(DRE->getLoc(),
350-
diag::transitive_capture_before_declaration,
351-
DRE->getDecl()->getBaseName().getIdentifier(),
352-
capturedDecl->getBaseName().getIdentifier());
353-
ValueDecl *prevDecl = capturedDecl;
354-
for (auto path : reversed(capturePath)) {
355-
TC.diagnose(path->getLoc(),
356-
diag::transitive_capture_through_here,
357-
path->getName(),
358-
prevDecl->getBaseName().getIdentifier());
359-
prevDecl = path;
360-
}
361-
}
362-
TC.diagnose(capturedDecl, diag::decl_declared_here,
363-
capturedDecl->getFullName());
364-
}
365-
return false;
366-
};
367-
368-
if (!validateForwardCapture(DRE->getDecl()))
369-
return { false, DRE };
370-
371303
// We're going to capture this, compute flags for the capture.
372304
unsigned Flags = 0;
373305

Diff for: lib/Sema/TypeChecker.h

-19
Original file line numberDiff line numberDiff line change
@@ -569,25 +569,6 @@ class TypeChecker final : public LazyResolver {
569569
/// will need to compute captures for.
570570
std::vector<AbstractClosureExpr *> ClosuresWithUncomputedCaptures;
571571

572-
/// Local functions that have been captured before their definitions.
573-
///
574-
/// We need this to guard against functions that would transitively capture
575-
/// variables before their definition, e.g.:
576-
///
577-
/// func outer() {
578-
/// func first() {
579-
/// second()
580-
/// }
581-
/// second()
582-
/// var x
583-
/// func second() {
584-
/// use(x)
585-
/// }
586-
/// }
587-
588-
llvm::SmallDenseMap<AnyFunctionRef, SmallVector<AnyFunctionRef, 4>, 4>
589-
ForwardCapturedFuncs;
590-
591572
/// A set of local functions from which C function pointers are derived.
592573
///
593574
/// This is used to diagnose the use of local functions with captured context

Diff for: test/Sema/diag_defer_captures.swift

-21
This file was deleted.

Diff for: test/expr/capture/order.swift

-100
This file was deleted.

0 commit comments

Comments
 (0)