diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/ast/CheckTrees.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TypedTrees.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 12 |
7 files changed, 45 insertions, 39 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala index 290d18b0c..cce68c557 100644 --- a/src/dotty/tools/dotc/ast/CheckTrees.scala +++ b/src/dotty/tools/dotc/ast/CheckTrees.scala @@ -88,7 +88,7 @@ object CheckTrees { check(tp <:< absMembers.head.info) case _ => check(expr.isValueOrPattern) - check(expr.tpe <:< tpt.tpe) + check(expr.tpe <:< tpt.tpe.translateParameterized(defn.RepeatedParamClass, defn.SeqClass)) } case NamedArg(name, arg) => case Assign(lhs, rhs) => diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala index e8303e6b8..60344267f 100644 --- a/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -73,7 +73,7 @@ trait TreeInfo[T >: Untyped] { self: Trees.Instance[T] => case Block(stats, expr) => methPart(expr) case _ => tree } - + /** If this is an application, its function part, stripping all * Apply nodes (but leaving TypeApply nodes in). Otherwise the tree itself. */ @@ -209,13 +209,6 @@ trait TreeInfo[T >: Untyped] { self: Trees.Instance[T] => case _ => false } - /** Is the argument a wildcard star type of the form `_*`? - */ - def isWildcardStarType(tree: Tree): Boolean = tree match { - case Ident(tpnme.WILDCARD_STAR) => true - case _ => false - } - /** Is this pattern node a catch-all (wildcard or variable) pattern? */ def isDefaultCase(cdef: CaseDef) = cdef match { case CaseDef(pat, EmptyTree, _) => isWildcardArg(pat) diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala index 79e54fccb..a498346f5 100644 --- a/src/dotty/tools/dotc/ast/TypedTrees.scala +++ b/src/dotty/tools/dotc/ast/TypedTrees.scala @@ -15,7 +15,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { sym.annotations map (_.tree)) def Ident(tp: NamedType)(implicit ctx: Context): Ident = - untpd.Ident(tp.name).withType(tp.underlyingIfRepeated).checked + underlyingIfRepeated(untpd.Ident(tp.name) withType tp).checked def Select(qualifier: Tree, name: Name)(implicit ctx: Context): Select = Select(qualifier, NamedType(qualifier.tpe, name)) @@ -155,7 +155,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { val untpdSeqLit = if (tpe derivesFrom defn.SeqClass) untpd.SeqLiteral(elems) else untpd.JavaSeqLiteral(elems) - untpdSeqLit.withType(tpe.elemType).checked + untpdSeqLit.withType(tpe).checked } def JavaSeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral = @@ -297,6 +297,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def ref(sym: Symbol)(implicit ctx: Context): tpd.NameTree = ref(NamedType(sym.owner.thisType, sym.name).withDenot(sym)) + // ----- Converting to releated trees ----------------------------------------------- + + def underlyingIfRepeated(id: Ident)(implicit ctx: Context): Ident = + if (id.isType) id else id withType id.tpe.underlyingIfRepeated + + def seqToRepeated(tree: Tree)(implicit ctx: Context): Tree = + Typed(tree, TypeTree(tree.tpe.translateParameterized(defn.SeqClass, defn.RepeatedParamClass))) + // ------ Creating typed equivalents of trees that exist only in untyped form ------- /** new C(args) */ diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index a2b67794c..96fe172b3 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -32,15 +32,15 @@ class Definitions(implicit ctx: Context) { private def newTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) = scope.enter(newSymbol(cls, name, flags | TypeParamCreationFlags, TypeBounds.empty)) - private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, suffix: String = "T0") = + private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, paramFlags: FlagSet, suffix: String = "T0") = newTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName, scope) - private def specialPolyClass(name: TypeName, flags: FlagSet, parentConstrs: Type*): ClassSymbol = { + private def specialPolyClass(name: TypeName, paramFlags: FlagSet, parentConstrs: Type*): ClassSymbol = { val completer = new LazyType { def complete(denot: SymDenotation): Unit = { val cls = denot.asClass.classSymbol val paramDecls = newScope - val typeParam = newSyntheticTypeParam(cls, paramDecls) + val typeParam = newSyntheticTypeParam(cls, paramDecls, paramFlags) def instantiate(tpe: Type) = if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.symTypeRef) else tpe @@ -49,7 +49,7 @@ class Definitions(implicit ctx: Context) { denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls) } } - newClassSymbol(ScalaPackageClass, name, flags, completer) + newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer) } private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol = @@ -185,8 +185,8 @@ class Definitions(implicit ctx: Context) { lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, AnyType) lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, AnyType) - lazy val RepeatedParamAlias = newAliasType(tpnme.REPEATED_PARAM_CLASS, SeqType) - lazy val JavaRepeatedParamAlias = newAliasType(tpnme.JAVA_REPEATED_PARAM_CLASS, ArrayType) + lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, SeqType) + lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS, Covariant, ArrayType) // fundamental classes lazy val StringClass = requiredClass("java.lang.String") @@ -257,8 +257,8 @@ class Definitions(implicit ctx: Context) { def DoubleType: Type = DoubleClass.typeConstructor def PairType: Type = PairClass.typeConstructor def StringType: Type = StringClass.typeConstructor - def RepeatedParamType = RepeatedParamAlias.typeConstructor - def JavaRepeatedParamType = JavaRepeatedParamAlias.typeConstructor + def RepeatedParamType = RepeatedParamClass.typeConstructor + def JavaRepeatedParamType = JavaRepeatedParamClass.typeConstructor def ThrowableType = ThrowableClass.typeConstructor def OptionType = OptionClass.typeConstructor @@ -300,7 +300,7 @@ class Definitions(implicit ctx: Context) { lazy val TupleClasses: Set[Symbol] = TupleClass.toSet lazy val ProductClasses: Set[Symbol] = ProductNClass.toSet - lazy val RepeatedParamAliases: Set[Symbol] = Set(RepeatedParamAlias, JavaRepeatedParamAlias) + lazy val RepeatedParamClasses: Set[Symbol] = Set(RepeatedParamClass, JavaRepeatedParamClass) /** Modules whose members are in the default namespace */ lazy val UnqualifiedModules: Set[TermSymbol] = Set(PredefModule, ScalaPackageVal, JavaLangPackageVal) @@ -377,7 +377,6 @@ class Definitions(implicit ctx: Context) { hkTraitOfArity.getOrElseUpdate(vcs, createTrait) } - // ----- Value class machinery ------------------------------------------ lazy val ScalaValueClasses: collection.Set[Symbol] = Set( @@ -439,8 +438,8 @@ class Definitions(implicit ctx: Context) { /** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ lazy val syntheticCoreClasses = List( AnyRefAlias, - RepeatedParamAlias, - JavaRepeatedParamAlias, + RepeatedParamClass, + JavaRepeatedParamClass, ByNameParamClass, AnyClass, AnyValClass, diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 0edb4b0cc..8b116baa5 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -171,7 +171,7 @@ object Types { that.existsPart(this == _) def isRepeatedParam(implicit ctx: Context): Boolean = - defn.RepeatedParamAliases contains typeSymbol + defn.RepeatedParamClasses contains typeSymbol // ----- Higher-order combinators ----------------------------------- @@ -862,6 +862,14 @@ object Types { NoType } + /** Translate a type of the form From[T] to To[T], keep other types as they are. + * `from` and `to` must be static classes, both with one type parameter, and the same variance. + */ + def translateParameterized(from: ClassSymbol, to: ClassSymbol)(implicit ctx: Context): Type = + if (this derivesFrom from) + RefinedType(to.typeConstructor, to.typeParams.head.name, member(from.typeParams.head.name).info) + else this + /** If this is an encoding of a (partially) applied type, return its arguments, * otherwise return Nil */ diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 0abaa17fe..e2e40e7e2 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -327,17 +327,10 @@ trait Applications extends Compatibility { self: Typer => init() } - /** Subtrait of Application for the cases where arguments are (typed or - * untyped) trees. - */ - trait TreeApplication[T >: Untyped] extends Application[Trees.Tree[T]] { - type TypeArg = Tree - def isVarArg(arg: Trees.Tree[T]): Boolean = isWildcardStarArg(arg) - } - /** Subclass of Application for applicability tests with trees as arguments. */ class ApplicableToTrees(methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context) - extends TestApplication(methRef, methRef, args, resultType) with TreeApplication[Type] { + extends TestApplication(methRef, methRef, args, resultType) { + def isVarArg(arg: Tree): Boolean = tpd.isWildcardStarArg(arg) def argType(arg: Tree): Type = normalize(arg.tpe) def treeToArg(arg: Tree): Tree = arg } @@ -355,8 +348,9 @@ trait Applications extends Compatibility { self: Typer => */ abstract class TypedApply[T >: Untyped]( app: untpd.Apply, fun: Tree, methRef: TermRef, args: List[Trees.Tree[T]], resultType: Type)(implicit ctx: Context) - extends Application(methRef, fun.tpe, args, resultType) with TreeApplication[T] { + extends Application(methRef, fun.tpe, args, resultType) { type TypedArg = Tree + def isVarArg(arg: Trees.Tree[T]): Boolean = untpd.isWildcardStarArg(arg) private var typedArgBuf = new mutable.ListBuffer[Tree] private var liftedDefs: mutable.ListBuffer[Tree] = null private var myNormalizedFun: Tree = fun @@ -369,7 +363,7 @@ trait Applications extends Compatibility { self: Typer => val args = typedArgBuf.takeRight(n).toList typedArgBuf.trimEnd(n) val seqLit = if (methodType.isJava) JavaSeqLiteral(args) else SeqLiteral(args) - typedArgBuf += seqLit + typedArgBuf += seqToRepeated(seqLit) } def fail(msg: => String, arg: Trees.Tree[T]) = { diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index a22d128e3..1bdc5516c 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -407,9 +407,13 @@ class Typer extends Namer with Applications with Implicits { import untpd._ typed(Bind(id.name, Typed(Ident(nme.WILDCARD), tree.tpt)).withPos(id.pos)) case _ => - val tpt1 = typedType(tree.tpt) - val expr1 = typedExpr(tree.expr, tpt1.tpe) - cpy.Typed(tree, expr1, tpt1).withType(tpt1.tpe) + if (untpd.isWildcardStarArg(tree)) + seqToRepeated(typedExpr(tree.expr, defn.SeqType)) + else { + val tpt1 = typedType(tree.tpt) + val expr1 = typedExpr(tree.expr, tpt1.tpe) + cpy.Typed(tree, expr1, tpt1).withType(tpt1.tpe) + } } } @@ -608,7 +612,7 @@ class Typer extends Namer with Applications with Implicits { def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") { val proto1 = pt.elemType orElse WildcardType val elems1 = tree.elems mapconserve (typed(_, proto1)) - cpy.SeqLiteral(tree, elems1) withType ctx.typeComparer.lub(elems1.tpes) + cpy.SeqLiteral(tree, elems1) withType defn.SeqType.appliedTo(ctx.typeComparer.lub(elems1.tpes)) } def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") { |