File tree 2 files changed +28
-1
lines changed
src/dotty/tools/dotc/core
2 files changed +28
-1
lines changed Original file line number Diff line number Diff line change @@ -177,7 +177,25 @@ trait ConstraintHandling {
177
177
case tp : RefinedType if param occursIn tp.refinedInfo => tp.parent
178
178
case tp : WildcardType =>
179
179
val bounds = tp.optBounds.orElse(TypeBounds .empty).bounds
180
- if (fromBelow == (variance >= 0 )) bounds.lo else bounds.hi
180
+ // Try to instantiate the wildcard to a type that is known to conform to it.
181
+ // This means:
182
+ // If fromBelow is true, we minimize the type overall
183
+ // Hence, if variance < 0, pick the maximal safe type: bounds.lo
184
+ // (i.e. the whole bounds range is over the type)
185
+ // if variance > 0, pick the minimal safe type: bounds.hi
186
+ // (i.e. the whole bounds range is under the type)
187
+ // if variance == 0, pick bounds.lo anyway (this is arbitrary but in line with
188
+ // the principle that we pick the smaller type when in doubt).
189
+ // If fromBelow is false, we maximize the type overall and reverse the bounds
190
+ // if variance != 0. For variance == 0, we still minimize.
191
+ // In summary we pick the bound given by this table:
192
+ //
193
+ // variance | -1 0 1
194
+ // ------------------------
195
+ // from below | lo lo hi
196
+ // from above | hi lo lo
197
+ //
198
+ if (variance == 0 || fromBelow == (variance < 0 )) bounds.lo else bounds.hi
181
199
case _ => tp
182
200
}
183
201
}
Original file line number Diff line number Diff line change 1
1
case class W [T ](seq : Option [Option [T ]] = Option .empty)
2
+ object W {
3
+ def apply [T ] = new W [T ]()
4
+ }
5
+
6
+ case class V [T ](vv : W [W [T ]] = W .apply)
7
+ object Test {
8
+ W [Int ]()
9
+ // V[Int]() fails in scalac and dotty: both instantiate the vv-default to W[Nothing]
10
+ }
You can’t perform that action at this time.
0 commit comments