aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala87
-rw-r--r--src/dotty/tools/dotc/typer/EtaExpansion.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Inliner.scala5
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala2
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala9
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala39
6 files changed, 59 insertions, 85 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 3ebae733f..dbfc89f6c 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -55,58 +55,45 @@ object Checking {
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
- /** If type is a higher-kinded application with wildcard arguments,
- * check that it or one of its supertypes can be reduced to a normal application.
- * Unreducible applications correspond to general existentials, and we
- * cannot handle those.
+ /** Check applied type trees for well-formedness. This means
+ * - all arguments are within their corresponding bounds
+ * - if type is a higher-kinded application with wildcard arguments,
+ * check that it or one of its supertypes can be reduced to a normal application.
+ * Unreducible applications correspond to general existentials, and we
+ * cannot handle those.
*/
- def checkWildcardHKApply(tp: Type, pos: Position)(implicit ctx: Context): Unit = tp match {
- case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) =>
- tycon match {
- case tycon: PolyType =>
- ctx.errorOrMigrationWarning(
- ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
- pos)
- case _ =>
- checkWildcardHKApply(tp.superType, pos)
- }
- case _ =>
- }
-
- /** Traverse type tree, performing the following checks:
- * 1. All arguments of applied type trees must conform to their bounds.
- * 2. Prefixes of type selections and singleton types must be realizable.
- */
- val typeChecker = new TreeTraverser {
- def traverse(tree: Tree)(implicit ctx: Context) = {
- tree match {
- case AppliedTypeTree(tycon, args) =>
- // If `args` is a list of named arguments, return corresponding type parameters,
- // otherwise return type parameters unchanged
- val tparams = tycon.tpe.typeParams
- def argNamed(tparam: TypeParamInfo) = args.find {
- case NamedArg(name, _) => name == tparam.paramName
- case _ => false
- }.getOrElse(TypeTree(tparam.paramRef))
- val orderedArgs = if (hasNamedArg(args)) tparams.map(argNamed) else args
- val bounds = tparams.map(_.paramBoundsAsSeenFrom(tycon.tpe))
- def instantiate(bound: Type, args: List[Type]) =
- bound.LambdaAbstract(tparams).appliedTo(args)
- checkBounds(orderedArgs, bounds, instantiate)
-
- def checkValidIfHKApply(implicit ctx: Context): Unit =
- checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
- checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
- case Select(qual, name) if name.isTypeName =>
- checkRealizable(qual.tpe, qual.pos.focus)
- case SingletonTypeTree(ref) =>
- checkRealizable(ref.tpe, ref.pos.focus)
- case _ =>
- }
- traverseChildren(tree)
- }
+ def checkAppliedType(tree: AppliedTypeTree)(implicit ctx: Context) = {
+ val AppliedTypeTree(tycon, args) = tree
+ // If `args` is a list of named arguments, return corresponding type parameters,
+ // otherwise return type parameters unchanged
+ val tparams = tycon.tpe.typeParams
+ def argNamed(tparam: TypeParamInfo) = args.find {
+ case NamedArg(name, _) => name == tparam.paramName
+ case _ => false
+ }.getOrElse(TypeTree(tparam.paramRef))
+ val orderedArgs = if (hasNamedArg(args)) tparams.map(argNamed) else args
+ val bounds = tparams.map(_.paramBoundsAsSeenFrom(tycon.tpe))
+ def instantiate(bound: Type, args: List[Type]) =
+ bound.LambdaAbstract(tparams).appliedTo(args)
+ checkBounds(orderedArgs, bounds, instantiate)
+
+ def checkWildcardHKApply(tp: Type, pos: Position): Unit = tp match {
+ case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) =>
+ tycon match {
+ case tycon: PolyType =>
+ ctx.errorOrMigrationWarning(
+ ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
+ pos)
+ case _ =>
+ checkWildcardHKApply(tp.superType, pos)
+ }
+ case _ =>
+ }
+ def checkValidIfHKApply(implicit ctx: Context): Unit =
+ checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
+ checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
}
-
+
/** Check that `tp` refers to a nonAbstract class
* and that the instance conforms to the self type of the created class.
*/
diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 397b6d95b..c390ae808 100644
--- a/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -138,7 +138,7 @@ object EtaExpansion {
if (mt.paramTypes.length == xarity) mt.paramTypes map (_ => TypeTree())
else mt.paramTypes map TypeTree
val params = (mt.paramNames, paramTypes).zipped.map((name, tpe) =>
- ValDef(name, TypeTree(tpe), EmptyTree).withFlags(Synthetic | Param).withPos(tree.pos))
+ ValDef(name, tpe, EmptyTree).withFlags(Synthetic | Param).withPos(tree.pos))
var ids: List[Tree] = mt.paramNames map (name => Ident(name).withPos(tree.pos))
if (mt.paramTypes.nonEmpty && mt.paramTypes.last.isRepeatedParam)
ids = ids.init :+ repeated(ids.last)
diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala
index 55008c0c5..40c1ca350 100644
--- a/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/src/dotty/tools/dotc/typer/Inliner.scala
@@ -244,8 +244,9 @@ object Inliner {
/** Replace `Inlined` node by a block that contains its bindings and expansion */
def dropInlined(inlined: tpd.Inlined)(implicit ctx: Context): Tree = {
val reposition = new TreeMap {
- override def transform(tree: Tree)(implicit ctx: Context): Tree =
- tree.withPos(inlined.call.pos)
+ override def transform(tree: Tree)(implicit ctx: Context): Tree = {
+ super.transform(tree).withPos(inlined.call.pos)
+ }
}
tpd.seq(inlined.bindings, reposition.transform(inlined.expansion))
}
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 00e92cbfb..9da0e2edc 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -927,7 +927,7 @@ class Namer { typer: Typer =>
val tptProto = mdef.tpt match {
case _: untpd.DerivedTypeTree =>
WildcardType
- case TypeTree(untpd.EmptyTree) =>
+ case TypeTree() =>
inferredType
case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) =>
val rhsType = typedAheadExpr(mdef.rhs, tpt.tpe).tpe
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index 834bb37a8..026015d1d 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -851,15 +851,6 @@ class RefChecks extends MiniPhase { thisTransformer =>
tree
}
- override def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo) = {
- if (!tree.original.isEmpty)
- tree.tpe.foreachPart {
- case tp: NamedType => checkUndesiredProperties(tp.symbol, tree.pos)
- case _ =>
- }
- tree
- }
-
override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
checkUndesiredProperties(tree.symbol, tree.pos)
currentLevel.enterReference(tree.symbol, tree.pos)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 56c04c063..c283f43cf 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -953,28 +953,23 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") {
- if (tree.original.isEmpty)
- tree match {
- case tree: untpd.DerivedTypeTree =>
- tree.ensureCompletions
- try
- TypeTree(tree.derivedType(tree.attachment(untpd.OriginalSymbol))) withPos tree.pos
- // btw, no need to remove the attachment. The typed
- // tree is different from the untyped one, so the
- // untyped tree is no longer accessed after all
- // accesses with typedTypeTree are done.
- catch {
- case ex: NoSuchElementException =>
- println(s"missing OriginalSymbol for ${ctx.owner.ownersIterator.toList}")
- throw ex
- }
- case _ =>
- assert(isFullyDefined(pt, ForceDegree.none))
- tree.withType(pt)
- }
- else {
- val original1 = typed(tree.original)
- cpy.TypeTree(tree)(original1).withType(original1.tpe)
+ tree match {
+ case tree: untpd.DerivedTypeTree =>
+ tree.ensureCompletions
+ try
+ TypeTree(tree.derivedType(tree.attachment(untpd.OriginalSymbol))) withPos tree.pos
+ // btw, no need to remove the attachment. The typed
+ // tree is different from the untyped one, so the
+ // untyped tree is no longer accessed after all
+ // accesses with typedTypeTree are done.
+ catch {
+ case ex: NoSuchElementException =>
+ println(s"missing OriginalSymbol for ${ctx.owner.ownersIterator.toList}")
+ throw ex
+ }
+ case _ =>
+ assert(isFullyDefined(pt, ForceDegree.none))
+ tree.withType(pt)
}
}