Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better anonymous record error reporting #15598

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b09d8dc
Better anonymous record error reporting
edgarfgp Jul 13, 2023
fec845b
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 13, 2023
229192e
remove extra ticks
edgarfgp Jul 13, 2023
80a3fdb
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 13, 2023
70c34d9
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 19, 2023
216a6e2
Another possible approach
edgarfgp Jul 19, 2023
b075dbb
Remove previous approach and update tests
edgarfgp Jul 19, 2023
d528edc
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 19, 2023
8fa772e
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 19, 2023
9900e78
Don't change unrelated lines
edgarfgp Jul 19, 2023
0aec3c0
Merge branch 'inaccurate-error-in-anonymous-record' of github.com:edg…
edgarfgp Jul 19, 2023
b9213fc
revert unrelated change to make easy to review
edgarfgp Jul 19, 2023
f62fc28
SendEntityPathToSink
edgarfgp Jul 19, 2023
3e9200b
Add struct anon record test
edgarfgp Jul 19, 2023
f65c8c8
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 19, 2023
372c4c1
Fix merge
edgarfgp Jul 19, 2023
78297dc
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 20, 2023
3a629db
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 21, 2023
a13e971
Update error name and message
edgarfgp Jul 21, 2023
73f3a9b
Use the type name as part of the error message
edgarfgp Jul 21, 2023
b1a4037
More tests
edgarfgp Jul 21, 2023
31b8222
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 21, 2023
d26aed5
format code
edgarfgp Jul 21, 2023
adc45f1
Move to CheckExpressions to avoid poluting sig file
edgarfgp Jul 23, 2023
1556f76
Add Symbol tests
edgarfgp Jul 23, 2023
622f56f
Update to minimize diff
edgarfgp Jul 23, 2023
4ef7e80
Update ConvertToAnonymousRecordQuickFix and Tests
edgarfgp Jul 24, 2023
f16ef8e
revert changes to minimize diff
edgarfgp Jul 24, 2023
53a9359
Fix PR comments
edgarfgp Jul 25, 2023
cd92b3c
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 25, 2023
1d111fb
Symbols test take 3
edgarfgp Jul 25, 2023
2237714
Merge branch 'inaccurate-error-in-anonymous-record' of https://github…
edgarfgp Jul 25, 2023
6e8e08b
take 4
edgarfgp Jul 25, 2023
ccefaed
take 5
edgarfgp Jul 25, 2023
32f159a
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 26, 2023
29f757b
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 27, 2023
9480d75
Merge branch 'main' into inaccurate-error-in-anonymous-record
edgarfgp Jul 27, 2023
f5f27af
Ok one more time
edgarfgp Jul 27, 2023
468396f
Merge branch 'inaccurate-error-in-anonymous-record' of https://github…
edgarfgp Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3685,8 +3685,9 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi
| [] ->
let lookup() =
let frefs =
try Map.find id.idText nenv.eFieldLabels
with :? KeyNotFoundException ->
match Map.tryFind id.idText nenv.eFieldLabels with
| Some fields -> fields
| None ->
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
// record label is unknown -> suggest related labels and give a hint to the user
error(SuggestLabelsOfRelatedRecords g nenv id allFields)

Expand Down Expand Up @@ -3716,8 +3717,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi
error(ErrorWithSuggestions(errorText, m, id.idText, suggestLabels))
else
lookup()
| _ ->
lookup()
| ValueNone -> lookup()
| _ ->
let lid = (mp@[id])
let tyconSearch ad () =
Expand Down Expand Up @@ -3749,16 +3749,26 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi
errorR(Error(FSComp.SR.nrInvalidFieldLabel(), (List.head rest).idRange))

[(resInfo, item)]

let ResolveAnonRecField (g: TcGlobals) ty (fldId: Ident) =
if (TryFindAnonRecdFieldOfType g ty fldId.idText).IsSome then
error(Error(FSComp.SR.chkAnonymousRecordFields(fldId.idText, fldId.idText), fldId.idRange))
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
else
error(UndefinedName(0, FSComp.SR.undefinedNameRecordLabel, fldId, NoSuggestions))

