Skip to content

Commit 1fcdd0d

Browse files
committed
Cleanups
- Add documentation - Drop debug code - Tweak what we do in the TypeVar case to align with interpolation.
1 parent c9b30ac commit 1fcdd0d

File tree

1 file changed

+19
-93
lines changed

1 file changed

+19
-93
lines changed

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

Lines changed: 19 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,19 @@ trait TypeAssigner {
6464
}
6565

6666
/** An upper approximation of the given type `tp` that does not refer to any symbol in `symsToAvoid`.
67+
* We need to approximate with ranges:
68+
*
69+
* term references to symbols in `symsToAvoid`,
70+
* term references that have a widened type of which some part refers
71+
* to a symbol in `symsToAvoid`,
72+
* type references to symbols in `symsToAvoid`,
73+
* this types of classes in `symsToAvoid`.
74+
*
75+
* Type variables that would be interpolated to a type that
76+
* needs to be widened are replaced by the widened interpolation instance.
6777
*/
6878
def avoid(tp: Type, symsToAvoid: => List[Symbol])(implicit ctx: Context): Type = {
69-
val wmap = new ApproximatingTypeMap {
79+
val widenMap = new ApproximatingTypeMap {
7080
lazy val forbidden = symsToAvoid.toSet
7181
def toAvoid(sym: Symbol) = !sym.isStatic && forbidden.contains(sym)
7282
def partsToAvoid = new NamedPartsAccumulator(tp => toAvoid(tp.symbol))
@@ -92,23 +102,18 @@ trait TypeAssigner {
92102
case tp: ThisType if toAvoid(tp.cls) =>
93103
range(tp.bottomType, apply(classBound(tp.cls.classInfo)))
94104
case tp: TypeVar if ctx.typerState.constraint.contains(tp) =>
95-
val lo = ctx.typeComparer.instanceType(tp.origin, fromBelow = true)
105+
val lo = ctx.typeComparer.instanceType(tp.origin, fromBelow = variance >= 0)
96106
val lo1 = apply(lo)
97-
//println(i"INST $tp --> $lo --> $lo1")
98107
if (lo1 ne lo) lo1 else tp
99-
case tp: TermRef if false =>
100-
val saved = variance
101-
variance = 0
102-
val prefix1 = this(tp.prefix)
103-
variance = saved
104-
if (isRange(prefix1)) range(tp.bottomType, apply(tp.info.widenExpr))
105-
else derivedSelect(tp, prefix1)
106108
case _ =>
107109
mapOver(tp)
108110
}
109111

110-
/** Needs to handle the case where the prefix type does not have a member
111-
* named `tp.name` anymmore.
112+
/** Two deviations from standard derivedSelect:
113+
* 1. The teh approximation result is a singleton references C#x.type, we
114+
* replace by the widened type, which is usually more natural.
115+
* 2. We need to handle the case where the prefix type does not have a member
116+
* named `tp.name` anymmore.
112117
*/
113118
override def derivedSelect(tp: NamedType, pre: Type) =
114119
if (pre eq tp.prefix) tp
@@ -117,87 +122,8 @@ trait TypeAssigner {
117122
else if (upper(pre).member(tp.name).exists) super.derivedSelect(tp, pre)
118123
else range(tp.bottomType, tp.topType)
119124
}
120-
val widenMap = new TypeMap {
121-
lazy val forbidden = symsToAvoid.toSet
122-
def toAvoid(tp: Type): Boolean =
123-
// TODO: measure the cost of using `existsPart`, and if necessary replace it
124-
// by a `TypeAccumulator` where we have set `stopAtStatic = true`.
125-
tp existsPart {
126-
case tp: TermRef => forbidden.contains(tp.symbol) || toAvoid(tp.underlying)
127-
case tp: TypeRef => forbidden.contains(tp.symbol)
128-
case tp: ThisType => forbidden.contains(tp.cls)
129-
case _ => false
130-
}
131-
def apply(tp: Type): Type = tp match {
132-
case tp: TermRef
133-
if toAvoid(tp) && (variance > 0 || tp.info.widenExpr <:< tp) =>
134-
// Can happen if `x: y.type`, then `x.type =:= y.type`, hence we can widen `x.type`
135-
// to y.type in all contexts, not just covariant ones.
136-
apply(tp.info.widenExpr)
137-
case tp: TypeRef if toAvoid(tp) =>
138-
tp.info match {
139-
case TypeAlias(ref) =>
140-
apply(ref)
141-
case info: ClassInfo if variance > 0 =>
142-
if (!(forbidden contains tp.symbol)) {
143-
val prefix = apply(tp.prefix)
144-
val tp1 = tp.derivedSelect(prefix)
145-
if (tp1.typeSymbol.exists)
146-
return tp1
147-
}
148-
val parentType = info.parentsWithArgs.reduceLeft(ctx.typeComparer.andType(_, _))
149-
def addRefinement(parent: Type, decl: Symbol) = {
150-
val inherited =
151-
parentType.findMember(decl.name, info.cls.thisType, Private)
152-
.suchThat(decl.matches(_))
153-
val inheritedInfo = inherited.info
154-
if (inheritedInfo.exists && decl.info <:< inheritedInfo && !(inheritedInfo <:< decl.info)) {
155-
val r = RefinedType(parent, decl.name, decl.info)
156-
typr.println(i"add ref $parent $decl --> " + r)
157-
r
158-
}
159-
else
160-
parent
161-
}
162-
val refinableDecls = info.decls.filter(
163-
sym => !(sym.is(TypeParamAccessor | Private) || sym.isConstructor))
164-
val fullType = (parentType /: refinableDecls)(addRefinement)
165-
apply(fullType)
166-
case TypeBounds(lo, hi) if variance > 0 =>
167-
apply(hi)
168-
case _ =>
169-
mapOver(tp)
170-
}
171-
case tp @ HKApply(tycon, args) if toAvoid(tycon) =>
172-
apply(tp.superType)
173-
case tp @ AppliedType(tycon, args) if toAvoid(tycon) =>
174-
val base = apply(tycon)
175-
var args = tp.baseArgInfos(base.typeSymbol)
176-
if (base.typeParams.length != args.length)
177-
args = base.typeParams.map(_.paramInfo)
178-
apply(base.appliedTo(args))
179-
case tp @ RefinedType(parent, name, rinfo) if variance > 0 =>
180-
val parent1 = apply(tp.parent)
181-
val refinedInfo1 = apply(rinfo)
182-
if (toAvoid(refinedInfo1)) {
183-
typr.println(s"dropping refinement from $tp")
184-
if (name.isTypeName) tp.derivedRefinedType(parent1, name, TypeBounds.empty)
185-
else parent1
186-
} else {
187-
tp.derivedRefinedType(parent1, name, refinedInfo1)
188-
}
189-
case tp: TypeVar if ctx.typerState.constraint.contains(tp) =>
190-
val lo = ctx.typerState.constraint.fullLowerBound(tp.origin)
191-
val lo1 = avoid(lo, symsToAvoid)
192-
if (lo1 ne lo) lo1 else tp
193-
case _ =>
194-
mapOver(tp)
195-
}
196-
}
197-
//val was = widenMap(tp)
198-
val now = wmap(tp)
199-
//if (was.show != now.show) println(i"difference for avoid $tp, ${tp.toString}, forbidden = $symsToAvoid%, %, was: $was, now: $now")
200-
now
125+
126+
widenMap(tp)
201127
}
202128

203129
def avoidingType(expr: Tree, bindings: List[Tree])(implicit ctx: Context): Type =

0 commit comments

Comments
 (0)