Skip to content

Commit ff4c2e0

Browse files
committed
Go back to given ... as for instances
1 parent dd6b326 commit ff4c2e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+191
-173
lines changed

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ object StdNames {
412412
val array_length : N = "array_length"
413413
val array_update : N = "array_update"
414414
val arraycopy: N = "arraycopy"
415+
val as: N = "as"
415416
val asTerm: N = "asTerm"
416417
val asModule: N = "asModule"
417418
val asMethod: N = "asMethod"

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@ object Parsers {
344344
offset
345345
}
346346

347+
def accept(name: Name): Int = {
348+
val offset = in.offset
349+
if !isIdent(name) then
350+
syntaxErrorOrIncomplete(em"`$name` expected")
351+
if isIdent(name) then
352+
in.nextToken()
353+
offset
354+
}
355+
347356
def reportMissing(expected: Token): Unit =
348357
syntaxError(ExpectedTokenButFound(expected, in.token))
349358

@@ -932,7 +941,7 @@ object Parsers {
932941
if lookahead.token == COLON then
933942
lookahead.nextToken()
934943
!lookahead.isAfterLineEnd
935-
else lookahead.token == SUBTYPE
944+
else lookahead.token == SUBTYPE || lookahead.isIdent(nme.as)
936945

937946
def followingIsExtension() =
938947
val lookahead = in.LookaheadScanner()
@@ -3404,9 +3413,9 @@ object Parsers {
34043413
syntaxError(i"extension clause can only define methods", stat.span)
34053414
}
34063415

3407-
/** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
3408-
* | [GivenSig ‘:’] ConstrApps [TemplateBody]
3409-
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
3416+
/** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
3417+
* | [GivenSig] ConstrApps [TemplateBody]
3418+
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} ‘as’
34103419
* ExtParamClause ::= [DefTypeParamClause] DefParamClause
34113420
* ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
34123421
*/
@@ -3433,7 +3442,7 @@ object Parsers {
34333442
templ.body.foreach(checkExtensionMethod(tparams, _))
34343443
ModuleDef(name, templ)
34353444
else
3436-
val hasLabel = !name.isEmpty && in.token == COLON
3445+
val hasLabel = !name.isEmpty && in.token == COLON || in.isIdent(nme.as)
34373446
if hasLabel then in.nextToken()
34383447
val tparams = typeParamClauseOpt(ParamOwner.Def)
34393448
val paramsStart = in.offset
@@ -3446,17 +3455,21 @@ object Parsers {
34463455
if !vparam.mods.is(Given) then syntaxError(em"$what must be `given`", vparam.span)))
34473456
checkAllGivens(vparamss, "parameter of given instance")
34483457
val parents =
3449-
if hasLabel then
3450-
constrApps(commaOK = true, templateCanFollow = true)
3451-
else if in.token == SUBTYPE then
3458+
if in.token == SUBTYPE && !hasLabel then
34523459
if !mods.is(Inline) then
34533460
syntaxError("`<:` is only allowed for given with `inline` modifier")
34543461
in.nextToken()
34553462
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
34563463
else
3457-
if !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3458-
accept(COLON)
3459-
constrApps(commaOK = true, templateCanFollow = true)
3464+
if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3465+
if in.token == COLON then in.nextToken()
3466+
else accept(nme.as)
3467+
if in.token == USCORE then
3468+
in.nextToken()
3469+
accept(SUBTYPE)
3470+
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
3471+
else
3472+
constrApps(commaOK = true, templateCanFollow = true)
34603473

34613474
if in.token == EQUALS && parents.length == 1 && parents.head.isType then
34623475
in.nextToken()

docs/blog/_posts/2019-11-04-20th-dotty-milestone-release.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,15 @@ It is now possible to specialize `inline given`s with the help of `<:` as follow
9696
trait A
9797
class B extends A
9898

99-
inline given tc <: A = B()
99+
inline given wb as _ <: A = B()
100100

101101
val x: B = summon[A]
102102
```
103-
104-
This change brings `given`s even with the ordinary `inline def`s.
103+
In this example, the inline given `wb` will return a result of a subtype of the declared upper bound `A` as determined by `B`. In our terminology, `wb` is a whitebox macro. Contrast with the following definition of a blackbox given macro `bb`:
104+
```
105+
inline given bb as A = B()
106+
```
107+
Here, the type of `bb` will always be `A`, no matter what `B` returns.
105108

106109
## Normal parameters can follow `given` parameters
107110
Previously normal parameters after `given` parameter was disallowed mainly because they looked awkward with the old syntax. With the syntax being improved, this restriction is now lifted and you can write, e.g., the following program:

docs/docs/internals/syntax.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,9 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses
384384
ConstrMods ::= {Annotation} [AccessModifier]
385385
ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor
386386
EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template)
387-
GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
388-
| [GivenSig ‘:’] ConstrApps [TemplateBody]
389-
GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
387+
GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
388+
| [GivenSig] ConstrApps [TemplateBody]
389+
GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} ‘as’
390390
ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods
391391
ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
392392
ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’

docs/docs/reference/contextual/implicit-function-types.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ with implicit function types as parameters to avoid the plumbing boilerplate
8383
that would otherwise be necessary.
8484
```scala
8585
def table(init: (given Table) => Unit) = {
86-
given t: Table
86+
given t as Table
8787
init
8888
t
8989
}
9090

9191
def row(init: (given Row) => Unit)(given t: Table) = {
92-
given r: Row
92+
given r as Row
9393
init
9494
t.add(r)
9595
}

docs/docs/reference/contextual/import-delegate.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A special form of import wildcard selector is used to import given instances. Ex
77
```scala
88
object A {
99
class TC
10-
given tc: TC
10+
given tc as TC
1111
def f(given TC) = ???
1212
}
1313
object B {
@@ -50,8 +50,8 @@ Importing all given instances of a parameterized type is expressed by wildcard a
5050
For instance, assuming the object
5151
```scala
5252
object Instances {
53-
given intOrd: Ordering[Int]
54-
given [T: Ordering] listOrd: Ordering[List[T]]
53+
given intOrd as Ordering[Int]
54+
given [T as Ordering] listOrd as Ordering[List[T]]
5555
given ec: ExecutionContext = ...
5656
given im: Monoid[Int]
5757
}

library/src/scala/IArray.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object opaques
88
opaque type IArray[+T] = Array[_ <: T]
99

1010
/** Defines extension methods for immutable arrays */
11-
given arrayOps: Object with
11+
given arrayOps: Object {
1212

1313
/** The selection operation on an immutable array.
1414
*
@@ -255,6 +255,7 @@ object opaques
255255
* If one of the two collections is longer than the other, its remaining elements are ignored. */
256256
def [T, U: ClassTag](arr: IArray[T]) zip(that: IArray[U]): IArray[(T, U)] =
257257
genericArrayOps(arr).zip(that).asInstanceOf[IArray[(T, U)]]
258+
}
258259
end opaques
259260

260261
type IArray[+T] = opaques.IArray[T]

tests/neg-custom-args/fatal-warnings/i7821.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ object XObject {
33

44
def anX: X = 5
55

6-
given ops: Object {
6+
given ops as Object {
77
def (x: X) + (y: X): X = x + y
88
}
99
}
@@ -13,7 +13,7 @@ object MyXObject {
1313

1414
def anX: MyX = XObject.anX
1515

16-
given ops: Object {
16+
given ops as Object {
1717
def (x: MyX) + (y: MyX): MyX = x + y // error: warring: Infinite recursive call
1818
}
1919
}

tests/neg/exports.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
type PrinterType
66
def print(bits: BitMap): Unit = ???
77
def status: List[String] = ???
8-
given bitmap : BitMap
8+
given bitmap as BitMap
99
}
1010

1111
class Scanner {

tests/neg/i5978.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ opaque type Position[Buffer] = Int
55
trait TokenParser[Token, R]
66

77
object TextParser {
8-
given TP : TokenParser[Char, Position[CharSequence]] {}
8+
given TP as TokenParser[Char, Position[CharSequence]] {}
99

1010
given FromCharToken(given T: TokenParser[Char, Position[CharSequence]])
1111
: Conversion[Char, Position[CharSequence]] = ???
@@ -22,7 +22,7 @@ object Testcase {
2222
val co_x : Position[CharSequence] = 'x' // error
2323

2424
{
25-
given XXX : Conversion[Char, Position[CharSequence]] = co_i
25+
given XXX as Conversion[Char, Position[CharSequence]] = co_i
2626
val co_y : Position[CharSequence] = 'x'
2727
}
2828
}

tests/neg/i7248.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
object Test extends App {
2-
given f[H](given h: H): H = h
2+
given f[H](given h: H) as H = h
33
summon[Int] // error
44
}

tests/neg/i7249.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ trait F[H, T]
44

55

66
object Test extends App {
7-
given f[H, T](given h: H, t: T): F[H, T] = ???
7+
given f[H, T](given h: H, t: T) as F[H, T] = ???
88
summon[F[Int, Unit]] // error
99
}

tests/neg/i7919.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import scala.quoted._
33
object Test {
44
def staged[T](given qctx: QuoteContext) = {
55
import qctx.tasty.{_, given}
6-
given typeT: quoted.Type[T] // error
6+
given typeT as quoted.Type[T] // error
77
val tTypeTree = typeT.unseal
88
val tt = typeOf[T]
99
'{ "in staged" }

tests/neg/implicit-params.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ object Test {
1111

1212
def h(x: Int) given () = x // error: missing return type
1313

14-
given C : C(11)
15-
given D : D(11)
14+
given C as C(11)
15+
given D as D(11)
1616

1717
f(1)
1818
f(1)(given C)

tests/neg/implied-for.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ class B extends T
33
class C extends T
44

55
object A {
6-
given b : B
7-
given c : C
6+
given b as B
7+
given c as C
88
}
99

1010
object Test extends App {

tests/neg/import-implied.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class TC
22
object A {
3-
given tc : TC
3+
given tc as TC
44
def foo(given TC) = ()
55
}
66
object B {

tests/neg/machine-state-encoding-with-implicit-match.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ final class Off extends State
88
@implicitNotFound("State must be Off")
99
class IsOff[S <: State]
1010
object IsOff {
11-
given isOff : IsOff[Off] = new IsOff[Off]
11+
given isOff as IsOff[Off] = new IsOff[Off]
1212
}
1313

1414
@implicitNotFound("State must be On")
1515
class IsOn[S <: State]
1616
object IsOn {
17-
given isOn : IsOn[On] = new IsOn[On]
17+
given isOn as IsOn[On] = new IsOn[On]
1818
}
1919

2020
class Machine[S <: State] {

tests/neg/missing-implicit1.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ object testObjectInstance:
55
}
66

77
object instances {
8-
given zipOption: Zip[Option] = ???
9-
given traverseList: Traverse[List] = ???
8+
given zipOption as Zip[Option] = ???
9+
given traverseList as Traverse[List] = ???
1010
extension listExtension on [T](xs: List[T]):
1111
def second: T = xs.tail.head
1212
def [T](xs: List[T]) first: T = xs.head
@@ -35,8 +35,8 @@ def testLocalInstance =
3535
}
3636

3737
object instances {
38-
given zipOption: Zip[Option] = ???
39-
given traverseList: Traverse[List] = ???
38+
given zipOption as Zip[Option] = ???
39+
given traverseList as Traverse[List] = ???
4040
}
4141

4242
def ff(given xs: Zip[Option]) = ???

tests/neg/missing-implicit2.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ trait Y
33
object test:
44
def f(given x: X) = ???
55
object instances {
6-
given y: Y = ???
6+
given y as Y = ???
77
}
88
locally {
9-
given xFromY(given y: Y): X = ???
9+
given xFromY(given y: Y) as X = ???
1010
f(given xFromY) // error
1111
}
1212
locally {
1313
object instances2 {
14-
given xFromY(given Y): X = ???
14+
given xFromY(given Y) as X = ???
1515
}
1616
f // error
1717
}

tests/neg/multi-param-derives.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ object Test extends App {
55
trait Show[T]
66
object Show {
77
given Show[Int] {}
8-
given [T](given st: Show[T]): Show[Tuple1[T]] {}
9-
given t2[T, U](given st: Show[T], su: Show[U]) : Show[(T, U)] {}
10-
given t3[T, U, V](given st: Show[T], su: Show[U], sv: Show[V]) : Show[(T, U, V)] {}
8+
given [T](given st: Show[T]) as Show[Tuple1[T]] {}
9+
given t2[T, U](given st: Show[T], su: Show[U]) as Show[(T, U)] {}
10+
given t3[T, U, V](given st: Show[T], su: Show[U], sv: Show[V]) as Show[(T, U, V)] {}
1111

1212
def derived[T](given m: Mirror.Of[T], r: Show[m.MirroredElemTypes]): Show[T] = new Show[T] {}
1313
}
@@ -22,10 +22,10 @@ object Test extends App {
2222
{
2323
trait Functor[F[_]]
2424
object Functor {
25-
given [C] : Functor[[T] =>> C] {}
25+
given [C] as Functor[[T] =>> C] {}
2626
given Functor[[T] =>> Tuple1[T]] {}
27-
given t2 [T] : Functor[[U] =>> (T, U)] {}
28-
given t3 [T, U] : Functor[[V] =>> (T, U, V)] {}
27+
given t2 [T] as Functor[[U] =>> (T, U)] {}
28+
given t3 [T, U] as Functor[[V] =>> (T, U, V)] {}
2929

3030
def derived[F[_]](given m: Mirror { type MirroredType = F ; type MirroredElemTypes[_] }, r: Functor[m.MirroredElemTypes]): Functor[F] = new Functor[F] {}
3131
}
@@ -40,8 +40,8 @@ object Test extends App {
4040
{
4141
trait FunctorK[F[_[_]]]
4242
object FunctorK {
43-
given [C] : FunctorK[[F[_]] =>> C] {}
44-
given [T] : FunctorK[[F[_]] =>> Tuple1[F[T]]]
43+
given [C] as FunctorK[[F[_]] =>> C] {}
44+
given [T] as FunctorK[[F[_]] =>> Tuple1[F[T]]]
4545

4646
def derived[F[_[_]]](given m: Mirror { type MirroredType = F ; type MirroredElemTypes[_[_]] }, r: FunctorK[m.MirroredElemTypes]): FunctorK[F] = new FunctorK[F] {}
4747
}
@@ -56,10 +56,10 @@ object Test extends App {
5656
{
5757
trait Bifunctor[F[_, _]]
5858
object Bifunctor {
59-
given [C] : Bifunctor[[T, U] =>> C] {}
59+
given [C] as Bifunctor[[T, U] =>> C] {}
6060
given Bifunctor[[T, U] =>> Tuple1[U]] {}
61-
given t2 : Bifunctor[[T, U] =>> (T, U)] {}
62-
given t3 [T] : Bifunctor[[U, V] =>> (T, U, V)] {}
61+
given t2 as Bifunctor[[T, U] =>> (T, U)] {}
62+
given t3 [T] as Bifunctor[[U, V] =>> (T, U, V)] {}
6363

6464
def derived[F[_, _]](given m: Mirror { type MirroredType = F ; type MirroredElemTypes[_, _] }, r: Bifunctor[m.MirroredElemTypes]): Bifunctor[F] = ???
6565
}

tests/pos-custom-args/erased/i7868.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Coproduct {
1919
val cast: Value <:< Head +: Tail = atNext.cast
2020
}
2121

22-
given [A](given A): (() => A)= { () => summon[A]}
22+
given [A](given A) as (() => A)= { () => summon[A]}
2323
}
2424

2525
def upCast[A, B](a: A)(given erased evidence: (A <:< B)): B = a.asInstanceOf[B]

tests/pos-custom-args/erased/i7878.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object Boom {
99
}
1010

1111
val a: Int = 1
12-
given ev1: Fail[a.type, 2] = null
12+
given ev1 as Fail[a.type, 2] = null
1313

1414
summon[Fail[a.type, 3]]
1515
}

0 commit comments

Comments
 (0)