Skip to content

Merge main to release/dev17.12 #17458

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

Merged
merged 13 commits into from
Jul 29, 2024
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 UseLocalCompiler.Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<Project>
<PropertyGroup>
<LoadLocalFSharpBuild Condition="'$(LoadLocalFSharpBuild)' == ''">False</LoadLocalFSharpBuild>

<LocalFSharpCompilerConfiguration Condition="'$(LocalFSharpCompilerConfiguration)' == ''">Release</LocalFSharpCompilerConfiguration>

<LocalFSharpCompilerPath Condition=" '$(LocalFSharpCompilerPath)' == '' ">$(MSBuildThisFileDirectory)</LocalFSharpCompilerPath>
Expand All @@ -12,7 +14,9 @@

<FSharpPreferNetFrameworkTools>False</FSharpPreferNetFrameworkTools>
<FSharpPrefer64BitTools>True</FSharpPrefer64BitTools>
</PropertyGroup>

<PropertyGroup Condition="'$(LoadLocalFSharpBuild)' == 'True'">
<LocalFSharpBuildBinPath>$(LocalFSharpCompilerPath)/artifacts/bin/fsc/$(LocalFSharpCompilerConfiguration)/net9.0</LocalFSharpBuildBinPath>
<FSharpBuildAssemblyFile>$(LocalFSharpBuildBinPath)/FSharp.Build.dll</FSharpBuildAssemblyFile>
<FSharpTargetsPath>$(LocalFSharpBuildBinPath)/Microsoft.FSharp.Targets</FSharpTargetsPath>
Expand All @@ -21,8 +25,8 @@
<FSharpOverridesTargetsShim>$(LocalFSharpBuildBinPath)/Microsoft.FSharp.Overrides.NetSdk.targets</FSharpOverridesTargetsShim>
</PropertyGroup>

<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
<UsingTask Condition="'$(LoadLocalFSharpBuild)' == 'True'" TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
<UsingTask Condition="'$(LoadLocalFSharpBuild)' == 'True'" TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />

