diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index e2505144abda..4ad31d65550c 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -418,6 +418,7 @@ object PatternMatcher {
               && !hasExplicitTypeArgs(extractor)
             case _ => false
           }
+          
           TestPlan(TypeTest(tpt, isTrusted), scrutinee, tree.span,
             letAbstract(ref(scrutinee).cast(tpt.tpe)) { casted =>
               nonNull += casted
diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
index a8c8ec8ce1d8..4798683da68b 100644
--- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
@@ -330,13 +330,17 @@ object TypeTestsCasts {
             expr.isInstance(testType).withSpan(tree.span)
           case OrType(tp1, tp2) =>
             evalOnce(expr) { e =>
-              transformTypeTest(e, tp1, flagUnrelated = false)
-                .or(transformTypeTest(e, tp2, flagUnrelated = false))
+              lazy val tp1Tree = transformTypeTest(e, tp1, flagUnrelated = false)
+              lazy val tp2Tree = transformTypeTest(e, tp2, flagUnrelated = false)
+
+              if (tp1.isNothingType || (tp1.isNullType && !tp2.isNotNull)) tp2Tree
+              else if (tp2.isNothingType || (tp2.isNullType && !tp1.isNotNull)) tp1Tree
+              else tp1Tree.or(tp2Tree)
             }
           case AndType(tp1, tp2) =>
             evalOnce(expr) { e =>
               transformTypeTest(e, tp1, flagUnrelated)
-                .and(transformTypeTest(e, tp2, flagUnrelated))
+              .and(transformTypeTest(e, tp2, flagUnrelated))
             }
           case defn.MultiArrayOf(elem, ndims) if isGenericArrayElement(elem, isScala2 = false) =>
             def isArrayTest(arg: Tree) =
diff --git a/tests/neg/i23243.check b/tests/neg/i23243.check
new file mode 100644
index 000000000000..9a73f6ef280d
--- /dev/null
+++ b/tests/neg/i23243.check
@@ -0,0 +1,4 @@
+-- Error: tests\neg\i23243.scala:8:20 ----------------------------------------------------------------------------------
+8 |    case Extractor() => println("foo matched") // error
+  |                    ^
+  |                    String | Null cannot be used in runtime type tests
diff --git a/tests/neg/i23243.scala b/tests/neg/i23243.scala
new file mode 100644
index 000000000000..9dd748da53ed
--- /dev/null
+++ b/tests/neg/i23243.scala
@@ -0,0 +1,9 @@
+object Extractor:
+  def unapply(s: String|Null): Boolean = true
+  
+class A
+
+def main =
+  ("foo": (A|String)) match
+    case Extractor() => println("foo matched") // error
+    case _ => println("foo didn't match")
diff --git a/tests/neg/i23243a.scala b/tests/neg/i23243a.scala
new file mode 100644
index 000000000000..c6330e49c17e
--- /dev/null
+++ b/tests/neg/i23243a.scala
@@ -0,0 +1,8 @@
+def main = {
+  ("foo": String) match {
+    case a: (String | Nothing) => // error
+      println("bar")
+    case _ =>
+      println("foo")
+  }
+}
diff --git a/tests/neg/i4004.scala b/tests/neg/i4004.scala
index bf757a0863a7..37b55891fd83 100644
--- a/tests/neg/i4004.scala
+++ b/tests/neg/i4004.scala
@@ -1,13 +1,8 @@
 @main def Test =
-  "a".isInstanceOf[Null] // error
-  null.isInstanceOf[Null] // error
-  "a".isInstanceOf[Nothing] // error
-  "a".isInstanceOf[Singleton] // error
 
   "a" match
   case _: Null => () // error
   case _: Nothing => () // error
-  case _: Singleton => () // error
   case _ => ()
 
   null match
diff --git a/tests/neg/i4004a.scala b/tests/neg/i4004a.scala
new file mode 100644
index 000000000000..10201409c908
--- /dev/null
+++ b/tests/neg/i4004a.scala
@@ -0,0 +1,10 @@
+@main def Test =
+   "a".isInstanceOf[Null] // error
+   null.isInstanceOf[Null] // error
+   "a".isInstanceOf[Nothing] // error
+   "a".isInstanceOf[Singleton] // error
+   
+   "a" match {
+    case _: Singleton => () // error
+    case _ => ()
+   }