dotnet / dotnet/fsharp

Cannot use `base` as identifier in a class, even double-backticked

Open
#16,482 0 comments 2 reactions 0 assignees View on GitHub
Area-Compiler-Checking Bug Impact-Low
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

There seems to be some inconsistency in whether `base` is treated as a keyword or as an identifier.

**Repro steps**

On one hand, this suggests that it is a keyword:

```fsharp
let base = 1
// Error: Unexpected keyword 'base' in binding
```

and indeed, it can be double-backticked:

```fsharp
let ``base`` = 1
// val ``base`` : int = 1
```

However, when in the context of a class that inherits from another class, it behaves more like an identifier: it always refers to the base class, even if backticked:

```fsharp
let ``base`` = 1

type BaseClass() =
member _.BaseMethod() = ()

type SomeClass() =
inherit BaseClass()

member _.Works() = base.BaseMethod() // Calls the base class, as expected

member _.Unexpected() : int = ``base`` // Error: This expression was expected to have type 'int' but here has type 'BaseClass'
```

**Expected behavior**

` ``base`` ` refers to the variable defined above.

**Actual behavior**

` ``base`` ` refers to the base class, just like `base`.

**Known workarounds**

If the identifier ` ``base`` ` is defined in another module that is `open`ed, then it can be referred to using a qualified name. But if it's defined directly in the parent module, then I think the only workaround is to rename it.

**Related information**

F# 8 / .NET SDK 8.0.100.

**Context**

I am running into this issue in the context of Bolero, where ` ``base`` ` is an HTML element. Because of this issue, it cannot be used directly inside a component (ie. a class that inherits from `Bolero.Component`). Instead, you have to use ` Bolero.Html.``base`` `, or define your HTML in a function outside the component and call that function from the component.

Annoyingly, it fails with a very confusing error message, because we're trying to use a `Component` as a CE builder:

```fsharp
open Bolero.Html
open Bolero.Server.Html

type HelloWorldPage() =
inherit Bolero.Component()

override _.Render() =
doctypeHtml {
head {
``base`` { attr.href "/" } // Error: This control construct may only be used if the computation expression builder defines a 'Zero' method
}
body { "Hello, world!" }
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.