Skip to content

Counterintuitive semicolon-related behavior in last expression of constructor #2844

Closed
@gwillen

Description

@gwillen

Not sure how best to title this. If you end a constructor with a compound expression, thus:

class foo {
    let x:();
    new() {
        self.x = ();
        if (1 == 1) {
            io::println("foo");
        } else {
            io::println("bar");
        }
    }
}

You end up with:


semicolon.rs:5:8: 9:9 error: mismatched types: expected `foo` but found `()` (class foo vs ())
semicolon.rs:5         if (1 == 1) {
semicolon.rs:6             io::println("foo");
semicolon.rs:7         } else {
semicolon.rs:8             io::println("bar");
semicolon.rs:9         }

I guess a constructor is allowed to return either () or the type it's constructing (a fact I did not previously know). It looks like the typechecker, seeing the if-then-else, can only assign it one of those types, and picks 'class foo' rather than '()', when it should pick '()'.

This can be worked around by putting a semicolon after the end of the if.

I'm really not sure if this is a bug or just a weird-but-correct behavior; I don't have a good grasp of the effect of semicolons on expression types yet. But it seems like it can only happen in constructors, with their weird return-type behavior, which makes me lean more towards bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions