Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Report `FS0037 Duplicate definition of type or module` at type-check time when two sibling modules in a `module rec` / `namespace rec` group share a name, instead of letting the duplicate slip through to IL emit where it surfaced as the cryptic `FS2014: duplicate entry . in type index table`. ([Issue #6694](https://github.com/dotnet/fsharp/issues/6694), [PR #19913](https://github.com/dotnet/fsharp/pull/19913))
* Suppress hover/symbol resolution for wildcard `_` patterns inside `member _.…` bodies that incorrectly showed `val _: T` tooltip. ([PR #19760](https://github.com/dotnet/fsharp/pull/19760))
* Deduplicate format specifier locations in computation expressions so editor tooling no longer reports duplicate entries for the same `%` specifier. ([Issue #16419](https://github.com/dotnet/fsharp/issues/16419), [PR #19791](https://github.com/dotnet/fsharp/pull/19791))
* Reject non-function bindings for single-case and partial active pattern names with FS1209, matching the existing multi-case behavior. ([PR #19763](https://github.com/dotnet/fsharp/pull/19763))
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4095,6 +4095,11 @@ module EstablishTypeDefinitionCores =
let envTmp, withEnvs =
(envInitial, withEntities) ||> MutRecShapes.computeEnvs
(fun envAbove (MutRecDefnsPhase2DataForModule (moduleTyAcc, moduleEntity)) ->
// In recursive scopes all siblings build their entities in Phase1A against the same
// envInitial, so duplicate sibling-module names are not yet visible there. Detect
// them here at the publish point, where envAbove's accumulator already contains
// any earlier-published siblings. See https://github.com/dotnet/fsharp/issues/6694.
CheckForDuplicateModule envAbove moduleEntity.DemangledModuleOrNamespaceName moduleEntity.Range
PublishModuleDefn cenv envAbove moduleEntity
MakeInnerEnvWithAcc true envAbove moduleEntity.Id moduleTyAcc moduleEntity.ModuleOrNamespaceType.ModuleOrNamespaceKind)
(fun envAbove _ -> envAbove)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,100 @@ AutoOpen>] L1 = do ()
|> shouldFail
|> withDiagnostics [
Error 10, Line 3, Col 1, Line 3, Col 9, "Unexpected start of structured construct in attribute list"
]
]

[<Fact>]
let ``Recursive module with duplicate sibling modules emits FS0037`` () =
FSharp """
module rec A

module Foobar = let x = 1
module Foobar = let y = 2
"""
|> typecheck
|> shouldFail
|> withErrorCode 37
|> withDiagnosticMessageMatches "Foobar"
|> ignore

[<Fact>]
let ``Recursive namespace with duplicate sibling modules emits FS0037`` () =
FSharp """
namespace rec N

module Foobar = let x = 1
module Foobar = let y = 2
"""
|> typecheck
|> shouldFail
|> withErrorCode 37
|> withDiagnosticMessageMatches "Foobar"
|> ignore

[<Fact>]
let ``Recursive module nested cousins with same name compile`` () =
FSharp """
module rec Outer

module A =
module Inner = let x = 1

module B =
module Inner = let y = 2
"""
|> typecheck
|> shouldSucceed

[<Fact>]
let ``Recursive module nested siblings with duplicate name emit FS0037`` () =
FSharp """
module rec Outer

module Inner =
module Dup = let x = 1
module Dup = let y = 2
"""
|> typecheck
|> shouldFail
|> withErrorCode 37
|> withDiagnosticMessageMatches "Dup"
|> ignore

[<Fact>]
let ``Non-recursive module with duplicate sibling modules still emits FS0037`` () =
FSharp """
module A

module Foobar = let x = 1
module Foobar = let y = 2
"""
|> typecheck
|> shouldFail
|> withErrorCode 37
|> withDiagnosticMessageMatches "Foobar"
|> ignore

[<Fact>]
let ``Single file with two namespace fragments and different modules compiles`` () =
FSharp """
namespace N

module M = let x = 1

namespace N

module M2 = let y = 2
"""
|> typecheck
|> shouldSucceed

[<Fact>]
let ``Recursive module siblings differing only in case compile`` () =
FSharp """
module rec A

module Foobar = let x = 1
module FooBar = let y = 2
"""
|> typecheck
|> shouldSucceed
Loading