Skip to content

Commit ebb616c

Browse files
committed
Use typed directly instead of finding conversions
1 parent 9579aa5 commit ebb616c

File tree

4 files changed

+39
-40
lines changed

4 files changed

+39
-40
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,7 @@ class MissingImplicitArgument(
25552555
where: String,
25562556
paramSymWithMethodCallTree: Option[(Symbol, tpd.Tree)] = None,
25572557
ignoredInstanceNormalImport: => Option[SearchSuccess],
2558-
ignoredConversions: => Iterable[(TermRef, Iterable[TermRef])]
2558+
ignoredConvertibleImplicits: => Iterable[TermRef]
25592559
)(using Context) extends TypeMsg(MissingImplicitArgumentID), ShowMatchTrace(pt):
25602560

25612561
arg.tpe match
@@ -2746,19 +2746,16 @@ class MissingImplicitArgument(
27462746
i"\n\nNote: ${s.ref.symbol.showLocated} was not considered because it was not imported with `import given`."
27472747
def showImplicitAndConversions(imp: TermRef, convs: Iterable[TermRef]) =
27482748
i"\n- ${imp.symbol.showDcl}${convs.map(c => "\n - " + c.symbol.showDcl).mkString}"
2749-
def noChainConversionsNote(ignoredConversions: Iterable[(TermRef, Iterable[TermRef])]): Option[String] = {
2750-
val convsFormatted = ignoredConversions.map{ (imp, convs) =>
2751-
s"\n- ${imp.symbol.showDcl}${convs.map(c => "\n - " + c.symbol.showDcl).mkString}"
2752-
}.mkString
2753-
Option.when(ignoredConversions.nonEmpty)(
2754-
i"\n\nNote: implicit conversions are not automatically applied to arguments of using clauses. " +
2755-
i"You will have to pass the argument explicitly.\n" +
2756-
i"The following conversions in scope result in ${pt.show}: $convsFormatted"
2749+
def noChainConversionsNote(ignoredConvertibleImplicits: Iterable[TermRef]): Option[String] =
2750+
Option.when(ignoredConvertibleImplicits.nonEmpty)(
2751+
i"\n\nNote: implicit conversions are not automatically applied to arguments of using clauses. " +
2752+
i"You will have to pass the argument explicitly.\n" +
2753+
i"The following implicits in scope can be converted to ${pt.show}:" +
2754+
ignoredConvertibleImplicits.map { imp => s"\n- ${imp.symbol.showDcl}"}.mkString
27572755
)
2758-
}
27592756
super.msgPostscript
27602757
++ ignoredInstanceNormalImport.map(hiddenImplicitNote)
2761-
.orElse(noChainConversionsNote(ignoredConversions))
2758+
.orElse(noChainConversionsNote(ignoredConvertibleImplicits))
27622759
.getOrElse(ctx.typer.importSuggestionAddendum(pt))
27632760

27642761
def explain(using Context) = ""

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -934,26 +934,34 @@ trait Implicits:
934934
case _ => true
935935
}
936936

937+
def isScala2Conv(typ: Type): Boolean = typ match {
938+
case PolyType(_, resType) => isScala2Conv(resType)
939+
case mt: MethodType =>
940+
(!mt.resultType.isImplicitMethod && !mt.resultType.isContextualMethod)
941+
|| isScala2Conv(mt.resultType)
942+
case _ => false
943+
}
944+
937945
def ignoredConversions = arg.tpe match
938946
case fail: SearchFailureType =>
939947
// Get every implicit in scope and find Conversions for each
940948
if (fail.expectedType eq pt) || isFullyDefined(fail.expectedType, ForceDegree.none) then
941-
// todo filter out implicit conversions
942949
allImplicits(ctx.implicits)
943-
.filter(imp => notImplicitConv(imp.underlyingRef.underlying))
944-
.map { imp =>
945-
val impRef = imp.underlyingRef
946-
val impResultType = wildApprox(impRef.underlying.finalResultType)
947-
val convs = ctx.implicits.eligible(ViewProto(impResultType, fail.expectedType))
948-
.filter { conv =>
949-
if !conv.isConversion then false
950-
else
951-
// TODO Actually feed the summoned implicit into the Conversion to
952-
// check if it works
953-
true
954-
}
955-
(impRef, convs.map(_.ref))
956-
}.filter(_._2.nonEmpty)
950+
.map(_.underlyingRef)
951+
.filter { imp =>
952+
if notImplicitConv(imp.underlying) then false
953+
else
954+
val locked = ctx.typerState.ownedVars
955+
val tryCtx = ctx.fresh
956+
val tried = Contexts.withMode(Mode.Printing) {
957+
typed(
958+
tpd.ref(imp).withSpan(arg.span),
959+
fail.expectedType,
960+
locked
961+
)
962+
}(using tryCtx)
963+
!tryCtx.reporter.hasErrors && fail.expectedType =:= tried.tpe
964+
}
957965
else
958966
Nil
959967

tests/neg/i16453.check

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
-- [E172] Type Error: tests/neg/i16453.scala:14:21 ---------------------------------------------------------------------
2-
14 | summon[Option[Int]] // error
1+
-- [E172] Type Error: tests/neg/i16453.scala:19:21 ---------------------------------------------------------------------
2+
19 | summon[Option[Int]] // error
33
| ^
44
|No given instance of type Option[Int] was found for parameter x of method summon in object Predef
55
|
66
|Note: implicit conversions are not automatically applied to arguments of using clauses. You will have to pass the argument explicitly.
7-
|The following conversions in scope result in Option[Int]:
8-
| - final given def given_Conversion_T_Option[T]: Conversion[T, Option[T]]
9-
| - implicit def toOption[T](t: T): Option[T]
10-
-- [E172] Type Error: tests/neg/i16453.scala:15:25 ---------------------------------------------------------------------
11-
15 | implicitly[Option[Int]] // error
7+
|The following conversions in scope can be converted to Option[Int]:
8+
|- given bar: Int
9+
-- [E172] Type Error: tests/neg/i16453.scala:20:25 ---------------------------------------------------------------------
10+
20 | implicitly[Option[Int]] // error
1211
| ^
13-
|No given instance of type Option[Int] was found for parameter e of method implicitly in object Predef
14-
|
15-
|Note: implicit conversions are not automatically applied to arguments of using clauses. You will have to pass the argument explicitly.
16-
|The following conversions in scope result in Option[Int]:
17-
| - final given def given_Conversion_T_Option[T]: Conversion[T, Option[T]]
18-
| - implicit def toOption[T](t: T): Option[T]
12+
| No given instance of type Option[Int] was found for parameter e of method implicitly in object Predef

tests/neg/i16453.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import scala.language.implicitConversions
33
trait Foo { type T }
44

55
// Scala 3 style conversion
6-
// given [T]: Conversion[T, Option[T]] = ???
6+
given [T]: Conversion[T, Option[T]] = ???
77
given [F <: Foo](using f: F): Conversion[f.T, Option[f.T]] = ???
88
// Scala 2 style conversion
99
implicit def toOption[T](t: T): Option[T] = Option(t)

0 commit comments

Comments
 (0)