@@ -786,15 +786,63 @@ ParserResult<Pattern> Parser::parseTypedPattern() {
786
786
auto result = parsePattern ();
787
787
788
788
// Now parse an optional type annotation.
789
- if (consumeIf (tok::colon)) {
789
+ if (Tok.is (tok::colon)) {
790
+ SourceLoc pastEndOfPrevLoc = getEndOfPreviousLoc ();
791
+ SourceLoc colonLoc = consumeToken (tok::colon);
792
+ SourceLoc startOfNextLoc = Tok.getLoc ();
793
+
790
794
if (result.isNull ()) // Recover by creating AnyPattern.
791
795
result = makeParserErrorResult (new (Context) AnyPattern (PreviousLoc));
792
796
793
797
ParserResult<TypeRepr> Ty = parseType ();
794
798
if (Ty.hasCodeCompletion ())
795
799
return makeParserCodeCompletionResult<Pattern>();
796
- if (Ty.isNull ())
800
+ if (!Ty.isNull ()) {
801
+ // Attempt to diagnose initializer calls incorrectly written
802
+ // as typed patterns, such as "var x: [Int]()".
803
+ if (Tok.isFollowingLParen ()) {
804
+ BacktrackingScope backtrack (*this );
805
+
806
+ // Create a local context if needed so we can parse trailing closures.
807
+ LocalContext dummyContext;
808
+ Optional<ContextChange> contextChange;
809
+ if (!CurLocalContext) {
810
+ contextChange.emplace (*this , CurDeclContext, &dummyContext);
811
+ }
812
+
813
+ SourceLoc lParenLoc, rParenLoc;
814
+ SmallVector<Expr *, 2 > args;
815
+ SmallVector<Identifier, 2 > argLabels;
816
+ SmallVector<SourceLoc, 2 > argLabelLocs;
817
+ Expr *trailingClosure;
818
+ ParserStatus status = parseExprList (tok::l_paren, tok::r_paren,
819
+ /* isPostfix=*/ true ,
820
+ /* isExprBasic=*/ false ,
821
+ lParenLoc, args, argLabels,
822
+ argLabelLocs, rParenLoc,
823
+ trailingClosure);
824
+ if (status.isSuccess ()) {
825
+ backtrack.cancelBacktrack ();
826
+
827
+ // Suggest replacing ':' with '=' (ensuring proper whitespace).
828
+
829
+ bool needSpaceBefore = (pastEndOfPrevLoc == colonLoc);
830
+ bool needSpaceAfter =
831
+ SourceMgr.getByteDistance (colonLoc, startOfNextLoc) <= 1 ;
832
+
833
+ StringRef replacement = " = " ;
834
+ if (!needSpaceBefore) replacement = replacement.drop_front ();
835
+ if (!needSpaceAfter) replacement = replacement.drop_back ();
836
+
837
+ diagnose (lParenLoc, diag::initializer_as_typed_pattern)
838
+ .highlight ({Ty.get ()->getStartLoc (), rParenLoc})
839
+ .fixItReplace (colonLoc, replacement);
840
+ result.setIsParseError ();
841
+ }
842
+ }
843
+ } else {
797
844
Ty = makeParserResult (new (Context) ErrorTypeRepr (PreviousLoc));
845
+ }
798
846
799
847
result = makeParserResult (result,
800
848
new (Context) TypedPattern (result.get (), Ty.get ()));
0 commit comments