forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix scala#5067: Ycheck failure in pattern matching against a value of…
… type `Nothing` When desugaring pattern matching code for expressions where the matched value has type `Null` or `Nothing`, we used to generate code that's type-incorrect. Example: ``` val Some(x) = null ``` got desugared into ``` val x: Nothing = matchResult1[Nothing]: { case val x1: Null @unchecked = null: Null @unchecked if x1.ne(null) then { case val x: Nothing = x1.value.asInstanceOf[Nothing] return[matchResult1] x: Nothing } else () return[matchResult1] throw new MatchError(x1) } ``` There were two problems here: 1) `x1.ne(null)` 2) `x1.value` In both cases, we're trying to invoke methods that don't exist for type `Nothing` (and #2 doesn't exist for `Null`). This commit changes the desugaring so we generate a no-op for unapply when the value matched has type `Nothing` or `Null`. This works because the code we used to generate is never executed (because the `x1.ne(null)`) check.
- Loading branch information
Showing
6 changed files
with
72 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
class Foo { | ||
val Some(_) = ??? | ||
val (_, _, _) = ??? | ||
??? match { | ||
case Some(_) => () | ||
case (_, _, _) => () | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
matches null literal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
match error | ||
match error nested | ||
not implemented error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
class B[T] {} | ||
object B { | ||
def unapply[T](x: Any): Option[B[T]] = None | ||
} | ||
try { | ||
val B(_) = null | ||
} catch { | ||
case e: MatchError => println("match error") | ||
} | ||
|
||
null match { | ||
case null => | ||
try { | ||
null match { | ||
case Some(_) => () | ||
} | ||
} catch { | ||
case e: MatchError => println("match error nested") | ||
} | ||
} | ||
|
||
try { | ||
??? match { | ||
case (_, _) => () | ||
case _ => () | ||
} | ||
} catch { | ||
case e: NotImplementedError => println("not implemented error") | ||
} | ||
} | ||
} |