aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-11-09 22:42:06 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-01 13:55:12 +0100
commit36f9133ff52c39660cd9fef37140f2f14531d678 (patch)
treea41b3c34f8ef77e54de2c99ec49c82370080c3d9 /compiler/src
parent34690395dd86c9e31eb38f73df35a5ebaf3b2c80 (diff)
downloaddotty-36f9133ff52c39660cd9fef37140f2f14531d678.tar.gz
dotty-36f9133ff52c39660cd9fef37140f2f14531d678.tar.bz2
dotty-36f9133ff52c39660cd9fef37140f2f14531d678.zip
Fix import disabling
It was broken before, since it worked only on wildcard imports.
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Contexts.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ImportInfo.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala38
3 files changed, 35 insertions, 23 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala
index ac722f390..909cebcc7 100644
--- a/compiler/src/dotty/tools/dotc/core/Contexts.scala
+++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala
@@ -216,8 +216,8 @@ object Contexts {
else if (isNonEmptyScopeContext) scope.implicitDecls
else Nil
val outerImplicits =
- if (isImportContext && importInfo.hiddenRoot.exists)
- outer.implicits exclude importInfo.hiddenRoot
+ if (isImportContext && importInfo.unimported.exists)
+ outer.implicits exclude importInfo.unimported
else
outer.implicits
if (implicitRefs.isEmpty) outerImplicits
diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
index 3aa289181..b4ec3390e 100644
--- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -95,14 +95,22 @@ class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], val isRootImp
/** The root import symbol hidden by this symbol, or NoSymbol if no such symbol is hidden.
* Note: this computation needs to work even for un-initialized import infos, and
* is not allowed to force initialization.
+ *
+ * TODO: Once we have fully bootstrapped, I would prefer if we expressed
+ * unimport with an `override` modifier, and generalized it to all imports.
+ * I believe this would be more transparent than the curren set of conditions. E.g.
+ *
+ * override import Predef.{any2stringAdd => _, StringAdd => _, _} // disables String +
+ * override import java.lang.{} // disables all imports
*/
- lazy val hiddenRoot: Symbol = {
- val sym = site.termSymbol
- def hasMaskingSelector = selectors exists {
+ lazy val unimported: Symbol = {
+ lazy val sym = site.termSymbol
+ val hasMaskingSelector = selectors exists {
case Thicket(_ :: Ident(nme.WILDCARD) :: Nil) => true
case _ => false
}
- if ((defn.RootImportTypes exists (_.symbol == sym)) && hasMaskingSelector) sym else NoSymbol
+ if (hasMaskingSelector && defn.RootImportTypes.exists(_.symbol == sym)) sym
+ else NoSymbol
}
override def toString = {
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 6c876858b..165d2e266 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -74,7 +74,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* Note: It would be more proper to move importedFromRoot into typedIdent.
* We should check that this has no performance degradation, however.
*/
- private var importedFromRoot: Set[Symbol] = Set()
+ private var unimported: Set[Symbol] = Set()
/** Temporary data item for single call to typed ident:
* This symbol would be found under Scala2 mode, but is not
@@ -102,15 +102,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
def error(msg: => Message, pos: Position) = ctx.error(msg, pos)
- /** Is this import a root import that has been shadowed by an explicit
- * import in the same program?
- */
- def isDisabled(imp: ImportInfo, site: Type): Boolean = {
- if (imp.isRootImport && (importedFromRoot contains site.termSymbol)) return true
- if (imp.hiddenRoot.exists) importedFromRoot += imp.hiddenRoot
- false
- }
-
/** Does this identifier appear as a constructor of a pattern? */
def isPatternConstr =
if (ctx.mode.isExpr && (ctx.outer.mode is Mode.Pattern))
@@ -201,7 +192,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def selection(name: Name) =
- if (imp.sym.isCompleting) {
+ if (unimported.contains(imp.site.termSymbol))
+ NoType
+ else if (imp.sym.isCompleting) {
ctx.warning(i"cyclic ${imp.sym}, ignored", tree.pos)
NoType
}
@@ -232,7 +225,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def wildImportRef(imp: ImportInfo)(implicit ctx: Context): Type = {
if (imp.isWildcardImport) {
val pre = imp.site
- if (!isDisabled(imp, pre) && !(imp.excluded contains name.toTermName) && name != nme.CONSTRUCTOR) {
+ 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)
}
@@ -289,6 +284,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (result.exists) result
else { // find import
val curImport = ctx.importInfo
+ def updateUnimported() =
+ if (curImport.unimported.exists) unimported += curImport.unimported
if (ctx.owner.is(Package) && curImport != null && curImport.isRootImport && previous.exists)
previous // no more conflicts possible in this case
else if (isPossibleImport(namedImport) && (curImport ne outer.importInfo)) {
@@ -299,8 +296,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val wildImp = wildImportRef(curImport)
if (wildImp.exists)
findRef(checkNewOrShadowed(wildImp, wildImport), wildImport, ctx)(outer)
- else loop(outer)
- } else loop(outer)
+ else {
+ updateUnimported()
+ loop(outer)
+ }
+ }
+ else {
+ updateUnimported()
+ loop(outer)
+ }
}
else loop(outer)
}
@@ -321,9 +325,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
val rawType = {
- val saved1 = importedFromRoot
+ val saved1 = unimported
val saved2 = foundUnderScala2
- importedFromRoot = Set.empty
+ unimported = Set.empty
foundUnderScala2 = NoType
try {
var found = findRef(NoType, BindingPrec.nothingBound, NoContext)
@@ -337,7 +341,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
found
}
finally {
- importedFromRoot = saved1
+ unimported = saved1
foundUnderScala2 = saved2
}
}