aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-11 18:05:36 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-12 18:14:04 +0200
commitcdebd91712b36b048233d7cf9501cc7a5bb50b31 (patch)
tree35d3ee5d8800e958640916cd0145def1f5726751
parent1792c9e9bcff1feba7b50a24a46e1e20d8a39d9b (diff)
downloaddotty-cdebd91712b36b048233d7cf9501cc7a5bb50b31.tar.gz
dotty-cdebd91712b36b048233d7cf9501cc7a5bb50b31.tar.bz2
dotty-cdebd91712b36b048233d7cf9501cc7a5bb50b31.zip
Allow definition of new types in refinements
Allow definition of types in refinements that do not appear in parent type.
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
-rw-r--r--tests/neg/i39.scala2
-rw-r--r--tests/neg/i50-volatile.scala4
-rw-r--r--tests/neg/subtyping.scala2
-rw-r--r--tests/neg/zoo.scala12
-rw-r--r--tests/pos/t2712-2.scala25
-rw-r--r--tests/pos/t2712-5.scala29
7 files changed, 65 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index da176427a..62d356e3d 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -913,7 +913,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
typr.println(s"adding refinement $refinement")
checkRefinementNonCyclic(refinement, refineCls, seen)
val rsym = refinement.symbol
- if ((rsym.is(Method) || rsym.isType) && rsym.allOverriddenSymbols.isEmpty)
+ if (rsym.is(Method) && rsym.allOverriddenSymbols.isEmpty)
ctx.error(i"refinement $rsym without matching type in parent $parent", refinement.pos)
val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
RefinedType(parent, rsym.name, rinfo)
diff --git a/tests/neg/i39.scala b/tests/neg/i39.scala
index df53d9816..8a13a7d06 100644
--- a/tests/neg/i39.scala
+++ b/tests/neg/i39.scala
@@ -1,7 +1,7 @@
object i39neg {
trait B {
- type D <: { type T } // error
+ type D <: { type T }
def d: D
}
diff --git a/tests/neg/i50-volatile.scala b/tests/neg/i50-volatile.scala
index f6fa3466d..fcfc9592b 100644
--- a/tests/neg/i50-volatile.scala
+++ b/tests/neg/i50-volatile.scala
@@ -3,10 +3,10 @@ class Test {
class Inner
}
type A <: Base {
- type X = String // error
+ type X = String // old-error
}
type B <: {
- type X = Int // error
+ type X = Int // old-error
}
lazy val o: A & B = ???
diff --git a/tests/neg/subtyping.scala b/tests/neg/subtyping.scala
index 27cc0568e..351fa0ecd 100644
--- a/tests/neg/subtyping.scala
+++ b/tests/neg/subtyping.scala
@@ -8,7 +8,7 @@ object Test {
implicitly[B#X <:< A#X] // error: no implicit argument
}
def test2(): Unit = {
- val a : { type T; type U } = ??? // error // error
+ val a : { type T; type U } = ???
implicitly[a.T <:< a.U] // error: no implicit argument
}
}
diff --git a/tests/neg/zoo.scala b/tests/neg/zoo.scala
index 3d9b77b72..19efcc1d7 100644
--- a/tests/neg/zoo.scala
+++ b/tests/neg/zoo.scala
@@ -1,23 +1,23 @@
object Test {
type Meat = {
- type IsMeat = Any // error
+ type IsMeat = Any
}
type Grass = {
- type IsGrass = Any // error
+ type IsGrass = Any
}
type Animal = {
- type Food // error
+ type Food
def eats(food: Food): Unit // error
def gets: Food // error
}
type Cow = {
- type IsMeat = Any // error
- type Food <: Grass // error
+ type IsMeat = Any
+ type Food <: Grass
def eats(food: Grass): Unit // error
def gets: Grass // error
}
type Lion = {
- type Food = Meat // error
+ type Food = Meat
def eats(food: Meat): Unit // error
def gets: Meat // error
}
diff --git a/tests/pos/t2712-2.scala b/tests/pos/t2712-2.scala
new file mode 100644
index 000000000..95172545d
--- /dev/null
+++ b/tests/pos/t2712-2.scala
@@ -0,0 +1,25 @@
+package test
+
+// See: https://github.com/milessabin/si2712fix-demo/issues/3
+object Test {
+ trait A[T1, T2] { }
+ trait B[T1, T2] { }
+ class C[T] extends A[T, Long] with B[T, Double]
+ class CB extends A[Boolean, Long] with B[Boolean, Double]
+
+ trait A2[T]
+ trait B2[T]
+ class C2[T] extends A2[T] with B2[T]
+ class CB2 extends A2[Boolean] with B2[Boolean]
+
+ def meh[M[_], A](x: M[A]): M[A] = x
+
+ val m0 = meh(new C[Boolean])
+ m0: C[Boolean]
+ val m1 = meh(new CB)
+ m1: B[Boolean, Double] // note: different order in which parents are visited for hk type inference. Dotty picks libearization order.
+ val m2 = meh(new C2[Boolean])
+ m2: C2[Boolean]
+ val m3 = meh(new CB2)
+ m3: B2[Boolean] // note: different order in which parents are visited for hk type inference. Dotty picks libearization order.
+}
diff --git a/tests/pos/t2712-5.scala b/tests/pos/t2712-5.scala
new file mode 100644
index 000000000..ed96d4c06
--- /dev/null
+++ b/tests/pos/t2712-5.scala
@@ -0,0 +1,29 @@
+package test
+
+import scala.language.higherKinds
+
+trait Functor[F[_]] {
+ def map[A, B](f: A => B, fa: F[A]): F[B]
+}
+
+object Functor {
+ implicit def function[A]: Functor[({ type l[B] = A => B })#l] =
+ new Functor[({ type l[B] = A => B })#l] {
+ def map[C, B](cb: C => B, ac: A => C): A => B = cb compose ac
+ }
+}
+
+object FunctorSyntax {
+ implicit class FunctorOps[F[_], A](fa: F[A])(implicit F: Functor[F]) {
+ def map[B](f: A => B): F[B] = F.map(f, fa)
+ }
+}
+
+object Test {
+
+ val f: Int => String = _.toString
+
+ import FunctorSyntax._
+
+ f.map((s: String) => s.reverse)
+}