@@ -35,7 +35,6 @@ import config.SourceVersion.*
35
35
import config .SourceVersion
36
36
import dotty .tools .dotc .config .MigrationVersion
37
37
import dotty .tools .dotc .util .chaining .*
38
- import dotty .tools .dotc .config .Printers .variances
39
38
40
39
object Parsers {
41
40
@@ -2278,49 +2277,28 @@ object Parsers {
2278
2277
* TypeBound ::= Type
2279
2278
* | CaptureSet -- under captureChecking
2280
2279
*/
2281
- 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
-
2280
+ def typeBounds (): TypeBoundsTree =
2288
2281
atSpan(in.offset):
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
2302
-
2303
- private def bound (tok : Int , isCapParamOrMem : Boolean = false ): Tree =
2282
+ TypeBoundsTree (bound(SUPERTYPE ), bound(SUBTYPE ))
2283
+
2284
+ private def bound (tok : Int ): Tree =
2304
2285
if (in.token == tok) then
2305
2286
in.nextToken()
2306
2287
if Feature .ccEnabled && (in.token == LBRACE && ! isDclIntroNext) then
2307
2288
capsBound(captureSet(), isLowerBound = tok == SUPERTYPE )
2308
2289
else toplevelTyp()
2309
- else if Feature .ccEnabled && isCapParamOrMem then
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 )
2312
2290
else EmptyTree
2313
2291
2314
2292
private def capsBound (refs : List [Tree ], isLowerBound : Boolean = false ): Tree =
2315
2293
if isLowerBound && refs.isEmpty then // lower bounds with empty capture sets become a pure CapSet
2316
2294
Select (scalaDot(nme.caps), tpnme.CapSet )
2317
2295
else
2318
- makeRetaining(Select (scalaDot(nme.caps), tpnme.CapSet ), refs, if refs.isEmpty then tpnme.retainsCap else tpnme.retains)
2296
+ makeRetaining(Select (scalaDot(nme.caps), tpnme.CapSet ), refs, tpnme.retains)
2319
2297
2320
2298
/** TypeAndCtxBounds ::= TypeBounds [`:` ContextBounds]
2321
2299
*/
2322
- def typeAndCtxBounds (pname : TypeName , isCapParamOrMem : Boolean = false ): Tree = {
2323
- val t = typeBounds(isCapParamOrMem )
2300
+ def typeAndCtxBounds (pname : TypeName ): Tree = {
2301
+ val t = typeBounds()
2324
2302
val cbs = contextBounds(pname)
2325
2303
if (cbs.isEmpty) t
2326
2304
else atSpan((t.span union cbs.head.span).start) { ContextBounds (t, cbs) }
@@ -3570,16 +3548,23 @@ object Parsers {
3570
3548
WildcardParamName .fresh().toTypeName
3571
3549
else ident().toTypeName
3572
3550
val isCap = gobbleHat()
3573
- if isCap && mods.isOneOf(Covariant | Contravariant ) then
3574
- syntaxError(em " capture parameters cannot have `+/-` variance annotations " ) // TODO we might want to allow those
3575
- if isCap && in.token == LBRACKET then
3576
- syntaxError(em " capture parameters do not take type parameters " )
3577
- in.nextToken()
3551
+ if isCap then
3552
+ if mods.isOneOf(Covariant | Contravariant ) then
3553
+ syntaxError(em " capture parameters cannot have `+/-` variance annotations " ) // TODO we might want to allow those
3554
+ if in.token == LBRACKET then
3555
+ syntaxError(em " capture parameters do not take type parameters " )
3556
+ in.nextToken()
3557
+ end if
3578
3558
val hkparams = typeParamClauseOpt(ParamOwner .Hk )
3579
3559
val bounds =
3580
- if paramOwner.acceptsCtxBounds then typeAndCtxBounds(name, isCap)
3581
- else if sourceVersion.enablesNewGivens && paramOwner == ParamOwner .Type then typeAndCtxBounds(name, isCap)
3582
- else typeBounds(isCap)
3560
+ if ! isCap && paramOwner.acceptsCtxBounds then typeAndCtxBounds(name)
3561
+ else if ! isCap && sourceVersion.enablesNewGivens && paramOwner == ParamOwner .Type then typeAndCtxBounds(name)
3562
+ else typeBounds()
3563
+ if isCap then
3564
+ bounds.pushAttachment(CaptureVar , ())
3565
+ val t = contextBounds(name)
3566
+ if t.nonEmpty then
3567
+ syntaxError(em " capture parameters cannot have context bounds " , t.head.span)
3583
3568
TypeDef (name, lambdaAbstract(hkparams, bounds)).withMods(mods)
3584
3569
}
3585
3570
}
@@ -4125,8 +4110,11 @@ object Parsers {
4125
4110
def makeTypeDef (rhs : Tree ): Tree = {
4126
4111
val rhs1 = lambdaAbstractAll(tparams :: vparamss, rhs)
4127
4112
val tdef = TypeDef (nameIdent.name.toTypeName, rhs1)
4128
- if ( nameIdent.isBackquoted)
4113
+ if nameIdent.isBackquoted then
4129
4114
tdef.pushAttachment(Backquoted , ())
4115
+ if isCapDef then rhs.match
4116
+ case ContextBounds (_, _) => syntaxError(em " capture-set member declarations cannot have context bounds " , rhs.span)
4117
+ case rhs => rhs.pushAttachment(CaptureVar , ())
4130
4118
finalizeDef(tdef, mods, start)
4131
4119
}
4132
4120
@@ -4135,7 +4123,7 @@ object Parsers {
4135
4123
in.nextToken()
4136
4124
makeTypeDef(typeDefRHS())
4137
4125
case SUBTYPE | SUPERTYPE =>
4138
- typeAndCtxBounds(tname, isCapDef ) match
4126
+ typeAndCtxBounds(tname) match
4139
4127
case bounds : TypeBoundsTree if in.token == EQUALS =>
4140
4128
val eqOffset = in.skipToken()
4141
4129
var rhs = typeDefRHS()
@@ -4156,10 +4144,10 @@ object Parsers {
4156
4144
makeTypeDef(rhs)
4157
4145
case bounds => makeTypeDef(bounds)
4158
4146
case SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | OUTDENT | EOF =>
4159
- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4147
+ makeTypeDef(typeAndCtxBounds(tname))
4160
4148
case _ if (staged & StageKind .QuotedPattern ) != 0
4161
4149
|| sourceVersion.enablesNewGivens && in.isColon =>
4162
- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4150
+ makeTypeDef(typeAndCtxBounds(tname))
4163
4151
case _ =>
4164
4152
syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
4165
4153
return EmptyTree // return to avoid setting the span to EmptyTree
0 commit comments