Skip to content

Commit 0684fca

Browse files
authored
Merge pull request #17458 from dotnet/merges/main-to-release/dev17.12
2 parents d0b2a41 + 3c95685 commit 0684fca

27 files changed

+4661
-82
lines changed

UseLocalCompiler.Directory.Build.props

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<Project>
22
<PropertyGroup>
3+
<LoadLocalFSharpBuild Condition="'$(LoadLocalFSharpBuild)' == ''">False</LoadLocalFSharpBuild>
4+
35
<LocalFSharpCompilerConfiguration Condition="'$(LocalFSharpCompilerConfiguration)' == ''">Release</LocalFSharpCompilerConfiguration>
46

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

1315
<FSharpPreferNetFrameworkTools>False</FSharpPreferNetFrameworkTools>
1416
<FSharpPrefer64BitTools>True</FSharpPrefer64BitTools>
17+
</PropertyGroup>
1518

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

24-
<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
25-
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
28+
<UsingTask Condition="'$(LoadLocalFSharpBuild)' == 'True'" TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
29+
<UsingTask Condition="'$(LoadLocalFSharpBuild)' == 'True'" TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFile)" Override="true" />
2630

2731
<ItemGroup>
2832
<Reference Include="$(LocalFSharpCompilerPath)/artifacts/bin/FSharp.Core/$(LocalFSharpCompilerConfiguration)/netstandard2.0/FSharp.Core.dll" />

docs/release-notes/.FSharp.Compiler.Service/9.0.100.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* 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))
44
* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375))
5+
* 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))
56

67
### Added
78

@@ -11,6 +12,7 @@
1112

