Skip to content

Commit 6783b97

Browse files
authored
Merge branch 'main' into otel
2 parents 43394e6 + cdc5963 commit 6783b97

File tree

5 files changed

+105
-48
lines changed

5 files changed

+105
-48
lines changed

src/Compiler/AbstractIL/il.fs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ type PrimaryAssembly =
5454
| System_Runtime -> "System.Runtime"
5555
| NetStandard -> "netstandard"
5656

57+
static member IsPossiblePrimaryAssembly(fileName: string) =
58+
let name = System.IO.Path.GetFileNameWithoutExtension(fileName)
59+
60+
String.Compare(name, "mscorlib", true) <> 0
61+
|| String.Compare(name, "System.Runtime", true) <> 0
62+
|| String.Compare(name, "netstandard", true) <> 0
63+
|| String.Compare(name, "System.Private.CoreLib", true) <> 0
64+
5765
// --------------------------------------------------------------------
5866
// Utilities: type names
5967
// --------------------------------------------------------------------
@@ -2803,12 +2811,16 @@ and [<Sealed>] ILTypeDefs(f: unit -> ILPreTypeDef[]) =
28032811
member x.GetEnumerator() =
28042812
(seq { for pre in array.Value -> pre.GetTypeDef() }).GetEnumerator()
28052813

2806-
member x.AsArrayOfPreTypeDefs() = array.Value
2814+
member _.AsArrayOfPreTypeDefs() = array.Value
28072815

2808-
member x.FindByName nm =
2816+
member _.FindByName nm =
28092817
let ns, n = splitILTypeName nm
28102818
dict.Value[ (ns, n) ].GetTypeDef()
28112819

2820+
member _.ExistsByName nm =
2821+
let ns, n = splitILTypeName nm
2822+
dict.Value.ContainsKey((ns, n))
2823+
28122824
and [<NoEquality; NoComparison>] ILPreTypeDef =
28132825
abstract Namespace: string list
28142826
abstract Name: string
@@ -3331,15 +3343,9 @@ let tname_UIntPtr = "System.UIntPtr"
33313343
let tname_TypedReference = "System.TypedReference"
33323344

33333345
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
3334-
type ILGlobals
3335-
(
3336-
primaryScopeRef: ILScopeRef,
3337-
assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list,
3338-
fsharpCoreAssemblyScopeRef: ILScopeRef
3339-
) =
3346+
type ILGlobals(primaryScopeRef: ILScopeRef, equivPrimaryAssemblyRefs: ILAssemblyRef list, fsharpCoreAssemblyScopeRef: ILScopeRef) =
33403347

3341-
let assembliesThatForwardToPrimaryAssembly =
3342-
Array.ofList assembliesThatForwardToPrimaryAssembly
3348+
let equivPrimaryAssemblyRefs = Array.ofList equivPrimaryAssemblyRefs
33433349

33443350
let mkSysILTypeRef nm = mkILTyRef (primaryScopeRef, nm)
33453351

@@ -3394,17 +3400,16 @@ type ILGlobals
33943400

33953401
member x.IsPossiblePrimaryAssemblyRef(aref: ILAssemblyRef) =
33963402
aref.EqualsIgnoringVersion x.primaryAssemblyRef
3397-
|| assembliesThatForwardToPrimaryAssembly
3398-
|> Array.exists aref.EqualsIgnoringVersion
3403+
|| equivPrimaryAssemblyRefs |> Array.exists aref.EqualsIgnoringVersion
33993404

34003405
/// For debugging
34013406
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
34023407
member x.DebugText = x.ToString()
34033408

34043409
override x.ToString() = "<ILGlobals>"
34053410

3406-
let mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef) =
3407-
ILGlobals(primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef)
3411+
let mkILGlobals (primaryScopeRef, equivPrimaryAssemblyRefs, fsharpCoreAssemblyScopeRef) =
3412+
ILGlobals(primaryScopeRef, equivPrimaryAssemblyRefs, fsharpCoreAssemblyScopeRef)
34083413

34093414
let mkNormalCall mspec = I_call(Normalcall, mspec, None)
34103415

src/Compiler/AbstractIL/il.fsi

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open FSharp.Compiler.IO
88
open System.Collections.Generic
99
open System.Reflection
1010

11+
/// Represents the target primary assembly
1112
[<RequireQualifiedAccess>]
1213
type internal PrimaryAssembly =
1314
| Mscorlib
@@ -16,6 +17,11 @@ type internal PrimaryAssembly =
1617

1718
member Name: string
1819

20+
/// Checks if an assembly resolution may represent a primary assembly that actually contains the
21+
/// definition of Sytem.Object. Note that the chosen target primary assembly may not actually be the one
22+
/// that contains the definition of System.Object - it is just the one we are choosing to emit for.
23+
static member IsPossiblePrimaryAssembly: fileName: string -> bool
24+
1925
/// Represents guids
2026
type ILGuid = byte[]
2127

