From 3c8545b8293b903ffe9178060ad1b630f19762f1 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Tue, 1 May 2018 23:38:49 +0200
Subject: [PATCH 1/4] Prevent position errors on Ident(nme.ERROR)
```
Exception in thread "main" java.lang.AssertionError: assertion failed: position error: position not set for Ident() # 24
at dotty.DottyPredef$.assertFail(DottyPredef.scala:36)
at dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:178)
at dotty.tools.dotc.ast.Positioned.check$5$$anonfun$4(Positioned.scala:203)
```
---
compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 12 ++++++++++--
tests/neg/parser-stability-23.scala | 3 +++
2 files changed, 13 insertions(+), 2 deletions(-)
create mode 100644 tests/neg/parser-stability-23.scala
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index edaf6850d8cf..5a8cfd3a4bea 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -518,8 +518,16 @@ object Parsers {
}
/** Accept identifier and return Ident with its name as a term name. */
- def termIdent(): Ident = atPos(in.offset) {
- makeIdent(in.token, ident())
+ def termIdent(): Ident = {
+ val start = in.offset
+ val id = makeIdent(in.token, ident())
+ if (id.name != nme.ERROR) {
+ atPos(start)(id)
+ } else {
+ // error identifiers don't consume any characters, so atPos(start)(id) wouldn't set a position.
+ // Some testcases would then fail in Positioned.checkPos. Set a position anyway!
+ atPos(start, start, in.lastOffset)(id)
+ }
}
/** Accept identifier and return Ident with its name as a type name. */
diff --git a/tests/neg/parser-stability-23.scala b/tests/neg/parser-stability-23.scala
new file mode 100644
index 000000000000..b8db4d937f25
--- /dev/null
+++ b/tests/neg/parser-stability-23.scala
@@ -0,0 +1,3 @@
+object i0 {
+ import Ordering.{ implicitly => } (true: Boolean) match { case _: i1 => true } // error // error
+}
From ad04880cd3f1af0e7e147e7fc31499c26ee7207f Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Wed, 2 May 2018 18:10:31 +0200
Subject: [PATCH 2/4] Revert parts of "Prevent position errors on
Ident(nme.ERROR)"
This reverts commit 0f7b1b0bba2f644141796be5217c3019ee643b2f but keeps the
testcase.
---
compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 5a8cfd3a4bea..edaf6850d8cf 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -518,16 +518,8 @@ object Parsers {
}
/** Accept identifier and return Ident with its name as a term name. */
- def termIdent(): Ident = {
- val start = in.offset
- val id = makeIdent(in.token, ident())
- if (id.name != nme.ERROR) {
- atPos(start)(id)
- } else {
- // error identifiers don't consume any characters, so atPos(start)(id) wouldn't set a position.
- // Some testcases would then fail in Positioned.checkPos. Set a position anyway!
- atPos(start, start, in.lastOffset)(id)
- }
+ def termIdent(): Ident = atPos(in.offset) {
+ makeIdent(in.token, ident())
}
/** Accept identifier and return Ident with its name as a type name. */
From 83610bb6fe4bd12e15b1462dd819bdb6bb079c4c Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Wed, 2 May 2018 18:06:37 +0200
Subject: [PATCH 3/4] Alternative fix
---
.../src/dotty/tools/dotc/parsing/Parsers.scala | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index edaf6850d8cf..4afea33c5798 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1975,11 +1975,24 @@ object Parsers {
/** ImportSelector ::= id [`=>' id | `=>' `_']
*/
def importSelector(): Tree = {
+ val start = in.offset
val from = termIdentOrWildcard()
if (from.name != nme.WILDCARD && in.token == ARROW)
atPos(startOffset(from), in.skipToken()) {
- Thicket(from, termIdentOrWildcard())
+ val start2 = in.offset
+ val to = termIdentOrWildcard()
+ val toWithPos =
+ if (to.name == nme.ERROR)
+ // error identifiers don't consume any characters, so atPos(start)(id) wouldn't set a position.
+ // Some testcases would then fail in Positioned.checkPos. Set a position anyway!
+ atPos(start2, start2, in.lastOffset)(to)
+ else
+ to
+ Thicket(from, toWithPos)
}
+ else if (from.name == nme.ERROR) {
+ atPos(start, start, in.lastOffset)(from)
+ }
else from
}
From 78afe8a3e81eb45da95c8164945c5d26e8237f86 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Wed, 2 May 2018 18:13:47 +0200
Subject: [PATCH 4/4] Simplify fix
---
compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 4afea33c5798..18e10817477f 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1975,24 +1975,20 @@ object Parsers {
/** ImportSelector ::= id [`=>' id | `=>' `_']
*/
def importSelector(): Tree = {
- val start = in.offset
val from = termIdentOrWildcard()
if (from.name != nme.WILDCARD && in.token == ARROW)
atPos(startOffset(from), in.skipToken()) {
- val start2 = in.offset
+ val start = in.offset
val to = termIdentOrWildcard()
val toWithPos =
if (to.name == nme.ERROR)
// error identifiers don't consume any characters, so atPos(start)(id) wouldn't set a position.
// Some testcases would then fail in Positioned.checkPos. Set a position anyway!
- atPos(start2, start2, in.lastOffset)(to)
+ atPos(start, start, in.lastOffset)(to)
else
to
Thicket(from, toWithPos)
}
- else if (from.name == nme.ERROR) {
- atPos(start, start, in.lastOffset)(from)
- }
else from
}