Skip to content

Commit 09559b0

Browse files
authored
Merge pull request #16102 from dotnet/merges/main-to-release/dev17.9
2 parents 8c92c8c + b7d70f3 commit 09559b0

File tree

75 files changed

+1497
-884
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1497
-884
lines changed

eng/Version.Details.xml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Dependencies>
33
<ProductDependencies>
4-
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.23468.3">
4+
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.23502.1">
55
<Uri>https://github.com/dotnet/source-build-reference-packages</Uri>
6-
<Sha>b88b567fbf54c5404d039b80cfb86f09a681f604</Sha>
6+
<Sha>05ffbf9df6c1dc621665ee1864874c4fe6de874c</Sha>
77
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
88
</Dependency>
99
<Dependency Name="Microsoft.SourceBuild.Intermediate.msbuild" Version="17.7.0-preview-23217-02">
@@ -39,25 +39,25 @@
3939
<Sha>194f32828726c3f1f63f79f3dc09b9e99c157b11</Sha>
4040
<SourceBuild RepoName="xliff-tasks" ManagedOnly="true" />
4141
</Dependency>
42-
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
42+
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
4343
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
44-
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
44+
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
4545
</Dependency>
46-
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
46+
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
4747
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
48-
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
48+
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
4949
</Dependency>
50-
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
50+
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
5151
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
52-
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
52+
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
5353
</Dependency>
54-
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
54+
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
5555
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
56-
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
56+
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
5757
</Dependency>
58-
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
58+
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
5959
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
60-
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
60+
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
6161
</Dependency>
6262
</ToolsetDependencies>
6363
</Dependencies>

eng/Versions.props

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@
206206
<FluentAssertionsVersion>5.10.3</FluentAssertionsVersion>
207207
<HumanizerCoreVersion>2.2.0</HumanizerCoreVersion>
208208
<!-- MIBC profile packages -->
209-
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntx64MIBCRuntimeVersion>
210-
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntx86MIBCRuntimeVersion>
211-
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntarm64MIBCRuntimeVersion>
212-
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationlinuxx64MIBCRuntimeVersion>
213-
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationlinuxarm64MIBCRuntimeVersion>
209+
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntx64MIBCRuntimeVersion>
210+
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntx86MIBCRuntimeVersion>
211+
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntarm64MIBCRuntimeVersion>
212+
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationlinuxx64MIBCRuntimeVersion>
213+
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationlinuxarm64MIBCRuntimeVersion>
214214
</PropertyGroup>
215215
</Project>

global.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
22
"sdk": {
33
"version": "8.0.100-rc.1.23455.8",
4-
"allowPrerelease": true,
5-
"rollForward": "latestMajor"
4+
"allowPrerelease": true
65
},
76
"tools": {
87
"dotnet": "8.0.100-rc.1.23455.8",

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10759,6 +10759,15 @@ and TcNonrecBindingTyparDecls cenv env tpenv bind =
1075910759
TcBindingTyparDecls true cenv env tpenv synTyparDecls
1076010760

1076110761
and TcNonRecursiveBinding declKind cenv env tpenv ty binding =
10762+
// Check for unintended shadowing
10763+
match binding with
10764+
| SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ident]); range = headPatRange)) ->
10765+
match env.eNameResEnv.ePatItems.TryFind ident.idText with
10766+
| Some (Item.UnionCase(_, false)) ->
10767+
warning(Error(FSComp.SR.tcInfoIfFunctionShadowsUnionCase(), headPatRange))
10768+
| _ -> ()
10769+
| _ -> ()
10770+
1076210771
let binding = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env binding
1076310772
let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv binding
1076410773
TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding

src/Compiler/Checking/TailCallChecks.fs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,31 @@ and CheckForNonTailRecCall (cenv: cenv) expr (tailCall: TailCall) =
216216
| _ -> ()
217217

218218
/// Check call arguments, including the return argument.
219-
and CheckCall cenv args ctxts = CheckExprs cenv args ctxts TailCall.No
219+
and CheckCall cenv args ctxts (tailCall: TailCall) =
220+
// detect CPS-like expressions
221+
let rec (|IsAppInLambdaBody|_|) e =
222+
match stripDebugPoints e with
223+
| Expr.TyLambda (bodyExpr = bodyExpr)
224+
| Expr.Lambda (bodyExpr = bodyExpr) ->
225+
match (stripDebugPoints bodyExpr) with
226+
| Expr.App _ -> Some(TailCall.YesFromExpr cenv.g e)
227+
| IsAppInLambdaBody t -> Some t
228+
| _ -> None
229+
| _ -> None
230+
231+
// if we haven't already decided this is no tail call, try to detect CPS-like expressions
232+
let tailCall =
233+
if tailCall = TailCall.No then
234+
tailCall
235+
else
236+
args
237+
|> List.tryPick (fun a ->
238+
match a with
239+
| IsAppInLambdaBody t -> Some t
240+
| _ -> None)
241+
|> Option.defaultValue TailCall.No
242+
243+
CheckExprs cenv args ctxts tailCall
220244

