fable-compiler / Fable

F# to JavaScript, TypeScript, Python, Rust and Dart Compiler
http://fable.io/
MIT License
2.93k stars 301 forks source link

private value referenced from inline causes import error #3866

Open joprice opened 4 months ago

joprice commented 4 months ago

Description

When an inline value references a private value, the generated inlined code attempts to import the private value, which is not exported, causing an import error.

Repro code

Reproducing requires multiple files, so I made a reproduction repository:

https://github.com/joprice/fable-repro/blob/2283eb46351bef3cc39ac02e9c5c4c303c7b6a8b/Client.fs#L10

An overview of the problem:

In one file:

module Client

let private x = 1
let inline y () = x

In another file:

Client.y()

This will generate an error like

import { x } from "./Client.fs.js";
         ^
SyntaxError: The requested module './Client.fs.js' does not provide an export named 'x'

Expected and actual results

Compilation should fail if an inline value references a private value, if the private value is not itself inline, instead of generating invalid code.

For comparison, fsc returns the following error in this case:

The value 'direct' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible

Related information

joprice commented 3 months ago

I just hit this when referencing a private string defined at the top-level of a module. In that case, adding [<Literal>] gets it to inline while still being private.