Skip to content

The union type of any pair of singleton types is equivalent to their supertype #829

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
propensive opened this issue Oct 18, 2015 · 7 comments
Assignees

Comments

@propensive
Copy link
Contributor

There are a couple of ways of demonstrating this. The following does not produce a type error when it should:

def foo: 1 | 2 = 1
def bar: 3 | 4 = foo

whereas this does (correctly):

def foo: 1 | 2 = 1
def bar: 1 = foo

Intersection types do, however, appear to work correctly. This produces the expected type error:

trait X {
  def foo: 1 & 2
  def bar: 2 & 3 = foo
}
@propensive propensive changed the title Union types of any pair of singleton types are equivalent to their supertype The union type of any pair of singleton types is equivalent to their supertype Oct 18, 2015
@smarter smarter self-assigned this Oct 21, 2015
smarter added a commit to smarter/dotty that referenced this issue Oct 22, 2015
…code

There are two cases where we should not widen singletons in unions:
- When we explicitly write the type, like `val x: 1 | 2`
- When pattern matching binds an alternative, like `case x @ (1 | 2) =>`

Fixes scala#829
smarter added a commit to smarter/dotty that referenced this issue Oct 22, 2015
…code

Note that we do not keep singletons in pattern alternatives like `case x
@ (1 | 2)` because if there are many alternatives like
`JavaScanner#fetchToken`, we end up with deep subtyping checks.

Fixes scala#829
smarter added a commit to smarter/dotty that referenced this issue Oct 22, 2015
…code

Note that we do not keep singletons in pattern alternatives like
`case x @ (1 | 2)` because if there are many alternatives like in
`JavaScanner#fetchToken`, we end up with deep subtyping checks.

Fixes scala#829
@propensive
Copy link
Contributor Author

Another useful test is to check whether this compiles:

implicitly[1 & (2 | 3) =:= (1 & 2) | (1 & 3)]

@smarter
Copy link
Member

smarter commented Oct 22, 2015

It does with #844 if you add a few parentheses to avoid precedence issues:

object Test {
  implicitly[(1 & (2 | 3)) =:= ((1 & 2) | (1 & 3))]
}

@propensive
Copy link
Contributor Author

Great!

Do you have any thoughts on the precedence rules for type operators, in light of | and & becoming more widely used at the type-level, @odersky?

@smarter
Copy link
Member

smarter commented Oct 22, 2015

Yes, it's especially confusing for pattern matching:

x match {
  case x: 1 | 2 => // means case (x: 1) | 2, but is likely to be interpreted as case x: (1 | 2)
  case x @ 1 | 2 => // means case (x @ 1) | 2, but is likely to be interpreted as case x @ (1 | 2)
}

@odersky
Copy link
Contributor

odersky commented Oct 22, 2015

The idea to take precedence from Java is still valid I think. Tweaking here
else risks becoming bikeshedding.

  • Martin

On Thu, Oct 22, 2015 at 9:45 PM, Guillaume Martres <notifications@github.com

wrote:

Yes, it's especially confusing for pattern matching:

x match {
case x: 1 | 2 => // means case (x: 1) | 2, but is likely to be interpreted as case x: (1 | 2)
case x @ 1 | 2 => // means case (x @ 1) | 2, but is likely to be interpreted as case x @ (1 | 2)
}


Reply to this email directly or view it on GitHub
#829 (comment).

Martin Odersky
EPFL

@smarter
Copy link
Member

smarter commented Oct 22, 2015

Fair enough, but note that this means that porting uses of intersection types from scalac to dotty is not trivial because with and & do not have the same precedence:

trait A
trait B
object Test {
  (new A with B) match { case x: A with B => x } // OK
  (new A with B) match { case x: A & B => x } // error
  (new A with B) match { case x: (A & B) => x } // OK
}
`

@odersky
Copy link
Contributor

odersky commented Oct 2, 2016

Superseded by #1551

@odersky odersky closed this as completed Oct 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants