fix <rdar://problem/20457938> typed pattern is not allowed on if/let condition

Swift SVN r27110
This commit is contained in:
Chris Lattner
2015-04-08 00:28:29 +00:00
parent 652aace9a6
commit a63120f11a
5 changed files with 33 additions and 24 deletions

View File

@@ -1021,7 +1021,8 @@ public:
parsePatternTupleElement();
ParserResult<Pattern> parsePatternTuple();
ParserResult<Pattern> parseTypedMatchingPattern();
ParserResult<Pattern>
parseOptionalPatternTypeAnnotation(ParserResult<Pattern> P);
ParserResult<Pattern> parseMatchingPattern(bool isExprBasic);
ParserResult<Pattern> parseMatchingPatternAsLetOrVar(bool isLet,
SourceLoc VarLoc,

View File

@@ -3452,7 +3452,8 @@ ParserStatus Parser::parseDeclVar(ParseDeclOptions Flags,
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
auto patternRes = parseTypedMatchingPattern();
auto patternRes = parseMatchingPattern(/*isExprBasic*/true);
patternRes = parseOptionalPatternTypeAnnotation(patternRes);
if (patternRes.hasCodeCompletion())
return makeParserCodeCompletionStatus();

View File

@@ -941,17 +941,22 @@ ParserResult<Pattern> Parser::parsePatternTuple() {
EllipsisLoc.isValid(), EllipsisLoc));
}
/// Parse a pattern with an optional type annotation.
/// Parse an optional type annotation on a pattern.
///
/// typed-pattern ::= mattching-pattern (':' type)?
/// pattern-type-annotation ::= (':' type)?
///
ParserResult<Pattern> Parser::parseTypedMatchingPattern() {
auto result = parseMatchingPattern(/*isExprBasic*/true);
ParserResult<Pattern> Parser::
parseOptionalPatternTypeAnnotation(ParserResult<Pattern> result) {
// Now parse an optional type annotation.
if (consumeIf(tok::colon)) {
// Parse an optional type annotation.
if (!consumeIf(tok::colon))
return result;
Pattern *P;
if (result.isNull()) // Recover by creating AnyPattern.
result = makeParserErrorResult(new (Context) AnyPattern(PreviousLoc));
P = new (Context) AnyPattern(Tok.getLoc());
else
P = result.get();
ParserResult<TypeRepr> Ty = parseType();
if (Ty.hasCodeCompletion())
@@ -959,11 +964,7 @@ ParserResult<Pattern> Parser::parseTypedMatchingPattern() {
if (Ty.isNull())
Ty = makeParserResult(new (Context) ErrorTypeRepr(PreviousLoc));
result = makeParserResult(result,
new (Context) TypedPattern(result.get(), Ty.get()));
}
return result;
return makeParserResult(new (Context) TypedPattern(P, Ty.get()));
}

View File

@@ -850,9 +850,11 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition,
//
if (Tok.is(tok::identifier) && peekToken().is(tok::colon))
Pattern = parseSwift1IfLetPattern(IsLet, VarLoc);
else
else {
Pattern = parseMatchingPatternAsLetOrVar(IsLet, VarLoc,
/*isExprBasic*/ true);
Pattern = parseOptionalPatternTypeAnnotation(Pattern);
}
Status |= Pattern;
if (Pattern.isNull() || Pattern.hasCodeCompletion())

View File

@@ -59,6 +59,10 @@ if 1 != 2, let x? = opt, y? = opt where x != y,
let a? = opt, var b? = opt {
}
// <rdar://problem/20457938> typed pattern is not allowed on if/let condition
if 1 != 2, let x? : Int? = opt {}
// Test error recovery.
// <rdar://problem/19939746> Improve error recovery for malformed if statements
if 1 != 2, { // expected-error {{expected 'let' or 'var' in conditional}}