@@ -1407,12 +1413,12 @@ type ILTypeDefs =
14071413
/// Get some information about the type defs, but do not force the read of the type defs themselves.
14081414
member internal AsArrayOfPreTypeDefs: unit -> ILPreTypeDef[]
14091415

1410-
/// Calls to <c>FindByName</c> will result in any laziness in the overall
1411-
/// set of ILTypeDefs being read in in addition
1412-
/// to the details for the type found, but the remaining individual
1413-
/// type definitions will not be read.
1416+
/// Calls to <c>FindByName</c> will result in all the ILPreTypeDefs being read.
14141417
member internal FindByName: string -> ILTypeDef
14151418

1419+
/// Calls to <c>ExistsByName</c> will result in all the ILPreTypeDefs being read.
1420+
member internal ExistsByName: string -> bool
1421+
14161422
/// Represents IL Type Definitions.
14171423
[<NoComparison; NoEquality>]
14181424
type ILTypeDef =
@@ -1841,10 +1847,11 @@ type internal ILGlobals =
18411847
member IsPossiblePrimaryAssemblyRef: ILAssemblyRef -> bool
18421848

18431849
/// Build the table of commonly used references given functions to find types in system assemblies
1850+
///
1851+
/// primaryScopeRef is the primary assembly we are emitting
1852+
/// equivPrimaryAssemblyRefs are ones regarded as equivalent
18441853
val internal mkILGlobals:
1845-
primaryScopeRef: ILScopeRef *
1846-
assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list *
1847-
fsharpCoreAssemblyScopeRef: ILScopeRef ->
1854+
primaryScopeRef: ILScopeRef * equivPrimaryAssemblyRefs: ILAssemblyRef list * fsharpCoreAssemblyScopeRef: ILScopeRef ->
18481855
ILGlobals
18491856

18501857
val internal PrimaryAssemblyILGlobals: ILGlobals

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8921,8 +8921,11 @@ and TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed
89218921
// To get better warnings we special case some of the few known mutate-a-struct method names
89228922
let mutates = (if methodName = "MoveNext" || methodName = "GetNextArg" then DefinitelyMutates else PossiblyMutates)
89238923

8924-
// Check if we have properties with "init-only" setters, which we try to call after init is done.
8925-
CheckInitProperties g (List.head minfos) methodName mItem
8924+
match minfos with
8925+
| minfo :: _ ->
8926+
// Check if we have properties with "init-only" setters, which we try to call after init is done.
8927+
CheckInitProperties g minfo methodName mItem
8928+
| _ -> ()
89268929

89278930
#if !NO_TYPEPROVIDERS
89288931
match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, tyArgsOpt, mExprAndItem, mItem) with

src/Compiler/Driver/CompilerImports.fs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,13 +2321,13 @@ and [<Sealed>] TcImports
23212321
| _, [ ResolvedImportedAssembly ccu ] -> ccu.FSharpViewOfMetadata.ILScopeRef
23222322
| _ -> failwith "primaryScopeRef - unexpected"
23232323

2324+
let resolvedAssemblies = tcResolutions.GetAssemblyResolutions()
2325+
23242326
let primaryAssemblyResolvedPath =
23252327
match primaryAssemblyResolution with
23262328
| [ primaryAssemblyResolution ] -> primaryAssemblyResolution.resolvedPath
23272329
| _ -> failwith "primaryAssemblyResolvedPath - unexpected"
23282330

2329-
let resolvedAssemblies = tcResolutions.GetAssemblyResolutions()
2330-
23312331
let readerSettings: ILReaderOptions =
23322332
{
23332333
pdbDirPath = None
@@ -2336,28 +2336,28 @@ and [<Sealed>] TcImports
23362336
tryGetMetadataSnapshot = tcConfig.tryGetMetadataSnapshot
23372337
}
23382338

