diff options
author | Martin Odersky <odersky@gmail.com> | 2014-07-20 14:44:31 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-03 17:28:34 +0200 |
commit | 38761d9d11a42635e64d6df54ecaf1968797e7e8 (patch) | |
tree | e0feb46fdbe76741edb339095a71ec23ec2f1afd /src/dotty/tools/dotc | |
parent | 948747ede5143db221b1b266d011900c3cc2a758 (diff) | |
download | dotty-38761d9d11a42635e64d6df54ecaf1968797e7e8.tar.gz dotty-38761d9d11a42635e64d6df54ecaf1968797e7e8.tar.bz2 dotty-38761d9d11a42635e64d6df54ecaf1968797e7e8.zip |
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.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 1 |
2 files changed, 15 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index ba2b62faa..c3d0f9c3a 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -191,9 +191,9 @@ object desugar { /** Fill in empty type bounds with Nothing/Any. Expand private local type parameters as follows: * - * class C[T] + * class C[v T] * ==> - * class C { type C$T; type T = C$T } + * class C { type v C$T; type v T = C$T } */ def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = { val TypeDef(mods, name, rhs) = tdef @@ -201,7 +201,8 @@ object desugar { val tparam = cpy.TypeDef(tdef, mods &~ PrivateLocal | ExpandedName, name.expandedName(ctx.owner), rhs, tdef.tparams) val alias = cpy.TypeDef(tdef, - Modifiers(PrivateLocalParamAccessor | Synthetic), name, refOfDef(tparam)) + Modifiers(PrivateLocalParamAccessor | Synthetic | mods.flags & VarianceFlags), + name, refOfDef(tparam)) Thicket(tparam, alias) } else cpy.TypeDef(tdef, mods, name, rhs, tdef.tparams) @@ -274,7 +275,13 @@ object desugar { // def _1 = this.p1 // ... // def _N = this.pN - // def copy(p1: T1 = p1, ..., pN: TN = pN)(moreParams) = new C[...](p1, ..., pN)(moreParams) + // def copy(p1: T1 = p1: @uncheckedVariance, ..., + // pN: TN = pN: @uncheckedVariance)(moreParams) = + // new C[...](p1, ..., pN)(moreParams) + // + // Note: copy default parameters need @uncheckedVariance; see + // neg/t1843-variances.scala for a test case. The test would give + // two errors without @uncheckedVariance, one of them spurious. val caseClassMeths = if (mods is Case) { def syntheticProperty(name: TermName, rhs: Tree) = @@ -289,8 +296,10 @@ object desugar { val copyMeths = if (mods is Abstract) Nil else { + def copyDefault(vparam: ValDef) = + makeAnnotated(defn.UncheckedVarianceAnnot, refOfDef(vparam)) val copyFirstParams = derivedVparamss.head.map(vparam => - cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, refOfDef(vparam))) + cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, copyDefault(vparam))) val copyRestParamss = derivedVparamss.tail.nestedMap(vparam => cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, EmptyTree)) DefDef(synthetic, nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr) :: Nil diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index d32fd1913..e7283c827 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -73,6 +73,7 @@ object NameOps { def isModuleClassName = name endsWith MODULE_SUFFIX def isImportName = name startsWith IMPORT def isInheritedName = name.length > 0 && name.head == '(' && name.startsWith(nme.INHERITED) + def isDefaultGetterName = name.isTermName && name.asTermName.defaultGetterIndex >= 0 def isModuleVarName(name: Name): Boolean = name.stripAnonNumberSuffix endsWith MODULE_VAR_SUFFIX |