Skip to content

Commit 80880d5

Browse files
committed
Simplify and fix type forwarders
The previous scheme did not work correctly for forwarding classes. the previous commit fixed that for unparameterized classes, but parameterized classes still had a problem, The current scheme is far simpler since it always uses unparameterized aliases.
1 parent 3d3021c commit 80880d5

File tree

2 files changed

+38
-21
lines changed

2 files changed

+38
-21
lines changed

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

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import ast._
77
import Trees._, StdNames._, Scopes._, Denotations._, Comments._
88
import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
99
import NameKinds.DefaultGetterName
10+
import TypeApplications.TypeParamInfo
1011
import ast.desugar, ast.desugar._
1112
import ProtoTypes._
1213
import util.Spans._
@@ -977,44 +978,33 @@ class Namer { typer: Typer =>
977978
*/
978979
def addForwarder(alias: TermName, mbr: SingleDenotation, span: Span): Unit =
979980
if (whyNoForwarder(mbr) == "") {
980-
981-
/** The info of a forwarder to type `ref` which has info `info`
982-
*/
983-
def fwdInfo(ref: Type, info: Type): Type = info match {
984-
case _: ClassInfo =>
985-
if (info.typeParams.isEmpty) TypeAlias(ref)
986-
else HKTypeLambda.fromParams(info.typeParams, ref)
987-
case _: TypeBounds =>
988-
TypeAlias(ref)
989-
case info: HKTypeLambda =>
990-
info.derivedLambdaType(info.paramNames, info.paramInfos,
991-
fwdInfo(ref.appliedTo(info.paramRefs), info.resultType))
992-
case info => // should happen only in error cases
993-
info
994-
}
995-
981+
val sym = mbr.symbol
996982
val forwarder =
997983
if (mbr.isType)
998984
ctx.newSymbol(
999985
cls, alias.toTypeName,
1000986
Exported | Final,
1001-
fwdInfo(path.tpe.select(mbr.symbol), mbr.info),
987+
TypeAlias(path.tpe.select(sym)),
1002988
coord = span)
989+
// Note: This will always create unparameterzied aliases. So even if the original type is
990+
// a parameterized class, say `C[X]` the alias will read `type C = d.C`. We currently do
991+
// allow such type aliases. If we forbid them at some point (requiring the referred type to be
992+
// fully applied), we'd have to change the scheme here as well.
1003993
else {
1004994
val (maybeStable, mbrInfo) =
1005-
if (mbr.symbol.isStableMember && mbr.symbol.isPublic)
1006-
(StableRealizable, ExprType(path.tpe.select(mbr.symbol)))
995+
if (sym.isStableMember && sym.isPublic)
996+
(StableRealizable, ExprType(path.tpe.select(sym)))
1007997
else
1008998
(EmptyFlags, mbr.info.ensureMethodic)
1009-
val mbrFlags = Exported | Method | Final | maybeStable | mbr.symbol.flags & RetainedExportFlags
999+
val mbrFlags = Exported | Method | Final | maybeStable | sym.flags & RetainedExportFlags
10101000
ctx.newSymbol(cls, alias, mbrFlags, mbrInfo, coord = span)
10111001
}
10121002
forwarder.info = avoidPrivateLeaks(forwarder)
10131003
val forwarderDef =
10141004
if (forwarder.isType) tpd.TypeDef(forwarder.asType)
10151005
else {
10161006
import tpd._
1017-
val ref = path.select(mbr.symbol.asTerm)
1007+
val ref = path.select(sym.asTerm)
10181008
tpd.polyDefDef(forwarder.asTerm, targs => prefss =>
10191009
ref.appliedToTypes(targs).appliedToArgss(prefss)
10201010
)

tests/pos/i7219.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,30 @@ class Foo {
77
val a: MyEnum.Blue = ???
88
a : Blue // ok
99
}
10+
11+
object Test {
12+
object Types {
13+
type T <: AnyRef
14+
type U = T
15+
type TC[X] <: AnyRef
16+
type UC[X] = TC[(X, X)]
17+
class C
18+
class D[X] extends C
19+
def x1: T = ???
20+
def x2: U = ???
21+
def x3: TC[Int] = ???
22+
def x4: UC[Int] = ???
23+
def x5: C = C()
24+
def x6: D[Int] = D()
25+
}
26+
export Types._
27+
type D1 = Types.D
28+
type U1 = Types.UC
29+
30+
val y1: T = x1
31+
val y2: U = x2
32+
val y3: TC[Int] = x3
33+
val y4: UC[Int] = x4
34+
val y5: C = x5
35+
val y6: D[Int] = x6
36+
}

0 commit comments

Comments
 (0)