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

Inconsistent treatment of <- with tuples #16987

Closed
brianrourkeboll opened this issue Apr 4, 2024 · 0 comments · Fixed by #17017
Closed

Inconsistent treatment of <- with tuples #16987

brianrourkeboll opened this issue Apr 4, 2024 · 0 comments · Fixed by #17017
Labels
Area-Compiler-Syntax lexfilter, indentation and parsing Feature Improvement
Milestone

Comments

@brianrourkeboll
Copy link
Contributor

brianrourkeboll commented Apr 4, 2024

Repro steps

Parentheses are not normally required around a tuple when using set/assignment syntax, including with an indexer, since , has higher precedence than <-.

When the assignment operation happens to translate to a method call like set_Item(key: …, value: …*…), however, parentheses are required — but only when using the x.[…] <- … syntax (i.e., with a dot .); when using the x[…] <- … syntax (without a dot), parentheses are never required.

open System.Collections.Generic

let xs = Array.zeroCreate 1

// OK.
xs[0] <- (2, 3, 4)
// OK.
xs[0] <- 2, 3, 4

// OK.
xs.[0] <- (2, 3, 4)
// OK.
xs.[0] <- 2, 3, 4

let ys = Dictionary ()

// OK.
ys[0] <- (2, 3, 4)
// OK.
ys[0] <- 2, 3, 4

// OK.
ys.[0] <- (2, 3, 4)
// error FS0501: The member or object constructor 'Item' takes 2 argument(s) but is here given 4.
// The required signature is 'Dictionary.set_Item(key: int, value: int * int * int) : unit'.
ys.[0] <- 2, 3, 4

// OK.
ys.Item 0 <- (2, 3, 4)
// error FS0501: The member or object constructor 'Item' takes 2 argument(s) but is here given 4.
// The required signature is 'Dictionary.set_Item(key: int, value: int * int * int) : unit'.
ys.Item 0 <- 2, 3, 4

// OK.
(ys).Item 0 <- (2, 3, 4)
// error FS0501: The member or object constructor 'Item' takes 2 argument(s) but is here given 4.
// The required signature is 'Dictionary.set_Item(key: int, value: int * int * int) : unit'.
(ys).Item 0 <- 2, 3, 4

Expected behavior

The syntactic precedence of , and <- should not change due to type information or presence of a . in the indexing syntax.

Actual behavior

The syntactic precedence of , and <- appear to change depending on type information and presence of a . in the indexing syntax.

Known workarounds

For the parentheses analyzer: always assume parentheses are required, or check the typed tree to see if the compiled translation involves a method call like set_Item(key: …, value: …*…).

@github-actions github-actions bot added this to the Backlog milestone Apr 4, 2024
@abonie abonie added Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code. Feature Improvement Area-Compiler-Syntax lexfilter, indentation and parsing and removed Needs-Triage Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code. labels Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Syntax lexfilter, indentation and parsing Feature Improvement
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants