Compiler does not infer string type for nameof pattern
See original GitHub issueWhen 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
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:10 (10 by maintainers)
Top Results From Across the Web
Why compiler cannot infer generic types of the inner class ...
When the above code snippet is compiled, it leads to Compile-Time error saying "incompatible types: cannot infer type arguments for A.InnerA<> .
Read more >What's the tradeoff for type inference?
The compiler won't complain if you give a function a less general type than would be inferred. The classic example is map ::...
Read more >Documentation - Advanced Types
This page lists some of the more advanced ways in which you can model types, it works in tandem with the Utility Types...
Read more >How To Use Generics in TypeScript
Generics are a fundamental feature of statically-typed languages, allowing developers to pass types as parameters to a type, function, ...
Read more >C# compiler breaking changes since C# 10
Possible workarounds are: Rename the type parameter or parameter to avoid shadowing the name from outer scope. Use a string literal instead of ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@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
Hey @T-Gro , Maybe you can check the linked PR?