Skip to content

Commit 4ded394

Browse files
authored
FCS: allow getting captured types (#18878)
1 parent e20e8a7 commit 4ded394

11 files changed

+70
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Add support for tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804))
55
* Add `--typecheck-only` flag support for F# Interactive (FSI) scripts to type-check without execution. ([Issue #18686](https://github.com/dotnet/fsharp/issues/18686))
66
* Diagnostics: add extended data for 'No constructors' error ([PR #18863](https://github.com/dotnet/fsharp/pull/18863))
7+
* FCS: allow getting captured types ([PR $18878](https://github.com/dotnet/fsharp/pull/18878))
78

89
### Fixed
910

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6198,6 +6198,7 @@ and TcExprTuple (cenv: cenv) overallTy env tpenv (isExplicitStruct, args, m) =
61986198
let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m overallTy isExplicitStruct args
61996199
let argsR, tpenv = TcExprsNoFlexes cenv env m tpenv argTys args
62006200
let expr = mkAnyTupled g m tupInfo argsR argTys
6201+
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, mkAnyTupledTy g tupInfo argTys, env.eAccessRights)
62016202
expr, tpenv
62026203
)
62036204

@@ -10652,6 +10653,8 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synExpr cont =
1065210653
if not isRecovery && Option.isNone synElseExprOpt then
1065310654
UnifyTypes cenv env m g.unit_ty overallTy.Commit
1065410655

10656+
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.eAccessRights)
10657+
1065510658
TcExprThatCanBeCtorBody cenv overallTy env tpenv synThenExpr
1065610659

1065710660
match synElseExprOpt with

src/Compiler/Service/FSharpCheckerResults.fs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,6 +2040,16 @@ type internal TypeCheckInfo
20402040
member scope.IsRelativeNameResolvableFromSymbol(cursorPos: pos, plid: string list, symbol: FSharpSymbol) : bool =
20412041
scope.IsRelativeNameResolvable(cursorPos, plid, symbol.Item)
20422042

2043+
member scope.TryGetCapturedType(range) =
2044+
sResolutions.CapturedExpressionTypings
2045+
|> Seq.tryFindBack (fun (_, _, _, m) -> equals m range)
2046+
|> Option.map (fun (ty, _, _, _) -> FSharpType(cenv, ty))
2047+
2048+
member scope.TryGetCapturedDisplayContext(range) =
2049+
sResolutions.CapturedExpressionTypings
2050+
|> Seq.tryFindBack (fun (_, _, _, m) -> equals m range)
2051+
|> Option.map (fun (_, q, _, _) -> FSharpDisplayContext(fun _ -> q.DisplayEnv))
2052+
20432053
/// Get the auto-complete items at a location
20442054
member _.GetDeclarations
20452055
(parseResultsOpt, line, lineStr, partialName, completionContextAtPos, getAllEntities, genBodyForOverriddenMeth)
@@ -3480,6 +3490,16 @@ type FSharpCheckFileResults
34803490

34813491
member _.DependencyFiles = dependencyFiles
34823492

3493+
member _.TryGetCapturedType(range: range) =
3494+
match details with
3495+
| None -> None
3496+
| Some(scope, _) -> scope.TryGetCapturedType(range)
3497+
3498+
member _.TryGetCapturedDisplayContext(range: range) =
3499+
match details with
3500+
| None -> None
3501+
| Some(scope, _) -> scope.TryGetCapturedDisplayContext(range)
3502+
34833503
member _.GetAllUsesOfAllSymbolsInFile(?cancellationToken: CancellationToken) =
34843504
match details with
34853505
| None -> Seq.empty

src/Compiler/Service/FSharpCheckerResults.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ type public FSharpCheckFileResults =
269269
/// in the documentation for compiler service.
270270
member DependencyFiles: string[]
271271

272+
member TryGetCapturedType: range -> FSharpType option
273+
member TryGetCapturedDisplayContext: range -> FSharpDisplayContext option
274+
272275
/// <summary>Get the items for a declaration list</summary>
273276
///
274277
/// <param name="parsedFileResults">
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module FSharp.Compiler.Service.Tests.CapturedTypes
2+
3+
open FSharp.Compiler.Symbols
4+
open FSharp.Test.Assert
5+
open Xunit
6+
7+
let private displayContext =
8+
FSharpDisplayContext.Empty.WithShortTypeNames(true)
9+
10+
let tryGetCapturedType markedSource =
11+
let context, checkResults = Checker.getCheckedResolveContext markedSource
12+
checkResults.TryGetCapturedType context.SelectedRange.Value
13+
14+
let assertCapturedType expectedTypeString markedSource =
15+
let capturedType = tryGetCapturedType markedSource
16+
capturedType.Value.Format displayContext |> shouldEqual expectedTypeString
17+
18+
[<Fact>]
19+
let ``Expr - If 01`` () =
20+
assertCapturedType "int * int" "{selstart}if true then 1, 2 else 1, true{selend}"
21+
22+
[<Fact>]
23+
let ``Expr - Literal 01`` () =
24+
assertCapturedType "int" "{selstart}1{selend}"
25+
26+
[<Fact>]
27+
let ``Expr - Literal 02`` () =
28+
assertCapturedType "string" "{selstart}\"\"{selend}"
29+
30+
[<Fact>]
31+
let ``Expr - Tuple 01`` () =
32+
assertCapturedType "int * int" "{selstart}1, 2{selend}"
33+
34+
[<Fact>]
35+
let ``Expr - Tuple 02`` () =
36+
assertCapturedType "int * int" "if true then {selstart}1, 2{selend} else 1, true"

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,9 +2081,11 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Text.Range[
20812081
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUsesAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
20822082
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetDeclarationListSymbols(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
20832083
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUseAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
2084+
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] TryGetCapturedDisplayContext(FSharp.Compiler.Text.Range)
20842085
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position)
20852086
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFile
20862087
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFile()
2088+
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] TryGetCapturedType(FSharp.Compiler.Text.Range)
20872089
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature(Microsoft.FSharp.Core.FSharpOption`1[System.Int32])
20882090
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetMethodsAsSymbols(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
20892091
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetF1Keyword(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="SourceTextTests.fs" />
7777
<Compile Include="SynExprTests.fs" />
7878
<Compile Include="SynPatTests.fs" />
79+
<Compile Include="CapturedTypes.fs" />
7980
<Compile Include="WarnScopeTests.fs" />
8081
</ItemGroup>
8182

tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net10.0.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
2424
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3499-814::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
2525
[IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@106::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
26-
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
26+
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2235::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
2727
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
2828
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
2929
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.

tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3499-814::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001E5][found Char] Unexpected type on the stack.
3232
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
3333
[IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@106::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
34-
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
34+
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+dataTipOfReferences@2235::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
3535
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x00000059][found Char] Unexpected type on the stack.
3636
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1<FSharp.Compiler.EditorServices.AssemblySymbol>&)][offset 0x000000DA][found Char] Unexpected type on the stack.
3737
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1447-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<FSharp.Compiler.Syntax.SyntaxNode>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1<FSharp.Compiler.EditorServices.CompletionContext>>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x000005FD][found Char] Unexpected type on the stack.

tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net10.0.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
2323
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
2424
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3499-852::Invoke([S.P.CoreLib]System.Tuple`3<char[],int32,int32>)][offset 0x000001C7][found Char] Unexpected type on the stack.
25-
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
25+
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2235::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack.
2626
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
2727
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
2828
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack.

0 commit comments

Comments
 (0)