Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 282435d

Browse files
No mixin forwarder when ancestor is sealed
1 parent 5429b1f commit 282435d

File tree

7 files changed

+46
-13
lines changed

7 files changed

+46
-13
lines changed

‎compiler/src/dotty/tools/dotc/config/ScalaSettings.scala‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ private sealed trait XSettings:
360360
AdvancedSetting,
361361
name = "Xmixin-force-forwarders",
362362
helpArg = "mode",
363-
descr = "Generate forwarder methods in classes inhering concrete methods from traits.",
363+
descr = "Generate forwarder methods in classes inheriting concrete methods from traits.",
364364
choices = List("true", "junit", "false"),
365365
default = "true")
366366

‎compiler/src/dotty/tools/dotc/transform/Mixin.scala‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ object Mixin {
9595
* <mods> def x_=(y: T) = ()
9696
*
9797
* 4.5 (done in `mixinForwarders`) For every method
98-
* `<mods> def f[Ts](ps1)...(psN): U` imn M` that needs to be disambiguated:
98+
* `<mods> def f[Ts](ps1)...(psN): U` in M` that needs to be disambiguated:
9999
*
100100
* <mods> def f[Ts](ps1)...(psN): U = super[M].f[Ts](ps1)...(psN)
101101
*

‎compiler/src/dotty/tools/dotc/transform/MixinOps.scala‎

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,39 @@ class MixinOps(cls: ClassSymbol, thisPhase: DenotTransformer)(using Context) {
4747
cls.info.nonPrivateMember(sym.name).hasAltWith(_.symbol == sym)
4848
}
4949

50-
/** Does `method` need a forwarder to in class `cls`
51-
* Method needs a forwarder in those cases:
50+
/** Does `method` need a forwarder in class `cls`?
51+
* Method needs a forwarder in these cases:
5252
* - there's a class defining a method with same signature
5353
* - there are multiple traits defining method with same signature
5454
*/
55-
def needsMixinForwarder(meth: Symbol): Boolean = {
55+
def needsMixinForwarder(meth: Symbol): Boolean =
5656
lazy val competingMethods = competingMethodsIterator(meth).toList
5757

58-
def needsDisambiguation = competingMethods.exists(x=>!x.is(Deferred)) // multiple implementations are available
58+
def needsDisambiguation = competingMethods.exists(!_.is(Deferred)) // multiple implementations are available
5959
def hasNonInterfaceDefinition = competingMethods.exists(!_.owner.is(Trait)) // there is a definition originating from class
6060

6161
// JUnit 4 won't recognize annotated default methods, so always generate a forwarder for them.
6262
def generateJUnitForwarder: Boolean =
63-
meth.annotations.nonEmpty && JUnit4Annotations.exists(annot =>meth.hasAnnotation(annot)) &&
63+
meth.annotations.nonEmpty && JUnit4Annotations.exists(meth.hasAnnotation) &&
6464
ctx.settings.mixinForwarderChoices.isAtLeastJunit
6565

6666
// Similarly, Java serialization won't take into account a readResolve/writeReplace default method.
6767
def generateSerializationForwarder: Boolean =
6868
(meth.name == nme.readResolve || meth.name == nme.writeReplace) && meth.info.paramNamess.flatten.isEmpty
6969

70-
!meth.isConstructor &&
71-
meth.is(Method, butNot = PrivateOrAccessorOrDeferred) &&
72-
(ctx.settings.mixinForwarderChoices.isTruthy || meth.owner.is(Scala2x) || needsDisambiguation || hasNonInterfaceDefinition ||
73-
generateJUnitForwarder || generateSerializationForwarder) &&
74-
isInImplementingClass(meth)
75-
}
70+
!meth.isConstructor
71+
&& meth.is(Method, butNot = PrivateOrAccessorOrDeferred)
72+
&& (!meth.is(JavaDefined) || !meth.owner.is(Sealed) || meth.owner.children.contains(cls))
73+
&& (
74+
ctx.settings.mixinForwarderChoices.isTruthy
75+
|| meth.owner.is(Scala2x)
76+
|| needsDisambiguation
77+
|| hasNonInterfaceDefinition
78+
|| generateJUnitForwarder
79+
|| generateSerializationForwarder
80+
)
81+
&& isInImplementingClass(meth)
82+
end needsMixinForwarder
7683

7784
final val PrivateOrAccessor: FlagSet = Private | Accessor
7885
final val PrivateOrAccessorOrDeferred: FlagSet = Private | Accessor | Deferred

‎tests/run/i23479/NonSeal.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// test: -jvm 17+
2+
public non-sealed interface NonSeal extends Seal {
3+
}

‎tests/run/i23479/Seal.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
public sealed interface Seal permits NonSeal {
3+
default int g() {
4+
return 42;
5+
}
6+
}

‎tests/run/i23479/test.scala‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// scalajs: --skip
2+
class C() extends NonSeal
3+
4+
@main def Test = C()

‎tests/run/i23479b.scala‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// scalajs: --skip
2+
trait Ord[A]
3+
4+
object Ord:
5+
sealed trait Rev[A] extends Ord[A]:
6+
def reverse: Rev[A] = this
7+
8+
trait IntOrd extends Ord[Int]
9+
10+
object Int extends IntOrd with Rev[Int]
11+
12+
@main def Test =
13+
assert(Ord.Int.getClass.getDeclaredMethods.map(_.getName).toList.contains("reverse"))

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /