Skip to content

Commit 775eb8a

Browse files
committed
Abstract type parameters out from type symbols
In the new hk scheme, a type parameter can be represented by a refinement without a corresponding symbol. Therefore, we need to disentangle the info inherent in a type parameter from the contents of a type symbol. We achieve this by creating a common super trait "MemerInfo" of Symbol and RefinedType.
1 parent 033a521 commit 775eb8a

10 files changed

+68
-27
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dotty.tools.dotc.core
2+
3+
import Names.Name
4+
import Contexts.Context
5+
import Types.Type
6+
7+
/** The common info associated with a member symbol and a refinement */
8+
trait MemberInfo {
9+
10+
def exists(implicit ctx: Context): Boolean
11+
12+
def memberName(implicit ctx: Context): Name
13+
14+
def memberInfo(implicit ctx: Context): Type
15+
16+
def memberInfoAsSeenFrom(pre: Type)(implicit ctx: Context): Type
17+
18+
def memberVariance(implicit ctx: Context): Int
19+
20+
21+
}

src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ object Symbols {
367367
* @param coord The coordinates of the symbol (a position or an index)
368368
* @param id A unique identifier of the symbol (unique per ContextBase)
369369
*/
370-
class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with printing.Showable {
370+
class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with MemberInfo with printing.Showable {
371371

372372
type ThisName <: Name
373373

@@ -489,6 +489,13 @@ object Symbols {
489489
*/
490490
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
491491

492+
// MemberInfo methods
493+
def exists(implicit ctx: Context) = denot.exists
494+
def memberName(implicit ctx: Context): Name = name
495+
def memberInfo(implicit ctx: Context) = denot.info
496+
def memberInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this)
497+
def memberVariance(implicit ctx: Context) = denot.variance
498+
492499
// -------- Printing --------------------------------------------------------
493500

494501
/** The prefix string to be used when displaying this symbol without denotation */

src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ object TypeApplications {
7575
/** Does the variance of `sym1` conform to the variance of `sym2`?
7676
* This is the case if the variances are the same or `sym` is nonvariant.
7777
*/
78-
def varianceConforms(sym1: TypeSymbol, sym2: TypeSymbol)(implicit ctx: Context) =
79-
sym1.variance == sym2.variance || sym2.variance == 0
78+
def varianceConforms(sym1: MemberInfo, sym2: MemberInfo)(implicit ctx: Context) =
79+
sym1.memberVariance == sym2.memberVariance || sym2.memberVariance == 0
8080

81-
def variancesConform(syms1: List[TypeSymbol], syms2: List[TypeSymbol])(implicit ctx: Context) =
81+
def variancesConform(syms1: List[MemberInfo], syms2: List[MemberInfo])(implicit ctx: Context) =
8282
syms1.corresponds(syms2)(varianceConforms)
8383

8484
/** Extractor for
@@ -143,7 +143,7 @@ object TypeApplications {
143143
object EtaExpansion {
144144
def apply(tycon: TypeRef)(implicit ctx: Context) = {
145145
assert(tycon.isEtaExpandable)
146-
tycon.EtaExpand(tycon.typeParams)
146+
tycon.EtaExpand(tycon.typeParamSymbols)
147147
}
148148

149149
def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = {
@@ -280,7 +280,7 @@ class TypeApplications(val self: Type) extends AnyVal {
280280
* with the bounds on its hk args. See `LambdaAbstract`, where these
281281
* types get introduced, and see `isBoundedLambda` below for the test.
282282
*/
283-
final def typeParams(implicit ctx: Context): List[TypeSymbol] = /*>|>*/ track("typeParams") /*<|<*/ {
283+
final def typeParams(implicit ctx: Context): List[MemberInfo] = /*>|>*/ track("typeParams") /*<|<*/ {
284284
self match {
285285
case self: ClassInfo =>
286286
self.cls.typeParams
@@ -309,7 +309,7 @@ class TypeApplications(val self: Type) extends AnyVal {
309309
val sym = self.parent.classSymbol
310310
if (sym.isLambdaTrait) return sym.typeParams
311311
}
312-
self.parent.typeParams.filterNot(_.name == self.refinedName)
312+
self.parent.typeParams.filterNot(_.memberName == self.refinedName)
313313
case self: SingletonType =>
314314
Nil
315315
case self: TypeProxy =>
@@ -319,6 +319,12 @@ class TypeApplications(val self: Type) extends AnyVal {
319319
}
320320
}
321321

322+
final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = {
323+
val tparams = typeParams
324+
assert(tparams.isEmpty || tparams.head.isInstanceOf[Symbol])
325+
tparams.asInstanceOf[List[TypeSymbol]]
326+
}
327+
322328
/** The named type parameters declared or inherited by this type.
323329
* These are all uninstantiated named type parameters of this type or one
324330
* of its base types.
@@ -498,7 +504,7 @@ class TypeApplications(val self: Type) extends AnyVal {
498504
* v1 is compatible with v2, if v1 = v2 or v2 is non-variant.
499505
*/
500506
def EtaExpand(tparams: List[TypeSymbol])(implicit ctx: Context): Type = {
501-
val tparamsToUse = if (variancesConform(typeParams, tparams)) tparams else typeParams
507+
val tparamsToUse = if (variancesConform(typeParams, tparams)) tparams else typeParamSymbols
502508
self.appliedTo(tparams map (_.typeRef)).LambdaAbstract(tparamsToUse)
503509
//.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
504510
}
@@ -508,7 +514,7 @@ class TypeApplications(val self: Type) extends AnyVal {
508514
case self: RefinedType =>
509515
self.derivedRefinedType(self.parent.EtaExpandCore, self.refinedName, self.refinedInfo)
510516
case _ =>
511-
self.EtaExpand(self.typeParams)
517+
self.EtaExpand(self.typeParamSymbols)
512518
}
513519

514520
/** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
@@ -621,12 +627,12 @@ class TypeApplications(val self: Type) extends AnyVal {
621627
* @param args = `U1, ..., Un`
622628
* @param tparams are assumed to be the type parameters of `T`.
623629
*/
624-
final def appliedTo(args: List[Type], typParams: List[TypeSymbol])(implicit ctx: Context): Type = {
625-
def matchParams(t: Type, tparams: List[TypeSymbol], args: List[Type])(implicit ctx: Context): Type = args match {
630+
final def appliedTo(args: List[Type], typParams: List[MemberInfo])(implicit ctx: Context): Type = {
631+
def matchParams(t: Type, tparams: List[MemberInfo], args: List[Type])(implicit ctx: Context): Type = args match {
626632
case arg :: args1 =>
627633
try {
628634
val tparam :: tparams1 = tparams
629-
matchParams(RefinedType(t, tparam.name, arg.toBounds(tparam)), tparams1, args1)
635+
matchParams(RefinedType(t, tparam.memberName, arg.toBounds(tparam)), tparams1, args1)
630636
} catch {
631637
case ex: MatchError =>
632638
println(s"applied type mismatch: $self $args, typeParams = $typParams") // !!! DEBUG
@@ -667,11 +673,11 @@ class TypeApplications(val self: Type) extends AnyVal {
667673
/** Turn this type, which is used as an argument for
668674
* type parameter `tparam`, into a TypeBounds RHS
669675
*/
670-
final def toBounds(tparam: Symbol)(implicit ctx: Context): TypeBounds = self match {
676+
final def toBounds(tparam: MemberInfo)(implicit ctx: Context): TypeBounds = self match {
671677
case self: TypeBounds => // this can happen for wildcard args
672678
self
673679
case _ =>
674-
val v = tparam.variance
680+
val v = tparam.memberVariance
675681
/* Not neeeded.
676682
if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self)
677683
else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self)

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
534534
* - the type parameters of `B` match one-by-one the variances of `tparams`,
535535
* - `B` satisfies predicate `p`.
536536
*/
537-
private def testLifted(tp1: Type, tp2: Type, tparams: List[TypeSymbol], p: Type => Boolean): Boolean = {
537+
private def testLifted(tp1: Type, tp2: Type, tparams: List[MemberInfo], p: Type => Boolean): Boolean = {
538538
val classBounds = tp2.member(tpnme.hkApply).info.classSymbols
539539
def recur(bcs: List[ClassSymbol]): Boolean = bcs match {
540540
case bc :: bcs1 =>
@@ -647,7 +647,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
647647
}
648648
}
649649

650-
/** Replace any top-level recursive type `{ z => T }` in `tp` with
650+
/** Replace any top-level recursive type `{ z => T }` in `tp` with
651651
* `[z := anchor]T`.
652652
*/
653653
private def fixRecs(anchor: SingletonType, tp: Type): Type = {
@@ -1117,8 +1117,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
11171117
* in where we allow which interpretation.
11181118
*/
11191119
private def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type) = {
1120-
val tparams1 = tp1.typeParams
1121-
val tparams2 = tp2.typeParams
1120+
val tparams1 = tp1.typeParamSymbols // TODO revise for new hk scheme
1121+
val tparams2 = tp2.typeParamSymbols
11221122
def onlyNamed(tparams: List[TypeSymbol]) = tparams.forall(!_.is(ExpandedName))
11231123
if (tparams1.isEmpty || tparams2.isEmpty ||
11241124
onlyNamed(tparams1) && onlyNamed(tparams2)) op(tp1, tp2)

src/dotty/tools/dotc/core/Types.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ object Types {
861861
def isParamName = tp.classSymbol.typeParams.exists(_.name == tp.refinedName)
862862
if (refinementOK || isParamName) tp.underlying.underlyingClassRef(refinementOK)
863863
else NoType
864-
case tp: RecType if refinementOK => tp.parent
864+
case tp: RecType if refinementOK => tp.parent
865865
case _ => NoType
866866
}
867867

@@ -2043,7 +2043,7 @@ object Types {
20432043
* given the refined type itself.
20442044
*/
20452045
abstract case class RefinedType(private var myParent: Type, refinedName: Name, private var myRefinedInfo: Type)
2046-
extends RefinedOrRecType with BindingType {
2046+
extends RefinedOrRecType with BindingType with MemberInfo {
20472047

20482048
final def parent = myParent
20492049
final def refinedInfo = myRefinedInfo
@@ -2082,6 +2082,13 @@ object Types {
20822082
if (parent.member(refinedName).exists) derivedRefinedType(parent, refinedName, refinedInfo)
20832083
else parent
20842084

2085+
// MemberInfo methods
2086+
def exists(implicit ctx: Context) = true
2087+
def memberName(implicit ctx: Context) = refinedName
2088+
def memberInfo(implicit ctx: Context) = refinedInfo
2089+
def memberInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = refinedInfo
2090+
def memberVariance(implicit ctx: Context) = BindingKind.toVariance(refinedInfo.bounds.bindingKind)
2091+
20852092
override def equals(that: Any) = that match {
20862093
case that: RefinedType =>
20872094
this.parent == that.parent &&

src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class ClassfileParser(
272272
if (sig(index) == '<') {
273273
accept('<')
274274
var tp1: Type = tp
275-
var formals = tp.typeParams
275+
var formals = tp.typeParamSymbols
276276
while (sig(index) != '>') {
277277
sig(index) match {
278278
case variance @ ('+' | '-' | '*') =>

src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ trait ImplicitRunInfo { self: RunInfo =>
322322
}
323323
def addParentScope(parent: TypeRef): Unit = {
324324
iscopeRefs(parent) foreach addRef
325-
for (param <- parent.typeParams)
325+
for (param <- parent.typeParamSymbols)
326326
comps ++= iscopeRefs(pre.member(param.name).info)
327327
}
328328
val companion = cls.companionModule

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ class Namer { typer: Typer =>
989989
if (args.nonEmpty) {
990990
val tycon = tp.withoutArgs(args)
991991
val tycon1 = this(tycon)
992-
val tparams = tycon.typeParams
992+
val tparams = tycon.typeParamSymbols
993993
val args1 = if (args.length == tparams.length) etaExpandIfHK(tparams, args) else args
994994
if ((tycon1 eq tycon) && (args1 eq args)) tp else tycon1.appliedTo(args1)
995995
} else mapOver(tp)

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ trait TypeAssigner {
409409
def refineNamed(tycon: Type, arg: Tree) = arg match {
410410
case ast.Trees.NamedArg(name, argtpt) =>
411411
// Dotty deviation: importing ast.Trees._ and matching on NamedArg gives a cyclic ref error
412-
val tparam = tparams.find(_.name == name) match {
412+
val tparam = tparams.find(_.memberName == name) match {
413413
case Some(tparam) => tparam
414414
case none => ntparams.find(_.name == name).getOrElse(NoSymbol)
415415
}

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -934,14 +934,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
934934
ctx.error(d"wrong number of type arguments for ${tpt1.tpe}, should be ${tparams.length}", tree.pos)
935935
args = args.take(tparams.length)
936936
}
937-
def typedArg(arg: untpd.Tree, tparam: Symbol) = {
937+
def typedArg(arg: untpd.Tree, tparam: MemberInfo) = {
938938
val (desugaredArg, argPt) =
939939
if (ctx.mode is Mode.Pattern)
940-
(if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.info)
940+
(if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.memberInfo)
941941
else
942942
(arg, WildcardType)
943943
val arg1 = typed(desugaredArg, argPt)
944-
adaptTypeArg(arg1, tparam.info)
944+
adaptTypeArg(arg1, tparam.memberInfo)
945945
}
946946
args.zipWithConserve(tparams)(typedArg(_, _)).asInstanceOf[List[Tree]]
947947
}

0 commit comments

Comments
 (0)