Skip to content

Commit 62d8eed

Browse files
committed
[Parse] Don't drop parsed error types in where clause from AST
Code completion requires the source range of the 'where' clause to correctly lookup member of types in where clause. rdar://problem/61911134
1 parent db3e9fc commit 62d8eed

File tree

6 files changed

+52
-39
lines changed

6 files changed

+52
-39
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4582,8 +4582,7 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
45824582
return whereStatus;
45834583
trailingWhereHadCodeCompletion = true;
45844584
}
4585-
4586-
if (whereStatus.isSuccess()) {
4585+
if (!requirements.empty()) {
45874586
trailingWhereClause = TrailingWhereClause::create(Context, whereLoc,
45884587
requirements);
45894588
}

lib/Parse/ParseGeneric.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,9 @@ ParserStatus Parser::parseGenericWhereClause(
332332
} else {
333333
// Parse the protocol or composition.
334334
ParserResult<TypeRepr> Protocol = parseType();
335-
336-
if (Protocol.isNull()) {
337-
Status.setIsParseError();
338-
if (Protocol.hasCodeCompletion())
339-
Status.setHasCodeCompletion();
340-
break;
341-
}
335+
Status |= Protocol;
336+
if (Protocol.isNull())
337+
Protocol = makeParserResult(new (Context) ErrorTypeRepr(PreviousLoc));
342338

343339
// Add the requirement.
344340
Requirements.push_back(RequirementRepr::getTypeConstraint(
@@ -356,17 +352,18 @@ ParserStatus Parser::parseGenericWhereClause(
356352

357353
// Parse the second type.
358354
ParserResult<TypeRepr> SecondType = parseType();
359-
if (SecondType.isNull()) {
360-
Status.setIsParseError();
361-
if (SecondType.hasCodeCompletion())
362-
Status.setHasCodeCompletion();
363-
break;
364-
}
355+
Status |= SecondType;
356+
if (SecondType.isNull())
357+
SecondType = makeParserResult(new (Context) ErrorTypeRepr(PreviousLoc));
365358

366359
// Add the requirement
367360
Requirements.push_back(RequirementRepr::getSameType(FirstType.get(),
368361
EqualLoc,
369362
SecondType.get()));
363+
} else if (FirstType.hasCodeCompletion()) {
364+
// Recover by adding dummy constraint.
365+
Requirements.push_back(RequirementRepr::getTypeConstraint(
366+
FirstType.get(), PreviousLoc, new (Context) ErrorTypeRepr(PreviousLoc)));
370367
} else {
371368
BodyContext->setTransparent();
372369
diagnose(Tok, diag::expected_requirement_delim);

lib/Parse/ParsePattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
332332

333333
// If we didn't parse a type, then we already diagnosed that the type
334334
// was invalid. Remember that.
335-
if (type.isParseError() && !type.hasCodeCompletion())
335+
if (type.isNull() && !type.hasCodeCompletion())
336336
param.isInvalid = true;
337337
} else if (paramContext != Parser::ParameterContextKind::Closure) {
338338
diagnose(Tok, diag::expected_parameter_colon);

lib/Parse/ParseType.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,8 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
179179
break;
180180
if (CodeCompletion)
181181
CodeCompletion->completeTypeSimpleBeginning();
182-
// Eat the code completion token because we handled it.
183-
consumeToken(tok::code_complete);
184-
return makeParserCodeCompletionResult<TypeRepr>();
182+
return makeParserCodeCompletionResult<TypeRepr>(
183+
new (Context) ErrorTypeRepr(consumeToken(tok::code_complete)));
185184
case tok::l_square: {
186185
auto Result = parseTypeCollection();
187186
if (Result.hasSyntax())
@@ -407,11 +406,10 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
407406

408407
ParserResult<TypeRepr> ty =
409408
parseTypeSimpleOrComposition(MessageID, HandleCodeCompletion);
410-
if (ty.hasCodeCompletion())
411-
return makeParserCodeCompletionResult<TypeRepr>();
412409
if (ty.isNull())
413-
return nullptr;
410+
return ty;
414411
auto tyR = ty.get();
412+
auto status = ParserStatus(ty);
415413

416414
// Parse a throws specifier.
417415
// Don't consume 'throws', if the next token is not '->', so we can emit a
@@ -442,10 +440,11 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
442440
}
443441
ParserResult<TypeRepr> SecondHalf =
444442
parseType(diag::expected_type_function_result);
445-
if (SecondHalf.hasCodeCompletion())
446-
return makeParserCodeCompletionResult<TypeRepr>();
447-
if (SecondHalf.isNull())
448-
return nullptr;
443+
if (SecondHalf.isNull()) {
444+
status.setIsParseError();
445+
return status;
446+
}
447+
status |= SecondHalf;
449448

450449
if (SyntaxContext->isEnabled()) {
451450
ParsedFunctionTypeSyntaxBuilder Builder(*SyntaxContext);
@@ -594,8 +593,8 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
594593
if (specifierLoc.isValid() || !attrs.empty())
595594
SyntaxContext->setCreateSyntax(SyntaxKind::AttributedType);
596595

597-
return makeParserResult(applyAttributeToType(tyR, attrs, specifier,
598-
specifierLoc));
596+
return makeParserResult(status, applyAttributeToType(tyR, attrs, specifier,
597+
specifierLoc));
599598
}
600599

601600
ParserResult<TypeRepr> Parser::parseDeclResultType(Diag<> MessageID) {
@@ -844,8 +843,6 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID,
844843
// Parse the first type
845844
ParserResult<TypeRepr> FirstType = parseTypeSimple(MessageID,
846845
HandleCodeCompletion);
847-
if (FirstType.hasCodeCompletion())
848-
return makeParserCodeCompletionResult<TypeRepr>();
849846
if (FirstType.isNull())
850847
return FirstType;
851848
if (!Tok.isContextualPunctuator("&")) {
@@ -1255,8 +1252,6 @@ ParserResult<TypeRepr> Parser::parseTypeArray(TypeRepr *Base) {
12551252
auto sizeEx = parseExprBasic(diag::expected_expr);
12561253
if (sizeEx.hasCodeCompletion())
12571254
return makeParserCodeCompletionStatus();
1258-
if (sizeEx.isNull())
1259-
return makeParserErrorResult(Base);
12601255
}
12611256

12621257
SourceLoc rsquareLoc;

test/IDE/complete_where_clause.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=NOMINAL_TYPEALIAS_NESTED2 | %FileCheck %s -check-prefix=NOMINAL_TYPEALIAS_NESTED2
3939
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=NOMINAL_TYPEALIAS_NESTED1_EXT | %FileCheck %s -check-prefix=NOMINAL_TYPEALIAS_NESTED1_EXT
4040
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=NOMINAL_TYPEALIAS_NESTED2_EXT | %FileCheck %s -check-prefix=NOMINAL_TYPEALIAS_NESTED2_EXT
41+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=EXT_ASSOC_MEMBER_1 | %FileCheck %s -check-prefix=EXT_ASSOC_MEMBER
42+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=EXT_ASSOC_MEMBER_2 | %FileCheck %s -check-prefix=EXT_ASSOC_MEMBER
43+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=EXT_SECONDTYPE | %FileCheck %s -check-prefix=EXT_SECONDTYPE
4144

4245
class A1<T1, T2, T3> {}
4346

@@ -226,3 +229,20 @@ extension TA2.Inner2 where #^NOMINAL_TYPEALIAS_NESTED2_EXT^# {}
226229
// NOMINAL_TYPEALIAS_NESTED2_EXT-DAG: Decl[TypeAlias]/CurrNominal: X1[#T#];
227230
// NOMINAL_TYPEALIAS_NESTED2_EXT-DAG: Decl[TypeAlias]/CurrNominal: X2[#T.Q#];
228231
// NOMINAL_TYPEALIAS_NESTED2_EXT: End completions
232+
233+
protocol WithAssoc {
234+
associatedtype T: Assoc
235+
}
236+
extension WithAssoc where T.#^EXT_ASSOC_MEMBER_1^#
237+
// EXT_ASSOC_MEMBER: Begin completions, 2 items
238+
// EXT_ASSOC_MEMBER-DAG: Decl[AssociatedType]/CurrNominal: Q;
239+
// EXT_ASSOC_MEMBER-DAG: Keyword/None: Type[#Self.T.Type#];
240+
// EXT_ASSOC_MEMBER: End completions
241+
242+
extension WithAssoc where Int == T.#^EXT_ASSOC_MEMBER_2^#
243+
// Same as EXT_ASSOC_MEMBER
244+
245+
extension WithAssoc where Int == #^EXT_SECONDTYPE^#
246+
// EXT_SECONDTYPE: Begin completions
247+
// EXT_SECONDTYPE-DAG: Decl[AssociatedType]/CurrNominal: T;
248+
// EXT_SECONDTYPE: End completions

test/Parse/recovery.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -436,19 +436,22 @@ struct ErrorTypeInVarDeclFunctionType1 {
436436
}
437437

438438
struct ErrorTypeInVarDeclArrayType1 {
439-
var v1 : Int[+] // expected-error {{unexpected ']' in type; did you mean to write an array type?}}
439+
var v1 : Int[+] // expected-error {{array types are now written with the brackets around the element type}}
440440
// expected-error @-1 {{expected expression after unary operator}}
441441
// expected-error @-2 {{expected expression}}
442442
var v2 : Int
443443
}
444444

445445
struct ErrorTypeInVarDeclArrayType2 {
446446
var v1 : Int[+ // expected-error {{unary operator cannot be separated from its operand}}
447+
// expected-error@-1 {{expected ']' in array type}}
448+
// expected-note@-2 {{to match this opening '['}}
447449
var v2 : Int // expected-error {{expected expression}}
448450
}
449451

450452
struct ErrorTypeInVarDeclArrayType3 {
451-
var v1 : Int[
453+
var v1 : Int[ // expected-error {{expected ']' in array type}}
454+
// expected-note@-1 {{to match this opening '['}}
452455
; // expected-error {{expected expression}}
453456
var v2 : Int
454457
}
@@ -480,8 +483,9 @@ struct ErrorTypeInVarDeclDictionaryType {
480483

481484
struct ErrorInFunctionSignatureResultArrayType1 {
482485
func foo() -> Int[ { // expected-error {{expected '{' in body of function declaration}}
486+
// expected-note@-1 {{to match this opening '['}}
483487
return [0]
484-
}
488+
} // expected-error {{expected ']' in array type}}
485489
func bar() -> Int] { // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{17-17=[}}
486490
return [0]
487491
}
@@ -669,10 +673,8 @@ case let (jeb):
669673
// rdar://19605164
670674
// expected-error@+2{{use of undeclared type 'S'}}
671675
struct Foo19605164 {
672-
func a(s: S[{{g) -> Int {}
673-
// expected-error@+2 {{expected parameter name followed by ':'}}
674-
// expected-error@+1 {{expected ',' separator}}
675-
}}}
676+
func a(s: S[{{g) -> Int {} // expected-note {{to match this opening '['}}
677+
}}} // expected-error {{expected ']' in array type}}
676678
#endif
677679

678680

0 commit comments

Comments
 (0)