diff options
23 files changed, 165 insertions, 80 deletions
diff --git a/src/dotty/annotation/internal/SourceFile.scala b/src/dotty/annotation/internal/SourceFile.scala new file mode 100644 index 000000000..c49fc2c8d --- /dev/null +++ b/src/dotty/annotation/internal/SourceFile.scala @@ -0,0 +1,10 @@ +package dotty.annotation.internal + +import scala.annotation.Annotation + +/** An annotation to record a Scala2 pickled alias. + * @param aliased A TermRef pointing to the aliased field. + */ +class SourceFile(path: String) extends Annotation { + +} diff --git a/src/dotty/tools/dotc/FromTasty.scala b/src/dotty/tools/dotc/FromTasty.scala index 8f29c882c..05e97f30a 100644 --- a/src/dotty/tools/dotc/FromTasty.scala +++ b/src/dotty/tools/dotc/FromTasty.scala @@ -64,6 +64,9 @@ object FromTasty extends Driver { } class ReadTastyTreesFromClasses extends FrontEnd { + + override def isTyper = false + override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = units.map(readTASTY) @@ -83,8 +86,8 @@ object FromTasty extends Driver { case info: ClassfileLoader => info.load(clsd) match { case Some(unpickler: DottyUnpickler) => - val (List(unpickled), source) = unpickler.body(readPositions = true) - val unit1 = new CompilationUnit(source) + val List(unpickled) = unpickler.body(readPositions = true) + val unit1 = new CompilationUnit(new SourceFile(clsd.symbol.sourceFile, Seq())) unit1.tpdTree = unpickled unit1.unpicklers += (clsd.classSymbol -> unpickler.unpickler) force.traverse(unit1.tpdTree) diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index dc4897233..5f96a60e6 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -94,6 +94,9 @@ object Annotations { def makeChild(sym: Symbol)(implicit ctx: Context) = deferred(defn.ChildAnnot, implicit ctx => New(defn.ChildAnnotType.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)) + + def makeSourceFile(path: String)(implicit ctx: Context) = + apply(defn.SourceFileAnnot, Literal(Constant(path))) } def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = { diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index ad3a0057d..bbe8e920c 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -336,13 +336,17 @@ object Contexts { def thisCallArgContext: Context = { assert(owner.isClassConstructor) val constrCtx = outersIterator.dropWhile(_.outer.owner == owner).next - superOrThisCallContext(owner, constrCtx.scope).setTyperState(typerState) + superOrThisCallContext(owner, constrCtx.scope) + .setTyperState(typerState) + .setGadt(gadt) } - /** The super= or this-call context with given owner and locals. */ + /** The super- or this-call context with given owner and locals. */ private def superOrThisCallContext(owner: Symbol, locals: Scope): FreshContext = { var classCtx = outersIterator.dropWhile(!_.isClassDefContext).next - classCtx.outer.fresh.setOwner(owner).setScope(locals).setMode(classCtx.mode | Mode.InSuperCall) + classCtx.outer.fresh.setOwner(owner) + .setScope(locals) + .setMode(classCtx.mode | Mode.InSuperCall) } /** The context of expression `expr` seen as a member of a statement sequence */ @@ -438,6 +442,7 @@ object Contexts { def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this } def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } + def setGadt(gadt: GADTMap): this.type = { this.gadt = gadt; this } def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this } diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index d8c882d5c..6625cff3f 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -456,6 +456,8 @@ class Definitions { def RemoteAnnot(implicit ctx: Context) = RemoteAnnotType.symbol.asClass lazy val RepeatedAnnotType = ctx.requiredClassRef("dotty.annotation.internal.Repeated") def RepeatedAnnot(implicit ctx: Context) = RepeatedAnnotType.symbol.asClass + lazy val SourceFileAnnotType = ctx.requiredClassRef("dotty.annotation.internal.SourceFile") + def SourceFileAnnot(implicit ctx: Context) = SourceFileAnnotType.symbol.asClass lazy val ScalaSignatureAnnotType = ctx.requiredClassRef("scala.reflect.ScalaSignature") def ScalaSignatureAnnot(implicit ctx: Context) = ScalaSignatureAnnotType.symbol.asClass lazy val ScalaLongSignatureAnnotType = ctx.requiredClassRef("scala.reflect.ScalaLongSignature") diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index ce87506ae..4b2861452 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -291,7 +291,11 @@ object Phases { */ def relaxedTyping: Boolean = false - /** Overridden by FrontEnd */ + /** Is this phase the standard typerphase? True for FrontEnd, but + * not for other first phases (such as FromTasty). The predicate + * is tested in some places that perform checks and corrections. It's + * different from isAfterTyper (and cheaper to test). + */ def isTyper = false def exists: Boolean = true diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 2a76f18d8..d40acdfa7 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -21,6 +21,7 @@ import StdNames._ import NameOps._ import ast.tpd.Tree import ast.TreeTypeMap +import Constants.Constant import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile @@ -463,20 +464,23 @@ object Symbols { denot.topLevelClass.symbol.associatedFile /** The class file from which this class was generated, null if not applicable. */ - final def binaryFile(implicit ctx: Context): AbstractFile = - pickFile(associatedFile, classFile = true) + final def binaryFile(implicit ctx: Context): AbstractFile = { + val file = associatedFile + if (file != null && file.path.endsWith("class")) file else null + } /** The source file from which this class was generated, null if not applicable. */ - final def sourceFile(implicit ctx: Context): AbstractFile = - pickFile(associatedFile, classFile = false) - - /** Desire to re-use the field in ClassSymbol which stores the source - * file to also store the classfile, but without changing the behavior - * of sourceFile (which is expected at least in the IDE only to - * return actual source code.) So sourceFile has classfiles filtered out. - */ - private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile = - if ((file eq null) || classFile != (file.path endsWith ".class")) null else file + final def sourceFile(implicit ctx: Context): AbstractFile = { + val file = associatedFile + if (file != null && !file.path.endsWith("class")) file + else denot.topLevelClass.getAnnotation(defn.SourceFileAnnot) match { + case Some(sourceAnnot) => sourceAnnot.argumentConstant(0) match { + case Some(Constant(path: String)) => AbstractFile.getFile(path) + case none => null + } + case none => null + } + } /** The position of this symbol, or NoPosition is symbol was not loaded * from source. diff --git a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index d62762571..0ad5d6966 100644 --- a/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -3,13 +3,13 @@ package dotc package core package tasty -import Contexts._, SymDenotations._ +import Contexts._, SymDenotations._, Symbols._ import dotty.tools.dotc.ast.tpd import TastyUnpickler._, TastyBuffer._ -import dotty.tools.dotc.core.tasty.DottyUnpickler.{SourceFileUnpickler, TreeSectionUnpickler, PositionsSectionUnpickler} import util.Positions._ import util.{SourceFile, NoSource} import PositionUnpickler._ +import Annotations.Annotation import classfile.ClassfileParser object DottyUnpickler { @@ -17,11 +17,6 @@ object DottyUnpickler { /** Exception thrown if classfile is corrupted */ class BadSignature(msg: String) extends RuntimeException(msg) - class SourceFileUnpickler extends SectionUnpickler[SourceFile]("Sourcefile") { - def unpickle(reader: TastyReader, tastyName: TastyName.Table) = - new SourceFile(tastyName(reader.readNameRef()).toString, Seq()) - } - class TreeSectionUnpickler extends SectionUnpickler[TreeUnpickler]("ASTs") { def unpickle(reader: TastyReader, tastyName: TastyName.Table) = new TreeUnpickler(reader, tastyName) @@ -38,6 +33,7 @@ object DottyUnpickler { */ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded { import tpd._ + import DottyUnpickler._ val unpickler = new TastyUnpickler(bytes) private val treeUnpickler = unpickler.unpickle(new TreeSectionUnpickler).get @@ -51,11 +47,10 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded { /** The unpickled trees, and the source file they come from * @param readPositions if true, trees get decorated with position information. */ - def body(readPositions: Boolean = false)(implicit ctx: Context): (List[Tree], SourceFile) = { - val source = unpickler.unpickle(new SourceFileUnpickler).getOrElse(NoSource) + def body(readPositions: Boolean = false)(implicit ctx: Context): List[Tree] = { if (readPositions) for ((totalRange, positions) <- unpickler.unpickle(new PositionsSectionUnpickler)) treeUnpickler.usePositions(totalRange, positions) - (treeUnpickler.unpickle(), source) + treeUnpickler.unpickle() } } diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index f3dabb517..ea7e985c9 100644 --- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -84,7 +84,7 @@ Standard-Section: "ASTs" TopLevelStat* MATCH Length sel_Term CaseDef* TRY Length expr_Term CaseDef* finalizer_Term? RETURN Length meth_ASTRef expr_Term? - REPEATED Length elem_Term* + REPEATED Length elem_Type elem_Term* BIND Length boundName_NameRef patType_Type pat_Term ALTERNATIVE Length alt_Term* UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* @@ -184,8 +184,6 @@ Note: Tree tags are grouped into 5 categories that determine what follows, and t Category 4 (tags 112-127): tag Nat AST Category 5 (tags 128-255): tag Length <payload> -Standard Section: "Sourcefile" sourcefile_NameRef - Standard Section: "Positions" sourceLength_Nat Assoc* Assoc = addr_Delta offset_Delta offset_Delta? diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index b547862b4..ad6ddf7fe 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -596,6 +596,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { vparamss.nestedMap(_.symbol), name == nme.CONSTRUCTOR) val resType = ctx.effectiveResultType(sym, typeParams, tpt.tpe) sym.info = ctx.methodType(typeParams, valueParamss, resType) + if (sym.isSetter && sym.accessedFieldOrGetter.is(ParamAccessor)) { + // reconstitute ParamAccessor flag of setters for var parameters, which is not pickled + sym.setFlag(ParamAccessor) + sym.resetFlag(Deferred) + } DefDef(tparams, vparamss, tpt) case VALDEF => sym.info = readType() @@ -802,9 +807,10 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass) case APPLY => val fn = readTerm() - val isJava = fn.tpe.isInstanceOf[JavaMethodType] + val isJava = fn.symbol.is(JavaDefined) def readArg() = readTerm() match { - case SeqLiteral(elems, elemtpt) if isJava => JavaSeqLiteral(elems, elemtpt) + case SeqLiteral(elems, elemtpt) if isJava => + JavaSeqLiteral(elems, elemtpt) case arg => arg } tpd.Apply(fn, until(end)(readArg())) @@ -813,7 +819,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { case PAIR => Pair(readTerm(), readTerm()) case TYPED => - Typed(readTerm(), readTpt()) + val expr = readTerm() + val tpt = readTpt() + val expr1 = expr match { + case SeqLiteral(elems, elemtpt) if tpt.tpe.isRef(defn.ArrayClass) => + JavaSeqLiteral(elems, elemtpt) + case expr => expr + } + Typed(expr1, tpt) case NAMEDARG => NamedArg(readName(), readTerm()) case ASSIGN => diff --git a/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/src/dotty/tools/dotc/transform/ExpandPrivate.scala index a6f203478..2e0759b89 100644 --- a/src/dotty/tools/dotc/transform/ExpandPrivate.scala +++ b/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -16,6 +16,7 @@ import TreeTransforms._ import Decorators._ import ast.Trees._ import TreeTransforms._ +import java.io.File.separatorChar /** Make private term members that are accessed from another class * non-private by resetting the Private flag and expanding their name. @@ -58,7 +59,20 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t */ private def ensurePrivateAccessible(d: SymDenotation)(implicit ctx: Context) = if (d.is(PrivateTerm) && d.owner != ctx.owner.enclosingClass) { - assert(d.symbol.sourceFile == ctx.source.file, + // Paths `p1` and `p2` are similar if they have a common suffix that follows + // possibly different directory paths. That is, their common suffix extends + // in both cases either to the start of the path or to a file separator character. + def isSimilar(p1: String, p2: String): Boolean = { + var i = p1.length - 1 + var j = p2.length - 1 + while (i >= 0 && j >= 0 && p1(i) == p2(j) && p1(i) != separatorChar) { + i -= 1 + j -= 1 + } + (i < 0 || p1(i) == separatorChar) && + (j < 0 || p1(j) == separatorChar) + } + assert(isSimilar(d.symbol.sourceFile.path, ctx.source.file.path), i"private ${d.symbol.showLocated} in ${d.symbol.sourceFile} accessed from ${ctx.owner.showLocated} in ${ctx.source.file}") d.ensureNotPrivate.installAfter(thisTransform) } diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala index c5b223d53..e8d6d03bf 100644 --- a/src/dotty/tools/dotc/transform/Pickler.scala +++ b/src/dotty/tools/dotc/transform/Pickler.scala @@ -11,7 +11,6 @@ import Periods._ import Phases._ import Symbols._ import Flags.Module -import util.SourceFile import collection.mutable /** This phase pickles trees */ @@ -48,8 +47,6 @@ class Pickler extends Phase { treePkl.pickle(tree :: Nil) pickler.addrOfTree = treePkl.buf.addrOfTree pickler.addrOfSym = treePkl.addrOfSym - if (unit.source.exists) - pickleSourcefile(pickler, unit.source) if (tree.pos.exists) new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil, tree.pos) @@ -65,12 +62,6 @@ class Pickler extends Phase { } } - private def pickleSourcefile(pickler: TastyPickler, source: SourceFile): Unit = { - val buf = new TastyBuffer(10) - pickler.newSection("Sourcefile", buf) - buf.writeNat(pickler.nameBuffer.nameIndex(source.file.path).index) - } - override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { val result = super.runOn(units) if (ctx.settings.YtestPickler.value) @@ -89,16 +80,16 @@ class Pickler extends Phase { } pickling.println("************* entered toplevel ***********") for ((cls, unpickler) <- unpicklers) { - val (unpickled, source) = unpickler.body(readPositions = true) - testSame(i"$unpickled%\n%", beforePickling(cls), cls, source) + val unpickled = unpickler.body(readPositions = true) + testSame(i"$unpickled%\n%", beforePickling(cls), cls) } } - private def testSame(unpickled: String, previous: String, cls: ClassSymbol, source: SourceFile)(implicit ctx: Context) = + private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) = if (previous != unpickled) { output("before-pickling.txt", previous) output("after-pickling.txt", unpickled) - ctx.error(s"""pickling difference for ${cls.fullName} in $source, for details: + ctx.error(s"""pickling difference for ${cls.fullName} in ${cls.sourceFile}, for details: | | diff before-pickling.txt after-pickling.txt""".stripMargin) } diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala index 01f9f6317..fcde59b24 100644 --- a/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/src/dotty/tools/dotc/transform/PostTyper.scala @@ -36,6 +36,8 @@ import Symbols._, TypeUtils._ * * (8) Replaces self references by name with `this` * + * (9) Adds SourceFile annotations to all top-level classes and objects + * * 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 * don't lend themselves to the bottom-up approach of a mini phase. The other two functions @@ -224,7 +226,13 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran transformMemberDef(tree) val sym = tree.symbol val tree1 = - if (sym.isClass) tree + if (sym.isClass) { + if (sym.owner.is(Package) && + ctx.compilationUnit.source.exists && + sym != defn.SourceFileAnnot) + sym.addAnnotation(Annotation.makeSourceFile(ctx.compilationUnit.source.file.path)) + tree + } else { Checking.typeChecker.traverse(tree.rhs) cpy.TypeDef(tree)(rhs = TypeTree(tree.symbol.info)) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index f3903e539..ec2508580 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -531,12 +531,16 @@ trait Applications extends Compatibility { self: Typer => def treeToArg(arg: Tree): Tree = arg } + /** If `app` is a `this(...)` constructor call, the this-call argument context, + * otherwise the current context. + */ + def argCtx(app: untpd.Tree)(implicit ctx: Context): Context = + if (untpd.isSelfConstrCall(app)) ctx.thisCallArgContext else ctx + def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = { def realApply(implicit ctx: Context): Tree = track("realApply") { - def argCtx(implicit ctx: Context) = - if (untpd.isSelfConstrCall(tree)) ctx.thisCallArgContext else ctx - var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx) + var proto = new FunProto(tree.args, IgnoredProto(pt), this)(argCtx(tree)) val fun1 = typedExpr(tree.fun, proto) // Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as @@ -554,7 +558,7 @@ trait Applications extends Compatibility { self: Typer => tryEither { implicit ctx => val app = if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt) - else new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx) + else new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx(tree)) val result = app.result convertNewArray(ConstFold(result)) } { (failedVal, failedState) => diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 84abf85e0..2575dbec2 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1022,17 +1022,20 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val DefDef(name, tparams, vparamss, tpt, _) = ddef completeAnnotations(ddef, sym) val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef]) - // for secondary constructors we need to use that their type parameters - // are aliases of the class type parameters. See pos/i941.scala - if (sym.isConstructor && !sym.isPrimaryConstructor) - (sym.owner.typeParams, tparams1).zipped.foreach {(tparam, tdef) => - tdef.symbol.info = TypeAlias(tparam.typeRef) - } - val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef]) if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1) val tpt1 = checkSimpleKinded(typedType(tpt)) - val rhs1 = typedExpr(ddef.rhs, tpt1.tpe) + + var rhsCtx = ctx + if (sym.isConstructor && !sym.isPrimaryConstructor && tparams1.nonEmpty) { + // for secondary constructors we need a context that "knows" + // that their type parameters are aliases of the class type parameters. + // See pos/i941.scala + rhsCtx = ctx.fresh.setFreshGADTBounds + (tparams1, sym.owner.typeParams).zipped.foreach ((tdef, tparam) => + rhsCtx.gadt.setBounds(tdef.symbol, TypeAlias(tparam.typeRef))) + } + val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx) assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym) //todo: make sure dependent method types do not depend on implicits or by-name params } @@ -1518,7 +1521,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val tvarsToInstantiate = tvarsInParams(tree) wtp.paramTypes.foreach(instantiateSelected(_, tvarsToInstantiate)) val constr = ctx.typerState.constraint - def addImplicitArgs = { + def addImplicitArgs(implicit ctx: Context) = { val errors = new mutable.ListBuffer[() => String] def implicitArgError(msg: => String) = { errors += (() => msg) @@ -1565,9 +1568,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } else adapt(tpd.Apply(tree, args), pt) } - if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs + if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs(argCtx(tree)) else - ctx.typerState.tryWithFallback(addImplicitArgs) { + ctx.typerState.tryWithFallback(addImplicitArgs(argCtx(tree))) { adapt(typed(original, WildcardType), pt, EmptyTree) } case wtp: MethodType if !pt.isInstanceOf[SingletonType] => @@ -1677,7 +1680,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (pt.isInstanceOf[PolyProto]) tree else { var typeArgs = tree match { - case Select(New(tpt), nme.CONSTRUCTOR) => tpt.tpe.dealias.argTypesLo + case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo case _ => Nil } if (typeArgs.isEmpty) typeArgs = constrained(poly, tree)._2 diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 51b8b3dc5..b646c72d5 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -200,11 +200,12 @@ class tests extends CompilerTest { @Test def tasty_new_all = compileFiles(newDir, testPickling) @Test def tasty_dotty = compileDir(sourceDir, "dotty", testPickling) - @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) - @Test def tasty_runtime = compileDir(s"$dottyDir", "runtime", testPickling) - //TODO: issues with ./src/dotty/runtime/vc/VCPrototype.scala - //@Test def tasty_runtime_vc = compileDir(s"${dottyDir}runtime/", "vc", testPickling) + // Disabled because we get stale symbol errors on the SourceFile annotation, which is normal. + // @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) + + @Test def tasty_runtime = compileDir(s"$dottyDir", "runtime", testPickling) + @Test def tasty_runtime_vc = compileDir(s"${dottyDir}runtime/", "vc", testPickling) @Test def tasty_tools = compileDir(dottyDir, "tools", testPickling) @@ -214,11 +215,7 @@ class tests extends CompilerTest { "scalaPrimitives.scala" ) map (s"${backendDir}jvm/" + _), testPickling) - //TODO: issue with ./src/dotty/tools/backend/sjs/JSCodeGen.scala - @Test def tasty_backend_sjs = compileList("tasty_backend_sjs", List( - "GenSJSIR.scala", "JSDefinitions.scala", "JSEncoding.scala", "JSInterop.scala", - "JSPositions.scala", "JSPrimitives.scala", "ScopedVar.scala" - ) map (s"${backendDir}sjs/" + _), testPickling) + @Test def tasty_backend_sjs = compileDir(s"${backendDir}", "sjs", testPickling) @Test def tasty_dotc = compileDir(toolsDir, "dotc", testPickling) @Test def tasty_dotc_ast = compileDir(dotcDir, "ast", testPickling) @@ -249,12 +246,7 @@ class tests extends CompilerTest { @Test def tasty_dotc_printing = compileDir(dotcDir, "printing", testPickling) - //TODO: issues with ./src/dotty/tools/dotc/repl/CompilingInterpreter.scala, - //./src/dotty/tools/dotc/repl/InterpreterLoop.scala - @Test def tasty_dotc_repl = compileList("tasty_dotc_repl", List( - "AbstractFileClassLoader.scala", "ConsoleWriter.scala", "InteractiveReader.scala", - "Interpreter.scala", "Main.scala", "NewLinePrintWriter.scala", "REPL.scala", "SimpleReader.scala" - ) map (dottyReplDir + _), testPickling) + @Test def tasty_dotc_repl = compileDir(dotcDir, "repl", testPickling) //@Test def tasty_dotc_reporting = compileDir(dotcDir, "reporting", testPickling) @Test def tasty_dotc_rewrite = compileDir(dotcDir, "rewrite", testPickling) diff --git a/tests/pending/pickling/cyclic-annotations.scala b/tests/pending/pickling/cyclic-annotations.scala new file mode 100644 index 000000000..b975afe37 --- /dev/null +++ b/tests/pending/pickling/cyclic-annotations.scala @@ -0,0 +1 @@ +@ann class ann extends scala.annotation.Annotation diff --git a/tests/pickling/i1202a.scala b/tests/pickling/i1202a.scala new file mode 100644 index 000000000..0bc19f4e3 --- /dev/null +++ b/tests/pickling/i1202a.scala @@ -0,0 +1,7 @@ +class Test[T] { + def testMethod: Unit = + new Foo(this) +} +class Foo[T]() { + def this(ct: Test[T]) = this() +} diff --git a/tests/pickling/i1202b.scala b/tests/pickling/i1202b.scala new file mode 100644 index 000000000..09d06170f --- /dev/null +++ b/tests/pickling/i1202b.scala @@ -0,0 +1,9 @@ +package i1202 + +class Test() { + import Test._ + val myStatus = Unknown +} +object Test { + private val Unknown: Int = 0 +} diff --git a/tests/pickling/i1202c.scala b/tests/pickling/i1202c.scala new file mode 100644 index 000000000..dde1f3aa6 --- /dev/null +++ b/tests/pickling/i1202c.scala @@ -0,0 +1 @@ +class Fail7(var in: Int) diff --git a/tests/pickling/i1202d.scala b/tests/pickling/i1202d.scala new file mode 100644 index 000000000..d03adf197 --- /dev/null +++ b/tests/pickling/i1202d.scala @@ -0,0 +1,4 @@ +class Fail5 { + val someClass: Class[_] = ??? + val resultMethod = someClass.getMethod("result") +} diff --git a/tests/pending/pickling/i94-nada.scala b/tests/pickling/i94-nada.scala index ce8dc98ad..ce8dc98ad 100644 --- a/tests/pending/pickling/i94-nada.scala +++ b/tests/pickling/i94-nada.scala diff --git a/tests/pos/i941.scala b/tests/pos/i941.scala index 75bf4e448..5a0ef512c 100644 --- a/tests/pos/i941.scala +++ b/tests/pos/i941.scala @@ -7,4 +7,18 @@ object Test { def foo(x: A): Unit = () } + class D[A](x: A) { + + var f = x + + def this(y1: A, y2: A) = { + this(y1) + f = y2 + val g: A = f + foo(y2) + } + + def foo(x: A): Unit = () + + } } |