let ResolveField sink ncenv nenv ad ty mp id allFields =
let res = ResolveFieldPrim sink ncenv nenv ad ty (mp, id) allFields
// Register the results of any field paths "Module.Type" in "Module.Type.field" as a name resolution. (Note, the path resolution
// info is only non-empty if there was a unique resolution of the field)
let checker = ResultTyparChecker(fun () -> true)
res
|> List.map (fun (resInfo, rfref) ->
ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, checker)
rfref)
let ResolveField sink (ncenv: NameResolver) nenv ad ty mp id allFields =
if isAnonRecdTy ncenv.g ty || isStructAnonRecdTy ncenv.g ty then
ResolveAnonRecField ncenv.g ty id
[]
else
let res = ResolveFieldPrim sink ncenv nenv ad ty (mp, id) allFields
// Register the results of any field paths "Module.Type" in "Module.Type.field" as a name resolution. (Note, the path resolution
// info is only non-empty if there was a unique resolution of the field)
let checker = ResultTyparChecker(fun () -> true)
res
|> List.map (fun (resInfo, rfref) ->
ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, checker)
rfref)

/// Resolve a long identifier representing a nested record field.
///
Expand Down
5 changes: 3 additions & 2 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1700,5 +1700,6 @@ featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj infer
3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements."
3567,parsMissingMemberBody,"Expecting member body"
3568,parsMissingKeyword,"Missing keyword '%s'"
3569,chkNotTailRecursive,"The member or function '%s' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way."
3577,tcOverrideUsesMultipleArgumentsInsteadOfTuple,"This override takes a tuple instead of multiple arguments. Try to add an additional layer of parentheses at the method definition (e.g. 'member _.Foo((x, y))'), or remove parentheses at the abstract method declaration (e.g. 'abstract member Foo: 'a * 'b -> 'c')."
3577,tcOverrideUsesMultipleArgumentsInsteadOfTuple,"This override takes a tuple instead of multiple arguments. Try to add an additional layer of parentheses at the method definition (e.g. 'member _.Foo((x, y))'), or remove parentheses at the abstract method declaration (e.g. 'abstract member Foo: 'a * 'b -> 'c')."
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
3578,chkAnonymousRecordFields,"Label '%s' is part of anonymous record. Use {{| expr with %s = ... |}} instead."
3569,chkNotTailRecursive,"The member or function '%s' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way."
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hant.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,33 @@ type ErrorResponse =
Error 10, Line 7, Col 12, Line 7, Col 14, "Unexpected symbol '|}' in field declaration. Expected identifier or other token."
Error 10, Line 10, Col 17, Line 10, Col 21, "Incomplete structured construct at or before this point in field declaration. Expected identifier or other token."
]

[<Fact>]
let ``Anonymous Record type annotation with with fields defined in a record`` () =
Fsx """
type T = { ff : int }

let t3 (t1: {| gu: string; ff: int |}) = { t1 with ff = 3 }
"""
|> ignoreWarnings
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3578, Line 4, Col 52, Line 4, Col 54, "Label 'ff' is part of anonymous record. Use {| expr with ff = ... |} instead.")
]

[<Fact>]
let ``This expression was expected to have an anonymous Record but has a record`` () =
Fsx """
let t3 (t1: {| gu: string; ff: int |}) = { t1 with ff = 3 }
"""
|> ignoreWarnings
|> compile
|> shouldFail
|> withDiagnostics [
(Error 3578, Line 2, Col 52, Line 2, Col 54, "Label 'ff' is part of anonymous record. Use {| expr with ff = ... |} instead.")
]

[<Fact>]
let ``Nested anonymous records where outer label = concatenated inner labels (see secondary issue reported in 6411)`` () =
FSharp """
Expand All @@ -74,4 +100,5 @@ module NestedAnonRecds
let x = {| abcd = {| ab = 4; cd = 1 |} |}
"""
|> compile
|> shouldSucceed
|> shouldSucceed

Loading