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

Compiler does not infer string type for nameof pattern #13377

Closed
niesmo opened this issue Jun 24, 2022 · 10 comments · Fixed by #14065
Closed

Compiler does not infer string type for nameof pattern #13377

niesmo opened this issue Jun 24, 2022 · 10 comments · Fixed by #14065
Assignees
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Bug good first issue help wanted Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.
Milestone

Comments

@niesmo
Copy link

niesmo commented Jun 24, 2022

When using nameof in a pattern match, I'd expect the compiler to infer the argument type as string since nameof returns a string. However, the argument is treated as generic and generates invalid IL.

Repro steps

// Expected:
//   FS0001: This expression was expected to have type 'int' but here has type 'string'
// Actual:
//   No compile error; InvalidProgramException at runtime.
match 3 with
| nameof int -> true
| _ -> false
// Expected inferred type:
//   val f : x:string -> bool
// Actual inferred type:
//   val f : x:'a -> bool
let f x = match x with nameof x -> true | _ -> false

According to the RFC for the nameof pattern feature, the nameof expr should be "equivalent to a literal string pattern" which is not being respected.

Expected behavior

Expect the compiler to infer argument type as string when nameof is used in a pattern match.

Actual behavior

Compiler infers argument type as generic argument when nameof is used in a pattern match.

Known workarounds

Explicit type annotation.

let f (x:string) = match x with nameof x -> true | _ -> false
@niesmo niesmo added the Bug label Jun 24, 2022
@NinoFloris
Copy link
Contributor

@dsyme this is indeed producing invalid IL, hit it today as well.

@dsyme dsyme added Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code. labels Jul 4, 2022
@dsyme
Copy link
Contributor

dsyme commented Jul 4, 2022

Thanks, should be a simple fix

@dsyme
Copy link
Contributor

dsyme commented Jul 8, 2022

@vzarytovskii this is a good first issue, happy to guide the fix

@edgarfgp
Copy link
Contributor

I have also hit this . Happy to help fixing this with a little bit of guidance as I’m still new to the compiler . cc @dsyme

@ntovas
Copy link
Contributor

ntovas commented Oct 9, 2022

I looked a bit into this and to me it seems that the issue to be in match than in nameof implementation.
I would like some guidance to make a fix for this, @vzarytovskii can you help?

@vzarytovskii
Copy link
Member

vzarytovskii commented Oct 9, 2022

I looked a bit into this and to me it seems that the issue to be in match than in nameof implementation.
I would like some guidance to make a fix for this, @vzarytovskii can you help?

Hey, @ntovas, I'm on vacation currently, without acces to my laptop unfortunately :(

Perhaps someone from the team can chime in, and help you looking into it? @dotnet/fsharp-team-msft ping!

@T-Gro
Copy link
Member

T-Gro commented Oct 10, 2022

@ntovas :

This is the approach I would take:
Add a failing test into the Component.Tests suite, into \tests\FSharp.Compiler.ComponentTests\Language*NameofTests*.fs .

Before starting it, sprinkle breakpoints around code in the TypeChecking state, so that you can step the execution and investigate the available parameters.

One of the places that seems to be related is \src\Compiler*Checking**CheckPatterns*.fs . I would try to put a few breakpoints into that and trace it - e.g. to verify that the nameof is infered to be a constant expression, and also explicitely marked as constant expression of string type.

All nameof-related functionality is a behind a feature flag, which can also give you an idea at which places the compiler interacts with this feature:
g.langVersion.SupportsFeature LanguageFeature.NameOf

@vzarytovskii
Copy link
Member

vzarytovskii commented Oct 10, 2022

I would also add that nameof is not a typical function, and has a special treatment in the compiler. That's why it behaves differently to all other functions.

@ntovas
Copy link
Contributor

ntovas commented Oct 11, 2022

Hey @T-Gro ,
Maybe you can check the linked PR?

@T-Gro
Copy link
Member

T-Gro commented Oct 11, 2022

On it :)

ntovas added a commit to ntovas/fsharp that referenced this issue Oct 18, 2022
@T-Gro T-Gro self-assigned this Nov 3, 2022
@T-Gro T-Gro modified the milestones: Backlog, November-2022 Nov 3, 2022
Repository owner moved this from Not Planned to Done in F# Compiler and Tooling Nov 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Checking Type checking, attributes and all aspects of logic checking Bug good first issue help wanted Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

7 participants