221245
/// Check call arguments, including the return argument. The receiver argument is handled differently.
222246
and CheckCallWithReceiver cenv args ctxts =
@@ -330,7 +354,25 @@ and CheckExpr (cenv: cenv) origExpr (ctxt: PermitByRefExpr) (tailCall: TailCall)
330354
| TypeDefOfExpr g ty when isVoidTy g ty -> ()
331355

332356
// Check an application
333-
| Expr.App (f, _fty, _tyargs, argsl, _m) -> CheckApplication cenv (f, argsl) tailCall
357+
| Expr.App (f, _fty, _tyargs, argsl, _m) ->
358+
// detect expressions like List.collect
359+
let checkArgForLambdaWithAppOfMustTailCall e =
360+
match stripDebugPoints e with
361+
| Expr.TyLambda (bodyExpr = bodyExpr)
362+
| Expr.Lambda (bodyExpr = bodyExpr) ->
363+
match bodyExpr with
364+
| Expr.App (ValUseAtApp (vref, _valUseFlags), _formalType, _typeArgs, _exprs, _range) ->
365+
cenv.mustTailCall.Contains vref.Deref
366+
| _ -> false
367+
| _ -> false
368+
369+
let tailCall =
370+
if argsl |> List.exists checkArgForLambdaWithAppOfMustTailCall then
371+
TailCall.No
372+
else
373+
tailCall
374+
375+
CheckApplication cenv (f, argsl) tailCall
334376

335377
| Expr.Lambda (_, _, _, argvs, _, m, bodyTy) -> CheckLambda cenv expr (argvs, m, bodyTy) tailCall
336378

@@ -388,7 +430,7 @@ and CheckApplication cenv (f, argsl) (tailCall: TailCall) : unit =
388430
if hasReceiver then
389431
CheckCallWithReceiver cenv argsl ctxts
390432
else
391-
CheckCall cenv argsl ctxts
433+
CheckCall cenv argsl ctxts tailCall
392434

393435
and CheckLambda cenv expr (argvs, m, bodyTy) (tailCall: TailCall) =
394436
let valReprInfo =
@@ -470,12 +512,12 @@ and CheckExprOp cenv (op, tyargs, args, m) ctxt : unit =
470512
if hasReceiver then
471513
CheckCallWithReceiver cenv args argContexts
472514
else
473-
CheckCall cenv args argContexts
515+
CheckCall cenv args argContexts TailCall.No
474516
| _ ->
475517
if hasReceiver then
476518
CheckCallWithReceiver cenv args argContexts
477519
else
478-
CheckCall cenv args argContexts
520+
CheckCall cenv args argContexts TailCall.No
479521

480522
| TOp.Tuple tupInfo, _, _ when not (evalTupInfoIsStruct tupInfo) ->
481523
match ctxt with
@@ -604,7 +646,7 @@ and CheckLambdas
604646
// allow byref to occur as return position for byref-typed top level function or method
605647
CheckExprPermitReturnableByRef cenv body
606648
else
607-
CheckExprNoByrefs cenv (TailCall.YesFromExpr cenv.g body) body // TailCall.Yes for CPS
649+
CheckExprNoByrefs cenv tailCall body
608650

609651
// This path is for expression bindings that are not actually lambdas
610652
| _ ->

src/Compiler/Driver/CompilerDiagnostics.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ type PhasedDiagnostic with
388388
| 3395 -> false // tcImplicitConversionUsedForMethodArg - off by default
389389
| 3559 -> false // typrelNeverRefinedAwayFromTop - off by default
390390
| 3579 -> false // alwaysUseTypedStringInterpolation - off by default
391+
| 3582 -> false // infoIfFunctionShadowsUnionCase - off by default
391392
| _ ->
392393
match x.Exception with
393394
| DiagnosticEnabledWithLanguageFeature (_, _, _, enabled) -> enabled

src/Compiler/Driver/GraphChecking/DependencyResolution.fs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,33 @@ let queryTriePartial (trie: TrieNode) (path: LongIdentifier) : TrieNode option =
1717

1818
visit trie path
1919

