Skip to content

Commit 4511803

Browse files
committed
When we lex an invalid leftbound dot, instead of emitting an error and swallowing it
silently, have the lexer return it as an unknown token. Enhance the expr parser to detect these things and squash any expression in progress into an ErrorExpr. This allows us to silence really bad downstream errors. For example, on: struct S { func f() {} } func f() { _ = S. } we formerly produced: x.swift:5:8: error: expected member name following '.' x.swift:5:7: error: expected member name or constructor call after type name x.swift:5:7: note: add arguments after the type to construct a value of the type x.swift:5:7: note: use '.self' to reference the type object we now emit just the first one. This fixes: <rdar://problem/22290244> QoI: "UIColor." gives two issues, should only give one
1 parent 2719203 commit 4511803

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

lib/Parse/Lexer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,8 +755,7 @@ void Lexer::lexOperatorIdentifier() {
755755

756756
// Otherwise, it is probably a missing member.
757757
diagnose(TokStart, diag::expected_member_name);
758-
//return formToken(tok::unknown, TokStart);
759-
return lexImpl();
758+
return formToken(tok::unknown, TokStart);
760759
}
761760
case '?':
762761
if (leftBound)

lib/Parse/ParseExpr.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
13921392
// FIXME: Better recovery.
13931393
if (Result.isNull())
13941394
return Result;
1395-
1395+
13961396
// Check for a .foo suffix.
13971397
SourceLoc TokLoc = Tok.getLoc();
13981398
if (consumeIf(tok::period) || consumeIf(tok::period_prefix)) {
@@ -1618,6 +1618,16 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
16181618
consumeToken(tok::code_complete);
16191619
return makeParserCodeCompletionResult<Expr>();
16201620
}
1621+
1622+
// If we end up with an unknown token on this line, return an ErrorExpr
1623+
// covering the range of the token.
1624+
if (!Tok.isAtStartOfLine() && consumeIf(tok::unknown)) {
1625+
Result = makeParserResult(
1626+
new (Context) ErrorExpr(Result.get()->getSourceRange()));
1627+
continue;
1628+
}
1629+
1630+
// Otherwise, we don't know what this token is, it must end the expression.
16211631
break;
16221632
}
16231633

test/IDE/complete_type.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@
131131

132132
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_STRUCT_INHERITANCE_4 > %t.types.txt
133133
// RUN: FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
134-
// RUN: FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.types.txt
135134

136135
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_STRUCT_INHERITANCE_5 > %t.types.txt
137136
// RUN: FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
@@ -147,7 +146,6 @@
147146

148147
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_STRUCT_INHERITANCE_8 > %t.types.txt
149148
// RUN: FileCheck %s -check-prefix=WITH_GLOBAL_TYPES < %t.types.txt
150-
// RUN: FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.types.txt
151149

152150

153151
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_IN_CLASS_INHERITANCE_1 > %t.types.txt

test/Parse/recovery.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ struct MissingInitializer1 {
405405

406406
func exprPostfix1(x : Int) {
407407
x. // expected-error {{expected member name following '.'}}
408-
// expected-warning @-1 {{expression of type 'Int' is unused}}
409408
}
410409

411410
func exprPostfix2() {
@@ -424,7 +423,7 @@ class ExprSuper1 {
424423

425424
class ExprSuper2 {
426425
init() {
427-
super. // expected-error {{expected member name following '.'}} expected-error {{expected '.' or '[' after 'super'}}
426+
super. // expected-error {{expected member name following '.'}}
428427
}
429428
}
430429

@@ -651,7 +650,6 @@ func postfixDot(a : String) {
651650
_ = a. utf8 // expected-error {{extraneous whitespace after '.' is not permitted}} {{9-12=}}
652651
_ = a. // expected-error {{expected member name following '.'}}
653652
a. // expected-error {{expected member name following '.'}}
654-
// expected-warning @-1 {{expression of type 'String' is unused}}
655653
}
656654

657655
// <rdar://problem/23036383> QoI: Invalid trailing closures in stmt-conditions produce lowsy diagnostics
@@ -664,3 +662,9 @@ func r23036383(arr : [Int]?) {
664662
}
665663
}
666664

665+
// <rdar://problem/22290244> QoI: "UIColor." gives two issues, should only give one
666+
func f() {
667+
_ = ClassWithStaticDecls. // expected-error {{expected member name following '.'}}
668+
}
669+
670+

test/Sema/diag_values_of_module_type.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ func badTest2() {
9595
_ = x
9696
}
9797
func badTest3() {
98-
var _ = Swift. // expected-error {{expected member name following '.'}} expected-error {{expected module member name after module name}}
98+
var _ = Swift. // expected-error {{expected member name following '.'}}
9999
}
100100
func badTest4() {
101101
_ = Swift // expected-error {{expected module member name after module name}}
102102
}
103103
func badTest5() {
104-
_ = Swift. // expected-error {{expected module member name after module name}} expected-error {{expected member name following '.'}}
104+
_ = Swift. // expected-error {{expected member name following '.'}}
105105
}
106106
func badTest6() {
107107
_ = { () -> Int in

0 commit comments

Comments
 (0)