Skip to content

Commit e2e2885

Browse files
authored
Merge pull request #14987 from dotty-staging/aggressive-reduction
More aggressive reduction of type selection (fixes parboiled2)
2 parents 119e3d7 + e0cce9a commit e2e2885

File tree

4 files changed

+82
-5
lines changed

4 files changed

+82
-5
lines changed

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -1548,9 +1548,10 @@ object Types {
15481548
@tailrec def loop(pre: Type): Type = pre.stripTypeVar match {
15491549
case pre: RefinedType =>
15501550
pre.refinedInfo match {
1551-
case TypeAlias(alias) =>
1552-
if (pre.refinedName ne name) loop(pre.parent) else alias
1553-
case _ => loop(pre.parent)
1551+
case tp: AliasingBounds =>
1552+
if (pre.refinedName ne name) loop(pre.parent) else tp.alias
1553+
case _ =>
1554+
loop(pre.parent)
15541555
}
15551556
case pre: RecType =>
15561557
val candidate = pre.parent.lookupRefined(name)
@@ -4640,7 +4641,7 @@ object Types {
46404641
myRepr.nn
46414642
}
46424643

4643-
override def toString: String = s"Skolem($hashCode)"
4644+
override def toString: String = s"SkolemType($hashCode)"
46444645
}
46454646

46464647
/** A skolem type used to wrap the type of the qualifier of a selection.

tests/pos/13491.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ object Rule {
8787

8888
def rule[I <: HList, O <: HList](r: Rule[I, O]): Rule[I, O] = ???
8989

90-
implicit def valueMap[T, Out0 <: HList](m: Map[String, T])(implicit h: HListable[T] { type Out = Out0 }): RuleN[Out0] = ???
90+
implicit def valueMap[T, Out0 <: HList](m: Map[String, T])(implicit h: HListable[T]): RuleN[h.Out] = ???
9191
}
9292

9393
object Test {

tests/pos/i14903a.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
trait Wrapper[T] {
2+
type Out
3+
}
4+
5+
type Func[T] =
6+
T match {
7+
case String => Long
8+
case Long => Int
9+
case Int => Float
10+
case Float => Double
11+
case Double => Unit
12+
case Unit => String
13+
}
14+
15+
implicit def infer[A]: Wrapper[One[A]] { type Out = Func[A] } = ???
16+
17+
trait One[A] {
18+
def use(implicit w: Wrapper[One[A]]): One[w.Out]
19+
}
20+
21+
val x: One[Long] = null
22+
val _ = x.use.use.use.use.use.use.use

tests/pos/i14903b.scala

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import annotation.unchecked.uncheckedVariance
2+
3+
sealed trait HList
4+
sealed trait HNil extends HList
5+
case object HNil extends HNil
6+
case class ::[+H, +T <: HList](head: H, tail: T) extends HList
7+
8+
type Concat[X <: HList, Y <: HList] <: HList = X match
9+
case HNil => Y
10+
case h :: t => h :: Concat[t, Y]
11+
12+
/**
13+
* Decompose L into Prefix ++ Suffix if possible
14+
*/
15+
type StripSuffix[L <: HList, Suffix <: HList] <: Option[HList] = L match
16+
case Suffix => Some[HNil]
17+
case h :: t => StripSuffix[t, Suffix] match
18+
case Some[x] => Some[h :: x]
19+
case _ => None.type
20+
case _ => None.type
21+
22+
/**
23+
* type-level implementation of this logic:
24+
* Out =
25+
* R if T has a tail of type L
26+
* (L dropRight T) ++ R if L has a tail of type T
27+
*/
28+
sealed trait TailSwitch[L <: HList, T <: HList, R <: HList]:
29+
type Out <: HList
30+
31+
object TailSwitch:
32+
type TS[L <: HList, T <: HList, R <: HList] <: HList =
33+
StripSuffix[T, L] match
34+
case Some[_] => R
35+
case _ => StripSuffix[L, T] match
36+
case Some[x] => Concat[x, R]
37+
38+
implicit def tailSwitch[L <: HList, T <: HList, R <: HList]: (TailSwitch[L, T, R] {
39+
type Out = TS[L, T, R]
40+
}) = new TailSwitch[L, T, R] { type Out = TS[L, T, R] }
41+
42+
/**
43+
* Rule popping I from stack and pushing back O
44+
*/
45+
sealed class Rule[-I <: HList, +O <: HList]:
46+
def ~[I2 <: HList, O2 <: HList](that: Rule[I2, O2])(implicit
47+
i: TailSwitch[I2, O @uncheckedVariance, I @uncheckedVariance],
48+
o: TailSwitch[O @uncheckedVariance, I2, O2]
49+
): Rule[i.Out, o.Out] = ???
50+
51+
object Test:
52+
def dot = new Rule[HNil, HNil] {}
53+
def num = new Rule[HNil, Byte :: HNil] {}
54+
def pattern = num ~ dot ~ num ~ dot ~ num ~ dot ~ num // error

0 commit comments

Comments
 (0)