Skip to content

Commit

Permalink
Merge pull request #16102 from dotnet/merges/main-to-release/dev17.9
Browse files Browse the repository at this point in the history
  • Loading branch information
vzarytovskii authored Oct 11, 2023
2 parents 8c92c8c + b7d70f3 commit 09559b0
Show file tree
Hide file tree
Showing 75 changed files with 1,497 additions and 884 deletions.
24 changes: 12 additions & 12 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Dependencies>
<ProductDependencies>
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.23468.3">
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.23502.1">
<Uri>https://github.com/dotnet/source-build-reference-packages</Uri>
<Sha>b88b567fbf54c5404d039b80cfb86f09a681f604</Sha>
<Sha>05ffbf9df6c1dc621665ee1864874c4fe6de874c</Sha>
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.SourceBuild.Intermediate.msbuild" Version="17.7.0-preview-23217-02">
Expand Down Expand Up @@ -39,25 +39,25 @@
<Sha>194f32828726c3f1f63f79f3dc09b9e99c157b11</Sha>
<SourceBuild RepoName="xliff-tasks" ManagedOnly="true" />
</Dependency>
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
</Dependency>
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
</Dependency>
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23471.3">
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.23507.6">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>ee166d79f3a269d2a1c6b7d400df7e284b1aa67b</Sha>
<Sha>9d70382f52bc311fa51e523bb066ebb012bf8035</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
10 changes: 5 additions & 5 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@
<FluentAssertionsVersion>5.10.3</FluentAssertionsVersion>
<HumanizerCoreVersion>2.2.0</HumanizerCoreVersion>
<!-- MIBC profile packages -->
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntx64MIBCRuntimeVersion>
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntx86MIBCRuntimeVersion>
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationwindows_ntarm64MIBCRuntimeVersion>
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationlinuxx64MIBCRuntimeVersion>
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.23471.3</optimizationlinuxarm64MIBCRuntimeVersion>
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntx64MIBCRuntimeVersion>
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntx86MIBCRuntimeVersion>
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationwindows_ntarm64MIBCRuntimeVersion>
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationlinuxx64MIBCRuntimeVersion>
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.23507.6</optimizationlinuxarm64MIBCRuntimeVersion>
</PropertyGroup>
</Project>
3 changes: 1 addition & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"sdk": {
"version": "8.0.100-rc.1.23455.8",
"allowPrerelease": true,
"rollForward": "latestMajor"
"allowPrerelease": true
},
"tools": {
"dotnet": "8.0.100-rc.1.23455.8",
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10759,6 +10759,15 @@ and TcNonrecBindingTyparDecls cenv env tpenv bind =
TcBindingTyparDecls true cenv env tpenv synTyparDecls

and TcNonRecursiveBinding declKind cenv env tpenv ty binding =
// Check for unintended shadowing
match binding with
| SynBinding(headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ident]); range = headPatRange)) ->
match env.eNameResEnv.ePatItems.TryFind ident.idText with
| Some (Item.UnionCase(_, false)) ->
warning(Error(FSComp.SR.tcInfoIfFunctionShadowsUnionCase(), headPatRange))
| _ -> ()
| _ -> ()

let binding = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env binding
let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv binding
TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) binding
Expand Down
54 changes: 48 additions & 6 deletions src/Compiler/Checking/TailCallChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,31 @@ and CheckForNonTailRecCall (cenv: cenv) expr (tailCall: TailCall) =
| _ -> ()

/// Check call arguments, including the return argument.
and CheckCall cenv args ctxts = CheckExprs cenv args ctxts TailCall.No
and CheckCall cenv args ctxts (tailCall: TailCall) =
// detect CPS-like expressions
let rec (|IsAppInLambdaBody|_|) e =
match stripDebugPoints e with
| Expr.TyLambda (bodyExpr = bodyExpr)
| Expr.Lambda (bodyExpr = bodyExpr) ->
match (stripDebugPoints bodyExpr) with
| Expr.App _ -> Some(TailCall.YesFromExpr cenv.g e)
| IsAppInLambdaBody t -> Some t
| _ -> None
| _ -> None

// if we haven't already decided this is no tail call, try to detect CPS-like expressions
let tailCall =
if tailCall = TailCall.No then
tailCall
else
args
|> List.tryPick (fun a ->
match a with
| IsAppInLambdaBody t -> Some t
| _ -> None)
|> Option.defaultValue TailCall.No

CheckExprs cenv args ctxts tailCall

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

// Check an application
| Expr.App (f, _fty, _tyargs, argsl, _m) -> CheckApplication cenv (f, argsl) tailCall
| Expr.App (f, _fty, _tyargs, argsl, _m) ->
// detect expressions like List.collect
let checkArgForLambdaWithAppOfMustTailCall e =
match stripDebugPoints e with
| Expr.TyLambda (bodyExpr = bodyExpr)
| Expr.Lambda (bodyExpr = bodyExpr) ->
match bodyExpr with
| Expr.App (ValUseAtApp (vref, _valUseFlags), _formalType, _typeArgs, _exprs, _range) ->
cenv.mustTailCall.Contains vref.Deref
| _ -> false
| _ -> false

let tailCall =
if argsl |> List.exists checkArgForLambdaWithAppOfMustTailCall then
TailCall.No
else
tailCall

CheckApplication cenv (f, argsl) tailCall

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

Expand Down Expand Up @@ -388,7 +430,7 @@ and CheckApplication cenv (f, argsl) (tailCall: TailCall) : unit =
if hasReceiver then
CheckCallWithReceiver cenv argsl ctxts
else
CheckCall cenv argsl ctxts
CheckCall cenv argsl ctxts tailCall

and CheckLambda cenv expr (argvs, m, bodyTy) (tailCall: TailCall) =
let valReprInfo =
Expand Down Expand Up @@ -470,12 +512,12 @@ and CheckExprOp cenv (op, tyargs, args, m) ctxt : unit =
if hasReceiver then
CheckCallWithReceiver cenv args argContexts
else
CheckCall cenv args argContexts
CheckCall cenv args argContexts TailCall.No
| _ ->
if hasReceiver then
CheckCallWithReceiver cenv args argContexts
else
CheckCall cenv args argContexts
CheckCall cenv args argContexts TailCall.No

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

// This path is for expression bindings that are not actually lambdas
| _ ->
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Driver/CompilerDiagnostics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ type PhasedDiagnostic with
| 3395 -> false // tcImplicitConversionUsedForMethodArg - off by default
| 3559 -> false // typrelNeverRefinedAwayFromTop - off by default
| 3579 -> false // alwaysUseTypedStringInterpolation - off by default
| 3582 -> false // infoIfFunctionShadowsUnionCase - off by default
| _ ->
match x.Exception with
| DiagnosticEnabledWithLanguageFeature (_, _, _, enabled) -> enabled
Expand Down
27 changes: 16 additions & 11 deletions src/Compiler/Driver/GraphChecking/DependencyResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,33 @@ let queryTriePartial (trie: TrieNode) (path: LongIdentifier) : TrieNode option =

visit trie path

let mapNodeToQueryResult (node: TrieNode option) : QueryTrieNodeResult =
let mapNodeToQueryResult (currentFileIndex: FileIndex) (node: TrieNode option) : QueryTrieNodeResult =
match node with
| Some finalNode ->
if Set.isEmpty finalNode.Files then
if
Set.isEmpty finalNode.Files
// If this node exposes files which the current index cannot see, we consider it not to have data at all.
|| Set.forall (fun idx -> idx >= currentFileIndex) finalNode.Files
then
QueryTrieNodeResult.NodeDoesNotExposeData
else
QueryTrieNodeResult.NodeExposesData(finalNode.Files)
| None -> QueryTrieNodeResult.NodeDoesNotExist

/// <summary>Find a path in the Trie.</summary>
let queryTrie (trie: TrieNode) (path: LongIdentifier) : QueryTrieNodeResult =
queryTriePartial trie path |> mapNodeToQueryResult
let queryTrie (currentFileIndex: FileIndex) (trie: TrieNode) (path: LongIdentifier) : QueryTrieNodeResult =
queryTriePartial trie path |> mapNodeToQueryResult currentFileIndex

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

/// Process namespace declaration.
let processNamespaceDeclaration (trie: TrieNode) (path: LongIdentifier) (state: FileContentQueryState) : FileContentQueryState =
let queryResult = queryTrie trie path
let queryResult = queryTrie state.CurrentFile trie path

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

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

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

| FileContentEntry.NestedModule (nestedContent = nestedContent) ->
Expand Down Expand Up @@ -137,7 +142,7 @@ let collectGhostDependencies (fileIndex: FileIndex) (trie: TrieNode) (result: Fi
// For each opened namespace, if none of already resolved dependencies define it, return the top-most file that defines it.
Set.toArray result.OpenedNamespaces
|> Array.choose (fun path ->
match queryTrie trie path with
match queryTrie fileIndex trie path with
| QueryTrieNodeResult.NodeExposesData _
| QueryTrieNodeResult.NodeDoesNotExist -> None
| QueryTrieNodeResult.NodeDoesNotExposeData ->
Expand Down
7 changes: 5 additions & 2 deletions src/Compiler/Driver/GraphChecking/DependencyResolution.fsi
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
/// Logic for constructing a file dependency graph for the purposes of parallel type-checking.
module internal FSharp.Compiler.GraphChecking.DependencyResolution

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

/// <summary>Process an open path (found in the ParsedInput) with a given FileContentQueryState.</summary>
/// <remarks>This code is only used directly in unit tests.</remarks>
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,7 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl
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."
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."
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."
3237,tcCannotCallExtensionMethodInrefToByref,"Cannot call the byref extension method '%s. The first parameter requires the value to be mutable or a non-readonly byref type."
3237,tcCannotCallExtensionMethodInrefToByref,"Cannot call the byref extension method '%s. 'this' parameter requires the value to be mutable or a non-readonly byref type."
3238,tcByrefsMayNotHaveTypeExtensions,"Byref types are not allowed to have optional type extensions."
3239,tcCannotPartiallyApplyExtensionMethodForByref,"Cannot partially apply the extension method '%s' because the first parameter is a byref type."
3242,tcTypeDoesNotInheritAttribute,"This type does not inherit Attribute, it will not work correctly with other .NET languages."
Expand Down Expand Up @@ -1724,3 +1724,4 @@ featureUnmanagedConstraintCsharpInterop,"Interop between C#'s and F#'s unmanaged
3578,chkCopyUpdateSyntaxInAnonRecords,"This expression is an anonymous record, use {{|...|}} instead of {{...}}."
3579,alwaysUseTypedStringInterpolation,"Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended."
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)."
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."
38 changes: 37 additions & 1 deletion src/Compiler/Facilities/prim-lexing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace FSharp.Compiler.Text

open System
open System.IO
open FSharp.Compiler

type ISourceText =

Expand All @@ -28,6 +27,8 @@ type ISourceText =

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

abstract GetSubTextFromRange: range: range -> string

[<Sealed>]
type StringText(str: string) =

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

member this.GetSubTextFromRange(range) =
let totalAmountOfLines = getLines.Value.Length

if
range.StartLine = 0
&& range.StartColumn = 0
&& range.EndLine = 0
&& range.EndColumn = 0
then
String.Empty
elif
range.StartLine < 1
|| (range.StartLine - 1) > totalAmountOfLines
|| range.EndLine < 1
|| (range.EndLine - 1) > totalAmountOfLines
then
invalidArg (nameof range) "The range is outside the file boundaries"
else
let sourceText = this :> ISourceText
let startLine = range.StartLine - 1
let line = sourceText.GetLineString startLine

if range.StartLine = range.EndLine then
let length = range.EndColumn - range.StartColumn
line.Substring(range.StartColumn, length)
else
let firstLineContent = line.Substring(range.StartColumn)
let sb = System.Text.StringBuilder().AppendLine(firstLineContent)

for lineNumber in range.StartLine .. range.EndLine - 2 do
sb.AppendLine(sourceText.GetLineString lineNumber) |> ignore

let lastLine = sourceText.GetLineString(range.EndLine - 1)
sb.Append(lastLine.Substring(0, range.EndColumn)).ToString()

module SourceText =

let ofString str = StringText(str) :> ISourceText
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Facilities/prim-lexing.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ type ISourceText =
/// Copies a section of the input to the given destination ad the given index
abstract CopyTo: sourceIndex: int * destination: char[] * destinationIndex: int * count: int -> unit

/// Gets a section of the input based on a given range.
/// <exception cref="System.ArgumentException">Throws an exception when the input range is outside the file boundaries.</exception>
abstract GetSubTextFromRange: range: range -> string

/// Functions related to ISourceText objects
module SourceText =

Expand Down
3 changes: 0 additions & 3 deletions src/Compiler/Symbols/Exprs.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,3 @@ module public FSharpExprPatterns =

/// Indicates a witness argument index from the witness arguments supplied to the enclosing method
val (|WitnessArg|_|): FSharpExpr -> int option

/// Matches an expression with a debug point
val (|DebugPoint|_|): FSharpExpr -> (DebugPointAtLeafExpr * FSharpExpr) option
Loading

0 comments on commit 09559b0

Please sign in to comment.