diff options
author | Martin Odersky <odersky@gmail.com> | 2017-01-15 21:46:25 +1100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-01-15 21:46:25 +1100 |
commit | eb1063725d74395a86b3191fc658b7963f07c4b5 (patch) | |
tree | e913c46b4034c9a596027a3b179cc897013b5531 | |
parent | ba7e12999dc645dbcba04cf365dfd4d621ee4662 (diff) | |
download | dotty-eb1063725d74395a86b3191fc658b7963f07c4b5.tar.gz dotty-eb1063725d74395a86b3191fc658b7963f07c4b5.tar.bz2 dotty-eb1063725d74395a86b3191fc658b7963f07c4b5.zip |
Adopt scala's scheme for root import hiding
scalac hides a root import from Predef if there is an eplicit Predef import.
We now do the same (previously we did this only if the overriding import undefined
something, using a `x => _` syntax). To avoid cycles and races one had to be very careful
not to force import symbols too early, so we now compare the name before the symbol proper.
All this is likely temporary - the comment of ImportInfo#unimported points to a different,
more systematic solution.
4 files changed, 23 insertions, 14 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 45e37eb8b..134b31519 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -747,6 +747,7 @@ class Definitions { else if (ctx.settings.YnoPredef.value) StaticRootImportFns else StaticRootImportFns ++ PredefImportFns + lazy val ShadowableImportNames = Set("Predef", "DottyPredef").map(_.toTermName) lazy val RootImportTypes = RootImportFns.map(_()) /** Modules whose members are in the default namespace and their module classes */ diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala index e44343e70..a5657890e 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -15,17 +15,20 @@ object ImportInfo { val selectors = untpd.Ident(nme.WILDCARD) :: Nil def expr = tpd.Ident(refFn()) def imp = tpd.Import(expr, selectors) - new ImportInfo(imp.symbol, selectors, isRootImport = true) + new ImportInfo(imp.symbol, selectors, None, isRootImport = true) } } /** Info relating to an import clause - * @param sym The import symbol defined by the clause - * @param selectors The selector clauses - * @param rootImport true if this is one of the implicit imports of scala, java.lang - * or Predef in the start context, false otherwise. + * @param sym The import symbol defined by the clause + * @param selectors The selector clauses + * @param symNameOpt Optionally, the name of the import symbol. None for root imports. + * Defined for all explicit imports from ident or select nodes. + * @param isRootImport true if this is one of the implicit imports of scala, java.lang, + * scala.Predef or dotty.DottyPredef in the start context, false otherwise. */ -class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], val isRootImport: Boolean = false)(implicit ctx: Context) { +class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], + symNameOpt: Option[TermName], val isRootImport: Boolean = false)(implicit ctx: Context) { lazy val sym = symf @@ -105,11 +108,11 @@ class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], val isRootImp */ lazy val unimported: Symbol = { lazy val sym = site.termSymbol - val hasMaskingSelector = selectors exists { - case Thicket(_ :: Ident(nme.WILDCARD) :: Nil) => true - case _ => false + def maybeShadowsRoot = symNameOpt match { + case Some(symName) => defn.ShadowableImportNames.contains(symName) + case None => false } - if (hasMaskingSelector && defn.RootImportTypes.exists(_.symbol == sym)) sym + if (maybeShadowsRoot && defn.RootImportTypes.exists(_.symbol == sym)) sym else NoSymbol } diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 1b6e437b5..068ef3e4b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -373,8 +373,13 @@ class Namer { typer: Typer => } /** A new context that summarizes an import statement */ - def importContext(sym: Symbol, selectors: List[Tree])(implicit ctx: Context) = - ctx.fresh.setImportInfo(new ImportInfo(sym, selectors)) + def importContext(imp: Import, sym: Symbol)(implicit ctx: Context) = { + val impNameOpt = imp.expr match { + case ref: RefTree => Some(ref.name.asTermName) + case _ => None + } + ctx.fresh.setImportInfo(new ImportInfo(sym, imp.selectors, impNameOpt)) + } /** A new context for the interior of a class */ def inClassContext(selfInfo: DotClass /* Should be Type | Symbol*/)(implicit ctx: Context): Context = { @@ -423,7 +428,7 @@ class Namer { typer: Typer => setDocstring(pkg, stat) ctx case imp: Import => - importContext(createSymbol(imp), imp.selectors) + importContext(imp, createSymbol(imp)) case mdef: DefTree => val sym = enterSymbol(createSymbol(mdef)) setDocstring(sym, origStat) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a053a0b0d..d05a0aaa7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1588,7 +1588,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case (imp: untpd.Import) :: rest => val imp1 = typed(imp) buf += imp1 - traverse(rest)(importContext(imp1.symbol, imp.selectors)) + traverse(rest)(importContext(imp, imp1.symbol)) case (mdef: untpd.DefTree) :: rest => mdef.removeAttachment(ExpandedTree) match { case Some(xtree) => |