Skip to content

Commit e9a0fec

Browse files
committed
Make ^ optional in more scenarios for cap vars
1 parent 83f2c19 commit e9a0fec

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+23-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import config.SourceVersion.*
3535
import config.SourceVersion
3636
import dotty.tools.dotc.config.MigrationVersion
3737
import dotty.tools.dotc.util.chaining.*
38+
import dotty.tools.dotc.config.Printers.variances
3839

3940
object Parsers {
4041

@@ -2285,11 +2286,29 @@ object Parsers {
22852286

22862287
/** TypeBounds ::= [`>:' TypeBound ] [`<:' TypeBound ]
22872288
* TypeBound ::= Type
2288-
* | CaptureSet -- under captureChecking
2289+
* | CaptureSet -- under captureChecking
22892290
*/
22902291
def typeBounds(isCapParamOrMem: Boolean = false): TypeBoundsTree =
2292+
def isCapsBound(t: Tree): Boolean =
2293+
t match
2294+
case Select(qual, tpnme.CapSet) => true
2295+
case Annotated(Select(qual, tpnme.CapSet), _) => true
2296+
case _ => false
2297+
22912298
atSpan(in.offset):
2292-
TypeBoundsTree(bound(SUPERTYPE, isCapParamOrMem), bound(SUBTYPE, isCapParamOrMem))
2299+
var lbound = bound(SUPERTYPE, isCapParamOrMem)
2300+
var ubound = bound(SUBTYPE, isCapParamOrMem)
2301+
if Feature.ccEnabled && !isCapParamOrMem then
2302+
/* We haven't annotated the `^` to a type parameter/member,
2303+
but an explicit capture-set bound makes it a capture parameter, so we make sure
2304+
to add the missing other CapSet bound. */
2305+
if lbound.isEmpty && isCapsBound(ubound) then
2306+
lbound = capsBound(Nil, isLowerBound = true)
2307+
if ubound.isEmpty && isCapsBound(lbound) then
2308+
ubound = capsBound(Nil, isLowerBound = false)
2309+
end if
2310+
TypeBoundsTree(lbound, ubound)
2311+
end typeBounds
22932312

22942313
private def bound(tok: Int, isCapParamOrMem: Boolean = false): Tree =
22952314
if (in.token == tok) then
@@ -2298,7 +2317,8 @@ object Parsers {
22982317
capsBound(captureSet(), isLowerBound = tok == SUPERTYPE)
22992318
else toplevelTyp()
23002319
else if Feature.ccEnabled && isCapParamOrMem then
2301-
capsBound(Nil, isLowerBound = tok == SUPERTYPE) // FIXME: should we avoid the CapSet^{} lower bound and make it Nothing?
2320+
// we hit this case if we have annotated a post-fix `^` but no bounds to a type parameter/member
2321+
capsBound(Nil, isLowerBound = tok == SUPERTYPE)
23022322
else EmptyTree
23032323

23042324
private def capsBound(refs: List[Tree], isLowerBound: Boolean = false): Tree =

tests/pos-custom-args/captures/cap-paramlists.scala

+11-11
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ def test =
99
val z: Any^ = ???
1010
def foo[A >: {y} <: {x},
1111
B^,
12-
C^ <: {x},
12+
C <: {x},
1313
D^ : Ctx,
14-
E^ <: {C},
15-
F^ <: {C},
16-
G^ <: {x, y},
17-
H >: {x} <: {x,y} : Ctx, T, U]()[I^ <: {y, G, H},
18-
J^ <: {O.z},
19-
K^ <: {x, O.z},
20-
L^ <: {x, y, O.z},
21-
M^ >: {x, y, O.z} <: {C} : Ctx,
22-
N^ >: {x} <: {x},
23-
O^ >: {O.z} <: {O.z}] = ???
14+
E <: {C},
15+
F <: {C},
16+
G <: {x, y},
17+
H >: {x} <: {x,y} : Ctx, T, U >: {x}]()[I^ <: {y, G, H},
18+
J <: {O.z},
19+
K <: {x, O.z},
20+
L <: {x, y, O.z},
21+
M >: {x, y, O.z} <: {C} : Ctx,
22+
N >: {x} <: {x},
23+
O >: {O.z} <: {O.z}] = ???

tests/pos-custom-args/captures/capset-members.scala

+12-11
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ def test =
99
val z: Any^ = ???
1010
trait CaptureSet:
1111
type A^ >: {y} <: {x}
12-
type B^ = {x}
13-
type C^ <: {x}
12+
type B = {x}
13+
type C <: {x}
1414
type D^ : Ctx
15-
type E^ <: {C}
16-
type F^ <: {C}
17-
type G^ <: {x, y}
18-
type H^ >: {x} <: {x,y} : Ctx
15+
type E <: {C}
16+
type F <: {C}
17+
type G <: {x, y}
18+
type H >: {x} <: {x,y} : Ctx
1919
type I^ = {y, G, H}
20-
type J^ = {O.z}
20+
type J = {O.z}
2121
type K^ = {x, O.z}
22-
type L^ <: {x, y, O.z}
23-
type M^ >: {x, y, O.z} <: {C}
24-
type N^ >: {x} <: {x}
25-
type O^ >: {O.z} <: {O.z}
22+
type L <: {x, y, O.z}
23+
type M >: {x, y, O.z} <: {C}
24+
type N >: {x} <: {x}
25+
type O >: {O.z} <: {O.z}
26+
type P >: {B,D}

0 commit comments

Comments
 (0)