Skip to content

Commit 34f73de

Browse files
committed
Fix and enable RefChecks
RefChecks is now enabled. Some of the tests had to be fixed to be refchecks-correct.
1 parent 3558e07 commit 34f73de

File tree

10 files changed

+76
-58
lines changed

10 files changed

+76
-58
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Compiler {
2222
List(new FirstTransform, new SyntheticMethods),
2323
List(new SuperAccessors),
2424
// pickling goes here
25-
List(/*new RefChecks, */new ElimRepeated, new ElimLocals),
25+
List(new RefChecks, new ElimRepeated, new ElimLocals),
2626
List(new ExtensionMethods),
2727
List(new TailRec),
2828
List(new PatternMatcher,

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

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ object RefChecks {
102102
* 4. Check that every member with an `override` modifier
103103
* overrides some other member.
104104
* TODO check that classes are not overridden
105+
* TODO This still needs to be cleaned up; the current version is a staright port of what was there
106+
* before, but it looks too complicated and method bodies are far too large.
105107
*/
106108
private def checkAllOverrides(clazz: Symbol)(implicit ctx: Context): Unit = {
107109
val self = clazz.thisType
@@ -116,11 +118,15 @@ object RefChecks {
116118
case List(MixinOverrideError(_, msg)) =>
117119
ctx.error(msg, clazz.pos)
118120
case MixinOverrideError(member, msg) :: others =>
119-
val others1 = others.map(_.member.name.decode).filter(member.name.decode != _).distinct
120-
ctx.error(
121-
msg + (if (others1.isEmpty) ""
122-
else ";\n other members with override errors are: " + (others1 mkString ", ")),
123-
clazz.pos)
121+
val others1 = others.map(_.member).filter(_.name != member.name).distinct
122+
def othersMsg = {
123+
val others1 = others.map(_.member)
124+
.filter(_.name != member.name)
125+
.map(_.show).distinct
126+
if (others1.isEmpty) ""
127+
else i";\n other members with override errors are:: $others1%, %"
128+
}
129+
ctx.error(msg + othersMsg, clazz.pos)
124130
}
125131
}
126132

@@ -129,9 +135,9 @@ object RefChecks {
129135

130136
def infoString0(sym: Symbol, showLocation: Boolean) = {
131137
val sym1 = sym.underlyingSymbol
132-
if (showLocation) sym1.show
138+
if (showLocation) sym1.showLocated
133139
else
134-
sym1.showLocated +
140+
sym1.show +
135141
(if (sym1.isAliasType) ", which equals " + self.memberInfo(sym1)
136142
else if (sym1.isAbstractType) " with bounds" + self.memberInfo(sym1)
137143
else if (sym1.is(Module)) ""
@@ -182,6 +188,8 @@ object RefChecks {
182188
}
183189

184190
def overrideAccessError() = {
191+
ctx.log(i"member: ${member.showLocated} ${member.flags}") // DEBUG
192+
ctx.log(i"other: ${other.showLocated} ${other.flags}") // DEBUG
185193
val otherAccess = (other.flags & AccessFlags).toString
186194
overrideError("has weaker access privileges; it should be " +
187195
(if (otherAccess == "") "public" else "at least " + otherAccess))
@@ -331,7 +339,7 @@ object RefChecks {
331339
// 2. Check that only abstract classes have deferred members
332340
def checkNoAbstractMembers(): Unit = {
333341
// Avoid spurious duplicates: first gather any missing members.
334-
val missing = clazz.info.abstractTermMembers.filterNot(ignoreDeferred)
342+
val missing = clazz.thisType.abstractTermMembers.filterNot(ignoreDeferred)
335343
// Group missing members by the name of the underlying symbol,
336344
// to consolidate getters and setters.
337345
val grouped: Map[Name, Seq[SingleDenotation]] = missing groupBy (_.symbol.underlyingSymbol.name)
@@ -464,6 +472,9 @@ object RefChecks {
464472
if (decl.is(Deferred) && !ignoreDeferred(decl)) {
465473
val impl = decl.matchingMember(clazz.thisType)
466474
if (impl == NoSymbol || (decl.owner isSubClass impl.owner)) {
475+
val impl1 = clazz.thisType.nonPrivateMember(decl.name) // DEBUG
476+
ctx.log(i"${impl1}: ${impl1.info}") // DEBUG
477+
ctx.log(i"${clazz.thisType.memberInfo(decl)}") // DEBUG
467478
abstractClassError(false, "there is a deferred declaration of " + infoString(decl) +
468479
" which is not implemented in a subclass" + err.abstractVarMessage(decl))
469480
}
@@ -499,7 +510,7 @@ object RefChecks {
499510
def hasMatchingSym(inclazz: Symbol, member: Symbol): Boolean = {
500511

501512
def isSignatureMatch(sym: Symbol) = !sym.isTerm ||
502-
clazz.thisType.memberInfo(sym).matches(member.info)
513+
clazz.thisType.memberInfo(sym).matchesLoosely(member.info)
503514

504515
/* The rules for accessing members which have an access boundary are more
505516
* restrictive in java than scala. Since java has no concept of package nesting,
@@ -626,7 +637,11 @@ object RefChecks {
626637
override val levelAndIndex: LevelAndIndex =
627638
((outerLevelAndIndex, 0) /: stats) {(mi, stat) =>
628639
val (m, idx) = mi
629-
(if (stat.symbol.exists) m.updated(stat.symbol, (this, idx)) else m, idx + 1)
640+
val m1 = stat match {
641+
case stat: MemberDef => m.updated(stat.symbol, (this, idx))
642+
case _ => m
643+
}
644+
(m1, idx + 1)
630645
}._1
631646
var maxIndex: Int = Int.MinValue
632647
var refPos: Position = _

test/dotc/tests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class tests extends CompilerTest {
1414
"-pagewidth", "160")
1515

1616
implicit val defaultOptions = noCheckOptions ++ List(
17-
"-Ycheck:synthetic,tailrec"
17+
"-Ycheck:refchecks,tailrec"
1818
)
1919

2020
val twice = List("#runs", "2", "-YnoDoubleBindings")

tests/pos/desugar.scala

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ object desugar {
66
val list = List(1, 2, 3)
77

88
{ var z: Int = y }
9-
9+
1010
def foo0(first: Int, second: Int = 2, third: Int = 3) = first + second
1111
def foo1(first: Int, second: Int = 2)(third: Int = 3) = first + second
1212
def foo2(first: Int)(second: Int = 2)(third: Int = 3) = first + second
13-
13+
1414
object caseClasses { self =>
1515
trait List[+T] {
1616
def head: T
@@ -23,34 +23,37 @@ object desugar {
2323
def apply[T](head: T): Cons[T] = apply(head, Nil)
2424
}
2525

26-
case object Nil extends List[Nothing]
26+
case object Nil extends List[Nothing] {
27+
def head = throw new Error()
28+
def tail = throw new Error()
29+
}
2730
}
28-
31+
2932
object patDefs {
30-
33+
3134
import caseClasses._
3235

3336
val xs: List[Int] = Cons(1, Cons(2, Nil))
34-
35-
val Cons(y, ys) = xs
37+
38+
val Cons(y, ys) = xs
3639
val Cons(z, _) = xs
3740
val Cons(_, _) = xs
38-
41+
3942
val (cons: Cons[Int]) = xs
40-
43+
4144
val x1, y1, z1: Int = 1
4245
}
43-
46+
4447
object Binops {
45-
48+
4649
x :: y :: Nil
47-
50+
4851
val x :: y :: Nil = list
49-
52+
5053
}
51-
54+
5255
object fors {
53-
56+
5457
for (x <- List(1, 2, 3)) yield 2
5558
for (x <- List(1, 2, 3) if x % 2 == 0) yield x * x
5659
for (x <- List(1, 2, 3); y <- 0 to x) yield x * y
@@ -65,7 +68,7 @@ object desugar {
6568
for (x <- List(1, 2, 3); y = x * x; if x + y % 2 == 0) println(x * y)
6669
for (x <- List(1, 2, 3); y = x * x; z = x * y; u <- 0 to y) println(x * y * z * u)
6770
}
68-
71+
6972
object misc {
7073
'hello
7174
s"this is a $x + ${x + y} string"
@@ -82,4 +85,4 @@ object desugar {
8285
do x -= 1 while (x > 0)
8386
}
8487

85-
}
88+
}

tests/pos/hk.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import language.higherKinds
22

33
object hk0 {
44

5-
class Base {
5+
abstract class Base {
66
type Rep[T]
77
val strRep: Rep[String]
88
}
@@ -13,7 +13,7 @@ object hk0 {
1313
val sr: Rep[String] = ""
1414
}
1515

16-
class Functor[F[_]] {
16+
abstract class Functor[F[_]] {
1717
def map[A, B](f: A => B): F[A] => F[B]
1818
}
1919
val ml: Functor[List] = ???
@@ -53,4 +53,4 @@ object higherKinded {
5353
tree1: Tree[String]
5454
}
5555

56-
}
56+
}

tests/pos/inferred.scala

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
class LIST[+T] {
2-
1+
abstract class LIST[+T] {
2+
33
def isEmpty: Boolean
44
def head: T
55
def tail: LIST[T]
6-
6+
77
def prepend [U >: T] (x: U): LIST[U] = new CONS(x, this)
8-
8+
99
def map[U](f: T => U): LIST[U] = if (isEmpty) NIL else tail.map(f).prepend(f(head))
10-
10+
1111
}
1212

1313
object NIL extends LIST[Nothing] {
@@ -37,22 +37,22 @@ object Inferred {
3737
val nn = bar(NIL)
3838

3939
val ints: LIST[Int] = NIL prepend 1
40-
40+
4141
val ints1 = NIL prepend 1 prepend 2
4242

4343
val a = if (1 == 0) NIL else ints
44-
44+
4545
val n2 = scala.collection.immutable.Nil
46-
46+
4747
val ss2: scala.collection.immutable.List[String] = "abc" :: n2
48-
48+
4949
val ss3 = "abc" :: n2
50-
50+
5151
def cl = ((x: Int) => x + 1)
52-
52+
5353
val ints2 = ints map (_ + 1)
54-
54+
5555
val ints3 = new CONS[Int](1, NIL)
56-
56+
5757
val ints4 = new CONS(1, NIL)
5858
}

tests/pos/opassign.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
object opassign {
2-
2+
33
var count: Int = 0
44

55
def next = { count += 1; count }
6-
6+
77
var x: Int = 0
88
x += 1
9-
9+
1010
{ var x: Int = 0
1111
x += 1
1212
}
13-
13+
1414
class Ref {
15-
var x: Int
15+
var x: Int = _
1616
}
1717
val r = new Ref
1818
r.x += 1
19-
19+
2020
val arr = new Array[Int](10)
2121
arr(0) += 1
22-
22+
2323
def f(x: Int): Ref = new Ref
2424
f(next).x += 1
25-
25+
2626
val buf = new collection.mutable.ListBuffer[Int]
2727
buf += 1
28-
}
28+
}

tests/pos/t1832.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ trait Cloning {
22
trait Foo
33
def fn(g: Any => Unit): Foo
44

5-
class Star { def *(a: Cloning.this.Foo): Cloning.this.Foo }
5+
abstract class Star { def *(a: Cloning.this.Foo): Cloning.this.Foo }
66

77
implicit def mkStar(i: Int): Star = new Star { def *(a: Foo): Foo = null }
88

tests/pos/tycons.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ object obj extends List[Number] with Set[Exception] {
1212
val e: Exception = x
1313
}
1414

15-
class Functor[F <: TypeConstructor] {
15+
abstract class Functor[F <: TypeConstructor] {
1616
def map[A, B](f: F { type TypeArg <: A }): F { type TypeArg <: B }
1717
}
1818

1919
implicit object ListFunctor extends Functor[List] {
20-
def map[A, B](f: List[A]): List[B] = ???
20+
override def map[A, B](f: List { type TypeArg <: A }): List { type TypeArg <: B } = ???
2121
}
2222

tests/pos/typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ object typers {
8888
}
8989

9090
class Refinements {
91-
val y: C { type T; val key: T; def process(x: T): Int }
91+
val y: C { type T; val key: T; def process(x: T): Int } = ???
9292
}
9393

9494
object Accessibility {

0 commit comments

Comments
 (0)