Skip to content

Commit 1b3b399

Browse files
committed
Remove false unchecked warnings on refined types
1 parent fe7535f commit 1b3b399

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -1764,11 +1764,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
17641764
case _ => false
17651765

17661766
/** Does type `tp1` have a member with name `name` whose normalized type is a subtype of
1767-
* the normalized type of the refinement `tp2`?
1767+
* the normalized type of the refinement of `tp2`?
17681768
* Normalization is as follows: If `tp2` contains a skolem to its refinement type,
17691769
* rebase both itself and the member info of `tp` on a freshly created skolem type.
17701770
*/
1771-
protected def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean =
1771+
def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean =
17721772
trace(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}), mbr: ${tp1.member(name).info}", subtyping) {
17731773

17741774
def qualifies(m: SingleDenotation): Boolean =
@@ -2750,6 +2750,9 @@ object TypeComparer {
27502750
def matchesType(tp1: Type, tp2: Type, relaxed: Boolean)(using Context): Boolean =
27512751
comparing(_.matchesType(tp1, tp2, relaxed))
27522752

2753+
def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType)(using Context): Boolean =
2754+
comparing(_.hasMatchingMember(name, tp1, tp2))
2755+
27532756
def matchingMethodParams(tp1: MethodType, tp2: MethodType)(using Context): Boolean =
27542757
comparing(_.matchingMethodParams(tp1, tp2))
27552758

compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ object TypeTestsCasts {
150150
case AndType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
151151
case OrType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
152152
case AnnotatedType(t, _) => recur(X, t)
153-
case _: RefinedType => false
153+
case tp2: RefinedType => recur(X, tp2.parent) && TypeComparer.hasMatchingMember(tp2.refinedName, X, tp2)
154154
case _ => true
155155
})
156156

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class A
2+
class B extends A
3+
type AA = A { type T = Int }
4+
type BA = B { type T = Int }
5+
type AL = A { type T >: Int }
6+
type BL = B { type T >: Int }
7+
type AU = A { type T <: Int }
8+
type BU = B { type T <: Int }
9+
10+
def aa(x: AA) = x.isInstanceOf[BA] // was: the type test for BA cannot be checked at runtime
11+
def al(x: AL) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime
12+
def au(x: AU) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime
13+
14+
// an alias leaves nothing unchecked when type testing against one bound:
15+
def bl(x: AA) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime
16+
def bu(x: AA) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime
17+
18+
// but static knowledge of only one bound makes checking against an alias unchecked:
19+
def al_ba(x: AL) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime
20+
def au_ba(x: AU) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime
21+
def al_bu(x: AL) = x.isInstanceOf[BU] // error: the type test for BU cannot be checked at runtime
22+
def au_bl(x: AU) = x.isInstanceOf[BL] // error: the type test for BL cannot be checked at runtime

0 commit comments

Comments
 (0)