@@ -35,7 +35,6 @@ import config.SourceVersion.*
3535import config .SourceVersion
3636import dotty .tools .dotc .config .MigrationVersion
3737import dotty .tools .dotc .util .chaining .*
38- import dotty .tools .dotc .config .Printers .variances
3938
4039object Parsers {
4140
@@ -2278,49 +2277,28 @@ object Parsers {
22782277 * TypeBound ::= Type
22792278 * | CaptureSet -- under captureChecking
22802279 */
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 =
22882281 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 =
23042285 if (in.token == tok) then
23052286 in.nextToken()
23062287 if Feature .ccEnabled && (in.token == LBRACE && ! isDclIntroNext) then
23072288 capsBound(captureSet(), isLowerBound = tok == SUPERTYPE )
23082289 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 )
23122290 else EmptyTree
23132291
23142292 private def capsBound (refs : List [Tree ], isLowerBound : Boolean = false ): Tree =
23152293 if isLowerBound && refs.isEmpty then // lower bounds with empty capture sets become a pure CapSet
23162294 Select (scalaDot(nme.caps), tpnme.CapSet )
23172295 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)
23192297
23202298 /** TypeAndCtxBounds ::= TypeBounds [`:` ContextBounds]
23212299 */
2322- def typeAndCtxBounds (pname : TypeName , isCapParamOrMem : Boolean = false ): Tree = {
2323- val t = typeBounds(isCapParamOrMem )
2300+ def typeAndCtxBounds (pname : TypeName ): Tree = {
2301+ val t = typeBounds()
23242302 val cbs = contextBounds(pname)
23252303 if (cbs.isEmpty) t
23262304 else atSpan((t.span union cbs.head.span).start) { ContextBounds (t, cbs) }
@@ -3570,16 +3548,23 @@ object Parsers {
35703548 WildcardParamName .fresh().toTypeName
35713549 else ident().toTypeName
35723550 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
35783558 val hkparams = typeParamClauseOpt(ParamOwner .Hk )
35793559 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)
35833568 TypeDef (name, lambdaAbstract(hkparams, bounds)).withMods(mods)
35843569 }
35853570 }
@@ -4125,8 +4110,11 @@ object Parsers {
41254110 def makeTypeDef (rhs : Tree ): Tree = {
41264111 val rhs1 = lambdaAbstractAll(tparams :: vparamss, rhs)
41274112 val tdef = TypeDef (nameIdent.name.toTypeName, rhs1)
4128- if ( nameIdent.isBackquoted)
4113+ if nameIdent.isBackquoted then
41294114 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 , ())
41304118 finalizeDef(tdef, mods, start)
41314119 }
41324120
@@ -4135,7 +4123,7 @@ object Parsers {
41354123 in.nextToken()
41364124 makeTypeDef(typeDefRHS())
41374125 case SUBTYPE | SUPERTYPE =>
4138- typeAndCtxBounds(tname, isCapDef ) match
4126+ typeAndCtxBounds(tname) match
41394127 case bounds : TypeBoundsTree if in.token == EQUALS =>
41404128 val eqOffset = in.skipToken()
41414129 var rhs = typeDefRHS()
@@ -4156,10 +4144,10 @@ object Parsers {
41564144 makeTypeDef(rhs)
41574145 case bounds => makeTypeDef(bounds)
41584146 case SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | OUTDENT | EOF =>
4159- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4147+ makeTypeDef(typeAndCtxBounds(tname))
41604148 case _ if (staged & StageKind .QuotedPattern ) != 0
41614149 || sourceVersion.enablesNewGivens && in.isColon =>
4162- makeTypeDef(typeAndCtxBounds(tname, isCapDef ))
4150+ makeTypeDef(typeAndCtxBounds(tname))
41634151 case _ =>
41644152 syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
41654153 return EmptyTree // return to avoid setting the span to EmptyTree
0 commit comments