Skip to content

Commit dd6b326

Browse files
committed
Revert "Fix #7788: Add new syntax for conditional given instances"
This reverts commit d1579e6. # Conflicts: # compiler/src/dotty/tools/dotc/parsing/Parsers.scala # docs/docs/internals/syntax.md # tests/pos/reference/delegates.scala
1 parent 31c9f08 commit dd6b326

25 files changed

+62
-113
lines changed

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

Lines changed: 19 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,6 @@ object Parsers {
902902

903903
/** Are the next tokens a prefix of a formal parameter or given type?
904904
* @pre: current token is LPAREN
905-
* TODO: Drop once syntax has stabilized
906905
*/
907906
def followingIsParamOrGivenType() =
908907
val lookahead = in.LookaheadScanner()
@@ -920,22 +919,6 @@ object Parsers {
920919
else false
921920
else false
922921

923-
/** Are the next tokens a prefix of a formal parameter?
924-
* @pre: current token is LPAREN
925-
*/
926-
def followingIsParam() =
927-
val lookahead = in.LookaheadScanner()
928-
lookahead.nextToken()
929-
if startParamTokens.contains(lookahead.token) then true
930-
else if lookahead.token == IDENTIFIER then
931-
if lookahead.name == nme.inline then
932-
lookahead.nextToken()
933-
if lookahead.token == IDENTIFIER then
934-
lookahead.nextToken()
935-
lookahead.token == COLON
936-
else false
937-
else false
938-
939922
/** Are the next token the "GivenSig" part of a given definition,
940923
* i.e. an identifier followed by type and value parameters, followed by `:`?
941924
* @pre The current token is an identifier
@@ -2788,18 +2771,16 @@ object Parsers {
27882771
def typeParamClauseOpt(ownerKind: ParamOwner.Value): List[TypeDef] =
27892772
if (in.token == LBRACKET) typeParamClause(ownerKind) else Nil
27902773

2791-
def typesToGivenParams(tps: List[Tree], ofClass: Boolean, nparams: Int): List[ValDef] =
2774+
/** OLD: GivenTypes ::= AnnotType {‘,’ AnnotType}
2775+
* NEW: GivenTypes ::= Type {‘,’ Type}
2776+
*/
2777+
def givenTypes(nparams: Int, ofClass: Boolean): List[ValDef] =
2778+
val tps = commaSeparated(typ)
27922779
var counter = nparams
27932780
def nextIdx = { counter += 1; counter }
27942781
val paramFlags = if ofClass then Private | Local | ParamAccessor else Param
27952782
tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given))
27962783

