Skip to content

Commit 10d36ee

Browse files
committed
Eliminate opaque types
This is done after RefChecks, so that we can check for proper overriding of opaque types.
1 parent 646e596 commit 10d36ee

File tree

5 files changed

+59
-5
lines changed

5 files changed

+59
-5
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class Compiler {
6464
new HoistSuperArgs, // Hoist complex arguments of supercalls to enclosing scope
6565
new ClassOf, // Expand `Predef.classOf` calls.
6666
new RefChecks) :: // Various checks mostly related to abstract members and overriding
67-
List(new TryCatchPatterns, // Compile cases in try/catch
67+
List(new ElimOpaque, // Turn opaque into normal aliases
68+
new TryCatchPatterns, // Compile cases in try/catch
6869
new PatternMatcher, // Compile pattern matches
6970
new ExplicitOuter, // Add accessors to outer classes from nested ones.
7071
new ExplicitSelf, // Make references to non-trivial self types explicit as casts

compiler/src/dotty/tools/dotc/core/Periods.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ abstract class Periods { self: Context =>
4343
val period = this.period
4444
period == p ||
4545
period.runId == p.runId &&
46-
this.phases(period.phaseId).sameParentsStartId ==
47-
this.phases(p.phaseId).sameParentsStartId
46+
this.phases(period.phaseId).sameBaseTypesStartId ==
47+
this.phases(p.phaseId).sameBaseTypesStartId
4848
}
4949
}
5050

compiler/src/dotty/tools/dotc/core/Phases.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ object Phases {
320320
/** Can this transform change the parents of a class? */
321321
def changesParents: Boolean = false
322322

323+
/** Can this transform change the base types of a type? */
324+
def changesBaseTypes: Boolean = changesParents
325+
323326
def exists: Boolean = true
324327

325328
def initContext(ctx: FreshContext): Unit = ()
@@ -332,6 +335,7 @@ object Phases {
332335

333336
private[this] var mySameMembersStartId = NoPhaseId
334337
private[this] var mySameParentsStartId = NoPhaseId
338+
private[this] var mySameBaseTypesStartId = NoPhaseId
335339

336340
/** The sequence position of this phase in the given context where 0
337341
* is reserved for NoPhase and the first real phase is at position 1.
@@ -351,6 +355,8 @@ object Phases {
351355
// id of first phase where all symbols are guaranteed to have the same members as in this phase
352356
final def sameParentsStartId: Int = mySameParentsStartId
353357
// id of first phase where all symbols are guaranteed to have the same parents as in this phase
358+
final def sameBaseTypesStartId: Int = mySameBaseTypesStartId
359+
// id of first phase where all symbols are guaranteed to have the same base tpyes as in this phase
354360

355361
protected[Phases] def init(base: ContextBase, start: Int, end: Int): Unit = {
356362
if (start >= FirstPhaseId)
@@ -363,6 +369,7 @@ object Phases {
363369
myRefChecked = prev.getClass == classOf[RefChecks] || prev.refChecked
364370
mySameMembersStartId = if (changesMembers) id else prev.sameMembersStartId
365371
mySameParentsStartId = if (changesParents) id else prev.sameParentsStartId
372+
mySameBaseTypesStartId = if (changesBaseTypes) id else prev.sameBaseTypesStartId
366373
}
367374

368375
protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import Names._
6+
import dotty.tools.dotc.transform.MegaPhase._
7+
import ast.Trees._
8+
import ast.untpd
9+
import Flags._
10+
import Types._
11+
import Constants.Constant
12+
import Contexts.Context
13+
import Symbols._
14+
import Decorators._
15+
import Annotations._
16+
import Annotations.ConcreteAnnotation
17+
import Denotations.SingleDenotation
18+
import SymDenotations.SymDenotation
19+
import scala.collection.mutable
20+
import DenotTransformers._
21+
import NameOps._
22+
import NameKinds.OuterSelectName
23+
import StdNames._
24+
25+
object ElimOpaque {
26+
val name: String = "elimOpaque"
27+
}
28+
29+
/** Rewrites opaque type aliases to normal alias types */
30+
class ElimOpaque extends MiniPhase with SymTransformer {
31+
32+
override def phaseName: String = ElimOpaque.name
33+
34+
// Override checks need to take place before treating opaque types as aliases
35+
override def runsAfterGroupsOf: Set[String] = Set(typer.RefChecks.name)
36+
37+
// base types of opaque aliases change
38+
override def changesBaseTypes = true
39+
40+
def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation =
41+
if (sym.isOpaqueHelper) {
42+
sym.copySymDenotation(
43+
info = TypeAlias(sym.opaqueAlias),
44+
initFlags = sym.flags &~ (Opaque | Deferred))
45+
}
46+
else sym
47+
}

compiler/src/dotty/tools/dotc/transform/FirstTransform.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ object FirstTransform {
2222
val name: String = "firstTransform"
2323
}
2424

25-
2625
/** The first tree transform
2726
* - eliminates some kinds of trees: Imports, NamedArgs
28-
* - stubs out native and typelevel methods
27+
* - stubs out native methods
2928
* - eliminates self tree in Template and self symbol in ClassInfo
3029
* - collapses all type trees to trees of class TypeTree
3130
* - converts idempotent expressions with constant types

0 commit comments

Comments
 (0)