Skip to content

Commit e77d53b

Browse files
dawedawepsfinaki
andauthored
Allow usage of [<TailCall>] with older FSharp.Core package versions (#16373)
* allow the TailCall attribute to be defined outside of FSharp.Core by just checking the CompiledName to be "TailCallAttribute" * check the FullName to make sure it's in the FSharp.Core namespace * add changelog entry * add PR number to changelog entry * - remove member attrib_TailCallAttribute from TcGlobals - move hasTailCallAttrib from TailCallChecks.fs to TcGlobals * Update tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs Co-authored-by: Petr <[email protected]> * remote "withLangVersionPreview" from test for self-defined attribute * add sample project to demonstrate --------- Co-authored-by: Petr <[email protected]>
1 parent e795c9b commit e77d53b

File tree

7 files changed

+73
-7
lines changed

7 files changed

+73
-7
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
- Parens analysis: fix some parenthesization corner-cases in record expressions - https://github.com/dotnet/fsharp/pull/16370
44
- Parens analysis: keep parens in method calls in dot-lambdas - https://github.com/dotnet/fsharp/pull/16395
55
- Fixes #16359 - correctly handle imports with 0 length public key tokens - https://github.com/dotnet/fsharp/pull/16363
6-
- Raise a new error when interfaces with auto properties are implemented on constructor-less types - https://github.com/dotnet/fsharp/pull/16352
6+
- Raise a new error when interfaces with auto properties are implemented on constructor-less types - https://github.com/dotnet/fsharp/pull/16352
7+
- Allow usage of `[<TailCall>]` with older `FSharp.Core` package versions - https://github.com/dotnet/fsharp/pull/16373

src/Compiler/Checking/TailCallChecks.fs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,7 @@ let CheckModuleBinding cenv (isRec: bool) (TBind _ as bind) =
738738
| Some info -> info.HasNoArgs
739739
| _ -> false
740740

741-
if
742-
(not isRec || isNotAFunction)
743-
&& HasFSharpAttribute cenv.g cenv.g.attrib_TailCallAttribute bind.Var.Attribs
744-
then
741+
if (not isRec || isNotAFunction) && cenv.g.HasTailCallAttrib bind.Var.Attribs then
745742
warning (Error(FSComp.SR.chkTailCallAttrOnNonRec (), bind.Var.Range))
746743

747744
// Check if a let binding to the result of a rec expression is not inside the rec expression
@@ -807,7 +804,7 @@ and CheckDefnInModule cenv mdef =
807804
let mustTailCall =
808805
Seq.fold
809806
(fun mustTailCall (v: Val) ->
810-
if HasFSharpAttribute cenv.g cenv.g.attrib_TailCallAttribute v.Attribs then
807+
if cenv.g.HasTailCallAttrib v.Attribs then
811808
let newSet = Zset.add v mustTailCall
812809
newSet
813810
else

src/Compiler/TypedTree/TcGlobals.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,6 @@ type TcGlobals(
15321532
member val attrib_CompilerFeatureRequiredAttribute = findSysAttrib "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute"
15331533
member val attrib_SetsRequiredMembersAttribute = findSysAttrib "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute"
15341534
member val attrib_RequiredMemberAttribute = findSysAttrib "System.Runtime.CompilerServices.RequiredMemberAttribute"
1535-
member val attrib_TailCallAttribute = mk_MFCore_attrib "TailCallAttribute"
15361535

15371536
member g.improveType tcref tinst = improveTy tcref tinst
15381537

@@ -1870,6 +1869,10 @@ type TcGlobals(
18701869

18711870
member _.DebuggerNonUserCodeAttribute = debuggerNonUserCodeAttribute
18721871

1872+
member _.HasTailCallAttrib (attribs: Attribs) =
1873+
attribs
1874+
|> List.exists (fun a -> a.TyconRef.CompiledRepresentationForNamedType.FullName = "Microsoft.FSharp.Core.TailCallAttribute")
1875+
18731876
member _.MakeInternalsVisibleToAttribute(simpleAssemName) =
18741877
mkILCustomAttribute (tref_InternalsVisibleToAttribute, [ilg.typ_String], [ILAttribElem.String (Some simpleAssemName)], [])
18751878

tests/FSharp.Compiler.ComponentTests/ErrorMessages/TailCallAttribute.fs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,3 +1486,29 @@ namespace N
14861486
Message =
14871487
"The TailCall attribute should only be applied to recursive functions." }
14881488
]
1489+
1490+
[<FSharp.Test.FactForNETCOREAPP>]
1491+
let ``Warn about self-defined attribute`` () = // is the analysis available for users of older FSharp.Core versions
1492+
"""
1493+
module Microsoft.FSharp.Core
1494+
1495+
open System
1496+
1497+
[<AttributeUsage(AttributeTargets.Method)>]
1498+
type TailCallAttribute() = inherit Attribute()
1499+
1500+
[<TailCall>]
1501+
let rec f x = 1 + f x
1502+
"""
1503+
|> FSharp
1504+
|> compile
1505+
|> shouldFail
1506+
|> withResults [
1507+
{ Error = Warning 3569
1508+
Range = { StartLine = 10
1509+
StartColumn = 23
1510+
EndLine = 10
1511+
EndColumn = 26 }
1512+
Message =
1513+
"The member or function 'f' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way." }
1514+
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Microsoft.FSharp.Core
2+
3+
open System
4+
5+
[<AttributeUsage(AttributeTargets.Method)>]
6+
type TailCallAttribute() = inherit Attribute()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace N
2+
3+
module M =
4+
5+
open Microsoft.FSharp.Core
6+
7+
[<TailCall>]
8+
let rec f x = 1 + f x
9+
10+
[<EntryPoint>]
11+
let main argv =
12+
printfn "Hello from F#"
13+
0
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
6+
<LangVersion>preview</LangVersion>
7+
</PropertyGroup>
8+
9+
<PropertyGroup>
10+
<DotnetFscCompilerPath>$(MSBuildThisFileDirectory)../../../../artifacts/bin/fsc/Debug/net8.0/fsc.dll</DotnetFscCompilerPath>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<Compile Include="Attribute.fs" />
15+
<Compile Include="Program.fs" />
16+
</ItemGroup>
17+
<ItemGroup>
18+
<PackageReference Include="FSharp.Core" Version="6.0.7" />
19+
</ItemGroup>
20+
</Project>

0 commit comments

Comments
 (0)