Skip to content

Commit 58e596e

Browse files
committed
Implement the method
Replaces `infer`, has the Shapeless semantics. This required moving `DottyPredef` to src-bootstrapped since Scala 2.12 can't express the semantics of `the` in a straightforward way.
1 parent fda1250 commit 58e596e

File tree

10 files changed

+71
-20
lines changed

10 files changed

+71
-20
lines changed

docs/docs/reference/contextual/derivation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ calling the `error` method defined in `scala.compiletime`.
317317
```scala
318318
implied [T] with (elemEq: Eq[T]) for Eq[Tree[T]] {
319319
def eql(x: Tree[T], y: Tree[T]): Boolean = {
320-
val ev = infer[Generic[Tree[T]]]
320+
val ev = the[Generic[Tree[T]]]
321321
val mx = ev.reflect(x)
322322
val my = ev.reflect(y)
323323
mx.ordinal == my.ordinal && {

docs/docs/reference/contextual/inferable-by-name-parameters.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ implied optionCodec[T] given (ev: => Codec[T]) for Codec[Option[T]] {
1919
}
2020
}
2121

22-
val s = infer[Codec[Option[Int]]]
22+
val s = the[Codec[Option[Int]]]
2323

2424
s.write(Some(33))
2525
s.write(None)
@@ -54,7 +54,7 @@ The precise steps for constructing an inferable argument for a by-name parameter
5454
In the example above, the definition of `s` would be expanded as follows.
5555

5656
```scala
57-
val s = infer[Test.Codec[Option[Int]]](
57+
val s = the[Test.Codec[Option[Int]]](
5858
optionCodec[Int](intCodec))
5959
```
6060

docs/docs/reference/contextual/inferable-params.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,16 @@ f("abc") given ctx
8585

8686
## Querying Implied Instances
8787

88-
A method `infer` in `Predef` creates an implied instance of a given type. For example,
88+
A method `the` in `Predef` creates an implied instance of a given type. For example,
8989
the implied instance of `Ord[List[Int]]` is generated by
9090
```scala
91-
infer[Ord[List[Int]]] // reduces to ListOrd given IntOrd
91+
the[Ord[List[Int]]] // reduces to ListOrd given IntOrd
9292
```
93-
The `infer` method is simply defined as the identity function over an inferable parameter.
93+
The `the` method is simply defined as the (non-widening) identity function over an inferable parameter.
9494
```scala
95-
def infer[T] given (x: T) = x
95+
def the[T] given (x: T): x.type = x
9696
```
97-
Functions like `infer` that have only inferable parameters are also called _context queries_.
97+
Functions like `the` that have only inferable parameters are also called _context queries_.
9898

9999
## Syntax
100100

docs/docs/reference/contextual/relationship-implicits.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ Explicit arguments to inferable parameters _must_ be written using `given`,
7575
mirroring the definition syntax. E.g, `max(2, 3) given IntOrd`.
7676
Scala 2 uses normal applications `max(2, 3)(IntOrd)` instead. The Scala 2 syntax has some inherent ambiguities and restrictions which are overcome by the new syntax. For instance, multiple implicit parameter lists are not available in the old syntax, even though they can be simulated using auxiliary objects in the "Aux" pattern.
7777

78-
The `infer` method corresponds to `implicitly` in Scala 2.
78+
The `the` method corresponds to `implicitly` in Scala 2.
79+
It is precisely the same as the `the` method in Shapeless.
80+
The difference between `the` (in both versions) and `implicitly` is
81+
that `the` can return a more precise type than the type that was
82+
asked for.
7983

8084
### Context Bounds
8185

docs/docs/reference/contextual/typeclasses.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ trait Monoid[T] extends SemiGroup[T] {
1717
def unit: T
1818
}
1919
object Monoid {
20-
def apply[T] = infer[Monoid[T]]
20+
def apply[T] = the[Monoid[T]]
2121
}
2222

2323
implied for Monoid[String] {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package dotty
2+
3+
object DottyPredef {
4+
5+
@forceInline final def assert(assertion: => Boolean, message: => Any): Unit = {
6+
if (!assertion)
7+
assertFail(message)
8+
}
9+
10+
@forceInline final def assert(assertion: => Boolean): Unit = {
11+
if (!assertion)
12+
assertFail()
13+
}
14+
15+
def assertFail(): Unit = throw new java.lang.AssertionError("assertion failed")
16+
def assertFail(message: => Any): Unit = throw new java.lang.AssertionError("assertion failed: " + message)
17+
18+
@forceInline final def implicitly[T](implicit ev: T): T = ev
19+
20+
@forceInline def locally[T](body: => T): T = body
21+
22+
/**
23+
* Retrieve the single value of a type with a unique inhabitant.
24+
*
25+
* @example {{{
26+
* object Foo
27+
* val foo = valueOf[Foo.type]
28+
* // foo is Foo.type = Foo
29+
*
30+
* val bar = valueOf[23]
31+
* // bar is 23.type = 23
32+
* }}}
33+
* @group utilities
34+
*/
35+
@forceInline def valueOf[T](implicit vt: ValueOf[T]): T = vt.value
36+
37+
inline def the[T](implicit x: T): x.type = x
38+
}

library/src/dotty/DottyPredef.scala renamed to library/src-non-bootstrapped/dotty/DottyPredef.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import scala.forceInline
44

55
object DottyPredef {
66

7-
87
@forceInline final def assert(assertion: => Boolean, message: => Any): Unit = {
98
if (!assertion)
109
assertFail(message)
@@ -36,6 +35,4 @@ object DottyPredef {
3635
* @group utilities
3736
*/
3837
@forceInline def valueOf[T](implicit vt: ValueOf[T]): T = vt.value
39-
40-
@forceInline def infer[T](implicit x: T) = x
4138
}

tests/pos/reference/instances.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,20 @@ object Instances extends Common {
120120
def f() = {
121121
locally {
122122
implied for Context = this.ctx
123-
println(infer[Context].value)
123+
println(the[Context].value)
124124
}
125125
locally {
126126
lazy val ctx1 = this.ctx
127127
implied for Context = ctx1
128-
println(infer[Context].value)
128+
println(the[Context].value)
129129
}
130130
locally {
131131
implied d[T] for D[T]
132-
println(infer[D[Int]])
132+
println(the[D[Int]])
133133
}
134134
locally {
135135
implied given Context for D[Int]
136-
println(infer[D[Int]])
136+
println(the[D[Int]])
137137
}
138138
}
139139
}
@@ -205,7 +205,7 @@ object AnonymousInstances extends Common {
205205
}
206206

207207
def sum[T: Monoid](xs: List[T]): T =
208-
xs.foldLeft(infer[Monoid[T]].unit)(_.combine(_))
208+
xs.foldLeft(the[Monoid[T]].unit)(_.combine(_))
209209
}
210210

211211
object Implicits extends Common {

tests/pos/the.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object Test {
2+
3+
trait Foo { type T; val x: T }
4+
5+
implied intFoo for Foo {
6+
type T = Int
7+
val x = 3
8+
}
9+
10+
val y: Int = the[Foo].x
11+
12+
}

tests/run/implicit-disambiguation.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ class C extends A {
99
}
1010
object M {
1111
def f given B, C : String = {
12-
implied a for A = infer[B]
13-
infer[A].show
12+
implied a for A = the[B]
13+
the[A].show
1414
}
1515
}
1616
object Test extends App {

0 commit comments

Comments
 (0)