Skip to content

bare fn types in record unification produces unexpected errors #1451

Closed
@nikomatsakis

Description

@nikomatsakis

In the following source:

type T = { mutable f: fn@() };
type S = { f: fn@() };

fn fooS(t: S) {
}

fn fooT(t: T) {
}

fn bar() {
}

fn main() {
    let x: fn@() = bar;
    fooS({f: x});
    fooS({f: bar});

    let x: fn@() = bar;
    fooT({mutable f: x});
    fooT({mutable f: bar});
}

the last call to fooT() results in an error:

/Users/nmatsakis/tmp/foo.rs:20:9: 20:25 error: mismatched types: expected `T` but found `{f: mutable fn()}` (types differ)
/Users/nmatsakis/tmp/foo.rs:20     fooT({mutable f: bar});

I believe this is because the field f is immutable and hence unified as invariant. This is kind of surprising to the user, though. The "right" fix is probably a bit involved though. If we were to get rid of bare function types, we'd be able to handle this, but it requires an improvement to the type checker (bounded type variables, since you don't know the type to assign to the bare function till later).

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-type-systemArea: Type system

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions