Skip to content

Commit 10a2ce6

Browse files
authored
Merge pull request #2329 from dotty-staging/fix-#2232
Fix #2232: Don't check AndTypes in liftToClasses
2 parents 16a28ac + 07f09cc commit 10a2ce6

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,7 +2219,7 @@ object Types {
22192219

22202220
def derivedAndType(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
22212221
if ((tp1 eq this.tp1) && (tp2 eq this.tp2)) this
2222-
else AndType.make(tp1, tp2)
2222+
else AndType.make(tp1, tp2, checkValid = true)
22232223

22242224
def derived_& (tp1: Type, tp2: Type)(implicit ctx: Context): Type =
22252225
if ((tp1 eq this.tp1) && (tp2 eq this.tp2)) this
@@ -2234,21 +2234,26 @@ object Types {
22342234
final class CachedAndType(tp1: Type, tp2: Type) extends AndType(tp1, tp2)
22352235

22362236
object AndType {
2237-
def apply(tp1: Type, tp2: Type)(implicit ctx: Context) = {
2237+
def apply(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = {
22382238
assert(tp1.isValueType && tp2.isValueType, i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
22392239
unchecked(tp1, tp2)
22402240
}
2241-
def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context) = {
2241+
2242+
def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context): AndType = {
22422243
assertUnerased()
22432244
unique(new CachedAndType(tp1, tp2))
22442245
}
2245-
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
2246+
2247+
/** Make an AndType using `op` unless clearly unnecessary (i.e. without
2248+
* going through `&`).
2249+
*/
2250+
def make(tp1: Type, tp2: Type, checkValid: Boolean = false)(implicit ctx: Context): Type =
22462251
if ((tp1 eq tp2) || (tp2 eq defn.AnyType))
22472252
tp1
22482253
else if (tp1 eq defn.AnyType)
22492254
tp2
22502255
else
2251-
apply(tp1, tp2)
2256+
if (checkValid) apply(tp1, tp2) else unchecked(tp1, tp2)
22522257
}
22532258

22542259
abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType with AndOrType {
@@ -2994,7 +2999,7 @@ object Types {
29942999
// ----- Skolem types -----------------------------------------------
29953000

29963001
/** A skolem type reference with underlying type `binder`. */
2997-
abstract case class SkolemType(info: Type) extends UncachedProxyType with ValueType with SingletonType {
3002+
case class SkolemType(info: Type) extends UncachedProxyType with ValueType with SingletonType {
29983003
override def underlying(implicit ctx: Context) = info
29993004
def derivedSkolemType(info: Type)(implicit ctx: Context) =
30003005
if (info eq this.info) this else SkolemType(info)
@@ -3010,13 +3015,6 @@ object Types {
30103015
override def toString = s"Skolem($hashCode)"
30113016
}
30123017

3013-
final class CachedSkolemType(info: Type) extends SkolemType(info)
3014-
3015-
object SkolemType {
3016-
def apply(info: Type)(implicit ctx: Context) =
3017-
unique(new CachedSkolemType(info))
3018-
}
3019-
30203018
// ------------ Type variables ----------------------------------------
30213019

30223020
/** In a TypeApply tree, a TypeVar is created for each argument type to be inferred.

tests/neg/i2232.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
object Cats {
2+
trait Trivial[A]
3+
implicit def trivial[A]: Trivial[A] = new Trivial[A] { }
4+
5+
type Obj[C[_[_[_], _[_, _]]]] =
6+
[A] => C[({type l[c0[_], c1[_, _]] = c0[A] })#l]
7+
type Cat[C[_[_[_], _[_, _]]]] =
8+
[A, B] => C[({type l[c0[_], c1[_, _]] = c1[A, B]})#l]
9+
10+
trait Category[C[_[_[_], _[_, _]]]] {
11+
type -> = Cats.Cat[C]
12+
type Obj = Cats.Obj[C]
13+
14+
def id[A: Obj]: A -> A
15+
def andThen[A, B, C](ab: A -> B, bc: B -> C): A -> C
16+
}
17+
18+
object Category {
19+
type ByF[F[_, _]] = Category[_] { type -> = F }
20+
}
21+
22+
type Scal[f[_[_], _[_, _]]] = f[Trivial, Function1]
23+
24+
implicit val scal: Category[Scal] = new Category[Scal] {
25+
def id[A: Obj]: A -> A = a => a
26+
def andThen[A, B, C](ab: A -> B, bc: B -> C): A -> C = ab.andThen(bc)
27+
}
28+
29+
implicit class CategoryOps[F[_, _], A, B](ab: F[A, B]) {
30+
def >>>[C](bc: F[B, C])(implicit F: Category.ByF[F]): F[A, C] =
31+
F.andThen(ab, bc)
32+
}
33+
34+
val f: Int => Int = _ + 1
35+
val g: Int => String = _.toString
36+
f >>> g // error: no implicit arg found
37+
}

0 commit comments

Comments
 (0)