Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 537211c

Browse files
authored
Add an irrefutable version of the NoSuccess extractor (#496)
1 parent 2ac42b0 commit 537211c

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

‎shared/src/main/scala/scala/util/parsing/combinator/Parsers.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,34 @@ trait Parsers {
176176

177177
def get: Nothing = scala.sys.error("No result when parsing failed")
178178
}
179-
/** An extractor so `NoSuccess(msg, next)` can be used in matches. */
179+
/**
180+
* An extractor so `case NoSuccess(msg, next)` can be used in matches.
181+
*
182+
* Note: On Scala 2.13, using this extractor leads to an exhaustivity warning:
183+
*
184+
* {{{
185+
* def m(r: ParseResult[Int]) = r match {
186+
* case Success(i) => ...
187+
* case NoSuccess(msg, _) => ... // "warning: match may not be exhaustive"
188+
* }}}
189+
*
190+
* To eliminate this warning, use the irrefutable `NoSuccess.I` extractor.
191+
* Due to binary compatibility, `NoSuccess` itself cannot be changed.
192+
*/
180193
object NoSuccess {
181194
def unapply[T](x: ParseResult[T]) = x match {
182195
case Failure(msg, next) => Some((msg, next))
183196
case Error(msg, next) => Some((msg, next))
184197
case _ => None
185198
}
199+
200+
/** An irrefutable version of the `NoSuccess` extractor, used as `case NoSuccess.I(msg, next)`. */
201+
object I {
202+
def unapply(x: NoSuccess): Some[(String, Input)] = x match {
203+
case Failure(msg, next) => Some((msg, next))
204+
case Error(msg, next) => Some((msg, next))
205+
}
206+
}
186207
}
187208

188209
/** The failure case of `ParseResult`: contains an error-message and the remaining input.

‎shared/src/test/scala/scala/util/parsing/combinator/PackratParsersTest.scala

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ class PackratParsersTest {
2828

2929
def extractResult(r : ParseResult[Int]): Int = r match {
3030
case Success(a,_) => a
31-
case NoSuccess(a,_) => sys.error(a)
32-
case Failure(a, _) => sys.error(a)
33-
case Error(a, _) => sys.error(a)
31+
case NoSuccess.I(a,_) => sys.error(a)
3432
}
3533
def check(expected: Int, expr: String): Unit = {
3634
val parseResult = head(new lexical.Scanner(expr))
@@ -84,9 +82,7 @@ class PackratParsersTest {
8482

8583
def extractResult(r : ParseResult[Int]): Int = r match {
8684
case Success(a,_) => a
87-
case NoSuccess(a,_) => sys.error(a)
88-
case Failure(a, _) => sys.error(a)
89-
case Error(a, _) => sys.error(a)
85+
case NoSuccess.I(a,_) => sys.error(a)
9086
}
9187
def check(expected: Int, expr: String): Unit = {
9288
val parseResult = head(new lexical.Scanner(expr))
@@ -109,9 +105,7 @@ class PackratParsersTest {
109105
val head = phrase(AnBnCn)
110106
def extractResult(r: ParseResult[AnBnCnResult]): AnBnCnResult = r match {
111107
case Success(a,_) => a
112-
case NoSuccess(a,_) => sys.error(a)
113-
case Failure(a, _) => sys.error(a)
114-
case Error(a, _) => sys.error(a)
108+
case NoSuccess.I(a,_) => sys.error(a)
115109
}
116110
def threeLists(as: List[Symbol], bs: List[Symbol], cs: List[Symbol]): AnBnCnResult = {
117111
val as1 = as.map(_.name)
@@ -152,9 +146,7 @@ class PackratParsersTest {
152146

153147
def extractResult(r: ParseResult[Res]): Res = r match {
154148
case Success(a,_) => a
155-
case NoSuccess(a,_) => sys.error(a)
156-
case Failure(a, _) => sys.error(a)
157-
case Error(a, _) => sys.error(a)
149+
case NoSuccess.I(a,_) => sys.error(a)
158150
}
159151
def check(expected: Term, input: String, ctx: Ctx): Unit = {
160152
val parseResult = phraseTerm(new lexical.Scanner(input))

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /