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

Creating a generative type provider with multiple type instantiations results in incorrect unverifiable IL #905

Closed
7sharp9 opened this issue Jan 28, 2016 · 4 comments

Comments

@7sharp9
Copy link
Contributor

7sharp9 commented Jan 28, 2016

Given the following generative provider:

[<TypeProvider>]
type GenerativeProvider (config : TypeProviderConfig) as this =
    inherit TypeProviderForNamespaces ()

    let ns = "BasicProvider.Generative"
    let asm = Assembly.LoadFrom(config.RuntimeAssembly)

    let createTypes () =
        let myType = ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>, IsErased=false)
        let myCtor = ProvidedConstructor(parameters = [], InvokeCode= (fun args -> <@@()@@>))
        let myStaticProp = ProvidedProperty("MyStaticProperty", typeof<string>, IsStatic = true, GetterCode = (fun args -> <@@ "Hello generative world" @@>))
        let myProp = ProvidedProperty("MyProperty", typeof<string>, IsStatic = false, GetterCode = (fun args -> <@@ "Hello generative world" @@>))
        let myStaticMethod = ProvidedMethod("MyStaticMethod", [], typeof<string>, IsStaticMethod=true, InvokeCode = (fun args -> <@@ "Hello generative world" @@>))
        let myMethod = ProvidedMethod("MyMethod", [], typeof<string>, IsStaticMethod=false, InvokeCode = (fun args -> <@@ "Hello generative world" @@>))

        myType.AddMember(myCtor)
        myType.AddMember(myStaticProp)
        myType.AddMember(myProp)
        myType.AddMember(myStaticMethod)
        myType.AddMember(myMethod)
        [myType]

    do
        let types = createTypes()
        let assemblyName =  Path.ChangeExtension(Path.GetTempFileName(), ".dll")
        let pa = ProvidedAssembly(assemblyName)
        pa.AddTypes types
        this.AddNamespace(ns, types )

And the following consumer:

namespace test
module main =

    type t = BasicProvider.Generative.MyType
    type u = BasicProvider.Generative.MyType

    [<EntryPoint>]
    let main argv =
      let tinstance = t()
      let uinstance = u()
      printfn "tinstance.MyProperty=%s" tinstance.MyProperty
      printfn "uinstance.MyProperty=%s" uinstance.MyProperty
      System.Console.ReadLine() |> ignore
      0

Incorrect IL is generated in the constructors for the type t. Notice below that type t is instantiated in correctly with type u.

ildasm output

This is also evident in the properties too:
ildasm properties

Finally peverify confirms this too:

Warning: Method has multiple semantics. [token:0x06000003] [hr:0x80131299]
Warning: Method has multiple semantics. [token:0x06000004] [hr:0x80131299]
Error: Property has related method belonging to another type (method: 0x06000003; type: 0x02000003). [token:0x17000003] [hr:0x801312C5]
Error: Property has related method belonging to another type (method: 0x06000004; type: 0x02000003). [token:0x17000004] [hr:0x801312C5]

Heres a gist of full il output: https://gist.github.com/7sharp9/79469a0861850791c6ec
Repo can be found here: https://github.com/7sharp9/IntrinsicTypeExtensions

@dsyme
Copy link
Contributor

dsyme commented Jan 28, 2016

Duplicate of #37?

@7sharp9
Copy link
Contributor Author

7sharp9 commented Jan 28, 2016

Ah yes, sorry missed that, I came to the same conclusion that the static linker somehow needed to duplicate the ILDefs etc to avoid the same reference being used.

I came across this while checking the intrinsic type extension patch #882. I initially though I had broken it :-)

@7sharp9
Copy link
Contributor Author

7sharp9 commented Jan 28, 2016

The information here may be useful anyway, closing.

@dsyme
Copy link
Contributor

dsyme commented Jan 28, 2016

Yes, very thorough report, will be helpful, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants