Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
### Fixed

* Fix missing warning for recursive calls in list comprehensions. ([PR #16652](https://github.com/dotnet/fsharp/pull/16652))
* Code generated files with > 64K methods and generated symbols crash when loaded. Use infered sequence points for debugging. ([Issue #16399](https://github.com/dotnet/fsharp/issues/16399), [#PR 16514](https://github.com/dotnet/fsharp/pull/16514))
* `nameof Module` expressions and patterns are processed to link files in `--test:GraphBasedChecking`. ([PR #16550](https://github.com/dotnet/fsharp/pull/16550))
* Graph Based Checking doesn't throw on invalid parsed input so it can be used for IDE scenarios ([PR #16575](https://github.com/dotnet/fsharp/pull/16575), [PR #16588](https://github.com/dotnet/fsharp/pull/16588), [PR #16643](https://github.com/dotnet/fsharp/pull/16643))
* Various parenthesization API fixes. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666))
* Keep parens for problematic exprs (`if`, `match`, etc.) in `$"{(…):N0}"`, `$"{(…),-3}"`, etc. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578))
* Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode [#PR 16471](https://github.com/dotnet/fsharp/pull/16471))

* Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode ([PR #16471](https://github.com/dotnet/fsharp/pull/16471))
* `[<CliEvent>]` member should not produce property symbol. ([Issue #16640](https://github.com/dotnet/fsharp/issues/16640), [PR #16658](https://github.com/dotnet/fsharp/pull/16658))
* Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661))

### Added

Expand All @@ -14,6 +17,7 @@
* Name resolution: keep type vars in subsequent checks ([PR #16456](https://github.com/dotnet/fsharp/pull/16456))
* Higher-order-function-based API for working with the untyped abstract syntax tree. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462))
* Allow returning bool instead of unit option for partial active patterns. ([Language suggestion #1041](https://github.com/fsharp/fslang-suggestions/issues/1041), [PR #16473](https://github.com/dotnet/fsharp/pull/16473))
* Symbols: Add GenericArguments to FSharpEntity ([PR #16470](https://github.com/dotnet/fsharp/pull/16470))

### Changed

Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/.VisualStudio/17.10.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### Fixed

* Show signature help mid-pipeline in more scenarios. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462))
* Various unneeded parentheses code fix improvements. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666))

### Changed

Expand Down
9 changes: 4 additions & 5 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Dependencies>
<ProductDependencies>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.24073.1">
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.24105.3">
<Uri>https://github.com/dotnet/source-build-reference-packages</Uri>
<Sha>412264fd6c04712d1d31ff05d37c6919101ef4f4</Sha>
<Sha>ffac2194c39660f03761ba81bdd6026202942184</Sha>
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
</Dependency>
<!-- Intermediate is necessary for source build. -->
Expand All @@ -31,9 +30,9 @@
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.24075.5">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.24081.5">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>07cf24f27ee58b5d1a9662334a101d84bd1e07e5</Sha>
<Sha>be88b08c41971b52ec11aec05ef31e72185d4a1f</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="1.0.0-beta.23475.1" CoherentParentDependency="Microsoft.DotNet.Arcade.Sdk">
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"perl": "5.38.0.1"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24075.5",
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24081.5",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
}
}
26 changes: 26 additions & 0 deletions src/Compiler/AbstractIL/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3952,6 +3952,29 @@ let mdef_code2code f (md: ILMethodDef) =
let b = MethodBody.IL(notlazy ilCode)
md.With(body = notlazy b)

let appendInstrsToCode (instrs: ILInstr list) (c2: ILCode) =
let instrs = Array.ofList instrs

match
c2.Instrs
|> Array.tryFindIndexBack (fun instr ->
match instr with
| I_ret -> true
| _ -> false)
with
| Some 0 ->
{ c2 with
Instrs = Array.concat [| instrs; c2.Instrs |]
}
| Some index ->
{ c2 with
Instrs = Array.concat [| c2.Instrs[.. index - 1]; instrs; c2.Instrs[index..] |]
}
| None ->
{ c2 with
Instrs = Array.append c2.Instrs instrs
}

let prependInstrsToCode (instrs: ILInstr list) (c2: ILCode) =
let instrs = Array.ofList instrs
let n = instrs.Length
Expand Down Expand Up @@ -3985,6 +4008,9 @@ let prependInstrsToCode (instrs: ILInstr list) (c2: ILCode) =
Instrs = Array.append instrs c2.Instrs
}

let appendInstrsToMethod newCode md =
mdef_code2code (appendInstrsToCode newCode) md

let prependInstrsToMethod newCode md =
mdef_code2code (prependInstrsToCode newCode) md

Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/AbstractIL/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2162,8 +2162,9 @@ val internal mkRawDataValueTypeDef: ILType -> string * size: int32 * pack: uint1
/// the code, and the first instruction will be the new entry
/// of the method. The instructions should be non-branching.

val internal appendInstrsToCode: ILInstr list -> ILCode -> ILCode
val internal appendInstrsToMethod: ILInstr list -> ILMethodDef -> ILMethodDef
val internal prependInstrsToCode: ILInstr list -> ILCode -> ILCode

val internal prependInstrsToMethod: ILInstr list -> ILMethodDef -> ILMethodDef

/// Injecting initialization code into a class.
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,11 +1140,11 @@ module MutRecBindingChecking =
for b1, b2 in List.pairwise defnAs do
match b1, b2 with
| TyconBindingPhase2A.Phase2AMember {
SyntacticBinding = NormalizedBinding(pat = SynPat.Named(ident = SynIdent(ident = getIdent)); valSynData = SynValData(memberFlags = Some mf))
SyntacticBinding = NormalizedBinding(pat = SynPat.Named(ident = SynIdent(ident = Get_OrSet_Ident & getIdent)); valSynData = SynValData(memberFlags = Some mf))
RecBindingInfo = RecursiveBindingInfo(vspec = vGet)
},
TyconBindingPhase2A.Phase2AMember {
SyntacticBinding = NormalizedBinding(pat = SynPat.Named(ident = SynIdent(ident = setIdent)))
SyntacticBinding = NormalizedBinding(pat = SynPat.Named(ident = SynIdent(ident = Get_OrSet_Ident & setIdent)))
RecBindingInfo = RecursiveBindingInfo(vspec = vSet)
} when Range.equals getIdent.idRange setIdent.idRange ->
match vGet.ApparentEnclosingEntity with
Expand Down
12 changes: 6 additions & 6 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ type Item =
| Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName
| Item.DelegateCtor ty ->
match ty with
| AbbrevOrAppTy tcref -> tcref.DisplayNameCore
| AbbrevOrAppTy(tcref, _) -> tcref.DisplayNameCore
// This case is not expected
| _ -> ""
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayNameCore
Expand Down Expand Up @@ -309,7 +309,7 @@ type Item =
| Item.Property(info = pinfo :: _) -> pinfo.DisplayName
| Item.Event einfo -> einfo.DisplayName
| Item.MethodGroup(_, minfo :: _, _) -> minfo.DisplayName
| Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayName
| Item.DelegateCtor (AbbrevOrAppTy(tcref, _)) -> tcref.DisplayName
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayName
| Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayName
| Item.TypeVar (nm, _) -> nm |> ConvertLogicalNameToDisplayName
Expand Down Expand Up @@ -1872,11 +1872,11 @@ let (|EntityUse|_|) (item: Item) =
match item with
| Item.UnqualifiedType (tcref :: _) -> ValueSome tcref
| Item.ExnCase tcref -> ValueSome tcref
| Item.Types(_, [AbbrevOrAppTy tcref])
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> ValueSome tcref
| Item.Types(_, [AbbrevOrAppTy(tcref, _)])
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> ValueSome tcref
| Item.CtorGroup(_, ctor :: _) ->
match ctor.ApparentEnclosingType with
| AbbrevOrAppTy tcref -> ValueSome tcref
| AbbrevOrAppTy(tcref, _) -> ValueSome tcref
| _ -> ValueNone
| _ -> ValueNone

Expand Down Expand Up @@ -1958,7 +1958,7 @@ let ItemsAreEffectivelyEqual g orig other =
not tp1.IsCompilerGenerated && not tp1.IsFromError &&
not tp2.IsCompilerGenerated && not tp2.IsFromError &&
equals tp1.Range tp2.Range
| AbbrevOrAppTy tcref1, AbbrevOrAppTy tcref2 ->
| AbbrevOrAppTy(tcref1, _), AbbrevOrAppTy(tcref2, _) ->
tyconRefDefnEq g tcref1 tcref2
| _ -> false)

Expand Down
6 changes: 2 additions & 4 deletions src/Compiler/Checking/TailCallChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -539,12 +539,10 @@ and CheckExprOp cenv (op, tyargs, args, m) ctxt : unit =
| TOp.ValFieldSet _rf, _, [ _arg1; _arg2 ] -> ()

| TOp.Coerce, [ tgtTy; srcTy ], [ x ] ->
let tailCall = TailCall.YesFromExpr cenv.g x

if TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgtTy srcTy then
CheckExpr cenv x ctxt tailCall
CheckExpr cenv x ctxt TailCall.No
else
CheckExprNoByrefs cenv tailCall x
CheckExprNoByrefs cenv TailCall.No x

| TOp.Reraise, [ _ty1 ], [] -> ()

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ type MethInfo =
member x.DebuggerDisplayName =
match x with
| ILMeth(_, y, _) -> y.DeclaringTyconRef.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + y.ILName
| FSMeth(_, AbbrevOrAppTy tcref, vref, _) -> tcref.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + vref.LogicalName
| FSMeth(_, AbbrevOrAppTy(tcref, _), vref, _) -> tcref.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + vref.LogicalName
| FSMeth(_, _, vref, _) -> "??::" + vref.LogicalName
#if !NO_TYPEPROVIDERS
| ProvidedMeth(_, mi, _, m) -> "ProvidedMeth: " + mi.PUntaint((fun mi -> mi.Name), m)
Expand Down
80 changes: 45 additions & 35 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1908,7 +1908,16 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) =
if not discard then
AddPropertyDefToHash m gproperties pdef

