From 99d397d7a02a2ad3aed07e8c48a60bd32564ea62 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 16 Sep 2015 18:54:02 +0200 Subject: [PATCH 1/5] Better diagnostic for weaker access errors Fix typo, and print infos alongside fully qualified names. --- src/dotty/tools/dotc/transform/ExpandPrivate.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/src/dotty/tools/dotc/transform/ExpandPrivate.scala index 11017515144c..f44be39584bb 100644 --- a/src/dotty/tools/dotc/transform/ExpandPrivate.scala +++ b/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -45,7 +45,7 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t } val fail = sym.allOverriddenSymbols.findSymbol(x => !hasWeakerAccess(x)) if (fail.exists) { - assert(false, i"${sym.showFullName} has weaker access that superclass method ${fail.showFullName}") + assert(false, i"${sym.showFullName}: ${sym.info} has weaker access than superclass method ${fail.showFullName}: ${fail.info}") } case _ => } From 7ee013745699029830a822d0b9e1e8862eaa0b8c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 16 Sep 2015 18:55:05 +0200 Subject: [PATCH 2/5] Fix weaker access error when generating bridges A bridge cannot have weaker access than the symbol it overrides. This triggered an assertion error on "clone" for pos/t2183.scala. --- src/dotty/tools/dotc/transform/Erasure.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 8b4c6a87db19..b1c8969976a5 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -625,8 +625,10 @@ object Erasure extends TypeTestsCasts{ assert(false, s"failure creating bridge from ${newDefSym} to ${parentSym}, reason: $reason") ??? } + var excluded = NoBridgeFlags + if (!newDefSym.is(Flags.Protected)) excluded |= Flags.Protected // needed to avoid "weaker access" assertion failures in expandPrivate val bridge = ctx.newSymbol(currentClass, - parentSym.name, parentSym.flags &~ NoBridgeFlags | Flags.Bridge, parentSym.info, coord = newDefSym.owner.coord).asTerm + parentSym.name, parentSym.flags &~ excluded | Flags.Bridge, parentSym.info, coord = newDefSym.owner.coord).asTerm bridge.enteredAfter(ctx.phase.prev.asInstanceOf[DenotTransformer]) // this should be safe, as we're executing in context of next phase ctx.debuglog(s"generating bridge from ${newDefSym} to $bridge") From 50e3a7d92f4b7cc4cd922eb92c7ed8bf793b159c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 17 Sep 2015 12:01:29 +0200 Subject: [PATCH 3/5] New phase: ExplicitSelf Makes self types explicit, if this is needed to identify a member in a select. Fixes #789. --- src/dotty/tools/dotc/Compiler.scala | 1 + src/dotty/tools/dotc/core/Types.scala | 5 ++- .../tools/dotc/transform/ExplicitSelf.scala | 37 +++++++++++++++++++ tests/run/i789.check | 1 + tests/run/i789.scala | 20 ++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/dotty/tools/dotc/transform/ExplicitSelf.scala create mode 100644 tests/run/i789.check create mode 100644 tests/run/i789.scala diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index c537d8885a99..a36743b59a03 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -52,6 +52,7 @@ class Compiler { new ClassOf), List(new PatternMatcher, new ExplicitOuter, + new ExplicitSelf, new Splitter), List(new VCInlineMethods, new SeqLiterals, diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index d04da30c07a6..358720836787 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2530,7 +2530,7 @@ object Types { def selfType(implicit ctx: Context): Type = { if (selfTypeCache == null) selfTypeCache = { - def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams) + def fullRef = fullyAppliedRef val given = givenSelfType val raw = if (!given.exists) fullRef @@ -2561,6 +2561,9 @@ object Types { base } + /** The class type with all type parameters */ + def fullyAppliedRef(implicit ctx: Context): Type = fullyAppliedRef(cls.typeRef, cls.typeParams) + def rebase(tp: Type)(implicit ctx: Context): Type = if ((prefix eq cls.owner.thisType) || !cls.owner.isClass || ctx.erasedTypes) tp else tp.substThis(cls.owner.asClass, prefix) diff --git a/src/dotty/tools/dotc/transform/ExplicitSelf.scala b/src/dotty/tools/dotc/transform/ExplicitSelf.scala new file mode 100644 index 000000000000..c6a2181576e7 --- /dev/null +++ b/src/dotty/tools/dotc/transform/ExplicitSelf.scala @@ -0,0 +1,37 @@ +package dotty.tools.dotc +package transform + +import core._ +import Contexts.Context +import Types._ +import TreeTransforms._ +import Decorators._ +import ast.Trees._ +import Flags._ + +/** Transform references of the form + * + * C.this.m + * + * where `C` is a class with explicit self type and `C` is not a + * subclass of the owner of `m` to + * + * C.this.asInstanceOf[S].m + * + * where `S` is the self type of `C`. + */ +class ExplicitSelf extends MiniPhaseTransform { thisTransform => + import ast.tpd._ + + override def phaseName = "explicitSelf" + + override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = tree match { + case Select(thiz: This, name) if name.isTermName => + val cls = thiz.symbol.asClass + val cinfo = cls.classInfo + if (cinfo.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner)) + cpy.Select(tree)(thiz.asInstance(cinfo.selfType), name) + else tree + case _ => tree + } +} diff --git a/tests/run/i789.check b/tests/run/i789.check new file mode 100644 index 000000000000..d41f69423581 --- /dev/null +++ b/tests/run/i789.check @@ -0,0 +1 @@ +atPhase: 2 diff --git a/tests/run/i789.scala b/tests/run/i789.scala new file mode 100644 index 000000000000..99b081f0a8e7 --- /dev/null +++ b/tests/run/i789.scala @@ -0,0 +1,20 @@ + trait Periods { self: Context => + + def atPhase(id: Int): Unit = println(s"atPhase: $id") + + } + + class Phase(val id: Int) + + trait Phases { self: Context => + def atPhase(phase: Phase): Unit = self.atPhase(phase.id) + } + + trait Context extends Phases with Periods + + object Test extends Context { + + def main(args: Array[String]) = atPhase(new Phase(2)) + + } + From 4966589b7d09f1650bf2df461ba3c6461552a0e3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 15 Sep 2015 18:11:35 +0200 Subject: [PATCH 4/5] Fix #791 erasedLub of two AnyVals is Object. --- src/dotty/tools/dotc/core/TypeErasure.scala | 6 +++++- tests/run/OrType.scala | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/run/OrType.scala diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala index 0ef31015c2de..f27b2fd1ea5f 100644 --- a/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/src/dotty/tools/dotc/core/TypeErasure.scala @@ -234,7 +234,11 @@ object TypeErasure { case nil => bestSoFar } - loop(tp1.baseClasses, defn.ObjectClass).typeRef + val t = loop(tp1.baseClasses, defn.ObjectClass) + if (t eq defn.AnyValClass) + // while AnyVal is a valid common super class for primitives it does not exist after erasure + defn.ObjectType + else t.typeRef } } diff --git a/tests/run/OrType.scala b/tests/run/OrType.scala new file mode 100644 index 000000000000..9ab805defbde --- /dev/null +++ b/tests/run/OrType.scala @@ -0,0 +1,11 @@ +class B(val x: Int) +class C(val x: Double) + +object Test{ + def bar(x: B | C): Int | Double = x.x + def main(args: Array[String]): Unit = { + val b = new B(1) + val c = new C(1) + bar(if (b.hashCode > c.hashCode) b else c) + } +} From 41b8853ca9a8327c65cb96a8ffccb5491d53edda Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 17 Sep 2015 13:02:49 +0200 Subject: [PATCH 5/5] Harmaonize numeric arguments only during typer. Afterwards, implicit conversions are no longer available. Fixes #791. --- src/dotty/tools/dotc/typer/Applications.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index c45db4ccc827..40029c42b805 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -1117,7 +1117,7 @@ trait Applications extends Compatibility { self: Typer => case cdef: CaseDef => tpd.cpy.CaseDef(cdef)(body = adapt(cdef.body, pt)) case _ => adaptInterpolated(tree, pt, tree) } - harmonizeWith(trees)(_.tpe, adapt) + if (ctx.isAfterTyper) trees else harmonizeWith(trees)(_.tpe, adapt) } /** If all `types` are numeric value types, and they are not all the same type,