object lib {
  inline def (op: => T) rescue[T] (fallback: => T) =
    try op
    catch {
      case _: Throwable => fallback
    }

  inline def (op: => T) rescue[T, E <: Throwable] (fallback: PartialFunction[E, T]) =
    try op
    catch {
      case ex: E =>
        if (fallback.isDefinedAt(ex)) fallback(ex) else throw ex
    }
}

import lib._

@main def Test = {
  assert((9 / 1 rescue 1) == 9)
  assert((9 / 0 rescue 1) == 1)
  assert(((9 / 0 rescue { case ex: NullPointerException => 5  }) rescue 10) == 10)
  assert(((9 / 0 rescue { case ex: ArithmeticException => 5  }) rescue 10) == 5)

  assert(
    {
      9 / 0 rescue {
        case ex: NullPointerException => 4
        case ex: ArithmeticException => 3
      }
    } == 3
  )

  assert(
    {
      {
        val a = 9 / 0 rescue {
          case ex: NullPointerException => 4
        }
        a * a
      } rescue {
        case ex: ArithmeticException => 3
      }
    } == 3
  )
}

object lib {
  inline def (op: => T) rescue[T] (fallback: => T) = try op catch { case _: Throwable => fallback }
  inline def (op: => T) rescue[T, E <: Throwable] (fallback: E => T) = try op catch { case ex: E => fallback(ex) }
}

import lib._

@main def Test = {
  assert((9 / 1 rescue 1) == 9)
  assert((9 / 0 rescue 1) == 1)
  assert(((9 / 0 rescue { ex: NullPointerException => 5  }) rescue 10) == 10)
  assert(((9 / 0 rescue { ex: ArithmeticException => 5  }) rescue 10) == 5)

  assert((9 / 0 rescue {
    case ex: NullPointerException => 4
    case ex: ArithmeticException => 3
  }) == 3)
}

--- 
+++ 
@@ -1,6 +1,16 @@
 object lib {
-  inline def (op: => T) rescue[T] (fallback: => T) = try op catch { case _: Throwable => fallback }
-  inline def (op: => T) rescue[T, E <: Throwable] (fallback: E => T) = try op catch { case ex: E => fallback(ex) }
+  inline def (op: => T) rescue[T] (fallback: => T) =
+    try op
+    catch {
+      case _: Throwable => fallback
+    }
+
+  inline def (op: => T) rescue[T, E <: Throwable] (fallback: PartialFunction[E, T]) =
+    try op
+    catch {
+      case ex: E =>
+        if (fallback.isDefinedAt(ex)) fallback(ex) else throw ex
+    }
 }
 
 import lib._
@@ -8,11 +18,28 @@
 @main def Test = {
   assert((9 / 1 rescue 1) == 9)
   assert((9 / 0 rescue 1) == 1)
-  assert(((9 / 0 rescue { ex: NullPointerException => 5  }) rescue 10) == 10)
-  assert(((9 / 0 rescue { ex: ArithmeticException => 5  }) rescue 10) == 5)
+  assert(((9 / 0 rescue { case ex: NullPointerException => 5  }) rescue 10) == 10)
+  assert(((9 / 0 rescue { case ex: ArithmeticException => 5  }) rescue 10) == 5)
 
-  assert((9 / 0 rescue {
-    case ex: NullPointerException => 4
-    case ex: ArithmeticException => 3
-  }) == 3)
+  assert(
+    {
+      9 / 0 rescue {
+        case ex: NullPointerException => 4
+        case ex: ArithmeticException => 3
+      }
+    } == 3
+  )
+
+  assert(
+    {
+      {
+        val a = 9 / 0 rescue {
+          case ex: NullPointerException => 4
+        }
+        a * a
+      } rescue {
+        case ex: ArithmeticException => 3
+      }
+    } == 3
+  )
 }
Use partial functions in interface (thanks @smarter)

Without the change, exceptions other than the following will not be propagated.
Instead, users will get `scala.MatchError`.

     op rescue {
        case ex: NullPointerException => 4
        case ex: ArithmeticException => 3
      }
