diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 527fc3233a..b2469920e6 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -3950,6 +3950,16 @@ let GetInstanceMemberThisVariable (vspec: Val, expr) = else None +/// c.atomicLeftMethExpr[idx] and atomicLeftExpr[idx] as applications give warnings +let checkHighPrecedenceFunctionApplicationToList (g: TcGlobals) args atomicFlag exprRange = + match args, atomicFlag with + | ([SynExpr.ArrayOrList (false, _, _)] | [SynExpr.ArrayOrListComputed (false, _, _)]), ExprAtomicFlag.Atomic -> + if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), exprRange)) + elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then + informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), exprRange)) + | _ -> () + /// Indicates whether a syntactic type is allowed to include new type variables /// not declared anywhere, e.g. `let f (x: 'T option) = x.Value` type ImplicitlyBoundTyparsAllowed = @@ -8202,13 +8212,7 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg // atomicLeftExpr[idx] unifying as application gives a warning if not isSugar then - match synArg, atomicFlag with - | (SynExpr.ArrayOrList (false, _, _) | SynExpr.ArrayOrListComputed (false, _, _)), ExprAtomicFlag.Atomic -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), mExprAndArg)) - elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then - informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), mExprAndArg)) - | _ -> () + checkHighPrecedenceFunctionApplicationToList g [synArg] atomicFlag mExprAndArg match leftExpr with | ApplicableExpr(expr=NameOfExpr g _) when g.langVersion.SupportsFeature LanguageFeature.NameOf -> @@ -9366,6 +9370,9 @@ and TcMethodApplicationThen // Nb. args is always of List.length <= 1 except for indexed setters, when it is 2 let mWholeExpr = (m, args) ||> List.fold (fun m arg -> unionRanges m arg.Range) + // c.atomicLeftMethExpr[idx] as application gives a warning + checkHighPrecedenceFunctionApplicationToList g args atomicFlag mWholeExpr + // Work out if we know anything about the return type of the overall expression. If there are any delayed // lookups then we don't know anything. let exprTy = if isNil delayed then overallTy else MustEqual (NewInferenceType g) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/IndexingSyntax.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/IndexingSyntax.fs new file mode 100644 index 0000000000..e0704dc52f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/IndexingSyntax.fs @@ -0,0 +1,74 @@ +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open FSharp.Test.Compiler +open FSharp.Test.Compiler.Assertions.StructuredResultsAsserts + +module ``Indexing Syntax`` = + + [] + let ``Warn successfully for SynExpr.Ident app`` () = + """ +namespace N + + module M = + + let f (a: int list) = a + + let g () = f [1] // should not warn + + let h () = f[1] // should warn + """ + |> FSharp + |> withLangVersion70 + |> compile + |> shouldFail + |> withResults + [ + { + Error = Information 3365 + Range = + { + StartLine = 10 + StartColumn = 20 + EndLine = 10 + EndColumn = 24 + } + Message = + "The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'." + } + ] + + [] + let ``Warn successfully for SynExpr.LongIdent app`` () = + """ +namespace N + + module N = + + type C () = + member _.MyFunc (inputList: int list) = inputList + + let g () = + let c = C() + let _ = c.MyFunc [23] // should not warn + c.MyFunc[42] // should warn + """ + |> FSharp + |> withLangVersion70 + |> compile + |> shouldFail + |> withResults + [ + { + Error = Information 3365 + Range = + { + StartLine = 12 + StartColumn = 13 + EndLine = 12 + EndColumn = 25 + } + Message = + "The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'." + } + ] diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index aefeb44cc5..99fbfe55d8 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -167,6 +167,7 @@ +