Skip to content

Commit d827b01

Browse files
committed
Merge pull request scala#47 from odersky/try/typer-reorg
Try/typer reorg
2 parents 5d70c58 + 6aa88d6 commit d827b01

19 files changed

+1087
-909
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/Trees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ object Trees {
644644

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

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

Lines changed: 64 additions & 158 deletions
Large diffs are not rendered by default.

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ object Contexts {
119119
protected def scope_=(scope: Scope) = _scope = scope
120120
def scope: Scope = _scope
121121

122-
/** The current typer */
123-
private[this] var _typer: Typer = _
124-
protected def typer_=(typer: Typer) = _typer = typer
125-
def typer: Typer = _typer
122+
/** The current type assigner ot typer */
123+
private[this] var _typeAssigner: TypeAssigner = _
124+
protected def typeAssigner_=(typeAssigner: TypeAssigner) = _typeAssigner = typeAssigner
125+
def typeAssigner: TypeAssigner = _typeAssigner
126+
def typer: Typer = _typeAssigner.asInstanceOf[Typer]
126127

127128
/** The currently active import info */
128129
private[this] var _importInfo: ImportInfo = _
@@ -312,7 +313,8 @@ object Contexts {
312313
def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
313314
def withScope(scope: Scope): this.type = { this.scope = scope; this }
314315
def withNewScope: this.type = { this.scope = newScope; this }
315-
def withTyper(typer: Typer): this.type = { this.typer = typer; this.scope = typer.scope; this }
316+
def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
317+
def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) }
316318
def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
317319
def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
318320
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
@@ -342,6 +344,7 @@ object Contexts {
342344
owner = NoSymbol
343345
sstate = settings.defaultState
344346
tree = untpd.EmptyTree
347+
typeAssigner = TypeAssigner
345348
runInfo = new RunInfo(this)
346349
diagnostics = None
347350
moreProperties = Map.empty

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,10 +715,28 @@ class TypeComparer(initctx: Context) extends DotClass {
715715

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

722+
/** Same as `isSameType` but also can be applied to overloaded TermRefs, where
723+
* two overloaded refs are the same if they have pairwise equal alternatives
724+
*/
725+
def isSameRef(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSameRef($tp1, $tp2") {
726+
def isSubRef(tp1: Type, tp2: Type): Boolean = tp1 match {
727+
case tp1: TermRef if tp1.isOverloaded =>
728+
tp1.alternatives forall (isSubRef(_, tp2))
729+
case _ =>
730+
tp2 match {
731+
case tp2: TermRef if tp2.isOverloaded =>
732+
tp2.alternatives exists (isSubRef(tp1, _))
733+
case _ =>
734+
isSubType(tp1, tp2)
735+
}
736+
}
737+
isSubRef(tp1, tp2) && isSubRef(tp2, tp1)
738+
}
739+
722740
/** The greatest lower bound of two types */
723741
def glb(tp1: Type, tp2: Type): Type = /*>|>*/ ctx.traceIndented(s"glb(${tp1.show}, ${tp2.show})", typr, show = true) /*<|<*/ {
724742
if (tp1 eq tp2) tp1

src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ object Types {
11401140
override def isOverloaded(implicit ctx: Context) = denot.isOverloaded
11411141

11421142
private def rewrap(sd: SingleDenotation)(implicit ctx: Context) =
1143-
TermRef(prefix, name, sd)
1143+
TermRef.withSig(prefix, name, sd.signature, sd)
11441144

11451145
def alternatives(implicit ctx: Context): List[TermRef] =
11461146
denot.alternatives map rewrap

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/printing/RefinedPrinter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annot
77
import StdNames.nme
88
import ast.{Trees, untpd}
99
import typer.Namer
10-
import typer.Inferencing.{SelectionProto, ViewProto}
10+
import typer.ProtoTypes.{SelectionProto, ViewProto, FunProto}
1111
import Trees._
1212
import scala.annotation.switch
1313

@@ -120,7 +120,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
120120
}
121121
case ExprType(result) =>
122122
return "=> " ~ toText(result)
123-
case typer.Inferencing.FunProto(args, resultType, _) =>
123+
case FunProto(args, resultType, _) =>
124124
return "funproto(" ~ toTextGlobal(args, ", ") ~ "):" ~ toText(resultType)
125125
case _ =>
126126
}

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

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import ErrorReporting._
1919
import Trees._
2020
import Names._
2121
import StdNames._
22-
import Inferencing._
22+
import ProtoTypes._
2323
import EtaExpansion._
2424
import collection.mutable
2525
import reflect.ClassTag
@@ -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
}

0 commit comments

Comments
 (0)