2339-
let tryFindAssemblyByExportedType manifest (exportedType: ILExportedTypeOrForwarder) =
2340-
match exportedType.ScopeRef, primaryScopeRef with
2341-
| ILScopeRef.Assembly aref1, ILScopeRef.Assembly aref2 when aref1.EqualsIgnoringVersion aref2 ->
2342-
mkRefToILAssembly manifest |> Some
2343-
| _ -> None
2344-
2345-
let tryFindAssemblyThatForwardsToPrimaryAssembly manifest =
2346-
manifest.ExportedTypes.TryFindByName "System.Object"
2347-
|> Option.bind (tryFindAssemblyByExportedType manifest)
2348-
2349-
// Determine what other assemblies could have been the primary assembly
2350-
// by checking to see if "System.Object" is an exported type.
2351-
let assembliesThatForwardToPrimaryAssembly =
2352-
resolvedAssemblies
2353-
|> List.choose (fun resolvedAssembly ->
2354-
if primaryAssemblyResolvedPath <> resolvedAssembly.resolvedPath then
2355-
let reader = OpenILModuleReader resolvedAssembly.resolvedPath readerSettings
2356-
2357-
reader.ILModuleDef.Manifest
2358-
|> Option.bind tryFindAssemblyThatForwardsToPrimaryAssembly
2359-
else
2360-
None)
2339+
let tryFindEquivPrimaryAssembly (resolvedAssembly: AssemblyResolution) =
2340+
if primaryAssemblyResolvedPath = resolvedAssembly.resolvedPath then
2341+
None
2342+
else
2343+
let reader = OpenILModuleReader resolvedAssembly.resolvedPath readerSettings
2344+
let mdef = reader.ILModuleDef
2345+
2346+
// We check the exported types of all assemblies, since many may forward System.Object,
2347+
// but only check the actual type definitions for specific assemblies that we know
2348+
// might actually declare System.Object.
2349+
match mdef.Manifest with
2350+
| Some manifest when
2351+
manifest.ExportedTypes.TryFindByName "System.Object" |> Option.isSome
2352+
|| PrimaryAssembly.IsPossiblePrimaryAssembly resolvedAssembly.resolvedPath
2353+
&& mdef.TypeDefs.ExistsByName "System.Object"
2354+
->
2355+
mkRefToILAssembly manifest |> Some
2356+
| _ -> None
2357+
2358+
// Find assemblies which also declare System.Object
2359+
let equivPrimaryAssemblyRefs =
2360+
resolvedAssemblies |> List.choose tryFindEquivPrimaryAssembly
23612361

23622362
let! fslibCcu, fsharpCoreAssemblyScopeRef =
23632363
node {
@@ -2406,7 +2406,7 @@ and [<Sealed>] TcImports
24062406
sysCcus |> Array.tryFind (fun ccu -> ccuHasType ccu path typeName)
24072407

24082408
let ilGlobals =
2409-
mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef)
2409+
mkILGlobals (primaryScopeRef, equivPrimaryAssemblyRefs, fsharpCoreAssemblyScopeRef)
24102410

24112411
// OK, now we have both mscorlib.dll and FSharp.Core.dll we can create TcGlobals
24122412
let tcGlobals =

tests/FSharp.Compiler.UnitTests/FsiTests.fs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ open FluentAssertions
66
open FSharp.Compiler.Interactive.Shell
77
open FSharp.Test
88
open Xunit
9+
open System.Threading
10+
11+
type Sentinel () =
12+
let x = ()
13+
14+
module MyModule =
15+
let test(x: int) = ()
916

1017
[<Collection("SingleThreaded")>]
1118
module FsiTests =
@@ -636,3 +643,38 @@ module FsiTests =
636643
let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne
637644
Assert.shouldBe typeof<CustomType2[,]> boundValue.Value.ReflectionType
638645
boundValue.Value.ReflectionValue.Should().Be(mdArr, "") |> ignore
646+
647+
#if NETCOREAPP
648+
[<Fact>]
649+
let ``Evaluating simple reference and code succeeds under permutations``() =
650+
651+
for useSdkRefsFlag in ["/usesdkrefs"; "/usesdkrefs-"] do
652+
for multiemitFlag in ["/multiemit"; "/multiemit-"] do
653+
let config = FsiEvaluationSession.GetDefaultConfiguration()
654+
let argv = [|
655+
typeof<Sentinel>.Assembly.Location
656+
"--noninteractive"
657+
"--targetprofile:netcore"
658+
"--langversion:preview"
659+
multiemitFlag
660+
useSdkRefsFlag
661+
|]
662+
let fsi = FsiEvaluationSession.Create(config, argv, TextReader.Null, TextWriter.Null, TextWriter.Null)
663+
let assemblyPath = typeof<Sentinel>.Assembly.Location.Replace("\\", "/")
664+
let code = $@"
665+
#r ""{assemblyPath}""
666+
FSharp.Compiler.UnitTests.MyModule.test(3)"
667+
let ch, errors = fsi.EvalInteractionNonThrowing(code, CancellationToken.None)
668+
errors
669+
|> Array.iter (fun e -> printfn "error: %A" e)
670+
match ch with
671+
| Choice1Of2 v ->
672+
let v =
673+
match v with
674+
| Some v -> sprintf "%A" v.ReflectionValue
675+
| None -> "(none)"
676+
printfn "value: %A" v
677+
| Choice2Of2 e ->
678+
printfn "exception: %A" e
679+
raise e
680+
#endif

0 commit comments

Comments
 (0)