From 40675e6939382a9063e5ac812725f93d17f9f98a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 11 Apr 2017 15:54:20 +0200 Subject: Fix #2212: Avoid imports in the wrong namespace Don't issue an error if when considering a named import that refers to a valoe or type which does not exist. Instead, disregard the import an continue. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 48 ++++++++++++------------- tests/pos/i2212.scala | 19 ++++++++++ 2 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 tests/pos/i2212.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a7b8200b5..8a124b17b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -178,6 +178,20 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit previous } + def selection(imp: ImportInfo, name: Name) = + if (imp.sym.isCompleting) { + ctx.warning(i"cyclic ${imp.sym}, ignored", tree.pos) + NoType + } else if (unimported.nonEmpty && unimported.contains(imp.site.termSymbol)) + NoType + else { + val pre = imp.site + val denot = pre.member(name).accessibleFrom(pre)(refctx) + // Pass refctx so that any errors are reported in the context of the + // reference instead of the + if (reallyExists(denot)) pre.select(name, denot) else NoType + } + /** The type representing a named import with enclosing name when imported * from given `site` and `selectors`. */ @@ -193,25 +207,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit found } - def selection(name: Name) = - if (imp.sym.isCompleting) { - ctx.warning(i"cyclic ${imp.sym}, ignored", tree.pos) - NoType - } - else if (unimported.nonEmpty && unimported.contains(imp.site.termSymbol)) - NoType - else { - // Pass refctx so that any errors are reported in the context of the - // reference instead of the - checkUnambiguous(selectionType(imp.site, name, tree.pos)(refctx)) - } + def unambiguousSelection(name: Name) = + checkUnambiguous(selection(imp, name)) selector match { case Thicket(fromId :: Ident(Name) :: _) => val Ident(from) = fromId - selection(if (name.isTypeName) from.toTypeName else from) + unambiguousSelection(if (name.isTypeName) from.toTypeName else from) case Ident(Name) => - selection(name) + unambiguousSelection(name) case _ => recur(rest) } @@ -224,18 +228,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit /** The type representing a wildcard import with enclosing name when imported * from given import info */ - def wildImportRef(imp: ImportInfo)(implicit ctx: Context): Type = { - if (imp.isWildcardImport) { - val pre = imp.site - if (!unimported.contains(pre.termSymbol) && - !imp.excluded.contains(name.toTermName) && - name != nme.CONSTRUCTOR) { - val denot = pre.member(name).accessibleFrom(pre)(refctx) - if (reallyExists(denot)) return pre.select(name, denot) - } - } - NoType - } + def wildImportRef(imp: ImportInfo)(implicit ctx: Context): Type = + if (imp.isWildcardImport && !imp.excluded.contains(name.toTermName) && name != nme.CONSTRUCTOR) + selection(imp, name) + else NoType /** Is (some alternative of) the given predenotation `denot` * defined in current compilation unit? diff --git a/tests/pos/i2212.scala b/tests/pos/i2212.scala new file mode 100644 index 000000000..416c8ca04 --- /dev/null +++ b/tests/pos/i2212.scala @@ -0,0 +1,19 @@ +package object squants { + type Time = squants.time.Time +} +package squants.time { + class Time + object Time { def x = 2 } +} +package squants.velocity { + import squants.time._ // <-- imports `Time` value + import squants.Time // <-- imports type alias + object Velocity { Time.x } +} + +import scala.math.BigDecimal.RoundingMode +import scala.math.BigDecimal.RoundingMode.RoundingMode + +object Money { + def foo(round: RoundingMode = RoundingMode.HALF_EVEN): Int = ??? +} -- cgit v1.2.3