Skip to content

Explicit constructor inheriting a class with a primary constructor drops the base #5227

Open

Description

@MangelMaxime

A class written with val fields and an explicit new that inherits from a class with a primary constructor compiles to a class that does not extend the base. The base constructor is called but its result is thrown away, so inherited members read undefined and type tests against the base fail.

type Point(x: int) =
    member _.X = x

type Labelled =
    inherit Point
    val Label: string
    new (x: int, label: string) = { inherit Point(x); Label = label }

let p = Labelled(3, "origin")
printfn "X: %A, Label: %A, isPoint: %b" p.X p.Label (box p :? Point)

.NET prints X: 3, Label: "origin", isPoint: true. Fable JS prints X: 0, Label: "origin", isPoint: false. Python behaves the same way.

Generated JS:

export class Labelled {
    constructor(Label) {
        this.Label = Label;
    }
}
export function Labelled_$ctor_Z176EF219(x, label) {
    Point_$ctor_Z524259A4(x);
    return new Labelled(label);
}

This is the case #5226 left out. That PR fixed #2425 for the situation where every class in the chain uses val fields: the generated constructor of the derived class takes the inherited fields and the explicit constructor copies them from an instance built by the base's own constructor function. That does not work here because Point's JS constructor takes its constructor arguments, not its fields, so there is nothing to copy from. The fix probably has to pass the inherit Point(x) arguments straight through to super(...), which also means a val class two levels below a primary-constructor class cannot be supported that way and should get a compile error rather than silent wrong output.

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

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions