Skip to content

Commit 9b5338d

Browse files
committed
Exclude implicit class conversions in SemanticDB
Conversions generated for implicit classes were synthetic before, now they need to be excluded separately.
1 parent 0925ac5 commit 9b5338d

File tree

5 files changed

+24
-17
lines changed

5 files changed

+24
-17
lines changed

compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class ExtractSemanticDB extends Phase:
7979
|| sym.isLocalDummy
8080
|| sym.is(Synthetic)
8181
|| sym.isSetter
82+
|| sym.isOldStyleImplicitConversion(forImplicitClassOnly = true)
8283
|| excludeDefOrUse(sym)
8384

8485
private def excludeDefOrUse(sym: Symbol)(using Context): Boolean =
@@ -102,6 +103,7 @@ class ExtractSemanticDB extends Phase:
102103
private def excludeChildren(sym: Symbol)(using Context): Boolean =
103104
!sym.exists
104105
|| sym.is(Param) && sym.info.bounds.hi.isInstanceOf[Types.HKTypeLambda]
106+
|| sym.isOldStyleImplicitConversion(forImplicitClassOnly = true)
105107

106108
/** Uses of this symbol where the reference has given span should be excluded from semanticdb */
107109
private def excludeUse(qualifier: Option[Symbol], sym: Symbol)(using Context): Boolean =

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ object SymUtils:
8787

8888
def isGenericProduct(using Context): Boolean = whyNotGenericProduct.isEmpty
8989

90+
/** Is this the an old style implicit conversion?
91+
* @param directOnly only consider explicitly written methods
92+
* @param forImplicitClassOnly only consider methods generated from implicit classes
93+
*/
94+
def isOldStyleImplicitConversion(directOnly: Boolean = false, forImplicitClassOnly: Boolean = false)(using Context): Boolean =
95+
self.is(Implicit) && self.info.stripPoly.match
96+
case mt @ MethodType(_ :: Nil) if !mt.isImplicitMethod =>
97+
if self.isCoDefinedGiven(mt.finalResultType.typeSymbol)
98+
then !directOnly
99+
else !forImplicitClassOnly
100+
case _ =>
101+
false
102+
90103
def useCompanionAsMirror(using Context): Boolean = self.linkedClass.exists && !self.is(Scala2x)
91104

92105
/** Is this a sealed class or trait for which a sum mirror is generated?

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -861,23 +861,14 @@ trait Checking {
861861
/** If `sym` is an old-style implicit conversion, check that implicit conversions are enabled.
862862
* @pre sym.is(GivenOrImplicit)
863863
*/
864-
def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit = {
865-
def check(): Unit =
864+
def checkImplicitConversionDefOK(sym: Symbol)(using Context): Unit =
865+
if sym.isOldStyleImplicitConversion(directOnly = true) then
866866
checkFeature(
867867
nme.implicitConversions,
868868
i"Definition of implicit conversion $sym",
869869
ctx.owner.topLevelClass,
870870
sym.srcPos)
871871

872-
sym.info.stripPoly match {
873-
case mt @ MethodType(_ :: Nil)
874-
if !mt.isImplicitMethod && !sym.isCoDefinedGiven(mt.finalResultType.typeSymbol) =>
875-
// it's an old-style conversion
876-
check()
877-
case _ =>
878-
}
879-
}
880-
881872
/** If `tree` is an application of a new-style implicit conversion (using the apply
882873
* method of a `scala.Conversion` instance), check that implicit conversions are
883874
* enabled.

tests/semanticdb/expect/InventedNames.expect.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ given X/*->givens::X#*/ with
2525
given (using X/*->givens::X#*/): Y/*->givens::Y#*/ with
2626
def doY/*<-givens::InventedNames$package.given_Y#doY().*/ = "7"
2727

28-
given [T/*<-givens::InventedNames$package.given_Z_T#[T]*/]: Z/*->givens::Z#*/[T/*->givens::InventedNames$package.given_Z_T#[T]*/] with
28+
given [T/*<-givens::InventedNames$package.given_Z_T#[T]*//*<-givens::InventedNames$package.given_Z_T().[T]*/]: Z/*->givens::Z#*/[T/*->givens::InventedNames$package.given_Z_T#[T]*/] with
2929
def doZ/*<-givens::InventedNames$package.given_Z_T#doZ().*/: List/*->scala::package.List#*/[T/*->givens::InventedNames$package.given_Z_T#[T]*/] = Nil/*->scala::package.Nil.*/
3030

3131

