Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Jan 8, 2024
1 parent 786852c commit 13a71ef
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 21 deletions.
14 changes: 11 additions & 3 deletions compiler/src/dotty/tools/dotc/config/MigrationVersion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ import SourceVersion.*
import Feature.*
import core.Contexts.Context

class MigrationVersion(val warnFrom: SourceVersion, val errorFrom: SourceVersion):
assert(warnFrom.ordinal <= errorFrom.ordinal)
class MigrationVersion(
val warnFrom: SourceVersion,
val errorFrom: SourceVersion):
require(warnFrom.ordinal <= errorFrom.ordinal)

def needsPatch(using Context): Boolean =
sourceVersion.isMigrating && sourceVersion.isAtLeast(errorFrom)
sourceVersion.isMigrating && sourceVersion.isAtLeast(warnFrom)

def patchFrom: SourceVersion =
warnFrom.prevMigrating

object MigrationVersion:

Expand All @@ -27,6 +33,8 @@ object MigrationVersion:

val AscriptionAfterPattern = MigrationVersion(`3.3`, future)

val ExplicitContextBoundArgument = MigrationVersion(`3.4`, `3.5`)

val AlphanumericInfix = MigrationVersion(`3.4`, future)
val RemoveThisQualifier = MigrationVersion(`3.4`, future)
val UninitializedVars = MigrationVersion(`3.4`, future)
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/config/SourceVersion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ enum SourceVersion:
def stable: SourceVersion =
if isMigrating then SourceVersion.values(ordinal + 1) else this

def prevMigrating: SourceVersion =
if isMigrating then this else SourceVersion.values(ordinal - 1).prevMigrating

def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal

def isAtMost(v: SourceVersion) = stable.ordinal <= v.ordinal
Expand Down
32 changes: 21 additions & 11 deletions compiler/src/dotty/tools/dotc/typer/Migrations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Symbols.*
import Trees.*
import ProtoTypes.*
import Decorators.*
import config.MigrationVersion
import config.MigrationVersion as mv
import config.Feature.{sourceVersion, migrateTo3}
import config.SourceVersion.*
import reporting.*
Expand All @@ -30,6 +30,15 @@ trait Migrations:

import tpd.*

/** Run `migration`, asserting we are in the proper Typer (not a ReTyper) */
inline def migrate[T](inline migration: T): T =
assert(!this.isInstanceOf[ReTyper])
migration

/** Run `migration`, provided we are in the proper Typer (not a ReTyper) */
inline def migrate(inline migration: Unit): Unit =
if !this.isInstanceOf[ReTyper] then migration

/** Flag & migrate `?` used as a higher-kinded type parameter
* Warning in 3.0-migration, error from 3.0
*/
Expand All @@ -40,7 +49,7 @@ trait Migrations:
else ""
val namePos = tree.sourcePos.withSpan(tree.nameSpan)
report.errorOrMigrationWarning(
em"`?` is not a valid type name$addendum", namePos, MigrationVersion.Scala2to3)
em"`?` is not a valid type name$addendum", namePos, mv.Scala2to3)

def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree = {
val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree: @unchecked
Expand All @@ -52,8 +61,8 @@ trait Migrations:
case _ =>
val recovered = typed(qual)(using ctx.fresh.setExploreTyperState())
val msg = OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen, tree)
report.errorOrMigrationWarning(msg, tree.srcPos, MigrationVersion.Scala2to3)
if MigrationVersion.Scala2to3.needsPatch then
report.errorOrMigrationWarning(msg, tree.srcPos, mv.Scala2to3)
if mv.Scala2to3.needsPatch then
// Under -rewrite, patch `x _` to `(() => x)`
msg.actions
.headOption
Expand All @@ -69,16 +78,16 @@ trait Migrations:
case _ =>
("(() => ", ")")
}
val mversion = mv.FunctionUnderscore
def remedy =
if ((prefix ++ suffix).isEmpty) "simply leave out the trailing ` _`"
else s"use `$prefix<function>$suffix` instead"
def rewrite = Message.rewriteNotice("This construct", `3.4-migration`)
def rewrite = Message.rewriteNotice("This construct", mversion.patchFrom)
report.errorOrMigrationWarning(
em"""The syntax `<function> _` is no longer supported;
|you can $remedy$rewrite""",
tree.srcPos,
MigrationVersion.FunctionUnderscore)
if MigrationVersion.FunctionUnderscore.needsPatch then
tree.srcPos, mversion)
if mversion.needsPatch then
patch(Span(tree.span.start), prefix)
patch(Span(qual.span.end, tree.span.end), suffix)

Expand All @@ -89,19 +98,20 @@ trait Migrations:
* Warning in 3.4, error in 3.5, rewrite in 3.5-migration.
*/
def contextBoundParams(tree: Tree, tp: Type, pt: FunProto)(using Context): Unit =
val mversion = mv.ExplicitContextBoundArgument
def isContextBoundParams = tp.stripPoly match
case MethodType(ContextBoundParamName(_) :: _) => true
case _ => false
if sourceVersion.isAtLeast(`3.4`)
&& isContextBoundParams
&& pt.applyKind != ApplyKind.Using
then
def rewriteMsg = Message.rewriteNotice("This code", `3.5-migration`)
def rewriteMsg = Message.rewriteNotice("This code", mversion.patchFrom)
report.errorOrMigrationWarning(
em"""Context bounds will map to context parameters.
|A `using` clause is needed to pass explicit arguments to them.$rewriteMsg""",
tree.srcPos, MigrationVersion(`3.4`, `3.5`))
if sourceVersion.isAtLeast(`3.5-migration`) then
tree.srcPos, mversion)
if mversion.needsPatch then
patch(Span(pt.args.head.span.start), "using ")
end contextBoundParams

Expand Down
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/ReTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,4 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
override protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(using Context): Unit = ()
override protected def matchingApply(methType: MethodOrPoly, pt: FunProto)(using Context): Boolean = true
override protected def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree = promote(call)
override protected def migrate[T](migration: => T, disabled: => T = ()): T = disabled
}
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// Overridden in derived typers
def newLikeThis(nestingLevel: Int): Typer = new Typer(nestingLevel)

// Overridden to do nothing in derived typers
protected def migrate[T](migration: => T, disabled: => T = ()): T = migration

/** Find the type of an identifier with given `name` in given context `ctx`.
* @param name the name of the identifier
* @param pt the expected type
Expand Down Expand Up @@ -2982,7 +2979,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
}

override def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree =
migrate(super.typedAsFunction(tree, pt), throw new AssertionError("can't retype a PostfixOp"))
migrate(super.typedAsFunction(tree, pt))

/** Translate infix operation expression `l op r` to
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//> using options -Xfatal-warnings
//> using options -source 3.4

class C[T]
def foo[X: C] = ()

given [T]: C[T] = C[T]()

def Test =
foo(C[Int]()) // error
foo(C[Int]()) // warn
foo(using C[Int]()) // ok

0 comments on commit 13a71ef

Please sign in to comment.