Skip to content

Commit 4b8a1de

Browse files
authored
Merge pull request #9935 from dotty-staging/change-implicit-conversion-warning
Change implicit conversions warnings
2 parents 7f46c25 + 556893b commit 4b8a1de

File tree

7 files changed

+24
-32
lines changed

7 files changed

+24
-32
lines changed

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

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -761,29 +761,21 @@ trait Checking {
761761
}
762762
}
763763

764-
/** If `sym` is an implicit conversion, check that that implicit conversions are enabled, unless
765-
* - it is synthetic
766-
* - it is has the same owner as one of the classes it converts to (modulo companions)
767-
* - it is defined in Predef
768-
* - it is the scala.reflect.Selectable.reflectiveSelectable conversion
764+
/** If `tree` is an application of a new-style implicit conversion (using the apply
765+
* method of a `scala.Conversion` instance), check that implicit conversions are
766+
* enabled.
769767
*/
770-
def checkImplicitConversionUseOK(sym: Symbol, pos: SrcPos)(using Context): Unit =
771-
if (sym.exists) {
772-
val conv =
773-
if (sym.isOneOf(GivenOrImplicit) || sym.info.isErroneous) sym
774-
else {
775-
assert(sym.name == nme.apply || ctx.reporter.errorsReported)
776-
sym.owner
777-
}
778-
val conversionOK =
779-
conv.is(Synthetic) ||
780-
sym.info.finalResultType.classSymbols.exists(_.isLinkedWith(conv.owner)) ||
781-
defn.isPredefClass(conv.owner) ||
782-
conv.name == nme.reflectiveSelectable && conv.maybeOwner.maybeOwner.maybeOwner == defn.ScalaPackageClass
783-
if (!conversionOK)
784-
checkFeature(nme.implicitConversions,
785-
i"Use of implicit conversion ${conv.showLocated}", NoSymbol, pos)
786-
}
768+
def checkImplicitConversionUseOK(tree: Tree)(using Context): Unit =
769+
val sym = tree.symbol
770+
if sym.name == nme.apply
771+
&& sym.owner.derivesFrom(defn.ConversionClass)
772+
&& !sym.info.isErroneous
773+
then
774+
def conv = methPart(tree) match
775+
case Select(qual, _) => qual.symbol.orElse(sym.owner)
776+
case _ => sym.owner
777+
checkFeature(nme.implicitConversions,
778+
i"Use of implicit conversion ${conv.showLocated}", NoSymbol, tree.srcPos)
787779

788780
private def infixOKSinceFollowedBy(tree: untpd.Tree): Boolean = tree match {
789781
case _: untpd.Block | _: untpd.Match => true
@@ -1244,7 +1236,7 @@ trait NoChecking extends ReChecking {
12441236
override def checkStable(tp: Type, pos: SrcPos, kind: String)(using Context): Unit = ()
12451237
override def checkClassType(tp: Type, pos: SrcPos, traitReq: Boolean, stablePrefixReq: Boolean)(using Context): Type = tp
12461238
override def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = ()
1247-
override def checkImplicitConversionUseOK(sym: Symbol, pos: SrcPos)(using Context): Unit = ()
1239+
override def checkImplicitConversionUseOK(tree: Tree)(using Context): Unit = ()
12481240
override def checkFeasibleParent(tp: Type, pos: SrcPos, where: => String = "")(using Context): Type = tp
12491241
override def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = ()
12501242
override def checkNoAlphaConflict(stats: List[Tree])(using Context): Unit = ()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3490,7 +3490,7 @@ class Typer extends Namer
34903490
case SearchSuccess(found: ExtMethodApply, _, _) =>
34913491
found // nothing to check or adapt for extension method applications
34923492
case SearchSuccess(found, _, _) =>
3493-
checkImplicitConversionUseOK(found.symbol, tree.srcPos)
3493+
checkImplicitConversionUseOK(found)
34943494
withoutMode(Mode.ImplicitsEnabled)(readapt(found))
34953495
case failure: SearchFailure =>
34963496
if (pt.isInstanceOf[ProtoType] && !failure.isAmbiguous) then

library/src/scala/Conversion.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ package scala
1919
* from two to one.
2020
*/
2121
@java.lang.FunctionalInterface
22-
abstract class Conversion[-T, +U] extends Function1[T, U]
22+
abstract class Conversion[-T, +U] extends Function1[T, U]:
23+
def apply(x: T): U

tests/neg-custom-args/impl-conv/A.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package implConv
33
object A {
44

55
implicit def s2i(x: String): Int = Integer.parseInt(x) // error: feature
6-
implicit val i2s: Conversion[Int, String] = _.toString // error: feature
6+
given i2s as Conversion[Int, String] = _.toString // ok
77

88
implicit class Foo(x: String) {
99
def foo = x.length
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package implConv
22

33
object B {
4-
import A._
4+
import A.{_, given _}
55

66
"".foo
77

8-
val x: Int = "" // error: feature
8+
val x: Int = "" // ok
99
val y: String = 1 // error: feature
10-
1110
}

tests/neg-custom-args/implicit-conversions-old.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ object Test {
1818
import D._
1919

2020
val x1: A = new B
21-
val x2: B = new A // error under -Xfatal-warnings -feature
22-
val x3: C = new A // error under -Xfatal-warnings -feature
21+
val x2: B = new A // ok, since it's an old-style comversion
22+
val x3: C = new A // ok, since it's an old-style comversion
2323
}

tests/neg-custom-args/implicit-conversions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object D {
2323
object Test {
2424
import D.{given _}
2525

26-
val x1: A = new B
26+
val x1: A = new B // error under -Xfatal-warnings -feature
2727
val x2: B = new A // error under -Xfatal-warnings -feature
2828
val x3: C = new A // error under -Xfatal-warnings -feature
2929
}

0 commit comments

Comments
 (0)