Skip to content

Commit 42d74c0

Browse files
committed
Allow types in given definitions to be infix types
A type implemented in a given definition can now be an infix type, without enclosing parens being necessary. By contrast, it cannot anymore be a refined type. Refined types have to be enclosed in parens. This second point aligns the dotty parser with the published syntax and the scala meta parser. # Conflicts: # tests/pos/typeclasses-this.scala
1 parent b6e2272 commit 42d74c0

File tree

8 files changed

+45
-35
lines changed

8 files changed

+45
-35
lines changed

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,8 +1791,8 @@ object Parsers {
17911791
*/
17921792
def infixType(): Tree = infixTypeRest(refinedType())
17931793

1794-
def infixTypeRest(t: Tree): Tree =
1795-
infixOps(t, canStartInfixTypeTokens, refinedTypeFn, Location.ElseWhere, ParseKind.Type,
1794+
def infixTypeRest(t: Tree, operand: Location => Tree = refinedTypeFn): Tree =
1795+
infixOps(t, canStartInfixTypeTokens, operand, Location.ElseWhere, ParseKind.Type,
17961796
isOperator = !followingIsVararg() && !isPureArrow
17971797
&& nextCanFollowOperator(canStartInfixTypeTokens))
17981798

@@ -1857,6 +1857,10 @@ object Parsers {
18571857
*/
18581858
def annotType(): Tree = annotTypeRest(simpleType())
18591859

1860+
/** AnnotType1 ::= SimpleType1 {Annotation}
1861+
*/
1862+
def annotType1(): Tree = annotTypeRest(simpleType1())
1863+
18601864
def annotTypeRest(t: Tree): Tree =
18611865
if (in.token == AT)
18621866
annotTypeRest(atSpan(startOffset(t)) {
@@ -4075,8 +4079,10 @@ object Parsers {
40754079
syntaxError(em"extension clause can only define methods", stat.span)
40764080
}
40774081

4078-
/** GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance)
4079-
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4082+
/** GivenDef ::= [GivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4083+
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4084+
* GivenType ::= AnnotType1 {id [nl] AnnotType1}
4085+
* StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
40804086
*/
40814087
def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) {
40824088
var mods1 = addMod(mods, givenMod)
@@ -4102,8 +4108,12 @@ object Parsers {
41024108
val noParams = tparams.isEmpty && vparamss.isEmpty
41034109
if !(name.isEmpty && noParams) then acceptColon()
41044110
val parents =
4105-
if isSimpleLiteral then rejectWildcardType(annotType()) :: Nil
4106-
else refinedTypeRest(constrApp()) :: withConstrApps()
4111+
if isSimpleLiteral then
4112+
rejectWildcardType(annotType()) :: Nil
4113+
else constrApp() match
4114+
case parent: Apply => parent :: withConstrApps()
4115+
case parent if in.isIdent => infixTypeRest(parent, _ => annotType1()) :: Nil
4116+
case parent => parent :: withConstrApps()
41074117
val parentsIsType = parents.length == 1 && parents.head.isType
41084118
if in.token == EQUALS && parentsIsType then
41094119
accept(EQUALS)
@@ -4197,10 +4207,10 @@ object Parsers {
41974207

41984208
/* -------- TEMPLATES ------------------------------------------- */
41994209

4200-
/** ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs}
4210+
/** ConstrApp ::= AnnotType1 {ParArgumentExprs}
42014211
*/
42024212
val constrApp: () => Tree = () =>
4203-
val t = rejectWildcardType(annotTypeRest(simpleType1()),
4213+
val t = rejectWildcardType(annotType1(),
42044214
fallbackTree = Ident(tpnme.ERROR))
42054215
// Using Ident(tpnme.ERROR) to avoid causing cascade errors on non-user-written code
42064216
if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t

docs/_docs/internals/syntax.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
191191
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
192192
RefinedType ::= AnnotType {[nl] Refinement} RefinedTypeTree(t, ds)
193193
AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
194+
AnnotType1 ::= SimpleType1 {Annotation} Annotated(t, annot)
194195
195196
SimpleType ::= SimpleLiteral SingletonTypeTree(l)
196197
| ‘?’ TypeBounds
@@ -459,8 +460,9 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses
459460
ConstrMods ::= {Annotation} [AccessModifier]
460461
ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor
461462
EnumDef ::= id ClassConstr InheritClauses EnumBody
462-
GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance)
463+
GivenDef ::= [GivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
463464
GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefTypeParamClause`, `UsingParamClause` must be present
465+
GivenType ::= AnnotType1 {id [nl] AnnotType1}
464466
StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
465467
Extension ::= ‘extension’ [DefTypeParamClause] {UsingParamClause}
466468
‘(’ DefTermParam ‘)’ {UsingParamClause} ExtMethods

docs/_docs/reference/syntax.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ SimpleType ::= SimpleLiteral
200200
| Singleton ‘.’ ‘type’
201201
| ‘(’ Types ‘)’
202202
| Refinement
203-
| SimpleType1 TypeArgs
204-
| SimpleType1 ‘#’ id
203+
| SimpleType TypeArgs
204+
| SimpleType ‘#’ id
205205
Singleton ::= SimpleRef
206206
| SimpleLiteral
207207
| Singleton ‘.’ id
@@ -392,7 +392,7 @@ LocalModifier ::= ‘abstract’
392392
AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier]
393393
AccessQualifier ::= ‘[’ id ‘]’
394394
395-
Annotation ::= ‘@’ SimpleType1 {ParArgumentExprs}
395+
Annotation ::= ‘@’ SimpleType {ParArgumentExprs}
396396
397397
Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
398398
Export ::= ‘export’ ImportExpr {‘,’ ImportExpr}
@@ -444,6 +444,7 @@ ObjectDef ::= id [Template]
444444
EnumDef ::= id ClassConstr InheritClauses EnumBody
445445
GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance)
446446
GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefTypeParamClause`, `UsingParamClause` must be present
447+
GivenType ::= AnnotType {id [nl] AnnotType}
447448
StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
448449
Extension ::= ‘extension’ [DefTypeParamClause] {UsingParamClause}
449450
‘(’ DefTermParam ‘)’ {UsingParamClause} ExtMethods
@@ -453,7 +454,7 @@ ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef
453454
Template ::= InheritClauses [TemplateBody]
454455
InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}]
455456
ConstrApps ::= ConstrApp ({‘,’ ConstrApp} | {‘with’ ConstrApp})
456-
ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs}
457+
ConstrApp ::= SimpleType {Annotation} {ParArgumentExprs}
457458
ConstrExpr ::= SelfInvocation
458459
| <<< SelfInvocation {semi BlockStat} >>>
459460
SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs}

tests/neg/i12348.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
-- [E040] Syntax Error: tests/neg/i12348.scala:2:15 --------------------------------------------------------------------
2-
2 | given inline x: Int = 0 // error
3-
| ^
4-
| 'with' expected, but identifier found
5-
-- [E040] Syntax Error: tests/neg/i12348.scala:3:10 --------------------------------------------------------------------
6-
3 |} // error
7-
| ^
8-
| '}' expected, but eof found
1+
-- [E040] Syntax Error: tests/neg/i12348.scala:2:16 --------------------------------------------------------------------
2+
2 | given inline x: Int = 0 // error // error
3+
| ^
4+
| an identifier expected, but ':' found
5+
-- [E067] Syntax Error: tests/neg/i12348.scala:2:8 ---------------------------------------------------------------------
6+
2 | given inline x: Int = 0 // error // error
7+
| ^
8+
|Declaration of given instance given_x_inline_<error> not allowed here: only classes can have declared but undefined members

tests/neg/i12348.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
object A {
2-
given inline x: Int = 0 // error
3-
} // error
2+
given inline x: Int = 0 // error // error

tests/neg/i7045.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Bar { type Y }
2+
trait Foo { type X }
3+
4+
class Test:
5+
given a1(using b: Bar): Foo = new Foo { type X = b.Y } // ok
6+
given a2(using b: Bar): (Foo { type X = b.Y }) = new Foo { type X = b.Y } // ok
7+
given a3(using b: Bar): Foo { type X = b.Y } = new Foo { type X = b.Y } // error

tests/pos/i7045.scala

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/pos/typeclass-aggregates.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ trait OrdWithMonoid extends Ord, Monoid
3030
def ordWithMonoid2(ord: Ord, monoid: Monoid{ type This = ord.This }) = //: OrdWithMonoid { type This = ord.This} =
3131
new OrdWithMonoid with ord.OrdProxy with monoid.MonoidProxy {}
3232

33-
given intOrd: Ord { type This = Int } = ???
34-
given intMonoid: Monoid { type This = Int } = ???
33+
given intOrd: (Ord { type This = Int }) = ???
34+
given intMonoid: (Monoid { type This = Int }) = ???
3535

3636
//given (using ord: Ord, monoid: Monoid{ type This = ord.This }): (Ord & Monoid { type This = ord.This}) =
3737
// ordWithMonoid2(ord, monoid)
@@ -42,6 +42,6 @@ val y: Int = ??? : x.This
4242
// given [A, B](using ord: A is Ord, monoid: A is Monoid) => A is Ord & Monoid =
4343
// new ord.OrdProxy with monoid.MonoidProxy {}
4444

45-
given [A](using ord: Ord { type This = A }, monoid: Monoid { type This = A}): (Ord & Monoid) { type This = A} =
45+
given [A](using ord: Ord { type This = A }, monoid: Monoid { type This = A}): ((Ord & Monoid) { type This = A}) =
4646
new ord.OrdProxy with monoid.MonoidProxy {}
4747

0 commit comments

Comments
 (0)