20-
let mapNodeToQueryResult (node: TrieNode option) : QueryTrieNodeResult =
20+
let mapNodeToQueryResult (currentFileIndex: FileIndex) (node: TrieNode option) : QueryTrieNodeResult =
2121
match node with
2222
| Some finalNode ->
23-
if Set.isEmpty finalNode.Files then
23+
if
24+
Set.isEmpty finalNode.Files
25+
// If this node exposes files which the current index cannot see, we consider it not to have data at all.
26+
|| Set.forall (fun idx -> idx >= currentFileIndex) finalNode.Files
27+
then
2428
QueryTrieNodeResult.NodeDoesNotExposeData
2529
else
2630
QueryTrieNodeResult.NodeExposesData(finalNode.Files)
2731
| None -> QueryTrieNodeResult.NodeDoesNotExist
2832

2933
/// <summary>Find a path in the Trie.</summary>
30-
let queryTrie (trie: TrieNode) (path: LongIdentifier) : QueryTrieNodeResult =
31-
queryTriePartial trie path |> mapNodeToQueryResult
34+
let queryTrie (currentFileIndex: FileIndex) (trie: TrieNode) (path: LongIdentifier) : QueryTrieNodeResult =
35+
queryTriePartial trie path |> mapNodeToQueryResult currentFileIndex
3236

3337
/// <summary>Same as 'queryTrie' but allows passing in a path combined from two parts, avoiding list allocation.</summary>
34-
let queryTrieDual (trie: TrieNode) (path1: LongIdentifier) (path2: LongIdentifier) : QueryTrieNodeResult =
38+
let queryTrieDual (currentFileIndex: FileIndex) (trie: TrieNode) (path1: LongIdentifier) (path2: LongIdentifier) : QueryTrieNodeResult =
3539
match queryTriePartial trie path1 with
3640
| Some intermediateNode -> queryTriePartial intermediateNode path2
3741
| None -> None
38-
|> mapNodeToQueryResult
42+
|> mapNodeToQueryResult currentFileIndex
3943

4044
/// Process namespace declaration.
4145
let processNamespaceDeclaration (trie: TrieNode) (path: LongIdentifier) (state: FileContentQueryState) : FileContentQueryState =
42-
let queryResult = queryTrie trie path
46+
let queryResult = queryTrie state.CurrentFile trie path
4347

