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 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8201ebd
Respect prefix when checking if selector selects
som-snytt Jun 29, 2024
2d88b98
Check scope type
som-snytt Oct 2, 2024
968c436
Use type test of prefix for usages in scope
som-snytt Oct 2, 2024
2d3454d
Style tweaks in CheckUnused
som-snytt Oct 2, 2024
eca54d2
Show more for misplaced warn comment
som-snytt Oct 3, 2024
e745c24
Attachment tracks derivation
som-snytt Oct 3, 2024
532ebde
Sort unfulfilled expectations
som-snytt Oct 3, 2024
f09e894
No warn serialization methods
som-snytt Oct 3, 2024
bd7ac2f
Assume tpd
som-snytt Oct 3, 2024
9be057e
Refactor traverser to miniphase callbacks
som-snytt Oct 3, 2024
3934aa4
Avoid tracking red herrings
som-snytt Oct 4, 2024
0cafda1
Mono Mega Phase
som-snytt Oct 4, 2024
9c00b44
Add test
som-snytt Oct 4, 2024
8ddf038
More broken tests
som-snytt Oct 4, 2024
3a07f34
Consider superclass context
som-snytt Oct 6, 2024
f089c91
Filter member of refinement, handle Annotated
som-snytt Oct 8, 2024
1133e42
TypeTree is usage of simple name
som-snytt Oct 9, 2024
9d1a40b
Handle quotes and splices
som-snytt Oct 9, 2024
7cb02f1
Tighten allowance for serialization methods
som-snytt Oct 9, 2024
75ea482
Restore inferred type is not a usage, noprefix is in import
som-snytt Oct 9, 2024
9467cda
Warn for top level private
som-snytt Oct 9, 2024
db2aec1
Regression tests
som-snytt Oct 9, 2024
12f75a9
Import given takes NoPrefix usage
som-snytt Oct 9, 2024
1d4db7f
Regression tests
som-snytt Oct 11, 2024
882cb84
Don't ignore params of public methods
som-snytt Oct 14, 2024
e8ca0cc
Attempt to ignore subtrees
som-snytt Oct 15, 2024
1907775
Enable more param warnings
som-snytt Nov 5, 2024
d5ea0e9
Tweak test warns
som-snytt Nov 5, 2024
57347d8
Accept updated semanticdb output
som-snytt Nov 5, 2024
ac3f5dc
Adjust more tests
som-snytt Nov 6, 2024
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
6 changes: 2 additions & 4 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 All @@ -50,10 +48,10 @@ class Compiler {
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
List(new Inlining) :: // Inline and execute macros
List(new PostInlining) :: // Add mirror support for inlined code
List(new CheckUnused.PostInlining) :: // Check for unused elements
List(new Staging) :: // Check staging levels and heal staged types
List(new Splicing) :: // Replace level 1 splices with holes
List(new PickleQuotes) :: // Turn quoted trees into explicit run-time data structures
List(new CheckUnused.PostInlining) :: // Check for unused elements
Nil

/** Phases dealing with the transformation from pickled trees to backend trees */
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ class Definitions {
@tu lazy val Predef_undefined: Symbol = ScalaPredefModule.requiredMethod(nme.???)
@tu lazy val ScalaPredefModuleClass: ClassSymbol = ScalaPredefModule.moduleClass.asClass

@tu lazy val SameTypeClass: ClassSymbol = requiredClass("scala.=:=")
@tu lazy val SameType_refl: Symbol = SameTypeClass.companionModule.requiredMethod(nme.refl)
@tu lazy val SubTypeClass: ClassSymbol = requiredClass("scala.<:<")
@tu lazy val SubType_refl: Symbol = SubTypeClass.companionModule.requiredMethod(nme.refl)

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 @@ -3295,14 +3295,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