diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 685b81be268e..dc927e713e65 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1092,25 +1092,6 @@ object Parsers { || in.lookahead.token == EOF // important for REPL completions || ctx.mode.is(Mode.Interactive) // in interactive mode the next tokens might be missing - /** Under `qualifiedTypes` language import: is the token sequence following - * the current `{` classified as a qualified type? This is the case if the - * next token is an `IDENT`, followed by `:`. - */ - def followingIsQualifiedType(): Boolean = - in.featureEnabled(Feature.qualifiedTypes) && { - val lookahead = in.LookaheadScanner(allowIndent = true) - - if in.token == INDENT then - () // The LookaheadScanner doesn't see previous indents, so no need to skip it - else - lookahead.nextToken() // skips the opening brace - - lookahead.token == IDENTIFIER && { - lookahead.nextToken() - lookahead.token == COLONfollow - } - } - /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ var opStack: List[OpInfo] = Nil @@ -2071,10 +2052,11 @@ object Parsers { atSpan(in.offset) { makeTupleOrParens(inParensWithCommas(argTypes(namedOK = false, wildOK = true, tupleOK = true))) } - else if in.token == LBRACE && followingIsQualifiedType() then - qualifiedType() else if in.token == LBRACE then - atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement(indentOK = false)) } + if in.featureEnabled(Feature.qualifiedTypes) && in.lookahead.token == IDENTIFIER then + qualifiedType() + else + atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement(indentOK = false)) } else if (isSplice) splice(isType = true) else diff --git a/tests/printing/qualifiers.check b/tests/printing/qualifiers.check index 2a7912741238..6d021fc599ce 100644 --- a/tests/printing/qualifiers.check +++ b/tests/printing/qualifiers.check @@ -15,10 +15,10 @@ package example { new example.qualifiers$package() final module class qualifiers$package() extends Object() { this: example.qualifiers$package.type => - type Useless = + type Neg = Int @qualified[Int]( { - def $anonfun(x: Int): Boolean = true + def $anonfun(x: Int): Boolean = x.<(0) closure($anonfun) } ) @@ -29,14 +29,39 @@ package example { closure($anonfun) } ) - type Neg = + type Pos2 = Int @qualified[Int]( { - def $anonfun(x: Int): Boolean = x.<(0) + def $anonfun(x: Int): Boolean = x.>(0) closure($anonfun) } ) - type Nesting = + type Pos3 = + Int @qualified[Int]( + { + def $anonfun(x: Int): Boolean = x.>(0) + closure($anonfun) + } + ) + type Pos4 = + Int @qualified[Int]( + { + def $anonfun(x: Int): Boolean = x.>(0) + closure($anonfun) + } + ) + type Pos5 = + Int @qualified[Int]( + { + def $anonfun(x: Int): Boolean = + { + val res: Boolean = x.>(0) + res:Boolean + } + closure($anonfun) + } + ) + type Nested = Int @qualified[Int]( { def $anonfun(x: Int): Boolean = @@ -54,7 +79,7 @@ package example { closure($anonfun) } ) - type Pos2 = + type Intersection = Int & Int @qualified[Int]( { @@ -76,7 +101,7 @@ package example { def id[T >: Nothing <: Any](x: T): T = x def test(): Unit = { - val x1: example.Pos = 1 + val x: example.Pos = 1 val x2: Int @qualified[Int]( { @@ -88,12 +113,28 @@ package example { val x3: Int @qualified[Int]( { - def $anonfun(x3: Int): Boolean = x3.>(0) + def $anonfun(x: Int): Boolean = x.>(0) + closure($anonfun) + } + ) + = 1 + val x4: + Int @qualified[Int]( + { + def $anonfun(x: Int): Boolean = x.>(0) closure($anonfun) } ) = 1 - val x4: Int = + val x5: + Int @qualified[Int]( + { + def $anonfun(x5: Int): Boolean = x.>(0) + closure($anonfun) + } + ) + = 1 + val x6: Int = example.id[ Int @qualified[Int]( { @@ -137,12 +178,38 @@ package example { val b: Boolean = false example.id[Boolean](true) } - type B = + type T1 = + Object + { + val x: Int + } + type T2 = + Object + { + val x: Int + } + type T3 = + Object + { + type T = Int + } + type T4 = + Object + { + def x: Int + } + type T5 = + Object + { + def x: Int + def x_=(x$1: Int): _root_.scala.Unit + } + type T6 = Object { val x: Int } - type C = + type T7 = Object { val x: Int diff --git a/tests/printing/qualifiers.scala b/tests/printing/qualifiers.scala index 15ed8d0da6e8..f09f260d4962 100644 --- a/tests/printing/qualifiers.scala +++ b/tests/printing/qualifiers.scala @@ -1,22 +1,37 @@ package example -type Useless = {x: Int with true} -type Pos = +type Neg = {x: Int with x < 0} +type Pos = {x: Int with x > 0} +type Pos2 = {x: Int + with x > 0 +} +type Pos3 = {x: Int with + x > 0 +} +type Pos4 = {x: Int with x > 0} -type Neg = {x: Int with - x < 0 +type Pos5 = {x: Int with + val res = x > 0 + res } -type Nesting = {x: Int with { val y: {z: Int with z > 0} = ??? ; x > y }} -type Pos2 = Int & {x: Int with x > 0} + +type Nested = {x: Int with { val y: {z: Int with z > 0} = ??? ; x > y }} +type Intersection = Int & {x: Int with x > 0} type ValRefinement = {val x: Int with x > 0} def id[T](x: T): T = x def test() = - val x1: Pos = 1 + val x: Pos = 1 val x2: {x: Int with x > 0} = 1 - val x3: Int with x3 > 0 = 1 - val x4: Int = id[{x: Int with x < 0}](1) + id[Neg](-1) + val x3: { + x: Int with x > 0 + } = 1 + val x4: {x: Int with + x > 0 + } = 1 + val x5: Int with x > 0 = 1 + val x6: Int = id[{x: Int with x < 0}](1) + id[Neg](-1) def bar(x: Int with x > 0) = ??? def secondGreater1(x: Int, y: Int)(z: {w: Int with x > y}) = ??? @@ -32,5 +47,13 @@ given A with id(true) // Also not qualified types: -type B = {val x: Int} -type C = Object {val x: Int} +type T1 = {val x: Int} +type T2 = { + val x: Int +} +type T3 = {type T = Int} +type T4 = {def x: Int} +type T5 = {var x: Int} +type T6 = Object {val x: Int} +type T7 = Object: + val x: Int