Skip to content

Fix #5750: Type then part of If with no else part as Unit #5751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 20, 2019

Conversation

allanrenucci
Copy link
Contributor

No description provided.

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that was quick! Doing it in Typer seems like a good idea.
Before merging, please delete the () and associated comment in https://github.com/dotty-staging/dotty/blob/2ee9994efaf6b3b8b97377002c4a237fe9b5ce00/compiler/src/dotty/tools/dotc/ast/Positioned.scala#L56

@allanrenucci
Copy link
Contributor Author

Actually I am not sure this is the correct fix. Consider:

class Test {
  def foo: String = ""
  def test(cond: Boolean): Int = {
    if (cond) foo else foo
    1
  }
}

This compiles to:

public class Test {
    public String foo() {
        return "";
    }

    public int test(boolean cond) {
        String string = cond ? this.foo() : this.foo();
        return 1;
    }
}

which is not optimal.

I believe the correct fix it to typecheck if in statement position with Unit as expected type

@smarter
Copy link
Member

smarter commented Jan 19, 2019

I believe the correct fix it to typecheck if in statement position with Unit as expected type

Careful though, we don't want val x = if ... else ... and if ... else ... to do different things because a different expected type was used leading to different type inference. So when there's an if/else we should first type it with the usual expected type computed through harmonic, then if it's a statement we can do something special.

@allanrenucci
Copy link
Contributor Author

Careful though, we don't want val x = if ... else ... and if ... else ... to do different things because a different expected type was used leading to different type inference

Why not? This is already the case:

def foo: String = if (...) ... else ... // typed with `String` as expected type
val x = if (...) ... else ... // typed with no expected type

So it seems reasonable to me to implicitly type an if with Unit as expected type when it is in a statement position.

And we already have expressions that are implicitly typed with an expected type when in a certain position:

throw expr // typed as `Throwable`
if (cond) // cond typed as `Boolean`

@smarter
Copy link
Member

smarter commented Jan 19, 2019

hmm, ok, maybe it's not a big deal.

@odersky
Copy link
Contributor

odersky commented Jan 20, 2019

I think we tried checking statements with Unit as expected type at some point, but that got us into weirdness with type inference, so we backed out. So I would not open that can of worms at this point. I think the changes are OK, I just have two proposed simplifications.

@allanrenucci
Copy link
Contributor Author

Comments addressed. Maybe we should keep the issue open since it doesn't solve the problem for if with else branch and matches

@odersky odersky merged commit 2ce89da into scala:master Jan 20, 2019
@allanrenucci allanrenucci deleted the fix-5750 branch January 20, 2019 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants