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
2 changes: 1 addition & 1 deletion docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
### 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))
* Tooltip "Full name" now shows demangled companion module names (e.g. `MyType.func` instead of `MyTypeModule.func`). ([Issue #17335](https://github.com/dotnet/fsharp/issues/17335), [PR #19867](https://github.com/dotnet/fsharp/pull/19867))
* Fix internal error (FS0193) when calling an indexed property setter with a named argument that matches an indexer parameter. ([Issue #16034](https://github.com/dotnet/fsharp/issues/16034), [PR #19851](https://github.com/dotnet/fsharp/pull/19851))
* Fix missing FS1182 ("unused binding") warning for unused `let` function bindings inside class types. ([Issue #13849](https://github.com/dotnet/fsharp/issues/13849), [PR #19805](https://github.com/dotnet/fsharp/pull/19805))
* Fix inner mutually-recursive `let rec ... and ...` functions under `--realsig+` not being lifted to top-level static methods (TLR), causing `FSharpFunc` closure allocations and loss of `tail.` opcodes — the large struct-mutual-recursion perf regression reported in [Issue #17607](https://github.com/dotnet/fsharp/issues/17607). ([PR #19882](https://github.com/dotnet/fsharp/pull/19882))
* Fix `TypeLoadException` ("Specialize tried to implicitly override a method with weaker type parameter constraints") and the related CLR crash with constrained inline calls by stripping constraints from closure-class typars in `EraseClosures.convIlxClosureDef`. ([Issue #14492](https://github.com/dotnet/fsharp/issues/14492), [Issue #19075](https://github.com/dotnet/fsharp/issues/19075), [PR #19882](https://github.com/dotnet/fsharp/pull/19882))

* 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
Comment on lines +201 to +202

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test showing whether the second module is analyzed properly and y is reported to the sink?

"""
|> 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