Skip to content

Commit 33ac5e0

Browse files
committed
flag simplification, but double def errors in in strap.comp
Compiling 327 files to /Users/adriaan/git/scala/build/strap/classes/compiler /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/transform/Constructors.scala:170: warning: postfix operator toMap should be enabled by making the implicit value scala.language.postfixOps visible. This can be achieved by adding the import clause 'import scala.language.postfixOps' or by setting the compiler option -language:postfixOps. See the Scala docs for value scala.language.postfixOps for a discussion why the feature should be explicitly enabled. lazy val bodyOfOuterAccessor = defs collect { case dd: DefDef if omittableOuterAcc(dd.symbol) => dd.symbol -> dd.rhs } toMap ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/transform/Fields.scala:193: warning: postfix operator nonEmpty should be enabled by making the implicit value scala.language.postfixOps visible. if (newSetters nonEmpty) { ^ /Users/adriaan/git/scala/src/compiler/scala/reflect/macros/contexts/Context.scala:6: error: double definition: def scala$reflect$macros$Aliases$_setter_$TypeTag_=(x$1: Context.this.universe.TypeTag.type): Unit at line 6 and def scala$reflect$macros$Aliases$_setter_$TypeTag_=(x$1: Context.this.universe.TypeTag.type): Unit at line 6 have same type abstract class Context extends scala.reflect.macros.blackbox.Context ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/Global.scala:1155: error: double definition: def scala$reflect$internal$Reporting$RunReporting$_setter_$reporting_=(x$1: Global.this.PerRunReporting): Unit at line 1155 and def scala$reflect$internal$Reporting$RunReporting$_setter_$reporting_=(x$1: Global.this.PerRunReporting): Unit at line 1155 have same type class Run extends RunContextApi with RunReporting with RunParsing { ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/Properties.scala:10: error: double definition: def scala$util$PropertiesTrait$_setter_$copyrightString_=(x$1: String): Unit at line 10 and def scala$util$PropertiesTrait$_setter_$copyrightString_=(x$1: String): Unit at line 10 have same type object Properties extends scala.util.PropertiesTrait { ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala:224: error: double definition: def selfOrSuperCalls_=(x$1: scala.collection.mutable.Stack[ExplicitOuter.this.global.Symbol]): Unit at line 224 and def selfOrSuperCalls_=(x$1: scala.collection.mutable.Stack[ExplicitOuter.this.global.Symbol]): Unit at line 224 have same type abstract class OuterPathTransformer(unit: CompilationUnit) extends TypingTransformer(unit) with UnderConstructionTransformer { ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/transform/UnCurry.scala:48: error: double definition: def uncurryType_=(x$1: UnCurry.this.global.TypeMap): Unit at line 48 and def uncurryType_=(x$1: UnCurry.this.global.TypeMap): Unit at line 48 have same type abstract class UnCurry extends InfoTransform ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala:279: error: double definition: def scala$reflect$internal$Trees$TreeStackTraverser$_setter_$path_=(x$1: scala.collection.mutable.Stack[TreeCheckers.this.global.Tree]): Unit at line 279 and def scala$reflect$internal$Trees$TreeStackTraverser$_setter_$path_=(x$1: scala.collection.mutable.Stack[TreeCheckers.this.global.Tree]): Unit at line 279 have same type object precheck extends TreeStackTraverser { ^ /Users/adriaan/git/scala/src/compiler/scala/tools/nsc/util/ShowPickled.scala:18: error: double definition: def scala$reflect$internal$Names$_setter_$TypeNameTag_=(x$1: scala.reflect.ClassTag[scala.tools.nsc.util.ShowPickled.TypeName]): Unit at line 18 and def scala$reflect$internal$Names$_setter_$TypeNameTag_=(x$1: scala.reflect.ClassTag[scala.tools.nsc.util.ShowPickled.TypeName]): Unit at line 18 have same type object ShowPickled extends Names { ^ /Users/adriaan/git/scala/src/compiler/scala/tools/reflect/ReflectGlobal.scala:13: error: double definition: def scala$reflect$api$JavaUniverse$_setter_$RuntimeClassTag_=(x$1: scala.reflect.ClassTag[ReflectGlobal.this.RuntimeClass]): Unit at line 13 and def scala$reflect$api$JavaUniverse$_setter_$RuntimeClassTag_=(x$1: scala.reflect.ClassTag[ReflectGlobal.this.RuntimeClass]): Unit at line 13 have same type class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val rootClassLoader: ClassLoader) ^ /Users/adriaan/git/scala/src/compiler/scala/tools/reflect/WrappedProperties.scala:42: error: double definition: def scala$util$PropertiesTrait$_setter_$copyrightString_=(x$1: String): Unit at line 42 and def scala$util$PropertiesTrait$_setter_$copyrightString_=(x$1: String): Unit at line 42 have same type object AccessControl extends WrappedProperties { ^ two warnings found 9 errors found
1 parent ae34ac7 commit 33ac5e0

File tree

3 files changed

+86
-69
lines changed

3 files changed

+86
-69
lines changed

src/compiler/scala/tools/nsc/transform/Fields.scala

Lines changed: 82 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import symtab.Flags._
1313
/** Lift rhs out of vals, synthesize accessors and field for each (strict) val owned by a class.
1414
*
1515
* For traits:
16+
*
1617
* - Namers translates a definition `val x = rhs` into a getter `def x = rhs`
1718
* - This phase moves `rhs` into a block nested under the template's local dummy.
1819
* If the value is memoized (stored), the block's final expression assigns the value to the val,
@@ -35,21 +36,48 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
3536
/** the following two members override abstract members in Transform */
3637
val phaseName: String = "fields"
3738

38-
// TODO: replace SYNTHESIZE_IMPL_IN_SUBCLASS by (late)DEFERRED | FINAL, which would also obviate need for FINAL_TRAIT_ACCESSOR
39+
protected def newTransformer(unit: CompilationUnit): Transformer = new FieldsTransformer(unit)
40+
override def transformInfo(sym: Symbol, tp: Type): Type =
41+
if (!sym.isJavaDefined && !(sym hasFlag FINAL_TRAIT_ACCESSOR)) {
42+
sym setFlag FINAL_TRAIT_ACCESSOR // TODO: remove overloaded use of this flag, used to check hypothesis that info transformer is run re-entrantly?
43+
synthFieldsAndAccessors(tp)
44+
} else tp
45+
46+
47+
// we leave lazy vars/accessors and early-init vals alone for now
48+
private def excludedAccessorOrFieldByFlags(statSym: Symbol): Boolean = statSym hasFlag LAZY | PRESUPER
3949

4050
// used for internal communication between info and tree transform of this phase -- not pickled, not in initialflags
41-
override def phaseNewFlags: Long = NEEDS_TREES | OVERRIDDEN_TRAIT_SETTER | FINAL_TRAIT_ACCESSOR
51+
override def phaseNewFlags: Long = NEEDS_TREES | OVERRIDDEN_TRAIT_SETTER
4252

43-
protected def newTransformer(unit: CompilationUnit): Transformer =
44-
new FieldsTransformer(unit)
53+
final val TRAIT_SETTER_FLAGS = NEEDS_TREES | DEFERRED
4554

46-
def matchingAccessor(pre: Type, member: Symbol, clazz: Symbol) = {
47-
val res = member.matchingSymbol(clazz, pre) filter (sym => (sym hasFlag ACCESSOR) && (!(sym hasFlag DEFERRED) || (sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS)))
48-
// if (res != NoSymbol) println(s"matching accessor for $member in $clazz = $res (under $pre)")
49-
// else println(s"no matching accessor for $member in $clazz (under $pre) among ${clazz.info.decls}")
50-
res
55+
private def accessorImplementedInSubclass(accessor: Symbol) = accessor hasAllFlags (ACCESSOR | SYNTHESIZE_IMPL_IN_SUBCLASS)
56+
57+
private def concreteOrSynthImpl(sym: Symbol): Boolean = !(sym hasFlag DEFERRED) || (sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS)
58+
59+
private def setTraitAccessorFlags(accessor: Symbol): Unit = {
60+
accessor setFlag lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS
61+
}
62+
63+
private def setClonedTraitSetterFlags(clazz: Symbol, correspondingGetter: Symbol, cloneInSubclass: Symbol): Unit = {
64+
val overridden = isOverriddenAccessor(correspondingGetter, clazz)
65+
if (overridden) cloneInSubclass setFlag OVERRIDDEN_TRAIT_SETTER
66+
else if (correspondingGetter.isEffectivelyFinal) cloneInSubclass setFlag FINAL
5167
}
5268

69+
private def setClonedAccessorFlags(orig: Symbol, cloneInSubclass: Symbol): Unit =
70+
cloneInSubclass setFlag NEEDS_TREES resetFlag DEFERRED | lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS
71+
72+
private def setFieldFlags(accessor: Symbol, fieldInSubclass: TermSymbol): Unit =
73+
fieldInSubclass setFlag ( NEEDS_TREES |
74+
PrivateLocal
75+
| (accessor getFlag MUTABLE | LAZY)
76+
| (if (accessor.hasStableFlag) 0 else MUTABLE)
77+
)
78+
79+
80+
5381
private def isOverriddenAccessor(member: Symbol, site: Symbol): Boolean = {
5482
val pre = site.thisType
5583
@tailrec def loop (bcs: List[Symbol]): Boolean = {
@@ -60,6 +88,16 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
6088
member.exists && loop(site.info.baseClasses)
6189
}
6290

91+
92+
def matchingAccessor(pre: Type, member: Symbol, clazz: Symbol) = {
93+
val res = member.matchingSymbol(clazz, pre) filter (sym => (sym hasFlag ACCESSOR) && concreteOrSynthImpl(sym))
94+
// if (res != NoSymbol) println(s"matching accessor for $member in $clazz = $res (under $pre)")
95+
// else println(s"no matching accessor for $member in $clazz (under $pre) among ${clazz.info.decls}")
96+
res
97+
}
98+
99+
100+
63101
class FieldMemoization(accessorOrField: Symbol, site: Symbol) {
64102
private val tp = fieldTypeOfAccessorIn(accessorOrField, site.thisType)
65103
val memoized = !tp.isInstanceOf[ConstantType]
@@ -93,26 +131,28 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
93131
// NOTE: this only considers type, filter on flags first!
94132
def fieldMemoizationIn(accessorOrField: Symbol, site: Symbol) = new FieldMemoization(accessorOrField, site)
95133

96-
override def transformInfo(sym: Symbol, tp: Type): Type = if (!sym.isJavaDefined) synthFieldsAndAccessors(tp) else tp
97-
98-
private def newTraitSetter(getter: Symbol, clazz: Symbol) = {
99-
// Add setter for an immutable, memoizing getter
100-
// (can't emit during namers because we don't yet know whether it's going to be memoized or not)
101-
// TODO: any flags to inherit from getter??? (probably not -- certainly exclude: stable, override, implicit, private, local)
102-
// TODO: stable/mutable? (we need to access the setter from the init method, so it needs to be in the interface)
103-
// TODO: annotations?
104-
// TODO: ARTIFACT or SYNTHETIC?? neither?
105-
// protected, because implemented by subclass, never used outside of hierarchy
106-
val setterFlags = (getter.flags & ~(STABLE | PrivateLocal | OVERRIDE | IMPLICIT | FINAL)) | MUTABLE | ACCESSOR | NEEDS_TREES | DEFERRED
107-
val setterName = nme.expandedSetterName(getter.name.setterName, clazz)
108-
val setter = clazz.newMethod(setterName, getter.pos.focus, setterFlags)
109-
val fieldTp = fieldTypeForGetterIn(getter, clazz.thisType)
110-
// println(s"newTraitSetter in $clazz for $getter = $setterName : $fieldTp")
111-
setter setInfo MethodType(List(setter.newSyntheticValueParam(fieldTp)), UnitTpe)
112-
setter
113-
}
114134

115-
private val synthFieldsAndAccessors = new TypeMap {
135+
136+
private object synthFieldsAndAccessors extends TypeMap {
137+
private def newTraitSetter(getter: Symbol, clazz: Symbol) = {
138+
// Add setter for an immutable, memoizing getter
139+
// (can't emit during namers because we don't yet know whether it's going to be memoized or not)
140+
// TODO: any flags to inherit from getter??? (probably not -- certainly exclude: stable, override, implicit, private, local)
141+
// TODO: stable/mutable? (we need to access the setter from the init method, so it needs to be in the interface)
142+
// TODO: annotations?
143+
// TODO: ARTIFACT or SYNTHETIC?? neither?
144+
// protected, because implemented by subclass, never used outside of hierarchy
145+
val setterFlags = (getter.flags & ~(STABLE | PrivateLocal | OVERRIDE | IMPLICIT | FINAL)) | MUTABLE | ACCESSOR | TRAIT_SETTER_FLAGS
146+
val setterName = nme.expandedSetterName(getter.name.setterName, clazz)
147+
val setter = clazz.newMethod(setterName, getter.pos.focus, setterFlags)
148+
val fieldTp = fieldTypeForGetterIn(getter, clazz.thisType)
149+
150+
// println(s"newTraitSetter in $clazz for $getter = $setterName : $fieldTp")
151+
152+
setter setInfo MethodType(List(setter.newSyntheticValueParam(fieldTp)), UnitTpe)
153+
setter
154+
}
155+
116156
def apply(tp0: Type): Type = mapOver(tp0) match {
117157
// TODO: make less destructive (name changes, decl additions, flag setting --
118158
// none of this is actually undone when travelling back in time using atPhase)
@@ -124,7 +164,6 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
124164
case accessor if accessor hasFlag ACCESSOR =>
125165
// check flags before calling makeNotPrivate
126166
val memoizedGetter = !(accessor hasFlag (DEFERRED | LAZY)) && fieldMemoizationIn(accessor, clazz).needsField
127-
val finality = if (accessor hasFlag FINAL) FINAL_TRAIT_ACCESSOR else 0
128167

129168
// only affects private symbols, with a destructive update of their name, also sets flags
130169
// required for private vals in traits
@@ -142,13 +181,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
142181

143182
// derive trait setter after calling makeNotPrivate (so that names are mangled consistently)
144183
if (memoizedGetter) {
145-
// memoized trait members cannot be final (but the synthesized ones should be)
146-
accessor resetFlag (FINAL)
147-
148-
// a memoized accessor in a trait is made deferred now (mixins will deal with non-memoized getters like any other method)
149-
// can't mark getter as FINAL in trait, but remember for when we synthetisize the impl in the subclass to make it FINAL
150-
// (it'll receive an implementation in the first real class to extend this trait)
151-
accessor setFlag (finality | DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS)
184+
setTraitAccessorFlags(accessor)
152185

153186
if ((accessor hasFlag STABLE) && accessor.isGetter) // TODO: isGetter is probably redundant?
154187
newSetters += newTraitSetter(accessor, clazz)
@@ -217,31 +250,25 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
217250
// invariant: (accessorsMaybeNeedingImpl, mixedInAccessorAndFields).zipped.forall(case (acc, clone :: _) => `clone` is clone of `acc` case _ => true)
218251
val mixedInAccessorAndFields = accessorsMaybeNeedingImpl map { accessor =>
219252
def cloneAccessor() = {
220-
val clonedAccessor = (accessor cloneSymbol clazz) setPos clazz.pos setFlag NEEDS_TREES resetFlag DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS | FINAL_TRAIT_ACCESSOR
221-
if (accessor hasFlag FINAL_TRAIT_ACCESSOR) {
222-
clonedAccessor setFlag FINAL | lateFINAL // lateFINAL thrown in for good measure, by analogy to makeNotPrivate
223-
}
253+
val clonedAccessor = (accessor cloneSymbol clazz) setPos clazz.pos
254+
setClonedAccessorFlags(accessor, clonedAccessor)
255+
224256
// if we don't cloneInfo, method argument symbols are shared between trait and subclasses --> lambalift proxy crash
225257
// TODO: use derive symbol variant?
226-
227258
// println(s"cloning accessor $accessor to $clazz / $clonedInfo -> $relativeInfo")
228259
clonedAccessor setInfo ((clazz.thisType memberType accessor) cloneInfo clonedAccessor) // accessor.info.cloneInfo(clonedAccessor).asSeenFrom(clazz.thisType, accessor.owner)
229-
230260
}
231261

232262
// when considering whether to mix in the trait setter, forget about conflicts -- they will be reported for the getter
233263
// a trait setter for an overridden val will receive a unit body in the tree transform
234-
// (this is communicated using the DEFERRED flag)
235264
if (nme.isTraitSetterName(accessor.name)) {
236265
val getter = accessor.getterIn(accessor.owner)
237-
val overridden = isOverriddenAccessor(getter, clazz)
238266
// println(s"mixing in trait setter ${accessor.defString}: $overridden")
239267
val clone = cloneAccessor()
240268

241269
clone filterAnnotations (ai => !ai.matches(TraitSetterAnnotationClass)) // only supposed to be set in trait
242270

243-
if (overridden) clone setFlag OVERRIDDEN_TRAIT_SETTER
244-
else if (getter.isEffectivelyFinal) clone setFlag FINAL // TODO: why isn't the FINAL_TRAIT_ACCESSOR carry-over from getter enough?
271+
setClonedTraitSetterFlags(clazz, getter, clone)
245272
// println(s"mixed in trait setter ${clone.defString}")
246273

247274
List(clone)
@@ -251,20 +278,14 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
251278
else if (accessorConflictsExistingVal(accessor) || isOverriddenAccessor(accessor, clazz)) Nil
252279
else if (accessor.isGetter && fieldMemoizationIn(accessor, clazz).needsField) {
253280
// add field if needed
254-
255281
val field = clazz.newValue(accessor.localName, accessor.pos) setInfo fieldTypeForGetterIn(accessor, clazz.thisType)
256282

257-
val newFlags = (
258-
(PrivateLocal | NEEDS_TREES)
259-
| (accessor getFlag MUTABLE | LAZY)
260-
| (if (accessor.hasStableFlag) 0 else MUTABLE)
261-
)
283+
setFieldFlags(accessor, field)
262284

263285
// TODO: filter getter's annotations to exclude those only meant for the field
264286
// we must keep them around long enough to see them here, though, when we create the field
265287
field setAnnotations (accessor.annotations filter AnnotationInfo.mkFilter(FieldTargetClass, defaultRetention = true))
266288

267-
field setFlag newFlags
268289
List(cloneAccessor(), field)
269290
} else List(cloneAccessor())
270291
}
@@ -300,9 +321,6 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
300321
}
301322
}
302323

303-
private def accessorImplementedInSubclass(accessor: Symbol) =
304-
accessor hasAllFlags (ACCESSOR | SYNTHESIZE_IMPL_IN_SUBCLASS)
305-
306324

307325
class FieldsTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
308326
def mkTypedUnit(pos: Position) = localTyper.typedPos(pos)(CODE.UNIT)
@@ -369,7 +387,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
369387
}
370388

371389
stat match {
372-
case DefDef(_, _, _, _, _, rhs) if (rhs ne EmptyTree) && (statSym hasFlag ACCESSOR) && !(statSym hasFlag LAZY) =>
390+
case DefDef(_, _, _, _, _, rhs) if (rhs ne EmptyTree) && (statSym hasFlag ACCESSOR) && !excludedAccessorOrFieldByFlags(statSym) =>
373391
val fieldMemoization = fieldMemoizationIn(statSym, clazz)
374392
def getterRhs(x: Tree) = if (fieldMemoization.effectOnly) mkTypedUnit(statSym.pos) else EmptyTree
375393

@@ -388,16 +406,13 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
388406
) :: Nil
389407

390408
// If a val needs a field, an empty valdef and an assignment to its rhs go into the template
391-
case ValDef(mods, _, _, rhs) if (rhs ne EmptyTree) && !(statSym hasFlag LAZY) && !(mods hasFlag PRESUPER) =>
409+
case ValDef(mods, _, _, rhs) if (rhs ne EmptyTree) && !excludedAccessorOrFieldByFlags(statSym) =>
392410
val fieldMemoization = fieldMemoizationIn(statSym, clazz)
393411

394412
if (fieldMemoization.needsField) deriveValDef(stat)(_ => EmptyTree) :: initEffect(rhs, fieldMemoization.assignSym) :: Nil
395413
else if (fieldMemoization.effectOnly) initEffect(rhs, NoSymbol) :: Nil // drop the val entirely -- it could not have been referenced outside accesors
396414
else Nil
397415

398-
// case Template(parents, self, body) =>
399-
// treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
400-
401416
case tree => List(
402417
if (exprOwner != currentOwner && tree.isTerm) atOwner(exprOwner)(super.transform(tree))
403418
else super.transform(tree)
@@ -408,9 +423,14 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
408423
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
409424
if (!currentOwner.isClass || currentOwner.isPackageClass || currentOwner.isInterface) super.transformStats(stats, exprOwner)
410425
else afterOwnPhase {
411-
fieldsAndAccessors(exprOwner) ++ (stats flatMap transformStat(exprOwner))
426+
fieldsAndAccessors(exprOwner) ++ (stats flatMap transformStat(exprOwner)) // TODO use thicket encoding of multi-tree transformStat?
412427
}
428+
}
429+
}
430+
413431

432+
// case Template(parents, self, body) =>
433+
// treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
414434
// override def transformTemplate(tree: Template): Template = {
415435
//// println(s"transforming stats in ${currentOwner}")
416436
// // Skip interfaces (they have no concrete methods, so no work to be done)
@@ -423,5 +443,3 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
423443
// }
424444
// }
425445

426-
}
427-
}

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
419419
overrideError("cannot be used here - class definitions cannot be overridden")
420420
} else if (!other.isDeferred && member.isClass) {
421421
overrideError("cannot be used here - classes can only override abstract types")
422-
} else if (other.isEffectivelyFinal) { // (1.2)
422+
} else if (other.isEffectivelyFinal && !other.hasFlag(SYNTHESIZE_IMPL_IN_SUBCLASS)) { // (1.2)
423423
overrideError("cannot override final member")
424-
} else if (!other.isDeferredOrJavaDefault && !other.hasFlag(JAVA_DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*)
424+
} else if (!other.isDeferredOrJavaDefault && !other.hasFlag(JAVA_DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic && !other.hasFlag(SYNTHESIZE_IMPL_IN_SUBCLASS)) { // (*)
425425
// (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to
426426
// the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket.
427427
if (isNeitherInClass && !(other.owner isSubClass member.owner))

test/files/neg/t1960.check

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
t1960.scala:5: error: class Aclass needs to be abstract, since variable p in trait TBase of type Int is not defined
2-
(Note that variables need to be initialized to be defined)
1+
t1960.scala:5: error: parameter 'p' requires field but conflicts with method p in trait TBase
32
class Aclass (p: Int) extends TBase { def g() { f(p) } }
4-
^
3+
^
54
one error found

0 commit comments

Comments
 (0)