diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index 16f5721e22a..aa4e6eea89a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -26,6 +26,7 @@ * Fix confusing type inference error in task expression ([Issue #13789](https://github.com/dotnet/fsharp/issues/13789), [PR #18450](https://github.com/dotnet/fsharp/pull/18450)) * Fix missing `null` highlighting in tooltips ([PR #18457](https://github.com/dotnet/fsharp/pull/18457)) * Make `[]` combination work([PR #18444](https://github.com/dotnet/fsharp/pull/18444/)) +* Fix code completion considers types from own namespace non-imported ([PR #18518](https://github.com/dotnet/fsharp/issues/18518)) ### Added * Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241)) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 78acf62bb98..92368118f3a 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -341,7 +341,7 @@ let AddNonLocalCcu g amap scopem env assemblyName (ccu: CcuThunk, internalsVisib env /// Adjust the TcEnv to account for a fully processed "namespace" declaration in this file -let AddLocalRootModuleOrNamespace tcSink g amap scopem env (moduleTy: ModuleOrNamespaceType) = +let AddLocalRootModuleOrNamespace g amap scopem env (moduleTy: ModuleOrNamespaceType) = // Compute the top-rooted module or namespace references let modrefs = moduleTy.ModuleAndNamespaceDefinitions |> List.map mkLocalModuleRef // Compute the top-rooted type definitions @@ -350,7 +350,6 @@ let AddLocalRootModuleOrNamespace tcSink g amap scopem env (moduleTy: ModuleOrNa let env = { env with eNameResEnv = if isNil tcrefs then env.eNameResEnv else AddTyconRefsToNameEnv BulkAdd.No false g amap env.eAccessRights scopem true env.eNameResEnv tcrefs eUngeneralizableItems = addFreeItemOfModuleTy moduleTy env.eUngeneralizableItems } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) env /// Inside "namespace X.Y.Z" there is an implicit open of "X.Y.Z" @@ -4978,7 +4977,7 @@ let rec TcSignatureElementNonMutRec (cenv: cenv) parent typeNames endm (env: TcE CallNameResolutionSink cenv.tcSink (moduleEntity.Range, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) // For 'namespace rec' and 'module rec' we add the thing being defined - let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink g cenv.amap m envNS modTyRoot else envNS + let envNS = if isRec then AddLocalRootModuleOrNamespace g cenv.amap m envNS modTyRoot else envNS let nsInfo = Some (modulNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) let mutRecNSInfo = if isRec then nsInfo else None @@ -4990,7 +4989,7 @@ let rec TcSignatureElementNonMutRec (cenv: cenv) parent typeNames endm (env: TcE if isNil enclosingNamespacePath then envAtEnd else - let env = AddLocalRootModuleOrNamespace cenv.tcSink g cenv.amap m env modTyRoot + let env = AddLocalRootModuleOrNamespace g cenv.amap m env modTyRoot // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment. let env, _openDecls = @@ -5440,7 +5439,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem CallNameResolutionSink cenv.tcSink (moduleEntity.Range, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) // For 'namespace rec' and 'module rec' we add the thing being defined - let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink g cenv.amap m envNS modTyRoot else envNS + let envNS = if isRec then AddLocalRootModuleOrNamespace g cenv.amap m envNS modTyRoot else envNS let nsInfo = Some (modulNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) let mutRecNSInfo = if isRec then nsInfo else None @@ -5453,7 +5452,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem if isNil enclosingNamespacePath then envAtEnd, [] else - let env = AddLocalRootModuleOrNamespace cenv.tcSink g cenv.amap m env modTyRoot + let env = AddLocalRootModuleOrNamespace g cenv.amap m env modTyRoot // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment let env, openDecls = diff --git a/src/Compiler/Checking/CheckDeclarations.fsi b/src/Compiler/Checking/CheckDeclarations.fsi index fb4679f2438..9b06fcc828d 100644 --- a/src/Compiler/Checking/CheckDeclarations.fsi +++ b/src/Compiler/Checking/CheckDeclarations.fsi @@ -13,8 +13,7 @@ open FSharp.Compiler.TcGlobals open FSharp.Compiler.Text open FSharp.Compiler.TypedTree -val AddLocalRootModuleOrNamespace: - TcResultsSink -> TcGlobals -> ImportMap -> range -> TcEnv -> ModuleOrNamespaceType -> TcEnv +val AddLocalRootModuleOrNamespace: TcGlobals -> ImportMap -> range -> TcEnv -> ModuleOrNamespaceType -> TcEnv val CreateInitialTcEnv: TcGlobals * ImportMap * range * assemblyName: string * (CcuThunk * string list * string list) list -> diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 6b7171b5697..3d9884b2cef 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -1198,14 +1198,14 @@ let AddCheckResultsToTcState // Add the implementation as to the implementation env let tcImplEnv = - AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcImplEnv implFileSigType + AddLocalRootModuleOrNamespace tcGlobals amap m tcImplEnv implFileSigType // Add the implementation as to the signature env (unless it had an explicit signature) let tcSigEnv = if hadSig then tcState.tcsTcSigEnv else - AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcState.tcsTcSigEnv implFileSigType + AddLocalRootModuleOrNamespace tcGlobals amap m tcState.tcsTcSigEnv implFileSigType // Open the prefixPath for fsi.exe (tcImplEnv) let tcImplEnv, openDecls = @@ -1563,7 +1563,7 @@ let CheckOneInputWithCallback let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs let tcSigEnv = - AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcState.tcsTcSigEnv sigFileType + AddLocalRootModuleOrNamespace tcGlobals amap m tcState.tcsTcSigEnv sigFileType // Add the signature to the signature env (unless it had an explicit signature) let ccuSigForFile = CombineCcuContentFragments [ sigFileType; tcState.tcsCcuSig ] diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 38c6812728d..c4a924d25d9 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -134,3 +134,67 @@ let f (s: string) = () """ assertHasItemWithNames ["Length"] info + + +[] +let ``Import - Ns 01`` () = + let info = + getCompletionInfo "let _: R " (14, 12) """ +namespace Ns + +type Rec1 = { F: int } + + +namespace Ns + +type Rec2 = { F: int } + +module M = + + type Rec3 = { F: int } + + let _: R = () +""" + assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info + +[] +let ``Import - Ns 02 - Rec`` () = + let info = + getCompletionInfo "let _: R " (14, 12) """ +namespace Ns + +type Rec1 = { F: int } + + +namespace rec Ns + +type Rec2 = { F: int } + +module M = + + type Rec3 = { F: int } + + let _: R = () +""" + assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info + +[] +let ``Import - Ns 03 - Rec`` () = + let info = + getCompletionInfo "let _: R " (14, 12) """ +namespace Ns + +type Rec1 = { F: int } + + +namespace rec Ns + +type Rec2 = { F: int } + +module rec M = + + type Rec3 = { F: int } + + let _: R = () +""" + assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info \ No newline at end of file