Skip to content

Commit cdebd91

Browse files
committed
Allow definition of new types in refinements
Allow definition of types in refinements that do not appear in parent type.
1 parent 1792c9e commit cdebd91

File tree

7 files changed

+65
-11
lines changed

7 files changed

+65
-11
lines changed

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
913913
typr.println(s"adding refinement $refinement")
914914
checkRefinementNonCyclic(refinement, refineCls, seen)
915915
val rsym = refinement.symbol
916-
if ((rsym.is(Method) || rsym.isType) && rsym.allOverriddenSymbols.isEmpty)
916+
if (rsym.is(Method) && rsym.allOverriddenSymbols.isEmpty)
917917
ctx.error(i"refinement $rsym without matching type in parent $parent", refinement.pos)
918918
val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
919919
RefinedType(parent, rsym.name, rinfo)

tests/neg/i39.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object i39neg {
22

33
trait B {
4-
type D <: { type T } // error
4+
type D <: { type T }
55
def d: D
66
}
77

tests/neg/i50-volatile.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ class Test {
33
class Inner
44
}
55
type A <: Base {
6-
type X = String // error
6+
type X = String // old-error
77
}
88
type B <: {
9-
type X = Int // error
9+
type X = Int // old-error
1010
}
1111
lazy val o: A & B = ???
1212

tests/neg/subtyping.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object Test {
88
implicitly[B#X <:< A#X] // error: no implicit argument
99
}
1010
def test2(): Unit = {
11-
val a : { type T; type U } = ??? // error // error
11+
val a : { type T; type U } = ???
1212
implicitly[a.T <:< a.U] // error: no implicit argument
1313
}
1414
}

tests/neg/zoo.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
object Test {
22
type Meat = {
3-
type IsMeat = Any // error
3+
type IsMeat = Any
44
}
55
type Grass = {
6-
type IsGrass = Any // error
6+
type IsGrass = Any
77
}
88
type Animal = {
9-
type Food // error
9+
type Food
1010
def eats(food: Food): Unit // error
1111
def gets: Food // error
1212
}
1313
type Cow = {
14-
type IsMeat = Any // error
15-
type Food <: Grass // error
14+
type IsMeat = Any
15+
type Food <: Grass
1616
def eats(food: Grass): Unit // error
1717
def gets: Grass // error
1818
}
1919
type Lion = {
20-
type Food = Meat // error
20+
type Food = Meat
2121
def eats(food: Meat): Unit // error
2222
def gets: Meat // error
2323
}

tests/pos/t2712-2.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package test
2+
3+
// See: https://github.com/milessabin/si2712fix-demo/issues/3
4+
object Test {
5+
trait A[T1, T2] { }
6+
trait B[T1, T2] { }
7+
class C[T] extends A[T, Long] with B[T, Double]
8+
class CB extends A[Boolean, Long] with B[Boolean, Double]
9+
10+
trait A2[T]
11+
trait B2[T]
12+
class C2[T] extends A2[T] with B2[T]
13+
class CB2 extends A2[Boolean] with B2[Boolean]
14+
15+
def meh[M[_], A](x: M[A]): M[A] = x
16+
17+
val m0 = meh(new C[Boolean])
18+
m0: C[Boolean]
19+
val m1 = meh(new CB)
20+
m1: B[Boolean, Double] // note: different order in which parents are visited for hk type inference. Dotty picks libearization order.
21+
val m2 = meh(new C2[Boolean])
22+
m2: C2[Boolean]
23+
val m3 = meh(new CB2)
24+
m3: B2[Boolean] // note: different order in which parents are visited for hk type inference. Dotty picks libearization order.
25+
}

tests/pos/t2712-5.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package test
2+
3+
import scala.language.higherKinds
4+
5+
trait Functor[F[_]] {
6+
def map[A, B](f: A => B, fa: F[A]): F[B]
7+
}
8+
9+
object Functor {
10+
implicit def function[A]: Functor[({ type l[B] = A => B })#l] =
11+
new Functor[({ type l[B] = A => B })#l] {
12+
def map[C, B](cb: C => B, ac: A => C): A => B = cb compose ac
13+
}
14+
}
15+
16+
object FunctorSyntax {
17+
implicit class FunctorOps[F[_], A](fa: F[A])(implicit F: Functor[F]) {
18+
def map[B](f: A => B): F[B] = F.map(f, fa)
19+
}
20+
}
21+
22+
object Test {
23+
24+
val f: Int => String = _.toString
25+
26+
import FunctorSyntax._
27+
28+
f.map((s: String) => s.reverse)
29+
}

0 commit comments

Comments
 (0)