Skip to content

Commit 0bc679c

Browse files
authored
Merge pull request #36927 from ahoppen/pr/fast-completion-bug
[CodeCompletion] Reset diagnostics when reusing an ASTContext for completion
2 parents b245257 + 6085e1d commit 0bc679c

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

lib/IDE/CompletionInstance.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,10 @@ bool CompletionInstance::performCachedOperationIfPossible(
493493
{
494494
PrettyStackTraceDeclContext trace("performing cached completion", traceDC);
495495

496+
// The diagnostic engine is keeping track of state which might modify
497+
// parsing and type checking behaviour. Clear the flags.
498+
CI.getDiags().resetHadAnyError();
499+
496500
if (DiagC)
497501
CI.addDiagnosticConsumer(DiagC);
498502

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8517,6 +8517,17 @@ static Optional<SolutionApplicationTarget> applySolutionToForEachStmt(
85178517

85188518
Optional<SolutionApplicationTarget>
85198519
ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
8520+
// Rewriting the target might abort in case one of visit methods returns
8521+
// nullptr. In this case, no more walkToExprPost calls are issues and thus
8522+
// nodes which were pushed on the Rewriter's ExprStack in walkToExprPre are
8523+
// not popped of the stack again in walkTokExprPost. Usually, that's not an
8524+
// issue if rewriting completely terminates because the ExprStack is never
8525+
// used again. Here, however, we recover from a rewriting failure and continue
8526+
// using the Rewriter. To make sure we don't continue with an ExprStack that
8527+
// is still in the state when rewriting was aborted, save it here and restore
8528+
// it once rewritingt this target has finished.
8529+
llvm::SaveAndRestore<SmallVector<Expr *, 8>> RestoreExprStack(
8530+
Rewriter.ExprStack);
85208531
auto &solution = Rewriter.solution;
85218532

85228533
// Apply the solution to the target.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Check that we are not crashing
2+
// RUN: %sourcekitd-test -req=complete -pos=48:28 %s -- %s == -req=complete -pos=48:16 %s -- %s
3+
4+
let abcde = "abc"
5+
6+
public struct MyEmptyView : MyView {
7+
public typealias Body = Never
8+
public var body: Never { fatalError() }
9+
}
10+
11+
extension Never : MyView {}
12+
13+
@resultBuilder public struct MyViewBuilder {
14+
public static func buildBlock() -> MyEmptyView {
15+
return MyEmptyView()
16+
}
17+
public static func buildBlock<Content>(_ content: Content) -> Content where Content : MyView {
18+
content
19+
}
20+
}
21+
22+
public protocol MyView {
23+
associatedtype Body : MyView
24+
@MyViewBuilder var body: Self.Body { get }
25+
}
26+
27+
public struct MyHStack<Content> : MyView {
28+
public init(@MyViewBuilder content: () -> Content) {}
29+
public typealias Body = Swift.Never
30+
public var body: Never { fatalError() }
31+
}
32+
33+
public struct MyText : MyView {
34+
public init(_ content: Swift.String) {}
35+
public typealias Body = Never
36+
public var body: Never { fatalError() }
37+
}
38+
39+
extension MyView {
40+
public func padding(_ insets: Bool) -> some MyView { return MyEmptyView() }
41+
public func padding(_ length: Float) -> some MyView { return MyEmptyView() }
42+
public func padding() -> some MyView { return MyEmptyView() }
43+
}
44+
45+
struct RoundedBadge : MyView {
46+
var body: some MyView {
47+
MyHStack {
48+
MyText(abcde).padding()
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)