Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

SIP-23 #86

Merged
merged 17 commits into from
Nov 15, 2014
Merged

SIP-23 #86

merged 17 commits into from
Nov 15, 2014

Conversation

folone
Copy link

@folone folone commented Nov 14, 2014

I'll just open this PR with @adriaanm's work on SIP-23 here to spawn some conversations. This implementation seems to solve all the issues I've been seeing in #45.

adriaanm and others added 17 commits November 14, 2014 13:12
This requires -Xexperimental in 2.11.x.

Update spec.

TODO:
 - test!
 - include SIP as spec addendum
 - don't predicate on -Xexperimental -- introduce -Xsip:23?

Notes:
 - `()` is not a literal, neither are `Symbol`s
`LiteralType` is a `SingleType` with a literal for its path.
With an example: `1` is to `p.type`, as `1` is to `p`.

`lit` is the most precise type for an expression known to evaluate to `lit`.
Note that we cannot constant fold the expression to `lit`, since it may have a side effect.

`ConstantType(c)` is the type of an expression that can be constant folded to `c`.

When an expressions should not be constant folded, the corresponding `LiteralType`
is created: `ConstantType(c).deconst == LiteralType(c)`
(this is where all `LiteralType`s originate, except for unpickling).

`typedLiteral` always infers a `ConstantType`, which is subsequently
`deconst`ed or `widen`ed where necessary (see `widenIfNecessary`).
In short, only `final val`s may have `ConstantType`s, and
`widen`ing is required to ensure that a path is stable and accessible (roughly speaking).

When checking subtyping, this invariant is useful: `LiteralType(c).widen == c.tpe`.

TODO:
  - test! (subtyping, type inference, type tests, patmat, dependent method types)
  - fully predicate implementation on -Xsip:23
  - is it safe to reduce LITERAL in pickler?
test case:

```
val y: 5 = 5
def g(x: Int) = x match {
  case _: y.type => 0
}
```
Before:

	sandbox/test.scala:2: error: type mismatch;
	 found   : Array[1]
	 required: Array[Int]
TODO: deriving this from type param bounds is not the best way,
should consider all constraints that we encounter

scala> def stable[T <: 1](x: T): T = x
stable: [T <: 1](x: T)T

scala> stable(1)
res0: 1 = 1

scala> stable(2)
<console>:9: error: inferred type arguments [2] do not conform to method stable's type parameter bounds [T <: 1]
              stable(2)
              ^
<console>:9: error: type mismatch;
 found   : Int(2)
 required: T
              stable(2)
                     ^

scala> def stable[T <: Singleton](x: T): T = x
stable: [T <: Singleton](x: T)T

scala> val x: Int = 2
x: Int = 2

scala> val y: x.type = x
y: x.type = 2

scala> stable(y)
res3: x.type = 2
this bootstraps
propensive pushed a commit that referenced this pull request Nov 15, 2014
@propensive propensive merged commit 52e949e into typelevel:2.11.x Nov 15, 2014
@folone
Copy link
Author

folone commented Nov 15, 2014

@propensive That thing had test failures! Sorry for not telling you before, I'll come up with a PR that fixes them soon :)

@propensive
Copy link

Aargh. Whoops! I was blinded by my own trigger-happy excitement!

On 15 November 2014 01:27, George Leontiev [email protected] wrote:

@propensive https://github.com/propensive That thing had test failures!
Sorry for not telling you before, I'll come up with a PR that fixes them
soon :)


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

Jon Pretty | @propensive

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants