Skip to content

Commit 20673f4

Browse files
committed
Handle AnnotatedTypes transparently like their underlying type
In Erasure, all type annotations are dropped (AnnotatedTypes are replaced with their underlying).
1 parent d9a013c commit 20673f4

24 files changed

+182
-152
lines changed

src/dotty/tools/dotc/TypeErasure.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ object TypeErasure {
3838
case JavaArrayType(elem) =>
3939
isErasedType(elem)
4040
case AnnotatedType(_, tp) =>
41-
isErasedType(tp)
41+
false
4242
case ThisType(tref) =>
4343
isErasedType(tref)
4444
case tp: MethodType =>
@@ -105,7 +105,7 @@ object TypeErasure {
105105
/** The erasure of a top-level reference. Differs from normal erasure in that
106106
* TermRefs are kept instead of being widened away.
107107
*/
108-
def erasedRef(tp: Type)(implicit ctx: Context): Type = tp match {
108+
def erasedRef(tp: Type)(implicit ctx: Context): Type = tp.stripAnnots match {
109109
case tp: TermRef =>
110110
assert(tp.symbol.exists, tp)
111111
val tp1 = ctx.makePackageObjPrefixExplicit(tp)
@@ -160,7 +160,7 @@ object TypeErasure {
160160
* as upper bound and that is not Java defined? Arrays of such types are
161161
* erased to `Object` instead of `ObjectArray`.
162162
*/
163-
def isUnboundedGeneric(tp: Type)(implicit ctx: Context): Boolean = tp.dealias match {
163+
def isUnboundedGeneric(tp: Type)(implicit ctx: Context): Boolean = tp.dealias.stripAnnots match {
164164
case tp: TypeRef =>
165165
!tp.symbol.isClass &&
166166
!tp.derivesFrom(defn.ObjectClass) &&
@@ -186,14 +186,14 @@ object TypeErasure {
186186
* come after S.
187187
* (the reason to pick last is that we prefer classes over traits that way).
188188
*/
189-
def erasedLub(tp1: Type, tp2: Type)(implicit ctx: Context): Type = tp1 match {
189+
def erasedLub(tp1: Type, tp2: Type)(implicit ctx: Context): Type = tp1.stripAnnots match {
190190
case JavaArrayType(elem1) =>
191-
tp2 match {
191+
tp2.stripAnnots match {
192192
case JavaArrayType(elem2) => JavaArrayType(erasedLub(elem1, elem2))
193193
case _ => defn.ObjectType
194194
}
195195
case _ =>
196-
tp2 match {
196+
tp2.stripAnnots match {
197197
case JavaArrayType(_) => defn.ObjectType
198198
case _ =>
199199
val cls2 = tp2.classSymbol
@@ -216,14 +216,14 @@ object TypeErasure {
216216
* - subtypes over supertypes, unless isJava is set
217217
* - real classes over traits
218218
*/
219-
def erasedGlb(tp1: Type, tp2: Type, isJava: Boolean)(implicit ctx: Context): Type = tp1 match {
219+
def erasedGlb(tp1: Type, tp2: Type, isJava: Boolean)(implicit ctx: Context): Type = tp1.stripAnnots match {
220220
case JavaArrayType(elem1) =>
221-
tp2 match {
221+
tp2.stripAnnots match {
222222
case JavaArrayType(elem2) => JavaArrayType(erasedGlb(elem1, elem2, isJava))
223223
case _ => tp1
224224
}
225225
case _ =>
226-
tp2 match {
226+
tp2.stripAnnots match {
227227
case JavaArrayType(_) => tp2
228228
case _ =>
229229
val tsym1 = tp1.typeSymbol
@@ -346,7 +346,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
346346
else JavaArrayType(this(elemtp))
347347
}
348348

349-
def eraseInfo(tp: Type, sym: Symbol)(implicit ctx: Context) = tp match {
349+
def eraseInfo(tp: Type, sym: Symbol)(implicit ctx: Context) = tp.stripAnnots match {
350350
case ExprType(rt) =>
351351
if (sym is Param) apply(tp)
352352
// Note that params with ExprTypes are eliminated by ElimByName,
@@ -365,7 +365,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
365365
(if (cls.owner is Package) normalizeClass(cls) else cls).typeRef
366366
}
367367

368-
private def eraseResult(tp: Type)(implicit ctx: Context): Type = tp match {
368+
private def eraseResult(tp: Type)(implicit ctx: Context): Type = tp.stripAnnots match {
369369
case tp: TypeRef =>
370370
val sym = tp.typeSymbol
371371
if (sym eq defn.UnitClass) sym.typeRef

src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
359359
/** Is symbol potentially a getter of a mutable variable?
360360
*/
361361
def mayBeVarGetter(sym: Symbol)(implicit ctx: Context): Boolean = {
362-
def maybeGetterType(tpe: Type): Boolean = tpe match {
362+
def maybeGetterType(tpe: Type): Boolean = tpe.stripAnnots match {
363363
case _: ExprType | _: ImplicitMethodType => true
364364
case tpe: PolyType => maybeGetterType(tpe.resultType)
365365
case _ => false

src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ final class TreeTypeMap(
8989
case tree1 =>
9090
tree1.withType(mapType(tree1.tpe)) match {
9191
case id: Ident if tpd.needsSelect(id.tpe) =>
92-
ref(id.tpe.asInstanceOf[TermRef]).withPos(id.pos)
92+
ref(id.tpe.stripAnnots.asInstanceOf[TermRef]).withPos(id.pos)
9393
case ddef @ DefDef(name, tparams, vparamss, tpt, rhs) =>
9494
val (tmap1, tparams1) = transformDefs(ddef.tparams)
9595
val (tmap2, vparamss1) = tmap1.transformVParamss(vparamss)

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
177177
polyDefDef(sym, Function.const(rhsFn))
178178

179179
def polyDefDef(sym: TermSymbol, rhsFn: List[Type] => List[List[Tree]] => Tree)(implicit ctx: Context): DefDef = {
180-
val (tparams, mtp) = sym.info match {
180+
val (tparams, mtp) = sym.info.stripAnnots match {
181181
case tp: PolyType =>
182182
val tparams = ctx.newTypeParams(sym, tp.paramNames, EmptyFlags, tp.instantiateBounds)
183183
(tparams, tp.instantiate(tparams map (_.typeRef)))
184184
case tp => (Nil, tp)
185185
}
186186

187-
def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match {
187+
def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp.stripAnnots match {
188188
case tp @ MethodType(paramNames, paramTypes) =>
189189
def valueParam(name: TermName, info: Type): TermSymbol =
190190
ctx.newSymbol(sym, name, TermParam, info)
@@ -256,7 +256,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
256256
// ------ Making references ------------------------------------------------------
257257

258258
def prefixIsElidable(tp: NamedType)(implicit ctx: Context) = {
259-
def test(implicit ctx: Context) = tp.prefix match {
259+
def test(implicit ctx: Context) = tp.prefix.stripAnnots match {
260260
case NoPrefix =>
261261
true
262262
case pre: ThisType =>
@@ -273,7 +273,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
273273
}
274274
}
275275

276-
def needsSelect(tp: Type)(implicit ctx: Context) = tp match {
276+
def needsSelect(tp: Type)(implicit ctx: Context) = tp.stripAnnots match {
277277
case tp: TermRef => !prefixIsElidable(tp)
278278
case _ => false
279279
}
@@ -282,15 +282,15 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
282282
def ref(tp: NamedType)(implicit ctx: Context): Tree =
283283
if (tp.isType) TypeTree(tp)
284284
else if (prefixIsElidable(tp)) Ident(tp)
285-
else tp.prefix match {
285+
else tp.prefix.stripAnnots match {
286286
case pre: SingletonType => singleton(pre).select(tp)
287287
case pre => SelectFromTypeTree(TypeTree(pre), tp)
288288
} // no checks necessary
289289

290290
def ref(sym: Symbol)(implicit ctx: Context): Tree =
291291
ref(NamedType(sym.owner.thisType, sym.name, sym.denot))
292292

293-
def singleton(tp: Type)(implicit ctx: Context): Tree = tp match {
293+
def singleton(tp: Type)(implicit ctx: Context): Tree = tp.stripAnnots match {
294294
case tp: TermRef => ref(tp)
295295
case tp: ThisType => This(tp.cls)
296296
case SuperType(qual, _) => singleton(qual)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ object Denotations {
382382

383383
final def signature(implicit ctx: Context): Signature = {
384384
if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation
385-
else info match {
385+
else info.stripAnnots match {
386386
case info: MethodicType =>
387387
try info.signature
388388
catch { // !!! DEBUG

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ object SymDenotations {
510510
/** Is `pre` the same as C.thisThis, where C is exactly the owner of this symbol,
511511
* or, if this symbol is protected, a subclass of the owner?
512512
*/
513-
def isCorrectThisType(pre: Type): Boolean = pre match {
513+
def isCorrectThisType(pre: Type): Boolean = pre.stripAnnots match {
514514
case pre: ThisType =>
515515
(pre.cls eq owner) || (this is Protected) && pre.cls.derivesFrom(owner)
516516
case pre: TermRef =>
@@ -573,7 +573,7 @@ object SymDenotations {
573573
!( this.isTerm
574574
|| this.isStaticOwner
575575
|| ctx.erasedTypes
576-
|| (pre eq NoPrefix) || (pre eq thisType)
576+
|| (pre.stripAnnots eq NoPrefix) || (pre.stripAnnots eq thisType.stripAnnots)
577577
)
578578

579579
/** Is this symbol concrete, or that symbol deferred? */
@@ -617,7 +617,7 @@ object SymDenotations {
617617
/** The class implementing this module, NoSymbol if not applicable. */
618618
final def moduleClass(implicit ctx: Context): Symbol =
619619
if (this is ModuleVal)
620-
myInfo match {
620+
myInfo.stripAnnots match {
621621
case info: TypeRef => info.symbol
622622
case ExprType(info: TypeRef) => info.symbol // needed after uncurry, when module terms might be accessor defs
623623
case info: LazyType => info.moduleClass
@@ -626,7 +626,7 @@ object SymDenotations {
626626
else NoSymbol
627627

628628
/** The module implemented by this module class, NoSymbol if not applicable. */
629-
final def sourceModule(implicit ctx: Context): Symbol = myInfo match {
629+
final def sourceModule(implicit ctx: Context): Symbol = myInfo.stripAnnots match {
630630
case ClassInfo(_, _, _, _, selfType: TermRef) if this is ModuleClass =>
631631
selfType.symbol
632632
case info: LazyType =>
@@ -1363,6 +1363,7 @@ object SymDenotations {
13631363
case tp: TypeVar => tp.inst.exists && inCache(tp.inst)
13641364
case tp: TypeProxy => inCache(tp.underlying)
13651365
case tp: AndOrType => inCache(tp.tp1) && inCache(tp.tp2)
1366+
case tp: AnnotatedType => isCachable(tp.tpe)
13661367
case _ => true
13671368
}
13681369

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,9 @@ class TypeApplications(val self: Type) extends AnyVal {
250250
*/
251251
final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"btwa ${self.show} wrt $base", core, show = true) {
252252
def default = self.baseTypeRef(base).appliedTo(baseArgInfos(base))
253-
self match {
253+
self.stripAnnots match {
254254
case tp: TypeRef =>
255-
tp.info match {
255+
tp.info.stripAnnots match {
256256
case TypeBounds(_, hi) => hi.baseTypeWithArgs(base)
257257
case _ => default
258258
}
@@ -297,7 +297,7 @@ class TypeApplications(val self: Type) extends AnyVal {
297297
*/
298298
final def argInfos(interpolate: Boolean)(implicit ctx: Context): List[Type] = {
299299
var tparams: List[TypeSymbol] = null
300-
def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar match {
300+
def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar.stripAnnots match {
301301
case tp @ RefinedType(tycon, name) =>
302302
val buf = recur(tycon, refineCount + 1)
303303
if (buf == null) null
@@ -352,7 +352,7 @@ class TypeApplications(val self: Type) extends AnyVal {
352352
*
353353
* for a contravariant type-parameter becomes L.
354354
*/
355-
final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self match {
355+
final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self.stripAnnots match {
356356
case self: TypeAlias => self.alias
357357
case TypeBounds(lo, hi) =>
358358
if (interpolate) {
@@ -367,14 +367,14 @@ class TypeApplications(val self: Type) extends AnyVal {
367367
}
368368

369369
/** The element type of a sequence or array */
370-
def elemType(implicit ctx: Context): Type = self match {
370+
def elemType(implicit ctx: Context): Type = self.stripAnnots match {
371371
case defn.ArrayType(elemtp) => elemtp
372372
case JavaArrayType(elemtp) => elemtp
373373
case _ => firstBaseArgInfo(defn.SeqClass)
374374
}
375375

376376
def containsSkolemType(target: Type)(implicit ctx: Context): Boolean = {
377-
def recur(tp: Type): Boolean = tp.stripTypeVar match {
377+
def recur(tp: Type): Boolean = tp.stripTypeVar.stripAnnots match {
378378
case SkolemType(tp) =>
379379
tp eq target
380380
case tp: NamedType =>
@@ -434,7 +434,7 @@ class TypeApplications(val self: Type) extends AnyVal {
434434
for (sym <- boundSyms)
435435
yield TypeRef(SkolemType(rt), correspondingParamName(sym))
436436

437-
def rewrite(tp: Type): Type = tp match {
437+
def rewrite(tp: Type): Type = tp.stripAnnots match {
438438
case tp @ RefinedType(parent, name: TypeName) =>
439439
if (correspondingNames contains name) rewrite(parent)
440440
else RefinedType(
@@ -482,7 +482,7 @@ class TypeApplications(val self: Type) extends AnyVal {
482482
//println(i"lambda abstract $self wrt $boundSyms%, % --> $res")
483483
res
484484
}
485-
self match {
485+
self.stripAnnots match {
486486
case self @ TypeBounds(lo, hi) =>
487487
self.derivedTypeBounds(lo, expand(TypeBounds.upper(hi)))
488488
case _ =>

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
200200
case tp2: LazyRef =>
201201
isSubType(tp1, tp2.ref)
202202
case tp2: AnnotatedType =>
203-
isSubType(tp1, tp2.tpe) // todo: refine?
203+
isSubType(tp1.stripAnnots, tp2.stripAnnots) // todo: refine?
204204
case tp2: ThisType =>
205205
def compareThis = {
206206
val cls2 = tp2.cls
@@ -282,7 +282,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
282282
case tp1: LazyRef =>
283283
isSubType(tp1.ref, tp2)
284284
case tp1: AnnotatedType =>
285-
isSubType(tp1.tpe, tp2)
285+
isSubType(tp1.stripAnnots, tp2.stripAnnots)
286286
case OrType(tp11, tp12) =>
287287
isSubType(tp11, tp2) && isSubType(tp12, tp2)
288288
case ErrorType =>
@@ -416,7 +416,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
416416
}
417417
isSubType(hi1, tp2) || compareGADT
418418
case _ =>
419-
def isNullable(tp: Type): Boolean = tp.dealias match {
419+
def isNullable(tp: Type): Boolean = tp.dealias.stripAnnots match {
420420
case tp: TypeRef => tp.symbol.isNullableClass
421421
case RefinedType(parent, _) => isNullable(parent)
422422
case AndType(tp1, tp2) => isNullable(tp1) && isNullable(tp2)
@@ -453,7 +453,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
453453
case JavaArrayType(elem2) => isSubType(elem1, elem2)
454454
case _ => tp2 isRef ObjectClass
455455
}
456-
compareJavaArray
456+
compareJavaArray
457+
case tp1: AnnotatedType =>
458+
isSubType(tp1.stripAnnots, tp2.stripAnnots)
457459
case _ =>
458460
false
459461
}
@@ -599,7 +601,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
599601
}
600602

601603
/** Defer constraining type variables when compared against prototypes */
602-
def isMatchedByProto(proto: ProtoType, tp: Type) = tp.stripTypeVar match {
604+
def isMatchedByProto(proto: ProtoType, tp: Type) = tp.stripTypeVar.stripAnnots match {
603605
case tp: PolyParam if constraint contains tp => true
604606
case _ => proto.isMatchedBy(tp)
605607
}
@@ -644,9 +646,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
644646
// Tests around `matches`
645647

646648
/** A function implementing `tp1` matches `tp2`. */
647-
final def matchesType(tp1: Type, tp2: Type, relaxed: Boolean): Boolean = tp1.widen match {
649+
final def matchesType(tp1: Type, tp2: Type, relaxed: Boolean): Boolean = tp1.widen.stripAnnots match {
648650
case tp1: MethodType =>
649-
tp2.widen match {
651+
tp2.widen.stripAnnots match {
650652
case tp2: MethodType =>
651653
tp1.isImplicit == tp2.isImplicit &&
652654
matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
@@ -656,15 +658,15 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
656658
matchesType(tp1.resultType, tp2, relaxed)
657659
}
658660
case tp1: PolyType =>
659-
tp2.widen match {
661+
tp2.widen.stripAnnots match {
660662
case tp2: PolyType =>
661663
sameLength(tp1.paramNames, tp2.paramNames) &&
662664
matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
663665
case _ =>
664666
false
665667
}
666668
case _ =>
667-
tp2.widen match {
669+
tp2.widen.stripAnnots match {
668670
case _: PolyType =>
669671
false
670672
case tp2: MethodType =>

0 commit comments

Comments
 (0)