<ItemGroup>
<Reference Include="$(LocalFSharpCompilerPath)/artifacts/bin/FSharp.Core/$(LocalFSharpCompilerConfiguration)/netstandard2.0/FSharp.Core.dll" />
Expand Down
2 changes: 2 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Compiler hangs when compiling inline recursive invocation ([Issue #17376](https://github.com/dotnet/fsharp/issues/17376), [PR #17394](https://github.com/dotnet/fsharp/pull/17394))
* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375))
* Optimize simple mappings in comprehensions when the body of the mapping has `let`-bindings and/or sequential expressions before a single yield. ([PR #17419](https://github.com/dotnet/fsharp/pull/17419))

### Added

Expand All @@ -11,6 +12,7 @@

* Change compiler default setting realsig+ when building assemblies ([Issue #17384](https://github.com/dotnet/fsharp/issues/17384), [PR #17378](https://github.com/dotnet/fsharp/pull/17385))
* Change compiler default setting for compressedMetadata ([Issue #17379](https://github.com/dotnet/fsharp/issues/17379), [PR #17383](https://github.com/dotnet/fsharp/pull/17383))
* Optimize metadata reading for type members and custom attributes. ([PR #17364](https://github.com/dotnet/fsharp/pull/17364))
* Enforce `AttributeTargets` on unions. ([PR #17389](https://github.com/dotnet/fsharp/pull/17389))

### Breaking Changes
2 changes: 2 additions & 0 deletions docs/release-notes/.VisualStudio/17.12.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### Fixed

* In the prefix-to-infix code fix, don't throw an exception if the error range for FS0003 extends through the end of the source text. ([PR #17448](https://github.com/dotnet/fsharp/pull/17448))

### Added

### Changed
Expand Down
11 changes: 0 additions & 11 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,6 @@
<Sha>4a7d983f833d6b86365ea1b2b4d6ee72fbdbf944</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="1.0.0-beta.23475.1"
CoherentParentDependency="Microsoft.DotNet.Arcade.Sdk">
<Uri>https://github.com/dotnet/xliff-tasks</Uri>
<Sha>73f0850939d96131c28cf6ea6ee5aacb4da0083a</Sha>
</Dependency>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.xliff-tasks" Version="1.0.0-beta.23475.1">
<Uri>https://github.com/dotnet/xliff-tasks</Uri>
<Sha>73f0850939d96131c28cf6ea6ee5aacb4da0083a</Sha>
<SourceBuild RepoName="xliff-tasks" ManagedOnly="true" />
</Dependency>
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23614.4">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>15f6d606bfc7cbb65587dd7bc1ec6e9ef283f7e3</Sha>
Expand Down
74 changes: 47 additions & 27 deletions src/Compiler/AbstractIL/ilread.fs
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ let tomdCompare (TaggedIndex(t1: TypeOrMethodDefTag, idx1)) (TaggedIndex(t2: Typ
elif idx1 > idx2 then 1
else compare t1.Tag t2.Tag

let simpleIndexCompare (idx1: int) (idx2: int) = compare idx1 idx2
let inline simpleIndexCompare (idx1: int) (idx2: int) = compare idx1 idx2

//---------------------------------------------------------------------
// The various keys for the various caches.
Expand Down Expand Up @@ -2314,18 +2314,23 @@ and seekReadTypeDefAsTypeUncached ctxtH (TypeDefAsTypIdx(boxity, ginst, idx)) =
mkILTy boxity (ILTypeSpec.Create(seekReadTypeDefAsTypeRef ctxt idx, ginst))

and seekReadTypeDefAsTypeRef (ctxt: ILMetadataReader) idx =
let mdv = ctxt.mdfile.GetView()

let enc =
if seekIsTopTypeDefOfIdx ctxt idx then
[]
else
let enclIdx =
seekReadIndexedRow (
ctxt.getNumRows TableNames.Nested,
seekReadNestedRow ctxt,
fst,
simpleIndexCompare idx,
id,
id,
(fun i ->
let mutable addr = ctxt.rowAddr TableNames.Nested i
let nestedIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
simpleIndexCompare idx nestedIdx),
isSorted ctxt TableNames.Nested,
snd
(fun i -> seekReadNestedRow ctxt i |> snd)
)

let tref = seekReadTypeDefAsTypeRef ctxt enclIdx
Expand Down Expand Up @@ -3086,15 +3091,18 @@ and seekReadMethodImpls (ctxt: ILMetadataReader) numTypars tidx =
let mimpls =
seekReadIndexedRows (
ctxt.getNumRows TableNames.MethodImpl,
seekReadMethodImplRow ctxt mdv,
(fun (a, _, _) -> a),
simpleIndexCompare tidx,
id,
id,
(fun i ->
let mutable addr = ctxt.rowAddr TableNames.MethodImpl i
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
simpleIndexCompare tidx _tidx),
isSorted ctxt TableNames.MethodImpl,
(fun (_, b, c) -> b, c)
seekReadMethodImplRow ctxt mdv
)

mimpls
|> List.map (fun (b, c) ->
|> List.map (fun (_, b, c) ->
{
OverrideBy =
let (MethodData(enclTy, cc, nm, argTys, retTy, methInst)) =
Expand Down Expand Up @@ -3163,11 +3171,14 @@ and seekReadEvents (ctxt: ILMetadataReader) numTypars tidx =
match
seekReadOptionalIndexedRow (
ctxt.getNumRows TableNames.EventMap,
(fun i -> i, seekReadEventMapRow ctxt mdv i),
(fun (_, row) -> fst row),
compare tidx,
id,
id,
(fun i ->
let mutable addr = ctxt.rowAddr TableNames.EventMap i
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
simpleIndexCompare tidx _tidx),
false,
(fun (i, row) -> (i, snd row))
(fun i -> i, seekReadEventMapRow ctxt mdv i |> snd)
)
with
| None -> []
Expand Down Expand Up @@ -3230,11 +3241,14 @@ and seekReadProperties (ctxt: ILMetadataReader) numTypars tidx =
match
seekReadOptionalIndexedRow (
ctxt.getNumRows TableNames.PropertyMap,
(fun i -> i, seekReadPropertyMapRow ctxt mdv i),
(fun (_, row) -> fst row),
compare tidx,
id,
id,
(fun i ->
let mutable addr = ctxt.rowAddr TableNames.PropertyMap i
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
simpleIndexCompare tidx _tidx),
false,
(fun (i, row) -> (i, snd row))
(fun i -> i, seekReadPropertyMapRow ctxt mdv i |> snd)
)
with
| None -> []
Expand All @@ -3258,16 +3272,22 @@ and customAttrsReader ctxtH tag : ILAttributesStored =
let (ctxt: ILMetadataReader) = getHole ctxtH
let mdv = ctxt.mdfile.GetView()

let reader =
{ new ISeekReadIndexedRowReader<CustomAttributeRow, TaggedIndex<HasCustomAttributeTag>, ILAttribute> with
member _.GetRow(i, row) =
seekReadCustomAttributeRow ctxt mdv i &row

member _.GetKey(attrRow) = attrRow.parentIndex

member _.CompareKey(key) = hcaCompare (TaggedIndex(tag, idx)) key
let searchedKey = TaggedIndex(tag, idx)

member _.ConvertRow(attrRow) =
let reader =
{ new ISeekReadIndexedRowReader<int, int, ILAttribute> with
member _.GetRow(i, rowIndex) = rowIndex <- i
member _.GetKey(rowIndex) = rowIndex

member _.CompareKey(rowIndex) =
let mutable addr = ctxt.rowAddr TableNames.CustomAttribute rowIndex
// read parentIndex
let key = seekReadHasCustomAttributeIdx ctxt mdv &addr
hcaCompare searchedKey key

member _.ConvertRow(rowIndex) =
let mutable attrRow = Unchecked.defaultof<_>
seekReadCustomAttributeRow ctxt mdv rowIndex &attrRow
seekReadCustomAttr ctxt (attrRow.typeIndex, attrRow.valueIndex)
}

Expand Down
63 changes: 48 additions & 15 deletions src/Compiler/Optimize/LowerComputedCollections.fs
Original file line number Diff line number Diff line change
Expand Up @@ -524,22 +524,46 @@ module Array =
)
)

/// f (); …; Seq.singleton x
/// Matches Seq.singleton and returns the body expression.
[<return: Struct>]
let (|SeqSingleton|_|) g expr : Expr voption =
match expr with
| ValApp g g.seq_singleton_vref (_, [body], _) -> ValueSome body
| _ -> ValueNone

/// Matches the compiled representation of the mapping in
///
/// for … in … do f (); …; yield …
/// for … in … do let … = … in yield …
/// for … in … do f (); …; …
/// for … in … do let … = … in …
///
/// E.g., in [for x in … do f (); …; yield x]
/// i.e.,
///
/// f (); …; Seq.singleton …
/// let … = … in Seq.singleton …
[<return: Struct>]
let (|SimpleSequential|_|) g expr : Expr voption =
let (|SingleYield|_|) g expr : Expr voption =
let rec loop expr cont =
match expr with
| Expr.Sequential (expr1, DebugPoints (ValApp g g.seq_singleton_vref (_, [body], _), debug), kind, m) ->
ValueSome (cont (expr1, debug body, kind, m))
| Expr.Let (binding, DebugPoints (SeqSingleton g body, debug), m, frees) ->
ValueSome (cont (Expr.Let (binding, debug body, m, frees)))

| Expr.Let (binding, DebugPoints (body, debug), m, frees) ->
loop body (cont << fun body -> Expr.Let (binding, debug body, m, frees))

| Expr.Sequential (expr1, DebugPoints (SeqSingleton g body, debug), kind, m) ->
ValueSome (cont (Expr.Sequential (expr1, debug body, kind, m)))

| Expr.Sequential (expr1, DebugPoints (body, debug), kind, m) ->
loop body (cont >> fun body -> Expr.Sequential (expr1, debug body, kind, m))
loop body (cont << fun body -> Expr.Sequential (expr1, debug body, kind, m))

| SeqSingleton g body ->
ValueSome (cont body)

| _ -> ValueNone

loop expr Expr.Sequential
loop expr id

/// Extracts any let-bindings or sequential
/// expressions that directly precede the specified mapping application, e.g.,
Expand Down Expand Up @@ -573,11 +597,9 @@ let gatherPrelude ((|App|_|) : _ -> _ voption) expr =

/// The representation used for
///
/// for … in … -> …
///
/// and
///
/// for … in … do yield …
/// for … in … -> …
/// for … in … do yield …
/// for … in … do …
[<return: Struct>]
let (|SeqMap|_|) g =
gatherPrelude (function
Expand All @@ -592,30 +614,41 @@ let (|SeqMap|_|) g =

/// The representation used for
///
/// for … in … do f (); …; yield …
/// for … in … do f (); …; yield …
/// for … in … do let … = … in yield …
/// for … in … do f (); …; …
/// for … in … do let … = … in …
[<return: Struct>]
let (|SeqCollectSingle|_|) g =
gatherPrelude (function
| ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = SimpleSequential g body; range = mIn) as mapping; input], mFor) ->
| ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = DebugPoints (SingleYield g body, debug); range = mIn) as mapping; input], mFor) ->
let spIn = match mIn.NotedSourceConstruct with NotedSourceConstruct.InOrTo -> DebugPointAtInOrTo.Yes mIn | _ -> DebugPointAtInOrTo.No
let spFor = DebugPointAtBinding.Yes mFor
let spInWhile = match spIn with DebugPointAtInOrTo.Yes m -> DebugPointAtWhile.Yes m | DebugPointAtInOrTo.No -> DebugPointAtWhile.No
let ranges = body.Range, spFor, spIn, mFor, mIn, spInWhile
ValueSome (ty1, ty2, input, mapping, loopVal, body, ranges)
ValueSome (ty1, ty2, input, mapping, loopVal, debug body, ranges)

| _ -> ValueNone)

/// for … in … -> …
/// for … in … do yield …
/// for … in … do …
/// for … in … do f (); …; yield …
/// for … in … do let … = … in yield …
/// for … in … do f (); …; …
/// for … in … do let … = … in …
[<return: Struct>]
let (|SimpleMapping|_|) g expr =
match expr with
// for … in … -> …
// for … in … do yield …
// for … in … do …
| ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = DebugPoints (SeqMap g (cont, (ty1, ty2, input, mapping, loopVal, body, ranges)), debug))], _)

// for … in … do f (); …; yield …
// for … in … do let … = … in yield …
// for … in … do f (); …; …
// for … in … do let … = … in …
| ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = DebugPoints (SeqCollectSingle g (cont, (ty1, ty2, input, mapping, loopVal, body, ranges)), debug))], _) ->
ValueSome (debug >> cont, (ty1, ty2, input, mapping, loopVal, body, ranges))

Expand Down
11 changes: 7 additions & 4 deletions src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,11 +1271,14 @@ let rec stripDebugPoints expr =
| Expr.DebugPoint (_, innerExpr) -> stripDebugPoints innerExpr
| expr -> expr

// Strip debug points and remember how to recrete them
// Strip debug points and remember how to recreate them
let (|DebugPoints|) expr =
match stripExpr expr with
| Expr.DebugPoint (dp, innerExpr) -> innerExpr, (fun e -> Expr.DebugPoint(dp, e))
| expr -> expr, id
let rec loop expr debug =
match stripExpr expr with
| Expr.DebugPoint (dp, innerExpr) -> loop innerExpr (debug << fun e -> Expr.DebugPoint (dp, e))
| expr -> expr, debug

loop expr id

let mkCase (a, b) = TCase(a, b)

Expand Down
2 changes: 1 addition & 1 deletion src/FSharp.Core/prim-types.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2788,7 +2788,7 @@ namespace Microsoft.FSharp.Core
/// <example id="addition-example-1">
/// <code lang="fsharp">
/// 2 + 2 // Evaluates to 4
/// "Hello " + "Word" // Evaluates to "Hello World"
/// "Hello " + "World" // Evaluates to "Hello World"
/// </code>
/// </example>
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
type ExpectedException() =
inherit Exception()

[<Fact>]
[<Fact(Skip="Flaky")>]
let ``Stress test`` () =

let seed = System.Random().Next()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
let f00 f g = [|for n in 1..10 do f (); g (); yield n|]
let f000 f = [|for n in 1..10 do f (); yield n; yield n + 1|]
let f0000 () = [|for n in 1..10 do yield n|]
let f00000 () = [|for n in 1..10 do n|]
let f000000 () = [|for n in 1..10 do let n = n in n|]
let f0000000 () = [|for n in 1..10 do let n = n in yield n|]
let f00000000 () = [|for n in 1..10 do let n = n in let n = n in yield n|]
let f000000000 x y = [|for n in 1..10 do let foo = n + x in let bar = n + y in yield n + foo + bar|]
let f0000000000 f g = [|for n in 1..10 do f (); g (); n|]
let f00000000000 (f : unit -> int) (g : unit -> int) = [|for n in 1..10 do f (); g (); n|]
let f1 () = [|for n in 1..10 -> n|]
let f2 () = [|for n in 10..1 -> n|]
let f3 () = [|for n in 1..1..10 -> n|]
Expand Down
Loading
Loading