@@ -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
@@ -2288,49 +2287,28 @@ object Parsers {
2288
2287
* TypeBound ::= Type
2289
2288
* | CaptureSet -- under captureChecking
2290
2289
*/
2291
- 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
-
2290
+ def typeBounds (): TypeBoundsTree =
2298
2291
atSpan(in.offset):
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
2312
-
2313
- private def bound (tok : Int , isCapParamOrMem : Boolean = false ): Tree =
2292
+ TypeBoundsTree (bound(SUPERTYPE ), bound(SUBTYPE ))
2293
+
2294
+ private def bound (tok : Int ): Tree =
2314
2295
if (in.token == tok) then
2315
2296
in.nextToken()
2316
2297
if Feature .ccEnabled && (in.token == LBRACE && ! isDclIntroNext) then
2317
2298
capsBound(captureSet(), isLowerBound = tok == SUPERTYPE )
2318
2299
else toplevelTyp()
2319
- else if Feature .ccEnabled && isCapParamOrMem then
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 )
2322
2300
else EmptyTree
2323
2301
2324
2302
private def capsBound (refs : List [Tree ], isLowerBound : Boolean = false ): Tree =
2325
2303
if isLowerBound && refs.isEmpty then // lower bounds with empty capture sets become a pure CapSet
2326
2304
Select (scalaDot(nme.caps), tpnme.CapSet )
2327
2305
else
2328
- makeRetaining(Select (scalaDot(nme.caps), tpnme.CapSet ), refs, if refs.isEmpty then tpnme.retainsCap else tpnme.retains)
2306
+ makeRetaining(Select (scalaDot(nme.caps), tpnme.CapSet ), refs, tpnme.retains)
2329
2307
2330
2308
/** TypeAndCtxBounds ::= TypeBounds [`:` ContextBounds]
2331
2309
*/
2332
- def typeAndCtxBounds (pname : TypeName , isCapParamOrMem : Boolean = false ): Tree = {
2333
- val t = typeBounds(isCapParamOrMem )
2310
+ def typeAndCtxBounds (pname : TypeName ): Tree = {
2311
+ val t = typeBounds()
2334
2312
val cbs = contextBounds(pname)
2335
2313
if (cbs.isEmpty) t
2336
2314
else atSpan((t.span union cbs.head.span).start) { ContextBounds (t, cbs) }
@@ -3580,16 +3558,23 @@ object Parsers {
3580
3558
WildcardParamName .fresh().toTypeName
3581
3559
else ident().toTypeName
3582
3560
val isCap = gobbleHat()
3583
- if isCap && mods.isOneOf(Covariant | Contravariant ) then
3584
- syntaxError(em " capture parameters cannot have `+/-` variance annotations " ) // TODO we might want to allow those
3585
- if isCap && in.token == LBRACKET then
3586
- syntaxError(em " capture parameters do not take type parameters " )
3587
- in.nextToken()
3561
+ if isCap then
3562
+ if mods.isOneOf(Covariant | Contravariant ) then
3563
+ syntaxError(em " capture parameters cannot have `+/-` variance annotations " ) // TODO we might want to allow those
3564
+ if in.token == LBRACKET then
3565
+ syntaxError(em " capture parameters do not take type parameters " )
3566
+ in.nextToken()
3567
+ end if
3588
3568
val hkparams = typeParamClauseOpt(ParamOwner .Hk )
3589
3569
val bounds =
3590
- if paramOwner.acceptsCtxBounds then typeAndCtxBounds(name, isCap)
3591
- else if sourceVersion.enablesNewGivens && paramOwner == ParamOwner .Type then typeAndCtxBounds(name, isCap)
3592
- else typeBounds(isCap)
3570
+ if ! isCap && paramOwner.acceptsCtxBounds then typeAndCtxBounds(name)
3571
+ else if ! isCap && sourceVersion.enablesNewGivens && paramOwner == ParamOwner .Type then typeAndCtxBounds(name)
3572
+ else typeBounds()
3573
+ if isCap then
3574
+ bounds.pushAttachment(CaptureVar , ())
3575
+ val t = contextBounds(name)
3576
+ if t.nonEmpty then
3577
+ syntaxError(em " capture parameters cannot have context bounds " , t.head.span)
3593
3578
TypeDef (name, lambdaAbstract(hkparams, bounds)).withMods(mods)
3594
3579
}
3595
3580
}
@@ -4135,8 +4120,11 @@ object Parsers {
4135
4120
def makeTypeDef (rhs : Tree ): Tree = {
4136
4121
val rhs1 = lambdaAbstractAll(tparams :: vparamss, rhs)
4137
4122
val tdef = TypeDef (nameIdent.name.toTypeName, rhs1)
4138
- if ( nameIdent.isBackquoted)
4123
+ if nameIdent.isBackquoted then
4139
4124
tdef.pushAttachment(Backquoted , ())
4125
+ if isCapDef then rhs.match
4126
+ case ContextBounds (_, _) => syntaxError(em " capture-set member declarations cannot have context bounds " , rhs.span)
4127
+ case rhs => rhs.pushAttachment(CaptureVar , ())
4140
4128
finalizeDef(tdef, mods, start)
4141
4129
}
4142
4130
@@ -4145,7 +4133,7 @@ object Parsers {
4145
4133
in.nextToken()
4146
4134
makeTypeDef(typeDefRHS())
4147
4135
case SUBTYPE | SUPERTYPE =>
4148
- typeAndCtxBounds(tname, isCapDef ) match
4136
+ typeAndCtxBounds(tname) match
4149
4137
case bounds : TypeBoundsTree if in.token == EQUALS =>
4150
4138
val eqOffset = in.skipToken()
4151
4139
var rhs = typeDefRHS()
@@ -4166,10 +4154,10 @@ object Parsers {
4166
4154
makeTypeDef(rhs)
4167
4155
case bounds => makeTypeDef(bounds)
4168
4156
case SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | OUTDENT | EOF =>
4169
- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4157
+ makeTypeDef(typeAndCtxBounds(tname))
4170
4158
case _ if (staged & StageKind .QuotedPattern ) != 0
4171
4159
|| sourceVersion.enablesNewGivens && in.isColon =>
4172
- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4160
+ makeTypeDef(typeAndCtxBounds(tname))
4173
4161
case _ =>
4174
4162
syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
4175
4163
return EmptyTree // return to avoid setting the span to EmptyTree
0 commit comments