Skip to content

GraphBasedChecking can break compilation when having unused open #16225

Closed

Description

@BoundedChenn31

Not sure if it's a real problem though.

Repro steps
Project file:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <OtherFlags>$(OtherFlags) --test:GraphBasedChecking</OtherFlags>
    </PropertyGroup>

    <ItemGroup>
        <Compile Include="File1.fs" />
        <Compile Include="File2.fs" />
        <Compile Include="Program.fs"/>
    </ItemGroup>

</Project>

File1:

namespace My.Great.Namespace

File2:

namespace My.Great.Namespace

open My.Great.Namespace

type Foo = class end

Program:

printfn "Hello"

Compilation fails with error
1>File2.fs(3,6): Error FS0039 : The namespace or module 'My' is not defined.

But with commented out <OtherFlags> line compilation is successful.
NamespaceIsNotDefRepro.zip

Activity

  1. added this to the Backlog milestone on Nov 3, 2023
  2. vzarytovskii commented on Nov 3, 2023

    @vzarytovskii
    Member
  3. vzarytovskii commented on Nov 3, 2023

    @vzarytovskii
    Member

    @BoundedChenn31 saw your message in the chat, thanks for the minimal repro

  4. nojaf commented on Nov 3, 2023

    @nojaf
    Contributor

    Problematic in what SDK? Reproduceable on main?

  5. safesparrow commented on Nov 3, 2023

    @safesparrow
    Contributor

    I reproduced it now on 8.0.100-rc.2. Note that namespace names must match (as showcased in the example code).

  6. safesparrow commented on Nov 3, 2023

    @safesparrow
    Contributor

    The problem, as expected, is lack of a dependency from B.fs to A.fs.

    This fails:
    1.

    // A.fs
    namespace A
    
    // B.fs
    namespace A
    open A
    type Foo = class end
    

    Graph:

    flowchart RL
        0["obj\Debug\net7.0\.NETCoreApp,Version=v7.0.AssemblyAttributes.fs"]
        1["obj\Debug\net7.0\fmodule.AssemblyInfo.fs"]
        2["A.fs"]
        3["B.fs"]
    
    Loading

    Trie:

    classDiagram
    
    class root
    
    root <|-- ns_Microsoft
    class ns_Microsoft {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    ns_Microsoft <|-- ns_BuildSettings
    class ns_BuildSettings {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    root <|-- ns_FSharp
    class ns_FSharp {
    
        fmodule.AssemblyInfo.fs(1)
    }
    
    root <|-- ns_A
    class ns_A {
        B.fs[3]
    
        A.fs(2)
    }
    
    Loading

    These succeed:
    2.

    // A.fs
    namespace A
    
    // B.fs
    namespace A
    open A
    module X = ()
    

    Graph:

    flowchart RL
        0["obj\Debug\net7.0\.NETCoreApp,Version=v7.0.AssemblyAttributes.fs"]
        1["obj\Debug\net7.0\fmodule.AssemblyInfo.fs"]
        2["A.fs"]
        3["B.fs"]
        3 --> 2
    
    Loading

    Trie:

    classDiagram
    
    class root
    
    root <|-- ns_Microsoft
    class ns_Microsoft {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    ns_Microsoft <|-- ns_BuildSettings
    class ns_BuildSettings {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    root <|-- ns_FSharp
    class ns_FSharp {
    
        fmodule.AssemblyInfo.fs(1)
    }
    
    root <|-- ns_A
    class ns_A {
    
        A.fs(2)
        B.fs(3)
    }
    
    ns_A <|-- mod_X
    class mod_X {
        B.fs[3]
    }
    
    Loading
    // A.fs
    namespace A
    
    // B.fs
    namespace B
    open A
    type Foo = class end
    

    Graph:

    flowchart RL
        0["obj\Debug\net7.0\.NETCoreApp,Version=v7.0.AssemblyAttributes.fs"]
        1["obj\Debug\net7.0\fmodule.AssemblyInfo.fs"]
        2["A.fs"]
        3["B.fs"]
        3 --> 2
    
    Loading

    Trie:

    classDiagram
    
    class root
    
    root <|-- ns_Microsoft
    class ns_Microsoft {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    ns_Microsoft <|-- ns_BuildSettings
    class ns_BuildSettings {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    root <|-- ns_FSharp
    class ns_FSharp {
    
        fmodule.AssemblyInfo.fs(1)
    }
    
    root <|-- ns_A
    class ns_A {
    
        A.fs(2)
    }
    
    root <|-- ns_B
    class ns_B {
        B.fs[3]
    
    }
    
    Loading
  7. safesparrow commented on Nov 3, 2023

    @safesparrow
    Contributor

    @nojaf this is reproducible on latest main.

  8. safesparrow commented on Nov 3, 2023

    @safesparrow
    Contributor

    Separately, we should consider either escaping the contents of Mermaid graphs, or at least replacing \ with / to avoid \n being presented as a newline:
    This mermaid .md file:

    flowchart RL
        0["obj\Debug\net7.0\.NETCoreApp,Version=v7.0.AssemblyAttributes.fs"]
        1["obj\Debug\net7.0\fmodule.AssemblyInfo.fs"]
        2["A.fs"]
        3["B.fs"]
    

    yields the below node:
    image

  9. nojaf commented on Nov 4, 2023

    @nojaf
    Contributor

    I can reproduce this with RC2 but not with my local compiler.
    @safesparrow could you try:

    • git clean -xdf (of fsharp repo)
    • dotnet build src/fsc/fscProject/fsc.fsproj /p:BUILDING_USING_DOTNET=true
    • <DotnetFscCompilerPath>C:\YourProjectFolder\fsharp\artifacts\bin\fsc\Debug\net8.0\fsc.dll</DotnetFscCompilerPath>
  10. safesparrow commented on Nov 4, 2023

    @safesparrow
    Contributor

    @nojaf You're right, my test setup was wrong (I haven't used the compiler from source in a while).

    Looks like this is already fixed on main as you said.

    Code:

    // A.fs
    namespace A
    
    // B.fs
    namespace A
    open A
    type Foo = class end
    

    Graph:

    flowchart RL
        0["obj\Debug\net7.0\.NETCoreApp,Version=v7.0.AssemblyAttributes.fs"]
        1["obj\Debug\net7.0\fmodule.AssemblyInfo.fs"]
        2["A.fs"]
        3["B.fs"]
        3 --> 2
    
    Loading

    Trie:

     classDiagram
    
    class root
    
    root <|-- ns_Microsoft
    class ns_Microsoft {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    ns_Microsoft <|-- ns_BuildSettings
    class ns_BuildSettings {
    
        .NETCoreApp,Version=v7.0.AssemblyAttributes.fs(0)
    }
    
    root <|-- ns_FSharp
    class ns_FSharp {
    
        fmodule.AssemblyInfo.fs(1)
    }
    
    root <|-- ns_A
    class ns_A {
    
        A.fs(2)
    }
    
    Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions