Skip to content
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

In selector check, prefix of reference must match import qualifier #20894

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import typer.{TyperPhase, RefChecks}
import parsing.Parser
import Phases.Phase
import transform.*
import dotty.tools.backend
import backend.jvm.{CollectSuperCalls, GenBCode}
import localopt.StringInterpolatorOpt

Expand All @@ -34,8 +33,7 @@ class Compiler {
protected def frontendPhases: List[List[Phase]] =
List(new Parser) :: // Compiler frontend: scanner, parser
List(new TyperPhase) :: // Compiler frontend: namer, typer
List(new CheckUnused.PostTyper) :: // Check for unused elements
List(new CheckShadowing) :: // Check shadowing elements
List(new CheckUnused.PostTyper, new CheckShadowing) :: // Check for unused, shadowed elements
List(new YCheckPositions) :: // YCheck positions
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files
Expand Down
15 changes: 7 additions & 8 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3293,14 +3293,13 @@ extends Message(UnusedSymbolID) {
override def explain(using Context) = ""
}

object UnusedSymbol {
def imports(using Context): UnusedSymbol = new UnusedSymbol(i"unused import")
def localDefs(using Context): UnusedSymbol = new UnusedSymbol(i"unused local definition")
def explicitParams(using Context): UnusedSymbol = new UnusedSymbol(i"unused explicit parameter")
def implicitParams(using Context): UnusedSymbol = new UnusedSymbol(i"unused implicit parameter")
def privateMembers(using Context): UnusedSymbol = new UnusedSymbol(i"unused private member")
def patVars(using Context): UnusedSymbol = new UnusedSymbol(i"unused pattern variable")
}
object UnusedSymbol:
def imports(using Context): UnusedSymbol = UnusedSymbol(i"unused import")
def localDefs(using Context): UnusedSymbol = UnusedSymbol(i"unused local definition")
def explicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused explicit parameter")
def implicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused implicit parameter")
def privateMembers(using Context): UnusedSymbol = UnusedSymbol(i"unused private member")
def patVars(using Context): UnusedSymbol = UnusedSymbol(i"unused pattern variable")

class NonNamedArgumentInJavaAnnotation(using Context) extends SyntaxMsg(NonNamedArgumentInJavaAnnotationID):

Expand Down
32 changes: 15 additions & 17 deletions compiler/src/dotty/tools/dotc/transform/CheckShadowing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,22 @@ class CheckShadowing extends MiniPhase:

override def description: String = CheckShadowing.description

override def isEnabled(using Context): Boolean = ctx.settings.Wshadow.value.nonEmpty

override def isRunnable(using Context): Boolean =
super.isRunnable &&
ctx.settings.Wshadow.value.nonEmpty &&
!ctx.isJava
super.isRunnable && ctx.settings.Wshadow.value.nonEmpty && !ctx.isJava

// Setup before the traversal
override def prepareForUnit(tree: tpd.Tree)(using Context): Context =
val data = ShadowingData()
val fresh = ctx.fresh.setProperty(_key, data)
shadowingDataApply(sd => sd.registerRootImports())(using fresh)

// Reporting on traversal's end
override def transformUnit(tree: tpd.Tree)(using Context): tpd.Tree =
shadowingDataApply(sd =>
reportShadowing(sd.getShadowingResult)
)
tree

// MiniPhase traversal :

override def prepareForPackageDef(tree: tpd.PackageDef)(using Context): Context =
shadowingDataApply(sd => sd.inNewScope())
ctx
Expand All @@ -94,14 +90,14 @@ class CheckShadowing extends MiniPhase:
if tree.symbol.isAliasType then // if alias, the parent is the current symbol
nestedTypeTraverser(tree.symbol).traverse(tree.rhs)
if tree.symbol.is(Param) then // if param, the parent is up
val owner = tree.symbol.owner
val parent = if (owner.isConstructor) then owner.owner else owner
nestedTypeTraverser(parent).traverse(tree.rhs)(using ctx.outer)
shadowingDataApply(sd => sd.registerCandidate(parent, tree))
val enclosing =
val owner = tree.symbol.ownersIterator.dropWhile(_.is(Param)).next()
if owner.isConstructor then owner.owner else owner
nestedTypeTraverser(enclosing).traverse(tree.rhs)(using ctx.outer)
shadowingDataApply(_.registerCandidate(enclosing, tree))
else
ctx


override def transformPackageDef(tree: tpd.PackageDef)(using Context): tpd.Tree =
shadowingDataApply(sd => sd.outOfScope())
tree
Expand All @@ -115,13 +111,16 @@ class CheckShadowing extends MiniPhase:
tree

override def transformTypeDef(tree: tpd.TypeDef)(using Context): tpd.Tree =
if tree.symbol.is(Param) && isValidTypeParamOwner(tree.symbol.owner) then // Do not register for constructors the work is done for the Class owned equivalent TypeDef
shadowingDataApply(sd => sd.computeTypeParamShadowsFor(tree.symbol.owner)(using ctx.outer))
if tree.symbol.isAliasType then // No need to start outer here, because the TypeDef reached here it's already the parent
// Do not register for constructors the work is done for the Class owned equivalent TypeDef
if tree.symbol.is(Param) then
val owner = tree.symbol.ownersIterator.dropWhile(_.is(Param)).next()
if isValidTypeParamOwner(owner) then
shadowingDataApply(_.computeTypeParamShadowsFor(owner)(using ctx.outer))
// No need to start outer here, because the TypeDef reached here it's already the parent
if tree.symbol.isAliasType then
shadowingDataApply(sd => sd.computeTypeParamShadowsFor(tree.symbol)(using ctx))
tree

// Helpers :
private def isValidTypeParamOwner(owner: Symbol)(using Context): Boolean =
!owner.isConstructor && !owner.is(Synthetic) && !owner.is(Exported)

Expand Down Expand Up @@ -310,4 +309,3 @@ object CheckShadowing:
case class ShadowResult(warnings: List[ShadowWarning])

end CheckShadowing

Loading
Loading