diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 5b6abfabfaec..516028ec9f1f 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1440,7 +1440,7 @@ object desugar { def collect(tree: Tree): Unit = tree match { case Bind(nme.WILDCARD, tree1) => collect(tree1) - case tree @ Bind(_, Typed(tree1, tpt)) if !mayBeTypePat(tpt) => + case tree @ Bind(_, Typed(tree1, tpt)) => add(tree, tpt) collect(tree1) case tree @ Bind(_, tree1) => diff --git a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala index f909efff6ba3..8f4e065fbf79 100644 --- a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala +++ b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala @@ -154,7 +154,7 @@ object DesugarEnums { parentTypes.head match { case parent: RefTree if parent.name == enumClass.name => // need a widen method to compute correct type parameters for enum base class - val widenParamType = (appliedEnumRef /: parentTypes.tail)(AndTypeTree) + val widenParamType = (appliedEnumRef /: parentTypes.tail)(makeAndType) val widenParam = makeSyntheticParameter(tpt = widenParamType) val widenDef = DefDef( name = s"${cdef.name}$$to$$${enumClass.name}".toTermName, @@ -164,7 +164,7 @@ object DesugarEnums { rhs = Ident(widenParam.name)) (TypeTree(), widenDef :: Nil) case _ => - (parentTypes.reduceLeft(AndTypeTree), Nil) + (parentTypes.reduceLeft(makeAndType), Nil) } } diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index b4637ff1516d..fe3f1e2d8c2a 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -164,17 +164,6 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] => /** Is name a left-associative operator? */ def isLeftAssoc(operator: Name): Boolean = !operator.isEmpty && (operator.toSimpleName.last != ':') - /** can this type be a type pattern? */ - def mayBeTypePat(tree: Tree): Boolean = unsplice(tree) match { - case AndTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2) - case OrTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2) - case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind]) - case AppliedTypeTree(tpt, args) => mayBeTypePat(tpt) || args.exists(_.isInstanceOf[Bind]) - case Select(tpt, _) => mayBeTypePat(tpt) - case Annotated(tpt, _) => mayBeTypePat(tpt) - case _ => false - } - /** Is this argument node of the form : _*, or is it a reference to * such an argument ? The latter case can happen when an argument is lifted. */ diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 6589104fb158..5eda3d940bcc 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -626,18 +626,6 @@ object Trees { type ThisTree[-T >: Untyped] = SingletonTypeTree[T] } - /** left & right */ - case class AndTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])(implicit @constructorOnly src: SourceFile) - extends TypTree[T] { - type ThisTree[-T >: Untyped] = AndTypeTree[T] - } - - /** left | right */ - case class OrTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])(implicit @constructorOnly src: SourceFile) - extends TypTree[T] { - type ThisTree[-T >: Untyped] = OrTypeTree[T] - } - /** tpt { refinements } */ case class RefinedTypeTree[-T >: Untyped] private[ast] (tpt: Tree[T], refinements: List[Tree[T]])(implicit @constructorOnly src: SourceFile) extends ProxyTree[T] with TypTree[T] { @@ -934,8 +922,6 @@ object Trees { type Inlined = Trees.Inlined[T] type TypeTree = Trees.TypeTree[T] type SingletonTypeTree = Trees.SingletonTypeTree[T] - type AndTypeTree = Trees.AndTypeTree[T] - type OrTypeTree = Trees.OrTypeTree[T] type RefinedTypeTree = Trees.RefinedTypeTree[T] type AppliedTypeTree = Trees.AppliedTypeTree[T] type LambdaTypeTree = Trees.LambdaTypeTree[T] @@ -1102,14 +1088,6 @@ object Trees { case tree: SingletonTypeTree if (ref eq tree.ref) => tree case _ => finalize(tree, untpd.SingletonTypeTree(ref)(sourceFile(tree))) } - def AndTypeTree(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = tree match { - case tree: AndTypeTree if (left eq tree.left) && (right eq tree.right) => tree - case _ => finalize(tree, untpd.AndTypeTree(left, right)(sourceFile(tree))) - } - def OrTypeTree(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = tree match { - case tree: OrTypeTree if (left eq tree.left) && (right eq tree.right) => tree - case _ => finalize(tree, untpd.OrTypeTree(left, right)(sourceFile(tree))) - } def RefinedTypeTree(tree: Tree)(tpt: Tree, refinements: List[Tree])(implicit ctx: Context): RefinedTypeTree = tree match { case tree: RefinedTypeTree if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree case _ => finalize(tree, untpd.RefinedTypeTree(tpt, refinements)(sourceFile(tree))) @@ -1271,10 +1249,6 @@ object Trees { tree case SingletonTypeTree(ref) => cpy.SingletonTypeTree(tree)(transform(ref)) - case AndTypeTree(left, right) => - cpy.AndTypeTree(tree)(transform(left), transform(right)) - case OrTypeTree(left, right) => - cpy.OrTypeTree(tree)(transform(left), transform(right)) case RefinedTypeTree(tpt, refinements) => cpy.RefinedTypeTree(tree)(transform(tpt), transformSub(refinements)) case AppliedTypeTree(tpt, args) => @@ -1399,10 +1373,6 @@ object Trees { x case SingletonTypeTree(ref) => this(x, ref) - case AndTypeTree(left, right) => - this(this(x, left), right) - case OrTypeTree(left, right) => - this(this(x, left), right) case RefinedTypeTree(tpt, refinements) => this(this(x, tpt), refinements) case AppliedTypeTree(tpt, args) => diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 1c9d0d77ae23..5672feb468b4 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -161,12 +161,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree = ta.assignType(untpd.SingletonTypeTree(ref), ref) - def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = - ta.assignType(untpd.AndTypeTree(left, right), left, right) - - def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = - ta.assignType(untpd.OrTypeTree(left, right), left, right) - def RefinedTypeTree(parent: Tree, refinements: List[Tree], refineCls: ClassSymbol)(implicit ctx: Context): Tree = ta.assignType(untpd.RefinedTypeTree(parent, refinements), parent, refinements, refineCls) diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 8dee85adb6b7..00d0b9fbbcc9 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -309,8 +309,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, bindings, expansion) def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree() def SingletonTypeTree(ref: Tree)(implicit src: SourceFile): SingletonTypeTree = new SingletonTypeTree(ref) - def AndTypeTree(left: Tree, right: Tree)(implicit src: SourceFile): AndTypeTree = new AndTypeTree(left, right) - def OrTypeTree(left: Tree, right: Tree)(implicit src: SourceFile): OrTypeTree = new OrTypeTree(left, right) def RefinedTypeTree(tpt: Tree, refinements: List[Tree])(implicit src: SourceFile): RefinedTypeTree = new RefinedTypeTree(tpt, refinements) def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit src: SourceFile): AppliedTypeTree = new AppliedTypeTree(tpt, args) def LambdaTypeTree(tparams: List[TypeDef], body: Tree)(implicit src: SourceFile): LambdaTypeTree = new LambdaTypeTree(tparams, body) @@ -403,6 +401,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { case _ => Tuple(ts) } + def makeAndType(left: Tree, right: Tree)(implicit ctx: Context): AppliedTypeTree = + AppliedTypeTree(ref(defn.andType.typeRef), left :: right :: Nil) + def makeParameter(pname: TermName, tpe: Tree, mods: Modifiers = EmptyModifiers)(implicit ctx: Context): ValDef = ValDef(pname, tpe, EmptyTree).withMods(mods | Param) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index ff380a4b534d..3e2d20a111c2 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -153,6 +153,11 @@ class Definitions { sym } + private def enterBinaryAlias(name: TypeName, op: (Type, Type) => Type): TypeSymbol = + enterAliasType(name, + HKTypeLambda(TypeBounds.empty :: TypeBounds.empty :: Nil)( + tl => op(tl.paramRefs(0), tl.paramRefs(1)))) + private def enterPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int, resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags, useCompleter: Boolean = false) = { @@ -322,6 +327,9 @@ class Definitions { } def AnyKindType: TypeRef = AnyKindClass.typeRef + lazy val andType: TypeSymbol = enterBinaryAlias(tpnme.AND, AndType(_, _)) + lazy val orType: TypeSymbol = enterBinaryAlias(tpnme.OR, OrType(_, _)) + /** Marker method to indicate an argument to a call-by-name parameter. * Created by byNameClosures and elimByName, eliminated by Erasure, */ @@ -1326,6 +1334,8 @@ class Definitions { AnyClass, AnyRefAlias, AnyKindClass, + andType, + orType, RepeatedParamClass, ByNameParamClass2x, AnyValClass, diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index b8edb41b0c4c..e853ded1ad13 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -106,8 +106,6 @@ Standard-Section: "ASTs" TopLevelStat* LAMBDAtpt Length TypeParam* body_Term TYPEBOUNDStpt Length low_Term high_Term? ANNOTATEDtpt Length underlying_Term fullAnnotation_Term - ANDtpt Length left_Term right_Term - ORtpt Length left_Term right_Term MATCHtpt Length bound_Term? sel_Term CaseDef* BYNAMEtpt underlying_Term SHAREDterm term_ASTRef @@ -246,7 +244,7 @@ Standard Section: "Comments" Comment* object TastyFormat { final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F) - val MajorVersion: Int = 12 + val MajorVersion: Int = 13 val MinorVersion: Int = 0 /** Tags used to serialize names */ @@ -419,9 +417,7 @@ object TastyFormat { final val TYPEBOUNDS = 163 final val TYPEBOUNDStpt = 164 final val ANDtype = 165 - final val ANDtpt = 166 final val ORtype = 167 - final val ORtpt = 168 final val POLYtype = 169 final val TYPELAMBDAtype = 170 final val LAMBDAtpt = 171 @@ -517,8 +513,6 @@ object TastyFormat { | LAMBDAtpt | TYPEBOUNDStpt | ANNOTATEDtpt - | ANDtpt - | ORtpt | BYNAMEtpt | MATCHtpt | BIND => true @@ -647,9 +641,7 @@ object TastyFormat { case TYPEBOUNDStpt => "TYPEBOUNDStpt" case TYPEALIAS => "TYPEALIAS" case ANDtype => "ANDtype" - case ANDtpt => "ANDtpt" case ORtype => "ORtype" - case ORtpt => "ORtpt" case BYNAMEtype => "BYNAMEtype" case BYNAMEtpt => "BYNAMEtpt" case POLYtype => "POLYtype" diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 101a03b9eec5..1cbe5d3a9581 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -559,12 +559,6 @@ class TreePickler(pickler: TastyPickler) { case AppliedTypeTree(tycon, args) => writeByte(APPLIEDtpt) withLength { pickleTree(tycon); args.foreach(pickleTree) } - case AndTypeTree(tp1, tp2) => - writeByte(ANDtpt) - withLength { pickleTree(tp1); pickleTree(tp2) } - case OrTypeTree(tp1, tp2) => - writeByte(ORtpt) - withLength { pickleTree(tp1); pickleTree(tp2) } case MatchTypeTree(bound, selector, cases) => writeByte(MATCHtpt) withLength { diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 15660c4b22bc..052497dad583 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1175,14 +1175,11 @@ class TreeUnpickler(reader: TastyReader, // types. This came up in #137 of collection strawman. val tycon = readTpt() val args = until(end)(readTpt()) - untpd.AppliedTypeTree(tycon, args).withType(tycon.tpe.safeAppliedTo(args.tpes)) - case ANDtpt => - val tpt1 = readTpt() - val tpt2 = readTpt() - // FIXME: We need to do this instead of "AndType(tpt1, tpt2)" to avoid self-type cyclic reference in tasty_tools - untpd.AndTypeTree(tpt1, tpt2).withType(AndType(tpt1.tpe, tpt2.tpe)) - case ORtpt => - OrTypeTree(readTpt(), readTpt()) + val ownType = + if (tycon.symbol == defn.andType) AndType(args(0).tpe, args(1).tpe) + else if (tycon.symbol == defn.orType) OrType(args(0).tpe, args(1).tpe) + else tycon.tpe.safeAppliedTo(args.tpes) + untpd.AppliedTypeTree(tycon, args).withType(ownType) case ANNOTATEDtpt => Annotated(readTpt(), readTerm()) case LAMBDAtpt => diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 3803559d4d10..fedca67ec6f2 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -428,7 +428,7 @@ object JavaParsers { } val ts = buf.toList if (ts.tail.isEmpty) ts.head - else ts.reduce(AndTypeTree(_,_)) + else ts.reduce(makeAndType(_,_)) } def formalParams(): List[ValDef] = { diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 76c727a00a7e..bdd00d714f9d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -423,6 +423,19 @@ object Parsers { case _ => false } + def isWildcardType(t: Tree): Boolean = t match { + case t: TypeBoundsTree => true + case Parens(t1) => isWildcardType(t1) + case _ => false + } + + def rejectWildcardType(t: Tree, fallbackTree: Tree = scalaAny): Tree = + if (isWildcardType(t)) { + syntaxError(UnboundWildcardType(), t.span) + fallbackTree + } + else t + /* -------------- XML ---------------------------------------------------- */ /** the markup parser */ @@ -488,15 +501,7 @@ object Parsers { opStack = opStack.tail recur { atSpan(opInfo.operator.span union opInfo.operand.span union top.span) { - val op = opInfo.operator - val l = opInfo.operand - val r = top - if (isType && !op.isBackquoted && op.name == tpnme.raw.BAR) { - OrTypeTree(checkAndOrArgument(l), checkAndOrArgument(r)) - } else if (isType && !op.isBackquoted && op.name == tpnme.raw.AMP) { - AndTypeTree(checkAndOrArgument(l), checkAndOrArgument(r)) - } else - InfixOp(l, op, r) + InfixOp(opInfo.operand, opInfo.operator, top) } } } @@ -768,7 +773,7 @@ object Parsers { /** Same as [[typ]], but if this results in a wildcard it emits a syntax error and * returns a tree for type `Any` instead. */ - def toplevelTyp(): Tree = checkWildcard(typ()) + def toplevelTyp(): Tree = rejectWildcardType(typ()) /** Type ::= FunTypeMods FunArgTypes `=>' Type * | HkTypeParamClause `->' Type @@ -830,7 +835,7 @@ object Parsers { t } } - val tuple = atSpan(start) { makeTupleOrParens(ts) } + val tuple = atSpan(start) { makeTupleOrParens(ts1) } infixTypeRest( refinedTypeRest( withTypeRest( @@ -885,7 +890,7 @@ object Parsers { def refinedTypeRest(t: Tree): Tree = { newLineOptWhenFollowedBy(LBRACE) - if (in.token == LBRACE) refinedTypeRest(atSpan(startOffset(t)) { RefinedTypeTree(checkWildcard(t), refinement()) }) + if (in.token == LBRACE) refinedTypeRest(atSpan(startOffset(t)) { RefinedTypeTree(rejectWildcardType(t), refinement()) }) else t } @@ -898,7 +903,7 @@ object Parsers { if (ctx.settings.strict.value) deprecationWarning(DeprecatedWithOperator()) in.nextToken() - AndTypeTree(checkAndOrArgument(t), checkAndOrArgument(withType())) + makeAndType(t, withType()) } else t @@ -907,7 +912,10 @@ object Parsers { def annotType(): Tree = annotTypeRest(simpleType()) def annotTypeRest(t: Tree): Tree = - if (in.token == AT) annotTypeRest(atSpan(startOffset(t)) { Annotated(t, annot()) }) + if (in.token == AT) + annotTypeRest(atSpan(startOffset(t)) { + Annotated(rejectWildcardType(t), annot()) + }) else t /** SimpleType ::= SimpleType TypeArgs @@ -949,7 +957,7 @@ object Parsers { private def simpleTypeRest(t: Tree): Tree = in.token match { case HASH => simpleTypeRest(typeProjection(t)) case LBRACKET => simpleTypeRest(atSpan(startOffset(t)) { - AppliedTypeTree(checkWildcard(t), typeArgs(namedOK = false, wildOK = true)) }) + AppliedTypeTree(rejectWildcardType(t), typeArgs(namedOK = false, wildOK = true)) }) case _ => t } @@ -959,18 +967,23 @@ object Parsers { atSpan(startOffset(t), startOffset(id)) { Select(t, id.name) } } - /** NamedTypeArg ::= id `=' Type - */ - val namedTypeArg: () => NamedArg = () => { - val name = ident() - accept(EQUALS) - NamedArg(name.toTypeName, typ()) - } - /** ArgTypes ::= Type {`,' Type} * | NamedTypeArg {`,' NamedTypeArg} + * NamedTypeArg ::= id `=' Type */ def argTypes(namedOK: Boolean, wildOK: Boolean): List[Tree] = { + + def argType() = { + val t = typ() + if (wildOK) t else rejectWildcardType(t) + } + + def namedTypeArg() = { + val name = ident() + accept(EQUALS) + NamedArg(name.toTypeName, argType()) + } + def otherArgs(first: Tree, arg: () => Tree): List[Tree] = { val rest = if (in.token == COMMA) { @@ -980,16 +993,15 @@ object Parsers { else Nil first :: rest } - def typParser() = checkWildcard(typ(), wildOK) if (namedOK && in.token == IDENTIFIER) - typParser() match { + argType() match { case Ident(name) if in.token == EQUALS => in.nextToken() - otherArgs(NamedArg(name, typ()), namedTypeArg) + otherArgs(NamedArg(name, argType()), () => namedTypeArg()) case firstArg => - otherArgs(firstArg, () => typ()) + otherArgs(firstArg, () => argType()) } - else commaSeparated(() => typParser()) + else commaSeparated(() => argType()) } /** FunArgType ::= Type | `=>' Type @@ -1064,46 +1076,6 @@ object Parsers { else if (location == Location.InPattern) refinedType() else infixType() - /** Checks whether `t` represents a non-value type (wildcard types, or ByNameTypeTree). - * If it is, returns the [[Tree]] which immediately represents the non-value type. - */ - @tailrec - private final def findNonValueTypeTree(t: Tree, alsoNonValue: Boolean): Option[Tree] = t match { - case TypeBoundsTree(_, _) => Some(t) - case ByNameTypeTree(_) if alsoNonValue => Some(t) - case Parens(t1) => findNonValueTypeTree(t1, alsoNonValue) - case Annotated(t1, _) => findNonValueTypeTree(t1, alsoNonValue) - case _ => None - } - - def rejectWildcard(t: Tree, fallbackTree: Tree): Tree = - findNonValueTypeTree(t, false) match { - case Some(wildcardTree) => - syntaxError(UnboundWildcardType(), wildcardTree.span) - fallbackTree - case None => t - } - - - def checkWildcard(t: Tree, wildOK: Boolean = false, fallbackTree: Tree = scalaAny): Tree = - if (wildOK) - t - else - rejectWildcard(t, fallbackTree) - - def checkAndOrArgument(t: Tree): Tree = - findNonValueTypeTree(t, true) match { - case Some(typTree) => - typTree match { - case typTree: TypeBoundsTree => - syntaxError(UnboundWildcardType(), typTree.span) - case typTree: ByNameTypeTree => - syntaxError(ByNameParameterNotSupported(typTree), typTree.span) - } - scalaAny - case None => t - } - /* ----------- EXPRESSIONS ------------------------------------------------ */ /** EqualsExpr ::= `=' Expr @@ -2580,7 +2552,7 @@ object Parsers { */ val constrApp: () => Tree = () => { // Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code - val t = checkWildcard(annotType(), fallbackTree = Ident(nme.ERROR)) + val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR)) if (in.token == LPAREN) parArgumentExprss(wrapNew(t)) else t } diff --git a/compiler/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused b/compiler/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused deleted file mode 100644 index d92cbd9572f1..000000000000 --- a/compiler/src/dotty/tools/dotc/parsing/TreeBuilder.scala.unused +++ /dev/null @@ -1,535 +0,0 @@ -package dotty.tools -package dotc -package parsing - -import core._ -import Flags._, Trees._, TypedTrees._, UntypedTrees._, Names._, StdNames._, NameOps._, Contexts._ -import scala.collection.mutable.ListBuffer -import util.Spans._, Symbols._, Decorators._, Flags._, Constants._ -import TreeInfo._ - -/** Methods for building trees, used in the parser. All the trees - * returned by this class must be untyped. - * Note: currently unused - */ -class TreeBuilder(implicit ctx: Context) { - - import untpd._ - - def scalaDot(name: Name): Select = - Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name) - - def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) - def scalaAnyValConstr = scalaDot(tpnme.AnyVal) - def scalaAnyConstr = scalaDot(tpnme.Any) - def scalaUnitConstr = scalaDot(tpnme.Unit) - def productConstr = scalaDot(tpnme.Product) - def productConstrN(n: Int) = scalaDot(("Product" + n).toTypeName) - def serializableConstr = scalaDot(tpnme.Serializable) - - def convertToTypeName(t: Tree): Tree = ??? - - private implicit val cpos = NoPosition - - /** Convert all occurrences of (lower-case) variables in a pattern as follows: - * x becomes x @ _ - * x: T becomes x @ (_: T) - * Also covert all toplevel lower-case type arguments as follows: - * t becomes t @ _ - */ - private object patvarTransformer extends TreeTransformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(name) if isVarPattern(tree) && name != nme.WILDCARD => - Bind( - name, Ident(nme.WILDCARD).withPos(tree.pos.focus) - ).withSpan(tree.span) - case Typed(id @ Ident(name), tpt) if isVarPattern(id) && name != nme.WILDCARD => - Bind( - name, - Typed( - Ident(nme.WILDCARD).withPos(tree.pos.focus), - transform(tpt) - ).withPos(tree.pos.withStart(tree.pos.point)) - ).withPos(tree.pos.withPoint(id.pos.point)) - case Apply(fn @ Apply(_, _), args) => - tree.derivedApply(transform(fn), transform(args)) - case Apply(fn, args) => - tree.derivedApply(fn, transform(args)) - case Typed(expr, tpt) => - tree.derivedTyped(transform(expr), transform(tpt)) - case Bind(name, body) => - tree.derivedBind(name, transform(body)) - case AppliedTypeTree(tycon, args) => - tree.derivedAppliedTypeTree(tycon, args map transform) - case Alternative(_) | Typed(_, _) | AndTypeTree(_, _) | Annotated(_, _) => - super.transform(tree) - case Parens(_) => - stripParens(tree) - case _ => - tree - } - } - - case class VariableInfo(name: Name, tree: Tree, pos: Position) - - /** Traverse pattern and collect all variable names with their types in buffer - * The variables keep their positions; whereas the pattern is converted to be - * synthetic for all nodes that contain a variable position. - */ - object getVars extends TreeAccumulator[ListBuffer[VariableInfo]] { - - def namePos(tree: Tree, name: Name): Position = - if (name contains '$') tree.pos.focus - else { - val start = tree.pos.start - val end = start + name.decode.length - Position(start, end) - } - - override def apply(buf: ListBuffer[VariableInfo], tree: Tree): ListBuffer[VariableInfo] = { - def seenName(name: Name) = buf exists (_.name == name) - def add(name: Name, t: Tree): ListBuffer[VariableInfo] = - if (seenName(name)) buf else buf += VariableInfo(name, t, namePos(tree, name)) - - tree match { - case Bind(nme.WILDCARD, _) => - foldOver(buf, tree) - case Bind(name, Typed(tree1, tpt)) if !mayBeTypePat(tpt) => - apply(add(name, tpt), tree1) - case Bind(name, tree1) => - apply(add(name, TypeTree()), tree1) - case _ => - foldOver(buf, tree) - } - } - } - - /** Returns list of all pattern variables, possibly with their types, - * without duplicates - */ - private def getVariables(tree: Tree): List[VariableInfo] = - getVars(new ListBuffer[VariableInfo], tree).toList - - def byNameApplication(tpe: Tree): Tree = - AppliedTypeTree(scalaDot(tpnme.BYNAME_PARAM_CLASS), List(tpe)) - def repeatedApplication(tpe: Tree): Tree = - AppliedTypeTree(scalaDot(tpnme.REPEATED_PARAM_CLASS), List(tpe)) - - def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = { - def mkPair(t1: Tree, t2: Tree) = { - if (t1.isType) AppliedTypeTree(scalaDot(tpnme.Pair), List(t1, t2)) - else Pair(t1, t2) - } - trees reduce mkPair - } - - def stripParens(t: Tree) = t match { - case Parens(t) => t - case _ => t - } - - def makeSelfDef(name: TermName, tpt: Tree): ValDef = - ValDef(Modifiers(Private), name, tpt, EmptyTree()) - - /** If tree is a variable pattern, return its variable info. - * Otherwise return none. - */ - private def matchVarPattern(tree: Tree): Option[VariableInfo] = { - def wildType(t: Tree): Option[Tree] = t match { - case Ident(x) if x.toTermName == nme.WILDCARD => Some(TypeTree()) - case Typed(Ident(x), tpt) if x.toTermName == nme.WILDCARD => Some(tpt) - case _ => None - } - tree match { - case Ident(name) => Some(VariableInfo(name, TypeTree(), tree.pos)) - case Bind(name, body) => wildType(body) map (x => VariableInfo(name, x, tree.pos)) - case Typed(id @ Ident(name), tpt) => Some(VariableInfo(name, tpt, id.pos)) - case _ => None - } - } - - /** Create tree representing (unencoded) binary operation expression or pattern. */ - def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = { - def mkNamed(args: List[Tree]) = - if (isExpr) args map { - case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs).withPos(arg.pos) - case arg => arg - } else args - val arguments = right match { - case Parens(arg) => mkNamed(arg :: Nil) - case _ => right :: Nil - } - if (isExpr) { - if (isLeftAssoc(op)) { - Apply(Select(stripParens(left), op.encode).withPos(opPos), arguments) - } else { - val x = ctx.freshName().toTermName - Block( - List(ValDef(Modifiers(Synthetic), x, TypeTree(), stripParens(left))), - Apply(Select(stripParens(right), op.encode).withPos(opPos), List(Ident(x).withPos(left.pos)))) - } - } else { - Apply(Ident(op.encode).withPos(opPos), stripParens(left) :: arguments) - } - } - - /** tpt. */ - def SelectConstructor(tpt: Tree): Tree = - Select(tpt, nme.CONSTRUCTOR) - - private def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match { - case Apply(tree, args) => splitArgss(tree, args :: outerArgss) - case _ => (constr, if (outerArgss.isEmpty) ListOfNil else outerArgss) - } - - /** new tpt(argss_1)...(argss_n) - * @param npos the position spanning , without any arguments - */ - def makeNew(parentConstr: Tree) = { - val (tpt, argss) = splitArgss(parentConstr, Nil) - New(tpt, argss) - } - - /** Create positioned tree representing an object creation stats } - */ - def makeNew(templ: Template): Tree = { - val x = tpnme.ANON_CLASS - val nu = makeNew(Ident(x)) - val clsDef = { - implicit val cpos = NoPosition - ClassDef(Modifiers(Final), x, Nil, templ) - } - Block(clsDef, nu) - } - - /** Create positioned tree representing an object creation stats } - * @param cpos the position of the new, focus should be the first parent's start. - */ - def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree]): Tree = { - val newPos = Position(cpos.start, cpos.point) - val clsPos = Position(cpos.point, cpos.end) - if (parents.isEmpty) - makeNew(List(scalaAnyRefConstr.withPos(newPos.endPos)), self, stats) - else if (parents.tail.isEmpty && stats.isEmpty) - makeNew(parents.head) - else { - val x = tpnme.ANON_CLASS - val nu = makeNew(Ident(x).withPos(newPos)).withPos(newPos) - val clsDef = { - implicit val cpos = clsPos - ClassDef(Modifiers(Final), x, Nil, Template(???, parents, self, stats)) - } - Block(clsDef, nu) - } - } - - /** Create a tree representing an assignment */ - def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match { - case Apply(fn, args) => - Apply(Select(fn, nme.update), args :+ rhs) - case _ => - Assign(lhs, rhs) - } - - /** A type tree corresponding to (possibly unary) intersection type - def makeIntersectionTypeTree(tps: List[Tree]): Tree = - if (tps.tail.isEmpty) tps.head - else CompoundTypeTree(Template(tps, emptyValDef, Nil))*/ - - private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = { - val ldef = DefDef(Modifiers(Label).withPos(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs) - Block(ldef, call) - } - - private def labelCall(lname: TermName): Apply = - Apply(Ident(lname), Nil) - - /** Create tree representing a while loop */ - def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { - val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos) - val rhs = { - implicit val cpos = NoPosition - If(cond, Block(body, continu), Literal(Constant()).withPos(continu.pos)) - } - labelDefAndCall(lname, rhs, continu) - } - - /** Create tree representing a do-while loop */ - def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = { - val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos) - val rhs = Block(body, If(cond, continu, Literal(Constant()).withPos(continu.pos))) - labelDefAndCall(lname, rhs, continu) - } - - /** Create block of statements `stats` */ - def makeBlock(stats: List[Tree]): Tree = - if (stats.isEmpty) Literal(Constant()) - else if (!stats.last.isTerm) Block(stats, Literal(Constant()).withPos(cpos.endPos)) - else if (stats.length == 1) stats.head - else Block(stats.init, stats.last) - - def makePatFilter(tree: Tree, condition: Tree, canDrop: Boolean): Tree = { - val cases = List( - CaseDef(condition, EmptyTree(), Literal(Constant(true))), - CaseDef(Ident(nme.WILDCARD), EmptyTree(), Literal(Constant(false))) - ) - val matchTree = makeVisitor(cases, checkExhaustive = false, canDrop) - locally { - implicit val cpos = tree.pos - Apply(Select(tree, nme.withFilter), matchTree :: Nil) - } - } - - /** Create tree for for-comprehension generator or */ - def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = { - val pat1 = patvarTransformer.transform(pat) - if (valeq) ValEq(pat1, rhs) - else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true)) - } - -/* - def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) = - TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds) -*/ - abstract class Enumerator { def pos: Position } - case class ValFrom(pat: Tree, rhs: Tree) extends Enumerator { - val pos = cpos union pat.pos union rhs.pos - } - case class ValEq(pat: Tree, rhs: Tree) extends Enumerator { - val pos = cpos union pat.pos union rhs.pos - } - case class Filter(test: Tree) extends Enumerator { - val pos = cpos union test.pos - } - - /** Create tree for for-comprehension or - * where mapName and flatMapName are chosen - * corresponding to whether this is a for-do or a for-yield. - * The creation performs the following rewrite rules: - * - * 1. - * - * for (P <- G) E ==> G.foreach (P => E) - * - * Here and in the following (P => E) is interpreted as the function (P => E) - * if P is a variable pattern and as the partial function { case P => E } otherwise. - * - * 2. - * - * for (P <- G) yield E ==> G.map (P => E) - * - * 3. - * - * for (P_1 <- G_1; P_2 <- G_2; ...) ... - * ==> - * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...) - * - * 4. - * - * for (P <- G; E; ...) ... - * => - * for (P <- G.filter (P => E); ...) ... - * - * 5. For any N: - * - * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...) - * ==> - * for (TupleN(P_1, P_2, ... P_N) <- - * for (x_1 @ P_1 <- G) yield { - * val x_2 @ P_2 = E_2 - * ... - * val x_N & P_N = E_N - * TupleN(x_1, ..., x_N) - * } ...) - * - * If any of the P_i are variable patterns, the corresponding `x_i @ P_i' is not generated - * and the variable constituting P_i is used instead of x_i - * - * @param mapName The name to be used for maps (either map or foreach) - * @param flatMapName The name to be used for flatMaps (either flatMap or foreach) - * @param enums The enumerators in the for expression - * @param body The body of the for expression - */ - private def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Enumerator], body: Tree): Tree = { - - /** make a closure pat => body. - * The closure is assigned a transparent position with the point at pos.point and - * the limits given by pat and body. - */ - def makeClosure(pat: Tree, body: Tree): Tree = - matchVarPattern(pat) match { - case Some(VariableInfo(name, tpt, pos)) => - Function(ValDef(Modifiers(Param).withPos(cpos.startPos), name.toTermName, tpt, EmptyTree()).withPos(pos) :: Nil, body) - case None => - makeVisitor(List(CaseDef(pat, EmptyTree(), body)), checkExhaustive = false) - } - - /** Make an application qual.meth(pat => body) positioned at `pos`. - */ - def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree): Tree = - Apply(Select(qual, meth).withPos(NoPosition), makeClosure(pat, body)) - - /** Optionally, if pattern is a `Bind`, the bound name, otherwise None. - */ - def patternVar(pat: Tree): Option[Name] = pat match { - case Bind(name, _) => Some(name) - case _ => None - } - - /** If `pat` is not yet a `Bind` wrap it in one with a fresh name - */ - def makeBind(pat: Tree): Tree = pat match { - case Bind(_, _) => pat - case _ => Bind(ctx.freshName().toTermName, pat) - } - - /** A reference to the name bound in Bind `pat`. - */ - def makeValue(pat: Tree): Tree = pat match { - case Bind(name, _) => Ident(name).withPos(pat.pos.focus) - } - - enums match { - case (enum @ ValFrom(pat, rhs)) :: Nil => - makeCombination(mapName, rhs, pat, body).withPos(enum.pos) - case ValFrom(pat, rhs) :: (rest @ (ValFrom( _, _) :: _)) => - makeCombination(flatMapName, rhs, pat, - makeFor(mapName, flatMapName, rest, body)) - case (enum @ ValFrom(pat, rhs)) :: Filter(test) :: rest => - makeFor(mapName, flatMapName, - ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test)) :: rest, - body) - case (enum @ ValFrom(pat, rhs)) :: rest => - val (valeqs, rest1) = rest.span(_.isInstanceOf[ValEq]) - assert(!valeqs.isEmpty) - val pats = valeqs map { case ValEq(pat, _) => pat } - val rhss = valeqs map { case ValEq(_, rhs) => rhs } - val defpat1 = makeBind(pat) - val defpats = pats map makeBind - val pdefs = (defpats, rhss).zipped flatMap (makePatDef) - val ids = (defpat1 :: defpats) map makeValue - val rhs1 = makeForYield(ValFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids))) - val allpats = pat :: pats - val vfrom1 = ValFrom(makeTuple(allpats), rhs1) - makeFor(mapName, flatMapName, vfrom1 :: rest1, body) - case _ => - EmptyTree() //may happen for erroneous input - } - } - - /** Create tree for for-do comprehension */ - def makeFor(enums: List[Enumerator], body: Tree): Tree = - makeFor(nme.foreach, nme.foreach, enums, body) - - /** Create tree for for-yield comprehension */ - def makeForYield(enums: List[Enumerator], body: Tree): Tree = - makeFor(nme.map, nme.flatMap, enums, body) - - /** Create tree for a pattern alternative */ - def makeAlternative(ts: List[Tree]): Tree = Alternative(ts flatMap alternatives) - - def alternatives(t: Tree): List[Tree] = t match { - case Alternative(ts) => ts - case _ => List(t) - } - - def mkAnnotated(cls: Symbol, tree: Tree) = - Annotated(TypedSplice(tpd.New(cls.typeRef)), tree) - - /** Create visitor x match cases> */ - def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean, canDrop: Boolean = false): Tree = { - val x = ctx.freshName().toTermName - val id = Ident(x) - val sel = - if (canDrop) mkAnnotated(???, id) - else if (!checkExhaustive) mkAnnotated(defn.UncheckedAnnot, id) - else id - Function(List(ugen.syntheticParameter(x)), Match(sel, cases)) - } - - /** Create tree for case definition rhs> */ - def makeCaseDef(pat: Tree, guard: Tree, rhs: Tree): CaseDef = - CaseDef(patvarTransformer.transform(pat), guard, rhs) - - /** Create tree for pattern definition */ - def makePatDef(pat: Tree, rhs: Tree): List[Tree] = - makePatDef(Modifiers(), pat, rhs) - - /** Create tree for pattern definition */ - def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree, varsArePatterns: Boolean = false): List[Tree] = matchVarPattern(pat) match { - case Some(VariableInfo(name, tpt, pos)) if varsArePatterns => - ValDef(mods, name.toTermName, tpt, rhs).withPos(pos) :: Nil // point comes from pat.pos - - case _ => - // in case there is exactly one variable x_1 in pattern - // val/var p = e ==> val/var x_1 = e.match (case p => (x_1)) - // - // in case there are zero or more than one variables in pattern - // val/var p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N)) - // val/var x_1 = t$._1 - // ... - // val/var x_N = t$._N - - val rhsUnchecked = mkAnnotated(defn.UncheckedAnnot, rhs) - - // TODO: clean this up -- there is too much information packed into makePatDef's `pat` argument - // when it's a simple identifier (case Some((name, tpt)) -- above), - // pat should have the type ascription that was specified by the user - // however, in `case None` (here), we must be careful not to generate illegal pattern trees (such as `(a, b): Tuple2[Int, String]`) - // i.e., this must hold: pat1 match { case Typed(expr, tp) => assert(expr.isInstanceOf[Ident]) case _ => } - // if we encounter such an erroneous pattern, we strip off the type ascription from pat and propagate the type information to rhs - val (pat1, rhs1) = patvarTransformer.transform(pat) match { - // move the Typed ascription to the rhs - case Typed(expr, tpt) if !expr.isInstanceOf[Ident] => - val rhsTypedUnchecked = - if (tpt.isEmpty) rhsUnchecked else Typed(rhsUnchecked, tpt) - (expr, rhsTypedUnchecked) - case ok => - (ok, rhsUnchecked) - } - val vars = getVariables(pat1) - val ids = vars map (v => Ident(v.name).withPos(v.pos)) - val caseDef = CaseDef(pat1, EmptyTree(), makeTuple(ids)) - val matchExpr = Match(rhs1, caseDef :: Nil) - vars match { - case List(VariableInfo(vname, tpt, pos)) => - ValDef(mods, vname.toTermName, tpt, matchExpr) :: Nil - case _ => - val tmpName = ctx.freshName().toTermName - val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy)) - val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr) - val restDefs = for { - (VariableInfo(vname, tpt, pos), n) <- vars.zipWithIndex - } yield { - val rhs = { - implicit val cpos = pos.focus - Select(Ident(tmpName), ("_" + n).toTermName) - } - ValDef(mods, vname.toTermName, tpt, rhs).withPos(pos) - } - firstDef :: restDefs - } - } - - /** Create a tree representing the function type (argtpes) => restpe */ - def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree = - AppliedTypeTree(scalaDot(("Function" + argtpes.length).toTypeName), argtpes ::: List(restpe)) - - /** Append implicit parameter section if `contextBounds` nonempty */ - def addEvidenceParams(owner: Name, vparamss: List[List[ValDef]], contextBounds: List[Tree]): List[List[ValDef]] = { - if (contextBounds.isEmpty) vparamss - else { - val mods = Modifiers(if (owner.isTypeName) PrivateLocal | ParamAccessor else Param) - val evidenceParams = for (tpt <- contextBounds) yield { - val pname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName - ValDef(mods | Implicit | Synthetic, pname, tpt, EmptyTree()) - } - vparamss.reverse match { - case (vparams @ (vparam :: _)) :: _ if vparam.mods is Implicit => - vparamss.init :+ (evidenceParams ++ vparams) - case _ => - vparamss :+ evidenceParams - } - } - } -} diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index ca97ba0f0eef..082b737c8d81 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -423,14 +423,15 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { typeText(toText(tree.typeOpt)) case SingletonTypeTree(ref) => toTextLocal(ref) ~ "." ~ keywordStr("type") - case AndTypeTree(l, r) => - changePrec(AndTypePrec) { toText(l) ~ " & " ~ atPrec(AndTypePrec + 1) { toText(r) } } - case OrTypeTree(l, r) => - changePrec(OrTypePrec) { toText(l) ~ " | " ~ atPrec(OrTypePrec + 1) { toText(r) } } case RefinedTypeTree(tpt, refines) => toTextLocal(tpt) ~ " " ~ blockText(refines) case AppliedTypeTree(tpt, args) => - toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]" + if (tpt.symbol == defn.orType && args.length == 2) + changePrec(OrTypePrec) { toText(args(0)) ~ " | " ~ atPrec(OrTypePrec + 1) { toText(args(1)) } } + else if (tpt.symbol == defn.andType && args.length == 2) + changePrec(AndTypePrec) { toText(args(0)) ~ " & " ~ atPrec(AndTypePrec + 1) { toText(args(1)) } } + else + toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]" case LambdaTypeTree(tparams, body) => changePrec(GlobalPrec) { tparamsText(tparams) ~ " -> " ~ toText(body) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala index 0682c5c5bbfe..b9d37c1e3647 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/CoreImpl.scala @@ -73,8 +73,6 @@ trait CoreImpl extends scala.tasty.reflect.Core { type Refined = tpd.RefinedTypeTree type Applied = tpd.AppliedTypeTree type Annotated = tpd.Annotated - type And = tpd.AndTypeTree - type Or = tpd.OrTypeTree type MatchType = tpd.MatchTypeTree type ByName = tpd.ByNameTypeTree type LambdaTypeTree = tpd.LambdaTypeTree diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsTreesOpsImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsTreesOpsImpl.scala index 34f7d45e7169..7541f6d820be 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsTreesOpsImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsTreesOpsImpl.scala @@ -50,16 +50,6 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w def annotation(implicit ctx: Contexts.Context): Term = x.annot } - def AndDeco(x: TypeTree.And): TypeTree.OrAPI = new TypeTree.OrAPI { - def left(implicit ctx: Contexts.Context): TypeTree = x.left - def right(implicit ctx: Contexts.Context): TypeTree = x.right - } - - def OrDeco(x: TypeTree.Or): TypeTree.OrAPI = new TypeTree.OrAPI { - def left(implicit ctx: Contexts.Context): TypeTree = x.left - def right(implicit ctx: Contexts.Context): TypeTree = x.right - } - def MatchTypeTreeDeco(x: TypeTree.MatchType): TypeTree.MatchTypeAPI = new TypeTree.MatchTypeAPI { def bound(implicit ctx: Contexts.Context): Option[TypeTree] = if (x.bound == tpd.EmptyTree) None else Some(x.bound) def selector(implicit ctx: Contexts.Context): TypeTree = x.selector @@ -253,46 +243,6 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w } } - object IsAnd extends IsAndModule { - def unapply(tpt: TypeOrBoundsTree)(implicit ctx: Context): Option[And] = tpt match { - case tpt: tpd.AndTypeTree => Some(tpt) - case _ => None - } - } - - object And extends AndModule { - def apply(left: TypeTree, right: TypeTree)(implicit ctx: Context): And = - withDefaultPos(ctx => tpd.AndTypeTree(left, right)(ctx)) - - def copy(original: And)(left: TypeTree, right: TypeTree)(implicit ctx: Context): And = - tpd.cpy.AndTypeTree(original)(left, right) - - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.AndTypeTree => Some(x.left, x.right) - case _ => None - } - } - - object IsOr extends IsOrModule { - def unapply(tpt: TypeOrBoundsTree)(implicit ctx: Context): Option[Or] = tpt match { - case tpt: tpd.OrTypeTree => Some(tpt) - case _ => None - } - } - - object Or extends OrModule { - def apply(left: TypeTree, right: TypeTree)(implicit ctx: Context): Or = - withDefaultPos(ctx => tpd.OrTypeTree(left, right)(ctx)) - - def copy(original: Or)(left: TypeTree, right: TypeTree)(implicit ctx: Context): Or = - tpd.cpy.OrTypeTree(original)(left, right) - - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.OrTypeTree => Some(x.left, x.right) - case _ => None - } - } - object IsMatchType extends IsMatchTypeModule { def unapply(tpt: TypeOrBoundsTree)(implicit ctx: Context): Option[MatchType] = tpt match { case tpt: tpd.MatchTypeTree => Some(tpt) diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index aa8b003795e7..5a21cf20c59f 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -280,7 +280,14 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase case tree @ Annotated(annotated, annot) => cpy.Annotated(tree)(transform(annotated), transformAnnot(annot)) case tree: AppliedTypeTree => - Checking.checkAppliedType(tree, boundsCheck = !ctx.mode.is(Mode.Pattern)) + if (tree.tpt.symbol == defn.andType) + Checking.checkNonCyclicInherited(tree.tpe, tree.args.tpes, EmptyScope, tree.posd) + // Ideally, this should be done by Typer, but we run into cyclic references + // when trying to typecheck self types which are intersections. + else if (tree.tpt.symbol == defn.orType) + () // nothing to do + else + Checking.checkAppliedType(tree, boundsCheck = !ctx.mode.is(Mode.Pattern)) super.transform(tree) case SingletonTypeTree(ref) => Checking.checkRealizable(ref.tpe, ref.posd) @@ -292,11 +299,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase case tpe => tpe } ) - case tree: AndTypeTree => - // Ideally, this should be done by Typer, but we run into cyclic references - // when trying to typecheck self types which are intersections. - Checking.checkNonCyclicInherited(tree.tpe, tree.left.tpe :: tree.right.tpe :: Nil, EmptyScope, tree.posd) - super.transform(tree) case tree: LambdaTypeTree => VarianceChecker.checkLambda(tree) super.transform(tree) diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 0ec7aa5217e5..e4d71a68488a 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -233,8 +233,6 @@ class TreeChecker extends Phase with SymTransformer { elems.foreach(assertIdentNotJavaClass) // case tree: TypeTree => // case tree: SingletonTypeTree => - // case tree: AndTypeTree => - // case tree: OrTypeTree => // case tree: RefinedTypeTree => // case tree: AppliedTypeTree => // case tree: ByNameTypeTree => diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 226d40b6f875..904c2fe4190f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -92,6 +92,11 @@ object Checking { checkValidIfApply(ctx.addMode(Mode.AllowLambdaWildcardApply)) } + def checkNoWildcard(tree: Tree)(implicit ctx: Context): Tree = tree.tpe match { + case tpe: TypeBounds => errorTree(tree, "no wildcard type allowed here") + case _ => tree + } + /** Check that kind of `arg` has the same outline as the kind of paramBounds. * E.g. if `paramBounds` has kind * -> *, `arg` must have that kind as well, * and analogously for all other kinds. This kind checking does not take into account diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index c04ac8e97af7..f171440b73bd 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -13,7 +13,7 @@ import ast.Trees._ import NameOps._ import collection.mutable import reporting.diagnostic.messages._ -import Checking.checkNoPrivateLeaks +import Checking.{checkNoPrivateLeaks, checkNoWildcard} trait TypeAssigner { import tpd._ @@ -518,12 +518,6 @@ trait TypeAssigner { def assignType(tree: untpd.SingletonTypeTree, ref: Tree)(implicit ctx: Context): SingletonTypeTree = tree.withType(ref.tpe) - def assignType(tree: untpd.AndTypeTree, left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = - tree.withType(AndType(left.tpe, right.tpe)) - - def assignType(tree: untpd.OrTypeTree, left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = - tree.withType(OrType(left.tpe, right.tpe)) - /** Assign type of RefinedType. * Refinements are typed as if they were members of refinement class `refineCls`. */ @@ -543,7 +537,11 @@ trait TypeAssigner { assert(!hasNamedArg(args)) val tparams = tycon.tpe.typeParams val ownType = - if (sameLength(tparams, args)) tycon.tpe.appliedTo(args.tpes) + if (sameLength(tparams, args)) { + if (tycon.symbol == defn.andType) AndType(args(0).tpe, args(1).tpe) + else if (tycon.symbol == defn.orType) OrType(args(0).tpe, args(1).tpe) + else tycon.tpe.appliedTo(args.tpes) + } else wrongNumberOfTypeArgs(tycon.tpe, tparams, args, tree.sourcePos) tree.withType(ownType) } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index fd6df929d16f..f7854d671c3e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1273,19 +1273,6 @@ class Typer extends Namer assignType(cpy.SingletonTypeTree(tree)(ref1), ref1) } - def typedAndTypeTree(tree: untpd.AndTypeTree)(implicit ctx: Context): AndTypeTree = track("typedAndTypeTree") { - val left1 = checkSimpleKinded(typed(tree.left)) - val right1 = checkSimpleKinded(typed(tree.right)) - assignType(cpy.AndTypeTree(tree)(left1, right1), left1, right1) - } - - def typedOrTypeTree(tree: untpd.OrTypeTree)(implicit ctx: Context): OrTypeTree = track("typedOrTypeTree") { - val where = "in a union type" - val left1 = checkNotSingleton(checkSimpleKinded(typed(tree.left)), where) - val right1 = checkNotSingleton(checkSimpleKinded(typed(tree.right)), where) - assignType(cpy.OrTypeTree(tree)(left1, right1), left1, right1) - } - def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = track("typedRefinedTypeTree") { val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt) val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements).withSpan(tree.span) @@ -1365,9 +1352,15 @@ class Typer extends Namer case (tparam, _) => tparam.paramInfo.bounds } - val args2 = preCheckKinds(args1, paramBounds) - // check that arguments conform to bounds is done in phase PostTyper - assignType(cpy.AppliedTypeTree(tree)(tpt1, args2), tpt1, args2) + var checkedArgs = preCheckKinds(args1, paramBounds) + // check that arguments conform to bounds is done in phase PostTyper + if (tpt1.symbol == defn.andType) + checkedArgs = checkedArgs.mapconserve(arg => + checkSimpleKinded(checkNoWildcard(arg))) + else if (tpt1.symbol == defn.orType) + checkedArgs = checkedArgs.mapconserve(arg => + checkNotSingleton(checkSimpleKinded(checkNoWildcard(arg)), "in a union type")) + assignType(cpy.AppliedTypeTree(tree)(tpt1, checkedArgs), tpt1, checkedArgs) } } @@ -2004,8 +1997,6 @@ class Typer extends Namer case tree: untpd.Inlined => typedInlined(tree, pt) case tree: untpd.TypeTree => typedTypeTree(tree, pt) case tree: untpd.SingletonTypeTree => typedSingletonTypeTree(tree) - case tree: untpd.AndTypeTree => typedAndTypeTree(tree) - case tree: untpd.OrTypeTree => typedOrTypeTree(tree) case tree: untpd.RefinedTypeTree => typedRefinedTypeTree(tree) case tree: untpd.AppliedTypeTree => typedAppliedTypeTree(tree) case tree: untpd.LambdaTypeTree => typedLambdaTypeTree(tree)(ctx.localContext(tree, NoSymbol).setNewScope) diff --git a/compiler/test/dotty/tools/dotc/printing/SyntaxHighlightingTests.scala b/compiler/test/dotty/tools/dotc/printing/SyntaxHighlightingTests.scala index 8bff254e663d..b60415205bba 100644 --- a/compiler/test/dotty/tools/dotc/printing/SyntaxHighlightingTests.scala +++ b/compiler/test/dotty/tools/dotc/printing/SyntaxHighlightingTests.scala @@ -39,8 +39,8 @@ class SyntaxHighlightingTests extends DottyTest { test("type Foo", " ") test("type Foo =", " =") test("type Foo = Int", " = ") - test("type A = String | Int", " = ") - test("type B = String & Int", " = ") + test("type A = String | Int", " = ") + test("type B = String & Int", " = ") } @Test diff --git a/docs/docs/reference/other-new-features/tasty-reflect.md b/docs/docs/reference/other-new-features/tasty-reflect.md index f2628371a541..1f85e824199f 100644 --- a/docs/docs/reference/other-new-features/tasty-reflect.md +++ b/docs/docs/reference/other-new-features/tasty-reflect.md @@ -124,8 +124,6 @@ TASTy Reflect provides the following types: +- TypeOrBoundsTree ---+ +- Refined | +- Applied | +- Annotated - | +- And - | +- Or | +- MatchType | +- ByName | +- LambdaTypeTree diff --git a/library/src/scala/tasty/reflect/Core.scala b/library/src/scala/tasty/reflect/Core.scala index c77e306144f5..c86a1e0447f6 100644 --- a/library/src/scala/tasty/reflect/Core.scala +++ b/library/src/scala/tasty/reflect/Core.scala @@ -45,8 +45,6 @@ package scala.tasty.reflect * +- TypeOrBoundsTree ---+ +- Refined * | +- Applied * | +- Annotated - * | +- And - * | +- Or * | +- MatchType * | +- ByName * | +- LambdaTypeTree @@ -295,12 +293,6 @@ trait Core { /** Type tree representing an annotated type */ type Annotated <: TypeTree - /** Type tree representing an intersection type */ - type And <: TypeTree - - /** Type tree representing a union type */ - type Or <: TypeTree - /** Type tree representing a type match */ type MatchType <: TypeTree diff --git a/library/src/scala/tasty/reflect/Printers.scala b/library/src/scala/tasty/reflect/Printers.scala index e24b5c0acc5a..ce3128c8b07b 100644 --- a/library/src/scala/tasty/reflect/Printers.scala +++ b/library/src/scala/tasty/reflect/Printers.scala @@ -217,10 +217,6 @@ trait Printers this += "TypeTree.Projection(" += qualifier += ", \"" += name += "\")" case TypeTree.Singleton(ref) => this += "TypeTree.Singleton(" += ref += ")" - case TypeTree.And(left, right) => - this += "TypeTree.And(" += left += ", " += right += ")" - case TypeTree.Or(left, right) => - this += "TypeTree.Or(" += left += ", " += right += ")" case TypeTree.Refined(tpt, refinements) => this += "TypeTree.Refined(" += tpt += ", " ++= refinements += ")" case TypeTree.Applied(tpt, args) => @@ -1419,16 +1415,6 @@ trait Printers printAnnotation(annot) } - case TypeTree.And(left, right) => - printTypeTree(left) - this += highlightTypeDef(" & ", color) - printTypeTree(right) - - case TypeTree.Or(left, right) => - printTypeTree(left) - this += highlightTypeDef(" | ", color) - printTypeTree(right) - case TypeTree.MatchType(bound, selector, cases) => printTypeTree(selector) this += highlightKeyword(" match ", color) diff --git a/library/src/scala/tasty/reflect/TreeUtils.scala b/library/src/scala/tasty/reflect/TreeUtils.scala index 36c0b5e2ca60..3463c8da8d51 100644 --- a/library/src/scala/tasty/reflect/TreeUtils.scala +++ b/library/src/scala/tasty/reflect/TreeUtils.scala @@ -93,8 +93,6 @@ trait TreeUtils case TypeTree.Select(qualifier, _) => foldTree(x, qualifier) case TypeTree.Projection(qualifier, _) => foldTypeTree(x, qualifier) case TypeTree.Singleton(ref) => foldTree(x, ref) - case TypeTree.And(left, right) => foldTypeTree(foldTypeTree(x, left), right) - case TypeTree.Or(left, right) => foldTypeTree(foldTypeTree(x, left), right) case TypeTree.Refined(tpt, refinements) => foldTrees(foldTypeTree(x, tpt), refinements) case TypeTree.Applied(tpt, args) => foldTypeTrees(foldTypeTree(x, tpt), args) case TypeTree.ByName(result) => foldTypeTree(x, result) @@ -254,10 +252,6 @@ trait TreeUtils TypeTree.Refined.copy(tree)(transformTypeTree(tree.tpt), transformTrees(tree.refinements).asInstanceOf[List[Definition]]) case TypeTree.IsApplied(tree) => TypeTree.Applied.copy(tree)(transformTypeTree(tree.tpt), transformTypeOrBoundsTrees(tree.args)) - case TypeTree.IsAnd(tree) => - TypeTree.And.copy(tree)(transformTypeTree(tree.left), transformTypeTree(tree.right)) - case TypeTree.IsOr(tree) => - TypeTree.Or.copy(tree)(transformTypeTree(tree.left), transformTypeTree(tree.right)) case TypeTree.IsMatchType(tree) => TypeTree.MatchType.copy(tree)(tree.bound.map(b => transformTypeTree(b)), transformTypeTree(tree.selector), transformTypeCaseDefs(tree.cases)) case TypeTree.IsByName(tree) => diff --git a/library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala b/library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala index 2d69c48a8929..35a1d8125080 100644 --- a/library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala +++ b/library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala @@ -14,8 +14,6 @@ trait TypeOrBoundsTreeOps extends Core { implicit def RefinedDeco(x: TypeTree.Refined): TypeTree.RefinedAPI implicit def AppliedDeco(x: TypeTree.Applied): TypeTree.AppliedAPI implicit def AnnotatedDeco(x: TypeTree.Annotated): TypeTree.AnnotatedAPI - implicit def AndDeco(x: TypeTree.And): TypeTree.OrAPI - implicit def OrDeco(x: TypeTree.Or): TypeTree.OrAPI implicit def MatchTypeTreeDeco(x: TypeTree.MatchType): TypeTree.MatchTypeAPI implicit def ByNameDeco(x: TypeTree.ByName): TypeTree.ByNameAPI implicit def LambdaTypeTreeDeco(x: TypeTree.LambdaTypeTree): TypeTree.LambdaTypeTreeAPI @@ -190,42 +188,6 @@ trait TypeOrBoundsTreeOps extends Core { def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, Term)] } - val IsAnd: IsAndModule - abstract class IsAndModule { - /** Matches any And and returns it */ - def unapply(tpt: TypeOrBoundsTree)(implicit ctx: Context): Option[And] - } - - trait AndAPI { - def left(implicit ctx: Context): TypeTree - def right(implicit ctx: Context): TypeTree - } - - val And: AndModule - abstract class AndModule { - def apply(left: TypeTree, right: TypeTree)(implicit ctx: Context): And - def copy(original: And)(left: TypeTree, right: TypeTree)(implicit ctx: Context): And - def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] - } - - val IsOr: IsOrModule - abstract class IsOrModule { - /** Matches any Or and returns it */ - def unapply(tpt: TypeOrBoundsTree)(implicit ctx: Context): Option[Or] - } - - trait OrAPI { - def left(implicit ctx: Context): TypeTree - def right(implicit ctx: Context): TypeTree - } - - val Or: OrModule - abstract class OrModule { - def apply(left: TypeTree, right: TypeTree)(implicit ctx: Context): Or - def copy(original: Or)(left: TypeTree, right: TypeTree)(implicit ctx: Context): Or - def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] - } - val IsMatchType: IsMatchTypeModule abstract class IsMatchTypeModule { /** Matches any MatchType and returns it */ diff --git a/tests/neg/and-wildcard.scala b/tests/neg/and-wildcard.scala new file mode 100644 index 000000000000..c4cf7baaa10f --- /dev/null +++ b/tests/neg/and-wildcard.scala @@ -0,0 +1,6 @@ +object Test { + + type And[X, Y] = X & Y + + val x: And[_, _] = ??? // error: unreducible +} \ No newline at end of file diff --git a/tests/neg/i4373.scala b/tests/neg/i4373.scala index 6ba7c81a617a..84b6a71666b2 100644 --- a/tests/neg/i4373.scala +++ b/tests/neg/i4373.scala @@ -41,8 +41,8 @@ object Test { type T19 = (_ with Int) @ annotation.tailrec // error type T20 = (Int with _) @ annotation.tailrec // error - type T21 = Int @ (_ with annotation.tailrec) // error // error - type T22 = Int @ (annotation.tailrec with _) // error // error + type T21 = Int @ (_ with annotation.tailrec) // error + type T22 = Int @ (annotation.tailrec with _) // error type T23 = (_ & Int) @ annotation.tailrec // error type T24 = (Int & _) @ annotation.tailrec // error diff --git a/tests/neg/patvars.scala b/tests/neg/patvars.scala new file mode 100644 index 000000000000..f0e2cd3da4ae --- /dev/null +++ b/tests/neg/patvars.scala @@ -0,0 +1,12 @@ +object Test { + + (??? : Any) match { + + case x1 | y1 => ??? // error // error + + case _: List[t2] | y2 => ??? // error // error + + case x3: Int | y3: String => ??? // error // error + + } +} \ No newline at end of file diff --git a/tests/pending/pos/i4987.scala b/tests/pending/pos/i4987.scala new file mode 100644 index 000000000000..e251c4091697 --- /dev/null +++ b/tests/pending/pos/i4987.scala @@ -0,0 +1,18 @@ +object Foo { + + class Expr[T] + + abstract class Liftable[T] { + def toExpr(x: T): Expr[T] + } + + implicit class LiftExprOps[T](val x: T) extends AnyVal { + def toExpr(implicit ev: Liftable[T]): Expr[T] = ev.toExpr(x) + } + + implicit def NilIsLiftable: Liftable[Nil.type] = ??? + + Nil.toExpr(NilIsLiftable) + (Nil.toExpr: Expr[Nil.type]) + Nil.toExpr +} \ No newline at end of file diff --git a/tests/pos/gadt-GadtStlc.scala b/tests/pos/gadt-GadtStlc.scala index 32e6f5630d6b..e51c5f61bf90 100644 --- a/tests/pos/gadt-GadtStlc.scala +++ b/tests/pos/gadt-GadtStlc.scala @@ -119,7 +119,7 @@ object GadtStlc { case Left(isv1) => progress(dapp.d2) match { case Right(r2) => Right(EApp2(isv1, r2)) case Left(isv2) => followsIsLambda(isv1, dapp.d1) match { - case _: ISLAMBDAC[x, e] => Right(EAppAbs[x, e, b, _](isv2)) + case _: ISLAMBDAC[x, e] => Right(EAppAbs[X = x, E = e, V2 = b](isv2)) } } } diff --git a/tests/run-with-compiler-custom-args/staged-streams_1.scala b/tests/run-with-compiler-custom-args/staged-streams_1.scala index 101433ddf317..775b2856541d 100644 --- a/tests/run-with-compiler-custom-args/staged-streams_1.scala +++ b/tests/run-with-compiler-custom-args/staged-streams_1.scala @@ -358,10 +358,10 @@ object Test { Linear(zip_producer(producer1, producer2)) case (Linear(producer1), Nested(producer2, nestf2)) => - pushLinear[Expr[A], _, B](producer1, producer2, nestf2) + pushLinear[A = Expr[A], C = B](producer1, producer2, nestf2) case (Nested(producer1, nestf1), Linear(producer2)) => - mapRaw[(B, Expr[A]), (Expr[A], B)]((t => k => '{ ~k((t._2, t._1)) }), pushLinear[B, _, Expr[A]](producer2, producer1, nestf1)) + mapRaw[(B, Expr[A]), (Expr[A], B)]((t => k => '{ ~k((t._2, t._1)) }), pushLinear[A = B, C = Expr[A]](producer2, producer1, nestf1)) case (Nested(producer1, nestf1), Nested(producer2, nestf2)) => zipRaw[A, B](Linear(makeLinear(stream1)), stream2) diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index 68b0372d7d9e..2f98f387de8a 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -16,10 +16,10 @@ Type.SymRef(IsClassSymbol(), Type.SymRef(IsPackageSymbol(), Ty Term.Inlined(None, Nil, Term.Typed(Term.Ident("Nil"), TypeTree.Applied(TypeTree.Ident("List"), List(TypeTree.Ident("Int"))))) Type.AppliedType(Type.SymRef(IsClassSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(), NoPrefix()))), List(Type.SymRef(IsClassSymbol(), Type.SymRef(IsPackageSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(<>), NoPrefix())))))) -Term.Inlined(None, Nil, Term.Typed(Term.Apply(Term.Select(Term.New(TypeTree.Ident("Baz")), ""), Nil), TypeTree.And(TypeTree.Ident("Foo"), TypeTree.Ident("Bar")))) +Term.Inlined(None, Nil, Term.Typed(Term.Apply(Term.Select(Term.New(TypeTree.Ident("Baz")), ""), Nil), TypeTree.Applied(TypeTree.Ident("&"), List(TypeTree.Ident("Foo"), TypeTree.Ident("Bar"))))) Type.AndType(Type.SymRef(IsClassSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(<>), NoPrefix()))), Type.SymRef(IsClassSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(<>), NoPrefix())))) -Term.Inlined(None, Nil, Term.Typed(Term.Literal(Constant.Int(1)), TypeTree.Or(TypeTree.Ident("Int"), TypeTree.Ident("String")))) +Term.Inlined(None, Nil, Term.Typed(Term.Literal(Constant.Int(1)), TypeTree.Applied(TypeTree.Ident("|"), List(TypeTree.Ident("Int"), TypeTree.Ident("String"))))) Type.OrType(Type.SymRef(IsClassSymbol(), Type.SymRef(IsPackageSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(<>), NoPrefix())))), Type.SymRef(IsTypeSymbol(), Type.SymRef(IsValSymbol(), Type.ThisType(Type.SymRef(IsPackageSymbol(), NoPrefix()))))) Term.Inlined(None, Nil, Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), TypeTree.Inferred(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Inferred()), ""), Nil)), Nil, None, Nil)), Term.Literal(Constant.Unit())))