From 472555dca6866b4ae1fde35f3abe99579689b8eb Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 14 Sep 2024 12:24:11 +0200 Subject: [PATCH 1/2] Survive inaccessible types when computing implicit scope Also: Give a better error message later when encountering a missing type that refers to a private member of a base class. The previous one was misleading since it referred to a potentially missing class file, which is certainly not the case here. Fixes #21543 --- compiler/src/dotty/tools/dotc/core/TypeErrors.scala | 2 ++ .../src/dotty/tools/dotc/reporting/messages.scala | 8 ++++---- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 4 ++++ tests/neg/i21543.scala | 13 +++++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i21543.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index 11e313c47932..1c9696da67d1 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -73,6 +73,8 @@ class MissingType(val pre: Type, val name: Name)(using Context) extends TypeErro case _ if givenSelf.exists && givenSelf.member(name).exists => i"""$name exists as a member of the self type $givenSelf of $cls |but it cannot be called on a receiver whose type does not extend $cls""" + case _ if pre.baseClasses.exists(_.findMember(name, pre, Private, EmptyFlags).exists) => + i"$name is a private member in a base class" case _ => missingClassFile diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 91642ca51bc5..01eb2acfa4de 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -3292,14 +3292,14 @@ object UnusedSymbol { class NonNamedArgumentInJavaAnnotation(using Context) extends SyntaxMsg(NonNamedArgumentInJavaAnnotationID): - override protected def msg(using Context): String = + override protected def msg(using Context): String = "Named arguments are required for Java defined annotations" + Message.rewriteNotice("This", version = SourceVersion.`3.6-migration`) - override protected def explain(using Context): String = + override protected def explain(using Context): String = i"""Starting from Scala 3.6.0, named arguments are required for Java defined annotations. - |Java defined annotations don't have an exact constructor representation - |and we previously relied on the order of the fields to create one. + |Java defined annotations don't have an exact constructor representation + |and we previously relied on the order of the fields to create one. |One possible issue with this representation is the reordering of the fields. |Lets take the following example: | diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 51e468153d1f..def5bb77519f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -821,6 +821,10 @@ trait ImplicitRunInfo: override def stopAt = StopAt.Static private val seen = util.HashSet[Type]() + override def derivedTypeBounds(tp: TypeBounds, lo: Type, hi: Type): Type = + if lo.exists && hi.exists then super.derivedTypeBounds(tp, lo, hi) + else NoType // Survive inaccessible types, for instance in i21543.scala. + def applyToUnderlying(t: TypeProxy) = if seen.contains(t) then WildcardType diff --git a/tests/neg/i21543.scala b/tests/neg/i21543.scala new file mode 100644 index 000000000000..98de8d3ec939 --- /dev/null +++ b/tests/neg/i21543.scala @@ -0,0 +1,13 @@ +object CompilerCrash { + trait Scope { + private type Event = String + + case class Cmd(events: List[Event]) + } + + new Scope { + val commands = List( + Cmd(List("1", "2")) + ) + } +} \ No newline at end of file From cd9a7c58afaab6d07bab91ebc059d98313a4713d Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 14 Sep 2024 14:22:58 +0200 Subject: [PATCH 2/2] Fix check files --- tests/neg/i20554-a.check | 8 ++++---- tests/neg/i20554-b.check | 4 ++-- tests/neg/i21543.check | 22 ++++++++++++++++++++++ tests/neg/i21543.scala | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 tests/neg/i21543.check diff --git a/tests/neg/i20554-a.check b/tests/neg/i20554-a.check index b223cba32f77..ac0890ba133a 100644 --- a/tests/neg/i20554-a.check +++ b/tests/neg/i20554-a.check @@ -7,8 +7,8 @@ | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Starting from Scala 3.6.0, named arguments are required for Java defined annotations. - | Java defined annotations don't have an exact constructor representation - | and we previously relied on the order of the fields to create one. + | Java defined annotations don't have an exact constructor representation + | and we previously relied on the order of the fields to create one. | One possible issue with this representation is the reordering of the fields. | Lets take the following example: | @@ -29,8 +29,8 @@ | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Starting from Scala 3.6.0, named arguments are required for Java defined annotations. - | Java defined annotations don't have an exact constructor representation - | and we previously relied on the order of the fields to create one. + | Java defined annotations don't have an exact constructor representation + | and we previously relied on the order of the fields to create one. | One possible issue with this representation is the reordering of the fields. | Lets take the following example: | diff --git a/tests/neg/i20554-b.check b/tests/neg/i20554-b.check index 5e5119e043fe..637b48ee93ef 100644 --- a/tests/neg/i20554-b.check +++ b/tests/neg/i20554-b.check @@ -7,8 +7,8 @@ | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Starting from Scala 3.6.0, named arguments are required for Java defined annotations. - | Java defined annotations don't have an exact constructor representation - | and we previously relied on the order of the fields to create one. + | Java defined annotations don't have an exact constructor representation + | and we previously relied on the order of the fields to create one. | One possible issue with this representation is the reordering of the fields. | Lets take the following example: | diff --git a/tests/neg/i21543.check b/tests/neg/i21543.check new file mode 100644 index 000000000000..9fa9a7779d7a --- /dev/null +++ b/tests/neg/i21543.check @@ -0,0 +1,22 @@ +-- [E007] Type Mismatch Error: tests/neg/i21543.scala:10:15 ------------------------------------------------------------ +10 | Cmd(List("1", "2")) // error // error + | ^^^ + | Found: ("1" : String) + | Required: Event + | + | Note that I could not resolve reference Event. + | Event is a private member in a base class + | + | + | longer explanation available when compiling with `-explain` +-- [E007] Type Mismatch Error: tests/neg/i21543.scala:10:20 ------------------------------------------------------------ +10 | Cmd(List("1", "2")) // error // error + | ^^^ + | Found: ("2" : String) + | Required: Event + | + | Note that I could not resolve reference Event. + | Event is a private member in a base class + | + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i21543.scala b/tests/neg/i21543.scala index 98de8d3ec939..aaadce6d22b4 100644 --- a/tests/neg/i21543.scala +++ b/tests/neg/i21543.scala @@ -7,7 +7,7 @@ object CompilerCrash { new Scope { val commands = List( - Cmd(List("1", "2")) + Cmd(List("1", "2")) // error // error ) } } \ No newline at end of file