member _.PrependInstructionsToSpecificMethodDef(cond, instrs, tag, imports) =
member _.AppendInstructionsToSpecificMethodDef(cond, instrs, tag, imports) =
match ResizeArray.tryFindIndex cond gmethods with
| Some idx -> gmethods[idx] <- appendInstrsToMethod instrs gmethods[idx]
| None ->
let body =
mkMethodBody (false, [], 1, nonBranchingInstrsToCode instrs, tag, imports)

gmethods.Add(mkILClassCtor body)

member this.PrependInstructionsToSpecificMethodDef(cond, instrs, tag, imports) =
match ResizeArray.tryFindIndex cond gmethods with
| Some idx -> gmethods[idx] <- prependInstrsToMethod instrs gmethods[idx]
| None ->
Expand All @@ -1917,6 +1926,8 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) =

gmethods.Add(mkILClassCtor body)

this

and TypeDefsBuilder() =

let tdefs =
Expand Down Expand Up @@ -2264,6 +2275,22 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf
/// static init fields on script modules.
let scriptInitFspecs = ConcurrentStack<ILFieldSpec * range>()

let initialInstrs seqpt feefee =
[
yield!
(if isEnvVarSet "NO_ADD_FEEFEE_TO_CCTORS" then []
elif isEnvVarSet "ADD_SEQPT_TO_CCTORS" then seqpt
else feefee) // mark start of hidden code
]

