Skip to content

Commit

Permalink
Merge pull request #14888 from dotty-staging/fix-12432
Browse files Browse the repository at this point in the history
Disallow package names as types
  • Loading branch information
griggt authored Apr 9, 2022
2 parents f3cca47 + 02a8b70 commit 70c6d1f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import printing.Printer
import printing.Texts.Text
import util.{Stats, Attachment, Property, SourceFile, NoSource, SrcPos, SourcePosition}
import config.Config
import config.Printers.overload
import annotation.internal.sharable
import annotation.unchecked.uncheckedVariance
import annotation.constructorOnly
Expand Down Expand Up @@ -1729,7 +1730,9 @@ object Trees {
val typer = ctx.typer
val proto = FunProto(args, expectedType)
val denot = receiver.tpe.member(method)
assert(denot.exists, i"no member $receiver . $method, members = ${receiver.tpe.decls}")
if !denot.exists then
overload.println(i"members = ${receiver.tpe.decls}")
report.error(i"no member $receiver . $method", receiver.srcPos)
val selected =
if (denot.isOverloaded) {
def typeParamCount(tp: Type) = tp.widen match {
Expand Down
29 changes: 18 additions & 11 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import core._
import dotty.tools.dotc.typer.Checking
import dotty.tools.dotc.typer.Inliner
import dotty.tools.dotc.typer.VarianceChecker
import typer.ErrorReporting.errorTree
import Types._, Contexts._, Names._, Flags._, DenotTransformers._, Phases._
import SymDenotations._, StdNames._, Annotations._, Trees._, Scopes._
import Decorators._
Expand Down Expand Up @@ -263,6 +264,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
case Select(qual, _) => check(qual) // simple select _n
case Apply(TypeApply(Select(qual, _), _), _) => check(qual) // generic select .apply[T](n)

def checkNotPackage(tree: Tree)(using Context): Tree =
if !tree.symbol.is(Package) then tree
else errorTree(tree, i"${tree.symbol} cannot be used as a type")

override def transform(tree: Tree)(using Context): Tree =
try tree match {
// TODO move CaseDef case lower: keep most probable trees first for performance
Expand All @@ -273,21 +278,23 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
case None =>
ctx
super.transform(tree)(using gadtCtx)
case tree: Ident if !tree.isType =>
if tree.symbol.is(Inline) && !Inliner.inInlineMethod then
ctx.compilationUnit.needsInlining = true
checkNoConstructorProxy(tree)
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withSpan(tree.span)
case _ => tree
}
case tree: Ident =>
if tree.isType then
checkNotPackage(tree)
else
if tree.symbol.is(Inline) && !Inliner.inInlineMethod then
ctx.compilationUnit.needsInlining = true
checkNoConstructorProxy(tree)
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withSpan(tree.span)
case _ => tree
}
case tree @ Select(qual, name) =>
if tree.symbol.is(Inline) then
ctx.compilationUnit.needsInlining = true
if (name.isTypeName) {
if name.isTypeName then
Checking.checkRealizable(qual.tpe, qual.srcPos)
withMode(Mode.Type)(super.transform(tree))
}
withMode(Mode.Type)(super.transform(checkNotPackage(tree)))
else
checkNoConstructorProxy(tree)
transformSelect(tree, Nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
// compare primitive fields first, slow equality checks of non-primitive fields can be skipped when primitives differ
val sortedAccessors = accessors.sortBy(accessor => if (accessor.info.typeSymbol.isPrimitiveValueClass) 0 else 1)
val comparisons = sortedAccessors.map { accessor =>
This(clazz).select(accessor).equal(ref(thatAsClazz).select(accessor)) }
This(clazz).withSpan(ctx.owner.span.focus).select(accessor).equal(ref(thatAsClazz).select(accessor)) }
var rhs = // this.x == this$0.x && this.y == x$0.y && that.canEqual(this)
if comparisons.isEmpty then Literal(Constant(true)) else comparisons.reduceLeft(_ and _)
val canEqualMeth = existingDef(defn.Product_canEqual, clazz)
Expand Down
4 changes: 4 additions & 0 deletions tests/neg/i12432.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

case class i1 ( i1 : annotation ) // error // error
class i2 ( a : scala.annotation ) // error

0 comments on commit 70c6d1f

Please # to comment.