diff --git a/compiler/src/dotty/tools/dotc/CompilationUnit.scala b/compiler/src/dotty/tools/dotc/CompilationUnit.scala index c275fb25ca66..00527db565a8 100644 --- a/compiler/src/dotty/tools/dotc/CompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/CompilationUnit.scala @@ -3,14 +3,12 @@ package dotc import util.SourceFile import ast.{tpd, untpd} -import dotty.tools.dotc.ast.Trees import tpd.{Tree, TreeTraverser} import typer.PrepareInlineable.InlineAccessors import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.SymDenotations.ClassDenotation import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.SymUtils._ -import dotty.tools.dotc.typer.Inliner class CompilationUnit(val source: SourceFile) { @@ -25,8 +23,8 @@ class CompilationUnit(val source: SourceFile) { /** Pickled TASTY binaries, indexed by class. */ var pickled: Map[ClassSymbol, Array[Byte]] = Map() - /** Will be set to `true` if contains `Quote`, `Splice` or calls to inline methods. - * The information is used in phase `Staging` in order to avoid traversing a quote-less tree. + /** Will be set to `true` if contains `Quote`. + * The information is used in phase `Staging` in order to avoid traversing trees that need no transformations. */ var needsStaging: Boolean = false @@ -57,8 +55,7 @@ object CompilationUnit { private class Force extends TreeTraverser { var needsStaging = false def traverse(tree: Tree)(implicit ctx: Context): Unit = { - // Note that top-level splices are still inside the inline methods - if (tree.symbol.isQuote || tpd.isInlineCall(tree)) + if (tree.symbol.isQuote) needsStaging = true traverseChildren(tree) } diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index 60a05d2d26c9..461b684e0bf4 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -44,7 +44,7 @@ class Compiler { /** Phases dealing with TASTY tree pickling and unpickling */ protected def picklerPhases: List[List[Phase]] = List(new Pickler) :: // Generate TASTY info - List(new Staging) :: // Inline calls, expand macros and turn quoted trees into explicit run-time data structures + List(new Staging) :: // Turn quoted trees into explicit run-time data structures Nil /** Phases dealing with the transformation from pickled trees to backend trees */ diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index 5daee6fc9b46..01f8d21259db 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -5,7 +5,7 @@ package ast import core._ import Flags._, Trees._, Types._, Contexts._ import Names._, StdNames._, NameOps._, Symbols._ -import typer.{ConstFold, Inliner} +import typer.ConstFold import reporting.trace import scala.annotation.tailrec @@ -770,14 +770,6 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => false } - /** Is this call a call to a method that is marked as Inline */ - def isInlineCall(arg: Tree)(implicit ctx: Context): Boolean = arg match { - case _: RefTree | _: GenericApply[_] => - !arg.tpe.widenDealias.isInstanceOf[MethodicType] && Inliner.isInlineable(arg) - case _ => - false - } - /** Structural tree comparison (since == on trees is reference equality). * For the moment, only Ident, Select, Literal, Apply and TypeApply are supported */ diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 10b5e93723bf..8206e8dcd763 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -585,8 +585,9 @@ object Trees { /** A tree representing inlined code. * - * @param call Info about the original call that was inlined. - * Only a reference to the toplevel class from which the call was inlined. + * @param call Info about the original call that was inlined + * Until PostTyper, this is the full call, afterwards only + * a reference to the toplevel class from which the call was inlined. * @param bindings Bindings for proxies to be used in the inlined code * @param expansion The inlined tree, minus bindings. * diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index 741176aad85f..b59a7fb02ecf 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -86,6 +86,7 @@ Standard-Section: "ASTs" TopLevelStat* TYPED Length expr_Term ascriptionType_Tern ASSIGN Length lhs_Term rhs_Term BLOCK Length expr_Term Stat* + INLINED Length expr_Term call_Term? ValOrDefDef* LAMBDA Length meth_Term target_Type? IF Length cond_Term then_Term else_Term MATCH Length sel_Term CaseDef* @@ -184,6 +185,7 @@ Standard-Section: "ASTs" TopLevelStat* OVERRIDE INLINE MACRO // inline method containing toplevel splices + INLINEPROXY // symbol of binding representing an inline parameter STATIC // mapped to static Java member OBJECT // an object or its class TRAIT // a trait @@ -234,7 +236,7 @@ Standard Section: "Comments" Comment* object TastyFormat { final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F) - val MajorVersion: Int = 12 + val MajorVersion: Int = 11 val MinorVersion: Int = 0 /** Tags used to serialize names */ @@ -287,26 +289,27 @@ object TastyFormat { final val IMPLICIT = 13 final val LAZY = 14 final val OVERRIDE = 15 - final val INLINE = 16 - final val STATIC = 17 - final val OBJECT = 18 - final val TRAIT = 19 - final val ENUM = 20 - final val LOCAL = 21 - final val SYNTHETIC = 22 - final val ARTIFACT = 23 - final val MUTABLE = 24 - final val LABEL = 25 - final val FIELDaccessor = 26 - final val CASEaccessor = 27 - final val COVARIANT = 28 - final val CONTRAVARIANT = 29 - final val SCALA2X = 30 - final val DEFAULTparameterized = 31 - final val STABLE = 32 - final val MACRO = 33 - final val ERASED = 34 - final val PARAMsetter = 35 + final val INLINEPROXY = 16 + final val INLINE = 17 + final val STATIC = 18 + final val OBJECT = 19 + final val TRAIT = 20 + final val ENUM = 21 + final val LOCAL = 22 + final val SYNTHETIC = 23 + final val ARTIFACT = 24 + final val MUTABLE = 25 + final val LABEL = 26 + final val FIELDaccessor = 27 + final val CASEaccessor = 28 + final val COVARIANT = 29 + final val CONTRAVARIANT = 30 + final val SCALA2X = 31 + final val DEFAULTparameterized = 32 + final val STABLE = 33 + final val MACRO = 34 + final val ERASED = 35 + final val PARAMsetter = 36 // Cat. 2: tag Nat @@ -380,35 +383,36 @@ object TastyFormat { final val RETURN = 144 final val WHILE = 145 final val TRY = 146 - final val SELECTouter = 147 - final val REPEATED = 148 - final val BIND = 149 - final val ALTERNATIVE = 150 - final val UNAPPLY = 151 - final val ANNOTATEDtype = 152 - final val ANNOTATEDtpt = 153 - final val CASEDEF = 154 - final val TEMPLATE = 155 - final val SUPER = 156 - final val SUPERtype = 157 - final val REFINEDtype = 158 - final val REFINEDtpt = 159 - final val APPLIEDtype = 160 - final val APPLIEDtpt = 161 - final val TYPEBOUNDS = 162 - final val TYPEBOUNDStpt = 163 - final val ANDtype = 164 - final val ANDtpt = 165 - final val ORtype = 166 - final val ORtpt = 167 - final val POLYtype = 168 - final val TYPELAMBDAtype = 169 - final val LAMBDAtpt = 170 - final val PARAMtype = 171 - final val ANNOTATION = 172 - final val TERMREFin = 173 - final val TYPEREFin = 174 - final val OBJECTDEF = 175 + final val INLINED = 147 + final val SELECTouter = 148 + final val REPEATED = 149 + final val BIND = 150 + final val ALTERNATIVE = 151 + final val UNAPPLY = 152 + final val ANNOTATEDtype = 153 + final val ANNOTATEDtpt = 154 + final val CASEDEF = 155 + final val TEMPLATE = 156 + final val SUPER = 157 + final val SUPERtype = 158 + final val REFINEDtype = 159 + final val REFINEDtpt = 160 + final val APPLIEDtype = 161 + final val APPLIEDtpt = 162 + 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 + final val PARAMtype = 172 + final val ANNOTATION = 173 + final val TERMREFin = 174 + final val TYPEREFin = 175 + final val OBJECTDEF = 176 // In binary: 101101EI // I = implicit method type @@ -458,6 +462,7 @@ object TastyFormat { | LAZY | OVERRIDE | INLINE + | INLINEPROXY | MACRO | STATIC | OBJECT @@ -515,6 +520,7 @@ object TastyFormat { case LAZY => "LAZY" case OVERRIDE => "OVERRIDE" case INLINE => "INLINE" + case INLINEPROXY => "INLINEPROXY" case MACRO => "MACRO" case STATIC => "STATIC" case OBJECT => "OBJECT" @@ -583,6 +589,7 @@ object TastyFormat { case MATCH => "MATCH" case RETURN => "RETURN" case WHILE => "WHILE" + case INLINED => "INLINED" case SELECTouter => "SELECTouter" case TRY => "TRY" case REPEATED => "REPEATED" diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 5a4cbc312076..a67197786cd2 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -442,6 +442,17 @@ class TreePickler(pickler: TastyPickler) { case SeqLiteral(elems, elemtpt) => writeByte(REPEATED) withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } + case Inlined(call, bindings, expansion) => + writeByte(INLINED) + bindings.foreach(preRegister) + withLength { + pickleTree(expansion) + if (!call.isEmpty) pickleTree(call) + bindings.foreach { b => + assert(b.isInstanceOf[DefDef] || b.isInstanceOf[ValDef]) + pickleTree(b) + } + } case Bind(name, body) => registerDef(tree.symbol) writeByte(BIND) @@ -608,6 +619,7 @@ class TreePickler(pickler: TastyPickler) { if (flags is Case) writeByte(CASE) if (flags is Override) writeByte(OVERRIDE) if (flags is Inline) writeByte(INLINE) + if (flags is InlineProxy) writeByte(INLINEPROXY) if (flags is Macro) writeByte(MACRO) if (flags is JavaStatic) writeByte(STATIC) if (flags is Module) writeByte(OBJECT) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index fcabd7184550..f1cd996f4f18 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -604,6 +604,7 @@ class TreeUnpickler(reader: TastyReader, case LAZY => addFlag(Lazy) case OVERRIDE => addFlag(Override) case INLINE => addFlag(Inline) + case INLINEPROXY => addFlag(InlineProxy) case MACRO => addFlag(Macro) case STATIC => addFlag(JavaStatic) case OBJECT => addFlag(Module) @@ -1073,6 +1074,17 @@ class TreeUnpickler(reader: TastyReader, val stats = readStats(ctx.owner, end) val expr = exprReader.readTerm() Block(stats, expr) + case INLINED => + val exprReader = fork + skipTree() + def maybeCall = nextUnsharedTag match { + case VALDEF | DEFDEF => EmptyTree + case _ => readTerm() + } + val call = ifBefore(end)(maybeCall, EmptyTree) + val bindings = readStats(ctx.owner, end).asInstanceOf[List[ValOrDefDef]] + val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before + Inlined(call, bindings, expansion) case IF => If(readTerm(), readTerm(), readTerm()) case LAMBDA => diff --git a/compiler/src/dotty/tools/dotc/decompiler/TASTYDecompiler.scala b/compiler/src/dotty/tools/dotc/decompiler/TASTYDecompiler.scala index 62627a6b050a..4601ff9d1a12 100644 --- a/compiler/src/dotty/tools/dotc/decompiler/TASTYDecompiler.scala +++ b/compiler/src/dotty/tools/dotc/decompiler/TASTYDecompiler.scala @@ -15,7 +15,6 @@ class TASTYDecompiler extends TASTYCompiler { Nil override protected def picklerPhases: List[List[Phase]] = Nil - override protected def transformPhases: List[List[Phase]] = Nil override protected def backendPhases: List[List[Phase]] = diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 3c99b15347c7..355bf11bc3d1 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -40,7 +40,8 @@ object PostTyper { * * (10) Adds Child annotations to all sealed classes * - * (11) Replace RHS of `erased` (but not `inline`) members by `(???: rhs.type)` + * (11) Minimizes `call` fields of `Inlined` nodes to just point to the toplevel + * class from which code was inlined. * * The reason for making this a macro transform is that some functions (in particular * super and protected accessors and instantiation checks) are naturally top-down and @@ -177,22 +178,23 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase } } - private def handleInlineCall(sym: Symbol)(implicit ctx: Context): Unit = { - if (sym.is(Inline)) - ctx.compilationUnit.needsStaging = true + private object dropInlines extends TreeMap { + override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match { + case Inlined(call, _, _) => + cpy.Inlined(tree)(call, Nil, Typed(ref(defn.Predef_undefined), TypeTree(tree.tpe))) + case _ => super.transform(tree) + } } override def transform(tree: Tree)(implicit ctx: Context): Tree = try tree match { case tree: Ident if !tree.isType => - handleInlineCall(tree.symbol) handleMeta(tree.symbol) tree.tpe match { case tpe: ThisType => This(tpe.cls).withPos(tree.pos) case _ => tree } case tree @ Select(qual, name) => - handleInlineCall(tree.symbol) handleMeta(tree.symbol) if (name.isTypeName) { Checking.checkRealizable(qual.tpe, qual.pos.focus) @@ -201,7 +203,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase else transformSelect(tree, Nil) case tree: Apply => - handleInlineCall(tree.symbol) val methType = tree.fun.tpe.widen val app = if (methType.isErasedMethod) @@ -209,7 +210,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase tree.fun, tree.args.map(arg => if (methType.isImplicitMethod && arg.pos.isSynthetic) ref(defn.Predef_undefined) - else arg)) + else dropInlines.transform(arg))) else tree methPart(app) match { @@ -222,7 +223,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase super.transform(app) } case tree: TypeApply => - handleInlineCall(tree.symbol) val tree1 @ TypeApply(fn, args) = normalizeTypeArgs(tree) if (fn.symbol != defn.ChildAnnot.primaryConstructor) { // Make an exception for ChildAnnot, which should really have AnyKind bounds @@ -236,6 +236,19 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase case _ => super.transform(tree1) } + case Inlined(call, bindings, expansion) if !call.isEmpty => + // Leave only a call trace consisting of + // - a reference to the top-level class from which the call was inlined, + // - the call's position + // in the call field of an Inlined node. + // The trace has enough info to completely reconstruct positions. + // The minimization is done for two reasons: + // 1. To save space (calls might contain large inline arguments, which would otherwise + // be duplicated + // 2. To enable correct pickling (calls can share symbols with the inlined code, which + // would trigger an assertion when pickling). + val callTrace = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos) + cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(inlineContext(call))) case tree: Template => withNoCheckNews(tree.parents.flatMap(newPart)) { val templ1 = paramFwd.forwardParamAccessors(tree) @@ -322,10 +335,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase } /** Transforms the rhs tree into a its default tree if it is in an `erased` val/def. - * Performed to shrink the tree that is known to be erased later. - */ + * Performed to shrink the tree that is known to be erased later. + */ private def normalizeErasedRhs(rhs: Tree, sym: Symbol)(implicit ctx: Context) = - if (!sym.isEffectivelyErased || sym.isInlineMethod || !rhs.tpe.exists) rhs - else Typed(ref(defn.Predef_undefined), TypeTree(rhs.tpe)) + if (sym.isEffectivelyErased) dropInlines.transform(rhs) else rhs } } diff --git a/compiler/src/dotty/tools/dotc/transform/Staging.scala b/compiler/src/dotty/tools/dotc/transform/Staging.scala index f94b422a5670..90a727e0eec8 100644 --- a/compiler/src/dotty/tools/dotc/transform/Staging.scala +++ b/compiler/src/dotty/tools/dotc/transform/Staging.scala @@ -2,12 +2,7 @@ package dotty.tools.dotc package transform import core._ -import Decorators._ -import Flags._ -import Types._ -import Contexts._ -import Symbols._ -import Constants._ +import Decorators._, Flags._, Types._, Contexts._, Symbols._, Constants._ import ast.Trees._ import ast.{TreeTypeMap, untpd} import util.Positions._ @@ -20,12 +15,11 @@ import typer.Implicits.SearchFailureType import scala.collection.mutable import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.quoted._ -import dotty.tools.dotc.typer.{ConstFold, Inliner} import dotty.tools.dotc.util.SourcePosition -/** Inline calls to inline methods, evaluates macros, translates quoted terms (and types) - * to `unpickle` method calls and checks that the phase consistency principle (PCP) holds. +/** Translates quoted terms and types to `unpickle` method calls. + * Checks that the phase consistency principle (PCP) holds. * * * Transforms top level quote @@ -443,8 +437,7 @@ class Staging extends MacroTransformWithImplicits { else if (enclosingInlineds.nonEmpty) { // level 0 in an inlined call val spliceCtx = ctx.outer // drop the last `inlineContext` val pos: SourcePosition = Decorators.sourcePos(enclosingInlineds.head.pos)(spliceCtx) - val splicedTree = InlineCalls.transform(splice.qualifier) // inline calls that where inlined at level -1 - val evaluatedSplice = Splicer.splice(splicedTree, pos, macroClassLoader)(spliceCtx).withPos(splice.pos) + val evaluatedSplice = Splicer.splice(splice.qualifier, pos, macroClassLoader)(spliceCtx).withPos(splice.pos) if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice) } else if (!ctx.owner.isInlineMethod) { // level 0 outside an inline method @@ -567,9 +560,6 @@ class Staging extends MacroTransformWithImplicits { enteredSyms = enteredSyms.tail } tree match { - case tree if isInlineCall(tree) && level == 0 && !ctx.reporter.hasErrors && !ctx.settings.YnoInline.value => - val tree2 = super.transform(tree) // transform arguments before inlining (inline arguments and constant fold arguments) - transform(Inliner.inlineCall(tree2, tree.tpe.widen)) case Quoted(quotedTree) => quotation(quotedTree, tree) case tree: TypeTree if tree.tpe.typeSymbol.isSplice => @@ -620,7 +610,7 @@ class Staging extends MacroTransformWithImplicits { } case _ => markDef(tree) - ConstFold(checkLevel(mapOverTree(enteredSyms))) + checkLevel(mapOverTree(enteredSyms)) } } @@ -676,20 +666,4 @@ object Staging { /** Get the list of embedded trees */ def getTrees: List[tpd.Tree] = trees.toList } - - /** β-reduce all calls to inline methods and preform constant folding */ - object InlineCalls extends TreeMap { - override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match { - case tree if isInlineCall(tree) && !ctx.reporter.hasErrors && !ctx.settings.YnoInline.value => - val tree2 = super.transform(tree) // transform arguments before inlining (inline arguments and constant fold arguments) - transform(Inliner.inlineCall(tree2, tree.tpe.widen)) - case _: MemberDef => - val newTree = super.transform(tree) - if (newTree.symbol.exists) - newTree.symbol.defTree = newTree // set for inlined members - newTree - case _ => - ConstFold(super.transform(tree)) - } - } } diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 1432c5405cad..933e7c10c81f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -455,18 +455,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { if (inlinedMethod == defn.Typelevel_error) issueError() - // Leave only a call trace consisting of - // - a reference to the top-level class from which the call was inlined, - // - the call's position - // in the call field of an Inlined node. - // The trace has enough info to completely reconstruct positions. - // The minimization is done for the following reason: - // * To save space (calls might contain large inline arguments, which would otherwise be duplicated - val callTrace = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos) - // Take care that only argument bindings go into `bindings`, since positions are // different for bindings from arguments and bindings from body. - tpd.Inlined(callTrace, finalBindings, finalExpansion) + tpd.Inlined(call, finalBindings, finalExpansion) } } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9c3901128aa2..1c8acf4264d0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2452,6 +2452,13 @@ class Typer extends Namer checkEqualityEvidence(tree, pt) tree } + else if (Inliner.isInlineable(tree) && + !ctx.settings.YnoInline.value && + !ctx.isAfterTyper && + !ctx.reporter.hasErrors && + tree.tpe <:< pt) { + readaptSimplified(Inliner.inlineCall(tree, pt)) + } else if (tree.tpe <:< pt) { if (pt.hasAnnotation(defn.InlineParamAnnot)) checkInlineConformant(tree, isFinal = false, "argument to inline parameter") diff --git a/compiler/test/dotc/pos-from-tasty.blacklist b/compiler/test/dotc/pos-from-tasty.blacklist index ace498a34d3f..a48abcd017a0 100644 --- a/compiler/test/dotc/pos-from-tasty.blacklist +++ b/compiler/test/dotc/pos-from-tasty.blacklist @@ -17,7 +17,4 @@ repeatedArgs213.scala default-super.scala # Need to implement printing of match types -matchtype.scala - -# Fails on CI (not locally) -inline-named-typeargs.scala +matchtype.scala \ No newline at end of file diff --git a/compiler/test/dotc/pos-recompilation.whitelist b/compiler/test/dotc/pos-recompilation.whitelist index ef14a97f1d25..eb4c22b9d238 100644 --- a/compiler/test/dotc/pos-recompilation.whitelist +++ b/compiler/test/dotc/pos-recompilation.whitelist @@ -985,6 +985,7 @@ t8132 t8177d t8177e t8177h +t8207 t8219 t8230a t8237 diff --git a/compiler/test/dotc/run-test-pickling.blacklist b/compiler/test/dotc/run-test-pickling.blacklist index 672cee097820..db1a51b342b3 100644 --- a/compiler/test/dotc/run-test-pickling.blacklist +++ b/compiler/test/dotc/run-test-pickling.blacklist @@ -7,3 +7,4 @@ lazy-traits.scala t8133 t8133b tuples1.scala +tuples1a.scala diff --git a/tests/neg-with-compiler/quote-run-in-macro-2/quoted_2.scala b/tests/neg-with-compiler/quote-run-in-macro-2/quoted_2.scala index 6e40f84ec7f0..02a0925642f4 100644 --- a/tests/neg-with-compiler/quote-run-in-macro-2/quoted_2.scala +++ b/tests/neg-with-compiler/quote-run-in-macro-2/quoted_2.scala @@ -2,5 +2,11 @@ import Macros._ object Test { def main(args: Array[String]): Unit = { println(foo(1)) // error + println(foo(1 + 3)) // error + val x = 3 + println(foo { // error + val x = 5 + x + }) } } diff --git a/tests/neg-with-compiler/quote-run-in-macro-3/quoted_1.scala b/tests/neg-with-compiler/quote-run-in-macro-3/quoted_1.scala deleted file mode 100644 index a9daf7d26556..000000000000 --- a/tests/neg-with-compiler/quote-run-in-macro-3/quoted_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.quoted._ - -import scala.quoted.Toolbox.Default._ - -object Macros { - inline def foo(i: => Int): Int = ~fooImpl('(i)) - def fooImpl(i: Expr[Int]): Expr[Int] = { - val y: Int = i.run - y.toExpr - } -} diff --git a/tests/neg-with-compiler/quote-run-in-macro-3/quoted_2.scala b/tests/neg-with-compiler/quote-run-in-macro-3/quoted_2.scala deleted file mode 100644 index 663912caa1e8..000000000000 --- a/tests/neg-with-compiler/quote-run-in-macro-3/quoted_2.scala +++ /dev/null @@ -1,6 +0,0 @@ -import Macros._ -object Test { - def main(args: Array[String]): Unit = { - println(foo(1 + 3)) // error - } -} diff --git a/tests/neg-with-compiler/quote-run-in-macro-4/quoted_1.scala b/tests/neg-with-compiler/quote-run-in-macro-4/quoted_1.scala deleted file mode 100644 index a9daf7d26556..000000000000 --- a/tests/neg-with-compiler/quote-run-in-macro-4/quoted_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.quoted._ - -import scala.quoted.Toolbox.Default._ - -object Macros { - inline def foo(i: => Int): Int = ~fooImpl('(i)) - def fooImpl(i: Expr[Int]): Expr[Int] = { - val y: Int = i.run - y.toExpr - } -} diff --git a/tests/neg-with-compiler/quote-run-in-macro-4/quoted_2.scala b/tests/neg-with-compiler/quote-run-in-macro-4/quoted_2.scala deleted file mode 100644 index f5fa99aa13e6..000000000000 --- a/tests/neg-with-compiler/quote-run-in-macro-4/quoted_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -import Macros._ -object Test { - def main(args: Array[String]): Unit = { - println(foo { // error - val x = 5 - x - }) - } -} diff --git a/tests/neg/tasty-macro-assert-2/quoted_1.scala b/tests/neg/tasty-macro-assert-2/quoted_1.scala deleted file mode 100644 index 59c7d29a4378..000000000000 --- a/tests/neg/tasty-macro-assert-2/quoted_1.scala +++ /dev/null @@ -1,69 +0,0 @@ -import scala.quoted._ - -import scala.tasty._ - -object Asserts { - - implicit class Ops[T](left: T) { - def ===(right: T): Boolean = left == right - def !==(right: T): Boolean = left != right - } - - object Ops - - inline def macroAssert(cond: => Boolean): Unit = - ~impl('(cond)) - - def impl(cond: Expr[Boolean])(implicit tasty: Tasty): Expr[Unit] = { - import tasty._ - - val tree = cond.toTasty - - def isOps(tpe: TypeOrBounds): Boolean = tpe match { - case Type.SymRef(IsDefSymbol(sym), _) => sym.name == "Ops" // TODO check that the parent is Asserts - case _ => false - } - - object OpsTree { - def unapply(arg: Term): Option[Term] = arg match { - case Term.Apply(Term.TypeApply(term, _), left :: Nil) if isOps(term.tpe) => - Some(left) - case _ => None - } - } - - tree match { - case Term.Inlined(_, Nil, Term.Apply(Term.Select(OpsTree(left), op, _), right :: Nil)) => - '(assertTrue(~left.toExpr[Boolean])) // Buggy code. To generate the errors - case _ => - '(assertTrue(~cond)) - } - - } - - def assertEquals[T](left: T, right: T): Unit = { - if (left != right) { - println( - s"""Error left did not equal right: - | left = $left - | right = $right""".stripMargin) - } - - } - - def assertNotEquals[T](left: T, right: T): Unit = { - if (left == right) { - println( - s"""Error left was equal to right: - | left = $left - | right = $right""".stripMargin) - } - - } - - def assertTrue(cond: Boolean): Unit = { - if (!cond) - println("Condition was false") - } - -} diff --git a/tests/neg/tasty-macro-assert-2/quoted_2.scala b/tests/neg/tasty-macro-assert-2/quoted_2.scala deleted file mode 100644 index b43e3cc84dde..000000000000 --- a/tests/neg/tasty-macro-assert-2/quoted_2.scala +++ /dev/null @@ -1,10 +0,0 @@ - -import Asserts._ - -object Test { - def main(args: Array[String]): Unit = { - macroAssert(false !== "acb") - macroAssert("acb" !== "acb") // error - } - -} diff --git a/tests/neg/tasty-macro-assert/quoted_2.scala b/tests/neg/tasty-macro-assert/quoted_2.scala index 25ef0291b120..b94c98ab6b70 100644 --- a/tests/neg/tasty-macro-assert/quoted_2.scala +++ b/tests/neg/tasty-macro-assert/quoted_2.scala @@ -5,6 +5,8 @@ object Test { def main(args: Array[String]): Unit = { macroAssert(true === "cde") macroAssert("acb" === "cde") // error + macroAssert(false !== "acb") + macroAssert("acb" !== "acb") // error } } diff --git a/tests/pos/simpleInline.decompiled b/tests/pos/simpleInline.decompiled index 7fa25f3b3720..492a0da6e777 100644 --- a/tests/pos/simpleInline.decompiled +++ b/tests/pos/simpleInline.decompiled @@ -1,5 +1,7 @@ /** Decompiled from out/posTestFromTasty/pos/simpleInline/Foo.class */ class Foo() { inline def foo: scala.Int = 9 - def bar: scala.Int = Foo.this.foo + def bar: scala.Int = { // inlined + 9 + } } diff --git a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners.check b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners.check index 690f56b6dba9..d541fcc56321 100644 --- a/tests/run-custom-args/Yretain-trees/tasty-extractors-owners.check +++ b/tests/run-custom-args/Yretain-trees/tasty-extractors-owners.check @@ -1,5 +1,5 @@ foo -DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Apply(Term.TypeApply(Term.Ident("printOwners"), List(TypeTree.Synthetic())), List(Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))) +DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.Ident("Macros$")), Nil, Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Synthetic())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Synthetic())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~", Some(Signature(Nil, java.lang.Object))))))) bar DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))) @@ -8,7 +8,7 @@ bar2 DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))) foo2 -DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Apply(Term.TypeApply(Term.Ident("printOwners"), List(TypeTree.Synthetic())), List(Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))) +DefDef("main", Nil, List(List(ValDef("args", TypeTree.Applied(TypeTree.Ident("Array"), List(TypeTree.Ident("String"))), None))), TypeTree.Ident("Unit"), Some(Term.Block(Nil, Term.Inlined(Some(TypeTree.Ident("Macros$")), Nil, Term.Select(Term.Apply(Term.Apply(Term.TypeApply(Term.Ident("impl"), List(TypeTree.Synthetic())), List(Term.Apply(Term.TypeApply(Term.Ident("apply"), List(TypeTree.Synthetic())), List(Term.Inlined(None, Nil, Term.Block(List(DefDef("foo", Nil, Nil, TypeTree.Synthetic(), Some(Term.Block(List(DefDef("bar", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(1)))), ValDef("bar2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(2))))), Term.Typed(Term.Ident("bar"), TypeTree.Synthetic())))), ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))), ClassDef("A", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("B", TypeTree.Ident("Int")), DefDef("b", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(5)))), ValDef("b2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(6))))))), Term.Literal(Constant.Unit()))))))), List(Term.Ident("macroContext"))), "unary_~", Some(Signature(Nil, java.lang.Object))))))) baz ValDef("foo2", TypeTree.Synthetic(), Some(Term.Block(List(DefDef("baz", Nil, Nil, TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(3)))), ValDef("baz2", TypeTree.Synthetic(), Some(Term.Literal(Constant.Int(4))))), Term.Typed(Term.Ident("baz"), TypeTree.Synthetic())))) diff --git a/tests/run-with-compiler/i3876-d.check b/tests/run-with-compiler/i3876-d.check index de27d152d558..746b7f8778a7 100644 --- a/tests/run-with-compiler/i3876-d.check +++ b/tests/run-with-compiler/i3876-d.check @@ -1,5 +1,5 @@ 6 { val x$1: scala.Int = 3 - Test.inlineLambda.apply(x$1) + x$1.+(x$1) }