diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index fa41b5adf9f2..a304fa9f5705 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -148,7 +148,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, private def paramCount(entries: Array[Type]) = entries.length >> 1 /** The type variable corresponding to parameter numbered `n`, null if none was created */ - private def typeVar(entries: Array[Type], n: Int): Type = + private def typeVar(entries: Array[Type], n: Int): Type | Null = entries(paramCount(entries) + n) /** The `boundsMap` entry corresponding to `param` */ @@ -203,11 +203,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds, def nonParamBounds(param: TypeParamRef)(using Context): TypeBounds = entry(param).bounds - def typeVarOfParam(param: TypeParamRef): Type = { + def typeVarOfParam(param: TypeParamRef): Type = val entries = boundsMap(param.binder) if entries == null then NoType - else typeVar(entries, param.paramNum) - } + else + val tvar = typeVar(entries, param.paramNum) + if tvar == null then NoType + else tvar // ---------- Adding TypeLambdas -------------------------------------------------- diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 2cfdd08128ce..3faab121637b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -145,7 +145,7 @@ object TypeOps: if normed.exists then normed else tp.map(simplify(_, theMap)) case tp: TypeParamRef => val tvar = ctx.typerState.constraint.typeVarOfParam(tp) - if (tvar.exists) tvar else tp + if tvar.exists then tvar else tp case _: ThisType | _: BoundType => tp case tp: AliasingBounds => diff --git a/tests/neg/i15272.scala b/tests/neg/i15272.scala new file mode 100644 index 000000000000..1d380a3b5333 --- /dev/null +++ b/tests/neg/i15272.scala @@ -0,0 +1,11 @@ + sealed trait EdgeN[+NT] + object EdgeN: + case class Head[+NT, +From <: NT, +To <: NT] (from: From, to: To ) extends EdgeN[NT] + case class Cons[+NT, +From <: NT, +ToE <: EdgeN[NT]](from: From, to: ToE) extends EdgeN[NT] + final type InNodesTupleOf[NT, E <: EdgeN[NT]] <: Tuple = E match + case Cons[nt,from,toE] => from *: InNodesTupleOf[nt,toE] + case Head[nt,from ,to] => from *: EmptyTuple + def inNodesTuple[NT,E <: EdgeN[NT]](edge: E): InNodesTupleOf[NT,E] = edge match + case e: Cons[nt,from,toE] => e.from *: inNodesTuple[nt,toE](e.to) // error + case e: Head[nt,from,to] => e.from *: EmptyTuple + end EdgeN \ No newline at end of file