tests/semanticdb/metac.expect

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ classes/C12#foo2Impl().(context) => param context: Context
484484
classes/C12#foo2Impl().(x) => param x: context.Expr[Int]
485485
classes/C12#foo2Impl().(y) => param y: context.Expr[String]
486486
classes/M. => final object M extends Object { self: M.type => +3 decls }
487-
classes/M.C5# => class C5 extends Object { self: C5 => +2 decls }
487+
classes/M.C5# => implicit class C5 extends Object { self: C5 => +2 decls }
488488
classes/M.C5#`<init>`(). => primary ctor <init> (param x: Int): C5
489489
classes/M.C5#`<init>`().(x) => param x: Int
490490
classes/M.C5#x. => private[this] val method x Int
@@ -1519,7 +1519,7 @@ example/ImplicitConversion#string2Number().(string) => param string: String
15191519
example/ImplicitConversion#tuple. => val method tuple Tuple2[Int, Int]
15201520
example/ImplicitConversion#x. => val method x Int
15211521
example/ImplicitConversion. => final object ImplicitConversion extends Object { self: ImplicitConversion.type => +6 decls }
1522-
example/ImplicitConversion.newAny2stringadd# => final class newAny2stringadd [typeparam A ] extends AnyVal { self: newAny2stringadd[A] => +4 decls }
1522+
example/ImplicitConversion.newAny2stringadd# => final implicit class newAny2stringadd [typeparam A ] extends AnyVal { self: newAny2stringadd[A] => +4 decls }
15231523
example/ImplicitConversion.newAny2stringadd#[A] => typeparam A
15241524
example/ImplicitConversion.newAny2stringadd#`+`(). => method + (param other: String): String
15251525
example/ImplicitConversion.newAny2stringadd#`+`().(other) => param other: String
@@ -1684,7 +1684,7 @@ Uri => InventedNames.scala
16841684
Text => empty
16851685
Language => Scala
16861686
Symbols => 45 entries
1687-
Occurrences => 61 entries
1687+
Occurrences => 62 entries
16881688

16891689
Symbols:
16901690
givens/InventedNames$package. => final package object givens extends Object { self: givens.type => +24 decls }
@@ -1705,14 +1705,14 @@ givens/InventedNames$package.given_List_T().[T] => typeparam T
17051705
givens/InventedNames$package.given_String. => final implicit lazy val given method given_String String
17061706
givens/InventedNames$package.given_X. => final implicit given object given_X extends Object with X { self: given_X.type => +2 decls }
17071707
givens/InventedNames$package.given_X.doX(). => method doX => Int <: givens/X#doX().
1708-
givens/InventedNames$package.given_Y# => class given_Y extends Object with Y { self: given_Y => +3 decls }
1708+
givens/InventedNames$package.given_Y# => implicit given class given_Y extends Object with Y { self: given_Y => +3 decls }
17091709
givens/InventedNames$package.given_Y#`<init>`(). => primary ctor <init> ()(implicit val given param x$1: X): given_Y
17101710
givens/InventedNames$package.given_Y#`<init>`().(x$1) => implicit val given param x$1: X
17111711
givens/InventedNames$package.given_Y#doY(). => method doY => String <: givens/Y#doY().
17121712
givens/InventedNames$package.given_Y#x$1. => protected implicit val given method x$1 X
17131713
givens/InventedNames$package.given_Y(). => final implicit given method given_Y (implicit given param x$1: X): given_Y
17141714
givens/InventedNames$package.given_Y().(x$1) => implicit given param x$1: X
1715-
givens/InventedNames$package.given_Z_T# => class given_Z_T [typeparam T ] extends Object with Z[T] { self: given_Z_T[T] => +3 decls }
1715+
givens/InventedNames$package.given_Z_T# => implicit given class given_Z_T [typeparam T ] extends Object with Z[T] { self: given_Z_T[T] => +3 decls }
17161716
givens/InventedNames$package.given_Z_T#[T] => typeparam T
17171717
givens/InventedNames$package.given_Z_T#`<init>`(). => primary ctor <init> [typeparam T ](): given_Z_T[T]
17181718
givens/InventedNames$package.given_Z_T#doZ(). => method doZ => List[T] <: givens/Z#doZ().
@@ -1767,6 +1767,7 @@ Occurrences:
17671767
[24:17..24:18): Y -> givens/Y#
17681768
[25:6..25:9): doY <- givens/InventedNames$package.given_Y#doY().
17691769
[27:7..27:8): T <- givens/InventedNames$package.given_Z_T#[T]
1770+
[27:7..27:8): T <- givens/InventedNames$package.given_Z_T().[T]
17701771
[27:11..27:12): Z -> givens/Z#
17711772
[27:13..27:14): T -> givens/InventedNames$package.given_Z_T#[T]
17721773
[28:6..28:9): doZ <- givens/InventedNames$package.given_Z_T#doZ().

0 commit comments

Comments
 (0)