Skip to content

Commit 7b102bc

Browse files
som-snytttgodzik
authored andcommitted
Dealias for unused param check (scala#23256)
Fixes scala#23250 The check for "unused implicit parameter" considers the type of the parameter, but it should dealias first. In addition, take an abstract type as not warnable, unless it has an upper bound that is warnable (has non-universal members). Note that `isSingleton` dealiases. There was an ancient (OG) typo of `&` for `&&` which has gone unfixed despite other edits. The right operand was always just an instanceof. Not sure if the previous idiom saves an opcode, but now it looks like other code nearby. [Cherry-picked 2d18655]
1 parent af8bcb7 commit 7b102bc

File tree

5 files changed

+41
-6
lines changed

5 files changed

+41
-6
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ object SymDenotations {
684684
isAbstractOrAliasType && !isAbstractOrParamType
685685

686686
/** Is this symbol an abstract or alias type? */
687-
final def isAbstractOrAliasType: Boolean = isType & !isClass
687+
final def isAbstractOrAliasType: Boolean = isType && !isClass
688688

689689
/** Is this symbol an abstract type or type parameter? */
690690
final def isAbstractOrParamType(using Context): Boolean = this.isOneOf(DeferredOrTypeParam)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,14 +613,14 @@ object CheckUnused:
613613
|| m.hasAnnotation(dd.UnusedAnnot) // param of unused method
614614
|| sym.owner.name.isContextFunction // a ubiquitous parameter
615615
|| sym.isCanEqual
616-
|| sym.info.typeSymbol.match // more ubiquity
616+
|| sym.info.dealias.typeSymbol.match // more ubiquity
617617
case dd.DummyImplicitClass | dd.SubTypeClass | dd.SameTypeClass => true
618618
case tps =>
619619
tps.isMarkerTrait // no members to use; was only if sym.name.is(ContextBoundParamName)
620620
|| // but consider NotGiven
621621
tps.hasAnnotation(dd.LanguageFeatureMetaAnnot)
622622
|| sym.info.isSingleton // DSL friendly
623-
|| sym.info.isInstanceOf[RefinedType] // can't be expressed as a context bound
623+
|| sym.info.dealias.isInstanceOf[RefinedType] // can't be expressed as a context bound
624624
if ctx.settings.WunusedHas.implicits
625625
&& !infos.skip(m)
626626
&& !m.isEffectivelyOverride
@@ -943,7 +943,7 @@ object CheckUnused:
943943
def isCanEqual: Boolean =
944944
sym.isOneOf(GivenOrImplicit) && sym.info.finalResultType.baseClasses.exists(_.derivesFrom(defn.CanEqualClass))
945945
def isMarkerTrait: Boolean =
946-
sym.isClass && sym.info.allMembers.forall: d =>
946+
sym.info.hiBound.allMembers.forall: d =>
947947
val m = d.symbol
948948
!m.isTerm || m.isSelfSym || m.is(Method) && (m.owner == defn.AnyClass || m.owner == defn.ObjectClass)
949949
def isEffectivelyPrivate: Boolean =

tests/warn/i17314.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -Wunused:all -deprecation -feature
1+
//> using options -Wunused:all -deprecation -feature -Werror
22

33
import java.net.URI
44

@@ -10,7 +10,7 @@ object circelike {
1010
type Configuration
1111
trait ConfiguredCodec[T]
1212
object ConfiguredCodec:
13-
inline final def derived[A](using conf: Configuration)(using inline mirror: Mirror.Of[A]): ConfiguredCodec[A] = // warn // warn
13+
inline final def derived[A](using conf: Configuration)(using inline mirror: Mirror.Of[A]): ConfiguredCodec[A] =
1414
class InlinedConfiguredCodec extends ConfiguredCodec[A]:
1515
val codec = summonInline[Codec[URI]] // simplification
1616
new InlinedConfiguredCodec

tests/warn/i23250.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//> using options -Wunused:all -Werror
2+
3+
trait MonadError[F[_], E]
4+
type MonadThrow[F[_]] = MonadError[F, Throwable]
5+
6+
trait MetaStreams[F[_]]:
7+
def use[A]: F[A] = ???
8+
trait WriteResult
9+
10+
trait MetaStreamsSyntax:
11+
extension [F[_]](ms: MetaStreams[F])(using MonadThrow[F])
12+
def setMaxAge(): F[WriteResult] =
13+
summon[MonadThrow[F]]
14+
ms.use[WriteResult]
15+
16+
def setTruncateBefore(): F[WriteResult] =
17+
ms.use[WriteResult]

tests/warn/i23250b.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//> using options -Wunused:all
2+
3+
trait Memberly:
4+
def member: Int
5+
6+
object Members:
7+
type MemberType <: Memberly
8+
type Empty
9+
10+
object Test:
11+
import Members.*
12+
13+
type MT = MemberType
14+
def membered(using MT) = println() // warn abstract type offers member in upper bound
15+
def remembered(using mt: MT) = mt.member
16+
17+
type Ignore = Empty
18+
def emptily(using Ignore) = println()

0 commit comments

Comments
 (0)