From c9682121b6ed33fe67dad445ebc665d13b369bbb Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 20 Sep 2016 23:42:38 -0700 Subject: SI-9839 Avoid crash in macro import selector pos Ignore bad name pos. Also delete unused val. Thanks, `-Ywarn-unused`! --- src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 10 ++++------ test/files/neg/warn-unused-imports.check | 5 ++++- test/files/neg/warn-unused-imports/sample_1.scala | 15 +++++++++++++++ .../neg/warn-unused-imports/warn-unused-imports_2.scala | 4 ++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 7a3b8d2ab6..67168917e1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -64,10 +64,8 @@ trait Contexts { self: Analyzer => for (imps <- allImportInfos.remove(unit)) { for (imp <- imps.distinct.reverse) { val used = allUsedSelectors(imp) - - imp.tree.selectors filterNot (s => isMaskImport(s) || used(s)) foreach { sel => - reporter.warning(imp posOf sel, "Unused import") - } + for (sel <- imp.tree.selectors if !isMaskImport(sel) && !used(sel)) + reporter.warning(imp.posOf(sel), "Unused import") } allUsedSelectors --= imps } @@ -825,7 +823,6 @@ trait Contexts { self: Analyzer => private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { val qual = imp.qual - val qualSym = qual.tpe.typeSymbol val pre = qual.tpe def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match { case List() => @@ -1412,7 +1409,8 @@ trait Contexts { self: Analyzer => class ImportInfo(val tree: Import, val depth: Int) { def pos = tree.pos - def posOf(sel: ImportSelector) = tree.pos withPoint sel.namePos + def posOf(sel: ImportSelector) = + if (sel.namePos >= 0) tree.pos withPoint sel.namePos else tree.pos /** The prefix expression */ def qual: Tree = tree.symbol.info match { diff --git a/test/files/neg/warn-unused-imports.check b/test/files/neg/warn-unused-imports.check index 0a53d7a9cd..29d73a6264 100644 --- a/test/files/neg/warn-unused-imports.check +++ b/test/files/neg/warn-unused-imports.check @@ -51,5 +51,8 @@ warn-unused-imports_2.scala:149: warning: Unused import warn-unused-imports_2.scala:150: warning: Unused import import p1.A // warn ^ -16 warnings found +warn-unused-imports_2.scala:158: warning: Unused import + def x = Macro.f // warn, not crash + ^ +17 warnings found one error found diff --git a/test/files/neg/warn-unused-imports/sample_1.scala b/test/files/neg/warn-unused-imports/sample_1.scala index d2f86239db..eea4d0eb4c 100644 --- a/test/files/neg/warn-unused-imports/sample_1.scala +++ b/test/files/neg/warn-unused-imports/sample_1.scala @@ -15,3 +15,18 @@ object Sample { def f(x: X) = ??? def g(y: Y) = ??? } + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macro { + def f: Int = macro fImpl + def fImpl(c: Context): c.Tree = { + import c.universe._ + + q""" + import scala.util.Random + 42 // TODO randomize + """ + } +} diff --git a/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala b/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala index 56ad3393a1..58fe0131d9 100644 --- a/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala +++ b/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala @@ -153,3 +153,7 @@ trait Outsiders { //Future("abc".bippy) } } + +class MacroClient { + def x = Macro.f // warn, not crash +} -- cgit v1.2.3