Skip to content

Commit 38761d9

Browse files
committed
Two variance-related fixes in Desugar
1) Type parameter accessors inherit their variance from the type parameter 2) Copy method parameter defaults are annotated @uncheckedVariance. This is necessary because default methods will be checked for variance.
1 parent 948747e commit 38761d9

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,17 +191,18 @@ object desugar {
191191

192192
/** Fill in empty type bounds with Nothing/Any. Expand private local type parameters as follows:
193193
*
194-
* class C[T]
194+
* class C[v T]
195195
* ==>
196-
* class C { type C$T; type T = C$T }
196+
* class C { type v C$T; type v T = C$T }
197197
*/
198198
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
199199
val TypeDef(mods, name, rhs) = tdef
200200
if (mods is PrivateLocalParam) {
201201
val tparam = cpy.TypeDef(tdef,
202202
mods &~ PrivateLocal | ExpandedName, name.expandedName(ctx.owner), rhs, tdef.tparams)
203203
val alias = cpy.TypeDef(tdef,
204-
Modifiers(PrivateLocalParamAccessor | Synthetic), name, refOfDef(tparam))
204+
Modifiers(PrivateLocalParamAccessor | Synthetic | mods.flags & VarianceFlags),
205+
name, refOfDef(tparam))
205206
Thicket(tparam, alias)
206207
}
207208
else cpy.TypeDef(tdef, mods, name, rhs, tdef.tparams)
@@ -274,7 +275,13 @@ object desugar {
274275
// def _1 = this.p1
275276
// ...
276277
// def _N = this.pN
277-
// def copy(p1: T1 = p1, ..., pN: TN = pN)(moreParams) = new C[...](p1, ..., pN)(moreParams)
278+
// def copy(p1: T1 = p1: @uncheckedVariance, ...,
279+
// pN: TN = pN: @uncheckedVariance)(moreParams) =
280+
// new C[...](p1, ..., pN)(moreParams)
281+
//
282+
// Note: copy default parameters need @uncheckedVariance; see
283+
// neg/t1843-variances.scala for a test case. The test would give
284+
// two errors without @uncheckedVariance, one of them spurious.
278285
val caseClassMeths =
279286
if (mods is Case) {
280287
def syntheticProperty(name: TermName, rhs: Tree) =
@@ -289,8 +296,10 @@ object desugar {
289296
val copyMeths =
290297
if (mods is Abstract) Nil
291298
else {
299+
def copyDefault(vparam: ValDef) =
300+
makeAnnotated(defn.UncheckedVarianceAnnot, refOfDef(vparam))
292301
val copyFirstParams = derivedVparamss.head.map(vparam =>
293-
cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, refOfDef(vparam)))
302+
cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, copyDefault(vparam)))
294303
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
295304
cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, EmptyTree))
296305
DefDef(synthetic, nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr) :: Nil

src/dotty/tools/dotc/core/NameOps.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ object NameOps {
7373
def isModuleClassName = name endsWith MODULE_SUFFIX
7474
def isImportName = name startsWith IMPORT
7575
def isInheritedName = name.length > 0 && name.head == '(' && name.startsWith(nme.INHERITED)
76+
def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0
7677

7778
def isModuleVarName(name: Name): Boolean =
7879
name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX

0 commit comments

Comments
 (0)