4448
match queryResult with
4549
| QueryTrieNodeResult.NodeDoesNotExist -> state
@@ -49,7 +53,7 @@ let processNamespaceDeclaration (trie: TrieNode) (path: LongIdentifier) (state:
4953
/// Process an "open" statement.
5054
/// The statement could link to files and/or should be tracked as an open namespace.
5155
let processOpenPath (trie: TrieNode) (path: LongIdentifier) (state: FileContentQueryState) : FileContentQueryState =
52-
let queryResult = queryTrie trie path
56+
let queryResult = queryTrie state.CurrentFile trie path
5357

5458
match queryResult with
5559
| QueryTrieNodeResult.NodeDoesNotExist -> state
@@ -99,12 +103,13 @@ let rec processStateEntry (trie: TrieNode) (state: FileContentQueryState) (entry
99103
||> Array.fold (fun state takeParts ->
100104
let path = List.take takeParts path
101105
// process the name was if it were a FQN
102-
let stateAfterFullIdentifier = processIdentifier (queryTrieDual trie [] path) state
106+
let stateAfterFullIdentifier =
107+
processIdentifier (queryTrieDual state.CurrentFile trie [] path) state
103108

104109
// Process the name in combination with the existing open namespaces
105110
(stateAfterFullIdentifier, state.OpenNamespaces)
106111
||> Set.fold (fun acc openNS ->
107-
let queryResult = queryTrieDual trie openNS path
112+
let queryResult = queryTrieDual state.CurrentFile trie openNS path
108113
processIdentifier queryResult acc))
109114

110115
| FileContentEntry.NestedModule (nestedContent = nestedContent) ->
@@ -137,7 +142,7 @@ let collectGhostDependencies (fileIndex: FileIndex) (trie: TrieNode) (result: Fi
137142
// For each opened namespace, if none of already resolved dependencies define it, return the top-most file that defines it.
138143
Set.toArray result.OpenedNamespaces
139144
|> Array.choose (fun path ->
140-
match queryTrie trie path with
145+
match queryTrie fileIndex trie path with
141146
| QueryTrieNodeResult.NodeExposesData _
142147
| QueryTrieNodeResult.NodeDoesNotExist -> None
143148
| QueryTrieNodeResult.NodeDoesNotExposeData ->

src/Compiler/Driver/GraphChecking/DependencyResolution.fsi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/// Logic for constructing a file dependency graph for the purposes of parallel type-checking.
22
module internal FSharp.Compiler.GraphChecking.DependencyResolution
33

4-
/// <summary>Query a TrieNode to find a certain path.</summary>
4+
/// <summary>
5+
/// Query a TrieNode to find a certain path.
6+
/// The result will take the current file index into account to determine if the result node contains data.
7+
/// </summary>
58
/// <remarks>This code is only used directly in unit tests.</remarks>
6-
val queryTrie: trie: TrieNode -> path: LongIdentifier -> QueryTrieNodeResult
9+
val queryTrie: currentFileIndex: FileIndex -> trie: TrieNode -> path: LongIdentifier -> QueryTrieNodeResult
710

811
/// <summary>Process an open path (found in the ParsedInput) with a given FileContentQueryState.</summary>
912
/// <remarks>This code is only used directly in unit tests.</remarks>

src/Compiler/FSComp.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl
15091509
3234,chkNoSpanLikeVariable,"The Span or IsByRefLike variable '%s' cannot be used at this point. This is to ensure the address of the local value does not escape its scope."
15101510
3235,chkNoSpanLikeValueFromExpression,"A Span or IsByRefLike value returned from the expression cannot be used at ths point. This is to ensure the address of the local value does not escape its scope."
15111511
3236,tastCantTakeAddressOfExpression,"Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address."
1512-
3237,tcCannotCallExtensionMethodInrefToByref,"Cannot call the byref extension method '%s. The first parameter requires the value to be mutable or a non-readonly byref type."
1512+
3237,tcCannotCallExtensionMethodInrefToByref,"Cannot call the byref extension method '%s. 'this' parameter requires the value to be mutable or a non-readonly byref type."
15131513
3238,tcByrefsMayNotHaveTypeExtensions,"Byref types are not allowed to have optional type extensions."
15141514
3239,tcCannotPartiallyApplyExtensionMethodForByref,"Cannot partially apply the extension method '%s' because the first parameter is a byref type."
15151515
3242,tcTypeDoesNotInheritAttribute,"This type does not inherit Attribute, it will not work correctly with other .NET languages."
@@ -1724,3 +1724,4 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged
17241724
3578,chkCopyUpdateSyntaxInAnonRecords,"This expression is an anonymous record, use {{|...|}} instead of {{...}}."
17251725
3579,alwaysUseTypedStringInterpolation,"Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended."
17261726
3580,tcUnexpectedFunTypeInUnionCaseField,"Unexpected function type in union case field definition. If you intend the field to be a function, consider wrapping the function signature with parens, e.g. | Case of a -> b into | Case of (a -> b)."
1727+
3582,tcInfoIfFunctionShadowsUnionCase,"This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses."

src/Compiler/Facilities/prim-lexing.fs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ namespace FSharp.Compiler.Text
66

77
open System
88
open System.IO
9-
open FSharp.Compiler
109

1110
type ISourceText =
1211

@@ -28,6 +27,8 @@ type ISourceText =
2827

2928
abstract CopyTo: sourceIndex: int * destination: char[] * destinationIndex: int * count: int -> unit
3029

30+
abstract GetSubTextFromRange: range: range -> string
31+
3132
[<Sealed>]
3233
type StringText(str: string) =
3334

@@ -108,6 +109,41 @@ type StringText(str: string) =
108109
member _.CopyTo(sourceIndex, destination, destinationIndex, count) =
109110
str.CopyTo(sourceIndex, destination, destinationIndex, count)
110111

112+
member this.GetSubTextFromRange(range) =
113+
let totalAmountOfLines = getLines.Value.Length
114+
115+
if
116+
range.StartLine = 0
117+
&& range.StartColumn = 0
118+
&& range.EndLine = 0
119+
&& range.EndColumn = 0
120+
then
121+
String.Empty
122+
elif
123+
range.StartLine < 1
124+
|| (range.StartLine - 1) > totalAmountOfLines
125+
|| range.EndLine < 1
126+
|| (range.EndLine - 1) > totalAmountOfLines
127+
then
128+
invalidArg (nameof range) "The range is outside the file boundaries"
129+
else
130+
let sourceText = this :> ISourceText
131+
let startLine = range.StartLine - 1
132+
let line = sourceText.GetLineString startLine
133+
134+
if range.StartLine = range.EndLine then
135+
let length = range.EndColumn - range.StartColumn
136+
line.Substring(range.StartColumn, length)
137+
else
138+
let firstLineContent = line.Substring(range.StartColumn)
139+
let sb = System.Text.StringBuilder().AppendLine(firstLineContent)
140+
141+
for lineNumber in range.StartLine .. range.EndLine - 2 do
142+
sb.AppendLine(sourceText.GetLineString lineNumber) |> ignore
143+
144+
let lastLine = sourceText.GetLineString(range.EndLine - 1)
145+
sb.Append(lastLine.Substring(0, range.EndColumn)).ToString()
146+
111147
module SourceText =
112148

113149
let ofString str = StringText(str) :> ISourceText

0 commit comments

Comments
 (0)