Skip to content

Commit

Permalink
Merge pull request #17098 from dotnet/merges/main-to-lsp
Browse files Browse the repository at this point in the history
Merge main to lsp
  • Loading branch information
abonie committed Apr 29, 2024
2 parents 104b13f + 7e1b266 commit b3c669d
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 50 deletions.
15 changes: 12 additions & 3 deletions src/Compiler/Checking/CheckExpressions.fs
Expand Up @@ -10625,6 +10625,11 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
| NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), mBinding, debugPoint) ->
let (SynValData(memberFlags = memberFlagsOpt)) = valSynData

let isClassLetBinding =
match declKind, kind with
| ClassLetBinding _, SynBindingKind.Normal -> true
| _ -> false

let callerName =
match declKind, kind, pat with
| ExpressionBinding, _, _ -> envinner.eCallerMemberName
Expand Down Expand Up @@ -10880,14 +10885,14 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding))

if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then
TcAttributeTargetsOnLetBindings cenv env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty)
TcAttributeTargetsOnLetBindings cenv env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding

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

// Note:
// - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue
// - Let function bindings can only have attributes that uses AttributeTargets.Method ||| AttributeTargets.ReturnValue
and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallExprTy areTyparsDeclared =
and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallExprTy areTyparsDeclared isClassLetBinding =
let attrTgt =
if
// It's a type function:
Expand All @@ -10899,7 +10904,11 @@ and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallE
|| isFunTy cenv.g overallPatTy
|| isFunTy cenv.g overallExprTy
then
AttributeTargets.ReturnValue ||| AttributeTargets.Method
// Class let bindings are a special case, they can have attributes that target fields and properties, since they might be lifted to those and contain lambdas/functions.
if isClassLetBinding then
AttributeTargets.ReturnValue ||| AttributeTargets.Method ||| AttributeTargets.Field ||| AttributeTargets.Property
else
AttributeTargets.ReturnValue ||| AttributeTargets.Method
else
AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property

Expand Down
4 changes: 3 additions & 1 deletion src/Compiler/Utilities/illib.fs
Expand Up @@ -14,7 +14,10 @@ open System.Runtime.CompilerServices
[<Class>]
type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) =
let syncObj = obj ()

[<VolatileField>]
let mutable valueFactory = valueFactory

let mutable value = value

new(valueFactory: unit -> 'T) = InterruptibleLazy(Unchecked.defaultof<_>, valueFactory)
Expand All @@ -28,7 +31,6 @@ type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) =
match box valueFactory with
| null -> value
| _ ->

Monitor.Enter(syncObj)

try
Expand Down
32 changes: 27 additions & 5 deletions src/FSharp.Build/Microsoft.FSharp.Targets
Expand Up @@ -235,7 +235,7 @@ this file.
</FSharpEmbedResXSource>

<ItemGroup>
<CompileBefore Include="@(_FsGeneratedResXSource)" />
<Compile Include="@(_FsGeneratedResXSource)" CompileOrder="CompileBefore" />
<FsGeneratedSource Include="@(_FsGeneratedResXSource)" />
<FileWrites Include="@(_FsGeneratedResXSource)" />
</ItemGroup>
Expand All @@ -247,14 +247,35 @@ this file.
</FSharpEmbedResourceText>

<ItemGroup>
<CompileBefore Include="@(_FsGeneratedTxtSource)" />
<Compile Include="@(_FsGeneratedTxtSource)" CompileOrder="CompileBefore" />
<FsGeneratedSource Include="@(_FsGeneratedTxtSource)" />
<EmbeddedResource Include="@(_FsGeneratedResx)" />
<FileWrites Include="@(_FsGeneratedTxtSource)" />
<FileWrites Include="@(_FsGeneratedResx)" />
</ItemGroup>
</Target>

