diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 87 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/EtaExpansion.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inliner.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/RefChecks.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 39 |
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) } } |