Skip to content

Property initialization doesn't work without space before interpolated string #16696

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

Open
Lanayx opened this issue Feb 13, 2024 · 10 comments · May be fixed by #18607
Open

Property initialization doesn't work without space before interpolated string #16696

Lanayx opened this issue Feb 13, 2024 · 10 comments · May be fixed by #18607
Assignees
Milestone

Comments

@Lanayx
Copy link
Contributor

Lanayx commented Feb 13, 2024

Repro steps

type C() =
    member val Name = "" with get, set
    
let x = C(Name="123") //works
let y = C(Name=$"123") // doesn't work
let z = C(Name= $"123") // works

Sharplab

Expected behavior

All three cases should work

Actual behavior

Second case doesn't work

Known workarounds

Add space before value

Related information

.NET 8
F# 8

@abonie
Copy link
Member

abonie commented Feb 15, 2024

It is not really related to property initialization, simpler repro:

> let x =$"123";;

  let x =$"123";;
  ------^^

stdin(2,7): error FS0035: This construct is deprecated: '$' is not permitted as a character in operator names and is reserved for future use

and not so much to interpolated strings either:

> let x =-1;;

  let x =-1;;
  ------^^

stdin(3,7): error FS0010: Unexpected infix operator in binding. Expected '=' or other token.

@Martin521
Copy link
Contributor

Martin521 commented Feb 15, 2024

Well, the last one I think is a different thing, and correctly reported as error.
Actually, if I think about it, also =$ is probably according to F# syntax recognized as an operator, and correctly rejected.
Same thing as let x = 1+-2.
A better error message might be in order.
(In any case, following the formatting guidelines and using Fantomas is helpful ;-))

@abonie
Copy link
Member

abonie commented Feb 15, 2024

@Martin521 it is kind of the same thing, because in both cases lexer thinks it sees INFIX_COMPARE_OP, in one case it throws an error there because $ is not allowed there, in the other case, I am actually not sure when the error is thrown (after lexing I think), but it stems from the way this code got lexed IMO.

And yeah, not quite sure if this is a bug tbh.

@Lanayx
Copy link
Contributor Author

Lanayx commented Feb 15, 2024

@abonie Property initialisation is a case where skipping spaces around = makes the most sense. I've met it when writing html dsl, so it looks like <img src="img_girl.jpg"> , note no spaces around equals operator.

@edgarfgp
Copy link
Contributor

I think this can be fixed following the same approach than https://github.com/dotnet/fsharp/pull/15923/files

@edgarfgp
Copy link
Contributor

This is really bad TBH. another glitch that should be addressed

Screenshot 2024-05-17 at 17 41 27

@vzarytovskii
Copy link
Member

This is really bad TBH. another glitch that should be addressed

Screenshot 2024-05-17 at 17 41 27

Easier said than done. It is lexed and parsed like an operator, so it needs be "special cased" for binding, fields and properties assignments (also, how should $"foo"=$"bar" be treated in this case?), but I'm pretty sure by the time we parsed it and produced this diagnostics, there's no "way back" to treating it as assignment.

One possible solution is for us to "deprecate" $ for good, removing it from lexing, so it's never treated as part of the operator, but this will need suggestion/discussion.

@auduchinok thoughts?

Also, I think message in Rider is outdated:
image

@edgarfgp
Copy link
Contributor

Never said it was easy 😅. I played around locally with a similar approach than https://github.com/dotnet/fsharp/pull/15923/files and it "works". But now shows that Name can't be resolved.

@auduchinok
Copy link
Member

@auduchinok thoughts?

We could try to special-case this in the parser: do a check after successfully parsing it as an operator and rewrite the resulting tree if it matches this pattern. We do a similar thing in some other cases already.

@vzarytovskii
Copy link
Member

@auduchinok thoughts?

We could try to special-case this in the parser: do a check after successfully parsing it as an operator and rewrite the resulting tree if it matches this pattern. We do a similar thing in some other cases already.

It should be relatively safe, since we don't allow defining (=$) operator.

@edgarfgp edgarfgp self-assigned this May 15, 2025
@edgarfgp edgarfgp linked a pull request May 25, 2025 that will close this issue
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: New
Development

Successfully merging a pull request may close this issue.

7 participants