<Target Name="FSharpSourceCodeCompileOrder">
<!-- implement <CompileOrder>CompileBefore</CompileOrder> -->
<ItemGroup>
<__Sources Remove="@(__Sources)" />
<__Sources Include="@(Compile->WithMetadataValue('CompileOrder', 'CompileFirst'))" />
<__Sources Include="@(CompileBefore)" />
<__Sources Include="@(Compile->WithMetadataValue('CompileOrder', 'CompileBefore'))" />
<__Sources Include="@(Compile->WithMetadataValue('CompileOrder', ''))" />
<__Sources Include="@(Compile->WithMetadataValue('CompileOrder', 'CompileAfter'))" />
<__Sources Include="@(CompileAfter)" />
<__Sources Include="@(Compile->WithMetadataValue('CompileOrder', 'CompileLast'))" />
</ItemGroup>
<ItemGroup>
<Compile Remove="@(Compile)" />
<CompileBefore Remove="@(CompileBefore)" />
<CompileAfter Remove="@(CompileAfter)" />
<Compile Include="@(__Sources)" />
</ItemGroup>
<Message Importance="low" Text="FSharpSourceCodeCompileOrder:Sources: '@(__Sources)'" />
</Target>

<Target
Name="CoreCompile"
Inputs="$(MSBuildAllProjects);
Expand Down Expand Up @@ -284,7 +305,7 @@ this file.
$(NonExistentFile);
@(CustomAdditionalCompileOutputs)"
Returns="@(FscCommandLineArgs)"
DependsOnTargets="$(CoreCompileDependsOn)"
DependsOnTargets="$(CoreCompileDependsOn);FSharpSourceCodeCompileOrder"
>

<Error
Expand Down Expand Up @@ -321,6 +342,7 @@ this file.
<EmbeddedFiles Include="@(FsGeneratedSource)" KeepDuplicates="false" Condition="'$(SourceLink)'!='' or '$(EmbeddedFiles)'!='' or '$(EmbedAllSources)'!=''" />
</ItemGroup>


<!-- Dotnet SDK requires SimpleResolution to be true Legacy project system build not -->
<PropertyGroup>
<FscOtherFlags Condition="'$(SimpleResolution)' == 'true'">--simpleresolution $(OtherFlags)</FscOtherFlags>
Expand Down Expand Up @@ -371,7 +393,7 @@ this file.
Resources="@(ActualEmbeddedResources)"
SkipCompilerExecution="$(SkipCompilerExecution)"
SourceLink="$(SourceLink)"
Sources="@(CompileBefore);@(Compile);@(CompileAfter)"
Sources="@(Compile)"
SubsystemVersion="$(SubsystemVersion)"
Tailcalls="$(Tailcalls)"
TargetType="$(OutputType)"
Expand Down Expand Up @@ -434,7 +456,7 @@ this file.
Overwrite="true"/>

