From 841fe014a7f33c40a853eb90a77a50af0994f3e6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 15 Nov 2020 11:19:16 +0100 Subject: [PATCH] Fix #9667: Do avoidance for classbound members --- .../src/dotty/tools/dotc/core/TypeOps.scala | 11 ++++----- tests/pos/i9667.scala | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 tests/pos/i9667.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index f5814935cfb6..a2dfffd74c99 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -350,6 +350,9 @@ object TypeOps: def classBound(info: ClassInfo)(using Context): Type = { val cls = info.cls val parentType = info.parents.reduceLeft(TypeComparer.andType(_, _)) + def isRefinable(sym: Symbol) = + !sym.is(Private) && !sym.isConstructor && !sym.isClass + val (refinableDecls, missingDecls) = info.decls.toList.partition(isRefinable) def addRefinement(parent: Type, decl: Symbol) = { val inherited = @@ -360,8 +363,7 @@ object TypeOps: val isPolyFunctionApply = decl.name == nme.apply && (parent <:< defn.PolyFunctionType) val needsRefinement = isPolyFunctionApply - || !decl.isClass - && { + || { if inheritedInfo.exists then decl.info.widenExpr <:< inheritedInfo.widenExpr && !(inheritedInfo.widenExpr <:< decl.info.widenExpr) @@ -369,8 +371,7 @@ object TypeOps: parent.derivesFrom(defn.SelectableClass) } if needsRefinement then - RefinedType(parent, decl.name, decl.info) - .showing(i"add ref $parent $decl --> " + result, typr) + RefinedType(parent, decl.name, avoid(decl.info, missingDecls)) else parent } @@ -378,8 +379,6 @@ object TypeOps: tp.subst(cls :: Nil, rt.recThis :: Nil).substThis(cls, rt.recThis) } - def isRefinable(sym: Symbol) = !sym.is(Private) && !sym.isConstructor - val refinableDecls = info.decls.filter(isRefinable) val raw = refinableDecls.foldLeft(parentType)(addRefinement) HKTypeLambda.fromParams(cls.typeParams, raw) match { case tl: HKTypeLambda => tl.derivedLambdaType(resType = close(tl.resType)) diff --git a/tests/pos/i9667.scala b/tests/pos/i9667.scala new file mode 100644 index 000000000000..a8287bf0b7bc --- /dev/null +++ b/tests/pos/i9667.scala @@ -0,0 +1,24 @@ + +def foo = new reflect.Selectable { object Foo } + +trait A { type M } + +val bar = new reflect.Selectable { + class C extends A + type B + type D = C + val x: C = ??? + val xx: x.M = ??? + val y: B = ??? + val z: C = ??? + val zz: z.M = ??? +} +val bar1: reflect.Selectable{ + type B + type D <: A + val x: A + val xx: Any + val y: this.B + val z: A + val zz: Any +} = bar \ No newline at end of file