Skip to content

Commit 41311bf

Browse files
committed
Don't run migration operations in ReTypers
1 parent 02b4ec7 commit 41311bf

File tree

3 files changed

+64
-54
lines changed

3 files changed

+64
-54
lines changed

compiler/src/dotty/tools/dotc/typer/Migrations.scala

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ import reporting.*
2020
import NameKinds.ContextBoundParamName
2121
import rewrites.Rewrites.patch
2222
import util.Spans.Span
23+
import rewrites.Rewrites
2324

24-
/** A utility module containing source-dependent deprecation messages
25-
* and migrations
25+
/** A utility trait containing source-dependent deprecation messages
26+
* and migrations.
2627
*/
27-
object Migrations:
28+
trait Migrations:
29+
this: Typer =>
2830

2931
import tpd.*
3032

3133
/** Flag & migrate `?` used as a higher-kinded type parameter
3234
* Warning in 3.0-migration, error from 3.0
3335
*/
34-
def migrateKindProjectorQMark(tree: untpd.TypeDef, sym: Symbol)(using Context): Unit =
36+
def kindProjectorQMark(tree: untpd.TypeDef, sym: Symbol)(using Context): Unit =
3537
if tree.name eq tpnme.? then
3638
val addendum = if sym.owner.is(TypeParam)
3739
then ", use `_` to denote a higher-kinded type parameter"
@@ -40,10 +42,53 @@ object Migrations:
4042
report.errorOrMigrationWarning(
4143
em"`?` is not a valid type name$addendum", namePos, MigrationVersion.Scala2to3)
4244

45+
def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree = {
46+
val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree: @unchecked
47+
val pt1 = if (defn.isFunctionNType(pt)) pt else AnyFunctionProto
48+
val nestedCtx = ctx.fresh.setNewTyperState()
49+
val res = typed(qual, pt1)(using nestedCtx)
50+
res match {
51+
case closure(_, _, _) =>
52+
case _ =>
53+
val recovered = typed(qual)(using ctx.fresh.setExploreTyperState())
54+
val msg = OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen, tree)
55+
report.errorOrMigrationWarning(msg, tree.srcPos, MigrationVersion.Scala2to3)
56+
if MigrationVersion.Scala2to3.needsPatch then
57+
// Under -rewrite, patch `x _` to `(() => x)`
58+
msg.actions
59+
.headOption
60+
.foreach(Rewrites.applyAction)
61+
return typed(untpd.Function(Nil, qual), pt)
62+
}
63+
nestedCtx.typerState.commit()
64+
65+
lazy val (prefix, suffix) = res match {
66+
case Block(mdef @ DefDef(_, vparams :: Nil, _, _) :: Nil, _: Closure) =>
67+
val arity = vparams.length
68+
if (arity > 0) ("", "") else ("(() => ", "())")
69+
case _ =>
70+
("(() => ", ")")
71+
}
72+
def remedy =
73+
if ((prefix ++ suffix).isEmpty) "simply leave out the trailing ` _`"
74+
else s"use `$prefix<function>$suffix` instead"
75+
def rewrite = Message.rewriteNotice("This construct", `3.4-migration`)
76+
report.errorOrMigrationWarning(
77+
em"""The syntax `<function> _` is no longer supported;
78+
|you can $remedy$rewrite""",
79+
tree.srcPos,
80+
MigrationVersion.FunctionUnderscore)
81+
if MigrationVersion.FunctionUnderscore.needsPatch then
82+
patch(Span(tree.span.start), prefix)
83+
patch(Span(qual.span.end, tree.span.end), suffix)
84+
85+
res
86+
}
87+
4388
/** Flag & migrate explicit normal arguments to parameters coming from context bounds
4489
* Warning in 3.4, error in 3.5, rewrite in 3.5-migration.
4590
*/
46-
def migrateContextBoundParams(tree: Tree, tp: Type, pt: FunProto)(using Context): Unit =
91+
def contextBoundParams(tree: Tree, tp: Type, pt: FunProto)(using Context): Unit =
4792
def isContextBoundParams = tp.stripPoly match
4893
case MethodType(ContextBoundParamName(_) :: _) => true
4994
case _ => false
@@ -58,4 +103,6 @@ object Migrations:
58103
tree.srcPos, MigrationVersion(`3.4`, `3.5`))
59104
if sourceVersion.isAtLeast(`3.5-migration`) then
60105
patch(Span(pt.args.head.span.start), "using ")
61-
end migrateContextBoundParams
106+
end contextBoundParams
107+
108+
end Migrations

compiler/src/dotty/tools/dotc/typer/ReTyper.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,5 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
189189
override protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(using Context): Unit = ()
190190
override protected def matchingApply(methType: MethodOrPoly, pt: FunProto)(using Context): Boolean = true
191191
override protected def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree = promote(call)
192+
override protected def migrate[T](migration: => T, disabled: => T = ()): T = disabled
192193
}

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ import config.Printers.{gadts, typr}
4343
import config.Feature
4444
import config.Feature.{sourceVersion, migrateTo3}
4545
import config.SourceVersion.*
46-
import rewrites.Rewrites.patch
46+
import rewrites.Rewrites, Rewrites.patch
4747
import staging.StagingLevel
4848
import reporting.*
4949
import Nullables.*
5050
import NullOpsDecorator.*
5151
import cc.CheckCaptures
5252
import config.Config
5353
import config.MigrationVersion
54-
import Migrations.*
5554

5655
import scala.annotation.constructorOnly
57-
import dotty.tools.dotc.rewrites.Rewrites
5856

5957
object Typer {
6058

@@ -128,7 +126,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
128126
with Dynamic
129127
with Checking
130128
with QuotesAndSplices
131-
with Deriving {
129+
with Deriving
130+
with Migrations {
132131

133132
import Typer.*
134133
import tpd.{cpy => _, _}
@@ -159,6 +158,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
159158
// Overridden in derived typers
160159
def newLikeThis(nestingLevel: Int): Typer = new Typer(nestingLevel)
161160

161+
// Overridden to do nothing in derived typers
162+
protected def migrate[T](migration: => T, disabled: => T = ()): T = migration
163+
162164
/** Find the type of an identifier with given `name` in given context `ctx`.
163165
* @param name the name of the identifier
164166
* @param pt the expected type
@@ -2979,48 +2981,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
29792981
else tree1
29802982
}
29812983

2982-
def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree = {
2983-
val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree: @unchecked
2984-
val pt1 = if (defn.isFunctionNType(pt)) pt else AnyFunctionProto
2985-
val nestedCtx = ctx.fresh.setNewTyperState()
2986-
val res = typed(qual, pt1)(using nestedCtx)
2987-
res match {
2988-
case closure(_, _, _) =>
2989-
case _ =>
2990-
val recovered = typed(qual)(using ctx.fresh.setExploreTyperState())
2991-
val msg = OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen, tree)
2992-
report.errorOrMigrationWarning(msg, tree.srcPos, MigrationVersion.Scala2to3)
2993-
if MigrationVersion.Scala2to3.needsPatch then
2994-
// Under -rewrite, patch `x _` to `(() => x)`
2995-
msg.actions
2996-
.headOption
2997-
.foreach(Rewrites.applyAction)
2998-
return typed(untpd.Function(Nil, qual), pt)
2999-
}
3000-
nestedCtx.typerState.commit()
3001-
3002-
lazy val (prefix, suffix) = res match {
3003-
case Block(mdef @ DefDef(_, vparams :: Nil, _, _) :: Nil, _: Closure) =>
3004-
val arity = vparams.length
3005-
if (arity > 0) ("", "") else ("(() => ", "())")
3006-
case _ =>
3007-
("(() => ", ")")
3008-
}
3009-
def remedy =
3010-
if ((prefix ++ suffix).isEmpty) "simply leave out the trailing ` _`"
3011-
else s"use `$prefix<function>$suffix` instead"
3012-
def rewrite = Message.rewriteNotice("This construct", `3.4-migration`)
3013-
report.errorOrMigrationWarning(
3014-
em"""The syntax `<function> _` is no longer supported;
3015-
|you can $remedy$rewrite""",
3016-
tree.srcPos,
3017-
MigrationVersion.FunctionUnderscore)
3018-
if MigrationVersion.FunctionUnderscore.needsPatch then
3019-
patch(Span(tree.span.start), prefix)
3020-
patch(Span(qual.span.end, tree.span.end), suffix)
3021-
3022-
res
3023-
}
2984+
override def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree =
2985+
migrate(super.typedAsFunction(tree, pt), throw new AssertionError("can't retype a PostfixOp"))
30242986

30252987
/** Translate infix operation expression `l op r` to
30262988
*
@@ -3138,7 +3100,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
31383100
case tree: untpd.TypeDef =>
31393101
// separate method to keep dispatching method `typedNamed` short which might help the JIT
31403102
def typedTypeOrClassDef: Tree =
3141-
migrateKindProjectorQMark(tree, sym)
3103+
migrate(kindProjectorQMark(tree, sym))
31423104
if tree.isClassDef then
31433105
typedClassDef(tree, sym.asClass)(using ctx.localContext(tree, sym))
31443106
else
@@ -3814,7 +3776,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38143776
case wtp: MethodOrPoly =>
38153777
def methodStr = methPart(tree).symbol.showLocated
38163778
if matchingApply(wtp, pt) then
3817-
migrateContextBoundParams(tree, wtp, pt)
3779+
migrate(contextBoundParams(tree, wtp, pt))
38183780
if needsTupledDual(wtp, pt) then adapt(tree, pt.tupledDual, locked)
38193781
else tree
38203782
else if wtp.isContextualMethod then

0 commit comments

Comments
 (0)