Skip to content

Commit 4985e6e

Browse files
committed
Drop given-: syntax
1 parent a29178c commit 4985e6e

34 files changed

+129
-176
lines changed

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

Lines changed: 24 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -910,28 +910,6 @@ object Parsers {
910910
followedByToken(LARROW) // `<-` comes before possible statement starts
911911
}
912912

913-
/** Are the next tokens a prefix of a formal parameter or given type?
914-
* @pre: current token is LPAREN
915-
* TODO: Drop once syntax has stabilized
916-
*/
917-
def followingIsParamOrGivenType() =
918-
val lookahead = in.LookaheadScanner()
919-
lookahead.nextToken()
920-
if startParamTokens.contains(lookahead.token)
921-
|| lookahead.isIdent(nme.using)
922-
then true
923-
else if lookahead.token == IDENTIFIER then
924-
if lookahead.name == nme.inline then
925-
lookahead.nextToken()
926-
if lookahead.token == IDENTIFIER then
927-
lookahead.nextToken()
928-
if lookahead.token == COLON then
929-
lookahead.nextToken()
930-
!lookahead.isAfterLineEnd
931-
else false
932-
else false
933-
else false
934-
935913
/** Are the next token the "GivenSig" part of a given definition,
936914
* i.e. an identifier followed by type and value parameters, followed by `:`?
937915
* @pre The current token is an identifier
@@ -942,12 +920,7 @@ object Parsers {
942920
lookahead.nextToken()
943921
while lookahead.token == LPAREN || lookahead.token == LBRACKET do
944922
lookahead.skipParens()
945-
if lookahead.token == COLON then // TODO: remove
946-
lookahead.nextToken()
947-
!lookahead.isAfterLineEnd
948-
else
949-
lookahead.token == SUBTYPE // TODO: remove
950-
|| lookahead.isIdent(nme.as)
923+
lookahead.isIdent(nme.as)
951924

952925
def followingIsExtension() =
953926
val lookahead = in.LookaheadScanner()
@@ -3502,57 +3475,37 @@ object Parsers {
35023475
* | [GivenSig] ConstrApps [TemplateBody]
35033476
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’
35043477
*/
3505-
def givenDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
3506-
var mods1 = addMod(mods, instanceMod)
3478+
def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) {
3479+
var mods1 = addMod(mods, givenMod)
35073480
val hasGivenSig = followingIsGivenSig()
35083481
val nameStart = in.offset
35093482
val name = if isIdent && hasGivenSig then ident() else EmptyTermName
35103483

35113484
val gdef = in.endMarkerScope(if name.isEmpty then GIVEN else name) {
3512-
val hasLabel = !name.isEmpty && in.token == COLON || isIdent(nme.as)
3513-
if hasLabel then in.nextToken()
35143485
val tparams = typeParamClauseOpt(ParamOwner.Def)
3515-
val paramsStart = in.offset
3516-
val vparamss =
3517-
if in.token == LPAREN && followingIsParamOrGivenType()
3518-
then paramClauses()
3519-
else Nil
3520-
def checkAllGivens(vparamss: List[List[ValDef]], what: String) =
3521-
vparamss.foreach(_.foreach(vparam =>
3522-
if !vparam.mods.is(Given) then syntaxError(em"$what must be preceded by `using`", vparam.span)))
3523-
checkAllGivens(vparamss, "parameter of given instance")
3524-
val parents =
3525-
if in.token == SUBTYPE && !hasLabel then
3526-
if !mods.is(Inline) then
3527-
syntaxError("`<:` is only allowed for given with `inline` modifier")
3528-
in.nextToken()
3529-
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
3530-
else
3531-
if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3532-
if in.token == COLON then in.nextToken()
3533-
else accept(nme.as)
3534-
if in.token == USCORE then
3535-
in.nextToken()
3536-
accept(SUBTYPE)
3537-
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
3538-
else
3539-
constrApps(commaOK = true, templateCanFollow = true)
3540-
3541-
if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3542-
in.nextToken()
3486+
val vparamss = paramClauses(givenOnly = true)
3487+
if !name.isEmpty || !tparams.isEmpty || !vparamss.isEmpty then
3488+
accept(nme.as)
3489+
def givenAlias(tpt: Tree) =
3490+
accept(EQUALS)
35433491
mods1 |= Final
3544-
DefDef(name, tparams, vparamss, parents.head, subExpr())
3492+
DefDef(name, tparams, vparamss, tpt, subExpr())
3493+
if in.token == USCORE then
3494+
in.nextToken()
3495+
accept(SUBTYPE)
3496+
givenAlias(TypeBoundsTree(EmptyTree, toplevelTyp()))
35453497
else
3546-
parents match
3547-
case (_: TypeBoundsTree) :: _ => syntaxError("`=` expected")
3548-
case _ =>
3549-
possibleTemplateStart()
3550-
val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))
3551-
val vparamss1 = vparamss.map(_.map(vparam =>
3552-
vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal)))
3553-
val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil)
3554-
if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ)
3555-
else TypeDef(name.toTypeName, templ)
3498+
val parents = constrApps(commaOK = true, templateCanFollow = true)
3499+
if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3500+
givenAlias(parents.head)
3501+
else
3502+
possibleTemplateStart()
3503+
val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal))
3504+
val vparamss1 = vparamss.map(_.map(vparam =>
3505+
vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal)))
3506+
val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil)
3507+
if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ)
3508+
else TypeDef(name.toTypeName, templ)
35563509
}
35573510
finalizeDef(gdef, mods1, start)
35583511
}

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,7 @@ trait Applications extends Compatibility {
14121412
/** Widen the result type of synthetic given methods from the implementation class to the
14131413
* type that's implemented. Example
14141414
*
1415-
* given I[X] : T { ... }
1415+
* given I[X] as T { ... }
14161416
*
14171417
* This desugars to
14181418
*
@@ -1422,7 +1422,7 @@ trait Applications extends Compatibility {
14221422
* To compare specificity we should compare with `T`, not with its implementation `I[X]`.
14231423
* No such widening is performed for given aliases, which are not synthetic. E.g.
14241424
*
1425-
* given J[X] : T = rhs
1425+
* given J[X] as T = rhs
14261426
*
14271427
* already has the right result type `T`. Neither is widening performed for given
14281428
* objects, since these are anyway taken to be more specific than methods

compiler/src/dotty/tools/dotc/typer/Deriving.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ trait Deriving {
122122
//
123123
// ADT: C[A, B] (A, B have same kinds at T, U)
124124
//
125-
// given derived$TC : TC[ C ] // a "natural" instance
125+
// given derived$TC as TC[ C ] // a "natural" instance
126126
//
127127
// ADT: C[A] (A has same kind as U)
128128
//
129-
// given derived$TC : TC[[t, u] =>> C[ u]]
129+
// given derived$TC as TC[[t, u] =>> C[ u]]
130130
//
131131
// (b) The type class and all ADT type parameters are of kind *
132132
//

compiler/test/dotty/tools/repl/ReplCompilerTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class ReplCompilerTests extends ReplTest {
151151
| def (x: T) > (y: T) = compare(x, y) > 0
152152
|}
153153
|
154-
|given IntOrd : Ord[Int] {
154+
|given IntOrd as Ord[Int] {
155155
| def compare(x: Int, y: Int) =
156156
| if (x < y) -1 else if (x > y) +1 else 0
157157
|}

docs/docs/internals/syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause]
296296
SubtypeBounds
297297
298298
ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
299-
ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’
299+
ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’
300300
| [nl] ‘(’ ‘using’ (ClsParams | Types) ‘)’
301301
ClsParams ::= ClsParam {‘,’ ClsParam}
302302
ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var

docs/docs/reference/changed-features/implicit-resolution.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ affect implicits on the language level.
4343
Example:
4444
```scala
4545
package p
46-
given a : A
46+
given a as A
4747

4848
object o {
49-
given b : B
49+
given b as B
5050
type C
5151
}
5252
```

docs/docs/reference/changed-features/numeric-literals.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ object BigFloat {
156156
To accept `BigFloat` literals, all that's needed in addition is a given instance of type
157157
`FromDigits.Floating[BigFloat]`:
158158
```scala
159-
given FromDigits : FromDigits.Floating[BigFloat] {
159+
given FromDigits as FromDigits.Floating[BigFloat] {
160160
def fromDigits(digits: String) = apply(digits)
161161
}
162162
} // end BigFloat

docs/docs/reference/metaprogramming/erased-terms-spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ title: "Erased Terms Spec"
3232

3333
3. Functions
3434
* `(erased x1: T1, x2: T2, ..., xN: TN) => y : (erased T1, T2, ..., TN) => R`
35-
* `(given erased x1: T1, x2: T2, ..., xN: TN) => y : (given erased T1, T2, ..., TN) => R`
35+
* `(given erased x1: T1, x2: T2, ..., xN: TN) => y as (given erased T1, T2, ..., TN) => R`
3636
* `(given erased T1) => R <:< erased T1 => R`
3737
* `(given erased T1, T2) => R <:< (erased T1, T2) => R`
3838
* ...

docs/docs/reference/metaprogramming/macros-spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ With the right extractors, the "AsFunction" conversion
191191
that maps expressions over functions to functions over expressions can
192192
be implemented in user code:
193193
```scala
194-
given AsFunction1[T, U] : Conversion[Expr[T => U], Expr[T] => Expr[U]] {
194+
given AsFunction1[T, U] as Conversion[Expr[T => U], Expr[T] => Expr[U]] {
195195
def apply(f: Expr[T => U]): Expr[T] => Expr[U] =
196196
(x: Expr[T]) => f match {
197197
case Lambda(g) => g(x)

docs/docs/reference/metaprogramming/macros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ given Liftable[Int] {
289289
Since `Liftable` is a type class, its instances can be conditional. For example,
290290
a `List` is liftable if its element type is:
291291
```scala
292-
given [T: Liftable : Type] : Liftable[List[T]] {
292+
given [T: Liftable : Type] as Liftable[List[T]] {
293293
def toExpr(xs: List[T]) = xs match {
294294
case head :: tail => '{ ${ Expr(head) } :: ${ toExpr(tail) } }
295295
case Nil => '{ Nil: List[T] }

0 commit comments

Comments
 (0)