<ItemGroup Condition="'$(AdditionalSourcesText)' != ''">
<CompileBefore Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
<Compile Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"><CompileOrder>CompileBefore</CompileOrder></Compile>
<_FsGeneratedTfmAttributesSource Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
</ItemGroup>
</Target>
Expand Down
13 changes: 13 additions & 0 deletions src/FSharp.Core/FSharp.Core.fsproj
Expand Up @@ -61,12 +61,25 @@
</EmbeddedResource>
<EmbeddedResource Include="ILLink.LinkAttributes.xml" LogicalName="ILLink.LinkAttributes.xml" />
<EmbeddedResource Include="ILLink.Substitutions.xml" LogicalName="ILLink.Substitutions.xml" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Proto'">
<!-- This can be removed once CompileBefore support is shipped in an rtm relase -->
<CompileBefore Include="prim-types-prelude.fsi">
<Link>Primitives/prim-types-prelude.fsi</Link>
</CompileBefore>
<CompileBefore Include="prim-types-prelude.fs">
<Link>Primitives/prim-types-prelude.fs</Link>
</CompileBefore>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' != 'Proto'">
<Compile Include="prim-types-prelude.fsi" CompileOrder="CompileFirst">
<Link>Primitives/prim-types-prelude.fsi</Link>
</Compile>
<Compile Include="prim-types-prelude.fs" CompileOrder="CompileFirst">
<Link>Primitives/prim-types-prelude.fs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="prim-types.fsi">
<Link>Primitives/prim-types.fsi</Link>
</Compile>
Expand Down
Expand Up @@ -171,27 +171,7 @@ module CustomAttributes_AttributeUsage =
|> withLangVersionPreview
|> withOptions ["--nowarn:25"]
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 842, Line 11, Col 6, Line 11, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 6, Line 14, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 17, Col 6, Line 17, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 19, Col 10, Line 19, Col 19, "This attribute is not valid for use on this language element")
(Error 842, Line 21, Col 6, Line 21, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 6, Line 24, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 27, Col 6, Line 27, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 30, Col 6, Line 30, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 33, Col 6, Line 33, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 36, Col 6, Line 36, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 39, Col 6, Line 39, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 42, Col 6, Line 42, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 45, Col 6, Line 45, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 49, Col 6, Line 49, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 56, Col 6, Line 56, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 64, Col 6, Line 64, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 66, Col 10, Line 66, Col 19, "This attribute is not valid for use on this language element")
(Error 842, Line 68, Col 6, Line 68, Col 15, "This attribute is not valid for use on this language element")
]
|> shouldSucceed

// SOURCE=E_AttributeTargetIsMethod02.fs # E_AttributeTargetIsMethod02.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsMethod02.fs"|])>]
Expand Down Expand Up @@ -591,4 +571,16 @@ module CustomAttributes_AttributeUsage =
(Error 842, Line 20, Col 3, Line 20, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element")
(Error 842, Line 22, Col 3, Line 22, Col 13, "This attribute is not valid for use on this language element")
]
]

