diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index e27dc791b594..0db1a52b138b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -7,6 +7,7 @@ import ast._ import Trees._, StdNames._, Scopes._, Denotations._, Comments._ import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._ import NameKinds.DefaultGetterName +import TypeApplications.TypeParamInfo import ast.desugar, ast.desugar._ import ProtoTypes._ import util.Spans._ @@ -977,35 +978,25 @@ class Namer { typer: Typer => */ def addForwarder(alias: TermName, mbr: SingleDenotation, span: Span): Unit = if (whyNoForwarder(mbr) == "") { - - /** The info of a forwarder to type `ref` which has info `info` - */ - def fwdInfo(ref: Type, info: Type): Type = info match { - case _: ClassInfo => - HKTypeLambda.fromParams(info.typeParams, ref) - case _: TypeBounds => - TypeAlias(ref) - case info: HKTypeLambda => - info.derivedLambdaType(info.paramNames, info.paramInfos, - fwdInfo(ref.appliedTo(info.paramRefs), info.resultType)) - case info => // should happen only in error cases - info - } - + val sym = mbr.symbol val forwarder = if (mbr.isType) ctx.newSymbol( cls, alias.toTypeName, Exported | Final, - fwdInfo(path.tpe.select(mbr.symbol), mbr.info), + TypeAlias(path.tpe.select(sym)), coord = span) + // Note: This will always create unparameterzied aliases. So even if the original type is + // a parameterized class, say `C[X]` the alias will read `type C = d.C`. We currently do + // allow such type aliases. If we forbid them at some point (requiring the referred type to be + // fully applied), we'd have to change the scheme here as well. else { val (maybeStable, mbrInfo) = - if (mbr.symbol.isStableMember && mbr.symbol.isPublic) - (StableRealizable, ExprType(path.tpe.select(mbr.symbol))) + if (sym.isStableMember && sym.isPublic) + (StableRealizable, ExprType(path.tpe.select(sym))) else (EmptyFlags, mbr.info.ensureMethodic) - val mbrFlags = Exported | Method | Final | maybeStable | mbr.symbol.flags & RetainedExportFlags + val mbrFlags = Exported | Method | Final | maybeStable | sym.flags & RetainedExportFlags ctx.newSymbol(cls, alias, mbrFlags, mbrInfo, coord = span) } forwarder.info = avoidPrivateLeaks(forwarder) @@ -1013,7 +1004,7 @@ class Namer { typer: Typer => if (forwarder.isType) tpd.TypeDef(forwarder.asType) else { import tpd._ - val ref = path.select(mbr.symbol.asTerm) + val ref = path.select(sym.asTerm) tpd.polyDefDef(forwarder.asTerm, targs => prefss => ref.appliedToTypes(targs).appliedToArgss(prefss) ) diff --git a/tests/pos-special/fatal-warnings/i7219.scala b/tests/pos-special/fatal-warnings/i7219.scala new file mode 100644 index 000000000000..903fc0429bf2 --- /dev/null +++ b/tests/pos-special/fatal-warnings/i7219.scala @@ -0,0 +1,18 @@ +object Foo { + enum MyEnum { + case Red + case Blue(msg: String) + } + export MyEnum._ +} + +object Bar { + type Blue = Foo.Blue +} + +import Foo._ + +def foo(a: MyEnum): Seq[Bar.Blue] = a match { + case Red => Seq.empty + case m: Foo.Blue => Seq(m) +} diff --git a/tests/pos-special/fatal-warnings/i7219b.scala b/tests/pos-special/fatal-warnings/i7219b.scala new file mode 100644 index 000000000000..f2fea75771ea --- /dev/null +++ b/tests/pos-special/fatal-warnings/i7219b.scala @@ -0,0 +1,18 @@ +object Foo { + enum MyEnum { + case Red + case Blue(msg: String) + } + export MyEnum._ +} + +object Bar { + export Foo.Blue +} + +import Foo._ + +def foo(a: MyEnum): Seq[Bar.Blue] = a match { + case Red => Seq.empty + case m: Foo.Blue => Seq(m) +} diff --git a/tests/pos/i7219.scala b/tests/pos/i7219.scala new file mode 100644 index 000000000000..8841f953f4a1 --- /dev/null +++ b/tests/pos/i7219.scala @@ -0,0 +1,36 @@ +class Foo { + object MyEnum { + class Blue + } + export MyEnum._ + + val a: MyEnum.Blue = ??? + a : Blue // ok +} + +object Test { + object Types { + type T <: AnyRef + type U = T + type TC[X] <: AnyRef + type UC[X] = TC[(X, X)] + class C + class D[X] extends C + def x1: T = ??? + def x2: U = ??? + def x3: TC[Int] = ??? + def x4: UC[Int] = ??? + def x5: C = C() + def x6: D[Int] = D() + } + export Types._ + type D1 = Types.D + type U1 = Types.UC + + val y1: T = x1 + val y2: U = x2 + val y3: TC[Int] = x3 + val y4: UC[Int] = x4 + val y5: C = x5 + val y6: D[Int] = x6 +}