Skip to content

Commit 22a79e2

Browse files
committed
Make ^ optional in more scenarios for cap vars
1 parent 57a1b73 commit 22a79e2

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

@@ -2275,11 +2276,29 @@ object Parsers {
22752276

22762277
/** TypeBounds ::= [`>:' TypeBound ] [`<:' TypeBound ]
22772278
* TypeBound ::= Type
2278-
* | CaptureSet -- under captureChecking
2279+
* | CaptureSet -- under captureChecking
22792280
*/
22802281
def typeBounds(isCapParamOrMem: Boolean = false): TypeBoundsTree =
2282+
def isCapsBound(t: Tree): Boolean =
2283+
t match
2284+
case Select(qual, tpnme.CapSet) => true
2285+
case Annotated(Select(qual, tpnme.CapSet), _) => true
2286+
case _ => false
2287+
22812288
atSpan(in.offset):
2282-
TypeBoundsTree(bound(SUPERTYPE, isCapParamOrMem), bound(SUBTYPE, isCapParamOrMem))
2289+
var lbound = bound(SUPERTYPE, isCapParamOrMem)
2290+
var ubound = bound(SUBTYPE, isCapParamOrMem)
2291+
if Feature.ccEnabled && !isCapParamOrMem then
2292+
/* We haven't annotated the `^` to a type parameter/member,
2293+
but an explicit capture-set bound makes it a capture parameter, so we make sure
2294+
to add the missing other CapSet bound. */
2295+
if lbound.isEmpty && isCapsBound(ubound) then
2296+
lbound = capsBound(Nil, isLowerBound = true)
2297+
if ubound.isEmpty && isCapsBound(lbound) then
2298+
ubound = capsBound(Nil, isLowerBound = false)
2299+
end if
2300+
TypeBoundsTree(lbound, ubound)
2301+
end typeBounds
22832302

22842303
private def bound(tok: Int, isCapParamOrMem: Boolean = false): Tree =
22852304
if (in.token == tok) then
@@ -2288,7 +2307,8 @@ object Parsers {
22882307
capsBound(captureSet(), isLowerBound = tok == SUPERTYPE)
22892308
else toplevelTyp()
22902309
else if Feature.ccEnabled && isCapParamOrMem then
2291-
capsBound(Nil, isLowerBound = tok == SUPERTYPE) // FIXME: should we avoid the CapSet^{} lower bound and make it Nothing?
2310+
// we hit this case if we have annotated a post-fix `^` but no bounds to a type parameter/member
2311+
capsBound(Nil, isLowerBound = tok == SUPERTYPE)
22922312
else EmptyTree
22932313

22942314
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)