diff options
Diffstat (limited to 'compiler/src/dotty')
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/Contexts.scala | 4 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/ImportInfo.scala | 16 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Typer.scala | 38 |
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 } } |