You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A static parameter for a provided type that has the type obj (or any other type that is not a direct type of a constant expression that does not involve upcasting) cannot ever be given an explicit value.
[<Literal>]letv= Providers.Const<const(2:obj)>.Value
printf "%A" v
Expected behavior
The program should compile and "2" should be printed.
Actual behavior
error FS3047: Unknown static argument kind 'System.Object' when resolving a reference to a provided type or method 'Const,value="2"'
error FS1109: A reference to the type 'Providers.Const,value="2"' in assembly 'Providers' was found, but the type could not be found in that assembly
Known workarounds
I am not aware of any workarounds that could produce a provided type based on a constant expression of an arbitrary type.
Related information
This or a similar issue prevents the following static arguments from being accepted:
const (expr:obj).
Same but with ValueType, Enum or any less specific type than those permitted by constant expressions, or, in general, const (upcast expr) when the static parameter has a less specific type.
null (any type).
I am led to believe that this is a bug for the following reasons:
The specification does not seem to mention any restriction on the types of static arguments, so I presume it should be able to be anything that can be given to ApplyStaticArguments.
Implicit arguments (those where the parameter is optional and no value is given) work fine and the value is correctly passed to ApplyStaticArguments (although any type works there).
ApplyStaticArguments is actually still called here, even with the errors. This can be verified by uncommenting failwith and observing that "2" is thrown.
There are other contexts where constant expressions can be treated as obj, such as in custom attributes.
From what I can tell, at least a part of the issue is caused here, where the type is hard-checked against a list of concrete types.
Being able to accept a type argument of an arbitrary type can have all sorts of nice use cases, from specifying values in queries, formatting, hashing, serialization, or other operations on constant expressions.
@kerams That is just about syntax as far as I can tell, so const expr should, I believe, cover this case. But thank you for mentioning this, since now I realized even this is not working, while permitted by the other syntax that is not relying on const:
[<Literal>]letnullobj:obj =null[<Literal>]letv= Providers.Const<nullobj>.Value
printf "%A" v
error FS3045: Invalid static argument to provided type. Expected an argument of kind 'obj'.
But it is an argument of kind obj! (And just to be sure, I verified that it works fine for a parameter and argument of a concrete type).
While investigating this, I also discovered another compiler issue: #18319. If such literals are even supposed to be valid, they also cannot be used as static arguments.
A static parameter for a provided type that has the type
obj
(or any other type that is not a direct type of a constant expression that does not involve upcasting) cannot ever be given an explicit value.Repro steps
Expected behavior
The program should compile and "2" should be printed.
Actual behavior
Known workarounds
I am not aware of any workarounds that could produce a provided type based on a constant expression of an arbitrary type.
Related information
This or a similar issue prevents the following static arguments from being accepted:
const (expr:obj)
.ValueType
,Enum
or any less specific type than those permitted by constant expressions, or, in general,const (upcast expr)
when the static parameter has a less specific type.null
(any type).I am led to believe that this is a bug for the following reasons:
ApplyStaticArguments
.ApplyStaticArguments
(although any type works there).ApplyStaticArguments
is actually still called here, even with the errors. This can be verified by uncommentingfailwith
and observing that "2" is thrown.obj
, such as in custom attributes.From what I can tell, at least a part of the issue is caused here, where the type is hard-checked against a list of concrete types.
Being able to accept a type argument of an arbitrary type can have all sorts of nice use cases, from specifying values in queries, formatting, hashing, serialization, or other operations on constant expressions.
FSharpObjectConstExample.zip
The text was updated successfully, but these errors were encountered: