Sunday, May 1, 2016

Error FS3039: A direct reference to the generated type 'MyType' is not permitted

Leave a Comment

The following type provider was intended to create GeneratedNamespace.MyType which accepts a static parameter of type string and contains only an empty constructor

namespace TypeProviderTest  open Microsoft.FSharp.Core.CompilerServices open ProviderImplementation.ProvidedTypes open System.Reflection open System  [<TypeProvider>] type MyTypeProvider(config:TypeProviderConfig) as this =      inherit TypeProviderForNamespaces()     let namespaceName="GeneratedNamespace"     let assembly = Assembly.LoadFrom(config.RuntimeAssembly)      //Provides definition, based on type parameters     let instantiationFunction typeName (typeParams:obj[]) =         match typeParams with                 | [|:? string as param|] ->                      //Creates an empty non-erased type                     let definition = ProvidedTypeDefinition(                                         assembly,                                         namespaceName,                                         typeName,                                         Some typedefof<Object>,                                         IsErased = false                                         )                      //Creates an empty constructor                     let emptyCtor = ProvidedConstructor (parameters = [])                     //Provides a call to base constructor                      //(http://stackoverflow.com/questions/22520352/)                     //Doesn't seem to help                     let objCtor = typedefof<Object>.GetType().GetConstructor([||])                     emptyCtor.BaseConstructorCall <- (fun _ -> objCtor,[])                     emptyCtor.AddXmlDoc("Empty constructor test")                      definition.AddMember(emptyCtor)                     definition                 | _ -> failwith "That was not supported"      let  staticParams = [ProvidedStaticParameter("value",typedefof<string>)]      let t = ProvidedTypeDefinition(assembly,namespaceName,"MyType",Some typedefof<Object>)     do t.DefineStaticParameters(staticParams,instantiationFunction)       do this.AddNamespace(namespaceName,[t]) [<assembly:TypeProviderAssembly>] do () 

When I try to use it like this

open System open GeneratedNamespace type X = MyType<"Abacaba"> [<EntryPoint>] let main argv =      printfn "%A %A" typedefof<X> (new X())     Console.ReadLine() |> ignore     0  

The line type X = MyType<"Abacaba"> produces the error

Error FS3039: A direct reference to the generated type 'MyType' is not permitted.

I added a base constructor call, but it didn't help

The type provider is made generative intentionally

Is there an error in my type provider?

1 Answers

Answers 1

I'm not sure how to make it fully work, but I think the reason why you're getting the error is that the parameterised type is an erased type (while the type that you return once static parameters are provided is not an erased type).

Adding IsErased = false to t makes the error go away:

let  staticParams = [ProvidedStaticParameter("value",typedefof<string>)]  let t =    ProvidedTypeDefinition     (assembly,namespaceName,"MyType",Some typedefof<Object>,IsErased = false) do t.DefineStaticParameters(staticParams,instantiationFunction) 

With this, the code can be compiled, but trying to create an instance using new X() gives:

error FS0192: internal error: null: GetTRefType

So, there is probably something else that I'm missing too. Perhaps it can point you into the right direction though!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment