Skip to content

Commit

Permalink
Merge branch 'main' into Fix16105
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinRansom authored Feb 26, 2024
2 parents 72772bd + beb01a0 commit 054fcc1
Show file tree
Hide file tree
Showing 43 changed files with 707 additions and 48 deletions.
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661))
* Allow calling method with both Optional and ParamArray. ([#PR 16688](https://github.com/dotnet/fsharp/pull/16688), [suggestions #1120](https://github.com/fsharp/fslang-suggestions/issues/1120))
* Fix release inline optimization, which leads to MethodAccessException if used with `assembly:InternalsVisibleTo`` attribute. ([Issue #16105](https://github.com/dotnet/fsharp/issues/16105), ([PR #16737](https://github.com/dotnet/fsharp/pull/16737))
* Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692))

### Added

Expand Down
3 changes: 2 additions & 1 deletion docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
### Fixed

* Allow extension methods without type attribute work for types from imported assemblies. ([PR #16368](https://github.com/dotnet/fsharp/pull/16368))
* Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692))

### Changed

* Lower interpolated strings to string concatenation. ([PR #16556](https://github.com/dotnet/fsharp/pull/16556))
* Lower interpolated strings to string concatenation. ([PR #16556](https://github.com/dotnet/fsharp/pull/16556))
4 changes: 2 additions & 2 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.24119.1">
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="9.0.0-alpha.1.24123.3">
<Uri>https://github.com/dotnet/source-build-reference-packages</Uri>
<Sha>539af5d8ae183d4fe61e8b2f8f4a8505c8a765a7</Sha>
<Sha>62fb9a85e5c4af657b0014fd6d6588c139d0bb4f</Sha>
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
</Dependency>
<!-- Intermediate is necessary for source build. -->
Expand Down
13 changes: 11 additions & 2 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10636,8 +10636,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
| ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor")
| _, _, _ -> envinner.eCallerMemberName

let envinner = {envinner with eCallerMemberName = callerName }

let envinner = { envinner with eCallerMemberName = callerName }
let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt

let isFixed, rhsExpr, overallPatTy, overallExprTy =
Expand Down Expand Up @@ -10873,6 +10872,16 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding))
if not (isNil declaredTypars) then
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding))

if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnFunctions) && memberFlagsOpt.IsNone && not attrs.IsEmpty then
let rhsIsFunction = isFunTy g overallPatTy
let lhsIsFunction = isFunTy g overallExprTy
let attrTgt =
match rhsIsFunction, lhsIsFunction with
| false, false when declaredTypars.IsEmpty -> AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
| _, _ -> AttributeTargets.Method ||| AttributeTargets.ReturnValue

TcAttributesWithPossibleTargets false cenv env attrTgt attrs |> ignore

CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv

Expand Down
7 changes: 1 addition & 6 deletions src/Compiler/Checking/TailCallChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -725,12 +725,7 @@ let CheckModuleBinding cenv (isRec: bool) (TBind _ as bind) =

// warn for non-rec functions which have the attribute
if cenv.g.langVersion.SupportsFeature LanguageFeature.WarningWhenTailCallAttrOnNonRec then
let isNotAFunction =
match bind.Var.ValReprInfo with
| Some info -> info.HasNoArgs
| _ -> false

if (not isRec || isNotAFunction) && cenv.g.HasTailCallAttrib bind.Var.Attribs then
if not isRec && cenv.g.HasTailCallAttrib bind.Var.Attribs then
warning (Error(FSComp.SR.chkTailCallAttrOnNonRec (), bind.Var.Range))

// Check if a let binding to the result of a rec expression is not inside the rec expression
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,7 @@ featureWarningIndexedPropertiesGetSetSameType,"Indexed properties getter and set
featureChkTailCallAttrOnNonRec,"Raises warnings if the 'TailCall' attribute is used on non-recursive functions."
featureUnionIsPropertiesVisible,"Union case test properties"
featureBooleanReturningAndReturnTypeDirectedPartialActivePattern,"Boolean-returning and return-type-directed partial active patterns"
featureEnforceAttributeTargetsOnFunctions,"Enforce AttributeTargets on functions"
featureLowerInterpolatedStringToConcat,"Optimizes interpolated strings in certain cases, by lowering to concatenation"
3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation."
3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation."
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/Facilities/AsyncMemoize.fs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,15 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T

}

member _.TryGet(key: 'TKey, predicate: 'TVersion -> bool) : 'TValue option =
let versionsAndJobs = cache.GetAll(key)

versionsAndJobs
|> Seq.tryPick (fun (version, job) ->
match predicate version, job with
| true, Completed(completed, _) -> Some completed
| _ -> None)

member _.Clear() = cache.Clear()

member _.Clear predicate = cache.Clear predicate
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Facilities/AsyncMemoize.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ type internal AsyncMemoize<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'T

member Get': key: 'TKey * computation: NodeCode<'TValue> -> NodeCode<'TValue>

member TryGet: key: 'TKey * predicate: ('TVersion -> bool) -> 'TValue option

member Event: IEvent<JobEvent * (string * 'TKey * 'TVersion)>

member OnEvent: ((JobEvent * (string * 'TKey * 'TVersion) -> unit) -> unit)
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type LanguageFeature =
| WarningIndexedPropertiesGetSetSameType
| WarningWhenTailCallAttrOnNonRec
| BooleanReturningAndReturnTypeDirectedPartialActivePattern
| EnforceAttributeTargetsOnFunctions
| LowerInterpolatedStringToConcat

/// LanguageVersion management
Expand Down Expand Up @@ -198,6 +199,7 @@ type LanguageVersion(versionText) =
LanguageFeature.WarningWhenTailCallAttrOnNonRec, previewVersion
LanguageFeature.UnionIsPropertiesVisible, previewVersion
LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern, previewVersion
LanguageFeature.EnforceAttributeTargetsOnFunctions, previewVersion
LanguageFeature.LowerInterpolatedStringToConcat, previewVersion
]

Expand Down Expand Up @@ -342,6 +344,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.WarningWhenTailCallAttrOnNonRec -> FSComp.SR.featureChkTailCallAttrOnNonRec ()
| LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern ->
FSComp.SR.featureBooleanReturningAndReturnTypeDirectedPartialActivePattern ()
| LanguageFeature.EnforceAttributeTargetsOnFunctions -> FSComp.SR.featureEnforceAttributeTargetsOnFunctions ()
| LanguageFeature.LowerInterpolatedStringToConcat -> FSComp.SR.featureLowerInterpolatedStringToConcat ()

/// Get a version string associated with the given feature.
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type LanguageFeature =
| WarningIndexedPropertiesGetSetSameType
| WarningWhenTailCallAttrOnNonRec
| BooleanReturningAndReturnTypeDirectedPartialActivePattern
| EnforceAttributeTargetsOnFunctions
| LowerInterpolatedStringToConcat

/// LanguageVersion management
Expand Down
22 changes: 22 additions & 0 deletions src/Compiler/Service/BackgroundCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ type internal IBackgroundCompiler =
fileName: string * options: FSharpProjectOptions * sourceText: ISourceText option * userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults * SourceTextHash) option

abstract member TryGetRecentCheckResultsForFile:
fileName: string * projectSnapshot: FSharpProjectSnapshot * userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults) option

abstract member BeforeBackgroundFileCheck: IEvent<string * FSharpProjectOptions>

abstract member FileChecked: IEvent<string * FSharpProjectOptions>
Expand Down Expand Up @@ -1174,6 +1178,16 @@ type internal BackgroundCompiler
| None -> None
| None -> None

member _.TryGetRecentCheckResultsForFile(fileName: string, projectSnapshot: FSharpProjectSnapshot, userOpName: string) =
projectSnapshot.ProjectSnapshot.SourceFiles
|> List.tryFind (fun f -> f.FileName = fileName)
|> Option.bind (fun (f: FSharpFileSnapshot) ->
let options = projectSnapshot.ToOptions()
let sourceText = f.GetSource() |> Async.AwaitTask |> Async.RunSynchronously

self.TryGetRecentCheckResultsForFile(fileName, options, Some sourceText, userOpName)
|> Option.map (fun (parseFileResults, checkFileResults, _hash) -> (parseFileResults, checkFileResults)))

/// Parse and typecheck the whole project (the implementation, called recursively as project graph is evaluated)
member private _.ParseAndCheckProjectImpl(options, userOpName) =
node {
Expand Down Expand Up @@ -1732,3 +1746,11 @@ type internal BackgroundCompiler
userOpName: string
) : (FSharpParseFileResults * FSharpCheckFileResults * SourceTextHash) option =
self.TryGetRecentCheckResultsForFile(fileName, options, sourceText, userOpName)

member _.TryGetRecentCheckResultsForFile
(
fileName: string,
projectSnapshot: FSharpProjectSnapshot,
userOpName: string
) : (FSharpParseFileResults * FSharpCheckFileResults) option =
self.TryGetRecentCheckResultsForFile(fileName, projectSnapshot, userOpName)
4 changes: 4 additions & 0 deletions src/Compiler/Service/BackgroundCompiler.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ type internal IBackgroundCompiler =
fileName: string * options: FSharpProjectOptions * sourceText: ISourceText option * userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults * SourceTextHash) option

abstract TryGetRecentCheckResultsForFile:
fileName: string * projectSnapshot: FSharpProjectSnapshot * userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults) option

abstract BeforeBackgroundFileCheck: IEvent<string * FSharpProjectOptions>

abstract FileChecked: IEvent<string * FSharpProjectOptions>
Expand Down
10 changes: 8 additions & 2 deletions src/Compiler/Service/FSharpProjectSnapshot.fs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ type internal ProjectSnapshotBase<'T when 'T :> IFileSnapshot>(projectCore: Proj
member this.FileKey(fileName: string) = this.UpTo(fileName).LastFileKey
member this.FileKey(index: FileIndex) = this.UpTo(index).LastFileKey

member this.FileKeyWithExtraFileSnapshotVersion(fileName: string) =
let fileKey = this.FileKey fileName
let fileSnapshot = this.SourceFiles |> Seq.find (fun f -> f.FileName = fileName)

fileKey.WithExtraVersion(fileSnapshot.Version |> Md5Hasher.toString)

/// Project snapshot with filenames and versions given as initial input
and internal ProjectSnapshot = ProjectSnapshotBase<FSharpFileSnapshot>

Expand Down Expand Up @@ -394,10 +400,10 @@ and internal ProjectCore
let commandLineOptions =
lazy
(seq {
yield! OtherOptions

for r in ReferencesOnDisk do
$"-r:{r.Path}"

yield! OtherOptions
}
|> Seq.toList)

Expand Down
36 changes: 33 additions & 3 deletions src/Compiler/Service/TransparentCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ type internal CompilerCaches(sizeFactor: int) =
this.AssemblyData.Clear(shouldClear)
this.SemanticClassification.Clear(snd >> shouldClear)
this.ItemKeyStore.Clear(snd >> shouldClear)
this.ScriptClosure.Clear(snd >> shouldClear) // Todo check if correct predicate
this.ScriptClosure.Clear(snd >> shouldClear)

type internal TransparentCompiler
(
Expand Down Expand Up @@ -1472,9 +1472,8 @@ type internal TransparentCompiler

let ComputeParseAndCheckFileInProject (fileName: string) (projectSnapshot: ProjectSnapshot) =
caches.ParseAndCheckFileInProject.Get(
projectSnapshot.FileKey fileName,
projectSnapshot.FileKeyWithExtraFileSnapshotVersion fileName,
node {

use _ =
Activity.start "ComputeParseAndCheckFileInProject" [| Activity.Tags.fileName, fileName |> Path.GetFileName |]

Expand Down Expand Up @@ -1605,6 +1604,29 @@ type internal TransparentCompiler
}
)

let TryGetRecentCheckResultsForFile
(
fileName: string,
projectSnapshot: FSharpProjectSnapshot,
userOpName: string
) : (FSharpParseFileResults * FSharpCheckFileResults) option =
ignore userOpName

let cacheKey =
projectSnapshot.ProjectSnapshot.FileKeyWithExtraFileSnapshotVersion fileName

let version = cacheKey.GetVersion()

let parseFileResultsAndcheckFileAnswer =
caches.ParseAndCheckFileInProject.TryGet(
cacheKey.GetKey(),
(fun (_fullVersion, fileContentVersion) -> fileContentVersion = (snd version))
)

match parseFileResultsAndcheckFileAnswer with
| Some(parseFileResults, FSharpCheckFileAnswer.Succeeded checkFileResults) -> Some(parseFileResults, checkFileResults)
| _ -> None

let ComputeProjectExtras (bootstrapInfo: BootstrapInfo) (projectSnapshot: ProjectSnapshotWithSources) =
caches.ProjectExtras.Get(
projectSnapshot.SignatureKey,
Expand Down Expand Up @@ -2356,3 +2378,11 @@ type internal TransparentCompiler
userOpName: string
) : (FSharpParseFileResults * FSharpCheckFileResults * SourceTextHash) option =
backgroundCompiler.TryGetRecentCheckResultsForFile(fileName, options, sourceText, userOpName)

member this.TryGetRecentCheckResultsForFile
(
fileName: string,
projectSnapshot: FSharpProjectSnapshot,
userOpName: string
) : (FSharpParseFileResults * FSharpCheckFileResults) option =
TryGetRecentCheckResultsForFile(fileName, projectSnapshot, userOpName)
2 changes: 1 addition & 1 deletion src/Compiler/Service/TransparentCompiler.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ type internal CompilerCaches =
member ParseAndCheckAllFilesInProject: AsyncMemoizeDisabled<obj, obj, obj>

member ParseAndCheckFileInProject:
AsyncMemoize<(string * (string * string)), string, (FSharpParseFileResults * FSharpCheckFileAnswer)>
AsyncMemoize<(string * (string * string)), string * string, (FSharpParseFileResults * FSharpCheckFileAnswer)>

member ParseAndCheckProject: AsyncMemoize<(string * string), string, FSharpCheckProjectResults>

Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Service/service.fs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ type FSharpChecker
let userOpName = defaultArg userOpName "Unknown"
backgroundCompiler.TryGetRecentCheckResultsForFile(fileName, options, sourceText, userOpName)

member _.TryGetRecentCheckResultsForFile(fileName: string, projectSnapshot: FSharpProjectSnapshot, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
backgroundCompiler.TryGetRecentCheckResultsForFile(fileName, projectSnapshot, userOpName)

member _.Compile(argv: string[], ?userOpName: string) =
let _userOpName = defaultArg userOpName "Unknown"
use _ = Activity.start "FSharpChecker.Compile" [| Activity.Tags.userOpName, _userOpName |]
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/Service/service.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ type public FSharpChecker =
fileName: string * options: FSharpProjectOptions * ?sourceText: ISourceText * ?userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults (* hash *) * int64) option

[<Experimental("This FCS API is experimental and subject to change.")>]
member TryGetRecentCheckResultsForFile:
fileName: string * projectSnapshot: FSharpProjectSnapshot * ?userOpName: string ->
(FSharpParseFileResults * FSharpCheckFileResults) option

/// This function is called when the entire environment is known to have changed for reasons not encoded in the ProjectOptions of any project/compilation.
member InvalidateAll: unit -> unit

Expand Down
14 changes: 10 additions & 4 deletions src/Compiler/Utilities/LruCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,27 @@ type internal LruCache<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVers

/// Returns an option of a value for given key and version, and also a list of all other versions for given key
member this.GetAll(key, version) =
this.TryGet(key, version),
let others =
this.GetAll(key) |> Seq.filter (fun (ver, _val) -> ver <> version) |> Seq.toList

this.TryGet(key, version), others

/// Returns a list of version * value pairs for a given key. The strongly held value is first in the list.
member _.GetAll(key: 'TKey) : ('TVersion * 'TValue) seq =
match dictionary.TryGetValue key with
| false, _ -> []
| true, versionDict ->
versionDict.Values
|> Seq.map (fun node -> node.Value)
|> Seq.filter (p24 >> ((<>) version))
|> Seq.map (_.Value)
|> Seq.sortBy (function
| _, _, _, Strong _ -> 0
| _ -> 1)
|> Seq.choose (function
| _, ver, _, Strong v -> Some(ver, v)
| _, ver, _, Weak r ->
match r.TryGetTarget() with
| true, x -> Some(ver, x)
| _ -> None)
|> Seq.toList

member _.Remove(key, version) =
match dictionary.TryGetValue key with
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Utilities/LruCache.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type internal LruCache<'TKey, 'TVersion, 'TValue when 'TKey: equality and 'TVers
/// Returns an option of a value for given key and version, and also a list of all other versions for given key
member GetAll: key: 'TKey * version: 'TVersion -> 'TValue option * ('TVersion * 'TValue) list

/// Returns a list of version * value pairs for a given key. The strongly held value is first in the list.
member GetAll: key: 'TKey -> ('TVersion * 'TValue) seq

member GetValues: unit -> (string * 'TVersion * 'TValue) seq

member Remove: key: 'TKey -> unit
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 054fcc1

Please sign in to comment.