2797-
/** OLD: GivenTypes ::= AnnotType {‘,’ AnnotType}
2798-
* NEW: GivenTypes ::= Type {‘,’ Type}
2799-
*/
2800-
def givenTypes(ofClass: Boolean, nparams: Int): List[ValDef] =
2801-
typesToGivenParams(commaSeparated(typ), ofClass, nparams)
2802-
28032784
/** ClsParamClause ::= ‘(’ [‘erased’] ClsParams ‘)’
28042785
* GivenClsParamClause::= ‘(’ ‘given’ [‘erased’] (ClsParams | GivenTypes) ‘)’
28052786
* ClsParams ::= ClsParam {‘,’ ClsParam}
@@ -2897,7 +2878,7 @@ object Parsers {
28972878
|| startParamTokens.contains(in.token)
28982879
|| isIdent && (in.name == nme.inline || in.lookaheadIn(BitSet(COLON)))
28992880
if isParams then commaSeparated(() => param())
2900-
else givenTypes(ofClass, nparams)
2881+
else givenTypes(nparams, ofClass)
29012882
checkVarArgsRules(clause)
29022883
clause
29032884
}
@@ -3423,12 +3404,11 @@ object Parsers {
34233404
syntaxError(i"extension clause can only define methods", stat.span)
34243405
}
34253406

3426-
/** GivenDef ::= [GivenSig (‘:’ | <:)] {FunArgTypes ‘=>’} AnnotType ‘=’ Expr
3427-
* | [GivenSig ‘:’] {FunArgTypes ‘=>’} ConstrApps [TemplateBody]
3407+
/** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
3408+
* | [GivenSig ‘:’] ConstrApps [TemplateBody]
34283409
* GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
34293410
* ExtParamClause ::= [DefTypeParamClause] DefParamClause
34303411
* ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
3431-
* TODO: cleanup once syntax has stabilized
34323412
*/
34333413
def givenDef(start: Offset, mods: Modifiers, instanceMod: Mod) = atSpan(start, nameStart) {
34343414
var mods1 = addMod(mods, instanceMod)
@@ -3453,60 +3433,30 @@ object Parsers {
34533433
templ.body.foreach(checkExtensionMethod(tparams, _))
34543434
ModuleDef(name, templ)
34553435
else
3456-
var hasLabel = false
3457-
def skipColon() =
3458-
if !hasLabel && in.token == COLON then
3459-
hasLabel = true
3460-
in.nextToken()
3461-
if !name.isEmpty then skipColon()
3436+
val hasLabel = !name.isEmpty && in.token == COLON
3437+
if hasLabel then in.nextToken()
34623438
val tparams = typeParamClauseOpt(ParamOwner.Def)
3463-
if !tparams.isEmpty then skipColon()
34643439
val paramsStart = in.offset
3465-
var vparamss =
3440+
val vparamss =
34663441
if in.token == LPAREN && followingIsParamOrGivenType()
3467-
then paramClauses() // todo: ONLY admit a single paramClause
3442+
then paramClauses()
34683443
else Nil
34693444
def checkAllGivens(vparamss: List[List[ValDef]], what: String) =
34703445
vparamss.foreach(_.foreach(vparam =>
34713446
if !vparam.mods.is(Given) then syntaxError(em"$what must be `given`", vparam.span)))
3472-
def makeGiven(params: List[ValDef]): List[ValDef] =
3473-
params.map(param => param.withMods(param.mods | Given))
3474-
def conditionalParents(): List[Tree] =
3475-
accept(ARROW)
3476-
if in.token == LPAREN && followingIsParam() then
3477-
vparamss = vparamss :+ makeGiven(paramClause(vparamss.flatten.length))
3478-
conditionalParents()
3479-
else
3480-
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3481-
if in.token == ARROW && constrs.forall(_.isType) then
3482-
vparamss = vparamss
3483-
:+ typesToGivenParams(constrs, ofClass = false, vparamss.flatten.length)
3484-
conditionalParents()
3485-
else constrs
3486-
3487-
val isConditional =
3488-
in.token == ARROW
3489-
&& vparamss.length == 1
3490-
&& (hasLabel || name.isEmpty && tparams.isEmpty)
3491-
if !isConditional then checkAllGivens(vparamss, "parameter of given instance")
3447+
checkAllGivens(vparamss, "parameter of given instance")
34923448
val parents =
3493-
if in.token == SUBTYPE && !hasLabel then
3449+
if hasLabel then
3450+
constrApps(commaOK = true, templateCanFollow = true)
3451+
else if in.token == SUBTYPE then
34943452
if !mods.is(Inline) then
34953453
syntaxError("`<:` is only allowed for given with `inline` modifier")
34963454
in.nextToken()
3497-
TypeBoundsTree(EmptyTree, annotType()) :: Nil
3498-
else if isConditional then
3499-
vparamss = vparamss.map(makeGiven)
3500-
conditionalParents()
3455+
TypeBoundsTree(EmptyTree, toplevelTyp()) :: Nil
35013456
else
3502-
if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3457+
if !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
35033458
accept(COLON)
3504-
val constrs = constrApps(commaOK = true, templateCanFollow = true)
3505-
if in.token == ARROW && vparamss.isEmpty && constrs.forall(_.isType) then
3506-
vparamss = typesToGivenParams(constrs, ofClass = false, 0) :: Nil
3507-
conditionalParents()
3508-
else
3509-
constrs
3459+
constrApps(commaOK = true, templateCanFollow = true)
35103460

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

docs/docs/internals/syntax.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ yield
103103
### Soft keywords
104104

105105
```
106-
derives extension inline opaque open
106+
as derives extension inline on opaque open
107107
~ * | & + -
108108
```
109109

@@ -384,10 +384,8 @@ 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 (‘:’ | <:)] {FunArgTypes ‘=>’}
388-
AnnotType ‘=’ Expr
389-
| [GivenSig ‘:’] {FunArgTypes ‘=>’}
390-
ConstrApps [TemplateBody]
387+
GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
388+
| [GivenSig ‘:’] ConstrApps [TemplateBody]
391389
GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
392390
ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods
393391
ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’

docs/docs/reference/contextual/derivation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ we need to implement a method `Eq.derived` on the companion object of `Eq` that
175175
a `Mirror[T]`. Here is a possible implementation,
176176

177177
```scala
178-
inline given derived[T]: (m: Mirror.Of[T]) => Eq[T] = {
178+
inline given derived[T](given m: Mirror.Of[T]): Eq[T] = {
179179
val elemInstances = summonAll[m.MirroredElemTypes] // (1)
180180
inline m match { // (2)
181181
case s: Mirror.SumOf[T] => eqSum(s, elemInstances)
@@ -281,7 +281,7 @@ object Eq {
281281
}
282282
}
283283

284-
inline given derived[T]: (m: Mirror.Of[T]) => Eq[T] = {
284+
inline given derived[T](given m: Mirror.Of[T]): Eq[T] = {
285285
val elemInstances = summonAll[m.MirroredElemTypes]
286286
inline m match {
287287
case s: Mirror.SumOf[T] => eqSum(s, elemInstances)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Given instances can be mapped to combinations of implicit objects, classes and i
2121
```
2222
2. Parameterized given instances are mapped to combinations of classes and implicit methods. E.g.,
2323
```scala
24-
given listOrd[T]: (ord: Ord[T]) => Ord[List[T]] { ... }
24+
given listOrd[T](given ord: Ord[T]): Ord[List[T]] { ... }
2525
```
2626
maps to
2727
```scala

library/src/scala/quoted/Liftable.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ object Liftable {
103103
else '{ Array(${Expr(array(0))}, ${Expr(array.toSeq.tail)}: _*) }
104104
}
105105

106-
given iArrayIsLiftable[T: Type]: (ltArray: Liftable[Array[T]]) => Liftable[IArray[T]] {
106+
given iArrayIsLiftable[T: Type](given ltArray: Liftable[Array[T]]): Liftable[IArray[T]] {
107107
def toExpr(iarray: IArray[T]): (given QuoteContext) => Expr[IArray[T]] =
108108
'{ ${ltArray.toExpr(iarray.asInstanceOf[Array[T]])}.asInstanceOf[IArray[T]] }
109109
}

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]: (h: H) => H = h
2+
given f[H](given h: H): 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]: (h: H, t: T) => F[H, T] = ???
7+
given f[H, T](given h: H, t: T): F[H, T] = ???
88
summon[F[Int, Unit]] // error
99
}

tests/neg/i7459.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ object Eq {
4747
}
4848
}
4949

50-
inline given derived[T]: (m: Mirror.Of[T]) => Eq[T] = {
50+
inline given derived[T](given m: Mirror.Of[T]): Eq[T] = {
5151
val elemInstances = summonAll[m.MirroredElemTypes]
5252
inline m match {
5353
case s: Mirror.SumOf[T] => eqSum(s, elemInstances)

tests/neg/missing-implicit2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ object test:
1111
}
1212
locally {
1313
object instances2 {
14-
given xFromY: Y => X = ???
14+
given xFromY(given Y): X = ???
1515
}
1616
f // error
1717
}

tests/neg/multi-param-derives.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ object Test extends App {
55
trait Show[T]
66
object Show {
77
given Show[Int] {}
8-
given [T]: (st: Show[T]) => Show[Tuple1[T]] {}
8+
given [T](given st: Show[T]): Show[Tuple1[T]] {}
99
given t2[T, U](given st: Show[T], su: Show[U]) : Show[(T, U)] {}
1010
given t3[T, U, V](given st: Show[T], su: Show[U], sv: Show[V]) : Show[(T, U, V)] {}
1111

0 commit comments

Comments
 (0)