diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index aa3cf8ce5cad1..cf329a4ae657e 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -25,6 +25,7 @@ #include "swift/AST/LazyResolver.h" #include "swift/AST/DebuggerClient.h" #include "swift/AST/DiagnosticsParse.h" +#include "swift/AST/DiagnosticSuppression.h" #include "swift/AST/Initializer.h" #include "swift/AST/Module.h" #include "swift/AST/ParameterList.h" @@ -3926,9 +3927,46 @@ Parser::parseDecl(ParseDeclOptions Flags, break; } - const bool IsProbablyFuncDecl = - Tok.isIdentifierOrUnderscore() || Tok.isAnyOperator(); + bool IsProbablyFuncDecl = false; + + if (Tok.isIdentifierOrUnderscore() || Tok.isAnyOperator()) { + + // This is a probe, so backtrack when we're done + // and don't emit diagnostics. + BacktrackingScope backtrackingScope(*this); + DiagnosticSuppression diagnosticSuppression(Diags); + + // TODO make sure we can't get these from the environment + SourceLoc staticLoc; + StaticSpellingKind staticSpelling = StaticSpellingKind::None; + DeclAttributes attributes; + bool hasFuncKeyword = false; + + ParserResult parserResult = + parseDeclFunc(staticLoc, + staticSpelling, + Flags, + attributes, + hasFuncKeyword); + + // it looks like we always get a good parse result. + // But if there are no parentheses + // the left and right parens will be at the beginning of + // the expression and will be equal so we use + // this to reject degenerate declarations. + + if (parserResult.isNonNull()) { + auto parameterList = parserResult.get()->getParameters(); + if (parameterList->getLParenLoc() != parameterList->getRParenLoc()) { + IsProbablyFuncDecl = true; + } + } + // backtrackingScope and diagnostic suppression are both RAII + // when they go out of scope, Tok returns to the beginning of + // the identifier, and diagnostics are unsuppressed. + } + // if probe succeeded, then do it for real if (IsProbablyFuncDecl) { DescriptiveDeclKind DescriptiveKind; diff --git a/test/Parse/diagnostic_call_at_type_level.swift b/test/Parse/diagnostic_call_at_type_level.swift new file mode 100644 index 0000000000000..d60a08ca24bc4 --- /dev/null +++ b/test/Parse/diagnostic_call_at_type_level.swift @@ -0,0 +1,12 @@ +// RUN: %target-typecheck-verify-swift + +struct Bar { // expected-note {{in declaration of 'Bar'}} + var fisr = 0x5F3759DF + var a: Int + + // ensure that the id.id pattern is not interpreted as a function + a.foo = 345 // expected-error {{expected declaration}} + // ensure that the id.id pattern generating an expected declaration + // diagnostic does not block further diagnostics. + fisr.bar = 345 +} diff --git a/test/Parse/diagnostic_missing_func_keyword.swift b/test/Parse/diagnostic_missing_func_keyword.swift index 295f9d73eea4b..7c9ac009780ba 100644 --- a/test/Parse/diagnostic_missing_func_keyword.swift +++ b/test/Parse/diagnostic_missing_func_keyword.swift @@ -34,10 +34,10 @@ struct Bar { } _: Int = 42 // expected-error {{expected 'var' keyword in property declaration}} {{3-3=var }} - // expected-error @-1 {{property declaration does not bind any variables}} + // expected-error @-1 {{property declaration does not bind any variables}} (light, dark) = (100, 200)// expected-error {{expected 'var' keyword in property declaration}} {{3-3=var }} - + a, b: Int // expected-error {{expected 'var' keyword in property declaration}} {{3-3=var }} } diff --git a/test/Parse/line-directive.swift b/test/Parse/line-directive.swift index 45bd84afaf947..30fe7b3c9c215 100644 --- a/test/Parse/line-directive.swift +++ b/test/Parse/line-directive.swift @@ -24,13 +24,6 @@ x x // expected-error{{consecutive statements}} {{2-2=;}} // rdar://19582475 public struct S { // expected-note{{in declaration of 'S'}} -// expected-error@+8{{expected 'func' keyword in operator function declaration}} -// expected-error@+7{{operator '/' declared in type 'S' must be 'static'}} -// expected-error@+6{{expected '(' in argument list of function declaration}} -// expected-error@+5{{operators must have one or two arguments}} -// expected-error@+4{{member operator '/()' must have at least one argument of type 'S'}} -// expected-error@+3{{expected '{' in body of function declaration}} -// expected-error@+2{{consecutive declarations on a line must be separated by ';}} // expected-error@+1{{expected declaration}} / ###line 25 "line-directive.swift" }