diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index c9d884ac673c..6a2faa74b13e 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -407,7 +407,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ref(defn.DottyArraysModule).select(defn.newArrayMethod).withSpan(span) if (!ctx.erasedTypes) { - assert(!TypeErasure.isGeneric(elemTpe)) //needs to be done during typer. See Applications.convertNewGenericArray + assert(!TypeErasure.isGeneric(elemTpe), elemTpe) //needs to be done during typer. See Applications.convertNewGenericArray newArr.appliedToTypeTrees(TypeTree(returnTpe) :: Nil).appliedToArgs(clsOf(elemTpe) :: clsOf(returnTpe) :: dims :: Nil).withSpan(span) } else // after erasure newArr.appliedToArgs(clsOf(elemTpe) :: clsOf(returnTpe) :: dims :: Nil).withSpan(span) diff --git a/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala b/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala index f8ea4fde1104..8b3bca405488 100644 --- a/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala +++ b/compiler/src/dotty/tools/dotc/core/DenotTransformers.scala @@ -57,7 +57,11 @@ object DenotTransformers { protected def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = true } - /** A transformer that only transforms SymDenotations */ + /** A transformer that only transforms SymDenotations. + * Note: Infos of non-sym denotations are left as is. So the transformer should + * be used before erasure only if this is not a problem. After erasure, all + * denotations are SymDenotations, so SymTransformers can be used freely. + */ trait SymTransformer extends DenotTransformer { def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index dae8aa99e997..6aaca2d587cc 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -19,6 +19,7 @@ import reporting.diagnostic.Message import reporting.diagnostic.messages.BadSymbolicReference import reporting.trace import collection.mutable +import transform.TypeUtils._ import scala.annotation.internal.sharable @@ -1082,16 +1083,10 @@ object SymDenotations { * containing object. */ def opaqueAlias(implicit ctx: Context): Type = { - if (isOpaqueHelper) { + if (isOpaqueHelper) owner.asClass.classInfo.selfType match { - case RefinedType(_, _, TypeBounds(lo, _)) => - def extractAlias(tp: Type): Type = tp match { - case OrType(alias, _) => alias - case tp: HKTypeLambda => tp.derivedLambdaType(resType = extractAlias(tp.resType)) - } - extractAlias(lo) + case RefinedType(_, _, bounds) => bounds.extractOpaqueAlias } - } else NoType } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 1056c8df4dca..40c7bd263a3e 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -254,7 +254,13 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { protected def typeApplyText[T >: Untyped](tree: TypeApply[T]): Text = { val isQuote = tree.fun.hasType && tree.fun.symbol == defn.InternalQuoted_typeQuote val (open, close) = if (isQuote) (keywordStr("'["), keywordStr("]")) else ("[", "]") - toTextLocal(tree.fun).provided(!isQuote) ~ open ~ toTextGlobal(tree.args, ", ") ~ close + val funText = toTextLocal(tree.fun).provided(!isQuote) + tree.fun match { + case Select(New(tpt), nme.CONSTRUCTOR) if tpt.typeOpt.dealias.isInstanceOf[AppliedType] => + funText // type was already printed by toText(new) + case _ => + funText ~ open ~ toTextGlobal(tree.args, ", ") ~ close + } } protected def toTextCore[T >: Untyped](tree: Tree[T]): Text = { diff --git a/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala b/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala index 3d022d451833..e4536c054fb1 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimOpaque.scala @@ -2,32 +2,23 @@ package dotty.tools.dotc package transform import core._ -import Names._ import dotty.tools.dotc.transform.MegaPhase._ -import ast.Trees._ -import ast.untpd import Flags._ import Types._ -import Constants.Constant import Contexts.Context import Symbols._ import Decorators._ -import Annotations._ -import Annotations.ConcreteAnnotation import Denotations.SingleDenotation import SymDenotations.SymDenotation -import scala.collection.mutable import DenotTransformers._ -import NameOps._ -import NameKinds.OuterSelectName -import StdNames._ +import TypeUtils._ object ElimOpaque { val name: String = "elimOpaque" } /** Rewrites opaque type aliases to normal alias types */ -class ElimOpaque extends MiniPhase with SymTransformer { +class ElimOpaque extends MiniPhase with DenotTransformer { override def phaseName: String = ElimOpaque.name @@ -37,11 +28,21 @@ class ElimOpaque extends MiniPhase with SymTransformer { // base types of opaque aliases change override def changesBaseTypes = true - def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = - if (sym.isOpaqueHelper) { - sym.copySymDenotation( - info = TypeAlias(sym.opaqueAlias), - initFlags = sym.flags &~ (Opaque | Deferred)) + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = { + val sym = ref.symbol + ref match { + case ref: SymDenotation if sym.isOpaqueHelper => + ref.copySymDenotation( + info = TypeAlias(ref.opaqueAlias), + initFlags = ref.flags &~ (Opaque | Deferred)) + case ref: SymDenotation if sym.isOpaqueCompanion => + val ref1 = ref.copySymDenotation(initFlags = ref.flags &~ Opaque) + ref1.registeredCompanion = NoSymbol + ref1 + case _ if sym.isOpaqueHelper => + ref.derivedSingleDenotation(sym, TypeAlias(ref.info.extractOpaqueAlias)) + case _ => + ref } - else sym + } } \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/transform/Getters.scala b/compiler/src/dotty/tools/dotc/transform/Getters.scala index d6d16a72ad47..f635412fae23 100644 --- a/compiler/src/dotty/tools/dotc/transform/Getters.scala +++ b/compiler/src/dotty/tools/dotc/transform/Getters.scala @@ -65,6 +65,10 @@ class Getters extends MiniPhase with SymTransformer { d.copySymDenotation( initFlags = d.flags | maybeStable | AccessorCreationFlags, info = ExprType(d.info)) + // Note: This change will only affect the SymDenotation itself, not + // SingleDenotations referring to a getter. In this case it does not + // seem to be a problem since references to a getter don't care whether + // it's a `T` or a `=> T` } else d diff --git a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala index a0adbfe7ba42..ee6938b78248 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeUtils.scala @@ -51,5 +51,17 @@ object TypeUtils { /** The `*:` equivalent of an instance of a Tuple class */ def toNestedPairs(implicit ctx: Context): Type = TypeOps.nestedPairs(tupleElementTypes) + + /** Extract opaque alias from TypeBounds type that combines it with the reference + * to the opaque type itself + */ + def extractOpaqueAlias(implicit ctx: Context): Type = self match { + case TypeBounds(lo, _) => + def extractAlias(tp: Type): Type = tp match { + case OrType(alias, _) => alias + case self: HKTypeLambda => self.derivedLambdaType(resType = extractAlias(self.resType)) + } + extractAlias(lo) + } } } diff --git a/tests/pos/i6286.scala b/tests/pos/i6286.scala new file mode 100644 index 000000000000..bfd20f99f94e --- /dev/null +++ b/tests/pos/i6286.scala @@ -0,0 +1,6 @@ +object A { + opaque type T33 = Int + object T33 { + val a = new Array[T33](3) + } +} \ No newline at end of file diff --git a/tests/pos/i6287.scala b/tests/pos/i6287.scala new file mode 100644 index 000000000000..c9c6f8fca97f --- /dev/null +++ b/tests/pos/i6287.scala @@ -0,0 +1,13 @@ +object O{ + def m() = { + opaque type T = Int + object T + } +} +object A { + { + opaque type T = Int + object T + println + } +} \ No newline at end of file