1213
* 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))
1314
* Change compiler default setting for compressedMetadata ([Issue #17379](https://github.com/dotnet/fsharp/issues/17379), [PR #17383](https://github.com/dotnet/fsharp/pull/17383))
15+
* Optimize metadata reading for type members and custom attributes. ([PR #17364](https://github.com/dotnet/fsharp/pull/17364))
1416
* Enforce `AttributeTargets` on unions. ([PR #17389](https://github.com/dotnet/fsharp/pull/17389))
1517

1618
### Breaking Changes

docs/release-notes/.VisualStudio/17.12.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
### Fixed
22

3+
* 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))
4+
35
### Added
46

57
### Changed

eng/Version.Details.xml

-11
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,6 @@
5252
<Sha>4a7d983f833d6b86365ea1b2b4d6ee72fbdbf944</Sha>
5353
<SourceBuild RepoName="arcade" ManagedOnly="true" />
5454
</Dependency>
55-
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="1.0.0-beta.23475.1"
56-
CoherentParentDependency="Microsoft.DotNet.Arcade.Sdk">
57-
<Uri>https://github.com/dotnet/xliff-tasks</Uri>
58-
<Sha>73f0850939d96131c28cf6ea6ee5aacb4da0083a</Sha>
59-
</Dependency>
60-
<!-- Intermediate is necessary for source build. -->
61-
<Dependency Name="Microsoft.SourceBuild.Intermediate.xliff-tasks" Version="1.0.0-beta.23475.1">
62-
<Uri>https://github.com/dotnet/xliff-tasks</Uri>
63-
<Sha>73f0850939d96131c28cf6ea6ee5aacb4da0083a</Sha>
64-
<SourceBuild RepoName="xliff-tasks" ManagedOnly="true" />
65-
</Dependency>
6655
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23614.4">
6756
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
6857
<Sha>15f6d606bfc7cbb65587dd7bc1ec6e9ef283f7e3</Sha>

src/Compiler/AbstractIL/ilread.fs

+47-27
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ let tomdCompare (TaggedIndex(t1: TypeOrMethodDefTag, idx1)) (TaggedIndex(t2: Typ
883883
elif idx1 > idx2 then 1
884884
else compare t1.Tag t2.Tag
885885

886-
let simpleIndexCompare (idx1: int) (idx2: int) = compare idx1 idx2
886+
let inline simpleIndexCompare (idx1: int) (idx2: int) = compare idx1 idx2
887887

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

23162316
and seekReadTypeDefAsTypeRef (ctxt: ILMetadataReader) idx =
2317+
let mdv = ctxt.mdfile.GetView()
2318+
23172319
let enc =
23182320
if seekIsTopTypeDefOfIdx ctxt idx then
23192321
[]
23202322
else
23212323
let enclIdx =
23222324
seekReadIndexedRow (
23232325
ctxt.getNumRows TableNames.Nested,
2324-
seekReadNestedRow ctxt,
2325-
fst,
2326-
simpleIndexCompare idx,
2326+
id,
2327+
id,
2328+
(fun i ->
2329+
let mutable addr = ctxt.rowAddr TableNames.Nested i
2330+
let nestedIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
2331+
simpleIndexCompare idx nestedIdx),
23272332
isSorted ctxt TableNames.Nested,
2328-
snd
2333+
(fun i -> seekReadNestedRow ctxt i |> snd)
23292334
)
23302335

23312336
let tref = seekReadTypeDefAsTypeRef ctxt enclIdx
@@ -3086,15 +3091,18 @@ and seekReadMethodImpls (ctxt: ILMetadataReader) numTypars tidx =
30863091
let mimpls =
30873092
seekReadIndexedRows (
30883093
ctxt.getNumRows TableNames.MethodImpl,
3089-
seekReadMethodImplRow ctxt mdv,
3090-
(fun (a, _, _) -> a),
3091-
simpleIndexCompare tidx,
3094+
id,
3095+
id,
3096+
(fun i ->
3097+
let mutable addr = ctxt.rowAddr TableNames.MethodImpl i
3098+
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
3099+
simpleIndexCompare tidx _tidx),
30923100
isSorted ctxt TableNames.MethodImpl,
3093-
(fun (_, b, c) -> b, c)
3101+
seekReadMethodImplRow ctxt mdv
30943102
)
30953103

30963104
mimpls
3097-
|> List.map (fun (b, c) ->
3105+
|> List.map (fun (_, b, c) ->
30983106
{
30993107
OverrideBy =
31003108
let (MethodData(enclTy, cc, nm, argTys, retTy, methInst)) =
@@ -3163,11 +3171,14 @@ and seekReadEvents (ctxt: ILMetadataReader) numTypars tidx =
31633171
match
31643172
seekReadOptionalIndexedRow (
31653173
ctxt.getNumRows TableNames.EventMap,
3166-
(fun i -> i, seekReadEventMapRow ctxt mdv i),
3167-
(fun (_, row) -> fst row),
3168-
compare tidx,
3174+
id,
3175+
id,
3176+
(fun i ->
3177+
let mutable addr = ctxt.rowAddr TableNames.EventMap i
3178+
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
3179+
simpleIndexCompare tidx _tidx),
31693180
false,
3170-
(fun (i, row) -> (i, snd row))
3181+
(fun i -> i, seekReadEventMapRow ctxt mdv i |> snd)
31713182
)
31723183
with
31733184
| None -> []
@@ -3230,11 +3241,14 @@ and seekReadProperties (ctxt: ILMetadataReader) numTypars tidx =
32303241
match
32313242
seekReadOptionalIndexedRow (
32323243
ctxt.getNumRows TableNames.PropertyMap,
3233-
(fun i -> i, seekReadPropertyMapRow ctxt mdv i),
3234-
(fun (_, row) -> fst row),
3235-
compare tidx,
3244+
id,
3245+
id,
3246+
(fun i ->
3247+
let mutable addr = ctxt.rowAddr TableNames.PropertyMap i
3248+
let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
3249+
simpleIndexCompare tidx _tidx),
32363250
false,
3237-
(fun (i, row) -> (i, snd row))
3251+
(fun i -> i, seekReadPropertyMapRow ctxt mdv i |> snd)
32383252
)
32393253
with
32403254
| None -> []
@@ -3258,16 +3272,22 @@ and customAttrsReader ctxtH tag : ILAttributesStored =
32583272
let (ctxt: ILMetadataReader) = getHole ctxtH
32593273
let mdv = ctxt.mdfile.GetView()
32603274

3261-
let reader =
3262-
{ new ISeekReadIndexedRowReader<CustomAttributeRow, TaggedIndex<HasCustomAttributeTag>, ILAttribute> with
3263-
member _.GetRow(i, row) =
3264-
seekReadCustomAttributeRow ctxt mdv i &row
3265-
3266-
member _.GetKey(attrRow) = attrRow.parentIndex
3267-
3268-
member _.CompareKey(key) = hcaCompare (TaggedIndex(tag, idx)) key
3275+
let searchedKey = TaggedIndex(tag, idx)
32693276

3270-
member _.ConvertRow(attrRow) =
3277+
let reader =
3278+
{ new ISeekReadIndexedRowReader<int, int, ILAttribute> with
3279+
member _.GetRow(i, rowIndex) = rowIndex <- i
3280+
member _.GetKey(rowIndex) = rowIndex
3281+
3282+
member _.CompareKey(rowIndex) =
3283+
let mutable addr = ctxt.rowAddr TableNames.CustomAttribute rowIndex
3284+
// read parentIndex
3285+
let key = seekReadHasCustomAttributeIdx ctxt mdv &addr
3286+
hcaCompare searchedKey key
3287+
3288+
member _.ConvertRow(rowIndex) =
3289+
let mutable attrRow = Unchecked.defaultof<_>
3290+
seekReadCustomAttributeRow ctxt mdv rowIndex &attrRow
32713291
seekReadCustomAttr ctxt (attrRow.typeIndex, attrRow.valueIndex)
32723292
}
32733293

src/Compiler/Optimize/LowerComputedCollections.fs

+48-15
Original file line numberDiff line numberDiff line change
@@ -524,22 +524,46 @@ module Array =
524524
)
525525
)
526526

527-
/// f (); …; Seq.singleton x
527+
/// Matches Seq.singleton and returns the body expression.
528+
[<return: Struct>]
529+
let (|SeqSingleton|_|) g expr : Expr voption =
530+
match expr with
531+
| ValApp g g.seq_singleton_vref (_, [body], _) -> ValueSome body
532+
| _ -> ValueNone
533+
534+
/// Matches the compiled representation of the mapping in
535+
///
536+
/// for … in … do f (); …; yield …
537+
/// for … in … do let … = … in yield …
538+
/// for … in … do f (); …; …
539+
/// for … in … do let … = … in …
528540
///
529-
/// E.g., in [for x in … do f (); …; yield x]
541+
/// i.e.,
542+
///
543+
/// f (); …; Seq.singleton …
544+
/// let … = … in Seq.singleton …
530545
[<return: Struct>]
531-
let (|SimpleSequential|_|) g expr : Expr voption =
546+
let (|SingleYield|_|) g expr : Expr voption =
532547
let rec loop expr cont =
533548
match expr with
534-
| Expr.Sequential (expr1, DebugPoints (ValApp g g.seq_singleton_vref (_, [body], _), debug), kind, m) ->
535-
ValueSome (cont (expr1, debug body, kind, m))
549+
| Expr.Let (binding, DebugPoints (SeqSingleton g body, debug), m, frees) ->
550+
ValueSome (cont (Expr.Let (binding, debug body, m, frees)))
551+
552+
| Expr.Let (binding, DebugPoints (body, debug), m, frees) ->
553+
loop body (cont << fun body -> Expr.Let (binding, debug body, m, frees))
554+
555+
| Expr.Sequential (expr1, DebugPoints (SeqSingleton g body, debug), kind, m) ->
556+
ValueSome (cont (Expr.Sequential (expr1, debug body, kind, m)))
536557

537558
| Expr.Sequential (expr1, DebugPoints (body, debug), kind, m) ->
538-
loop body (cont >> fun body -> Expr.Sequential (expr1, debug body, kind, m))
559+
loop body (cont << fun body -> Expr.Sequential (expr1, debug body, kind, m))
560+
561+
| SeqSingleton g body ->
562+
ValueSome (cont body)
539563

540564
| _ -> ValueNone
541565

542-
loop expr Expr.Sequential
566+
loop expr id
543567

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

574598
/// The representation used for
575599
///
576-
/// for … in … -> …
577-
///
578-
/// and
579-
///
580-
/// for … in … do yield …
600+
/// for … in … -> …
601+
/// for … in … do yield …
602+
/// for … in … do …
581603
[<return: Struct>]
582604
let (|SeqMap|_|) g =
583605
gatherPrelude (function
@@ -592,30 +614,41 @@ let (|SeqMap|_|) g =
592614

593615
/// The representation used for
594616
///
595-
/// for … in … do f (); …; yield …
617+
/// for … in … do f (); …; yield …
618+
/// for … in … do let … = … in yield …
619+
/// for … in … do f (); …; …
620+
/// for … in … do let … = … in …
596621
[<return: Struct>]
597622
let (|SeqCollectSingle|_|) g =
598623
gatherPrelude (function
599-
| ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = SimpleSequential g body; range = mIn) as mapping; input], mFor) ->
624+
| ValApp g g.seq_collect_vref ([ty1; _; ty2], [Expr.Lambda (valParams = [loopVal]; bodyExpr = DebugPoints (SingleYield g body, debug); range = mIn) as mapping; input], mFor) ->
600625
let spIn = match mIn.NotedSourceConstruct with NotedSourceConstruct.InOrTo -> DebugPointAtInOrTo.Yes mIn | _ -> DebugPointAtInOrTo.No
601626
let spFor = DebugPointAtBinding.Yes mFor
602627
let spInWhile = match spIn with DebugPointAtInOrTo.Yes m -> DebugPointAtWhile.Yes m | DebugPointAtInOrTo.No -> DebugPointAtWhile.No
603628
let ranges = body.Range, spFor, spIn, mFor, mIn, spInWhile
604-
ValueSome (ty1, ty2, input, mapping, loopVal, body, ranges)
629+
ValueSome (ty1, ty2, input, mapping, loopVal, debug body, ranges)
605630

606631
| _ -> ValueNone)
607632

608633
/// for … in … -> …
609634
/// for … in … do yield …
635+
/// for … in … do …
610636
/// for … in … do f (); …; yield …
637+
/// for … in … do let … = … in yield …
638+
/// for … in … do f (); …; …
639+
/// for … in … do let … = … in …
611640
[<return: Struct>]
612641
let (|SimpleMapping|_|) g expr =
613642
match expr with
614643
// for … in … -> …
615644
// for … in … do yield …
645+
// for … in … do …
616646
| ValApp g g.seq_delay_vref (_, [Expr.Lambda (bodyExpr = DebugPoints (SeqMap g (cont, (ty1, ty2, input, mapping, loopVal, body, ranges)), debug))], _)
617647

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

src/Compiler/TypedTree/TypedTreeOps.fs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1271,11 +1271,14 @@ let rec stripDebugPoints expr =
12711271
| Expr.DebugPoint (_, innerExpr) -> stripDebugPoints innerExpr
12721272
| expr -> expr
12731273

1274-
// Strip debug points and remember how to recrete them
1274+
// Strip debug points and remember how to recreate them
12751275
let (|DebugPoints|) expr =
1276-
match stripExpr expr with
1277-
| Expr.DebugPoint (dp, innerExpr) -> innerExpr, (fun e -> Expr.DebugPoint(dp, e))
1278-
| expr -> expr, id
1276+
let rec loop expr debug =
1277+
match stripExpr expr with
1278+
| Expr.DebugPoint (dp, innerExpr) -> loop innerExpr (debug << fun e -> Expr.DebugPoint (dp, e))
1279+
| expr -> expr, debug
1280+
1281+
loop expr id
12791282

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

src/FSharp.Core/prim-types.fsi

+1-1
Original file line numberDiff line numberDiff line change
@@ -2788,7 +2788,7 @@ namespace Microsoft.FSharp.Core
27882788
/// <example id="addition-example-1">
27892789
/// <code lang="fsharp">
27902790
/// 2 + 2 // Evaluates to 4
2791-
/// "Hello " + "Word" // Evaluates to "Hello World"
2791+
/// "Hello " + "World" // Evaluates to "Hello World"
27922792
/// </code>
27932793
/// </example>
27942794
///

tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
249249
type ExpectedException() =
250250
inherit Exception()
251251

252-
[<Fact>]
252+
[<Fact(Skip="Flaky")>]
253253
let ``Stress test`` () =
254254

255255
let seed = System.Random().Next()

tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForNInRangeArrays.fs

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
let f00 f g = [|for n in 1..10 do f (); g (); yield n|]
33
let f000 f = [|for n in 1..10 do f (); yield n; yield n + 1|]
44
let f0000 () = [|for n in 1..10 do yield n|]
5+
let f00000 () = [|for n in 1..10 do n|]
6+
let f000000 () = [|for n in 1..10 do let n = n in n|]
7+
let f0000000 () = [|for n in 1..10 do let n = n in yield n|]
8+
let f00000000 () = [|for n in 1..10 do let n = n in let n = n in yield n|]
9+
let f000000000 x y = [|for n in 1..10 do let foo = n + x in let bar = n + y in yield n + foo + bar|]
10+
let f0000000000 f g = [|for n in 1..10 do f (); g (); n|]
11+
let f00000000000 (f : unit -> int) (g : unit -> int) = [|for n in 1..10 do f (); g (); n|]
512
let f1 () = [|for n in 1..10 -> n|]
613
let f2 () = [|for n in 10..1 -> n|]
714
let f3 () = [|for n in 1..1..10 -> n|]

0 commit comments

Comments
 (0)