[<Fact>]
let ``Type-level let bindings allowed to use attribute with Field target`` () =
FSharp"""
module Foo
type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
[<VolatileField>]
let mutable valueFactory = valueFactory
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
Expand Up @@ -8,62 +8,62 @@ type FieldOnlyAttribute() =
inherit Attribute()

type TestClass() =
[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
static let func1() = "someFunction"

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
static let rec func2() = "someFunction"

[<FieldOnly>]// Should fail
[<FieldOnly>]// Should succeed (special exception when function can be lifted to a field)
static let rec func3() = "someFunction"
and [<FieldOnly>] fun4() = "someFunction" // Should fail
and [<FieldOnly>] fun4() = "someFunction" // Should succeed (special exception when function can be lifted to a field)

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func5 () = "someFunction"

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func6 a = a + 1

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func7 (a, b) = a + b

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func8 (a: int) : int = a + 1

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func9 a b = [ a; b ]

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func10 = fun x -> x

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let func11 = id

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let (|Bool|_|) = function "true" -> Some true | "false" -> Some false | _ -> None

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
[<return: Struct>]
let (|BoolExpr2|_|) = function "true" -> ValueSome true | "false" -> ValueSome false | _ -> ValueNone

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let (|BoolExpr3|_|) x =
match x with
| "true" -> Some true
| "false" -> Some false
| _ -> None

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
[<return: Struct>]
let (|BoolExpr4|_|) x =
match x with
| "true" -> ValueSome true
| "false" -> ValueSome false
| _ -> ValueNone

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let rec func12() = 0
and [<FieldOnly>] func13() = [] // Should fail
and [<FieldOnly>] func13() = [] // Should succeed (special exception when function can be lifted to a field)

[<FieldOnly>] // Should fail
[<FieldOnly>] // Should succeed (special exception when function can be lifted to a field)
let rec func14() = 0
42 changes: 42 additions & 0 deletions tests/fsharp/SDKTests/tests/CompileOrder - BeforeAndAfter.proj
@@ -0,0 +1,42 @@
<Project ToolsVersion="4.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- Initialize Variables -->
<PropertyGroup>
<FSharpCompilerPath></FSharpCompilerPath>
</PropertyGroup>

<!-- Expected Values -->
<PropertyGroup>
<ExpectedFSharpShimPresent>true</ExpectedFSharpShimPresent>
<ExpectedFSharpCompilerPath>/Common7/IDE/CommonExtensions/Microsoft/FSharp/Tools/</ExpectedFSharpCompilerPath>
<ExpectedFscToolExe>fscAnyCpu.exe</ExpectedFscToolExe>
<ExpectedFscToolPath>_VsInstallRoot_/Common7/IDE/CommonExtensions/Microsoft/FSharp/Tools/</ExpectedFscToolPath>
<ExpectedDotnetFscCompilerPath></ExpectedDotnetFscCompilerPath>
<ExpectedCompile>One;Two;Three;Four;Five;Six;Seven;Eight;Nine;Ten;Eleven;Twelve;Thirteen;Fourteen</ExpectedCompile>
</PropertyGroup>

<Import Project="ToolsTest.props" />

<PropertyGroup>
</PropertyGroup>

<ItemGroup>
<CompileAfter Include="Eleven" />
<Compile Include="Thirteen" CompileOrder="CompileLast" />
<CompileBefore Include="Three" />
<CompileAfter Include="Twelve" />
<CompileBefore Include="Four" />
<Compile Include="Seven" />
<Compile Include="Eight" />
<Compile Include="Five" CompileOrder="CompileBefore" />
<Compile Include="One" CompileOrder="CompileFirst" />
<Compile Include="Nine" CompileOrder="CompileAfter" />
<Compile Include="Fourteen" CompileOrder="CompileLast" />
<Compile Include="Ten" CompileOrder="CompileAfter" />
<Compile Include="Two" CompileOrder="CompileFirst" />
<Compile Include="Six" CompileOrder="CompileBefore" />
</ItemGroup>

<Import Project="ToolsTest.targets" />

</Project>
5 changes: 4 additions & 1 deletion tests/fsharp/SDKTests/tests/ToolsTest.targets
Expand Up @@ -4,10 +4,11 @@

<Import Project="$(TargetsDirectory)\Microsoft.FSharp.targets" />

<Target Name="Test">
<Target Name="Test" DependsOnTargets="FSharpSourceCodeCompileOrder">
<Message Importance="High" Text="===========================================================================================================" />
<Message Importance="High" Text="Testing : $(MSBuildProjectName)" />


<!-- check for expected settings -->
<Error Condition="'$(ExpectedFSharpShimPresent)' != '$(FSharp_Shim_Present)'" Text="FSharp_Shim_Present expected:'$(ExpectedFSharpShimPresent)' actual: '$(FSharp_Shim_Present)'" />

Expand All @@ -17,6 +18,8 @@

<Error Condition="'$(ExpectedFscToolPath)' != '$(FscToolPath)'" Text="FscToolPath: expected:'$(ExpectedFscToolPath)' actual:'$(FscToolPath)'" />

<Error Condition="'$(ExpectedCompile)' != '' and '$(ExpectedCompile)' != '@(Compile)'" Text="ExpectedCompile: expected:'$(ExpectedCompile)' actual:'@(Compile)'" />

<Error Condition="'$(ExpectedDotnetFscCompilerPath)' == '' and '$(DotnetFscCompilerPath)' != ''" Text="DotnetFscCompilerPath expected to be empty actual:'$(DotnetFscCompilerPath)'" />

<Error Condition="'$(ExpectedDotnetFscCompilerPath)' != '' and $([System.String]::new('$(DotnetFscCompilerPath)').EndsWith('$(ExpectedDotnetFscCompilerPath)')) == true" Text="DotnetFscCompilerPath expected to end with: '$(ExpectedDotnetFscCompilerPath)' actual:'$(DotnetFscCompilerPath)'" />
Expand Down

0 comments on commit b3c669d

Please sign in to comment.