From 46bfe909afd0a0607ce327063b5332d788d809e9 Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 12 Mar 2024 22:11:44 +0100 Subject: [PATCH 1/2] Don't allow implicit conversions on prefixes of type selections Fixes #19888 --- .../src/dotty/tools/dotc/typer/Typer.scala | 6 ++-- tests/neg/i11994.check | 34 ++++++------------- tests/neg/i19888.scala | 16 +++++++++ 3 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 tests/neg/i19888.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 47bd25e5d45e..549ebcdc49a1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -714,9 +714,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val elems = qual.tpe.widenTermRefExpr.tupleElementTypes.getOrElse(Nil) typedSelect(tree, pt, qual.cast(defn.tupleType(elems))) else - val tree1 = tryExtensionOrConversion( + val tree1 = { + if selName.isTypeName then EmptyTree + else tryExtensionOrConversion( tree, pt, IgnoredProto(pt), qual, ctx.typerState.ownedVars, this, inSelect = true) - .orElse { + }.orElse { if ctx.gadt.isNarrowing then // try GADT approximation if we're trying to select a member // Member lookup cannot take GADTs into account b/c of cache, so we diff --git a/tests/neg/i11994.check b/tests/neg/i11994.check index 76860af70a39..8895515898c2 100644 --- a/tests/neg/i11994.check +++ b/tests/neg/i11994.check @@ -1,26 +1,12 @@ --- [E008] Not Found Error: tests/neg/i11994.scala:2:28 ----------------------------------------------------------------- -2 |implicit def foo[T <: Tuple.meow]: Unit = ??? // error - | ^^^^^^^^^^ - | type meow is not a member of object Tuple. - | Extension methods were tried, but the search failed with: - | - | Cyclic reference involving method foo - | - | The error occurred while trying to compute the signature of method foo - | which required to compute the signature of type T - | which required to compute the signature of method foo - | - | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. --- [E008] Not Found Error: tests/neg/i11994.scala:3:18 ----------------------------------------------------------------- +-- [E046] Cyclic Error: tests/neg/i11994.scala:3:18 -------------------------------------------------------------------- 3 |given [T <: Tuple.meow]: Unit = ??? // error - | ^^^^^^^^^^ - | type meow is not a member of object Tuple. - | Extension methods were tried, but the search failed with: + | ^ + | Cyclic reference involving method given_Unit + | + | The error occurred while trying to compute the signature of given instance given_Unit + | which required to compute the signature of type T + | which required to compute the signature of given instance given_Unit + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. | - | Cyclic reference involving method given_Unit - | - | The error occurred while trying to compute the signature of given instance given_Unit - | which required to compute the signature of type T - | which required to compute the signature of given instance given_Unit - | - | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i19888.scala b/tests/neg/i19888.scala new file mode 100644 index 000000000000..d258672feed6 --- /dev/null +++ b/tests/neg/i19888.scala @@ -0,0 +1,16 @@ +object Main{ + object Foo + object Bar{ type Qux = Unit } + + + implicit def conv(f: Foo.type): Bar.type = Bar + + def B: Bar.type = Bar + + def main(args: Array[String]): Unit = { + val x: Foo.Qux = null // error + val y: B.Qux = null + println(x) + println(y) + } +} \ No newline at end of file From b5cff5717bd6830f3cef6112308c705ff762b5b4 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 13 Mar 2024 19:05:25 +0100 Subject: [PATCH 2/2] Put all code in import suggestions under a try-catch There was a val that escaped before, which caused cyclic references raised during importSuggestions to be reported instead of being ignored. --- .../tools/dotc/typer/ImportSuggestions.scala | 2 +- tests/neg/i11994.check | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala b/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala index 7615fbda9f0a..33643a0fae2f 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala @@ -158,7 +158,7 @@ trait ImportSuggestions: // Candidates that are already available without explicit import because they // are already provided by the context (imported or inherited) or because they // are in the implicit scope of `pt`. - val alreadyAvailableCandidates: Set[Symbol] = { + lazy val alreadyAvailableCandidates: Set[Symbol] = { val wildProto = wildApprox(pt) val contextualCandidates = ctx.implicits.eligible(wildProto) val implicitScopeCandidates = ctx.run.nn.implicitScope(wildProto).eligible diff --git a/tests/neg/i11994.check b/tests/neg/i11994.check index 8895515898c2..fcb49fe3411d 100644 --- a/tests/neg/i11994.check +++ b/tests/neg/i11994.check @@ -1,12 +1,8 @@ --- [E046] Cyclic Error: tests/neg/i11994.scala:3:18 -------------------------------------------------------------------- +-- [E008] Not Found Error: tests/neg/i11994.scala:2:28 ----------------------------------------------------------------- +2 |implicit def foo[T <: Tuple.meow]: Unit = ??? // error + | ^^^^^^^^^^ + | type meow is not a member of object Tuple +-- [E008] Not Found Error: tests/neg/i11994.scala:3:18 ----------------------------------------------------------------- 3 |given [T <: Tuple.meow]: Unit = ??? // error - | ^ - | Cyclic reference involving method given_Unit - | - | The error occurred while trying to compute the signature of given instance given_Unit - | which required to compute the signature of type T - | which required to compute the signature of given instance given_Unit - | - | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. - | - | longer explanation available when compiling with `-explain` + | ^^^^^^^^^^ + | type meow is not a member of object Tuple