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

Try/typer reorg #47

Merged
merged 9 commits into from Mar 8, 2014
5 changes: 3 additions & 2 deletions src/dotty/tools/dotc/ast/CheckTrees.scala
Expand Up @@ -6,6 +6,7 @@ import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._

// TODO: revise, integrate in a checking phase.
object CheckTrees {

import tpd._
Expand All @@ -19,7 +20,7 @@ object CheckTrees {

def escapingRefs(block: Block)(implicit ctx: Context): collection.Set[NamedType] = {
var hoisted: Set[Symbol] = Set()
lazy val locals = localSyms(block.stats).toSet
lazy val locals = ctx.typeAssigner.localSyms(block.stats).toSet
def isLocal(sym: Symbol): Boolean =
(locals contains sym) && !isHoistableClass(sym)
def isHoistableClass(sym: Symbol) =
Expand Down Expand Up @@ -177,7 +178,7 @@ object CheckTrees {
checkRefinements(forbidden - rsym, rs1)
case nil =>
}
checkRefinements(localSyms(refinements).toSet, refinements)
checkRefinements(ctx.typeAssigner.localSyms(refinements).toSet, refinements)
case AppliedTypeTree(tpt, args) =>
check(tpt.isValueType)
val tparams = tpt.tpe.typeParams
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/Trees.scala
Expand Up @@ -644,7 +644,7 @@ object Trees {

/** >: lo <: hi */
case class TypeBoundsTree[-T >: Untyped] private[ast] (lo: Tree[T], hi: Tree[T])
extends Tree[T] {
extends TypTree[T] {
type ThisTree[-T >: Untyped] = TypeBoundsTree[T]
}

Expand Down
222 changes: 64 additions & 158 deletions src/dotty/tools/dotc/ast/tpd.scala

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/dotty/tools/dotc/core/Contexts.scala
Expand Up @@ -119,10 +119,11 @@ object Contexts {
protected def scope_=(scope: Scope) = _scope = scope
def scope: Scope = _scope

/** The current typer */
private[this] var _typer: Typer = _
protected def typer_=(typer: Typer) = _typer = typer
def typer: Typer = _typer
/** The current type assigner ot typer */
private[this] var _typeAssigner: TypeAssigner = _
protected def typeAssigner_=(typeAssigner: TypeAssigner) = _typeAssigner = typeAssigner
def typeAssigner: TypeAssigner = _typeAssigner
def typer: Typer = _typeAssigner.asInstanceOf[Typer]

/** The currently active import info */
private[this] var _importInfo: ImportInfo = _
Expand Down Expand Up @@ -312,7 +313,8 @@ object Contexts {
def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
def withScope(scope: Scope): this.type = { this.scope = scope; this }
def withNewScope: this.type = { this.scope = newScope; this }
def withTyper(typer: Typer): this.type = { this.typer = typer; this.scope = typer.scope; this }
def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) }
def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
Expand Down Expand Up @@ -342,6 +344,7 @@ object Contexts {
owner = NoSymbol
sstate = settings.defaultState
tree = untpd.EmptyTree
typeAssigner = TypeAssigner
runInfo = new RunInfo(this)
diagnostics = None
moreProperties = Map.empty
Expand Down
20 changes: 19 additions & 1 deletion src/dotty/tools/dotc/core/TypeComparer.scala
Expand Up @@ -715,10 +715,28 @@ class TypeComparer(initctx: Context) extends DotClass {

/** Two types are the same if are mutual subtypes of each other */
def isSameType(tp1: Type, tp2: Type): Boolean =
if (tp1 == NoType || tp2 == NoType) false
if (tp1 eq NoType) false
else if (tp1 eq tp2) true
else isSubType(tp1, tp2) && isSubType(tp2, tp1)

/** Same as `isSameType` but also can be applied to overloaded TermRefs, where
* two overloaded refs are the same if they have pairwise equal alternatives
*/
def isSameRef(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSameRef($tp1, $tp2") {
def isSubRef(tp1: Type, tp2: Type): Boolean = tp1 match {
case tp1: TermRef if tp1.isOverloaded =>
tp1.alternatives forall (isSubRef(_, tp2))
case _ =>
tp2 match {
case tp2: TermRef if tp2.isOverloaded =>
tp2.alternatives exists (isSubRef(tp1, _))
case _ =>
isSubType(tp1, tp2)
}
}
isSubRef(tp1, tp2) && isSubRef(tp2, tp1)
}

/** The greatest lower bound of two types */
def glb(tp1: Type, tp2: Type): Type = /*>|>*/ ctx.traceIndented(s"glb(${tp1.show}, ${tp2.show})", typr, show = true) /*<|<*/ {
if (tp1 eq tp2) tp1
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/Types.scala
Expand Up @@ -1140,7 +1140,7 @@ object Types {
override def isOverloaded(implicit ctx: Context) = denot.isOverloaded

private def rewrap(sd: SingleDenotation)(implicit ctx: Context) =
TermRef(prefix, name, sd)
TermRef.withSig(prefix, name, sd.signature, sd)

def alternatives(implicit ctx: Context): List[TermRef] =
denot.alternatives map rewrap
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/core/pickling/UnPickler.scala
Expand Up @@ -988,7 +988,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
case UNAPPLYtree =>
val fun = readTreeRef()
val args = until(end, readTreeRef)
UnApply(fun, Nil, args) // !!! this is wrong in general
UnApply(fun, Nil, args, defn.AnyType) // !!! this is wrong in general

case ARRAYVALUEtree =>
val elemtpt = readTreeRef()
Expand Down Expand Up @@ -1067,7 +1067,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
setSym()
val qual = readTreeRef()
val mix = readTypeNameRef()
Super(qual, mix)
Super(qual, mix, inConstrCall = false) // todo: revise

case THIStree =>
setSym()
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/printing/RefinedPrinter.scala
Expand Up @@ -7,7 +7,7 @@ import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annot
import StdNames.nme
import ast.{Trees, untpd}
import typer.Namer
import typer.Inferencing.{SelectionProto, ViewProto}
import typer.ProtoTypes.{SelectionProto, ViewProto, FunProto}
import Trees._
import scala.annotation.switch

Expand Down Expand Up @@ -120,7 +120,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
case ExprType(result) =>
return "=> " ~ toText(result)
case typer.Inferencing.FunProto(args, resultType, _) =>
case FunProto(args, resultType, _) =>
return "funproto(" ~ toTextGlobal(args, ", ") ~ "):" ~ toText(resultType)
case _ =>
}
Expand Down
43 changes: 17 additions & 26 deletions src/dotty/tools/dotc/typer/Applications.scala
Expand Up @@ -19,7 +19,7 @@ import ErrorReporting._
import Trees._
import Names._
import StdNames._
import Inferencing._
import ProtoTypes._
import EtaExpansion._
import collection.mutable
import reflect.ClassTag
Expand Down Expand Up @@ -398,8 +398,9 @@ trait Applications extends Compatibility { self: Typer =>

val result = {
var typedArgs = typedArgBuf.toList
val ownType =
if (!success) ErrorType
val app0 = cpy.Apply(app, normalizedFun, typedArgs)
val app1 =
if (!success) app0.withType(ErrorType)
else {
if (!sameSeq(args, orderedArgs)) {
// need to lift arguments to maintain evaluation order in the
Expand All @@ -411,9 +412,9 @@ trait Applications extends Compatibility { self: Typer =>
}
if (sameSeq(typedArgs, args)) // trick to cut down on tree copying
typedArgs = args.asInstanceOf[List[Tree]]
methodType.instantiate(typedArgs.tpes)
assignType(app0, normalizedFun, typedArgs)
}
wrapDefs(liftedDefs, cpy.Apply(app, normalizedFun, typedArgs).withType(ownType))
wrapDefs(liftedDefs, app1)
}
}

Expand Down Expand Up @@ -513,21 +514,11 @@ trait Applications extends Compatibility { self: Typer =>
def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = track("typedTypeApply") {
val typedArgs = tree.args mapconserve (typedType(_))
val typedFn = typedExpr(tree.fun, PolyProto(typedArgs.tpes, pt))
val ownType = typedFn.tpe.widen match {
case pt: PolyType =>
checkBounds(typedArgs, pt, tree.pos)
val argTypes = typedArgs.tpes
if (argTypes.length == pt.paramNames.length)
pt.resultType.substParams(pt, typedArgs.tpes)
else {
ctx.error(i"wrong number of type parameters for ${typedFn.tpe}; expected: ${pt.paramNames.length}", tree.pos)
ErrorType
}
typedFn.tpe.widen match {
case pt: PolyType => checkBounds(typedArgs, pt, tree.pos)
case _ =>
ctx.error(s"${err.exprStr(typedFn)} does not take type parameters", tree.pos)
ErrorType
}
cpy.TypeApply(tree, typedFn, typedArgs).withType(ownType)
assignType(cpy.TypeApply(tree, typedFn, typedArgs), typedFn, typedArgs)
}

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

def fromScala2x = unapply.symbol.exists && (unapply.symbol.owner is Scala2x)
def fromScala2x = unapplyFn.symbol.exists && (unapplyFn.symbol.owner is Scala2x)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"fromScala2x" feels like a conversion, maybe "isFromScala2x"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.


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

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

val dummyArg = dummyTreeOfType(unapplyArgType)
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapply, dummyArg :: Nil)))
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
val unapplyImplicits = unapplyApp match {
case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); args2
case Apply(unapply, `dummyArg` :: Nil) => Nil
Expand All @@ -695,12 +686,12 @@ trait Applications extends Compatibility { self: Typer =>
List.fill(argTypes.length - args.length)(WildcardType)
}
val unapplyPatterns = (bunchedArgs, argTypes).zipped map (typed(_, _))
val result = cpy.UnApply(tree, unapply, unapplyImplicits, unapplyPatterns) withType ownType
val result = assignType(cpy.UnApply(tree, unapplyFn, unapplyImplicits, unapplyPatterns), ownType)
unapp.println(s"unapply patterns = $unapplyPatterns")
if ((ownType eq pt) || ownType.isError) result
else Typed(result, TypeTree(ownType))
case tp =>
val unapplyErr = if (tp.isError) unapply else notAnExtractor(unapply)
val unapplyErr = if (tp.isError) unapplyFn else notAnExtractor(unapplyFn)
val typedArgsErr = args mapconserve (typed(_, defn.AnyType))
cpy.UnApply(tree, unapplyErr, Nil, typedArgsErr) withType ErrorType
}
Expand Down