let finalInstrs fspec =
[
yield mkLdcInt32 0
yield mkNormalStsfld fspec
yield mkNormalLdsfld fspec
yield AI_pop
]

member _.AddScriptInitFieldSpec(fieldSpec, range) =
scriptInitFspecs.Push((fieldSpec, range))

Expand All @@ -2276,15 +2303,7 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf
let InitializeCompiledScript (fspec, m) =
let ilDebugRange = GenPossibleILDebugRange cenv m

mgbuf.AddExplicitInitToSpecificMethodDef(
(fun (md: ILMethodDef) -> md.IsEntryPoint),
tref,
fspec,
ilDebugRange,
imports,
[],
[]
)
mgbuf.AddExplicitInitToEntryPoint(tref, fspec, ilDebugRange, imports, [], [])

scriptInitFspecs |> Seq.iter InitializeCompiledScript
| None -> ()
Expand Down Expand Up @@ -2325,24 +2344,23 @@ and AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf
if ilMethodDef.IsEntryPoint then
explicitEntryPointInfo <- Some tref

member _.AddExplicitInitToSpecificMethodDef(cond, tref, fspec, sourceOpt, imports, feefee, seqpt) =
// Authoring a .cctor with effects forces the cctor for the 'initialization' module by doing a dummy store & load of a field
// Doing both a store and load keeps FxCop happier because it thinks the field is useful
let instrs =
[
yield!
(if isEnvVarSet "NO_ADD_FEEFEE_TO_CCTORS" then []
elif isEnvVarSet "ADD_SEQPT_TO_CCTORS" then seqpt
else feefee) // mark start of hidden code
yield mkLdcInt32 0
yield mkNormalStsfld fspec
yield mkNormalLdsfld fspec
yield AI_pop
]
member _.AddExplicitInitToEntryPoint(tref, fspec, sourceOpt, imports, feefee, seqpt) =

