Skip to content

Commit

Permalink
Handle OrType in local class checking
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Jul 6, 2022
1 parent 62fdf0e commit 7f51a86
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
20 changes: 10 additions & 10 deletions compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ object TypeTestsCasts {
case tp2: RefinedType => recur(X, tp2.parent) && TypeComparer.hasMatchingMember(tp2.refinedName, X, tp2)
case tp2: RecType => recur(X, tp2.parent)
case _
if P.classSymbol.isLocal && P.classSymbol.isInaccessibleChildOf(X.classSymbol) => // 8
if P.classSymbol.isLocal && foundClasses(X, Nil).exists(P.classSymbol.isInaccessibleChildOf) => // 8
false
case _ => true
})
Expand All @@ -178,15 +178,6 @@ object TypeTestsCasts {
def derivedTree(expr1: Tree, sym: Symbol, tp: Type) =
cpy.TypeApply(tree)(expr1.select(sym).withSpan(expr.span), List(TypeTree(tp)))

def effectiveClass(tp: Type): Symbol =
if tp.isRef(defn.PairClass) then effectiveClass(erasure(tp))
else if tp.isRef(defn.AnyValClass) then defn.AnyClass
else tp.classSymbol

def foundClasses(tp: Type, acc: List[Symbol]): List[Symbol] = tp.dealias match
case OrType(tp1, tp2) => foundClasses(tp2, foundClasses(tp1, acc))
case _ => effectiveClass(tp) :: acc

def inMatch =
tree.fun.symbol == defn.Any_typeTest || // new scheme
expr.symbol.is(Case) // old scheme
Expand Down Expand Up @@ -376,4 +367,13 @@ object TypeTestsCasts {
}
interceptWith(expr)
}

private def effectiveClass(tp: Type)(using Context): Symbol =
if tp.isRef(defn.PairClass) then effectiveClass(erasure(tp))
else if tp.isRef(defn.AnyValClass) then defn.AnyClass
else tp.classSymbol

private def foundClasses(tp: Type, acc: List[Symbol])(using Context): List[Symbol] = tp.dealias match
case OrType(tp1, tp2) => foundClasses(tp2, foundClasses(tp1, acc))
case _ => effectiveClass(tp) :: acc
}
6 changes: 6 additions & 0 deletions tests/neg/i4812.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ object Test:
x match
case x: B => x

def test12 =
class Foo
class Bar
val x: Foo | Bar = new Foo
x.isInstanceOf[Foo]

def main(args: Array[String]): Unit =
test(1)
val x: String = test("") // was: ClassCastException: java.lang.Integer cannot be cast to java.lang.String

0 comments on commit 7f51a86

Please sign in to comment.