Skip to content

Compiler allows what looks like a module nested inside of a type, but isn't #10066

@brianrourkeboll

Description

@brianrourkeboll

When defining a type using light syntax (it doesn't matter what kind of type: class, interface, union, record), it is possible to define what appears to be a nested module (at the same indentation level as the rest of the contents of the type), but what actually results in a module defined in the same scope as the type.

https://sharplab.io/#v2:DYLgZgzgPgLgngBwKYAICSAxAhgY1QXgFgAoFMlLAIwhgCdcYUMUQUBLAO0YFoA+driXIoAtgHsAJgFdgqALIoipYeVmMwKABQBKRVu0kS8ZCgDC+xUPIikIyklooA+gDpmOvQGYrZcdNkocgBMlsoqKGooGh74+obExqgAqqHCUCgAgj4o6QBC2X4y8p6p4RFI6haxOvGJKABKpWQA3pksAowAvgWSRYEALE0qkdG61QbEQA===

type IFace =
    abstract F : int -> int
    module M =
        let f () = ()

type C () =
    member _.F () = 3
    module M2 =
        let f () = ()

type U =
    | A
    | B
    module M3 =
        let f () = ()

type R =
    { A : int }
    module M4 =
        let f () = ()

// Etc.
// All modules M, M2, M3, M4 are in scope here.

Using verbose syntax disallows this, as expected.

https://sharplab.io/#v2:DYLgZgzgPgLgngBwKYAICSAxAhgY1QXgFgAoFMlASwDsYkAnMXJE81lLAIwhjtxhQwoQlGigC0APhEwWbMgFsA9gBMArsFQBZFPhQB6PQIDKABhMBGE8ICqVJAA9kOWspQBrJHADuiuq4DkSmoa/iIo8Mgoykhg1BQwFIpUAHQoAKKOSM5IAUhUyqG+KIowABb04YoeKbJyrBr8YCgAFACUOihNbbUoecpAA

type IFace =
    interface
        abstract F : int -> int
        module M = // FS0010: Unexpected keyword 'module' in type definition. Expected 'end' or other token.
            let f () = f ()
    end

// Etc.

Expected behavior

A module nested inside of a type shouldn't compile, or some kind of indentation warning should be given.

Actual behavior

The module is compiled in the same scope as the type.

Known workarounds

Don't confusingly misindent your module definition.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

New

Relationships

None yet

Development

No branches or pull requests

Issue actions