diff options
author | Martin Odersky <odersky@gmail.com> | 2008-08-07 17:16:59 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-08-07 17:16:59 +0000 |
commit | aa1f5a76e4b16035328444cd12e3bc35cc864b09 (patch) | |
tree | 81b60c8f66a490ce94ca5ccb49ecb1cf81d2b99e /src | |
parent | 6de93c661f06eac429a1fee6677f408c562534b2 (diff) | |
download | scala-aa1f5a76e4b16035328444cd12e3bc35cc864b09.tar.gz scala-aa1f5a76e4b16035328444cd12e3bc35cc864b09.tar.bz2 scala-aa1f5a76e4b16035328444cd12e3bc35cc864b09.zip |
fixed #1127
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 33 |
2 files changed, 33 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 760cb819ca..5142ebad4e 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -618,7 +618,7 @@ abstract class ClassfileParser { val sig = pool.getExternalName(in.nextChar) val newType = sigToType(sym, sig) sym.setInfo(newType) - if (settings.debug.value) + if (settings.debug.value && settings.verbose.value) println("" + sym + "; signature = " + sig + " type = " + newType) hasMeta = true } else diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 486dc1c36c..c64aa4c36c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3033,7 +3033,7 @@ trait Typers { self: Analyzer => // begin typed1 implicit val scopeKind = TypedScopeKind val sym: Symbol = tree.symbol - if (sym ne null) sym.initialize + if ((sym ne null) && (sym ne NoSymbol)) sym.initialize //if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG tree match { case PackageDef(name, stats) => @@ -3631,7 +3631,38 @@ trait Typers { self: Analyzer => (info1 != NoImplicitInfo) && isStrictlyMoreSpecific(info1.tpe, info2.tpe) val shadowed = new HashSet[Name](8) + def hasExplicitResultType(tree: Tree) = tree match { + case ValDef(_, _, tpt, _) => !tpt.isEmpty + case DefDef(_, _, _, _, tpt, _) => !tpt.isEmpty + case _ => false + } + /** Should implicit definition symbol `sym' be considered for applicability testing? + * This is the case if one of the following holds: + * - the symbol's type is initialized + * - the symbol comes from a classfile + * - the symbol comes from a different sourcefile than the current one + * - the symbol's definition comes before, and does not contain the closest enclosing definition, + * - the symbol's definition is a val, var, or def with an explicit result type + * The aim of this method is to prevent premature cyclic reference errors + * by computing the types of only those implicitis for which one of these + * conditions is true. + */ + def isValid(sym: Symbol) = { + sym.isInitialized || + sym.sourceFile == null || + (sym.sourceFile ne context.unit.source.file) || { + sym.rawInfo match { + case tc: TypeCompleter => hasExplicitResultType(tc.tree) + case PolyType(_, tc: TypeCompleter) => hasExplicitResultType(tc.tree) + case _ => true + } + } || { + sym.pos.offset.getOrElse(0) < context.owner.pos.offset.getOrElse(Integer.MAX_VALUE) && + !(context.owner.ownerChain contains sym) + } + } def isApplicable(info: ImplicitInfo): Boolean = + isValid(info.sym) && !containsError(info.tpe) && !(isLocal && shadowed.contains(info.name)) && (!isView || info.sym != Predef_identity) && |