Skip to content

Commit 609e40e

Browse files
committed
Make forwardTypeParams configurable
A new setting, -Ysuppress-param-forwarding is used to make forwarding type parameters confihurable. Forwarding type parameters from base class to subclass instance is done in `normalizeToClassRefs` for optimization, but I just found out this optimization is not always type-preserving and in fact can lead to type errors. SortedMap.scala in the collection strawman is an example. With parameter forwarding enabled, we get: Error: immutable/SortedMap.scala -------------------------------------------- | with MapValuePolyTransforms[K, V, C] { | ^ |Type argument C does not conform to upper bound [=X, +Y] => | strawman.collection.immutable.Map[=X, +Y] & | strawman.collection.immutable.MapValuePolyTransforms[=X', +Y', LazyRef(C)] | |where: +Y is a type variable | +Y' is a type variable | =X is a type variable | =X' is a type variable If we turn off forwarding with the option, the strawman compiles OK. Unfortunately turning the option off altogether does not work (yet). It leads to increased compile times, and more tests fail with deep subtype recursions. Dotty bootstrap seems to not terminate at all. Related: Refine notion of self in RefChecks. This is Needed to make pos/i1401.scala compile when forwardTypeParams is off. # Conflicts: # compiler/src/dotty/tools/dotc/typer/RefChecks.scala
1 parent 6c21f08 commit 609e40e

File tree

5 files changed

+9
-4
lines changed

5 files changed

+9
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class ScalaSettings extends Settings.SettingGroup {
9696
val YforceSbtPhases = BooleanSetting("-Yforce-sbt-phases", "Run the phases used by sbt for incremental compilation (ExtractDependencies and ExtractAPI) even if the compiler is ran outside of sbt, for debugging.")
9797
val YdumpSbtInc = BooleanSetting("-Ydump-sbt-inc", "For every compiled foo.scala, output the API representation and dependencies used for sbt incremental compilation in foo.inc, implies -Yforce-sbt-phases.")
9898
val YcheckAllPatmat = BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm)")
99+
val YsuppressParamForwarding = BooleanSetting("-Ysuppress-param-forwarding", "Don't install aliases for base type parameters.")
99100

100101
/** Area-specific debug output */
101102
val Yexplainlowlevel = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

compiler/src/dotty/tools/dotc/core/Mode.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ object Mode {
3939
val TypevarsMissContext = newMode(4, "TypevarsMissContext")
4040
val CheckCyclic = newMode(5, "CheckCyclic")
4141

42+
/** We are looking at the arguments of a supercall */
4243
val InSuperCall = newMode(6, "InSuperCall")
4344

4445
/** Allow GADTFlexType labelled types to have their bounds adjusted */
@@ -81,7 +82,7 @@ object Mode {
8182
val ReadPositions = newMode(16, "ReadPositions")
8283

8384
val PatternOrType = Pattern | Type
84-
85+
8586
/** We are elaborating the fully qualified name of a package clause.
8687
* In this case, identifiers should never be imported.
8788
*/

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,8 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
338338
if (name == from.name &&
339339
(lo2 eq hi2) &&
340340
info.variance == to.variance &&
341-
!decls.lookup(argSym.name).exists) {
341+
!decls.lookup(argSym.name).exists &&
342+
!ctx.settings.YsuppressParamForwarding.value) {
342343
// println(s"short-circuit ${argSym.name} was: ${argSym.info}, now: $to")
343344
enterArgBinding(argSym, to, cls, decls)
344345
}

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,6 +3030,8 @@ object Types {
30303030
override def hashCode: Int = identityHash
30313031
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
30323032

3033+
def withName(name: Name): this.type = { myRepr = name; this }
3034+
30333035
private var myRepr: Name = null
30343036
def repr(implicit ctx: Context): Name = {
30353037
if (myRepr == null) myRepr = SkolemName.fresh()

tests/pos/i1401.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package i1401
22

3-
trait Subtractable[A, +Repr <: Subtractable[A, Repr]] {
4-
def -(elem: A): Repr
3+
trait Subtractable[AS, +Repr <: Subtractable[AS, Repr]] {
4+
def -(elem: AS): Repr
55
}
66

77
trait BufferLike[BA, +This <: BufferLike[BA, This] with Buffer[BA]]

0 commit comments

Comments
 (0)