Skip to content

Commit 2fa2663

Browse files
authored
Merge pull request #14855 from dotty-staging/test-6778
Regression tests
2 parents 73cda0c + 3db1b25 commit 2fa2663

File tree

5 files changed

+165
-0
lines changed

5 files changed

+165
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
object Main {
2+
def main(a: Array[String]): Unit = {
3+
println("you may not run `testHasThisType` - just check that it compiles")
4+
// comment lines after "// this line of code makes" comments to make it compilable again
5+
testHasThisType()
6+
testHasThisType2()
7+
}
8+
9+
// ---- ---- ---- ----
10+
11+
trait HasThisType[PThis <: HasThisType[_ <: PThis]] {
12+
this: PThis =>
13+
type This = PThis
14+
15+
// inline // uncommenting `inline` cause problem in scastie dotty version, but is fixed in dotty `master`
16+
def self(): This with this.type = this
17+
}
18+
19+
// ---- ---- ---- ----
20+
21+
def testHasThisType(): Unit = {
22+
def testSelf[PThis <: HasThisType[_ <: PThis]](that: HasThisType[PThis]): Unit = {
23+
val thatSelf = that.self()
24+
// that.self().type <: that.This
25+
assert(implicitly[thatSelf.type <:< that.This] != null)
26+
}
27+
val that: HasThisType[_] = Foo() // null.asInstanceOf
28+
testSelf(that) // error
29+
}
30+
31+
32+
def testHasThisType2(): Unit = {
33+
def testSelf[PThis <: HasThisType[_ <: PThis]](that: PThis with HasThisType[PThis]): Unit = {
34+
// that.type <: that.This
35+
assert(implicitly[that.type <:< that.This] != null)
36+
}
37+
val that: HasThisType[_] = Foo() // null.asInstanceOf
38+
// this line of code makes Dotty compiler infinite recursion (stopped only by overflow) - comment it to make it compilable again
39+
testSelf(that) // error
40+
}
41+
42+
// ---- ---- ---- ----
43+
44+
// `HasThisType` instantiation/sub-classing
45+
trait FooLike[PThis <: FooLike[_ <: PThis]] extends HasThisType[PThis] {
46+
this: PThis =>
47+
}
48+
case class Foo(payload: Any = "dummy") extends FooLike[Foo]
49+
case class Bar(dummy: Any = "payload") extends FooLike[FooLike[_]]
50+
51+
}

tests/neg/i6778.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- [E104] Syntax Error: tests/neg/i6778.scala:3:27 ---------------------------------------------------------------------
2+
3 |class Bar extends Foo with A(10) // error
3+
| ^^^^^
4+
| class A is not a trait
5+
|
6+
| longer explanation available when compiling with `-explain`

tests/neg/i6778.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait Foo
2+
class A(x: Int)
3+
class Bar extends Foo with A(10) // error

tests/pos/i5288.scala

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
trait C { type M; val m: M }
2+
3+
object Test {
4+
// Arity 1 ------------------------------------------------------------------
5+
6+
// Function1
7+
def m1(i: Int): Int = 1
8+
val f1Expected: Int => Int = m1
9+
val f1Inferred = m1
10+
identity[Int => Int](f1Inferred)
11+
12+
// ImplicitFunction1
13+
def m4(using i: Int): Int = 4
14+
val f4Expected: Int ?=> Int = m4
15+
// val f4Inferred = m4 // can't work since no expected type
16+
// identity[Int ?=> Int](f4Inferred)
17+
18+
// DependentFunction1
19+
def m7(c: C): c.M = c.m
20+
val f7Expected: (c: C) => c.M = m7
21+
val f7Inferred = m7
22+
identity[(c: C) => c.M](f7Inferred)
23+
24+
// Arity 2 ------------------------------------------------------------------
25+
26+
// Function2
27+
def m2(i: Int, s: String): Int = 2
28+
val f2Expected: (Int, String) => Int = m2
29+
val f2Inferred = m2
30+
identity[(Int, String) => Int](f2Inferred)
31+
32+
// ImplicitFunction2
33+
def m5(using i: Int, s: String): Int = 5
34+
val f5Expected: (Int, String) ?=> Int = m5
35+
// val f5Inferred = m5 // can't work since no expected type
36+
// identity[(Int, String) ?=> Int](f5Inferred)
37+
38+
// DependentFunction2
39+
def m9(c1: C, c2: C): c1.M | c2.M = c1.m
40+
val f9Expected: (c1: C, c2: C) => c1.M | c2.M = m9
41+
val f9Inferred = m9
42+
identity[(c1: C, c2: C) => c1.M | c2.M](f9Inferred)
43+
44+
// Function1[Function1]
45+
def m8(i: Int)(s: String): Int = 8
46+
val f8Expected: Int => String => Int = m8
47+
val f8Inferred = m8
48+
identity[Int => String => Int](f8Inferred)
49+
50+
// Function1[ImplicitFunction1]
51+
def m6(i: Int)(using s: String): Int = 6
52+
val f6Expected: Int => String ?=> Int = m6
53+
//val f6Inferred = m6 // can't work since no expected type
54+
//identity[Int => String ?=> Int](f6Inferred)
55+
56+
// Function1[DependentFunction1]
57+
def mA(i: Int)(c: C): c.M = c.m
58+
val fAExpected: Int => (c: C) => c.M = mA
59+
val fAInferred = mA
60+
identity[Int => (c: C) => c.M](fAInferred)
61+
62+
// ImplicitFunction1[ImplicitFunction1] -- Can't be expressed as a method...
63+
// ImplicitFunction1[Function1] -- Can't be expressed as a method...
64+
// ImplicitFunction1[DependentFunction1] -- Can't be expressed as a method...
65+
66+
// DependentFunction1[Function1]
67+
def mB(c: C)(s: String): c.M = c.m
68+
val fBExpected: (c: C) => String => c.M = mB
69+
val fBInferred = mB
70+
identity[(c: C) => String => c.M](fBInferred)
71+
72+
// DependentFunction1[ImplicitFunction1]
73+
def mC(c: C)(using s: String): c.M = c.m
74+
// val fCExpected: (c: C) => String ?=> c.M = mC
75+
// gives:
76+
// Implementation restriction: Expected result type (c: C) => (String) ?=> c.M
77+
// is a curried dependent context function type. Such types are not yet supported.
78+
79+
// val fCInferred = mC // can't work since no expected type
80+
// identity[(c: C) => String ?=> c.m](fCInferred)
81+
82+
// DependentFunction1[DependentFunction1]
83+
def mD(c1: C)(c2: C): c1.M | c2.M = c1.m
84+
val fDExpected: (c1: C) => (c2: C) => c1.M | c2.M = mD
85+
val fDInferred = mD
86+
identity[(c1: C) => (c2: C) => c1.M | c2.M](fDInferred)
87+
88+
// Missing from the above:
89+
// - interactions with by name
90+
// - interactions with default arguments
91+
// - interactions with inline method
92+
// - interactions with inline arguments
93+
}

tests/run/i7281.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
trait T {
3+
case class X[A]()
4+
}
5+
6+
object a extends T
7+
object b extends T
8+
9+
val ax = a.X()
10+
val bx = b.X()
11+
12+
@main def Test = assert(ax != bx)

0 commit comments

Comments
 (0)