From 8b80c3dc8cdf448b0860754070a9bb3eed084760 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 26 Jun 2023 11:32:42 +0200 Subject: [PATCH 1/2] On invalid prefix, throw a TypeError Previously, the type was set to UnspecifiedErrorType. But that violates the rule that every ErrorType has to be reported. If that does not happen, crashes in pickler will result. --- compiler/src/dotty/tools/dotc/core/Types.scala | 6 +++++- compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala | 3 +++ tests/neg/i18058.scala | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i18058.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index bbec037ebef1..c8f1ea53291e 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2751,7 +2751,8 @@ object Types { NamedType(prefix, name, d) } if (prefix eq this.prefix) this - else if !NamedType.validPrefix(prefix) then UnspecifiedErrorType + else if !NamedType.validPrefix(prefix) then + throw TypeError(em"invalid new prefix $prefix cannot replace ${this.prefix} in type $this") else if (lastDenotation == null) NamedType(prefix, designator) else designator match { case sym: Symbol => @@ -5400,6 +5401,9 @@ object Types { def explanation(using Context): String = msg.message } + /** Note: Make sure an errors is reported before construtcing this + * as the type of a tree. + */ object ErrorType: def apply(m: Message)(using Context): ErrorType = val et = new PreviousErrorType diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 645c6f81e539..b5042c295932 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -699,6 +699,9 @@ class TreePickler(pickler: TastyPickler) { case ex: AssertionError => println(i"error when pickling tree $tree") throw ex + case ex: MatchError => + println(i"error when pickling tree $tree") + throw ex } } diff --git a/tests/neg/i18058.scala b/tests/neg/i18058.scala new file mode 100644 index 000000000000..b7309294aade --- /dev/null +++ b/tests/neg/i18058.scala @@ -0,0 +1,4 @@ +trait F: + type A + +type G = (f: _ <: F) => f.A // error From 7a68165af9086af853cac4e52b944fd4a74dca0b Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 26 Jun 2023 13:12:55 +0200 Subject: [PATCH 2/2] Fix tests and add check files --- compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala | 2 +- tests/neg/i12448.scala | 4 ++-- tests/neg/i16842.check | 4 ++++ tests/neg/i16842.scala | 2 +- tests/neg/i18058.check | 4 ++++ 5 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i16842.check create mode 100644 tests/neg/i18058.check diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index b5042c295932..54d064454f13 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -699,7 +699,7 @@ class TreePickler(pickler: TastyPickler) { case ex: AssertionError => println(i"error when pickling tree $tree") throw ex - case ex: MatchError => + case ex: MatchError => println(i"error when pickling tree $tree") throw ex } diff --git a/tests/neg/i12448.scala b/tests/neg/i12448.scala index e495cfd19f1d..dab781729ae1 100644 --- a/tests/neg/i12448.scala +++ b/tests/neg/i12448.scala @@ -1,5 +1,5 @@ object Main { def mkArray[T <: A]: T#AType // error // error - mkArray[Array] // was: "assertion failed: invalid prefix HKTypeLambda..." - val x = mkArray[Array] + mkArray[Array] // was: "assertion failed: invalid prefix HKTypeLambda..." // error + val x = mkArray[Array] // error } diff --git a/tests/neg/i16842.check b/tests/neg/i16842.check new file mode 100644 index 000000000000..936b08f95dbb --- /dev/null +++ b/tests/neg/i16842.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i16842.scala:24:7 ---------------------------------------------------------------------------------- +24 | Liter(SemanticArray[SemanticInt.type], x) // error + | ^ + | invalid new prefix (dim: Int): SemanticArray[SemanticInt.type] cannot replace ty.type in type ty.T diff --git a/tests/neg/i16842.scala b/tests/neg/i16842.scala index 1e7e5cc14339..e9935b46c01d 100644 --- a/tests/neg/i16842.scala +++ b/tests/neg/i16842.scala @@ -21,5 +21,5 @@ def typecheckArrayLiter( a: ArrayLiter ): Liter[SemanticArray[SemanticType]] = { val x: List[Expr2[SemanticInt.type]] = List() - Liter(SemanticArray[SemanticInt.type], x) // error // error + Liter(SemanticArray[SemanticInt.type], x) // error } diff --git a/tests/neg/i18058.check b/tests/neg/i18058.check new file mode 100644 index 000000000000..2622eeb82a45 --- /dev/null +++ b/tests/neg/i18058.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i18058.scala:4:21 ---------------------------------------------------------------------------------- +4 |type G = (f: _ <: F) => f.A // error + | ^ + | invalid new prefix <: F cannot replace f.type in type f.A