diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 0df10a1035bb..5a14dfa316c4 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1196,6 +1196,7 @@ object SymDenotations { isOneOf(EffectivelyFinalFlags) || is(Inline, butNot = Deferred) || is(JavaDefinedVal, butNot = Method) + || isConstructor || !owner.isExtensibleClass /** A class is effectively sealed if has the `final` or `sealed` modifier, or it diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index c00ec5eec64d..6ca2e993209c 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -703,7 +703,7 @@ object Types { } findMember(name, pre, required, excluded) } - + /** The implicit members with given name. If there are none and the denotation * contains private members, also look for shadowed non-private implicits. */ @@ -2583,6 +2583,7 @@ object Types { (symd.isAbstractType || symd.isTerm && !symd.flagsUNSAFE.isOneOf(Module | Final | Param) + && !symd.isConstructor && !symd.maybeOwner.isEffectivelyFinal) && prefix.sameThis(symd.maybeOwner.thisType) && refines(givenSelfTypeOrCompleter(prefix.cls), symd.name) diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index de611db6c14e..c142364a8857 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -557,7 +557,7 @@ object TreeChecker { val TypeDef(_, impl @ Template(constr, _, _, _)) = cdef: @unchecked assert(cdef.symbol == cls) assert(impl.symbol.owner == cls) - assert(constr.symbol.owner == cls) + assert(constr.symbol.owner == cls, i"constr ${constr.symbol} in $cdef has wrong owner; should be $cls but is ${constr.symbol.owner}") assert(cls.primaryConstructor == constr.symbol, i"mismatch, primary constructor ${cls.primaryConstructor}, in tree = ${constr.symbol}") checkOwner(impl) checkOwner(impl.constr) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Util.scala b/compiler/src/dotty/tools/dotc/transform/init/Util.scala index ad7d2afffbaf..ec7b50d10e8e 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Util.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Util.scala @@ -75,11 +75,9 @@ object Util: case _ => None - def resolve(cls: ClassSymbol, sym: Symbol)(using Context): Symbol = log("resove " + cls + ", " + sym, printer, (_: Symbol).show) { - if (sym.isEffectivelyFinal || sym.isConstructor) sym + def resolve(cls: ClassSymbol, sym: Symbol)(using Context): Symbol = log("resove " + cls + ", " + sym, printer, (_: Symbol).show): + if sym.isEffectivelyFinal then sym else sym.matchingMember(cls.appliedRef) - } - extension (sym: Symbol) def hasSource(using Context): Boolean = !sym.defTree.isEmpty diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 601dadbb58f9..6cc574751dda 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1706,7 +1706,7 @@ class RefChecks extends MiniPhase { thisPhase => // if (settings.warnNullaryUnit) // checkNullaryMethodReturnType(sym) // if (settings.warnInaccessible) { - // if (!sym.isConstructor && !sym.isEffectivelyFinal && !sym.isSynthetic) + // if (!sym.isEffectivelyFinal && !sym.isSynthetic) // checkAccessibilityOfReferencedTypes(tree) // } // tree match { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index ee8aa668296d..b0b30457bab7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3957,7 +3957,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer sym.isConstructor || sym.matchNullaryLoosely || Feature.warnOnMigration(msg, tree.srcPos, version = `3.0`) - && { + && { msg.actions .headOption .foreach(Rewrites.applyAction) diff --git a/tests/pos/i18160/Test_2.scala b/tests/pos/i18160/Test_2.scala new file mode 100644 index 000000000000..9ee40c3d37f9 --- /dev/null +++ b/tests/pos/i18160/Test_2.scala @@ -0,0 +1,11 @@ +class SynchronizedReevaluation +class SynchronizedReevaluationApi[Api <: RescalaInterface](val api: Api){ + import api._ + + def SynchronizedReevaluation[A](evt: Event[A])(implicit + turnSource: CreationTicket + ): (SynchronizedReevaluation, Event[A]) = { + val sync = new SynchronizedReevaluation + (sync, evt.map(identity)(turnSource)) + } +} diff --git a/tests/pos/i18160/repro_1.scala b/tests/pos/i18160/repro_1.scala new file mode 100644 index 000000000000..060f2d325d2d --- /dev/null +++ b/tests/pos/i18160/repro_1.scala @@ -0,0 +1,25 @@ +object core { + final class CreationTicket[State[_]] +} + +trait ReadAs[S[_], +A] { type State[V] = S[V] } + +trait EventCompatBundle { + bundle: Operators => + + trait EventCompat[+T] extends ReadAs[State, Option[T]] { + selfType: Event[T] => + final inline def map[B](inline expression: T => B)(implicit ticket: CreationTicket): Event[B] = ??? + } +} + +trait EventBundle extends EventCompatBundle { self: Operators => + trait Event[+T] extends EventCompat[T]: + final override type State[V] = self.State[V] +} +trait Operators extends EventBundle { + type State[_] + type CreationTicket = core.CreationTicket[State] +} +trait RescalaInterface extends Operators +