Skip to content

Commit 6aa88d6

Browse files
committed
Main Typer reorg.
Common code between tpd and Typer has been factored out into class TypeAssigner.
1 parent dbd5a4d commit 6aa88d6

File tree

8 files changed

+472
-394
lines changed

8 files changed

+472
-394
lines changed

src/dotty/tools/dotc/ast/CheckTrees.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import core._
66
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
77
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
88

9+
// TODO: revise, integrate in a checking phase.
910
object CheckTrees {
1011

1112
import tpd._
@@ -19,7 +20,7 @@ object CheckTrees {
1920

2021
def escapingRefs(block: Block)(implicit ctx: Context): collection.Set[NamedType] = {
2122
var hoisted: Set[Symbol] = Set()
22-
lazy val locals = localSyms(block.stats).toSet
23+
lazy val locals = ctx.typeAssigner.localSyms(block.stats).toSet
2324
def isLocal(sym: Symbol): Boolean =
2425
(locals contains sym) && !isHoistableClass(sym)
2526
def isHoistableClass(sym: Symbol) =
@@ -177,7 +178,7 @@ object CheckTrees {
177178
checkRefinements(forbidden - rsym, rs1)
178179
case nil =>
179180
}
180-
checkRefinements(localSyms(refinements).toSet, refinements)
181+
checkRefinements(ctx.typeAssigner.localSyms(refinements).toSet, refinements)
181182
case AppliedTypeTree(tpt, args) =>
182183
check(tpt.isValueType)
183184
val tparams = tpt.tpe.typeParams

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 61 additions & 157 deletions
Large diffs are not rendered by default.

src/dotty/tools/dotc/core/pickling/UnPickler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
988988
case UNAPPLYtree =>
989989
val fun = readTreeRef()
990990
val args = until(end, readTreeRef)
991-
UnApply(fun, Nil, args) // !!! this is wrong in general
991+
UnApply(fun, Nil, args, defn.AnyType) // !!! this is wrong in general
992992

993993
case ARRAYVALUEtree =>
994994
val elemtpt = readTreeRef()
@@ -1067,7 +1067,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
10671067
setSym()
10681068
val qual = readTreeRef()
10691069
val mix = readTypeNameRef()
1070-
Super(qual, mix)
1070+
Super(qual, mix, inConstrCall = false) // todo: revise
10711071

10721072
case THIStree =>
10731073
setSym()

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,9 @@ trait Applications extends Compatibility { self: Typer =>
398398

399399
val result = {
400400
var typedArgs = typedArgBuf.toList
401-
val ownType =
402-
if (!success) ErrorType
401+
val app0 = cpy.Apply(app, normalizedFun, typedArgs)
402+
val app1 =
403+
if (!success) app0.withType(ErrorType)
403404
else {
404405
if (!sameSeq(args, orderedArgs)) {
405406
// need to lift arguments to maintain evaluation order in the
@@ -411,9 +412,9 @@ trait Applications extends Compatibility { self: Typer =>
411412
}
412413
if (sameSeq(typedArgs, args)) // trick to cut down on tree copying
413414
typedArgs = args.asInstanceOf[List[Tree]]
414-
methodType.instantiate(typedArgs.tpes)
415+
assignType(app0, normalizedFun, typedArgs)
415416
}
416-
wrapDefs(liftedDefs, cpy.Apply(app, normalizedFun, typedArgs).withType(ownType))
417+
wrapDefs(liftedDefs, app1)
417418
}
418419
}
419420

@@ -513,21 +514,11 @@ trait Applications extends Compatibility { self: Typer =>
513514
def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = track("typedTypeApply") {
514515
val typedArgs = tree.args mapconserve (typedType(_))
515516
val typedFn = typedExpr(tree.fun, PolyProto(typedArgs.tpes, pt))
516-
val ownType = typedFn.tpe.widen match {
517-
case pt: PolyType =>
518-
checkBounds(typedArgs, pt, tree.pos)
519-
val argTypes = typedArgs.tpes
520-
if (argTypes.length == pt.paramNames.length)
521-
pt.resultType.substParams(pt, typedArgs.tpes)
522-
else {
523-
ctx.error(i"wrong number of type parameters for ${typedFn.tpe}; expected: ${pt.paramNames.length}", tree.pos)
524-
ErrorType
525-
}
517+
typedFn.tpe.widen match {
518+
case pt: PolyType => checkBounds(typedArgs, pt, tree.pos)
526519
case _ =>
527-
ctx.error(s"${err.exprStr(typedFn)} does not take type parameters", tree.pos)
528-
ErrorType
529520
}
530-
cpy.TypeApply(tree, typedFn, typedArgs).withType(ownType)
521+
assignType(cpy.TypeApply(tree, typedFn, typedArgs), typedFn, typedArgs)
531522
}
532523

533524
def typedUnApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = track("typedUnApply") {
@@ -577,13 +568,13 @@ trait Applications extends Compatibility { self: Typer =>
577568
/** Produce a typed qual.unappy or qual.unappySeq tree, or
578569
* else if this fails follow a type alias and try again.
579570
*/
580-
val unapply = trySelectUnapply(qual) { sel =>
571+
val unapplyFn = trySelectUnapply(qual) { sel =>
581572
val qual1 = followTypeAlias(qual)
582573
if (qual1.isEmpty) notAnExtractor(sel)
583574
else trySelectUnapply(qual1)(_ => notAnExtractor(sel))
584575
}
585576

586-
def fromScala2x = unapply.symbol.exists && (unapply.symbol.owner is Scala2x)
577+
def fromScala2x = unapplyFn.symbol.exists && (unapplyFn.symbol.owner is Scala2x)
587578

588579
def unapplyArgs(unapplyResult: Type)(implicit ctx: Context): List[Type] = {
589580
def extractorMemberType(tp: Type, name: Name) = {
@@ -609,7 +600,7 @@ trait Applications extends Compatibility { self: Typer =>
609600
// println(s"unapply $unapplyResult ${extractorMemberType(unapplyResult, nme.isDefined)}")
610601
if (extractorMemberType(unapplyResult, nme.isDefined) isRef defn.BooleanClass) {
611602
if (getTp.exists)
612-
if (unapply.symbol.name == nme.unapplySeq) {
603+
if (unapplyFn.symbol.name == nme.unapplySeq) {
613604
val seqArg = boundsToHi(getTp.firstBaseArgInfo(defn.SeqClass))
614605
if (seqArg.exists) return args map Function.const(seqArg)
615606
}
@@ -634,7 +625,7 @@ trait Applications extends Compatibility { self: Typer =>
634625
case _ => false
635626
}
636627

637-
unapply.tpe.widen match {
628+
unapplyFn.tpe.widen match {
638629
case mt: MethodType if mt.paramTypes.length == 1 && !mt.isDependent =>
639630
val unapplyArgType = mt.paramTypes.head
640631
unapp.println(s"unapp arg tpe = ${unapplyArgType.show}, pt = ${pt.show}")
@@ -661,7 +652,7 @@ trait Applications extends Compatibility { self: Typer =>
661652
// can open unsoundness holes. See SI-7952 for an example of the hole this opens.
662653
if (ctx.settings.verbose.value) ctx.warning(msg, tree.pos)
663654
} else {
664-
unapp.println(s" ${unapply.symbol.owner} ${unapply.symbol.owner is Scala2x}")
655+
unapp.println(s" ${unapplyFn.symbol.owner} ${unapplyFn.symbol.owner is Scala2x}")
665656
ctx.error(msg, tree.pos)
666657
}
667658
case _ =>
@@ -677,7 +668,7 @@ trait Applications extends Compatibility { self: Typer =>
677668
}
678669

679670
val dummyArg = dummyTreeOfType(unapplyArgType)
680-
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapply, dummyArg :: Nil)))
671+
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
681672
val unapplyImplicits = unapplyApp match {
682673
case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); args2
683674
case Apply(unapply, `dummyArg` :: Nil) => Nil
@@ -695,12 +686,12 @@ trait Applications extends Compatibility { self: Typer =>
695686
List.fill(argTypes.length - args.length)(WildcardType)
696687
}
697688
val unapplyPatterns = (bunchedArgs, argTypes).zipped map (typed(_, _))
698-
val result = cpy.UnApply(tree, unapply, unapplyImplicits, unapplyPatterns) withType ownType
689+
val result = assignType(cpy.UnApply(tree, unapplyFn, unapplyImplicits, unapplyPatterns), ownType)
699690
unapp.println(s"unapply patterns = $unapplyPatterns")
700691
if ((ownType eq pt) || ownType.isError) result
701692
else Typed(result, TypeTree(ownType))
702693
case tp =>
703-
val unapplyErr = if (tp.isError) unapply else notAnExtractor(unapply)
694+
val unapplyErr = if (tp.isError) unapplyFn else notAnExtractor(unapplyFn)
704695
val typedArgsErr = args mapconserve (typed(_, defn.AnyType))
705696
cpy.UnApply(tree, unapplyErr, Nil, typedArgsErr) withType ErrorType
706697
}

src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package typer
55
import core._
66
import ast._
77
import Contexts._, Types._, Flags._, Denotations._, Names._, StdNames._, NameOps._, Symbols._
8-
import Trees._
8+
import Trees._, ProtoTypes._
99
import Constants._
1010
import Scopes._
1111
import annotation.unchecked
@@ -20,6 +20,7 @@ import collection.mutable
2020

2121
trait NoChecking {
2222
import tpd._
23+
def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
2324
def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = ()
2425
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
2526
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
@@ -33,6 +34,16 @@ trait Checking extends NoChecking {
3334

3435
import tpd._
3536

37+
/** Check that Java statics and packages can only be used in selections.
38+
*/
39+
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = {
40+
if (!proto.isInstanceOf[SelectionProto]) {
41+
val sym = tree.tpe.termSymbol
42+
if ((sym is Package) || (sym is JavaModule)) ctx.error(i"$sym is not a value", tree.pos)
43+
}
44+
tree
45+
}
46+
3647
/** Check that type arguments `args` conform to corresponding bounds in `poly` */
3748
override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit =
3849
for ((arg, bounds) <- args zip poly.paramBounds) {

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ class Namer { typer: Typer =>
591591
(paramSymss.isEmpty || paramSymss.head.nonEmpty && (paramSymss.head.head is Implicit)))
592592
paramSymss = Nil :: paramSymss
593593
val restpe1 = // try to make anonymous functions non-dependent, so that they can be used in closures
594-
if (name == nme.ANON_FUN) tpd.avoid(restpe, paramSymss.flatten)
594+
if (name == nme.ANON_FUN) avoid(restpe, paramSymss.flatten)
595595
else restpe
596596
val monotpe =
597597
(paramSymss :\ restpe1) { (params, restpe) =>

0 commit comments

Comments
 (0)