Skip to content

Commit 88d2546

Browse files
authored
Merge pull request #9564 from dotty-staging/fix-#9346-2
Fix #9346: Shortcut type aliases in refinements
2 parents 4beb03a + 9aa1308 commit 88d2546

File tree

5 files changed

+29
-6
lines changed

5 files changed

+29
-6
lines changed

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -148,21 +148,24 @@ class CheckRealizable(using Context) {
148148
*/
149149
private def boundsRealizability(tp: Type) = {
150150

151-
val memberProblems =
151+
val memberProblems = withMode(Mode.CheckBounds) {
152152
for {
153153
mbr <- tp.nonClassTypeMembers
154154
if !(mbr.info.loBound <:< mbr.info.hiBound)
155155
}
156156
yield new HasProblemBounds(mbr.name, mbr.info)
157+
}
157158

158-
val refinementProblems =
159+
val refinementProblems = withMode(Mode.CheckBounds) {
159160
for {
160161
name <- refinedNames(tp)
161162
if (name.isTypeName)
162163
mbr <- tp.member(name).alternatives
163164
if !(mbr.info.loBound <:< mbr.info.hiBound)
164165
}
165-
yield new HasProblemBounds(name, mbr.info)
166+
yield
167+
new HasProblemBounds(name, mbr.info)
168+
}
166169

167170
def baseTypeProblems(base: Type) = base match {
168171
case AndType(base1, base2) =>

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

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ object Mode {
7272
/** We are currently unpickling Scala2 info */
7373
val Scala2Unpickling: Mode = newMode(13, "Scala2Unpickling")
7474

75+
/** We are currently checking bounds to be non-empty, so we should not
76+
* do any widening when computing members of refined types.
77+
*/
78+
val CheckBounds: Mode = newMode(14, "CheckBounds")
79+
7580
/** Use Scala2 scheme for overloading and implicit resolution */
7681
val OldOverloadingResolution: Mode = newMode(15, "OldOverloadingResolution")
7782

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ object TypeOps:
507507
boundss: List[TypeBounds],
508508
instantiate: (Type, List[Type]) => Type,
509509
app: Type)(
510-
using Context): List[BoundsViolation] = {
510+
using Context): List[BoundsViolation] = withMode(Mode.CheckBounds) {
511511
val argTypes = args.tpes
512512

513513
/** Replace all wildcards in `tps` with `<app>#<tparam>` where `<tparam>` is the

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,16 @@ object Types {
671671
val rinfo = tp.refinedInfo
672672
if (name.isTypeName && !pinfo.isInstanceOf[ClassInfo]) { // simplified case that runs more efficiently
673673
val jointInfo =
674-
if (ctx.base.pendingMemberSearches.contains(name)) pinfo safe_& rinfo
675-
else pinfo recoverable_& rinfo
674+
if rinfo.isInstanceOf[TypeAlias] && !ctx.mode.is(Mode.CheckBounds) then
675+
// In normal situations, the only way to "improve" on rinfo is to return an empty type bounds
676+
// So, we do not lose anything essential in "widening" to rinfo.
677+
// We need to compute the precise info only when checking for empty bounds
678+
// which is communicated by the CheckBounds mode.
679+
rinfo
680+
else if ctx.base.pendingMemberSearches.contains(name) then
681+
pinfo safe_& rinfo
682+
else
683+
pinfo recoverable_& rinfo
676684
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, jointInfo)
677685
}
678686
else

tests/pos-deep-subtype/i9346.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Foo {
2+
type Repr[+O] <: Foo {
3+
type Repr[+OO] = Foo.this.Repr[OO]
4+
}
5+
6+
def foo[T](f: Repr[T]): f.Repr[T] = ???
7+
}

0 commit comments

Comments
 (0)