let cond = (fun (md: ILMethodDef) -> md.IsEntryPoint)

gtdefs
.FindNestedTypeDefBuilder(tref)
.PrependInstructionsToSpecificMethodDef(cond, instrs, sourceOpt, imports)
.PrependInstructionsToSpecificMethodDef(cond, (initialInstrs seqpt feefee) @ (finalInstrs fspec), sourceOpt, imports)
|> ignore

member _.AddExplicitInitToCctor(tref, fspec, sourceOpt, imports, feefee, seqpt) =

let cond = (fun (md: ILMethodDef) -> md.Name = ".cctor")

gtdefs
.FindNestedTypeDefBuilder(tref)
.PrependInstructionsToSpecificMethodDef(cond, initialInstrs seqpt feefee, sourceOpt, imports)
.AppendInstructionsToSpecificMethodDef(cond, finalInstrs fspec, sourceOpt, imports)

member _.AddEventDef(tref, edef) =
gtdefs.FindNestedTypeDefBuilder(tref).AddEventDef(edef)
Expand Down Expand Up @@ -10194,15 +10212,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: Checke
// This adds the explicit init of the .cctor to the explicit entry point main method
let ilDebugRange = GenPossibleILDebugRange cenv m

mgbuf.AddExplicitInitToSpecificMethodDef(
(fun md -> md.IsEntryPoint),
tref,
fspec,
ilDebugRange,
eenv.imports,
feefee,
seqpt
))
mgbuf.AddExplicitInitToEntryPoint(tref, fspec, ilDebugRange, eenv.imports, feefee, seqpt))

let cctorMethDef =
mkILClassCtor (MethodBody.IL(InterruptibleLazy.FromValue topCode))
Expand Down Expand Up @@ -10289,7 +10299,7 @@ and GenForceWholeFileInitializationAsPartOfCCtor cenv (mgbuf: AssemblyBuilder) (
// Doing both a store and load keeps FxCop happier because it thinks the field is useful
lazyInitInfo.Add(fun fspec feefee seqpt ->
let ilDebugRange = GenPossibleILDebugRange cenv m
mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.Name = ".cctor"), tref, fspec, ilDebugRange, imports, feefee, seqpt))
mgbuf.AddExplicitInitToCctor(tref, fspec, ilDebugRange, imports, feefee, seqpt))

/// Generate an Equals method.
and GenEqualsOverrideCallingIComparable cenv (tcref: TyconRef, ilThisTy, _ilThatTy) =
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1805,9 +1805,9 @@ type internal TypeCheckInfo
|> List.sortBy (fun d ->
let n =
match d.Item with
| Item.Types(_, AbbrevOrAppTy tcref :: _) -> 1 + tcref.TyparsNoRange.Length
| Item.Types(_, AbbrevOrAppTy(tcref, _) :: _) -> 1 + tcref.TyparsNoRange.Length
// Put delegate ctors after types, sorted by #typars. RemoveDuplicateItems will remove FakeInterfaceCtor and DelegateCtor if an earlier type is also reported with this name
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> 1000 + tcref.TyparsNoRange.Length
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> 1000 + tcref.TyparsNoRange.Length
// Put type ctors after types, sorted by #typars. RemoveDuplicateItems will remove DefaultStructCtors if a type is also reported with this name
| Item.CtorGroup(_, cinfo :: _) -> 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length
| _ -> 0
Expand All @@ -1823,10 +1823,10 @@ type internal TypeCheckInfo
items
|> List.groupBy (fun d ->
match d.Item with
| Item.Types(_, AbbrevOrAppTy tcref :: _)
| Item.Types(_, AbbrevOrAppTy(tcref, _) :: _)
| Item.ExnCase tcref -> tcref.LogicalName
| Item.UnqualifiedType(tcref :: _)
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> tcref.CompiledName
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> tcref.CompiledName
| Item.CtorGroup(_, cinfo :: _) -> cinfo.ApparentEnclosingTyconRef.CompiledName
| _ -> d.Item.DisplayName)

Expand Down
Loading