Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Dealias for unused param check #23256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ object SymDenotations {
isAbstractOrAliasType && !isAbstractOrParamType

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

/** Is this symbol an abstract type or type parameter? */
final def isAbstractOrParamType(using Context): Boolean = this.isOneOf(DeferredOrTypeParam)
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -575,14 +575,14 @@ object CheckUnused:
|| m.hasAnnotation(dd.UnusedAnnot) // param of unused method
|| sym.name.is(ContextFunctionParamName) // a ubiquitous parameter
|| sym.isCanEqual
|| sym.info.typeSymbol.match // more ubiquity
|| sym.info.dealias.typeSymbol.match // more ubiquity
case dd.DummyImplicitClass | dd.SubTypeClass | dd.SameTypeClass => true
case tps =>
tps.isMarkerTrait // no members to use; was only if sym.name.is(ContextBoundParamName)
|| // but consider NotGiven
tps.hasAnnotation(dd.LanguageFeatureMetaAnnot)
|| sym.info.isSingleton // DSL friendly
|| sym.info.isInstanceOf[RefinedType] // can't be expressed as a context bound
|| sym.info.dealias.isInstanceOf[RefinedType] // can't be expressed as a context bound
if ctx.settings.WunusedHas.implicits
&& !infos.skip(m)
&& !m.isEffectivelyOverride
Expand Down Expand Up @@ -905,7 +905,7 @@ object CheckUnused:
def isCanEqual: Boolean =
sym.isOneOf(GivenOrImplicit) && sym.info.finalResultType.baseClasses.exists(_.derivesFrom(defn.CanEqualClass))
def isMarkerTrait: Boolean =
sym.isClass && sym.info.allMembers.forall: d =>
sym.info.hiBound.allMembers.forall: d =>
val m = d.symbol
!m.isTerm || m.isSelfSym || m.is(Method) && (m.owner == defn.AnyClass || m.owner == defn.ObjectClass)
def isEffectivelyPrivate: Boolean =
Expand Down
4 changes: 2 additions & 2 deletions tests/warn/i17314.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -Wunused:all -deprecation -feature
//> using options -Wunused:all -deprecation -feature -Werror

import java.net.URI

Expand All @@ -10,7 +10,7 @@ object circelike {
type Configuration
trait ConfiguredCodec[T]
object ConfiguredCodec:
inline final def derived[A](using conf: Configuration)(using inline mirror: Mirror.Of[A]): ConfiguredCodec[A] = // warn // warn
inline final def derived[A](using conf: Configuration)(using inline mirror: Mirror.Of[A]): ConfiguredCodec[A] =
class InlinedConfiguredCodec extends ConfiguredCodec[A]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These warning seemed valid, neither mirror nor conf is actually used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a consequence of In addition, take an abstract type as not warnable, unless it has an upper bound that is warnable (has non-universal members). ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Mirror doesn't have terms to use. Also Of is an alias so warned previously.

val codec = summonInline[Codec[URI]] // simplification
new InlinedConfiguredCodec
Expand Down
17 changes: 17 additions & 0 deletions tests/warn/i23250.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//> using options -Wunused:all -Werror

trait MonadError[F[_], E]
type MonadThrow[F[_]] = MonadError[F, Throwable]

trait MetaStreams[F[_]]:
def use[A]: F[A] = ???
trait WriteResult

trait MetaStreamsSyntax:
extension [F[_]](ms: MetaStreams[F])(using MonadThrow[F])
def setMaxAge(): F[WriteResult] =
summon[MonadThrow[F]]
ms.use[WriteResult]

def setTruncateBefore(): F[WriteResult] =
ms.use[WriteResult]
18 changes: 18 additions & 0 deletions tests/warn/i23250b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//> using options -Wunused:all

trait Memberly:
def member: Int

object Members:
type MemberType <: Memberly
type Empty

object Test:
import Members.*

type MT = MemberType
def membered(using MT) = println() // warn abstract type offers member in upper bound
def remembered(using mt: MT) = mt.member

type Ignore = Empty
def emptily(using Ignore) = println()
Loading