diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 2733248bea1..5c44b5f339c 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1532,5 +1532,6 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable 3379,parsEofInInterpolatedString,"Incomplete interpolated string begun at or before here" 3380,parsEofInInterpolatedVerbatimString,"Incomplete interpolated verbatim string begun at or before here" 3381,parsEofInInterpolatedTripleQuoteString,"Incomplete interpolated triple-quote string begun at or before here" -3382,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string." +3382,parsEmptyFillInInterpolatedString,"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected." +3383,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string." #3501 "This construct is not supported by your version of the F# compiler" CompilerMessage(ExperimentalAttributeMessages.NotSupportedYet, 3501, IsError=true) diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 1d757e4789d..ae1950914f5 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -5504,6 +5504,13 @@ interpolatedStringParts: | INTERP_STRING_PART interpolatedStringFill interpolatedStringParts { SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 } + | INTERP_STRING_PART interpolatedStringParts + { + let rbrace = parseState.InputEndPosition 1 + let lbrace = parseState.InputStartPosition 2 + reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString()) + SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 } + /* INTERP_STRING_BEGIN_END */ /* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_END */ /* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_PART int32 INTERP_STRING_END */ @@ -5513,6 +5520,13 @@ interpolatedString: | INTERP_STRING_BEGIN_END { [ SynInterpolatedStringPart.String (fst $1, rhs parseState 1) ] } + + | INTERP_STRING_BEGIN_PART interpolatedStringParts + { + let rbrace = parseState.InputEndPosition 1 + let lbrace = parseState.InputStartPosition 2 + reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString()) + SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 } opt_HIGH_PRECEDENCE_APP: | HIGH_PRECEDENCE_BRACK_APP { } diff --git a/tests/fsharp/Compiler/Language/StringInterpolation.fs b/tests/fsharp/Compiler/Language/StringInterpolation.fs index 83ea5c14078..7ad8d4f38c1 100644 --- a/tests/fsharp/Compiler/Language/StringInterpolation.fs +++ b/tests/fsharp/Compiler/Language/StringInterpolation.fs @@ -683,8 +683,17 @@ let xd = $"%A{}" // empty expression """ CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] code - [|(FSharpErrorSeverity.Error, 10, (2, 15, 2, 17), - "Unexpected interpolated string (final part) in binding") + [|(FSharpErrorSeverity.Error, 3382, (2, 15, 2, 15), + "Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.") + |] + + let code = """ +let xd = $"%A{ }" // empty expression +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] + code + [|(FSharpErrorSeverity.Error, 3382, (2, 15, 2, 17), + "Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.") |] [] @@ -818,7 +827,7 @@ let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}3 let code = "let x1 = $\"}\"" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] code - [|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 14), + [|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 14), "A '}' character must be escaped (by doubling) in an interpolated string.")|] [] @@ -826,7 +835,7 @@ let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}3 let code = "let x1 = @$\"}\"" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] code - [|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 15), + [|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 15), "A '}' character must be escaped (by doubling) in an interpolated string.")|] [] @@ -834,7 +843,7 @@ let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}3 let code = "let x1 = $\"\"\"}\"\"\"" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] code - [|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 18), + [|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 18), "A '}' character must be escaped (by doubling) in an interpolated string.")|] [] @@ -842,5 +851,5 @@ let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}3 let code = "let x1 = $\"{0}}\"" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] code - [|(FSharpErrorSeverity.Error, 3382, (1, 14, 1, 17), + [|(FSharpErrorSeverity.Error, 3383, (1, 14, 1, 17), "A '}' character must be escaped (by doubling) in an interpolated string.")|]