diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 6 |
5 files changed, 60 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 2fa0d5519..5c21584bd 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -18,12 +18,23 @@ import ErrorReporting.{errorType, InfoString} import config.Printers._ import collection.mutable -trait Checking { +trait NoChecking { + import tpd._ + def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = () + def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = () + def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp + def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = () + def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = () + def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp + def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = () +} + +trait Checking extends NoChecking { import tpd._ /** Check that type arguments `args` conform to corresponding bounds in `poly` */ - def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = + override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = for ((arg, bounds) <- args zip poly.paramBounds) { def notConforms(which: String, bound: Type) = ctx.error(i"Type argument ${arg.tpe} does not conform to $which bound $bound", arg.pos) @@ -34,14 +45,14 @@ trait Checking { /** Check that type `tp` is stable. * @return The type itself */ - def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = + override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = if (!tp.isStable) ctx.error(i"Prefix of type ${tp.widenIfUnstable} is not stable", pos) /** Check that `tp` is a class type with a stable prefix. Also, if `isFirst` is * false check that `tp` is a trait. * @return `tp` itself if it is a class or trait ref, ObjectClass.typeRef if not. */ - def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = + override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp.underlyingClassRef match { case tref: TypeRef => checkStable(tref.prefix, pos) @@ -53,7 +64,7 @@ trait Checking { } /** Check that (return) type of implicit definition is not empty */ - def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match { + override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match { case TypeTree(original) if original.isEmpty => val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else "" ctx.error(i"${resStr}type of implicit definition needs to be given explicitly", defTree.pos) @@ -63,7 +74,7 @@ trait Checking { /** Check that a non-implicit parameter making up the first parameter section of an * implicit conversion is not a singleton type. */ - def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = vparamss match { + override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = vparamss match { case (vparam :: Nil) :: _ if !(vparam.symbol is Implicit) => if (vparam.tpt.tpe.isInstanceOf[SingletonType]) ctx.error(s"implicit conversion may not have a parameter of singleton type", vparam.tpt.pos) @@ -74,7 +85,7 @@ trait Checking { * their lower bound conforms to their upper cound. If a type argument is * infeasible, issue and error and continue with upper bound. */ - def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp match { + override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp match { case tp: RefinedType => tp.derivedRefinedType(tp.parent, tp.refinedName, checkFeasible(tp.refinedInfo, pos, where)) case tp @ TypeBounds(lo, hi) if !(lo <:< hi) => @@ -85,7 +96,7 @@ trait Checking { } /** Check that class does not define */ - def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = { + override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = { val seen = new mutable.HashMap[Name, List[Symbol]] { override def default(key: Name) = Nil } diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 7d1e0629e..6e91e4754 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -58,14 +58,16 @@ trait NamerContextOps { this: Context => /** The symbol (stored in some typer's symTree) of an enclosing context definition */ def symOfContextTree(tree: untpd.Tree) = { def go(ctx: Context): Symbol = { - val typer = ctx.typer - if (typer == null) NoSymbol - else tree.getAttachment(typer.SymOfTree) match { - case Some(sym) => sym - case None => - var cx = ctx.outer - while (cx.typer eq typer) cx = cx.outer - go(cx) + ctx.typeAssigner match { + case typer: Typer => + tree.getAttachment(typer.SymOfTree) match { + case Some(sym) => sym + case None => + var cx = ctx.outer + while (cx.typeAssigner eq typer) cx = cx.outer + go(cx) + } + case _ => NoSymbol } } go(this) diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 87c556fdc..b4068408b 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -103,7 +103,7 @@ object ProtoTypes { def map(tm: TypeMap)(implicit ctx: Context) = derivedSelectionProto(name, tm(memberProto), compat) def fold[T](x: T, ta: TypeAccumulator[T])(implicit ctx: Context) = ta(x, memberProto) - override def computeHash = addDelta(doHash(name, memberProto), if (compat == NoViewsAllowed) 1 else 0) + override def computeHash = addDelta(doHash(name, memberProto), if (compat eq NoViewsAllowed) 1 else 0) } class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility) extends SelectionProto(name, memberProto, compat) diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala new file mode 100644 index 000000000..e711ee949 --- /dev/null +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -0,0 +1,27 @@ +package dotty.tools +package dotc +package typer + +import core._ +import ast._ +import Scopes._, Contexts._, Constants._, Types._, Symbols._ + +trait TypeAssigner extends NoChecking { + + def assignType(tree: untpd.New)(implicit ctx: Context) = { + checkClassTypeWithStablePrefix(tree.tpt.tpe, tree.tpt.pos, traitReq = false) + tree.withType(tree.tpt.tpe) + } + + def assignType(tree: untpd.Literal)(implicit ctx: Context) = + tree.withType { + tree.const.tag match { + case UnitTag => defn.UnitType + case NullTag => defn.NullType + case _ => ConstantType(tree.const) + } + } +} + +object TypeAssigner extends TypeAssigner + diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 12d349ce4..c545641a0 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -48,7 +48,7 @@ object Typer { } } -class Typer extends Namer with Applications with Implicits with Inferencing with Checking { +class Typer extends Namer with TypeAssigner with Applications with Implicits with Inferencing with Checking { import Typer._ import tpd.{cpy => _, _} @@ -413,7 +413,7 @@ class Typer extends Namer with Applications with Implicits with Inferencing with } def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) = track("typedLiteral") { - tpd.typedLiteral(tree) + assignType(tree) } def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context) = track("typedNew") { @@ -425,7 +425,7 @@ class Typer extends Namer with Applications with Implicits with Inferencing with typed(cpy.Block(tree, clsDef :: Nil, New(Ident(x), Nil)), pt) case _ => val tpt1 = typedType(tree.tpt) - tpd.typedNew(cpy.New(tree, tpt1)) + assignType(cpy.New(tree, tpt1)) // todo in a later phase: checkInstantiatable(cls, tpt1.pos) } } |