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