Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SIP 64 as non-experimental #21668

Merged
merged 9 commits into from
Oct 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum MigrationVersion(val warnFrom: SourceVersion, val errorFrom: SourceVersion)
case ImportRename extends MigrationVersion(future, future)
case ParameterEnclosedByParenthesis extends MigrationVersion(future, future)
case XmlLiteral extends MigrationVersion(future, future)
case GivenSyntax extends MigrationVersion(future, never)

require(warnFrom.ordinal <= errorFrom.ordinal)

Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/config/SourceVersion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ enum SourceVersion:
// !!! Keep in sync with scala.runtime.stdlibPatches.language !!!
case `future-migration`, `future`

case `never` // needed for MigrationVersion.errorFrom if we never want to issue an error
bishabosha marked this conversation as resolved.
Show resolved Hide resolved

val isMigrating: Boolean = toString.endsWith("-migration")

def stable: SourceVersion =
Expand Down
24 changes: 22 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2240,7 +2240,16 @@ object Parsers {
in.nextToken()
if in.token == LBRACE && sourceVersion.isAtLeast(`3.6`)
then inBraces(commaSeparated(() => contextBound(pname)))
else contextBound(pname) :: contextBounds(pname)
else
val bound = contextBound(pname)
val rest =
if in.isColon then
report.errorOrMigrationWarning(
em"Multiple context bounds should be enclosed in `{ ... }`",
in.sourcePos(), MigrationVersion.GivenSyntax)
contextBounds(pname)
else Nil
bound :: rest
else if in.token == VIEWBOUND then
report.errorOrMigrationWarning(
em"view bounds `<%' are no longer supported, use a context bound `:' instead",
Expand Down Expand Up @@ -4015,7 +4024,7 @@ object Parsers {
case SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | OUTDENT | EOF =>
makeTypeDef(typeAndCtxBounds(tname))
case _ if (staged & StageKind.QuotedPattern) != 0
|| in.featureEnabled(Feature.modularity) && in.isColon =>
|| sourceVersion.isAtLeast(`3.6`) && in.isColon =>
makeTypeDef(typeAndCtxBounds(tname))
case _ =>
syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals(in.token))
Expand Down Expand Up @@ -4261,6 +4270,9 @@ object Parsers {
in.nextToken()
newSignature()
else if hasEmbeddedColon then
report.errorOrMigrationWarning(
em"This old given syntax is no longer supported; use `=>` instead of `:`",
in.sourcePos(), MigrationVersion.GivenSyntax)
newSyntaxAllowed = false
val tparamsOld = typeParamClauseOpt(ParamOwner.Given)
newLineOpt()
Expand Down Expand Up @@ -4294,6 +4306,11 @@ object Parsers {
// old-style abstract given
if name.isEmpty then
syntaxError(em"Anonymous given cannot be abstract, or maybe you want to define a concrete given and are missing a `()` argument?", in.lastOffset)
if newSyntaxAllowed then
report.errorOrMigrationWarning(
em"""This defines an abstract given, which is no longer supported. Use a `deferred` given instead.
|Or, if you intend to define a concrete given, follow the type with `()` arguments.""",
in.sourcePos(in.lastOffset), MigrationVersion.GivenSyntax)
DefDef(name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, EmptyTree)
else
// structural instance
Expand Down Expand Up @@ -4483,6 +4500,9 @@ object Parsers {

/** with Template, with EOL <indent> interpreted */
def withTemplate(constr: DefDef, parents: List[Tree]): Template =
report.errorOrMigrationWarning(
em"Given member definitions starting with `with` are no longer supported; use `{...}` or `:` followed by newline instead",
in.sourcePos(), MigrationVersion.GivenSyntax)
accept(WITH)
val (self, stats) = templateBody(parents, rewriteWithColon = false)
Template(constr, parents, Nil, self, stats)
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/cb-companion-leaks.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future -explain
//> using options -language:experimental.modularity -explain

class C[Self]

Expand Down
4 changes: 4 additions & 0 deletions tests/neg/context-bounds-migration-future.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
| method foo does not take more parameters
|
| longer explanation available when compiling with `-explain`
-- Warning: tests/neg/context-bounds-migration-future.scala:6:6 --------------------------------------------------------
6 |given [T]: C[T] = C[T]()
| ^
| This old given syntax is no longer supported; use `=>` instead of `:`
2 changes: 1 addition & 1 deletion tests/neg/deferred-givens.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future

import compiletime.deferred

class Ctx
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/deferredSummon.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity


object Test:
given Int = compiletime.deferred // error
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/infix.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class C:
def +(x: Int): Int = ???

object C:
given AnyRef with
given AnyRef:
extension (x: C)
infix def iop (y: Int) = ???
def mop (y: Int) = ???
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/tracked.check
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
17 | tracked type T = Int // error // error
| ^^^^
| end of statement expected but 'type' found
-- Error: tests/neg/tracked.scala:20:29 --------------------------------------------------------------------------------
20 | given g2(using tracked val x: Int): C = C(x) // error
| ^^^^^^^^^^^^^^^^^^
| method parameter x may not be a `val`
-- Error: tests/neg/tracked.scala:20:25 --------------------------------------------------------------------------------
20 | given g2: (tracked val x: Int) => C = C(x) // error
| ^^^^^^^^^^^^^^^^^^
| method parameter x may not be a `val`
-- Error: tests/neg/tracked.scala:4:21 ---------------------------------------------------------------------------------
4 |class C2(tracked var x: Int) // error
| ^
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/tracked.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ object D:
tracked type T = Int // error // error

object E:
given g2(using tracked val x: Int): C = C(x) // error
given g2: (tracked val x: Int) => C = C(x) // error
1 change: 0 additions & 1 deletion tests/pos-custom-args/captures/logger.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import language.experimental.saferExceptions
import language.experimental.modularity

class FileSystem extends caps.Capability

Expand Down
1 change: 0 additions & 1 deletion tests/pos-custom-args/captures/nested-classes.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import language.experimental.captureChecking
import language.experimental.modularity
import annotation.{capability, constructorOnly}

class IO extends caps.Capability
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/FromString-cb-companion.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future
//> using options -language:experimental.modularity

trait FromString[Self]:
def fromString(s: String): Self
Expand Down
1 change: 0 additions & 1 deletion tests/pos/FromString-typeparam.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//> using options -language:experimental.modularity -source future

trait FromString[A]:
def fromString(s: String): A
Expand Down
1 change: 0 additions & 1 deletion tests/pos/cb-companion-joins.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import language.experimental.modularity
import language.future

trait M[Self]:
extension (x: Self) def combine (y: Self): String
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/deferred-givens-singletons.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future
// //> using options -language:experimental.modularity -source future
import compiletime.*

trait A:
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/deferred-givens.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future

import compiletime.*
class Ord[Elem]
given Ord[Double]()
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/dep-context-bounds.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -language:experimental.modularity -source future
//> using options -language:experimental.modularity
trait A:
type Self

Expand Down
2 changes: 0 additions & 2 deletions tests/pos/i21189-alt.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -source:future -language:experimental.modularity

class MySortedSet[T : Ord] extends SortedSet[T]

trait Ord[T]
Expand Down
2 changes: 0 additions & 2 deletions tests/pos/i21189.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -source:future -language:experimental.modularity

class MySortedSet[T : Ord] extends SortedSet[T]

trait Ord[T]
Expand Down
2 changes: 0 additions & 2 deletions tests/pos/typeclasses-arrow0.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -language:experimental.modularity -source future

class Common:

trait Ord[A]:
Expand Down
1 change: 0 additions & 1 deletion tests/run/Providers.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import language.experimental.modularity
import compiletime.constValue
import compiletime.ops.int.S

Expand Down
2 changes: 0 additions & 2 deletions tests/run/byname-given.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -language:experimental.modularity -source future

@main def Test =
var x: Int = 0
given () => Int = x
Expand Down
6 changes: 5 additions & 1 deletion tests/warn/abstract-givens-new.check
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@

-- Warning: tests/warn/abstract-givens-new.scala:7:22 ------------------------------------------------------------------
7 | given intC: Int is C // warn
| ^
| This defines an abstract given, which is no longer supported. Use a `deferred` given instead.
| Or, if you intend to define a concrete given, follow the type with `()` arguments.
2 changes: 1 addition & 1 deletion tests/warn/abstract-givens-new.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class C:

trait T:
given Int is C // ok
given intC: Int is C // ok for now, will be warning
given intC: Int is C // warn
given intC2: (Int is C)() // ok
given intC3: Int is C {} // also ok

25 changes: 25 additions & 0 deletions tests/warn/old-givens.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Warning: tests/warn/old-givens.scala:8:20 ---------------------------------------------------------------------------
8 | given intC: C[Int] // warn
| ^
| This defines an abstract given, which is no longer supported. Use a `deferred` given instead.
| Or, if you intend to define a concrete given, follow the type with `()` arguments.
-- Warning: tests/warn/old-givens.scala:11:8 ---------------------------------------------------------------------------
11 | given [T]: Ord[T] with // warn // warn
| ^
| This old given syntax is no longer supported; use `=>` instead of `:`
-- Warning: tests/warn/old-givens.scala:11:20 --------------------------------------------------------------------------
11 | given [T]: Ord[T] with // warn // warn
| ^
|Given member definitions starting with `with` are no longer supported; use `{...}` or `:` followed by newline instead
-- Warning: tests/warn/old-givens.scala:14:8 ---------------------------------------------------------------------------
14 | given [T](using Ord[T]): Ord[List[T]] with // warn // warn
| ^
| This old given syntax is no longer supported; use `=>` instead of `:`
-- Warning: tests/warn/old-givens.scala:14:40 --------------------------------------------------------------------------
14 | given [T](using Ord[T]): Ord[List[T]] with // warn // warn
| ^
|Given member definitions starting with `with` are no longer supported; use `{...}` or `:` followed by newline instead
-- Warning: tests/warn/old-givens.scala:17:15 --------------------------------------------------------------------------
17 | def f[T: Ord : C]() = ??? // warn
| ^
| Multiple context bounds should be enclosed in `{ ... }`
18 changes: 18 additions & 0 deletions tests/warn/old-givens.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//> using options -source future
trait Ord[T]:
def compare(x: T, y: T): Boolean

class C[T]

trait T:
given intC: C[Int] // warn
given intC2: C[Int] () // OK

given [T]: Ord[T] with // warn // warn
def compare(x: T, y: T): Boolean = ???

given [T](using Ord[T]): Ord[List[T]] with // warn // warn
def compare(x: List[T], y: List[T]): Boolean = ???

def f[T: Ord : C]() = ??? // warn

Loading