Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
brianrourkeboll opened this issue Sep 3, 2020 · 5 comments
Assignees
Labels
Area-Diagnostics mistakes and possible improvements to diagnostics Feature Request
Milestone

Comments

@brianrourkeboll
Copy link
Contributor

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.

@cartermp
Copy link
Contributor

cartermp commented Sep 4, 2020

For this I think it would make sense to emit a warning. I suppose this is considered by design but it's reasonable to warn since the code is kind of wonky.

@auduchinok
Copy link
Member

auduchinok commented Sep 4, 2020

@cartermp @dsyme Would you accept a language suggestion producing errors for these cases? I think making the light syntax work properly (or just in more predictable ways) in more cases is really important.

@dsyme
Copy link
Contributor

dsyme commented Sep 4, 2020

@cartermp @dsyme Would you accept a language suggestion producing errors for these cases? I think making the light syntax work properly (or just in more expected ways) in more cases is really important.

Definitely would accept a PR that produces a warning for this case

@cartermp
Copy link
Contributor

cartermp commented Sep 4, 2020

Yes, and in the case of an error, a language suggestion would be appropriate.

@auduchinok
Copy link
Member

I'd be happy to know if there's any chance for such a suggestion to be approved before filing one. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Diagnostics mistakes and possible improvements to diagnostics Feature Request
Projects
Status: New
Development

No branches or pull requests

5 participants