Skip to content

Commit 2c0b021

Browse files
authored
Fix Java record problems (#19578) and (#19386) (#19583)
This is a dependency of #19577 and should be reviewed and merged first. fixes #18639 fixes #19386 fixes #19578
2 parents 7bcfce2 + 5be6fac commit 2c0b021

File tree

8 files changed

+25
-8
lines changed

8 files changed

+25
-8
lines changed

compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -854,13 +854,13 @@ object JavaParsers {
854854

855855
val accessors =
856856
(for (name, (tpt, annots)) <- fieldsByName yield
857-
DefDef(name, Nil, tpt, unimplementedExpr)
857+
DefDef(name, List(Nil), tpt, unimplementedExpr)
858858
.withMods(Modifiers(Flags.JavaDefined | Flags.Method | Flags.Synthetic))
859859
).toList
860860

861861
// generate the canonical constructor
862862
val canonicalConstructor =
863-
DefDef(nme.CONSTRUCTOR, joinParams(tparams, List(header)), TypeTree(), EmptyTree)
863+
DefDef(nme.CONSTRUCTOR, joinParams(Nil, List(header)), TypeTree(), EmptyTree)
864864
.withMods(Modifiers(Flags.JavaDefined | Flags.Synthetic, mods.privateWithin))
865865

866866
// return the trees
@@ -872,7 +872,7 @@ object JavaParsers {
872872
tparams = tparams,
873873
needsDummyConstr = true
874874
)
875-
).withMods(mods)
875+
).withMods(mods.withFlags(Flags.JavaDefined | Flags.Final))
876876
}
877877
addCompanionObject(statics, recordTypeDef)
878878
end recordDecl

compiler/src/dotty/tools/dotc/typer/Namer.scala

+7-3
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,10 @@ class Namer { typer: Typer =>
879879
* with a user-defined method in the same scope with a matching type.
880880
*/
881881
private def invalidateIfClashingSynthetic(denot: SymDenotation): Unit =
882+
883+
def isJavaRecord(owner: Symbol) =
884+
owner.is(JavaDefined) && owner.derivesFrom(defn.JavaRecordClass)
885+
882886
def isCaseClassOrCompanion(owner: Symbol) =
883887
owner.isClass && {
884888
if (owner.is(Module)) owner.linkedClass.is(CaseClass)
@@ -902,9 +906,9 @@ class Namer { typer: Typer =>
902906
&& (definesMember || inheritsConcreteMember)
903907
)
904908
||
905-
// remove synthetic constructor of a java Record if it clashes with a non-synthetic constructor
906-
(denot.isConstructor
907-
&& denot.owner.is(JavaDefined) && denot.owner.derivesFrom(defn.JavaRecordClass)
909+
// remove synthetic constructor or method of a java Record if it clashes with a non-synthetic constructor
910+
(isJavaRecord(denot.owner)
911+
&& denot.is(Method)
908912
&& denot.owner.unforcedDecls.lookupAll(denot.name).exists(c => c != denot.symbol && c.info.matches(denot.info))
909913
)
910914
)

compiler/src/dotty/tools/dotc/typer/Typer.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2548,10 +2548,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
25482548
def canBeInvalidated(sym: Symbol): Boolean =
25492549
sym.is(Synthetic)
25502550
&& (desugar.isRetractableCaseClassMethodName(sym.name) ||
2551-
(sym.isConstructor && sym.owner.derivesFrom(defn.JavaRecordClass)))
2551+
(sym.owner.is(JavaDefined) && sym.owner.derivesFrom(defn.JavaRecordClass) && sym.is(Method)))
25522552

25532553
if !sym.info.exists then
2554-
// it's a discarded method (synthetic case class method or synthetic java record constructor), drop it
2554+
// it's a discarded method (synthetic case class method or synthetic java record constructor or overriden member), drop it
25552555
assert(canBeInvalidated(sym))
25562556
sym.owner.info.decls.openForMutations.unlink(sym)
25572557
return EmptyTree
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def test(r: R1): Unit =
2+
val i: Int = r.i()

tests/pos-java16+/i19386/R1.java

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public record R1(int i) {}

tests/pos-java16+/java-records/FromScala.scala

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
object C:
2+
3+
def useR0: Unit =
4+
val r = R0()
5+
26
def useR1: Unit =
37
// constructor signature
48
val r = R1(123, "hello")
@@ -41,3 +45,7 @@ object C:
4145
val l2: Long = r3.l(43L, 44L)
4246
// supertype
4347
val isRecord: java.lang.Record = r3
48+
49+
def useR4: Unit =
50+
val r4 = R4(1)
51+
val i: Int = r4.t
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public record R0() {}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public record R4<T>(T t) {}

0 commit comments

Comments
 (0)