dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.93k stars 788 forks source link

Instantiating a generative type provider twice results in invalid IL #37

Open KevinRansom opened 9 years ago

KevinRansom commented 9 years ago

[from fsbugs]

If one defines a generative type provider with some fields/properties, then creates 2 identical versions of that provided type:

type T2 = Samples.ShareInfo.TPTest.TPTestType
type T  = Samples.ShareInfo.TPTest.TPTestType

the resulting assembly contains invalid IL.

file attachments

comments latkin wrote Mar 24, 2014 at 4:22 PM [x]

[investigation from Vlad] It looks like a bug in type relocation code in fsc.fs around ~1531.

Here we have 2 type reference T and T2 that point to one actual type definition so the final copy-and-update expression below will create 2 different ILTypeDefs that originate from the same ILTypeDef => they will share same set of members (up to reference equality) => later it will lead to unexpected consequences in codegen because we'll generate normal type T2 and type T where property definition uses metadata token of getter from the type T2 => invalid IL.

 let generatedILTypeDefs = 
    let rec buildRelocatedGeneratedType (ProviderGeneratedType(ilOrigTyRef, ilTgtTyRef, ch)) = 
        let isNested = ilTgtTyRef.Enclosing |> nonNil
        if allTypeDefsInProviderGeneratedAssemblies.ContainsKey ilOrigTyRef then 
            let ilOrigTypeDef = allTypeDefsInProviderGeneratedAssemblies.[ilOrigTyRef]
            if debugStaticLinking then printfn "Relocating %s to %s " ilOrigTyRef.QualifiedName ilTgtTyRef.QualifiedName
            { ilOrigTypeDef with 
                  Name = ilTgtTyRef.Name
                  Access = (match ilOrigTypeDef.Access with 
                            | ILTypeDefAccess.Public when isNested -> ILTypeDefAccess.Nested ILMemberAccess.Public 
                            | ILTypeDefAccess.Private when isNested -> ILTypeDefAccess.Nested ILMemberAccess.Assembly 
                            | x -> x)
                  NestedTypes = mkILTypeDefs (List.map buildRelocatedGeneratedType ch) }
enricosada commented 8 years ago

additional info/repro in @7Sharp9 https://github.com/Microsoft/visualfsharp/issues/905#issue-129416759

7sharp9 commented 8 years ago

@enricosada I was going to add a comment, got distracted though :-)

enricosada commented 8 years ago

@7sharp9 np, it's a nice bug report and useful info, better not lose it