Skip to content

Type If and Match in statement position as Unit #5768

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

Closed
wants to merge 1 commit into from

Conversation

allanrenucci
Copy link
Contributor

This is an alternative fix for #5750

@biboudis
Copy link
Contributor

Is it more performant than the other fix?

@allanrenucci
Copy link
Contributor Author

Is it more performant than the other fix?

I am not sure what you mean by that. But it covers more cases than the previous fix. See the added bytecode tests. As a side effect, it also emits more (legitimate) "A pure expression does nothing in statement position" warnings (see the updated tests)

@allanrenucci
Copy link
Contributor Author

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.

This is fairly conservative as it only typechecks If and Match with Unit as expected type. I tried typing all statements with Unit as expected type but it would insert unit literals after all expressions in statement position and would break in many places.

@odersky
Copy link
Contributor

odersky commented Jan 24, 2019

I think the original fix for #5750 is preferable to this version. It seems unsystematic to single out if and match to be typed with Unit expected type, but not other statements. So this means that (say) a function call f(x) gets Unit as expected type, if it appears in a branch of an if or match, but not if it appears at toplevel.

The other possible design point would be to type all statements with Unit as expected type and to postulate an implicit conversion from T to Unit. It would get rid of a special case in adapt, so it might be interesting to check out.

@odersky
Copy link
Contributor

odersky commented Jan 24, 2019

@allanrenucci If you want to work on the proposed other possible design point, we can leave this open. Otherwise I propose to close.

@odersky odersky assigned allanrenucci and unassigned odersky Jan 24, 2019
@allanrenucci
Copy link
Contributor Author

allanrenucci commented Jan 24, 2019

I think the original fix for #5750 is preferable to this version. It seems unsystematic to single out if and match to be typed with Unit expected type, but not other statements. So this means that (say) a function call f(x) gets Unit as expected type, if it appears in a branch of an if or match, but not if it appears at toplevel.

This is a generalisation of the previous fix. In the previous fix, a function call f(x) gets Unit as expected type if it appears in the then branch of a if with no else part, but nowhere else. It is even less systematic.

The other possible design point would be to type all statements with Unit as expected type and to postulate an implicit conversion from T to Unit. It would get rid of a special case in adapt, so it might be interesting to check out.

I am not sure what you are proposing. What would the implicit conversion synthesise?

@odersky
Copy link
Contributor

odersky commented Jan 31, 2019

I am not sure what you are proposing. What would the implicit conversion synthesise?

Something like:

inline def anyToUnit(x: => Any): Unit = { x; () }

but it could be implemented with compiler magic instead of having this conversion around.

@allanrenucci
Copy link
Contributor Author

The issue with typing all statements with Unit as expected type is that it would insert a large number of unit literal trees. Currently, expressions in statement position are not required to type to Unit. For example:

def foo(): String = ""
def bar: Unit = {
  foo()
  foo()
  foo()
}

After typer, would become:

def foo(): String = ""
def bar = {
  { foo(); () }
  { foo(); () }
  { foo(); () }
}

In that respect, special casing if and match is conservative.

Replacing a special case in adapt with an implicit conversion seems orthogonal.

@odersky
Copy link
Contributor

odersky commented Jan 31, 2019

If the implicit conversion is compiler-magic, we could avoid the creation of Unit trees. Just wrap the statements in a

dropResult(expr)

and eliminate that later in a Miniphase. But it might well be that we are overthinking this. #5750 is fine, and we should stick with it if a general Unit dropping conversion is too complicated. But singling out If and Match for special treatment is worse than either.

@odersky odersky closed this Feb 23, 2019
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