Skip to content

Commit c3e88b7

Browse files
authored
Merge pull request #6298 from dotty-staging/fix-#6286
Fix #6286: Fix ElimOpaque transformation
2 parents 99a4fa6 + efc48c3 commit c3e88b7

File tree

9 files changed

+69
-28
lines changed

9 files changed

+69
-28
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
407407
ref(defn.DottyArraysModule).select(defn.newArrayMethod).withSpan(span)
408408

409409
if (!ctx.erasedTypes) {
410-
assert(!TypeErasure.isGeneric(elemTpe)) //needs to be done during typer. See Applications.convertNewGenericArray
410+
assert(!TypeErasure.isGeneric(elemTpe), elemTpe) //needs to be done during typer. See Applications.convertNewGenericArray
411411
newArr.appliedToTypeTrees(TypeTree(returnTpe) :: Nil).appliedToArgs(clsOf(elemTpe) :: clsOf(returnTpe) :: dims :: Nil).withSpan(span)
412412
} else // after erasure
413413
newArr.appliedToArgs(clsOf(elemTpe) :: clsOf(returnTpe) :: dims :: Nil).withSpan(span)

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ object DenotTransformers {
5757
protected def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = true
5858
}
5959

60-
/** A transformer that only transforms SymDenotations */
60+
/** A transformer that only transforms SymDenotations.
61+
* Note: Infos of non-sym denotations are left as is. So the transformer should
62+
* be used before erasure only if this is not a problem. After erasure, all
63+
* denotations are SymDenotations, so SymTransformers can be used freely.
64+
*/
6165
trait SymTransformer extends DenotTransformer {
6266

6367
def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation

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

+3-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import reporting.diagnostic.Message
1919
import reporting.diagnostic.messages.BadSymbolicReference
2020
import reporting.trace
2121
import collection.mutable
22+
import transform.TypeUtils._
2223

2324
import scala.annotation.internal.sharable
2425

@@ -1082,16 +1083,10 @@ object SymDenotations {
10821083
* containing object.
10831084
*/
10841085
def opaqueAlias(implicit ctx: Context): Type = {
1085-
if (isOpaqueHelper) {
1086+
if (isOpaqueHelper)
10861087
owner.asClass.classInfo.selfType match {
1087-
case RefinedType(_, _, TypeBounds(lo, _)) =>
1088-
def extractAlias(tp: Type): Type = tp match {
1089-
case OrType(alias, _) => alias
1090-
case tp: HKTypeLambda => tp.derivedLambdaType(resType = extractAlias(tp.resType))
1091-
}
1092-
extractAlias(lo)
1088+
case RefinedType(_, _, bounds) => bounds.extractOpaqueAlias
10931089
}
1094-
}
10951090
else NoType
10961091
}
10971092

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,13 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
254254
protected def typeApplyText[T >: Untyped](tree: TypeApply[T]): Text = {
255255
val isQuote = tree.fun.hasType && tree.fun.symbol == defn.InternalQuoted_typeQuote
256256
val (open, close) = if (isQuote) (keywordStr("'["), keywordStr("]")) else ("[", "]")
257-
toTextLocal(tree.fun).provided(!isQuote) ~ open ~ toTextGlobal(tree.args, ", ") ~ close
257+
val funText = toTextLocal(tree.fun).provided(!isQuote)
258+
tree.fun match {
259+
case Select(New(tpt), nme.CONSTRUCTOR) if tpt.typeOpt.dealias.isInstanceOf[AppliedType] =>
260+
funText // type was already printed by toText(new)
261+
case _ =>
262+
funText ~ open ~ toTextGlobal(tree.args, ", ") ~ close
263+
}
258264
}
259265

260266
protected def toTextCore[T >: Untyped](tree: Tree[T]): Text = {

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

+18-17
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,23 @@ package dotty.tools.dotc
22
package transform
33

44
import core._
5-
import Names._
65
import dotty.tools.dotc.transform.MegaPhase._
7-
import ast.Trees._
8-
import ast.untpd
96
import Flags._
107
import Types._
11-
import Constants.Constant
128
import Contexts.Context
139
import Symbols._
1410
import Decorators._
15-
import Annotations._
16-
import Annotations.ConcreteAnnotation
1711
import Denotations.SingleDenotation
1812
import SymDenotations.SymDenotation
19-
import scala.collection.mutable
2013
import DenotTransformers._
21-
import NameOps._
22-
import NameKinds.OuterSelectName
23-
import StdNames._
14+
import TypeUtils._
2415

2516
object ElimOpaque {
2617
val name: String = "elimOpaque"
2718
}
2819

2920
/** Rewrites opaque type aliases to normal alias types */
30-
class ElimOpaque extends MiniPhase with SymTransformer {
21+
class ElimOpaque extends MiniPhase with DenotTransformer {
3122

3223
override def phaseName: String = ElimOpaque.name
3324

@@ -37,11 +28,21 @@ class ElimOpaque extends MiniPhase with SymTransformer {
3728
// base types of opaque aliases change
3829
override def changesBaseTypes = true
3930

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))
31+
def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
32+
val sym = ref.symbol
33+
ref match {
34+
case ref: SymDenotation if sym.isOpaqueHelper =>
35+
ref.copySymDenotation(
36+
info = TypeAlias(ref.opaqueAlias),
37+
initFlags = ref.flags &~ (Opaque | Deferred))
38+
case ref: SymDenotation if sym.isOpaqueCompanion =>
39+
val ref1 = ref.copySymDenotation(initFlags = ref.flags &~ Opaque)
40+
ref1.registeredCompanion = NoSymbol
41+
ref1
42+
case _ if sym.isOpaqueHelper =>
43+
ref.derivedSingleDenotation(sym, TypeAlias(ref.info.extractOpaqueAlias))
44+
case _ =>
45+
ref
4546
}
46-
else sym
47+
}
4748
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ class Getters extends MiniPhase with SymTransformer {
6565
d.copySymDenotation(
6666
initFlags = d.flags | maybeStable | AccessorCreationFlags,
6767
info = ExprType(d.info))
68+
// Note: This change will only affect the SymDenotation itself, not
69+
// SingleDenotations referring to a getter. In this case it does not
70+
// seem to be a problem since references to a getter don't care whether
71+
// it's a `T` or a `=> T`
6872
}
6973
else d
7074

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

+12
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,17 @@ object TypeUtils {
5151
/** The `*:` equivalent of an instance of a Tuple class */
5252
def toNestedPairs(implicit ctx: Context): Type =
5353
TypeOps.nestedPairs(tupleElementTypes)
54+
55+
/** Extract opaque alias from TypeBounds type that combines it with the reference
56+
* to the opaque type itself
57+
*/
58+
def extractOpaqueAlias(implicit ctx: Context): Type = self match {
59+
case TypeBounds(lo, _) =>
60+
def extractAlias(tp: Type): Type = tp match {
61+
case OrType(alias, _) => alias
62+
case self: HKTypeLambda => self.derivedLambdaType(resType = extractAlias(self.resType))
63+
}
64+
extractAlias(lo)
65+
}
5466
}
5567
}

tests/pos/i6286.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object A {
2+
opaque type T33 = Int
3+
object T33 {
4+
val a = new Array[T33](3)
5+
}
6+
}

tests/pos/i6287.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object O{
2+
def m() = {
3+
opaque type T = Int
4+
object T
5+
}
6+
}
7+
object A {
8+
{
9+
opaque type T = Int
10+
object T
11+
println
12+
}
13+
}

0 commit comments

Comments
 (0)