diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Substituters.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 14 |
3 files changed, 26 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala index 8255a6750..471718f63 100644 --- a/src/dotty/tools/dotc/core/Substituters.scala +++ b/src/dotty/tools/dotc/core/Substituters.scala @@ -54,7 +54,8 @@ trait Substituters { this: Context => case tp: NamedType => val sym = tp.symbol if (tp.prefix eq NoPrefix) { - if (sym eq from) return to + if (sym eq from) + return if (to.exists) to else tp } if (sym.isStatic) tp else tp.derivedNamedType(subst1(tp.prefix, from, to, map), tp.name) @@ -79,8 +80,10 @@ trait Substituters { this: Context => case tp: NamedType => val sym = tp.symbol if (tp.prefix eq NoPrefix) { - if (sym eq from1) return to1 - if (sym eq from2) return to2 + if (sym eq from1) + return if (to1.exists) to1 else tp + if (sym eq from2) + return if (to2.exists) to2 else tp } if (sym.isStatic) tp else tp.derivedNamedType(subst2(tp.prefix, from1, to1, from2, to2, map), tp.name) @@ -108,7 +111,8 @@ trait Substituters { this: Context => var fs = from var ts = to while (fs.nonEmpty) { - if (fs.head eq sym) return ts.head + if (fs.head eq sym) + return if (ts.head.exists) ts.head else tp fs = fs.tail ts = ts.tail } diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index a0cc00b4b..8b4952489 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -48,9 +48,11 @@ trait TypeOps { this: Context => } def instParam(ps: List[Symbol], as: List[Type]): Type = - if (ps.isEmpty || as.isEmpty) throwError - else if (tparam eq ps.head) as.head - else throwError + if (as.isEmpty) tp + else if (ps.isEmpty) throwError + else if (tparam eq ps.head) + if (as.head.exists) as.head else tp + else instParam(ps.tail, as.tail) if (tparamOwner == clazz && prefixMatches) instParamFrom(basePre) else toInstance(basePre.normalizedPrefix, clazz.owner, tparam) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 460265e3d..dc8c7c9f1 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -409,7 +409,15 @@ object Types { */ final def typeParams(implicit ctx: Context): List[TypeSymbol] = this match { case tp: AppliedType => - tp.tycon.typeParams drop tp.targs.length + def loop(tparams: List[TypeSymbol], targs: List[Type]): List[TypeSymbol] = tparams match { + case tparam :: tparams1 => + if (targs.isEmpty) tparams + else if (targs.head eq NoType) loop(tparams1, targs.tail) + else tparam :: loop(tparams1, targs.tail) + case _ => + Nil + } + loop(tp.tycon.typeParams, tp.targs) case tp: TypeProxy => tp.underlying.typeParams case tp: ClassInfo => @@ -701,6 +709,10 @@ object Types { // --- AppliedType ----------------------------------------------------------------- + /** An applied type of the form tycon[..targs]. + * ..targs must match the length to tycon.typeParams. + * Missing type arguments are represented by NoType. + */ abstract case class AppliedType(tycon: Type, targs: List[Type]) extends CachedProxyType { override def underlying(implicit ctx: Context) = tycon |