Skip to content

Commit

Permalink
Remove false unchecked warnings on refined types
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Mar 17, 2022
1 parent fe7535f commit b53fdea
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
* Normalization is as follows: If `tp2` contains a skolem to its refinement type,
* rebase both itself and the member info of `tp` on a freshly created skolem type.
*/
protected def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean =
def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean =
trace(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}), mbr: ${tp1.member(name).info}", subtyping) {

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

def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType)(using Context): Boolean =
comparing(_.hasMatchingMember(name, tp1, tp2))

def matchingMethodParams(tp1: MethodType, tp2: MethodType)(using Context): Boolean =
comparing(_.matchingMethodParams(tp1, tp2))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ object TypeTestsCasts {
case AndType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
case OrType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
case AnnotatedType(t, _) => recur(X, t)
case _: RefinedType => false
case tp2: RefinedType => recur(X, tp2.parent) && TypeComparer.hasMatchingMember(tp2.refinedName, X, tp2)
case _ => true
})

Expand Down
22 changes: 22 additions & 0 deletions tests/neg-custom-args/isInstanceOf/refined-types.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class A
class B extends A
type AA = A { type T = Int }
type BA = B { type T = Int }
type AL = A { type T >: Int }
type BL = B { type T >: Int }
type AU = A { type T <: Int }
type BU = B { type T <: Int }

def aa(x: AA) = x.isInstanceOf[BA] // was: the type test for BA cannot be checked at runtime
def al(x: AL) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime
def au(x: AU) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime

// an alias leaves nothing unchecked when type testing against one bound:
def bl(x: AA) = x.isInstanceOf[BL] // was: the type test for BL cannot be checked at runtime
def bu(x: AA) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime

// but static knowledge of only one bound makes checking against an alias unchecked:
def al_ba(x: AL) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime
def au_ba(x: AU) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime
def al_bu(x: AL) = x.isInstanceOf[BU] // error: the type test for BU cannot be checked at runtime
def au_bl(x: AU) = x.isInstanceOf[BL] // error: the type test for BL cannot be checked at runtime

0 comments on commit b53fdea

Please sign in to comment.