Skip to content

Commit a1ecaa1

Browse files
authored
Fix 15958: Missing warning FS3365 for SynLongIdent (dotless indexing vs application) (#16224)
* Add tests for FS3365 * improve tests * add missing warning for 3365 * format * refactor
1 parent 046ff38 commit a1ecaa1

File tree

3 files changed

+89
-7
lines changed

3 files changed

+89
-7
lines changed

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3950,6 +3950,16 @@ let GetInstanceMemberThisVariable (vspec: Val, expr) =
39503950
else
39513951
None
39523952

3953+
/// c.atomicLeftMethExpr[idx] and atomicLeftExpr[idx] as applications give warnings
3954+
let checkHighPrecedenceFunctionApplicationToList (g: TcGlobals) args atomicFlag exprRange =
3955+
match args, atomicFlag with
3956+
| ([SynExpr.ArrayOrList (false, _, _)] | [SynExpr.ArrayOrListComputed (false, _, _)]), ExprAtomicFlag.Atomic ->
3957+
if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then
3958+
informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), exprRange))
3959+
elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then
3960+
informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), exprRange))
3961+
| _ -> ()
3962+
39533963
/// Indicates whether a syntactic type is allowed to include new type variables
39543964
/// not declared anywhere, e.g. `let f (x: 'T option) = x.Value`
39553965
type ImplicitlyBoundTyparsAllowed =
@@ -8202,13 +8212,7 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg
82028212

82038213
// atomicLeftExpr[idx] unifying as application gives a warning
82048214
if not isSugar then
8205-
match synArg, atomicFlag with
8206-
| (SynExpr.ArrayOrList (false, _, _) | SynExpr.ArrayOrListComputed (false, _, _)), ExprAtomicFlag.Atomic ->
8207-
if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then
8208-
informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), mExprAndArg))
8209-
elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then
8210-
informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), mExprAndArg))
8211-
| _ -> ()
8215+
checkHighPrecedenceFunctionApplicationToList g [synArg] atomicFlag mExprAndArg
82128216

82138217
match leftExpr with
82148218
| ApplicableExpr(expr=NameOfExpr g _) when g.langVersion.SupportsFeature LanguageFeature.NameOf ->
@@ -9366,6 +9370,9 @@ and TcMethodApplicationThen
93669370
// Nb. args is always of List.length <= 1 except for indexed setters, when it is 2
93679371
let mWholeExpr = (m, args) ||> List.fold (fun m arg -> unionRanges m arg.Range)
93689372

9373+
// c.atomicLeftMethExpr[idx] as application gives a warning
9374+
checkHighPrecedenceFunctionApplicationToList g args atomicFlag mWholeExpr
9375+
93699376
// Work out if we know anything about the return type of the overall expression. If there are any delayed
93709377
// lookups then we don't know anything.
93719378
let exprTy = if isNil delayed then overallTy else MustEqual (NewInferenceType g)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
namespace FSharp.Compiler.ComponentTests.ErrorMessages
2+
3+
open FSharp.Test.Compiler
4+
open FSharp.Test.Compiler.Assertions.StructuredResultsAsserts
5+
6+
module ``Indexing Syntax`` =
7+
8+
[<FSharp.Test.FactForNETCOREAPP>]
9+
let ``Warn successfully for SynExpr.Ident app`` () =
10+
"""
11+
namespace N
12+
13+
module M =
14+
15+
let f (a: int list) = a
16+
17+
let g () = f [1] // should not warn
18+
19+
let h () = f[1] // should warn
20+
"""
21+
|> FSharp
22+
|> withLangVersion70
23+
|> compile
24+
|> shouldFail
25+
|> withResults
26+
[
27+
{
28+
Error = Information 3365
29+
Range =
30+
{
31+
StartLine = 10
32+
StartColumn = 20
33+
EndLine = 10
34+
EndColumn = 24
35+
}
36+
Message =
37+
"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]'."
38+
}
39+
]
40+
41+
[<FSharp.Test.FactForNETCOREAPP>]
42+
let ``Warn successfully for SynExpr.LongIdent app`` () =
43+
"""
44+
namespace N
45+
46+
module N =
47+
48+
type C () =
49+
member _.MyFunc (inputList: int list) = inputList
50+
51+
let g () =
52+
let c = C()
53+
let _ = c.MyFunc [23] // should not warn
54+
c.MyFunc[42] // should warn
55+
"""
56+
|> FSharp
57+
|> withLangVersion70
58+
|> compile
59+
|> shouldFail
60+
|> withResults
61+
[
62+
{
63+
Error = Information 3365
64+
Range =
65+
{
66+
StartLine = 12
67+
StartColumn = 13
68+
EndLine = 12
69+
EndColumn = 25
70+
}
71+
Message =
72+
"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]'."
73+
}
74+
]

tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
<Compile Include="EmittedIL\FixedBindings\FixedBindings.fs" />
168168
<Compile Include="ErrorMessages\UnsupportedAttributes.fs" />
169169
<Compile Include="ErrorMessages\TailCallAttribute.fs" />
170+
<Compile Include="ErrorMessages\IndexingSyntax.fs" />
170171
<Compile Include="ErrorMessages\TypeEqualsMissingTests.fs" />
171172
<Compile Include="ErrorMessages\AccessOfTypeAbbreviationTests.fs" />
172173
<Compile Include="ErrorMessages\AssignmentErrorTests.fs" />

0 commit comments

Comments
 (0)