Skip to content

Move checkValue to Typer #11431

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 1 commit into from
Feb 16, 2021
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
17 changes: 3 additions & 14 deletions compiler/src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import typer.{NoChecking, LiftErased}
import typer.Inliner
import typer.ProtoTypes._
import typer.ErrorReporting.errorTree
import typer.Checking.checkValue
import core.TypeErasure._
import core.Decorators._
import dotty.tools.dotc.ast.{tpd, untpd}
Expand Down Expand Up @@ -569,18 +570,6 @@ object Erasure {

/** Check that Java statics and packages can only be used in selections.
*/
private def checkValue(tree: Tree, proto: Type)(using Context): tree.type =
if (!proto.isInstanceOf[SelectionProto] && !proto.isInstanceOf[ApplyingProto]) then
checkValue(tree)
tree

private def checkValue(tree: Tree)(using Context): Unit =
val sym = tree.tpe.termSymbol
if (sym is Flags.Package)
|| (sym.isAllOf(Flags.JavaModule) && !ctx.isJava)
then
report.error(JavaSymbolIsNotAValue(sym), tree.srcPos)

private def checkNotErased(tree: Tree)(using Context): tree.type = {
if (!ctx.mode.is(Mode.Type)) {
if (isErased(tree))
Expand Down Expand Up @@ -644,7 +633,7 @@ object Erasure {
super.typedLiteral(tree)

override def typedIdent(tree: untpd.Ident, pt: Type)(using Context): Tree =
checkValue(checkNotErased(super.typedIdent(tree, pt)), pt)
checkNotErased(super.typedIdent(tree, pt))

/** Type check select nodes, applying the following rewritings exhaustively
* on selections `e.m`, where `OT` is the type of the owner of `m` and `ET`
Expand Down Expand Up @@ -772,7 +761,7 @@ object Erasure {
}
}

checkValue(checkNotErased(recur(qual1)), pt)
checkNotErased(recur(qual1))
}

override def typedThis(tree: untpd.This)(using Context): Tree =
Expand Down
15 changes: 15 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,21 @@ object Checking {
|| to.isRef(defn.ObjectClass, skipRefined = false)
then
report.error(em"the result of an implicit conversion must be more specific than $to", pos)

def checkValue(tree: Tree)(using Context): Unit =
val sym = tree.tpe.termSymbol
if sym.is(Flags.Package) || sym.isAllOf(Flags.JavaModule) && !ctx.isJava then
report.error(JavaSymbolIsNotAValue(sym), tree.srcPos)

def checkValue(tree: Tree, proto: Type)(using Context): tree.type =
tree match
case tree: RefTree
if tree.name.isTermName
&& !proto.isInstanceOf[SelectionProto]
&& !proto.isInstanceOf[FunOrPolyProto] =>
checkValue(tree)
case _ =>
tree
}

trait Checking {
Expand Down
13 changes: 8 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ class Typer extends Namer
case _ =>
tree.withType(ownType)
val tree2 = toNotNullTermRef(tree1, pt)
checkStableIdentPattern(tree2, pt)
checkLegalValue(tree2, pt)
tree2

def isLocalExtensionMethodRef: Boolean = rawType match
Expand Down Expand Up @@ -537,9 +537,12 @@ class Typer extends Namer
errorTree(tree, MissingIdent(tree, kind, name))
end typedIdent

/** Check that a stable identifier pattern is indeed stable (SLS 8.1.5)
/** (1) If this reference is neither applied nor selected, check that it does
* not refer to a package or Java companion object.
* (2) Check that a stable identifier pattern is indeed stable (SLS 8.1.5)
*/
private def checkStableIdentPattern(tree: Tree, pt: Type)(using Context): Unit =
private def checkLegalValue(tree: Tree, pt: Type)(using Context): Unit =
checkValue(tree, pt)
if ctx.mode.is(Mode.Pattern)
&& !tree.isType
&& !pt.isInstanceOf[ApplyingProto]
Expand All @@ -557,7 +560,7 @@ class Typer extends Namer
if checkedType.exists then
val select = toNotNullTermRef(assignType(tree, checkedType), pt)
if selName.isTypeName then checkStable(qual.tpe, qual.srcPos, "type prefix")
checkStableIdentPattern(select, pt)
checkLegalValue(select, pt)
ConstFold(select)
else if couldInstantiateTypeVar(qual.tpe.widen) then
// try again with more defined qualifier type
Expand Down Expand Up @@ -2343,7 +2346,7 @@ class Typer extends Namer
assert(imp.selectors.length == 1, imp)
val from = imp.selectors.head.imported
val sel = tryAlternatively
(typedIdent(from, WildcardType))
(typedIdent(from, AnySelectionProto))
(typedIdent(cpy.Ident(from)(from.name.toTypeName), WildcardType))

sel.tpe match
Expand Down
4 changes: 4 additions & 0 deletions tests/neg/i11430.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def a(o: String) = Seq(o, org) // error: package org is not a value
def a2(o: String) = Seq[String](o, org) // error: package org is not a value
def a3(o: String): Seq[String] = Seq(o, org) // error: package org is not a value
def a4(o: String): Seq[String] = Seq(o, org) // error: package org is not a value