diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/RefChecks.scala | 20 |
2 files changed, 24 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index c543a5a0c..a6fce8eee 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -714,20 +714,29 @@ object SymDenotations { /** The non-private symbol whose name and type matches the type of this symbol * in the given class. - * @param inClass The class containing the symbol's definition + * @param inClass The class containing the result symbol's definition * @param site The base type from which member types are computed * * inClass <-- find denot.symbol class C { <-- symbol is here * * site: Subtype of both inClass and C */ - final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = { + final def matchingDecl(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = { var denot = inClass.info.nonPrivateDecl(name) if (denot.isTerm) // types of the same name always match denot = denot.matchingDenotation(site, site.memberInfo(symbol)) denot.symbol } + /** The non-private member of `site` whose name and type matches the type of this symbol + */ + final def matchingMember(site: Type)(implicit ctx: Context): Symbol = { + var denot = site.nonPrivateMember(name) + if (denot.isTerm) // types of the same name always match + denot = denot.matchingDenotation(site, site.memberInfo(symbol)) + denot.symbol + } + /** If false, this symbol cannot possibly participate in an override, * either as overrider or overridee. */ @@ -737,7 +746,7 @@ object SymDenotations { /** The symbol, in class `inClass`, that is overridden by this denotation. */ final def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = if (!canMatchInheritedSymbols && (owner ne inClass)) NoSymbol - else matchingSymbol(inClass, owner.thisType) + else matchingDecl(inClass, owner.thisType) /** All symbols overriden by this denotation. */ final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] = @@ -757,7 +766,7 @@ object SymDenotations { * @param ofclazz is a subclass of this symbol's owner */ final def overridingSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = - if (canMatchInheritedSymbols) matchingSymbol(inClass, inClass.thisType) + if (canMatchInheritedSymbols) matchingDecl(inClass, inClass.thisType) else NoSymbol /** The symbol accessed by a super in the definition of this symbol when @@ -767,7 +776,7 @@ object SymDenotations { final def superSymbolIn(base: Symbol)(implicit ctx: Context): Symbol = { def loop(bcs: List[ClassSymbol]): Symbol = bcs match { case bc :: bcs1 => - val sym = matchingSymbol(bcs.head, base.thisType) + val sym = matchingDecl(bcs.head, base.thisType) .suchThat(alt => !(alt is Deferred)).symbol if (sym.exists) sym else loop(bcs.tail) case _ => diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala index 23a810638..85e4696ef 100644 --- a/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/src/dotty/tools/dotc/typer/RefChecks.scala @@ -17,6 +17,7 @@ import scala.util.{Try, Success, Failure} import config.{ScalaVersion, NoScalaVersion} import typer.ErrorReporting._ import DenotTransformers._ +import ValueClasses.isDerivedValueClass object RefChecks { import tpd._ @@ -296,7 +297,7 @@ object RefChecks { printMixinOverrideErrors() // Verifying a concrete class has nothing unimplemented. - if (!clazz.is(Abstract)) { + if (!clazz.is(AbstractOrTrait)) { val abstractErrors = new mutable.ListBuffer[String] def abstractErrorMessage = // a little formatting polish @@ -348,8 +349,8 @@ object RefChecks { val missingMethods = grouped.toList flatMap { case (name, syms) => - if (syms exists (_.symbol.isSetter)) syms filterNot (_.symbol.isGetter) - else syms + val withoutSetters = syms filterNot (_.symbol.isSetter) + if (withoutSetters.nonEmpty) withoutSetters else syms } def stubImplementations: List[String] = { @@ -461,7 +462,7 @@ object RefChecks { def checkNoAbstractDecls(bc: Symbol): Unit = { for (decl <- bc.info.decls) { if (decl.is(Deferred) && !ignoreDeferred(decl)) { - val impl = decl.matchingSymbol(bc, clazz.thisType) + val impl = decl.matchingMember(clazz.thisType) if (impl == NoSymbol || (decl.owner isSubClass impl.owner)) { abstractClassError(false, "there is a deferred declaration of " + infoString(decl) + " which is not implemented in a subclass" + err.abstractVarMessage(decl)) @@ -485,7 +486,7 @@ object RefChecks { // Have to use matchingSymbol, not a method involving overridden symbols, // because the scala type system understands that an abstract method here does not // override a concrete method in Object. The jvm, however, does not. - val overridden = decl.matchingSymbol(defn.ObjectClass, defn.ObjectType) + val overridden = decl.matchingDecl(defn.ObjectClass, defn.ObjectType) if (overridden.is(Final)) ctx.error("trait cannot redefine final method from class AnyRef", decl.pos) } @@ -605,7 +606,7 @@ object RefChecks { /** Verify classes extending AnyVal meet the requirements */ private def checkAnyValSubclass(clazz: Symbol)(implicit ctx: Context) = - if (clazz.isDerivedValueClass) { + if (isDerivedValueClass(clazz)) { if (clazz.is(Trait)) ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos) else if (clazz.is(Abstract)) @@ -632,7 +633,7 @@ object RefChecks { var refSym: Symbol = _ override def enterReference(sym: Symbol, pos: Position): Unit = - if (sym.owner.isTerm) + if (sym.exists && sym.owner.isTerm) levelAndIndex.get(sym) match { case Some((level, idx)) if (level.maxIndex < idx) => level.maxIndex = idx @@ -676,7 +677,7 @@ class RefChecks extends MiniPhase with IdentityDenotTransformer { thisTransforme class Transform(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform { def phase = thisTransformer override def prepareForStats(trees: List[Tree])(implicit ctx: Context) = { - println(i"preparing for $trees%; %, owner = ${ctx.owner}") + // println(i"preparing for $trees%; %, owner = ${ctx.owner}") if (ctx.owner.isTerm) new Transform(new LevelInfo(currentLevel.levelAndIndex, trees)) else this } @@ -706,7 +707,7 @@ class RefChecks extends MiniPhase with IdentityDenotTransformer { thisTransforme checkOverloadedRestrictions(cls) checkAllOverrides(cls) checkAnyValSubclass(cls) - if (cls.isDerivedValueClass) + if (isDerivedValueClass(cls)) cls.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisTransformer) // SI-6601, must be done *after* pickler! tree } @@ -721,7 +722,6 @@ class RefChecks extends MiniPhase with IdentityDenotTransformer { thisTransforme } override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = { - assert(ctx.phase.exists) checkUndesiredProperties(tree.symbol, tree.pos) currentLevel.enterReference(tree.symbol, tree.pos) tree |