From cf44e915381169a38ebdfad5ef73bd96dc428930 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Wed, 26 Jun 2019 17:25:51 +0100 Subject: [PATCH] Symbol#source correct for all phases A combination of the inliner missing opportunities for setting defTrees with the correct inlined source information and some suspect post erasure logic in Symbol#source led to the same-source check in ExpandPrivate failing in joint-compilation scenarios resulting in multi-file programs being incorrectly rejected for access violations. --- .../src/dotty/tools/dotc/core/Symbols.scala | 30 +++++++++++++------ .../src/dotty/tools/dotc/typer/Inliner.scala | 1 + tests/pos/inline-joint/defn.scala | 5 ++++ tests/pos/inline-joint/use.scala | 3 ++ 4 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 tests/pos/inline-joint/defn.scala create mode 100644 tests/pos/inline-joint/use.scala diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 496eacbdf546..b4306a3a2de4 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -626,15 +626,27 @@ object Symbols { final def symbol(implicit ev: DontUseSymbolOnSymbol): Nothing = unsupported("symbol") type DontUseSymbolOnSymbol - final def source(implicit ctx: Context): SourceFile = - if (!defTree.isEmpty && !ctx.erasedTypes) defTree.source - else this match { - case cls: ClassSymbol => cls.sourceOfClass - case _ => - if (denot.is(Module)) denot.moduleClass.source - else if (denot.exists) denot.owner.source - else NoSource - } + final def source(implicit ctx: Context): SourceFile = { + def valid(src: SourceFile): SourceFile = + if (src.exists && src.file.extension != "class") src + else NoSource + + if (!denot.exists) NoSource + else + valid(defTree.source) match { + case NoSource => + valid(denot.owner.source) match { + case NoSource => + this match { + case cls: ClassSymbol => valid(cls.sourceOfClass) + case _ if denot.is(Module) => valid(denot.moduleClass.source) + case _ => NoSource + } + case src => src + } + case src => src + } + } /** A symbol related to `sym` that is defined in source code. * diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 4595720091b2..6a502209e0f9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -165,6 +165,7 @@ object Inliner { case tree: SeqLiteral => finalize(tree, untpd.SeqLiteral(transform(tree.elems), transform(tree.elemtpt))(curSource)) case tree: TypeTree => tpd.TypeTree(tree.tpe)(ctx.withSource(curSource)).withSpan(tree.span) case tree: Bind => finalize(tree, untpd.Bind(tree.name, transform(tree.body))(curSource)) + case tree: DefTree => super.transform(tree).setDefTree case _ => super.transform(tree) }) assert(transformed.isInstanceOf[EmptyTree[_]] || transformed.isInstanceOf[EmptyValDef[_]] || transformed.source == curSource) diff --git a/tests/pos/inline-joint/defn.scala b/tests/pos/inline-joint/defn.scala new file mode 100644 index 000000000000..e95dafd36135 --- /dev/null +++ b/tests/pos/inline-joint/defn.scala @@ -0,0 +1,5 @@ +object Foo { + inline def foo = new { bar(0) } + + def bar(i: => Int): Unit = () +} diff --git a/tests/pos/inline-joint/use.scala b/tests/pos/inline-joint/use.scala new file mode 100644 index 000000000000..74965f6e50f1 --- /dev/null +++ b/tests/pos/inline-joint/use.scala @@ -0,0 +1,3 @@ +object Test { + val v = Foo.foo +}