Skip to content

Commit 280f094

Browse files
committed
Allow with in refinements
1 parent d31eba1 commit 280f094

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

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

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,33 +1566,32 @@ object Parsers {
15661566
def infixTypeRest(t: Tree): Tree =
15671567
infixOps(t, canStartTypeTokens, refinedType, isType = true, isOperator = !isPostfixStar)
15681568

1569-
/** RefinedType ::= WithType {[nl] Refinement}
1569+
/** RefinedType ::= WithType {[nl | ‘with’] Refinement}
15701570
*/
15711571
val refinedType: () => Tree = () => refinedTypeRest(withType())
15721572

1573-
def refinedTypeRest(t: Tree): Tree = {
1573+
def refinedTypeRest(t: Tree): Tree =
15741574
argumentStart()
1575-
if (in.isNestedStart)
1575+
if isTemplateBodyStart then
1576+
if in.token == WITH then in.nextToken()
15761577
refinedTypeRest(atSpan(startOffset(t)) {
15771578
RefinedTypeTree(rejectWildcardType(t), refinement(indentOK = true))
15781579
})
15791580
else t
1580-
}
15811581

15821582
/** WithType ::= AnnotType {`with' AnnotType} (deprecated)
15831583
*/
15841584
def withType(): Tree = withTypeRest(annotType())
15851585

15861586
def withTypeRest(t: Tree): Tree =
1587-
if in.token == WITH then
1588-
val withOffset = in.offset
1587+
def isRefinementStart =
1588+
val la = in.lookahead
1589+
la.isAfterLineEnd || la.token == LBRACE
1590+
if in.token == WITH && !isRefinementStart then
15891591
in.nextToken()
1590-
if in.token == LBRACE || in.token == INDENT then
1591-
t
1592-
else
1593-
if sourceVersion.isAtLeast(`3.1`) then
1594-
deprecationWarning(DeprecatedWithOperator(), withOffset)
1595-
atSpan(startOffset(t)) { makeAndType(t, withType()) }
1592+
if sourceVersion.isAtLeast(`3.1`) then
1593+
deprecationWarning(DeprecatedWithOperator())
1594+
atSpan(startOffset(t)) { makeAndType(t, withType()) }
15961595
else t
15971596

15981597
/** AnnotType ::= SimpleType {Annotation}

tests/pos/abstract-givens.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class C { type T }
2+
trait A with
3+
given C with {} // concrete
4+
given c0: C {} // concrete
5+
given c1: C {} // concrete
6+
given c2: (C {type T <: Int}) // abstract with refinement
7+
8+
object B extends A with
9+
override given c2: C with { type T = Int }

tests/pos/refinements.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ trait UU {
1010
type UX
1111
val u: UX
1212
val x: this.type & { type UX = Int }
13+
val x1: this.type { type UX = Int }
14+
val x2: this.type with { type UX = Int }
15+
val x3: this.type with
16+
type UX = Int
1317
val y: Int = x.u
1418
val z: x.UX = y
1519
}

0 commit comments

Comments
 (0)