diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index d6f9e0d24c91..e658a3e9a142 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1824,16 +1824,6 @@ object desugar { flatTree(pats1 map (makePatDef(tree, mods, _, rhs))) case ext: ExtMethods => Block(List(ext), Literal(Constant(())).withSpan(ext.span)) - case CapturingTypeTree(refs, parent) => - // convert `{refs} T` to `T @retains refs` - // `{refs}-> T` to `-> (T @retainsByName refs)` - def annotate(annotName: TypeName, tp: Tree) = - Annotated(tp, New(scalaAnnotationDot(annotName), List(refs))) - parent match - case ByNameTypeTree(restpt) => - cpy.ByNameTypeTree(parent)(annotate(tpnme.retainsByName, restpt)) - case _ => - annotate(tpnme.retains, parent) case f: FunctionWithMods if f.hasErasedParams => makeFunctionWithValDefs(f, pt) } desugared.withSpan(tree.span) @@ -1927,7 +1917,7 @@ object desugar { } tree match case tree: FunctionWithMods => - untpd.FunctionWithMods(applyVParams, tree.body, tree.mods, tree.erasedParams) + untpd.FunctionWithMods(applyVParams, result, tree.mods, tree.erasedParams) case _ => untpd.Function(applyVParams, result) } } @@ -1993,8 +1983,6 @@ object desugar { case _ => traverseChildren(tree) } }.traverse(body) - case CapturingTypeTree(refs, parent) => - collect(parent) case _ => } collect(tree) diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index 5b409b6fec9a..a2e3277c9f81 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -223,9 +223,6 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] => /** Strip `=> T` to `T` and (under pureFunctions) `{refs}-> T` to `T` */ def stripByNameType(tree: Tree)(using Context): Tree = unsplice(tree) match case ByNameTypeTree(t1) => t1 - case untpd.CapturingTypeTree(_, parent) => - val parent1 = stripByNameType(parent) - if parent1 eq parent then tree else parent1 case _ => tree /** All type and value parameter symbols of this DefDef */ @@ -473,13 +470,15 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped] */ object ImpureByNameTypeTree: - def apply(tp: ByNameTypeTree)(using Context): untpd.CapturingTypeTree = - untpd.CapturingTypeTree( - untpd.captureRoot.withSpan(tp.span.startPos) :: Nil, tp) + def apply(tp: Tree)(using Context): untpd.ByNameTypeTree = + untpd.ByNameTypeTree( + untpd.CapturesAndResult( + untpd.captureRoot.withSpan(tp.span.startPos) :: Nil, tp)) - def unapply(tp: Tree)(using Context): Option[ByNameTypeTree] = tp match - case untpd.CapturingTypeTree(id @ Select(_, nme.CAPTURE_ROOT) :: Nil, bntp: ByNameTypeTree) - if id.span == bntp.span.startPos => Some(bntp) + def unapply(tp: Tree)(using Context): Option[Tree] = tp match + case untpd.ByNameTypeTree( + untpd.CapturesAndResult(id @ Select(_, nme.CAPTURE_ROOT) :: Nil, result)) + if id.span == result.span.startPos => Some(result) case _ => None end ImpureByNameTypeTree } diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 30f58fba44ec..231454921a36 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -148,7 +148,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { } /** {x1, ..., xN} T (only relevant under captureChecking) */ - case class CapturingTypeTree(refs: List[Tree], parent: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree + case class CapturesAndResult(refs: List[Tree], parent: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree /** Short-lived usage in typer, does not need copy/transform/fold infrastructure */ case class DependentTypeTree(tp: List[Symbol] => Type)(implicit @constructorOnly src: SourceFile) extends Tree @@ -501,6 +501,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def captureRoot(using Context): Select = Select(scalaDot(nme.caps), nme.CAPTURE_ROOT) + def makeRetaining(parent: Tree, refs: List[Tree], annotName: TypeName)(using Context): Annotated = + Annotated(parent, New(scalaAnnotationDot(annotName), List(refs))) + def makeConstructor(tparams: List[TypeDef], vparamss: List[List[ValDef]], rhs: Tree = EmptyTree)(using Context): DefDef = DefDef(nme.CONSTRUCTOR, joinParams(tparams, vparamss), TypeTree(), rhs) @@ -658,9 +661,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { case tree: Number if (digits == tree.digits) && (kind == tree.kind) => tree case _ => finalize(tree, untpd.Number(digits, kind)) } - def CapturingTypeTree(tree: Tree)(refs: List[Tree], parent: Tree)(using Context): Tree = tree match - case tree: CapturingTypeTree if (refs eq tree.refs) && (parent eq tree.parent) => tree - case _ => finalize(tree, untpd.CapturingTypeTree(refs, parent)) + def CapturesAndResult(tree: Tree)(refs: List[Tree], parent: Tree)(using Context): Tree = tree match + case tree: CapturesAndResult if (refs eq tree.refs) && (parent eq tree.parent) => tree + case _ => finalize(tree, untpd.CapturesAndResult(refs, parent)) def TypedSplice(tree: Tree)(splice: tpd.Tree)(using Context): ProxyTree = tree match { case tree: TypedSplice if splice `eq` tree.splice => tree @@ -723,8 +726,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { tree case MacroTree(expr) => cpy.MacroTree(tree)(transform(expr)) - case CapturingTypeTree(refs, parent) => - cpy.CapturingTypeTree(tree)(transform(refs), transform(parent)) + case CapturesAndResult(refs, parent) => + cpy.CapturesAndResult(tree)(transform(refs), transform(parent)) case _ => super.transformMoreCases(tree) } @@ -782,7 +785,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { this(x, splice) case MacroTree(expr) => this(x, expr) - case CapturingTypeTree(refs, parent) => + case CapturesAndResult(refs, parent) => this(this(x, refs), parent) case _ => super.foldMoreCases(x, tree) diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala index 2b9fe9d3d923..509fecd4d3b4 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala @@ -70,7 +70,7 @@ sealed abstract class CaptureSet extends Showable: assert(!isConst) asInstanceOf[Var] - /** Does this capture set contain the root reference `*` as element? */ + /** Does this capture set contain the root reference `cap` as element? */ final def isUniversal(using Context) = elems.exists { case ref: TermRef => ref.symbol == defn.captureRoot @@ -133,7 +133,7 @@ sealed abstract class CaptureSet extends Showable: * for `x` in a state where we assume all supersets of `x` have just the elements * known at this point. On the other hand if x's capture set has no known elements, * a set `cs` might account for `x` only if it subsumes `x` or it contains the - * root capability `*`. + * root capability `cap`. */ def mightAccountFor(x: CaptureRef)(using Context): Boolean = reporting.trace(i"$this mightAccountFor $x, ${x.captureSetOfInfo}?", show = true) { @@ -270,7 +270,7 @@ sealed abstract class CaptureSet extends Showable: def substParams(tl: BindingType, to: List[Type])(using Context) = map(Substituters.SubstParamsMap(tl, to)) - /** Invoke handler if this set has (or later aquires) the root capability `*` */ + /** Invoke handler if this set has (or later aquires) the root capability `cap` */ def disallowRootCapability(handler: () => Context ?=> Unit)(using Context): this.type = if isUniversal then handler() this @@ -372,7 +372,7 @@ object CaptureSet: def isConst = isSolved def isAlwaysEmpty = false - /** A handler to be invoked if the root reference `*` is added to this set */ + /** A handler to be invoked if the root reference `cap` is added to this set */ var rootAddedHandler: () => Context ?=> Unit = () => () var description: String = "" diff --git a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala index f9401a0c509f..72a166dbbecc 100644 --- a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala +++ b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala @@ -52,12 +52,12 @@ object CheckCaptures: * @param outer0 the next enclosing environment */ case class Env( - owner: Symbol, - nestedInOwner: Boolean, - captured: CaptureSet, - isBoxed: Boolean, - outer0: Env | Null - ): + owner: Symbol, + nestedInOwner: Boolean, + captured: CaptureSet, + isBoxed: Boolean, + outer0: Env | Null): + def outer = outer0.nn def isOutermost = outer0 == null @@ -433,7 +433,7 @@ class CheckCaptures extends Recheck, SymTransformer: case defn.FunctionOf(ptformals, _, _) if ptformals.nonEmpty && ptformals.forall(_.captureSet.isAlwaysEmpty) => // Redo setup of the anonymous function so that formal parameters don't - // get capture sets. This is important to avoid false widenings to `*` + // get capture sets. This is important to avoid false widenings to `cap` // when taking the base type of the actual closures's dependent function // type so that it conforms to the expected non-dependent function type. // See withLogFile.scala for a test case. @@ -582,7 +582,7 @@ class CheckCaptures extends Recheck, SymTransformer: refs.disallowRootCapability { () => val kind = if tree.isInstanceOf[ValDef] then "mutable variable" else "expression" report.error( - em"""The $kind's type $wtp is not allowed to capture the root capability `*`. + em"""The $kind's type $wtp is not allowed to capture the root capability `cap`. |This usually means that a capability persists longer than its allowed lifetime.""", tree.srcPos) } @@ -768,9 +768,9 @@ class CheckCaptures extends Recheck, SymTransformer: styp1.capturing(if alwaysConst then CaptureSet(cs1.elems) else cs1).forceBoxStatus(resultBoxed) if needsAdaptation then - val criticalSet = // the set which is not allowed to have `*` - if covariant then cs1 // can't box with `*` - else expected.captureSet // can't unbox with `*` + val criticalSet = // the set which is not allowed to have `cap` + if covariant then cs1 // can't box with `cap` + else expected.captureSet // can't unbox with `cap` if criticalSet.isUniversal && expected.isValueType then // We can't box/unbox the universal capability. Leave `actual` as it is // so we get an error in checkConforms. This tends to give better error @@ -779,11 +779,11 @@ class CheckCaptures extends Recheck, SymTransformer: println(i"cannot box/unbox $actual vs $expected") actual else - // Disallow future addition of `*` to `criticalSet`. + // Disallow future addition of `cap` to `criticalSet`. criticalSet.disallowRootCapability { () => report.error( em"""$actual cannot be box-converted to $expected - |since one of their capture sets contains the root capability `*`""", + |since one of their capture sets contains the root capability `cap`""", pos) } if !insertBox then // unboxing @@ -922,8 +922,8 @@ class CheckCaptures extends Recheck, SymTransformer: * usingLogFile[box ?1 () -> Unit] { (f: {*} File) => () => { f.write(0) } } * * We may propagate `f` into ?1, making ?1 ill-formed. - * This also causes soundness issues, since `f` in ?1 should be widened to `*`, - * giving rise to an error that `*` cannot be included in a boxed capture set. + * This also causes soundness issues, since `f` in ?1 should be widened to `cap`, + * giving rise to an error that `cap` cannot be included in a boxed capture set. * * To solve this, we still allow ?1 to capture parameter refs like `f`, but * compensate this by pushing the widened capture set of `f` into ?1. diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index b7211b3ce5e3..82b1a6354321 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -968,7 +968,7 @@ class Definitions { @tu lazy val BreakClass: Symbol = requiredClass("scala.util.boundary.Break") @tu lazy val CapsModule: Symbol = requiredModule("scala.caps") - @tu lazy val captureRoot: TermSymbol = CapsModule.requiredValue("*") + @tu lazy val captureRoot: TermSymbol = CapsModule.requiredValue("cap") @tu lazy val CapsUnsafeModule: Symbol = requiredModule("scala.caps.unsafe") @tu lazy val Caps_unsafeBox: Symbol = CapsUnsafeModule.requiredMethod("unsafeBox") @tu lazy val Caps_unsafeUnbox: Symbol = CapsUnsafeModule.requiredMethod("unsafeUnbox") diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 27e97a92b48e..5c718ef26289 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -286,7 +286,7 @@ object StdNames { // ----- Term names ----------------------------------------- // Compiler-internal - val CAPTURE_ROOT: N = "*" + val CAPTURE_ROOT: N = "cap" val CONSTRUCTOR: N = "" val STATIC_CONSTRUCTOR: N = "" val EVT2U: N = "evt2u$" @@ -301,6 +301,7 @@ object StdNames { val THROWS: N = "$throws" val U2EVT: N = "u2evt$" val ALLARGS: N = "$allArgs" + val UPARROW: N = "^" final val Nil: N = "Nil" final val Predef: N = "Predef" diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index fe0fc8a6dc2d..0a374cadd2ec 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2102,7 +2102,7 @@ object Types { */ final def isTracked(using Context): Boolean = canBeTracked && !captureSetOfInfo.isAlwaysEmpty - /** Is this reference the root capability `*` ? */ + /** Is this reference the root capability `cap` ? */ def isRootCapability(using Context): Boolean = false /** Normalize reference so that it can be compared with `eq` for equality */ @@ -4999,9 +4999,9 @@ object Types { if (!givenSelf.isValueType) appliedRef else if (clsd.is(Module)) givenSelf else if (ctx.erasedTypes) appliedRef - else givenSelf match - case givenSelf @ EventuallyCapturingType(tp, _) => - givenSelf.derivedAnnotatedType(tp & appliedRef, givenSelf.annot) + else givenSelf.dealiasKeepAnnots match + case givenSelf1 @ EventuallyCapturingType(tp, _) => + givenSelf1.derivedAnnotatedType(tp & appliedRef, givenSelf1.annot) case _ => AndType(givenSelf, appliedRef) } diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 7fecdd2c5eae..2f51af8549ae 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -970,29 +970,6 @@ object Parsers { isArrowIndent() else false - /** Under captureChecking language import: is the following token sequence a - * capture set `{ref1, ..., refN}` followed by a token that can start a type? - */ - def followingIsCaptureSet(): Boolean = - Feature.ccEnabled && { - val lookahead = in.LookaheadScanner() - def followingIsTypeStart() = - lookahead.nextToken() - canStartInfixTypeTokens.contains(lookahead.token) - || lookahead.token == LBRACKET - def recur(): Boolean = - (lookahead.isIdent || lookahead.token == THIS) && { - lookahead.nextToken() - if lookahead.token == COMMA then - lookahead.nextToken() - recur() - else - lookahead.token == RBRACE && followingIsTypeStart() - } - lookahead.nextToken() - if lookahead.token == RBRACE then followingIsTypeStart() else recur() - } - /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ var opStack: List[OpInfo] = Nil @@ -1475,17 +1452,21 @@ object Parsers { if in.token == RBRACE then Nil else commaSeparated(captureRef) } + def capturesAndResult(core: () => Tree): Tree = + if Feature.ccEnabled && in.token == LBRACE && in.offset == in.lastOffset + then CapturesAndResult(captureSet(), core()) + else core() + /** Type ::= FunType * | HkTypeParamClause ‘=>>’ Type * | FunParamClause ‘=>>’ Type * | MatchType * | InfixType - * | CaptureSet Type -- under captureChecking * FunType ::= (MonoFunType | PolyFunType) * MonoFunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type - * | (‘->’ | ‘?->’ ) Type -- under pureFunctions + * | (‘->’ | ‘?->’ ) [CaptureSet] Type -- under pureFunctions * PolyFunType ::= HKTypeParamClause '=>' Type - * | HKTypeParamClause ‘->’ Type -- under pureFunctions + * | HKTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions * FunTypeArgs ::= InfixType * | `(' [ [ ‘[using]’ ‘['erased'] FunArgType {`,' FunArgType } ] `)' * | '(' [ ‘[using]’ ‘['erased'] TypedFunParam {',' TypedFunParam } ')' @@ -1498,9 +1479,12 @@ object Parsers { val paramSpan = Span(start, in.lastOffset) atSpan(start, in.offset) { var token = in.token + var isPure = false if isPureArrow(nme.PUREARROW) then + isPure = true token = ARROW else if isPureArrow(nme.PURECTXARROW) then + isPure = true token = CTXARROW else if token == TLARROW then if !imods.flags.isEmpty || params.isEmpty then @@ -1519,7 +1503,7 @@ object Parsers { else accept(ARROW) - val resultType = typ() + val resultType = if isPure then capturesAndResult(typ) else typ() if token == TLARROW then for case ValDef(_, tpt, _) <- params do if isByNameType(tpt) then @@ -1612,8 +1596,6 @@ object Parsers { } else { accept(TLARROW); typ() } } - else if in.token == LBRACE && followingIsCaptureSet() then - CapturingTypeTree(captureSet(), typ()) else if (in.token == INDENT) enclosed(INDENT, typ()) else infixType() @@ -1683,6 +1665,7 @@ object Parsers { if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil /** InfixType ::= RefinedType {id [nl] RefinedType} + * | RefinedType `^` */ def infixType(): Tree = infixTypeRest(refinedType()) @@ -1690,19 +1673,41 @@ object Parsers { infixOps(t, canStartInfixTypeTokens, refinedTypeFn, Location.ElseWhere, ParseKind.Type, isOperator = !followingIsVararg() && !isPureArrow) - /** RefinedType ::= WithType {[nl] Refinement} + /** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet] */ val refinedTypeFn: Location => Tree = _ => refinedType() def refinedType() = refinedTypeRest(withType()) + /** Disambiguation: a `^` is treated as a postfix operator meaning `^{cap}` + * if followed by `{`, `->`, or `?->`, + * or followed by a new line (significant or not), + * or followed by a token that cannot start an infix type. + * Otherwise it is treated as an infix operator. + */ + private def isCaptureUpArrow = + val ahead = in.lookahead + ahead.token == LBRACE + || ahead.isIdent(nme.PUREARROW) + || ahead.isIdent(nme.PURECTXARROW) + || !canStartInfixTypeTokens.contains(ahead.token) + || ahead.lineOffset > 0 + def refinedTypeRest(t: Tree): Tree = { argumentStart() - if (in.isNestedStart) + if in.isNestedStart then refinedTypeRest(atSpan(startOffset(t)) { RefinedTypeTree(rejectWildcardType(t), refinement(indentOK = true)) }) - else t + else if Feature.ccEnabled && in.isIdent(nme.UPARROW) && isCaptureUpArrow then + val upArrowStart = in.offset + in.nextToken() + def cs = + if in.token == LBRACE then captureSet() + else atSpan(upArrowStart)(captureRoot) :: Nil + makeRetaining(t, cs, tpnme.retains) + else + t } /** WithType ::= AnnotType {`with' AnnotType} (deprecated) @@ -1929,31 +1934,10 @@ object Parsers { def paramTypeOf(core: () => Tree): Tree = if in.token == ARROW || isPureArrow(nme.PUREARROW) then val isImpure = in.token == ARROW - val tp = atSpan(in.skipToken()) { ByNameTypeTree(core()) } - if isImpure && Feature.pureFunsEnabled then ImpureByNameTypeTree(tp) else tp - else if in.token == LBRACE && followingIsCaptureSet() then - val start = in.offset - val cs = captureSet() - val endCsOffset = in.lastOffset - val startTpOffset = in.offset - val tp = paramTypeOf(core) - val tp1 = tp match - case ImpureByNameTypeTree(tp1) => - syntaxError(em"explicit captureSet is superfluous for impure call-by-name type", start) - tp1 - case CapturingTypeTree(_, tp1: ByNameTypeTree) => - syntaxError(em"only one captureSet is allowed here", start) - tp1 - case _: ByNameTypeTree if startTpOffset > endCsOffset => - report.warning( - i"""Style: by-name `->` should immediately follow closing `}` of capture set - |to avoid confusion with function type. - |That is, `{c}-> T` instead of `{c} -> T`.""", - source.atSpan(Span(startTpOffset, startTpOffset))) - tp - case _ => - tp - CapturingTypeTree(cs, tp1) + atSpan(in.skipToken()): + val tp = if isImpure then core() else capturesAndResult(core) + if isImpure && Feature.pureFunsEnabled then ImpureByNameTypeTree(tp) + else ByNameTypeTree(tp) else core() @@ -1966,13 +1950,13 @@ object Parsers { /** FunArgType ::= Type * | `=>' Type - * | [CaptureSet] `->' Type + * | `->' [CaptureSet] Type */ val funArgType: () => Tree = () => paramTypeOf(typ) /** ParamType ::= ParamValueType * | `=>' ParamValueType - * | [CaptureSet] `->' ParamValueType + * | `->' [CaptureSet] ParamValueType */ def paramType(): Tree = paramTypeOf(paramValueType) @@ -2040,8 +2024,6 @@ object Parsers { def typeDependingOn(location: Location): Tree = if location.inParens then typ() else if location.inPattern then rejectWildcardType(refinedType()) - else if in.token == LBRACE && followingIsCaptureSet() then - CapturingTypeTree(captureSet(), infixType()) else infixType() /* ----------- EXPRESSIONS ------------------------------------------------ */ @@ -2113,7 +2095,7 @@ object Parsers { * | ‘inline’ InfixExpr MatchClause * Bindings ::= `(' [Binding {`,' Binding}] `)' * Binding ::= (id | `_') [`:' Type] - * Ascription ::= `:' [CaptureSet] InfixType + * Ascription ::= `:' InfixType * | `:' Annotation {Annotation} * | `:' `_' `*' * Catches ::= ‘catch’ (Expr | ExprCaseClause) @@ -4172,8 +4154,8 @@ object Parsers { stats.toList } - /** SelfType ::= id [‘:’ [CaptureSet] InfixType] ‘=>’ - * | ‘this’ ‘:’ [CaptureSet] InfixType ‘=>’ + /** SelfType ::= id [‘:’ InfixType] ‘=>’ + * | ‘this’ ‘:’ InfixType ‘=>’ */ def selfType(): ValDef = if (in.isIdent || in.token == THIS) @@ -4189,10 +4171,7 @@ object Parsers { val selfTpt = if in.isColon then in.nextToken() - if in.token == LBRACE && followingIsCaptureSet() then - CapturingTypeTree(captureSet(), infixType()) - else - infixType() + infixType() else if selfName == nme.WILDCARD then accept(COLONfollow) TypeTree() diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index ee0062f77dcd..fa58c467bfa5 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -149,8 +149,21 @@ class PlainPrinter(_ctx: Context) extends Printer { + defn.ObjectClass + defn.FromJavaObjectSymbol - def toText(cs: CaptureSet): Text = - "{" ~ Text(cs.elems.toList.map(toTextCaptureRef), ", ") ~ "}" + def toTextCaptureSet(cs: CaptureSet): Text = + if printDebug && !cs.isConst then cs.toString + else if ctx.settings.YccDebug.value then cs.show + else if !cs.isConst && cs.elems.isEmpty then "?" + else "{" ~ Text(cs.elems.toList.map(toTextCaptureRef), ", ") ~ "}" + + /** Print capturing type, overridden in RefinedPrinter to account for + * capturing function types. + */ + protected def toTextCapturing(parent: Type, refsText: Text, boxText: Text): Text = + changePrec(InfixPrec): + boxText ~ toTextLocal(parent) ~ "^" + ~ (refsText provided refsText != rootSetText) + + final protected def rootSetText = Str("{*}") def toText(tp: Type): Text = controlled { homogenize(tp) match { @@ -207,20 +220,9 @@ class PlainPrinter(_ctx: Context) extends Printer { (" <: " ~ toText(bound) provided !bound.isAny) }.close case tp @ EventuallyCapturingType(parent, refs) => - def box = - Str("box ") provided tp.isBoxed //&& ctx.settings.YccDebug.value - def printRegular(refsText: Text) = - changePrec(GlobalPrec)(box ~ refsText ~ " " ~ toText(parent)) - if printDebug && !refs.isConst then - printRegular(refs.toString) - else if ctx.settings.YccDebug.value then - printRegular(refs.show) - else if !refs.isConst && refs.elems.isEmpty then - printRegular("?") - else if Config.printCaptureSetsAsPrefix then - printRegular(toText(refs)) - else - changePrec(InfixPrec)(box ~ toText(parent) ~ " @retains(" ~ toText(refs.elems.toList, ",") ~ ")") + val boxText: Text = Str("box ") provided tp.isBoxed //&& ctx.settings.YccDebug.value + val refsText = if refs.isUniversal then rootSetText else toTextCaptureSet(refs) + toTextCapturing(parent, refsText, boxText) case tp: PreviousErrorType if ctx.settings.XprintTypes.value => "" // do not print previously reported error message because they may try to print this error type again recuresevely case tp: ErrorType => @@ -241,14 +243,13 @@ class PlainPrinter(_ctx: Context) extends Printer { ~ (Str(": ") provided !tp.resultType.isInstanceOf[MethodOrPoly]) ~ toText(tp.resultType) } - case ExprType(ct @ EventuallyCapturingType(parent, refs)) - if ct.annot.symbol == defn.RetainsByNameAnnot => - if refs.isUniversal then changePrec(GlobalPrec) { "=> " ~ toText(parent) } - else toText(CapturingType(ExprType(parent), refs)) case ExprType(restp) => - changePrec(GlobalPrec) { - (if Feature.pureFunsEnabled then "-> " else "=> ") ~ toText(restp) - } + def arrowText: Text = restp match + case ct @ EventuallyCapturingType(parent, refs) if ct.annot.symbol == defn.RetainsByNameAnnot => + if refs.isUniversal then Str("=>") else Str("->") ~ toTextCaptureSet(refs) + case _ => + if Feature.pureFunsEnabled then "->" else "=>" + changePrec(GlobalPrec)(arrowText ~ " " ~ toText(restp)) case tp: HKTypeLambda => changePrec(GlobalPrec) { "[" ~ paramsText(tp) ~ "]" ~ lambdaHash(tp) ~ Str(" =>> ") ~ toTextGlobal(tp.resultType) @@ -385,7 +386,7 @@ class PlainPrinter(_ctx: Context) extends Printer { def toTextCaptureRef(tp: Type): Text = homogenize(tp) match - case tp: TermRef if tp.symbol == defn.captureRoot => Str("*") + case tp: TermRef if tp.symbol == defn.captureRoot => Str("cap") case tp: SingletonType => toTextRef(tp) case _ => toText(tp) diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 93de33778750..0a059fdf00eb 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -144,44 +144,55 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { private def arrow(isGiven: Boolean, isPure: Boolean): String = (if isGiven then "?" else "") + (if isPure then "->" else "=>") - override def toText(tp: Type): Text = controlled { - def toTextTuple(args: List[Type]): Text = - "(" ~ argsText(args) ~ ")" + private def toTextFunction(tp: AppliedType, refs: Text = Str("")): Text = + val AppliedType(tycon, args) = (tp: @unchecked) + val tsym = tycon.typeSymbol + val isGiven = tsym.name.isContextFunction + val capturesRoot = refs == rootSetText + val isPure = + Feature.pureFunsEnabled && !tsym.name.isImpureFunction && !capturesRoot + changePrec(GlobalPrec) { + val argStr: Text = + if args.length == 2 + && !defn.isTupleNType(args.head) + && !isGiven + then + atPrec(InfixPrec) { argText(args.head) } + else + "(" + ~ argsText(args.init) + ~ ")" + argStr + ~ " " ~ arrow(isGiven, isPure) + ~ (refs provided !capturesRoot) + ~ " " ~ argText(args.last) + } - def toTextFunction(args: List[Type], isGiven: Boolean, isPure: Boolean): Text = + private def toTextMethodAsFunction(info: Type, isPure: Boolean, refs: Text = Str("")): Text = info match + case info: MethodType => + val capturesRoot = refs == rootSetText changePrec(GlobalPrec) { - val argStr: Text = - if args.length == 2 - && !defn.isTupleNType(args.head) - && !isGiven - then - atPrec(InfixPrec) { argText(args.head) } - else - "(" - ~ argsText(args.init) - ~ ")" - argStr ~ " " ~ arrow(isGiven, isPure) ~ " " ~ argText(args.last) + "(" + ~ paramsText(info) + ~ ") " + ~ arrow(info.isImplicitMethod, isPure && !capturesRoot) + ~ (refs provided !capturesRoot) + ~ " " + ~ toTextMethodAsFunction(info.resultType, isPure) } + case info: PolyType => + changePrec(GlobalPrec) { + "[" + ~ paramsText(info) + ~ "] => " + ~ toTextMethodAsFunction(info.resultType, isPure) + } + case _ => + toText(info) - def toTextMethodAsFunction(info: Type, isPure: Boolean): Text = info match - case info: MethodType => - changePrec(GlobalPrec) { - "(" - ~ paramsText(info) - ~ ") " - ~ arrow(info.isImplicitMethod, isPure) - ~ " " - ~ toTextMethodAsFunction(info.resultType, isPure) - } - case info: PolyType => - changePrec(GlobalPrec) { - "[" - ~ paramsText(info) - ~ "] => " - ~ toTextMethodAsFunction(info.resultType, isPure) - } - case _ => - toText(info) + override def toText(tp: Type): Text = controlled { + def toTextTuple(args: List[Type]): Text = + "(" ~ argsText(args) ~ ")" def isInfixType(tp: Type): Boolean = tp match case AppliedType(tycon, args) => @@ -223,9 +234,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { val tsym = tycon.typeSymbol if tycon.isRepeatedParam then toTextLocal(args.head) ~ "*" else if tp.isConvertibleParam then "into " ~ toText(args.head) - else if defn.isFunctionSymbol(tsym) then - toTextFunction(args, tsym.name.isContextFunction, - isPure = Feature.pureFunsEnabled && !tsym.name.isImpureFunction) + else if defn.isFunctionSymbol(tsym) then toTextFunction(tp) else if isInfixType(tp) then val l :: r :: Nil = args: @unchecked val opName = tyconName(tycon) @@ -557,9 +566,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { toText(sel) ~ keywordStr(" match ") ~ blockText(cases) ~ (" <: " ~ toText(bound) provided !bound.isEmpty) } + case ImpureByNameTypeTree(tpt) => + "=> " ~ toTextLocal(tpt) case ByNameTypeTree(tpt) => - (if Feature.pureFunsEnabled then "-> " else "=> ") - ~ toTextLocal(tpt) + (if Feature.pureFunsEnabled then "-> " else "=> ") ~ toTextLocal(tpt) case TypeBoundsTree(lo, hi, alias) => if (lo eq hi) && alias.isEmpty then optText(lo)(" = " ~ _) else optText(lo)(" >: " ~ _) ~ optText(hi)(" <: " ~ _) ~ optText(alias)(" = " ~ _) @@ -618,7 +628,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def toTextAnnot = toTextLocal(arg) ~~ annotText(annot.symbol.enclosingClass, annot) def toTextRetainsAnnot = - try changePrec(GlobalPrec)(toText(captureSet) ~ " " ~ toText(arg)) + try changePrec(GlobalPrec)(toText(arg) ~ "^" ~ toTextCaptureSet(captureSet)) catch case ex: IllegalCaptureRef => toTextAnnot if annot.symbol.maybeOwner == defn.RetainsAnnot && Feature.ccEnabled && Config.printCaptureSetsAsPrefix && !printDebug @@ -730,17 +740,21 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { val contentText = toTextGlobal(content) val tptText = toTextGlobal(tpt) prefix ~~ idx.toString ~~ "|" ~~ tptText ~~ "|" ~~ argsText ~~ "|" ~~ contentText ~~ postfix - case CapturingTypeTree(refs, parent) => - parent match - case ImpureByNameTypeTree(bntpt) => - "=> " ~ toTextLocal(bntpt) - case _ => - changePrec(GlobalPrec)("{" ~ Text(refs.map(toText), ", ") ~ "} " ~ toText(parent)) + case CapturesAndResult(refs, parent) => + changePrec(GlobalPrec)("^{" ~ Text(refs.map(toText), ", ") ~ "}" ~ toText(parent)) case _ => tree.fallbackToText(this) } } + override protected def toTextCapturing(tp: Type, refsText: Text, boxText: Text): Text = tp match + case tp: AppliedType if defn.isFunctionSymbol(tp.typeSymbol) && !printDebug => + boxText ~ toTextFunction(tp, refsText) + case tp: RefinedType if defn.isFunctionOrPolyType(tp) && !printDebug => + boxText ~ toTextMethodAsFunction(tp.refinedInfo, isPure = !tp.typeSymbol.name.isImpureFunction, refsText) + case _ => + super.toTextCapturing(tp, refsText, boxText) + override def toText[T <: Untyped](tree: Tree[T]): Text = controlled { import untpd._ diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 7eb8519739c6..9f13071ae4b7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1389,6 +1389,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def typedFunctionType(tree: untpd.Function, pt: Type)(using Context): Tree = { val untpd.Function(args, body) = tree + body match + case untpd.CapturesAndResult(refs, result) => + return typedUnadapted(untpd.makeRetaining( + cpy.Function(tree)(args, result), refs, tpnme.retains), pt) + case _ => var (funFlags, erasedParams) = tree match { case tree: untpd.FunctionWithMods => (tree.mods.flags, tree.erasedParams) case _ => (EmptyFlags, args.map(_ => false)) @@ -2274,10 +2279,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer assignType(cpy.MatchTypeTree(tree)(bound1, sel1, cases1), bound1, sel1, cases1) } - def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(using Context): ByNameTypeTree = { - val result1 = typed(tree.result) - assignType(cpy.ByNameTypeTree(tree)(result1), result1) - } + def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(using Context): ByNameTypeTree = tree.result match + case untpd.CapturesAndResult(refs, tpe) => + typedByNameTypeTree( + cpy.ByNameTypeTree(tree)(untpd.makeRetaining(tpe, refs, tpnme.retainsByName))) + case _ => + val result1 = typed(tree.result) + assignType(cpy.ByNameTypeTree(tree)(result1), result1) def typedTypeBoundsTree(tree: untpd.TypeBoundsTree, pt: Type)(using Context): Tree = val TypeBoundsTree(lo, hi, alias) = tree diff --git a/library/src/scala/caps.scala b/library/src/scala/caps.scala index fb1721f98b35..6b7b085bbc06 100644 --- a/library/src/scala/caps.scala +++ b/library/src/scala/caps.scala @@ -4,9 +4,13 @@ import annotation.experimental @experimental object caps: - /** The universal capture reference */ + /** The universal capture reference (deprecated) */ + @deprecated("Use `cap` instead") val `*`: Any = () + /** The universal capture reference */ + val cap: Any = () + object unsafe: /** If argument is of type `cs T`, converts to type `box cs T`. This diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index d53eeb7077a4..5009d68a7247 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -5,6 +5,7 @@ object MiMaFilters { val Library: Seq[ProblemFilter] = Seq( ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.unsafeBox"), ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.unsafeUnbox"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.cap"), ProblemFilters.exclude[DirectMissingMethodProblem]("scala.CanEqual.canEqualMap"), ProblemFilters.exclude[MissingClassProblem]("scala.caps$Pure"), ProblemFilters.exclude[MissingClassProblem]("scala.caps$unsafe$"), diff --git a/tests/neg-custom-args/boxmap.scala b/tests/neg-custom-args/boxmap.scala index e66b0a8ec808..1696ac3505e4 100644 --- a/tests/neg-custom-args/boxmap.scala +++ b/tests/neg-custom-args/boxmap.scala @@ -1,5 +1,5 @@ import annotation.retains -type Top = Any @retains(caps.*) +type Top = Any @retains(caps.cap) type Box[+T <: Top] = ([K <: Top] -> (T => K) -> K) @@ -16,6 +16,6 @@ def test[A <: Top, B <: Top] = def lazymap[A <: Top, B <: Top](b: Box[A])(f: A => B) = () => b[Box[B]]((x: A) => box(f(x))) val x0: (b: Box[A]) -> (f: A => B) -> (() -> Box[B]) = lazymap[A, B] // error - val x: (b: Box[A]) -> (f: A => B) -> {b, f} (() -> Box[B]) = lazymap[A, B] // works - val y: (b: Box[A]) -> (f: A => B) -> {*} (() -> Box[B]) = lazymap[A, B] // works + val x: (b: Box[A]) -> (f: A => B) -> (() ->{b, f} Box[B]) = lazymap[A, B] // works + val y: (b: Box[A]) -> (f: A => B) -> (() ->{cap} Box[B]) = lazymap[A, B] // works () diff --git a/tests/neg-custom-args/capt-wf.scala b/tests/neg-custom-args/capt-wf.scala index 3bd80e0d0f68..67e1bc9906fe 100644 --- a/tests/neg-custom-args/capt-wf.scala +++ b/tests/neg-custom-args/capt-wf.scala @@ -1,35 +1,35 @@ class C -type Cap = {*} C +type Cap = C^ object foo def test(c: Cap, other: String): Unit = - val x1: {*} C = ??? // OK - val x2: {other} C = ??? // error: cs is empty + val x1: C^ = ??? // OK + val x2: C^{other} = ??? // error: cs is empty val s1 = () => "abc" - val x3: {s1} C = ??? // error: cs is empty + val x3: C^{s1} = ??? // error: cs is empty val x3a: () -> String = s1 val s2 = () => if x1 == null then "" else "abc" - val x4: {s2} C = ??? // OK - val x5: {c, c} C = ??? // error: redundant - val x6: {c} {c} C = ??? // error: redundant - val x7: {c} Cap = ??? // error: redundant - val x8: {*} {c} C = ??? // OK - val x9: {c, *} C = ??? // error: redundant - val x10: {*, c} C = ??? // error: redundant + val x4: C^{s2} = ??? // OK + val x5: C^{c, c} = ??? // error: redundant + // val x6: C^{c}^{c} = ??? // would be syntax error + val x7: Cap^{c} = ??? // error: redundant + // val x8: C^{c}^{cap} = ??? // would be syntax error + val x9: C^{c, cap} = ??? // error: redundant + val x10: C^{cap, c} = ??? // error: redundant def even(n: Int): Boolean = if n == 0 then true else odd(n - 1) def odd(n: Int): Boolean = if n == 1 then true else even(n - 1) val e1 = even val o1 = odd - val y1: {e1} String = ??? // error cs is empty - val y2: {o1} String = ??? // error cs is empty + val y1: String^{e1} = ??? // error cs is empty + val y2: String^{o1} = ??? // error cs is empty lazy val ev: (Int -> Boolean) = (n: Int) => lazy val od: (Int -> Boolean) = (n: Int) => if n == 1 then true else ev(n - 1) if n == 0 then true else od(n - 1) - val y3: {ev} String = ??? // error cs is empty + val y3: String^{ev} = ??? // error cs is empty () \ No newline at end of file diff --git a/tests/neg-custom-args/captures/boundschecks.scala b/tests/neg-custom-args/captures/boundschecks.scala index cf4eab28f19d..766d89d2f37b 100644 --- a/tests/neg-custom-args/captures/boundschecks.scala +++ b/tests/neg-custom-args/captures/boundschecks.scala @@ -6,13 +6,13 @@ object test { class C[X <: Tree](x: X) - def foo(t: {*} Tree) = + def foo(t: Tree^) = f(t) // error - f[{*} Tree](t) // error + f[Tree^](t) // error f[Tree](t) // error val c1 = C(t) // error - val c2 = C[{*} Tree](t) // error + val c2 = C[Tree^](t) // error val c3 = C[Tree](t) // error - val foo: C[{*} Tree] = ??? + val foo: C[Tree^] = ??? } diff --git a/tests/neg-custom-args/captures/boundschecks2.scala b/tests/neg-custom-args/captures/boundschecks2.scala index f6927b04931b..923758d722f9 100644 --- a/tests/neg-custom-args/captures/boundschecks2.scala +++ b/tests/neg-custom-args/captures/boundschecks2.scala @@ -6,8 +6,8 @@ object test { class C[X <: Tree](x: X) - val foo: C[{*} Tree] = ??? // error - type T = C[{*} Tree] // error + val foo: C[Tree^] = ??? // error + type T = C[Tree^] // error val bar: T -> T = ??? - val baz: C[{*} Tree] -> Unit = ??? // error + val baz: C[Tree^] -> Unit = ??? // error } diff --git a/tests/neg-custom-args/captures/box-adapt-boxing.scala b/tests/neg-custom-args/captures/box-adapt-boxing.scala index 7a624d4225fc..ea133051a21a 100644 --- a/tests/neg-custom-args/captures/box-adapt-boxing.scala +++ b/tests/neg-custom-args/captures/box-adapt-boxing.scala @@ -1,23 +1,23 @@ trait Cap -def main(io: {*} Cap, fs: {*} Cap): Unit = { - val test1: {} Unit -> Unit = _ => { // error - type Op = [T] -> ({io} T -> Unit) -> Unit - val f: ({io} Cap) -> Unit = ??? +def main(io: Cap^, fs: Cap^): Unit = { + val test1: Unit -> Unit = _ => { // error + type Op = [T] -> (T ->{io} Unit) -> Unit + val f: (Cap^{io}) -> Unit = ??? val op: Op = ??? - op[{io} Cap](f) + op[Cap^{io}](f) // expected type of f: {io} (box {io} Cap) -> Unit // actual type: ({io} Cap) -> Unit // adapting f to the expected type will also // charge the environment with {io} } - val test2: {} Unit -> Unit = _ => { + val test2: Unit -> Unit = _ => { type Box[X] = X type Op0[X] = Box[X] -> Unit type Op1[X] = Unit -> Box[X] - val f: Unit -> ({io} Cap) -> Unit = ??? - val test: {} Op1[{io} Op0[{io} Cap]] = f + val f: Unit -> (Cap^{io}) -> Unit = ??? + val test: Op1[Op0[Cap^{io}]^{io}]^{} = f // expected: {} Unit -> box {io} (box {io} Cap) -> Unit // actual: Unit -> ({io} Cap) -> Unit // @@ -31,8 +31,8 @@ def main(io: {*} Cap, fs: {*} Cap): Unit = { type Box[X] = X type Id[X] = Box[X] -> Unit type Op[X] = Unit -> Box[X] - val f: Unit -> ({io} Cap) -> Unit = ??? - val g: Op[{fs} Id[{io} Cap]] = f // error - val h: {} Op[{io} Id[{io} Cap]] = f + val f: Unit -> (Cap^{io}) -> Unit = ??? + val g: Op[Id[Cap^{io}]^{fs}] = f // error + val h: Op[Id[Cap^{io}]^{io}] = f } } diff --git a/tests/neg-custom-args/captures/box-adapt-cases.scala b/tests/neg-custom-args/captures/box-adapt-cases.scala index 049ff385d73c..351fab2bd8a5 100644 --- a/tests/neg-custom-args/captures/box-adapt-cases.scala +++ b/tests/neg-custom-args/captures/box-adapt-cases.scala @@ -3,27 +3,27 @@ trait Cap { def use(): Int } def test1(): Unit = { type Id[X] = [T] -> (op: X => T) -> T - val x: Id[{*} Cap] = ??? + val x: Id[Cap^] = ??? x(cap => cap.use()) // error } -def test2(io: {*} Cap): Unit = { +def test2(io: Cap^{cap}): Unit = { type Id[X] = [T] -> (op: X -> T) -> T - val x: Id[{io} Cap] = ??? + val x: Id[Cap^{io}] = ??? x(cap => cap.use()) // error } -def test3(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {io} X -> T) -> T +def test3(io: Cap^{cap}): Unit = { + type Id[X] = [T] -> (op: X ->{io} T) -> T - val x: Id[{io} Cap] = ??? + val x: Id[Cap^{io}] = ??? x(cap => cap.use()) // ok } -def test4(io: {*} Cap, fs: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {io} X -> T) -> T +def test4(io: Cap^{cap}, fs: Cap^{cap}): Unit = { + type Id[X] = [T] -> (op: X ->{io} T) -> T - val x: Id[{io, fs} Cap] = ??? + val x: Id[Cap^{io, fs}] = ??? x(cap => cap.use()) // error } diff --git a/tests/neg-custom-args/captures/box-adapt-cov.scala b/tests/neg-custom-args/captures/box-adapt-cov.scala index 2040a1c4654d..96901e81458d 100644 --- a/tests/neg-custom-args/captures/box-adapt-cov.scala +++ b/tests/neg-custom-args/captures/box-adapt-cov.scala @@ -1,14 +1,14 @@ trait Cap -def test1(io: {*} Cap) = { +def test1(io: Cap^{cap}) = { type Op[X] = [T] -> Unit -> X - val f: Op[{io} Cap] = ??? - val x: [T] -> Unit -> ({io} Cap) = f // error + val f: Op[Cap^{io}] = ??? + val x: [T] -> Unit -> Cap^{io} = f // error } -def test2(io: {*} Cap) = { - type Op[X] = [T] -> Unit -> {io} X - val f: Op[{io} Cap] = ??? - val x: Unit -> ({io} Cap) = f[Unit] // error - val x1: {io} Unit -> ({io} Cap) = f[Unit] // ok +def test2(io: Cap^{cap}) = { + type Op[X] = [T] -> Unit -> X^{io} + val f: Op[Cap^{io}] = ??? + val x: Unit -> Cap^{io} = f[Unit] // error + val x1: Unit ->{io} Cap^{io} = f[Unit] // ok } diff --git a/tests/neg-custom-args/captures/box-adapt-cs.scala b/tests/neg-custom-args/captures/box-adapt-cs.scala index e35388efd203..a39ed0200151 100644 --- a/tests/neg-custom-args/captures/box-adapt-cs.scala +++ b/tests/neg-custom-args/captures/box-adapt-cs.scala @@ -1,19 +1,17 @@ trait Cap { def use(): Int } -def test1(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {io} X -> T) -> T +def test1(io: Cap^{cap}): Unit = { + type Id[X] = [T] -> (op: X ->{io} T) -> T - val x: Id[{io} Cap] = ??? - val f: ({*} Cap) -> Unit = ??? + val x: Id[Cap^{io}] = ??? + val f: (Cap^{cap}) -> Unit = ??? x(f) // ok - // actual: {*} Cap -> Unit - // expected: {io} box {io} Cap -> Unit } -def test2(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {*} X -> T) -> T +def test2(io: Cap^{cap}): Unit = { + type Id[X] = [T] -> (op: X => T) -> T - val x: Id[{*} Cap] = ??? - val f: ({io} Cap) -> Unit = ??? + val x: Id[Cap^] = ??? + val f: Cap^{io} -> Unit = ??? x(f) // error } diff --git a/tests/neg-custom-args/captures/box-adapt-depfun.scala b/tests/neg-custom-args/captures/box-adapt-depfun.scala index 294e2c33f7fa..9416ffa040ab 100644 --- a/tests/neg-custom-args/captures/box-adapt-depfun.scala +++ b/tests/neg-custom-args/captures/box-adapt-depfun.scala @@ -1,23 +1,23 @@ trait Cap { def use(): Int } -def test1(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {io} X -> T) -> T +def test1(io: Cap^): Unit = { + type Id[X] = [T] -> (op: X ->{io} T) -> T - val x: Id[{io} Cap] = ??? + val x: Id[Cap]^{io} = ??? x(cap => cap.use()) // ok } -def test2(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {io} (x: X) -> T) -> T +def test2(io: Cap^): Unit = { + type Id[X] = [T] -> (op: (x: X) ->{io} T) -> T - val x: Id[{io} Cap] = ??? + val x: Id[Cap^{io}] = ??? x(cap => cap.use()) // should work when the expected type is a dependent function } -def test3(io: {*} Cap): Unit = { - type Id[X] = [T] -> (op: {} (x: X) -> T) -> T +def test3(io: Cap^{cap}): Unit = { + type Id[X] = [T] -> (op: (x: X) ->{} T) -> T - val x: Id[{io} Cap] = ??? + val x: Id[Cap^{io}] = ??? x(cap => cap.use()) // error } diff --git a/tests/neg-custom-args/captures/box-adapt-typefun.scala b/tests/neg-custom-args/captures/box-adapt-typefun.scala index b14b07e72e9b..65a06cd68ed9 100644 --- a/tests/neg-custom-args/captures/box-adapt-typefun.scala +++ b/tests/neg-custom-args/captures/box-adapt-typefun.scala @@ -1,13 +1,13 @@ trait Cap { def use(): Int } -def test1(io: {*} Cap): Unit = { +def test1(io: Cap^{cap}): Unit = { type Op[X] = [T] -> X -> Unit - val f: [T] -> ({io} Cap) -> Unit = ??? - val op: Op[{io} Cap] = f // error + val f: [T] -> (Cap^{io}) -> Unit = ??? + val op: Op[Cap^{io}] = f // error } -def test2(io: {*} Cap): Unit = { +def test2(io: Cap^{cap}): Unit = { type Lazy[X] = [T] -> Unit -> X - val f: Lazy[{io} Cap] = ??? - val test: [T] -> Unit -> ({io} Cap) = f // error + val f: Lazy[Cap^{io}] = ??? + val test: [T] -> Unit -> (Cap^{io}) = f // error } diff --git a/tests/neg-custom-args/captures/byname.check b/tests/neg-custom-args/captures/byname.check index 90cf6c145c33..b1d8fb3b5404 100644 --- a/tests/neg-custom-args/captures/byname.check +++ b/tests/neg-custom-args/captures/byname.check @@ -1,20 +1,14 @@ --- Warning: tests/neg-custom-args/captures/byname.scala:17:18 ---------------------------------------------------------- -17 | def h(x: {cap1} -> I) = x // warning - | ^ - | Style: by-name `->` should immediately follow closing `}` of capture set - | to avoid confusion with function type. - | That is, `{c}-> T` instead of `{c} -> T`. -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:10:6 ---------------------------------------- 10 | h(f2()) // error | ^^^^ - | Found: {cap1} (x$0: Int) -> Int - | Required: {cap2} (x$0: Int) -> Int + | Found: (x$0: Int) ->{cap1} Int + | Required: (x$0: Int) ->{cap2} Int | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:19:5 ---------------------------------------- 19 | h(g()) // error | ^^^ - | Found: {cap2} () ?-> I - | Required: {cap1} () ?-> I + | Found: () ?->{cap2} I + | Required: () ?->{cap1} I | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/byname.scala b/tests/neg-custom-args/captures/byname.scala index 1838647f2899..ac13174eb4f4 100644 --- a/tests/neg-custom-args/captures/byname.scala +++ b/tests/neg-custom-args/captures/byname.scala @@ -5,16 +5,16 @@ def test(cap1: Cap, cap2: Cap) = def g(x: Int) = if cap2 == cap2 then 1 else x def g2(x: Int) = if cap1 == cap1 then 1 else x def f2() = if cap1 == cap1 then g2 else g2 - def h(ff: => {cap2} Int -> Int) = ff + def h(ff: => Int ->{cap2} Int) = ff h(f()) // ok h(f2()) // error class I -def test2(cap1: Cap, cap2: Cap): {cap1} I = +def test2(cap1: Cap, cap2: Cap): I^{cap1} = def f() = if cap1 == cap1 then I() else I() def g() = if cap2 == cap2 then I() else I() - def h(x: {cap1} -> I) = x // warning + def h(x: ->{cap1} I) = x // ok h(f()) // OK h(g()) // error diff --git a/tests/neg-custom-args/captures/capt-depfun.scala b/tests/neg-custom-args/captures/capt-depfun.scala index c01eed7c4b25..20226b239198 100644 --- a/tests/neg-custom-args/captures/capt-depfun.scala +++ b/tests/neg-custom-args/captures/capt-depfun.scala @@ -1,9 +1,9 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) class Str def f(y: Cap, z: Cap) = def g(): C @retains(y, z) = ??? val ac: ((x: Cap) => Str @retains(x) => Str @retains(x)) = ??? - val dc: (({y, z} Str) => {y, z} Str) = ac(g()) // error + val dc: ((Str^{y, z}) => Str^{y, z}) = ac(g()) // error diff --git a/tests/neg-custom-args/captures/capt-depfun2.scala b/tests/neg-custom-args/captures/capt-depfun2.scala index 52dd74aabf9f..cb4bc5f9634d 100644 --- a/tests/neg-custom-args/captures/capt-depfun2.scala +++ b/tests/neg-custom-args/captures/capt-depfun2.scala @@ -1,6 +1,6 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) class Str def f(y: Cap, z: Cap) = diff --git a/tests/neg-custom-args/captures/capt-env.scala b/tests/neg-custom-args/captures/capt-env.scala index 52fa4abfdaa8..6602678af167 100644 --- a/tests/neg-custom-args/captures/capt-env.scala +++ b/tests/neg-custom-args/captures/capt-env.scala @@ -1,5 +1,5 @@ class C -type Cap = {*} C +type Cap = C^ class Pair[+A, +B](x: A, y: B): def fst: A = x diff --git a/tests/neg-custom-args/captures/capt-test.scala b/tests/neg-custom-args/captures/capt-test.scala index 1799fc5073ca..13368aeea190 100644 --- a/tests/neg-custom-args/captures/capt-test.scala +++ b/tests/neg-custom-args/captures/capt-test.scala @@ -2,8 +2,8 @@ import annotation.retains import language.experimental.erasedDefinitions class CT[E <: Exception] -type CanThrow[E <: Exception] = CT[E] @retains(caps.*) -type Top = Any @retains(caps.*) +type CanThrow[E <: Exception] = CT[E] @retains(caps.cap) +type Top = Any @retains(caps.cap) infix type throws[R, E <: Exception] = (erased CanThrow[E]) ?=> R diff --git a/tests/neg-custom-args/captures/capt-wf-typer.scala b/tests/neg-custom-args/captures/capt-wf-typer.scala index 4fc50caed1f7..09b2841d3c77 100644 --- a/tests/neg-custom-args/captures/capt-wf-typer.scala +++ b/tests/neg-custom-args/captures/capt-wf-typer.scala @@ -1,11 +1,11 @@ import annotation.retains class C -type Cap = {*} C +type Cap = C^ object foo def test(c: Cap, other: String): Unit = - val x7: {c} String = ??? // OK + val x7: String^{c} = ??? // OK val x8: String @retains(x7 + x7) = ??? // error val x9: String @retains(foo) = ??? // error () \ No newline at end of file diff --git a/tests/neg-custom-args/captures/capt-wf2.scala b/tests/neg-custom-args/captures/capt-wf2.scala index ddde535fcab0..6c65e0dc77f7 100644 --- a/tests/neg-custom-args/captures/capt-wf2.scala +++ b/tests/neg-custom-args/captures/capt-wf2.scala @@ -1,5 +1,5 @@ @annotation.capability class C def test(c: C) = - var x: {c} Any = ??? - val y: {x} Any = x // error + var x: Any^{c} = ??? + val y: Any^{x} = x // error diff --git a/tests/neg-custom-args/captures/capt1.check b/tests/neg-custom-args/captures/capt1.check index 51ed3e6736cf..f51d4631782d 100644 --- a/tests/neg-custom-args/captures/capt1.check +++ b/tests/neg-custom-args/captures/capt1.check @@ -1,21 +1,21 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:4:2 ------------------------------------------ 4 | () => if x == null then y else y // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: {x} () -> ? C + | Found: () ->{x} C^? | Required: () -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:7:2 ------------------------------------------ 7 | () => if x == null then y else y // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: {x} () -> ? C + | Found: () ->{x} C^? | Required: Matchable | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:14:2 ----------------------------------------- 14 | def f(y: Int) = if x == null then y else y // error | ^ - | Found: {x} Int -> Int + | Found: Int ->{x} Int | Required: Matchable 15 | f | @@ -23,7 +23,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:21:2 ----------------------------------------- 21 | class F(y: Int) extends A: // error | ^ - | Found: {x} A + | Found: A^{x} | Required: A 22 | def m() = if x == null then y else y 23 | F(22) @@ -32,7 +32,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:26:2 ----------------------------------------- 26 | new A: // error | ^ - | Found: {x} A + | Found: A^{x} | Required: A 27 | def m() = if x == null then y else y | @@ -40,14 +40,14 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:32:24 ---------------------------------------- 32 | val z2 = h[() -> Cap](() => x) // error | ^^^^^^^ - | Found: {x} () -> Cap - | Required: () -> box {*} C + | Found: () ->{x} Cap + | Required: () -> box C^ | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:33:5 ----------------------------------------- 33 | (() => C()) // error | ^^^^^^^^^ - | Found: ? () -> Cap - | Required: () -> box {*} C + | Found: () ->? Cap + | Required: () -> box C^ | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/capt1.scala b/tests/neg-custom-args/captures/capt1.scala index 59ba874b02f5..69b4c9984494 100644 --- a/tests/neg-custom-args/captures/capt1.scala +++ b/tests/neg-custom-args/captures/capt1.scala @@ -1,21 +1,21 @@ import annotation.retains class C -def f(x: C @retains(caps.*), y: C): () -> C = +def f(x: C @retains(caps.cap), y: C): () -> C = () => if x == null then y else y // error -def g(x: C @retains(caps.*), y: C): Matchable = +def g(x: C @retains(caps.cap), y: C): Matchable = () => if x == null then y else y // error -def h1(x: C @retains(caps.*), y: C): Any = +def h1(x: C @retains(caps.cap), y: C): Any = def f() = if x == null then y else y () => f() // ok -def h2(x: C @retains(caps.*)): Matchable = +def h2(x: C @retains(caps.cap)): Matchable = def f(y: Int) = if x == null then y else y // error f class A -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) def h3(x: Cap): A = class F(y: Int) extends A: // error @@ -27,7 +27,7 @@ def h4(x: Cap, y: Int): A = def m() = if x == null then y else y def foo() = - val x: C @retains(caps.*) = ??? + val x: C @retains(caps.cap) = ??? def h[X](a: X)(b: X) = a val z2 = h[() -> Cap](() => x) // error (() => C()) // error diff --git a/tests/neg-custom-args/captures/capt2.scala b/tests/neg-custom-args/captures/capt2.scala index 8b08832dfdb9..cd6f41424a22 100644 --- a/tests/neg-custom-args/captures/capt2.scala +++ b/tests/neg-custom-args/captures/capt2.scala @@ -1,9 +1,9 @@ //import scala.retains class C -type Cap = {*} C +type Cap = C^ -def f1(c: Cap): (() -> {c} C) = () => c // error, but would be OK under capture abbreciations for funciton types -def f2(c: Cap): ({c} () -> C) = () => c // error +def f1(c: Cap): (() -> C^{c}) = () => c // error, but would be OK under capture abbreciations for funciton types +def f2(c: Cap): (() ->{c} C) = () => c // error def h5(x: Cap): () -> C = f1(x) // error diff --git a/tests/neg-custom-args/captures/capt3.scala b/tests/neg-custom-args/captures/capt3.scala index 84164d433029..44a7ffdc6c4a 100644 --- a/tests/neg-custom-args/captures/capt3.scala +++ b/tests/neg-custom-args/captures/capt3.scala @@ -1,6 +1,6 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) def test1() = val x: Cap = C() diff --git a/tests/neg-custom-args/captures/caseclass/Test_2.scala b/tests/neg-custom-args/captures/caseclass/Test_2.scala index 4eac6a260292..bffc0a295bdc 100644 --- a/tests/neg-custom-args/captures/caseclass/Test_2.scala +++ b/tests/neg-custom-args/captures/caseclass/Test_2.scala @@ -2,7 +2,7 @@ def test(c: C) = val pure: () -> Unit = () => () val impure: () => Unit = pure - val mixed: {c} () -> Unit = pure + val mixed: () ->{c} Unit = pure val x = Ref(impure) val _: Ref = x // error val y = x.copy() @@ -16,10 +16,10 @@ def test(c: C) = val yc2: Ref = y2 val x3 = Ref(mixed) - val _: {c} Ref = x3 + val _: Ref^{c} = x3 val y3 = x3.copy() - val yc3: {c} Ref = y3 + val yc3: Ref^{c} = y3 val y4 = y3 match case Ref(xx) => xx - val y4c: {x3} () -> Unit = y4 + val y4c: () ->{x3} Unit = y4 diff --git a/tests/neg-custom-args/captures/cc-depfun.scala b/tests/neg-custom-args/captures/cc-depfun.scala index c4ef303f4712..106a73dd7ce1 100644 --- a/tests/neg-custom-args/captures/cc-depfun.scala +++ b/tests/neg-custom-args/captures/cc-depfun.scala @@ -1,9 +1,9 @@ trait Cap { def use(): Unit } def main() = { - val f: (io: {*} Cap) -> {} () -> Unit = + val f: (io: Cap^) -> () ->{} Unit = io => () => io.use() // error - val g: ({*} Cap) -> {} () -> Unit = + val g: (Cap^) -> () ->{} Unit = io => () => io.use() // error } diff --git a/tests/neg-custom-args/captures/cc-this.check b/tests/neg-custom-args/captures/cc-this.check index 0049f42a5db5..47207f913f1d 100644 --- a/tests/neg-custom-args/captures/cc-this.check +++ b/tests/neg-custom-args/captures/cc-this.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-this.scala:8:15 --------------------------------------- 8 | val y: C = this // error | ^^^^ - | Found: (C.this : {C.this.x} C) + | Found: (C.this : C^{C.this.x}) | Required: C | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-this2.check b/tests/neg-custom-args/captures/cc-this2.check index 086524d307a2..e0df7c857c85 100644 --- a/tests/neg-custom-args/captures/cc-this2.check +++ b/tests/neg-custom-args/captures/cc-this2.check @@ -2,5 +2,5 @@ -- Error: tests/neg-custom-args/captures/cc-this2/D_2.scala:2:6 -------------------------------------------------------- 2 |class D extends C: // error |^ - |reference (scala.caps.* : Any) is not included in allowed capture set {} of pure base class class C -3 | this: {*} D => + |reference (scala.caps.cap : Any) is not included in allowed capture set {} of pure base class class C +3 | this: D^ => diff --git a/tests/neg-custom-args/captures/cc-this2/D_2.scala b/tests/neg-custom-args/captures/cc-this2/D_2.scala index 793f3f6353a9..b22e5e456092 100644 --- a/tests/neg-custom-args/captures/cc-this2/D_2.scala +++ b/tests/neg-custom-args/captures/cc-this2/D_2.scala @@ -1,3 +1,3 @@ class D extends C: // error - this: {*} D => + this: D^ => diff --git a/tests/neg-custom-args/captures/cc-this3.check b/tests/neg-custom-args/captures/cc-this3.check index 705cdfbc00d7..d57471c6872e 100644 --- a/tests/neg-custom-args/captures/cc-this3.check +++ b/tests/neg-custom-args/captures/cc-this3.check @@ -1,14 +1,14 @@ -- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this3.scala:8:6 --------------------------------------- 8 |class B extends A: // error | ^ - | illegal inheritance: self type {*} B of class B does not conform to self type {} A + | illegal inheritance: self type B^ of class B does not conform to self type A^{} | of parent class A | | longer explanation available when compiling with `-explain` -- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this3.scala:11:6 -------------------------------------- 11 |class C(val f: () => Int) extends A // error | ^ - | illegal inheritance: self type {C.this.f} C of class C does not conform to self type {} A + | illegal inheritance: self type C^{C.this.f} of class C does not conform to self type A^{} | of parent class A | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-this3.scala b/tests/neg-custom-args/captures/cc-this3.scala index eeb9606f0c81..25af19dd6c4a 100644 --- a/tests/neg-custom-args/captures/cc-this3.scala +++ b/tests/neg-custom-args/captures/cc-this3.scala @@ -6,13 +6,13 @@ class A: val x: A = this class B extends A: // error - this: {*} B => + this: B^ => class C(val f: () => Int) extends A // error class A2 class B2 extends A2: // ok - this: {*} B2 => + this: B2^ => class C2(val f: () => Int) extends A2 // ok diff --git a/tests/neg-custom-args/captures/cc-this4.check b/tests/neg-custom-args/captures/cc-this4.check index a54ca8d57f4e..52c06f5bbc30 100644 --- a/tests/neg-custom-args/captures/cc-this4.check +++ b/tests/neg-custom-args/captures/cc-this4.check @@ -2,5 +2,5 @@ 1 |open class C: // error | ^ | class C needs an explicitly declared self type since its - | inferred self type {} C + | inferred self type C^{} | is not visible in other compilation units that define subclasses. diff --git a/tests/neg-custom-args/captures/cc-this5.check b/tests/neg-custom-args/captures/cc-this5.check index 8cc1ac9ccc5d..84ac97474b80 100644 --- a/tests/neg-custom-args/captures/cc-this5.check +++ b/tests/neg-custom-args/captures/cc-this5.check @@ -5,14 +5,14 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-this5.scala:21:15 ------------------------------------- 21 | val x: A = this // error | ^^^^ - | Found: (A.this : {c} A) + | Found: (A.this : A^{c}) | Required: A | | longer explanation available when compiling with `-explain` -- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this5.scala:7:9 --------------------------------------- 7 | object D extends C: // error | ^ - | illegal inheritance: self type {c} D.type of object D does not conform to self type {} C + | illegal inheritance: self type D.type^{c} of object D does not conform to self type C^{} | of parent class C | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc1.scala b/tests/neg-custom-args/captures/cc1.scala index 10a9793eabe8..6787b417a3b2 100644 --- a/tests/neg-custom-args/captures/cc1.scala +++ b/tests/neg-custom-args/captures/cc1.scala @@ -1,5 +1,5 @@ import annotation.retains object Test: - def f[A <: Matchable @retains(caps.*)](x: A): Matchable = x // error + def f[A <: Matchable @retains(caps.cap)](x: A): Matchable = x // error diff --git a/tests/neg-custom-args/captures/class-constr.scala b/tests/neg-custom-args/captures/class-constr.scala index eeedf1043f37..9afb6972ccfa 100644 --- a/tests/neg-custom-args/captures/class-constr.scala +++ b/tests/neg-custom-args/captures/class-constr.scala @@ -6,10 +6,10 @@ class C(x: Cap, @constructorOnly y: Cap) def test(a: Cap, b: Cap) = val f = () => C(a, b) - val f_ok: {a, b} () -> {a} C = f - val f_no1: {a, b} () -> C = f // error - val f_no2: {a} () -> {a} C = f // error - val f_no3: {b} () -> {a} C = f // error + val f_ok: () ->{a, b} C^{a} = f + val f_no1: () ->{a, b} C = f // error + val f_no2: () ->{a} C^{a} = f // error + val f_no3: () ->{a} C^{a} = f // error class D: val xz = @@ -19,6 +19,6 @@ def test(a: Cap, b: Cap) = println(b) 2 val d = () => new D() - val d_ok1: {a, b} () -> {a, b} D = d - val d_ok2: () -> {a, b} D = d // because of function shorthand - val d_ok3: {a, b} () -> {b} D = d // error, but should work + val d_ok1: () ->{a, b} D^{a, b} = d + val d_ok2: () -> D^{a, b} = d // because of function shorthand + val d_ok3: () ->{a, b} D^{b} = d // error, but should work diff --git a/tests/neg-custom-args/captures/class-contra.check b/tests/neg-custom-args/captures/class-contra.check index 69a5f0097de8..6d4c89f872ad 100644 --- a/tests/neg-custom-args/captures/class-contra.check +++ b/tests/neg-custom-args/captures/class-contra.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/class-contra.scala:12:39 --------------------------------- -12 | def fun(x: K{val f: {a} T}) = x.setf(a) // error +12 | def fun(x: K{val f: T^{a}}) = x.setf(a) // error | ^ - | Found: (a : {x, y} T) + | Found: (a : T^{x, y}) | Required: T | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/class-contra.scala b/tests/neg-custom-args/captures/class-contra.scala index 270aaf9309a9..210fd4e331f1 100644 --- a/tests/neg-custom-args/captures/class-contra.scala +++ b/tests/neg-custom-args/captures/class-contra.scala @@ -1,13 +1,13 @@ class C -type Cap = {*} C +type Cap = C^ -class K(val f: {*} T): - def setf(x: {f} T) = ??? +class K(val f: T^): + def setf(x: T^{f}) = ??? class T def test(x: Cap, y: Cap) = - val a: {x, y} T = ??? - def fun(x: K{val f: {a} T}) = x.setf(a) // error + val a: T^{x, y} = ??? + def fun(x: K{val f: T^{a}}) = x.setf(a) // error () \ No newline at end of file diff --git a/tests/neg-custom-args/captures/classes.scala b/tests/neg-custom-args/captures/classes.scala index e4c141ea981b..3572e31a6f50 100644 --- a/tests/neg-custom-args/captures/classes.scala +++ b/tests/neg-custom-args/captures/classes.scala @@ -1,12 +1,12 @@ class B -type Cap = {*} B +type Cap = B^ class C0(n: Cap) // was error: class parameter must be a `val`, now OK class C(val n: Cap): - def foo(): {n} B = n + def foo(): B^{n} = n def test(x: Cap, y: Cap) = val c0 = C(x) val c1: C = c0 // error val c2 = if ??? then C(x) else identity(C(y)) - val c3: {x} C { val n: {x, y} B } = c2 // error + val c3: C { val n: B^{x, y} }^{x} = c2 // error diff --git a/tests/neg-custom-args/captures/ctest.scala b/tests/neg-custom-args/captures/ctest.scala index 08bec16d8177..37d6ad034936 100644 --- a/tests/neg-custom-args/captures/ctest.scala +++ b/tests/neg-custom-args/captures/ctest.scala @@ -1,5 +1,5 @@ class CC -type Cap = {*} CC +type Cap = CC^ def test(cap1: Cap, cap2: Cap) = var b: List[String => String] = Nil // was error, now OK diff --git a/tests/neg-custom-args/captures/curried-simplified.check b/tests/neg-custom-args/captures/curried-simplified.check index 5d23a7a4955e..6a792314e4e3 100644 --- a/tests/neg-custom-args/captures/curried-simplified.check +++ b/tests/neg-custom-args/captures/curried-simplified.check @@ -1,42 +1,42 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:7:28 ---------------------------- 7 | def y1: () -> () -> Int = x1 // error | ^^ - | Found: {x} () -> {x} () -> Int + | Found: () ->? () ->{x} Int | Required: () -> () -> Int | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:9:28 ---------------------------- 9 | def y2: () -> () => Int = x2 // error | ^^ - | Found: {x} () -> {*} () -> Int + | Found: () ->{x} () => Int | Required: () -> () => Int | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:11:39 --------------------------- 11 | def y3: Cap -> Protect[Int -> Int] = x3 // error | ^^ - | Found: ? (x$0: Cap) -> {x$0} Int -> Int + | Found: (x$0: Cap) ->? Int ->{x$0} Int | Required: Cap -> Protect[Int -> Int] | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:15:33 --------------------------- -15 | def y5: Cap -> {} Int -> Int = x5 // error - | ^^ - | Found: ? Cap -> {x} Int -> Int - | Required: Cap -> {} Int -> Int +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:15:32 --------------------------- +15 | def y5: Cap -> Int ->{} Int = x5 // error + | ^^ + | Found: Cap ->? Int ->{x} Int + | Required: Cap -> Int ->{} Int | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:17:49 --------------------------- -17 | def y6: Cap -> {} Cap -> Protect[Int -> Int] = x6 // error - | ^^ - | Found: ? (x$0: Cap) -> {x$0} (x$0: Cap) -> {x$0, x$0} Int -> Int - | Required: Cap -> {} Cap -> Protect[Int -> Int] +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:17:48 --------------------------- +17 | def y6: Cap -> Cap ->{} Protect[Int -> Int] = x6 // error + | ^^ + | Found: (x$0: Cap) ->? (x$0: Cap) ->{x$0} Int ->{x$0, x$0} Int + | Required: Cap -> Cap ->{} Protect[Int -> Int] | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:19:49 --------------------------- -19 | def y7: Cap -> Protect[Cap -> {} Int -> Int] = x7 // error - | ^^ - | Found: ? (x$0: Cap) -> {x$0} (x: Cap) -> {x$0, x} Int -> Int - | Required: Cap -> Protect[Cap -> {} Int -> Int] +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:19:48 --------------------------- +19 | def y7: Cap -> Protect[Cap -> Int ->{} Int] = x7 // error + | ^^ + | Found: (x$0: Cap) ->? (x: Cap) ->{x$0} Int ->{x$0, x} Int + | Required: Cap -> Protect[Cap -> Int ->{} Int] | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/curried-simplified.scala b/tests/neg-custom-args/captures/curried-simplified.scala index 25b23370d154..988cf7c11c45 100644 --- a/tests/neg-custom-args/captures/curried-simplified.scala +++ b/tests/neg-custom-args/captures/curried-simplified.scala @@ -3,19 +3,19 @@ type Protect[T] = T def test(x: Cap, y: Cap) = - def x1: {x} () -> () -> Int = ??? + def x1: () -> () ->{x} Int = ??? def y1: () -> () -> Int = x1 // error - def x2: {x} () -> () => Int = ??? + def x2: () ->{x} () => Int = ??? def y2: () -> () => Int = x2 // error def x3: Cap -> Int -> Int = ??? def y3: Cap -> Protect[Int -> Int] = x3 // error def x4: Cap -> Protect[Int -> Int] = ??? - def y4: Cap -> {} Int -> Int = x4 // ok - def x5: Cap -> {x} Int -> Int = ??? - def y5: Cap -> {} Int -> Int = x5 // error + def y4: Cap -> Int ->{} Int = x4 // ok + def x5: Cap -> Int ->{x} Int = ??? + def y5: Cap -> Int ->{} Int = x5 // error def x6: Cap -> Cap -> Int -> Int = ??? - def y6: Cap -> {} Cap -> Protect[Int -> Int] = x6 // error + def y6: Cap -> Cap ->{} Protect[Int -> Int] = x6 // error def x7: Cap -> (x: Cap) -> Int -> Int = ??? - def y7: Cap -> Protect[Cap -> {} Int -> Int] = x7 // error + def y7: Cap -> Protect[Cap -> Int ->{} Int] = x7 // error diff --git a/tests/neg-custom-args/captures/emptyref-in-self.scala b/tests/neg-custom-args/captures/emptyref-in-self.scala index 60f782deca6b..8bac47212f5b 100644 --- a/tests/neg-custom-args/captures/emptyref-in-self.scala +++ b/tests/neg-custom-args/captures/emptyref-in-self.scala @@ -1,3 +1,3 @@ -class Zip[A, B](underlying: String, other: {*} String) { - this: {underlying, other} Zip[A, B] => // error +class Zip[A, B](underlying: String, other: String^) { + this: Zip[A, B]^{underlying, other} => // error } diff --git a/tests/neg-custom-args/captures/eta.check b/tests/neg-custom-args/captures/eta.check index ebd63855181b..a77d66382095 100644 --- a/tests/neg-custom-args/captures/eta.check +++ b/tests/neg-custom-args/captures/eta.check @@ -1,14 +1,14 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/eta.scala:4:9 -------------------------------------------- 4 | g // error | ^ - | Found: ? () -> A - | Required: () -> {f} Proc + | Found: () ->? A + | Required: () -> Proc^{f} | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/eta.scala:6:14 ------------------------------------------- 6 | bar( () => f ) // error | ^^^^^^^ - | Found: {f} () -> box {f} () -> Unit - | Required: () -> box ? () -> Unit + | Found: () ->{f} box () ->{f} Unit + | Required: () -> box () ->? Unit | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/eta.scala b/tests/neg-custom-args/captures/eta.scala index 3d9d759d2203..5cc0196a04c6 100644 --- a/tests/neg-custom-args/captures/eta.scala +++ b/tests/neg-custom-args/captures/eta.scala @@ -1,7 +1,7 @@ - type Proc = (() -> Unit) - def foo(f: {*} Proc): {} Proc = - def bar[A <: {f} Proc](g: () -> A): () -> {f} Proc = + type Proc = () -> Unit + def foo(f: Proc^): Proc^{} = + def bar[A <: Proc^{f}](g: () -> A): () -> Proc^{f} = g // error - val stowaway: () -> {f} Proc = + val stowaway: () -> Proc^{f} = bar( () => f ) // error () => { stowaway.apply().apply() } \ No newline at end of file diff --git a/tests/neg-custom-args/captures/exception-definitions.check b/tests/neg-custom-args/captures/exception-definitions.check index aca5d9217d64..8dca91bc8e43 100644 --- a/tests/neg-custom-args/captures/exception-definitions.check +++ b/tests/neg-custom-args/captures/exception-definitions.check @@ -1,17 +1,17 @@ -- Error: tests/neg-custom-args/captures/exception-definitions.scala:2:6 ----------------------------------------------- 2 |class Err extends Exception: // error |^ - |reference (scala.caps.* : Any) is not included in allowed capture set {} of pure base class class Throwable -3 | self: {*} Err => + |reference (scala.caps.cap : Any) is not included in allowed capture set {} of pure base class class Throwable +3 | self: Err^ => -- Error: tests/neg-custom-args/captures/exception-definitions.scala:10:6 ---------------------------------------------- -10 |class Err4(c: {*} Any) extends AnyVal // error - |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |reference (Err4.this.c : {*} Any) is not included in allowed capture set {} of pure base class class AnyVal +10 |class Err4(c: Any^) extends AnyVal // error + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |reference (Err4.this.c : Any^) is not included in allowed capture set {} of pure base class class AnyVal -- Error: tests/neg-custom-args/captures/exception-definitions.scala:7:12 ---------------------------------------------- 7 | val x = c // error | ^ - |(c : {*} Any) cannot be referenced here; it is not included in the allowed capture set {} of pure base class class Throwable + |(c : Any^) cannot be referenced here; it is not included in the allowed capture set {} of pure base class class Throwable -- Error: tests/neg-custom-args/captures/exception-definitions.scala:8:8 ----------------------------------------------- -8 | class Err3(c: {*} Any) extends Exception // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | reference (Err3.this.c : {*} Any) is not included in allowed capture set {} of pure base class class Throwable +8 | class Err3(c: Any^) extends Exception // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | reference (Err3.this.c : Any^) is not included in allowed capture set {} of pure base class class Throwable diff --git a/tests/neg-custom-args/captures/exception-definitions.scala b/tests/neg-custom-args/captures/exception-definitions.scala index 9f3539b7febf..996f64ae4bd1 100644 --- a/tests/neg-custom-args/captures/exception-definitions.scala +++ b/tests/neg-custom-args/captures/exception-definitions.scala @@ -1,12 +1,12 @@ class Err extends Exception: // error - self: {*} Err => + self: Err^ => -def test(c: {*} Any) = +def test(c: Any^) = class Err2 extends Exception: val x = c // error - class Err3(c: {*} Any) extends Exception // error + class Err3(c: Any^) extends Exception // error -class Err4(c: {*} Any) extends AnyVal // error +class Err4(c: Any^) extends AnyVal // error diff --git a/tests/neg-custom-args/captures/filevar.scala b/tests/neg-custom-args/captures/filevar.scala index 9251be8f1592..474ba36b0e79 100644 --- a/tests/neg-custom-args/captures/filevar.scala +++ b/tests/neg-custom-args/captures/filevar.scala @@ -5,10 +5,10 @@ class File: def write(x: String): Unit = ??? class Service: - var file: {*} File = uninitialized + var file: File^ = uninitialized def log = file.write("log") // error -def withFile[T](op: (f: {*} File) => T): T = +def withFile[T](op: (f: File^) => T): T = op(new File) def test = diff --git a/tests/neg-custom-args/captures/heal-tparam-cs.scala b/tests/neg-custom-args/captures/heal-tparam-cs.scala index 3ff34d0a8a42..173de2b1cbb5 100644 --- a/tests/neg-custom-args/captures/heal-tparam-cs.scala +++ b/tests/neg-custom-args/captures/heal-tparam-cs.scala @@ -2,31 +2,31 @@ import language.experimental.captureChecking trait Cap { def use(): Unit } -def localCap[T](op: (cap: {*} Cap) => T): T = ??? +def localCap[T](op: (cap: Cap^{cap}) => T): T = ??? -def main(io: {*} Cap, net: {*} Cap): Unit = { +def main(io: Cap^{cap}, net: Cap^{cap}): Unit = { val test1 = localCap { cap => // error () => { cap.use() } } - val test2: (cap: {*} Cap) -> {cap} () -> Unit = + val test2: (cap: Cap^{cap}) -> () ->{cap} Unit = localCap { cap => // should work - (cap1: {*} Cap) => () => { cap1.use() } + (cap1: Cap^{cap}) => () => { cap1.use() } } - val test3: (cap: {io} Cap) -> {io} () -> Unit = + val test3: (cap: Cap^{io}) -> () ->{io} Unit = localCap { cap => // should work - (cap1: {io} Cap) => () => { cap1.use() } + (cap1: Cap^{io}) => () => { cap1.use() } } - val test4: (cap: {io} Cap) -> {net} () -> Unit = + val test4: (cap: Cap^{io}) -> () ->{net} Unit = localCap { cap => // error - (cap1: {io} Cap) => () => { cap1.use() } + (cap1: Cap^{io}) => () => { cap1.use() } } - def localCap2[T](op: (cap: {io} Cap) => T): T = ??? + def localCap2[T](op: (cap: Cap^{io}) => T): T = ??? - val test5: {io} () -> Unit = + val test5: () ->{io} Unit = localCap2 { cap => // ok () => { cap.use() } } diff --git a/tests/neg-custom-args/captures/i15049.scala b/tests/neg-custom-args/captures/i15049.scala index 4e32172c025d..bc65db2147f8 100644 --- a/tests/neg-custom-args/captures/i15049.scala +++ b/tests/neg-custom-args/captures/i15049.scala @@ -1,10 +1,10 @@ class Session: def request = "Response" class Foo: - private val session: {*} Session = new Session - def withSession[T](f: ({*} Session) => T): T = f(session) + private val session: Session^{cap} = new Session + def withSession[T](f: (Session^{cap}) => T): T = f(session) def Test = val f = new Foo f.withSession(s => s).request // error - f.withSession[{*} Session](t => t) // error + f.withSession[Session^](t => t) // error diff --git a/tests/neg-custom-args/captures/i15116.check b/tests/neg-custom-args/captures/i15116.check index 7c73a7ff52ff..4b637a7c2e40 100644 --- a/tests/neg-custom-args/captures/i15116.check +++ b/tests/neg-custom-args/captures/i15116.check @@ -2,27 +2,27 @@ 3 | val x = Foo(m) // error | ^^^^^^^^^^^^^^ | Non-local value x cannot have an inferred type - | {Bar.this.m} Foo{val m: {Bar.this.m} String} + | Foo{val m: String^{Bar.this.m}}^{Bar.this.m} | with non-empty capture set {Bar.this.m}. | The type needs to be declared explicitly. -- Error: tests/neg-custom-args/captures/i15116.scala:5:6 -------------------------------------------------------------- 5 | val x = Foo(m) // error | ^^^^^^^^^^^^^^ | Non-local value x cannot have an inferred type - | {Baz.this} Foo{val m: {*} String} + | Foo{val m: String^}^{Baz.this} | with non-empty capture set {Baz.this}. | The type needs to be declared explicitly. -- Error: tests/neg-custom-args/captures/i15116.scala:7:6 -------------------------------------------------------------- 7 | val x = Foo(m) // error | ^^^^^^^^^^^^^^ | Non-local value x cannot have an inferred type - | {Bar1.this.m} Foo{val m: {Bar1.this.m} String} + | Foo{val m: String^{Bar1.this.m}}^{Bar1.this.m} | with non-empty capture set {Bar1.this.m}. | The type needs to be declared explicitly. -- Error: tests/neg-custom-args/captures/i15116.scala:9:6 -------------------------------------------------------------- 9 | val x = Foo(m) // error | ^^^^^^^^^^^^^^ | Non-local value x cannot have an inferred type - | {Baz2.this} Foo{val m: {*} String} + | Foo{val m: String^}^{Baz2.this} | with non-empty capture set {Baz2.this}. | The type needs to be declared explicitly. diff --git a/tests/neg-custom-args/captures/i15116.scala b/tests/neg-custom-args/captures/i15116.scala index 1659f251df3e..c4dc6c88d56c 100644 --- a/tests/neg-custom-args/captures/i15116.scala +++ b/tests/neg-custom-args/captures/i15116.scala @@ -1,9 +1,9 @@ -class Foo(m: {*} String) -class Bar(val m: {*} String): +class Foo(m: String^) +class Bar(val m: String^): val x = Foo(m) // error -trait Baz(val m: {*} String): +trait Baz(val m: String^): val x = Foo(m) // error -class Bar1(m: {*} String): +class Bar1(m: String^): val x = Foo(m) // error -trait Baz2(m: {*} String): +trait Baz2(m: String^): val x = Foo(m) // error diff --git a/tests/neg-custom-args/captures/i15749.scala b/tests/neg-custom-args/captures/i15749.scala index 00d1811498f7..32947c146021 100644 --- a/tests/neg-custom-args/captures/i15749.scala +++ b/tests/neg-custom-args/captures/i15749.scala @@ -1,15 +1,15 @@ class Unit object unit extends Unit -type Top = {*} Any +type Top = Any^{cap} -type LazyVal[T] = {*} Unit -> T +type LazyVal[T] = Unit ->{cap} T class Foo[T](val x: T) -// Foo[□ {*} Unit -> T] +// Foo[□ Unit => T] type BoxedLazyVal[T] = Foo[LazyVal[T]] def force[A](v: BoxedLazyVal[A]): A = - // Γ ⊢ v.x : □ {*} Unit -> A + // Γ ⊢ v.x : □ {cap} Unit -> A v.x(unit) // error: (unbox v.x)(unit), where (unbox v.x) should be untypable \ No newline at end of file diff --git a/tests/neg-custom-args/captures/i15749a.scala b/tests/neg-custom-args/captures/i15749a.scala index 9e439e28e98c..e4d70efa5206 100644 --- a/tests/neg-custom-args/captures/i15749a.scala +++ b/tests/neg-custom-args/captures/i15749a.scala @@ -1,21 +1,21 @@ class Unit object unit extends Unit -type Top = {*} Any +type Top = Any^ -type Wrapper[T] = [X] -> (op: {*} T -> X) -> X +type Wrapper[T] = [X] -> (op: T ->{cap} X) -> X def test = def wrapper[T](x: T): Wrapper[T] = - [X] => (op: {*} T -> X) => op(x) + [X] => (op: T ->{cap} X) => op(x) - def strictMap[A <: Top, B <: Top](mx: Wrapper[A])(f: {*} A -> B): Wrapper[B] = + def strictMap[A <: Top, B <: Top](mx: Wrapper[A])(f: A ->{cap} B): Wrapper[B] = mx((x: A) => wrapper(f(x))) - def force[A](thunk: {*} Unit -> A): A = thunk(unit) + def force[A](thunk: Unit ->{cap} A): A = thunk(unit) - def forceWrapper[A](mx: Wrapper[{*} Unit -> A]): Wrapper[A] = - // Γ ⊢ mx: Wrapper[□ {*} Unit => A] - // `force` should be typed as ∀(□ {*} Unit -> A) A, but it can not - strictMap[{*} Unit -> A, A](mx)(t => force[A](t)) // error + def forceWrapper[A](mx: Wrapper[Unit ->{cap} A]): Wrapper[A] = + // Γ ⊢ mx: Wrapper[□ {cap} Unit => A] + // `force` should be typed as ∀(□ {cap} Unit -> A) A, but it can not + strictMap[Unit ->{cap} A, A](mx)(t => force[A](t)) // error diff --git a/tests/neg-custom-args/captures/i15772.check b/tests/neg-custom-args/captures/i15772.check index a587f2d262ed..e77d4022451d 100644 --- a/tests/neg-custom-args/captures/i15772.check +++ b/tests/neg-custom-args/captures/i15772.check @@ -1,28 +1,28 @@ --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:20:49 --------------------------------------- -20 | val boxed1 : (({*} C) => Unit) -> Unit = box1(c) // error - | ^^^^^^^ - | Found: {c} ({*} ({c} C{val arg: {*} C}) -> Unit) -> Unit - | Required: (({*} C) => Unit) -> Unit +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:20:46 --------------------------------------- +20 | val boxed1 : ((C^) => Unit) -> Unit = box1(c) // error + | ^^^^^^^ + | Found: (C{val arg: C^}^{c} => Unit) ->{c} Unit + | Required: (C^ => Unit) -> Unit | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:27:38 --------------------------------------- -27 | val boxed2 : Observe[{*} C] = box2(c) // error - | ^^^^^^^ - | Found: {c} ({*} ({c} C{val arg: {*} C}) -> Unit) -> Unit - | Required: Observe[{*} C] +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:27:35 --------------------------------------- +27 | val boxed2 : Observe[C^] = box2(c) // error + | ^^^^^^^ + | Found: (C{val arg: C^}^{c} => Unit) ->{c} Unit + | Required: Observe[C^] | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:33:37 --------------------------------------- -33 | val boxed2 : Observe[{*} C] = box2(c) // error - | ^ - | Found: {*} C - | Required: box {*} C{val arg: ? C} +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:33:34 --------------------------------------- +33 | val boxed2 : Observe[C]^ = box2(c) // error + | ^ + | Found: C^ + | Required: box C{val arg: C^?}^ | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:44:2 ---------------------------------------- 44 | x: (() -> Unit) // error | ^ - | Found: {x} () -> Unit + | Found: () ->{x} Unit | Required: () -> Unit | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i15772.scala b/tests/neg-custom-args/captures/i15772.scala index d3afdb6c63f1..e4efb6b9ccab 100644 --- a/tests/neg-custom-args/captures/i15772.scala +++ b/tests/neg-custom-args/captures/i15772.scala @@ -1,6 +1,6 @@ type Observe[T] = (T => Unit) -> Unit -def unsafe(cap: {*} C) = cap.bad() +def unsafe(cap: C^) = cap.bad() def box1[T](v: T) : (T => Unit) -> Unit = { (fn: T => Unit) => fn(v) @@ -10,35 +10,35 @@ def box2[T](v: T) : Observe[T] = { (fn: T => Unit) => fn(v) } -class C(val arg: {*} C) { +class C(val arg: C^) { def bad() = println("I've gone bad!") } -def main1(x: {*} C) : () -> Int = +def main1(x: C^) : () -> Int = () => - val c : {x} C = new C(x) - val boxed1 : (({*} C) => Unit) -> Unit = box1(c) // error - boxed1((cap: {*} C) => unsafe(c)) + val c : C^{x} = new C(x) + val boxed1 : ((C^) => Unit) -> Unit = box1(c) // error + boxed1((cap: C^) => unsafe(c)) 0 -def main2(x: {*} C) : () -> Int = +def main2(x: C^) : () -> Int = () => - val c : {x} C = new C(x) - val boxed2 : Observe[{*} C] = box2(c) // error - boxed2((cap: {*} C) => unsafe(c)) + val c : C^{x} = new C(x) + val boxed2 : Observe[C^] = box2(c) // error + boxed2((cap: C^) => unsafe(c)) 0 -def main3(x: {*} C) = - def c : {*} C = new C(x) - val boxed2 : Observe[{*} C] = box2(c) // error - boxed2((cap: {*} C) => unsafe(c)) +def main3(x: C^) = + def c : C^ = new C(x) + val boxed2 : Observe[C]^ = box2(c) // error + boxed2((cap: C^) => unsafe(c)) 0 trait File: def write(s: String): Unit -def main(io: {*} Any) = - val sayHello: (({io} File) => Unit) = (file: {io} File) => file.write("Hello World!\r\n") - val filesList : List[{io} File] = ??? +def main(io: Any^) = + val sayHello: ((File^{io}) => Unit) = (file: File^{io}) => file.write("Hello World!\r\n") + val filesList : List[File]^{io} = ??? val x = () => filesList.foreach(sayHello) x: (() -> Unit) // error diff --git a/tests/neg-custom-args/captures/i15921.scala b/tests/neg-custom-args/captures/i15921.scala index 291673746e33..233ef23991fc 100644 --- a/tests/neg-custom-args/captures/i15921.scala +++ b/tests/neg-custom-args/captures/i15921.scala @@ -1,7 +1,7 @@ trait Stream { def close(): Unit = (); def write(x: Any): Unit = () } object Test { - def usingLogFile[T](op: (c: {*} Stream) => T): T = + def usingLogFile[T](op: (c: Stream^) => T): T = val logFile = new Stream { } val result = op(logFile) logFile.close() diff --git a/tests/neg-custom-args/captures/i15923-cases.scala b/tests/neg-custom-args/captures/i15923-cases.scala index 5fbb95355a60..9a103c976a8e 100644 --- a/tests/neg-custom-args/captures/i15923-cases.scala +++ b/tests/neg-custom-args/captures/i15923-cases.scala @@ -2,14 +2,14 @@ trait Cap { def use(): Int } type Id[X] = [T] -> (op: X => T) -> T def mkId[X](x: X): Id[X] = [T] => (op: X => T) => op(x) -def foo(x: Id[{*} Cap]) = { +def foo(x: Id[Cap^{cap}]) = { x(_.use()) // error } -def bar(io: {*} Cap, x: Id[{io} Cap]) = { +def bar(io: Cap^{cap}, x: Id[Cap^{io}]) = { x(_.use()) } -def barAlt(a: {*} Cap, b: {*} Cap, x: Id[{a, b} Cap]) = { +def barAlt(a: Cap^{cap}, b: Cap^{cap}, x: Id[Cap]^{a, b}) = { x(_.use()) } diff --git a/tests/neg-custom-args/captures/i15923.scala b/tests/neg-custom-args/captures/i15923.scala index ac7ee995150e..3ce9d6121396 100644 --- a/tests/neg-custom-args/captures/i15923.scala +++ b/tests/neg-custom-args/captures/i15923.scala @@ -3,8 +3,8 @@ type Id[X] = [T] -> (op: X => T) -> T def mkId[X](x: X): Id[X] = [T] => (op: X => T) => op(x) def bar() = { - def withCap[X](op: ({*} Cap) => X): X = { - val cap: {*} Cap = new Cap { def use() = { println("cap is used"); 0 } } + def withCap[X](op: (Cap^) => X): X = { + val cap: Cap^ = new Cap { def use() = { println("cap is used"); 0 } } val result = op(cap) result } diff --git a/tests/neg-custom-args/captures/i16114.scala b/tests/neg-custom-args/captures/i16114.scala index cc491226f9df..d22c7f02d5fb 100644 --- a/tests/neg-custom-args/captures/i16114.scala +++ b/tests/neg-custom-args/captures/i16114.scala @@ -1,46 +1,46 @@ trait Cap { def use(): Int; def close(): Unit } -def mkCap(): {*} Cap = ??? +def mkCap(): Cap^ = ??? def expect[T](x: T): x.type = x -def withCap[T](op: ({*} Cap) => T): T = { - val cap: {*} Cap = mkCap() +def withCap[T](op: Cap^ => T): T = { + val cap: Cap^ = mkCap() val result = op(cap) cap.close() result } -def main(fs: {*} Cap): Unit = { - def badOp(io: {*} Cap): {} Unit -> Unit = { - val op1: {io} Unit -> Unit = (x: Unit) => // error // limitation - expect[{*} Cap] { +def main(fs: Cap^): Unit = { + def badOp(io: Cap^{cap}): Unit ->{} Unit = { + val op1: Unit ->{io} Unit = (x: Unit) => // error // limitation + expect[Cap^] { io.use() fs } - val op2: {fs} Unit -> Unit = (x: Unit) => // error // limitation - expect[{*} Cap] { + val op2: Unit ->{fs} Unit = (x: Unit) => // error // limitation + expect[Cap^] { fs.use() io } - val op3: {io} Unit -> Unit = (x: Unit) => // ok - expect[{*} Cap] { + val op3: Unit ->{io} Unit = (x: Unit) => // ok + expect[Cap^] { io.use() io } - val op4: {} Unit -> Unit = (x: Unit) => // ok - expect[{*} Cap](io) + val op4: Unit ->{} Unit = (x: Unit) => // ok + expect[Cap^](io) - val op: {} Unit -> Unit = (x: Unit) => // error - expect[{*} Cap] { + val op: Unit -> Unit = (x: Unit) => // error + expect[Cap^] { io.use() io } op } - val leaked: {} Unit -> Unit = withCap(badOp) + val leaked: Unit -> Unit = withCap(badOp) leaked(()) } diff --git a/tests/neg-custom-args/captures/impurefuns.scala b/tests/neg-custom-args/captures/impurefuns.scala new file mode 100644 index 000000000000..d15d9a466307 --- /dev/null +++ b/tests/neg-custom-args/captures/impurefuns.scala @@ -0,0 +1,3 @@ +def f(x: Object^): Any = + val f: Int =>{x} Int = ??? // error // error // error + f diff --git a/tests/neg-custom-args/captures/inner-classes.scala b/tests/neg-custom-args/captures/inner-classes.scala index cf4073b36f81..181b830e4996 100644 --- a/tests/neg-custom-args/captures/inner-classes.scala +++ b/tests/neg-custom-args/captures/inner-classes.scala @@ -5,21 +5,21 @@ object test: def foo(fs: FileSystem) = trait LazyList[+A]: - this: {fs} LazyList[A] => + this: LazyList[A]^{fs} => def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? - final class LazyCons[+T](val x: T, val xs: () => {*} LazyList[T]) extends LazyList[T]: // error + final class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]: // error def isEmpty = false def head = x - def tail: {this} LazyList[T] = xs() + def tail: LazyList[T]^{this} = xs() end LazyCons new LazyCons(1, () => LazyNil) diff --git a/tests/neg-custom-args/captures/io.scala b/tests/neg-custom-args/captures/io.scala index ae686d6b154e..f481bf357fc8 100644 --- a/tests/neg-custom-args/captures/io.scala +++ b/tests/neg-custom-args/captures/io.scala @@ -3,17 +3,17 @@ sealed trait IO: def puts(msg: Any): Unit = println(msg) def test1 = - val IO : IO @retains(caps.*) = new IO {} + val IO : IO @retains(caps.cap) = new IO {} def foo = {IO; IO.puts("hello") } val x : () -> Unit = () => foo // error: Found: (() -> Unit) retains IO; Required: () -> Unit def test2 = - val IO : IO @retains(caps.*) = new IO {} - def puts(msg: Any, io: IO @retains(caps.*)) = println(msg) + val IO : IO @retains(caps.cap) = new IO {} + def puts(msg: Any, io: IO @retains(caps.cap)) = println(msg) def foo() = puts("hello", IO) val x : () -> Unit = () => foo() // error: Found: (() -> Unit) retains IO; Required: () -> Unit -type Capability[T] = T @retains(caps.*) +type Capability[T] = T @retains(caps.cap) def test3 = val IO : Capability[IO] = new IO {} diff --git a/tests/neg-custom-args/captures/lazylist.check b/tests/neg-custom-args/captures/lazylist.check index 471e2a038450..4b7611fc3fb7 100644 --- a/tests/neg-custom-args/captures/lazylist.check +++ b/tests/neg-custom-args/captures/lazylist.check @@ -1,42 +1,42 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:17:15 ------------------------------------- 17 | def tail = xs() // error | ^^^^ - | Found: {LazyCons.this.xs} lazylists.LazyList[T] + | Found: lazylists.LazyList[T]^{LazyCons.this.xs} | Required: lazylists.LazyList[T] | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:35:29 ------------------------------------- 35 | val ref1c: LazyList[Int] = ref1 // error | ^^^^ - | Found: (ref1 : {cap1} lazylists.LazyCons[Int]{val xs: {cap1} () -> {*} lazylists.LazyList[Int]}) - | Required: lazylists.LazyList[Int] + | Found: (ref1 : lazylists.LazyCons[Int]{val xs: () ->{cap1} lazylists.LazyList[Int]^}^{cap1}) + | Required: lazylists.LazyList[Int] | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:37:36 ------------------------------------- -37 | val ref2c: {ref1} LazyList[Int] = ref2 // error +37 | val ref2c: LazyList[Int]^{ref1} = ref2 // error | ^^^^ - | Found: (ref2 : {cap2, ref1} lazylists.LazyList[Int]) - | Required: {ref1} lazylists.LazyList[Int] + | Found: (ref2 : lazylists.LazyList[Int]^{cap2, ref1}) + | Required: lazylists.LazyList[Int]^{ref1} | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:39:36 ------------------------------------- -39 | val ref3c: {cap2} LazyList[Int] = ref3 // error +39 | val ref3c: LazyList[Int]^{cap2} = ref3 // error | ^^^^ - | Found: (ref3 : {cap2, ref1} lazylists.LazyList[Int]) - | Required: {cap2} lazylists.LazyList[Int] + | Found: (ref3 : lazylists.LazyList[Int]^{cap2, ref1}) + | Required: lazylists.LazyList[Int]^{cap2} | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:41:48 ------------------------------------- -41 | val ref4c: {cap1, ref3, cap3} LazyList[Int] = ref4 // error +41 | val ref4c: LazyList[Int]^{cap1, ref3, cap3} = ref4 // error | ^^^^ - | Found: (ref4 : {cap3, cap2, ref1, cap1} lazylists.LazyList[Int]) - | Required: {cap1, ref3, cap3} lazylists.LazyList[Int] + | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap2, ref1, cap1}) + | Required: lazylists.LazyList[Int]^{cap1, ref3, cap3} | | longer explanation available when compiling with `-explain` -- [E164] Declaration Error: tests/neg-custom-args/captures/lazylist.scala:22:6 ---------------------------------------- -22 | def tail: {*} LazyList[Nothing] = ??? // error overriding +22 | def tail: LazyList[Nothing]^ = ??? // error overriding | ^ | error overriding method tail in class LazyList of type -> lazylists.LazyList[Nothing]; - | method tail of type -> {*} lazylists.LazyList[Nothing] has incompatible type + | method tail of type -> lazylists.LazyList[Nothing]^ has incompatible type | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lazylist.scala b/tests/neg-custom-args/captures/lazylist.scala index 2674f15a0ee3..e6e4d003f7ae 100644 --- a/tests/neg-custom-args/captures/lazylist.scala +++ b/tests/neg-custom-args/captures/lazylist.scala @@ -1,17 +1,17 @@ package lazylists abstract class LazyList[+T]: - this: ({*} LazyList[T]) => + this: LazyList[T]^ => def isEmpty: Boolean def head: T def tail: LazyList[T] - def map[U](f: T => U): {f, this} LazyList[U] = + def map[U](f: T => U): LazyList[U]^{f, this} = if isEmpty then LazyNil else LazyCons(f(head), () => tail.map(f)) -class LazyCons[+T](val x: T, val xs: () => {*} LazyList[T]) extends LazyList[T]: +class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]: def isEmpty = false def head = x def tail = xs() // error @@ -19,13 +19,13 @@ class LazyCons[+T](val x: T, val xs: () => {*} LazyList[T]) extends LazyList[T]: object LazyNil extends LazyList[Nothing]: def isEmpty = true def head = ??? - def tail: {*} LazyList[Nothing] = ??? // error overriding + def tail: LazyList[Nothing]^ = ??? // error overriding -def map[A, B](xs: {*} LazyList[A], f: A => B): {f, xs} LazyList[B] = +def map[A, B](xs: LazyList[A]^, f: A => B): LazyList[B]^{f, xs} = xs.map(f) class CC -type Cap = {*} CC +type Cap = CC^ def test(cap1: Cap, cap2: Cap, cap3: Cap) = def f[T](x: LazyList[T]): LazyList[T] = if cap1 == cap1 then x else LazyNil @@ -34,8 +34,8 @@ def test(cap1: Cap, cap2: Cap, cap3: Cap) = val ref1 = LazyCons(1, () => f(LazyNil)) val ref1c: LazyList[Int] = ref1 // error val ref2 = map(ref1, g) - val ref2c: {ref1} LazyList[Int] = ref2 // error + val ref2c: LazyList[Int]^{ref1} = ref2 // error val ref3 = ref1.map(g) - val ref3c: {cap2} LazyList[Int] = ref3 // error + val ref3c: LazyList[Int]^{cap2} = ref3 // error val ref4 = (if cap1 == cap2 then ref1 else ref2).map(h) - val ref4c: {cap1, ref3, cap3} LazyList[Int] = ref4 // error + val ref4c: LazyList[Int]^{cap1, ref3, cap3} = ref4 // error diff --git a/tests/neg-custom-args/captures/lazylists-exceptions.check b/tests/neg-custom-args/captures/lazylists-exceptions.check index bd6fad047fe9..03278f25e8dc 100644 --- a/tests/neg-custom-args/captures/lazylists-exceptions.check +++ b/tests/neg-custom-args/captures/lazylists-exceptions.check @@ -1,7 +1,7 @@ -- Error: tests/neg-custom-args/captures/lazylists-exceptions.scala:36:2 ----------------------------------------------- 36 | try // error | ^ - | The expression's type {*} LazyList[Int] is not allowed to capture the root capability `*`. + | The expression's type LazyList[Int]^ is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. 37 | tabulate(10) { i => 38 | if i > 9 then throw Ex1() diff --git a/tests/neg-custom-args/captures/lazylists-exceptions.scala b/tests/neg-custom-args/captures/lazylists-exceptions.scala index 6cba934d61e8..6a72facf7285 100644 --- a/tests/neg-custom-args/captures/lazylists-exceptions.scala +++ b/tests/neg-custom-args/captures/lazylists-exceptions.scala @@ -1,31 +1,31 @@ import language.experimental.saferExceptions trait LazyList[+A]: - this: {*} LazyList[A] => + this: LazyList[A]^ => def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? -final class LazyCons[+T](val x: T, val xs: () => {*} LazyList[T]) extends LazyList[T]: - this: {*} LazyList[T] => +final class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]: + this: LazyList[T]^ => def isEmpty = false def head = x - def tail: {this} LazyList[T] = xs() + def tail: LazyList[T]^{this} = xs() end LazyCons extension [A](x: A) - def #:(xs1: => {*} LazyList[A]): {xs1} LazyList[A] = + def #:(xs1: => LazyList[A]^): LazyList[A]^{xs1} = LazyCons(x, () => xs1) -def tabulate[A](n: Int)(gen: Int => A): {gen} LazyList[A] = - def recur(i: Int): {gen} LazyList[A] = +def tabulate[A](n: Int)(gen: Int => A): LazyList[A]^{gen} = + def recur(i: Int): LazyList[A]^{gen} = if i == n then LazyNil else gen(i) #: recur(i + 1) recur(0) diff --git a/tests/neg-custom-args/captures/lazylists1.check b/tests/neg-custom-args/captures/lazylists1.check index f91e2500dc15..127a0563c3c9 100644 --- a/tests/neg-custom-args/captures/lazylists1.check +++ b/tests/neg-custom-args/captures/lazylists1.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists1.scala:25:66 ----------------------------------- -25 | def concat(other: {f} LazyList[A]): {this, f} LazyList[A] = ??? : ({xs, f} LazyList[A]) // error +25 | def concat(other: LazyList[A]^{f}): LazyList[A]^{this, f} = ??? : (LazyList[A]^{xs, f}) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: {xs, f} LazyList[A] - | Required: {Mapped.this, f} LazyList[A] + | Found: LazyList[A]^{xs, f} + | Required: LazyList[A]^{Mapped.this, f} | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lazylists1.scala b/tests/neg-custom-args/captures/lazylists1.scala index c6475223b783..99472c13ebec 100644 --- a/tests/neg-custom-args/captures/lazylists1.scala +++ b/tests/neg-custom-args/captures/lazylists1.scala @@ -1,27 +1,27 @@ class CC -type Cap = {*} CC +type Cap = CC^{cap} trait LazyList[+A]: - this: ({*} LazyList[A]) => + this: LazyList[A]^{cap} => def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? -extension [A](xs: {*} LazyList[A]) - def map[B](f: A => B): {xs, f} LazyList[B] = +extension [A](xs: LazyList[A]^{cap}) + def map[B](f: A => B): LazyList[B]^{xs, f} = final class Mapped extends LazyList[B]: - this: ({xs, f} Mapped) => + this: (Mapped^{xs, f}) => def isEmpty = false def head: B = f(xs.head) - def tail: {this} LazyList[B] = xs.tail.map(f) // OK - def drop(n: Int): {this} LazyList[B] = ??? : ({xs, f} LazyList[B]) // OK - def concat(other: {f} LazyList[A]): {this, f} LazyList[A] = ??? : ({xs, f} LazyList[A]) // error + def tail: LazyList[B]^{this} = xs.tail.map(f) // OK + def drop(n: Int): LazyList[B]^{this} = ??? : (LazyList[B]^{xs, f}) // OK + def concat(other: LazyList[A]^{f}): LazyList[A]^{this, f} = ??? : (LazyList[A]^{xs, f}) // error new Mapped diff --git a/tests/neg-custom-args/captures/lazylists2.check b/tests/neg-custom-args/captures/lazylists2.check index 812170aabdfe..72efbc08f8e2 100644 --- a/tests/neg-custom-args/captures/lazylists2.check +++ b/tests/neg-custom-args/captures/lazylists2.check @@ -1,24 +1,24 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:18:4 ------------------------------------ 18 | final class Mapped extends LazyList[B]: // error | ^ - | Found: {f, xs} LazyList[? B] - | Required: {f} LazyList[B] -19 | this: ({xs, f} Mapped) => + | Found: LazyList[B^?]^{f, xs} + | Required: LazyList[B]^{f} +19 | this: (Mapped^{xs, f}) => 20 | def isEmpty = false 21 | def head: B = f(xs.head) -22 | def tail: {this} LazyList[B] = xs.tail.map(f) +22 | def tail: LazyList[B]^{this} = xs.tail.map(f) 23 | new Mapped | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:27:4 ------------------------------------ 27 | final class Mapped extends LazyList[B]: // error | ^ - | Found: {f, xs} LazyList[? B] - | Required: {xs} LazyList[B] -28 | this: ({xs, f} Mapped) => + | Found: LazyList[B^?]^{f, xs} + | Required: LazyList[B]^{xs} +28 | this: Mapped^{xs, f} => 29 | def isEmpty = false 30 | def head: B = f(xs.head) -31 | def tail: {this} LazyList[B] = xs.tail.map(f) +31 | def tail: LazyList[B]^{this} = xs.tail.map(f) 32 | new Mapped | | longer explanation available when compiling with `-explain` @@ -26,19 +26,19 @@ 40 | def head: B = f(xs.head) // error | ^ |(f : A => B) cannot be referenced here; it is not included in the allowed capture set {xs} of the self type of class Mapped --- Error: tests/neg-custom-args/captures/lazylists2.scala:41:49 -------------------------------------------------------- -41 | def tail: {this} LazyList[B] = xs.tail.map(f) // error - | ^ +-- Error: tests/neg-custom-args/captures/lazylists2.scala:41:48 -------------------------------------------------------- +41 | def tail: LazyList[B]^{this}= xs.tail.map(f) // error + | ^ |(f : A => B) cannot be referenced here; it is not included in the allowed capture set {xs} of the self type of class Mapped -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:45:4 ------------------------------------ 45 | final class Mapped extends LazyList[B]: // error | ^ - | Found: {f, xs} LazyList[? B] - | Required: {xs} LazyList[B] -46 | this: ({xs, f} Mapped) => + | Found: LazyList[B^?]^{f, xs} + | Required: LazyList[B]^{xs} +46 | this: (Mapped^{xs, f}) => 47 | def isEmpty = false 48 | def head: B = f(xs.head) -49 | def tail: {xs, f} LazyList[B] = xs.tail.map(f) +49 | def tail: LazyList[B]^{xs, f} = xs.tail.map(f) 50 | new Mapped | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lazylists2.scala b/tests/neg-custom-args/captures/lazylists2.scala index 574fb5a1a488..f6c1cf95a8ed 100644 --- a/tests/neg-custom-args/captures/lazylists2.scala +++ b/tests/neg-custom-args/captures/lazylists2.scala @@ -1,62 +1,62 @@ class CC -type Cap = {*} CC +type Cap = CC^ trait LazyList[+A]: - this: ({*} LazyList[A]) => + this: LazyList[A]^ => def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? -extension [A](xs: {*} LazyList[A]) - def map[B](f: A => B): {f} LazyList[B] = +extension [A](xs: LazyList[A]^) + def map[B](f: A => B): LazyList[B]^{f} = final class Mapped extends LazyList[B]: // error - this: ({xs, f} Mapped) => + this: (Mapped^{xs, f}) => def isEmpty = false def head: B = f(xs.head) - def tail: {this} LazyList[B] = xs.tail.map(f) + def tail: LazyList[B]^{this} = xs.tail.map(f) new Mapped - def map2[B](f: A => B): {xs} LazyList[B] = + def map2[B](f: A => B): LazyList[B]^{xs} = final class Mapped extends LazyList[B]: // error - this: ({xs, f} Mapped) => + this: Mapped^{xs, f} => def isEmpty = false def head: B = f(xs.head) - def tail: {this} LazyList[B] = xs.tail.map(f) + def tail: LazyList[B]^{this} = xs.tail.map(f) new Mapped - def map3[B](f: A => B): {xs} LazyList[B] = + def map3[B](f: A => B): LazyList[B]^{xs} = final class Mapped extends LazyList[B]: - this: ({xs} Mapped) => + this: Mapped^{xs} => def isEmpty = false def head: B = f(xs.head) // error - def tail: {this} LazyList[B] = xs.tail.map(f) // error + def tail: LazyList[B]^{this}= xs.tail.map(f) // error new Mapped - def map4[B](f: A => B): {xs} LazyList[B] = + def map4[B](f: A => B): LazyList[B]^{xs} = final class Mapped extends LazyList[B]: // error - this: ({xs, f} Mapped) => + this: (Mapped^{xs, f}) => def isEmpty = false def head: B = f(xs.head) - def tail: {xs, f} LazyList[B] = xs.tail.map(f) + def tail: LazyList[B]^{xs, f} = xs.tail.map(f) new Mapped def map5[B](f: A => B): LazyList[B] = class Mapped extends LazyList[B]: - this: ({xs, f} Mapped) => + this: (Mapped^{xs, f}) => def isEmpty = false def head: B = f(xs.head) - def tail: {this} LazyList[B] = xs.tail.map(f) + def tail: LazyList[B]^{this} = xs.tail.map(f) class Mapped2 extends Mapped: // error this: Mapped => new Mapped2 diff --git a/tests/neg-custom-args/captures/lazyref.check b/tests/neg-custom-args/captures/lazyref.check index 7471f8f4f686..8c91ec13b5d8 100644 --- a/tests/neg-custom-args/captures/lazyref.check +++ b/tests/neg-custom-args/captures/lazyref.check @@ -1,28 +1,28 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:19:28 -------------------------------------- 19 | val ref1c: LazyRef[Int] = ref1 // error | ^^^^ - | Found: (ref1 : {cap1} LazyRef[Int]{val elem: {cap1} () -> Int}) + | Found: (ref1 : LazyRef[Int]{val elem: () ->{cap1} Int}^{cap1}) | Required: LazyRef[Int] | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:21:35 -------------------------------------- -21 | val ref2c: {cap2} LazyRef[Int] = ref2 // error +21 | val ref2c: LazyRef[Int]^{cap2} = ref2 // error | ^^^^ - | Found: (ref2 : {cap2, ref1} LazyRef[Int]{val elem: {*} () -> Int}) - | Required: {cap2} LazyRef[Int] + | Found: (ref2 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1}) + | Required: LazyRef[Int]^{cap2} | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:23:35 -------------------------------------- -23 | val ref3c: {ref1} LazyRef[Int] = ref3 // error +23 | val ref3c: LazyRef[Int]^{ref1} = ref3 // error | ^^^^ - | Found: (ref3 : {cap2, ref1} LazyRef[Int]{val elem: {*} () -> Int}) - | Required: {ref1} LazyRef[Int] + | Found: (ref3 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1}) + | Required: LazyRef[Int]^{ref1} | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:25:35 -------------------------------------- -25 | val ref4c: {cap1} LazyRef[Int] = ref4 // error +25 | val ref4c: LazyRef[Int]^{cap1} = ref4 // error | ^^^^ - | Found: (ref4 : {cap2, cap1} LazyRef[Int]{val elem: {*} () -> Int}) - | Required: {cap1} LazyRef[Int] + | Found: (ref4 : LazyRef[Int]{val elem: () => Int}^{cap2, cap1}) + | Required: LazyRef[Int]^{cap1} | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lazyref.scala b/tests/neg-custom-args/captures/lazyref.scala index 8395e5cb42cd..99aa10d5d2b2 100644 --- a/tests/neg-custom-args/captures/lazyref.scala +++ b/tests/neg-custom-args/captures/lazyref.scala @@ -1,15 +1,15 @@ class CC -type Cap = {*} CC +type Cap = CC^ class LazyRef[T](val elem: () => T): val get: () => T = elem - def map[U](f: T => U): {f, this} LazyRef[U] = + def map[U](f: T => U): LazyRef[U]^{f, this} = new LazyRef(() => f(elem())) -def map[A, B](ref: {*} LazyRef[A], f: A => B): {f, ref} LazyRef[B] = +def map[A, B](ref: LazyRef[A]^, f: A => B): LazyRef[B]^{f, ref} = new LazyRef(() => f(ref.elem())) -def mapc[A, B]: (ref: {*} LazyRef[A], f: A => B) -> {f, ref} LazyRef[B] = +def mapc[A, B]: (ref: LazyRef[A]^, f: A => B) -> LazyRef[B]^{f, ref} = (ref1, f1) => map[A, B](ref1, f1) def test(cap1: Cap, cap2: Cap) = @@ -18,8 +18,8 @@ def test(cap1: Cap, cap2: Cap) = val ref1 = LazyRef(() => f(0)) val ref1c: LazyRef[Int] = ref1 // error val ref2 = map(ref1, g) - val ref2c: {cap2} LazyRef[Int] = ref2 // error + val ref2c: LazyRef[Int]^{cap2} = ref2 // error val ref3 = ref1.map(g) - val ref3c: {ref1} LazyRef[Int] = ref3 // error + val ref3c: LazyRef[Int]^{ref1} = ref3 // error val ref4 = (if cap1 == cap2 then ref1 else ref2).map(g) - val ref4c: {cap1} LazyRef[Int] = ref4 // error + val ref4c: LazyRef[Int]^{cap1} = ref4 // error diff --git a/tests/neg-custom-args/captures/nestedclass.check b/tests/neg-custom-args/captures/nestedclass.check index cb4421ece0ec..2987318caf4f 100644 --- a/tests/neg-custom-args/captures/nestedclass.check +++ b/tests/neg-custom-args/captures/nestedclass.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/nestedclass.scala:15:15 ---------------------------------- 15 | val xsc: C = xs // error | ^^ - | Found: (xs : {cap1} C) + | Found: (xs : C^{cap1}) | Required: C | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/nestedclass.scala b/tests/neg-custom-args/captures/nestedclass.scala index 38adf7998868..0581f9ce9b2d 100644 --- a/tests/neg-custom-args/captures/nestedclass.scala +++ b/tests/neg-custom-args/captures/nestedclass.scala @@ -1,5 +1,5 @@ class CC -type Cap = {*} CC +type Cap = CC^ abstract class C: def head: String diff --git a/tests/neg-custom-args/captures/override-adapt-box-selftype.scala b/tests/neg-custom-args/captures/override-adapt-box-selftype.scala index a4dc92429192..f44add78e246 100644 --- a/tests/neg-custom-args/captures/override-adapt-box-selftype.scala +++ b/tests/neg-custom-args/captures/override-adapt-box-selftype.scala @@ -4,45 +4,45 @@ class IO class C object Test1 { - abstract class A[X] { this: {} A[X] => + abstract class A[X] { this: A[X] => def foo(x: X): X } - def test(io: {*} IO) = { - class B extends A[{io} C] { // X =:= {io} C // error - override def foo(x: {io} C): {io} C = ??? + def test(io: IO^) = { + class B extends A[C^{io}] { // X =:= {io} C // error + override def foo(x: C^{io}): C^{io} = ??? } } } -def Test2(io: {*} IO, fs: {io} IO, ct: {*} IO) = { - abstract class A[X] { this: {io} A[X] => +def Test2(io: IO^{cap}, fs: IO^{io}, ct: IO^) = { + abstract class A[X] { this: A[X]^{io} => def foo(x: X): X } - class B1 extends A[{io} C] { - override def foo(x: {io} C): {io} C = ??? + class B1 extends A[C^{io}] { + override def foo(x: C^{io}): C^{io} = ??? } - class B2 extends A[{ct} C] { // error - override def foo(x: {ct} C): {ct} C = ??? + class B2 extends A[C^{ct}] { // error + override def foo(x: C^{ct}): C^{ct} = ??? } - class B3 extends A[{fs} C] { - override def foo(x: {fs} C): {fs} C = ??? + class B3 extends A[C^{fs}] { + override def foo(x: C^{fs}): C^{fs} = ??? } } -def Test3(io: {*} IO, ct: {*} IO) = { - abstract class A[X] { this: {*} A[X] => +def Test3(io: IO^, ct: IO^) = { + abstract class A[X] { this: A[X]^ => def foo(x: X): X } - class B1 extends A[{io} C] { - override def foo(x: {io} C): {io} C = ??? + class B1 extends A[C^{io}] { + override def foo(x: C^{io}): C^{io} = ??? } - class B2 extends A[{io, ct} C] { - override def foo(x: {io, ct} C): {io, ct} C = ??? + class B2 extends A[C^{io, ct}] { + override def foo(x: C^{io, ct}): C^{io, ct} = ??? } } diff --git a/tests/neg-custom-args/captures/override-adapt-box.scala b/tests/neg-custom-args/captures/override-adapt-box.scala index 64ba8743bf91..70023dfbc941 100644 --- a/tests/neg-custom-args/captures/override-adapt-box.scala +++ b/tests/neg-custom-args/captures/override-adapt-box.scala @@ -1,14 +1,14 @@ import language.experimental.captureChecking -abstract class A[X] { this: ({} A[X]) => +abstract class A[X] { this: A[X]^{} => def foo(x: X): X } class IO class C -def test(io: {*} IO) = { - class B extends A[{io} C] { // X =:= {io} C // error - override def foo(x: {io} C): {io} C = ??? +def test(io: IO^{cap}) = { + class B extends A[C^{io}] { // X =:= {io} C // error + override def foo(x: C^{io}): C^{io} = ??? } } diff --git a/tests/neg-custom-args/captures/override-boxed.scala b/tests/neg-custom-args/captures/override-boxed.scala index 720b50732f61..d66d28d15aaa 100644 --- a/tests/neg-custom-args/captures/override-boxed.scala +++ b/tests/neg-custom-args/captures/override-boxed.scala @@ -1,7 +1,8 @@ + class A -def test(x: {*} Any) = +def test(x: Any^{cap}) = abstract class Getter: - def get(): {x} A - class PolyGetter[T <: {x} A] extends Getter: + def get(): A^{x} + class PolyGetter[T <: A^{x}] extends Getter: override def get(): T = ??? // error diff --git a/tests/neg-custom-args/captures/real-try.check b/tests/neg-custom-args/captures/real-try.check index 9745470f219c..0b4da5af27b5 100644 --- a/tests/neg-custom-args/captures/real-try.check +++ b/tests/neg-custom-args/captures/real-try.check @@ -1,7 +1,7 @@ -- Error: tests/neg-custom-args/captures/real-try.scala:12:2 ----------------------------------------------------------- 12 | try // error | ^ - | The expression's type {*} () -> Unit is not allowed to capture the root capability `*`. + | The expression's type () => Unit is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. 13 | () => foo(1) 14 | catch @@ -10,7 +10,7 @@ -- Error: tests/neg-custom-args/captures/real-try.scala:18:2 ----------------------------------------------------------- 18 | try // error | ^ - | The expression's type {*} () -> ? Cell[Unit] is not allowed to capture the root capability `*`. + | The expression's type () => Cell[Unit]^? is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. 19 | () => Cell(foo(1)) 20 | catch @@ -19,5 +19,5 @@ -- Error: tests/neg-custom-args/captures/real-try.scala:30:4 ----------------------------------------------------------- 30 | b.x // error | ^^^ - | The expression's type box {*} () -> Unit is not allowed to capture the root capability `*`. + | The expression's type box () => Unit is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. diff --git a/tests/neg-custom-args/captures/real-try.scala b/tests/neg-custom-args/captures/real-try.scala index 94e1eafd9af2..03e168032122 100644 --- a/tests/neg-custom-args/captures/real-try.scala +++ b/tests/neg-custom-args/captures/real-try.scala @@ -22,7 +22,7 @@ def test() = case _: Ex2 => ??? val b = try // ok here, but error on use - Cell(() => foo(1))//: Cell[box {ev} () => Unit] <: Cell[box {*} () => Unit] + Cell(() => foo(1))//: Cell[box {ev} () => Unit] <: Cell[box {cap} () => Unit] catch case _: Ex1 => ??? case _: Ex2 => ??? diff --git a/tests/neg-custom-args/captures/stack-alloc.scala b/tests/neg-custom-args/captures/stack-alloc.scala index b646c0736f2c..027f2b3e005c 100644 --- a/tests/neg-custom-args/captures/stack-alloc.scala +++ b/tests/neg-custom-args/captures/stack-alloc.scala @@ -5,7 +5,7 @@ class Pooled val stack = mutable.ArrayBuffer[Pooled]() var nextFree = 0 -def withFreshPooled[T](op: ({*} Pooled) => T): T = +def withFreshPooled[T](op: Pooled^ => T): T = if nextFree >= stack.size then stack.append(new Pooled) val pooled = stack(nextFree) nextFree = nextFree + 1 diff --git a/tests/neg-custom-args/captures/try.check b/tests/neg-custom-args/captures/try.check index d4bcc859d256..f85ca468e6e5 100644 --- a/tests/neg-custom-args/captures/try.check +++ b/tests/neg-custom-args/captures/try.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:23:49 ------------------------------------------ 23 | val a = handle[Exception, CanThrow[Exception]] { // error | ^ - | Found: ? ({*} CT[Exception]) -> CanThrow[Exception] - | Required: {*} CanThrow[Exception] -> box {*} CT[Exception] + | Found: CT[Exception]^ ->? CanThrow[Exception] + | Required: CanThrow[Exception] => box CT[Exception]^ 24 | (x: CanThrow[Exception]) => x 25 | }{ | @@ -10,8 +10,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:29:43 ------------------------------------------ 29 | val b = handle[Exception, () -> Nothing] { // error | ^ - | Found: ? (x: {*} CT[Exception]) -> {x} () -> Nothing - | Required: {*} (x$0: CanThrow[Exception]) -> () -> Nothing + | Found: (x: CT[Exception]^) ->? () ->{x} Nothing + | Required: (x$0: CanThrow[Exception]) => () -> Nothing 30 | (x: CanThrow[Exception]) => () => raise(new Exception)(using x) 31 | } { | @@ -24,7 +24,7 @@ 51 | 22 52 |} { // error | ^ - | Found: {x$0} () -> Int + | Found: () ->{x$0} Int | Required: () -> Int 53 | (ex: Exception) => () => 22 54 |} @@ -38,7 +38,7 @@ 39 | 22 40 | } { // error | ^ - | The expression's type box {x$0, *} () -> Int is not allowed to capture the root capability `*`. + | The expression's type box () => Int is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. 41 | (ex: Exception) => () => 22 42 | } diff --git a/tests/neg-custom-args/captures/try.scala b/tests/neg-custom-args/captures/try.scala index 9489766d41be..ef375c62b817 100644 --- a/tests/neg-custom-args/captures/try.scala +++ b/tests/neg-custom-args/captures/try.scala @@ -2,8 +2,8 @@ import annotation.retains import language.experimental.erasedDefinitions class CT[E <: Exception] -type CanThrow[E <: Exception] = CT[E] @retains(caps.*) -type Top = Any @retains(caps.*) +type CanThrow[E <: Exception] = CT[E] @retains(caps.cap) +type Top = Any @retains(caps.cap) infix type throws[R, E <: Exception] = (erased CanThrow[E]) ?=> R diff --git a/tests/neg-custom-args/captures/try3.scala b/tests/neg-custom-args/captures/try3.scala index 8c5bc18bf3be..5a569aa5fd8d 100644 --- a/tests/neg-custom-args/captures/try3.scala +++ b/tests/neg-custom-args/captures/try3.scala @@ -1,8 +1,8 @@ import java.io.IOException class CT[E] -type CanThrow[E] = {*} CT[E] -type Top = {*} Any +type CanThrow[E] = CT[E]^ +type Top = Any^ def handle[E <: Exception, T <: Top](op: CanThrow[E] ?=> T)(handler: E => T): T = val x: CanThrow[E] = ??? diff --git a/tests/neg-custom-args/captures/unbox.scala b/tests/neg-custom-args/captures/unbox.scala index c615cf1d9176..18a86a1237ff 100644 --- a/tests/neg-custom-args/captures/unbox.scala +++ b/tests/neg-custom-args/captures/unbox.scala @@ -1,4 +1,4 @@ -type Proc = {*} () => Unit +type Proc = () => Unit val xs: List[Proc] = ??? diff --git a/tests/neg-custom-args/captures/usingLogFile.check b/tests/neg-custom-args/captures/usingLogFile.check index 05fb385a64f7..17b9146ce71c 100644 --- a/tests/neg-custom-args/captures/usingLogFile.check +++ b/tests/neg-custom-args/captures/usingLogFile.check @@ -1,39 +1,39 @@ -- Error: tests/neg-custom-args/captures/usingLogFile.scala:33:2 ------------------------------------------------------- 33 | later3() // error | ^^^^^^ - | box {*} () -> Unit cannot be box-converted to a type that can be selected or applied - | since one of their capture sets contains the root capability `*` + | box () => Unit cannot be box-converted to a type that can be selected or applied + | since one of their capture sets contains the root capability `cap` -- Error: tests/neg-custom-args/captures/usingLogFile.scala:37:9 ------------------------------------------------------- 37 | later4.x() // error | ^^^^^^^^ - | The expression's type box {*} () -> Unit is not allowed to capture the root capability `*`. + | The expression's type box () => Unit is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. -- Error: tests/neg-custom-args/captures/usingLogFile.scala:23:6 ------------------------------------------------------- 23 | val later = usingLogFile { f => () => f.write(0) } // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Non-local value later cannot have an inferred type - | {x$0} () -> Unit + | () ->{x$0} Unit | with non-empty capture set {x$0}. | The type needs to be declared explicitly. -- Error: tests/neg-custom-args/captures/usingLogFile.scala:29:9 ------------------------------------------------------- 29 | later2.x() // error | ^^^^^^^^ - | The expression's type box {x$0, *} () -> Unit is not allowed to capture the root capability `*`. + | The expression's type box () => Unit is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. -- Error: tests/neg-custom-args/captures/usingLogFile.scala:47:6 ------------------------------------------------------- 47 | val later = usingLogFile { f => () => f.write(0) } // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Non-local value later cannot have an inferred type - | {x$0} () -> Unit + | () ->{x$0} Unit | with non-empty capture set {x$0}. | The type needs to be declared explicitly. -- Error: tests/neg-custom-args/captures/usingLogFile.scala:62:25 ------------------------------------------------------ 62 | val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | The expression's type box {x$0, *} (x$0: Int) -> Unit is not allowed to capture the root capability `*`. - | This usually means that a capability persists longer than its allowed lifetime. + | The expression's type box (x$0: Int) => Unit is not allowed to capture the root capability `cap`. + | This usually means that a capability persists longer than its allowed lifetime. -- Error: tests/neg-custom-args/captures/usingLogFile.scala:71:25 ------------------------------------------------------ 71 | val later = usingFile("logfile", usingLogger(_, l => () => l.log("test"))) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | The expression's type box {x$0, *} () -> Unit is not allowed to capture the root capability `*`. + | The expression's type box () => Unit is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. diff --git a/tests/neg-custom-args/captures/usingLogFile.scala b/tests/neg-custom-args/captures/usingLogFile.scala index 8b367239050d..1e281f130b8a 100644 --- a/tests/neg-custom-args/captures/usingLogFile.scala +++ b/tests/neg-custom-args/captures/usingLogFile.scala @@ -14,7 +14,7 @@ object Test1: object Test2: - def usingLogFile[T](op: ({*} FileOutputStream) => T): T = + def usingLogFile[T](op: FileOutputStream^ => T): T = val logFile = FileOutputStream("log") val result = op(logFile) logFile.close() @@ -38,7 +38,7 @@ object Test2: object Test3: - def usingLogFile[T](op: ({*} FileOutputStream) => T) = + def usingLogFile[T](op: FileOutputStream^ => T) = val logFile = FileOutputStream("log") val result = op(logFile) logFile.close() @@ -47,10 +47,10 @@ object Test3: val later = usingLogFile { f => () => f.write(0) } // error object Test4: - class Logger(f: {*} OutputStream): + class Logger(f: OutputStream^): def log(msg: String): Unit = ??? - def usingFile[T](name: String, op: ({*} OutputStream) => T): T = + def usingFile[T](name: String, op: OutputStream^ => T): T = val f = new FileOutputStream(name) val result = op(f) f.close() @@ -63,7 +63,7 @@ object Test4: later(1) - def usingLogger[T](f: {*} OutputStream, op: ({f} Logger) => T): T = + def usingLogger[T](f: OutputStream^, op: Logger^{f} => T): T = val logger = Logger(f) op(logger) diff --git a/tests/neg-custom-args/captures/vars.check b/tests/neg-custom-args/captures/vars.check index 4b9ab5723ce6..565101359673 100644 --- a/tests/neg-custom-args/captures/vars.check +++ b/tests/neg-custom-args/captures/vars.check @@ -1,31 +1,31 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:11:24 ----------------------------------------- 11 | val z2c: () -> Unit = z2 // error | ^^ - | Found: {z2} () -> Unit + | Found: () ->{z2} Unit | Required: () -> Unit | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:15:10 ----------------------------------------- 15 | val u = a // error | ^ - | Found: (a : box {*} String -> String) - | Required: {*} (x$0: String) -> String + | Found: (a : box String => String) + | Required: (x$0: String) => String | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/vars.scala:16:2 --------------------------------------------------------------- 16 | a("") // error | ^ - | box {*} String -> String cannot be box-converted to a type that can be selected or applied - | since one of their capture sets contains the root capability `*` + | box String => String cannot be box-converted to a type that can be selected or applied + | since one of their capture sets contains the root capability `cap` -- Error: tests/neg-custom-args/captures/vars.scala:17:4 --------------------------------------------------------------- 17 | b.head // error | ^^^^^^ - | The expression's type box {*} String -> String is not allowed to capture the root capability `*`. + | The expression's type box String => String is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. -- Error: tests/neg-custom-args/captures/vars.scala:32:8 --------------------------------------------------------------- 32 | local { cap3 => // error | ^ - | The expression's type box {x$0, *} (x$0: String) -> String is not allowed to capture the root capability `*`. + | The expression's type box (x$0: String) => String is not allowed to capture the root capability `cap`. | This usually means that a capability persists longer than its allowed lifetime. 33 | def g(x: String): String = if cap3 == cap3 then "" else "a" 34 | g diff --git a/tests/neg-custom-args/captures/vars.scala b/tests/neg-custom-args/captures/vars.scala index 2ad8fec53619..e437d087d5a2 100644 --- a/tests/neg-custom-args/captures/vars.scala +++ b/tests/neg-custom-args/captures/vars.scala @@ -1,12 +1,12 @@ class CC -type Cap = {*} CC +type Cap = CC^ def test(cap1: Cap, cap2: Cap) = def f(x: String): String = if cap1 == cap1 then "" else "a" var x = f val y = x val z = () => if x("") == "" then "a" else "b" - val zc: {cap1} () -> String = z + val zc: () ->{cap1} String = z val z2 = () => { x = identity } val z2c: () -> Unit = z2 // error @@ -35,7 +35,7 @@ def test(cap1: Cap, cap2: Cap) = } class Ref: - var elem: {cap1} String -> String = null + var elem: String ->{cap1} String = null val r = Ref() r.elem = f diff --git a/tests/pending/neg/cc-depfun.scala b/tests/pending/neg/cc-depfun.scala new file mode 100644 index 000000000000..4d600872d208 --- /dev/null +++ b/tests/pending/neg/cc-depfun.scala @@ -0,0 +1,14 @@ +import language.experimental.captureChecking + +// compare with neg-custom-args/captures/depfun.scala, which produces errors +// but the errors go away if ->{} gets replaced by ->. + +trait Cap { def use(): Unit } + +def main() = { + val f: (io: Cap^) -> () -> Unit = + io => () => io.use() // error + + val g: (Cap^) -> () -> Unit = + io => () => io.use() // error +} diff --git a/tests/pos-custom-args/bounded1.scala b/tests/pos-custom-args/bounded1.scala index 5fb7f0da904b..e16da4935a14 100644 --- a/tests/pos-custom-args/bounded1.scala +++ b/tests/pos-custom-args/bounded1.scala @@ -1,27 +1,27 @@ // To be revisited class CC -type Cap = {*} CC +type Cap = CC^ def test(c: Cap) = - class B[X <: {c} Object](x: X): + class B[X <: Object^{c}](x: X): def elem = x def lateElem = () => x def f(x: Int): Int = if c == c then x else 0 val b = new B(f) val r1 = b.elem - val r1c: {c} Int -> Int = r1 + val r1c: Int^{c} -> Int = r1 val r2 = b.lateElem - val r2c: () -> {c} Int -> Int = r2 // was error now OK + val r2c: () -> Int^{c} -> Int = r2 // was error now OK def test2(c: Cap) = - class B[X <: {*} Any](x: X): + class B[X <: Any^](x: X): def elem = x def lateElem = () => x def f(x: Int): Int = if c == c then x else 0 val b = new B(f) val r1 = b.elem - val r1c: {c} Int -> Int = r1 + val r1c: Int ->{c} Int = r1 val r2 = b.lateElem - val r2c: () -> {c} Int -> Int = r2 // was error now OK \ No newline at end of file + val r2c: () -> Int ->{c} Int = r2 // was error now OK \ No newline at end of file diff --git a/tests/pos-custom-args/captures/bounded.scala b/tests/pos-custom-args/captures/bounded.scala index 85c1a67387b5..7959df7d50cf 100644 --- a/tests/pos-custom-args/captures/bounded.scala +++ b/tests/pos-custom-args/captures/bounded.scala @@ -1,14 +1,14 @@ class CC -type Cap = {*} CC +type Cap = CC^ def test(c: Cap) = - class B[X <: {c} Object](x: X): + class B[X <: Object^{c}](x: X): def elem = x def lateElem = () => x def f(x: Int): Int = if c == c then x else 0 val b = new B(f) val r1 = b.elem - val r1c: {c} Int -> Int = r1 + val r1c: Int ->{c} Int = r1 val r2 = b.lateElem - val r2c: {c} () -> {c} Int -> Int = r2 \ No newline at end of file + val r2c: () ->{c} Int ->{c} Int = r2 \ No newline at end of file diff --git a/tests/pos-custom-args/captures/boxed1.scala b/tests/pos-custom-args/captures/boxed1.scala index ba198335f51d..8c6b63ef0134 100644 --- a/tests/pos-custom-args/captures/boxed1.scala +++ b/tests/pos-custom-args/captures/boxed1.scala @@ -6,6 +6,6 @@ def foo(x: => Int): Unit = () def test(c: Cap) = val f = () => { c; 1 } - val _: {c} () -> Int = f + val _: () ->{c} Int = f val g = () => Box(f) - val _: () -> Box[{f} () -> Int] = g + val _: () -> Box[() ->{f} Int] = g diff --git a/tests/pos-custom-args/captures/boxmap-paper.scala b/tests/pos-custom-args/captures/boxmap-paper.scala index aff4c38e1b9d..9d5bb49af25d 100644 --- a/tests/pos-custom-args/captures/boxmap-paper.scala +++ b/tests/pos-custom-args/captures/boxmap-paper.scala @@ -12,25 +12,25 @@ def map[A, B](c: Cell[A])(f: A => B): Cell[B] def pureMap[A, B](c: Cell[A])(f: A -> B): Cell[B] = c[Cell[B]]((x: A) => cell(f(x))) -def lazyMap[A, B](c: Cell[A])(f: A => B): {f} () -> Cell[B] +def lazyMap[A, B](c: Cell[A])(f: A => B): () ->{f} Cell[B] = () => c[Cell[B]]((x: A) => cell(f(x))) trait IO: def print(s: String): Unit -def test(io: {*} IO) = +def test(io: IO^) = - val loggedOne: {io} () -> Int = () => { io.print("1"); 1 } + val loggedOne: () ->{io} Int = () => { io.print("1"); 1 } - val c: Cell[{io} () -> Int] - = cell[{io} () -> Int](loggedOne) + val c: Cell[() ->{io} Int] + = cell[() ->{io} Int](loggedOne) - val g = (f: {io} () -> Int) => + val g = (f: () ->{io} Int) => val x = f(); io.print(" + ") val y = f(); io.print(s" = ${x + y}") - val r = lazyMap[{io} () -> Int, Unit](c)(f => g(f)) - val r2 = lazyMap[{io} () -> Int, Unit](c)(g) + val r = lazyMap[() ->{io} Int, Unit](c)(f => g(f)) + val r2 = lazyMap[() ->{io} Int, Unit](c)(g) val r3 = lazyMap(c)(g) val _ = r() val _ = r2() diff --git a/tests/pos-custom-args/captures/byname.scala b/tests/pos-custom-args/captures/byname.scala index 35b8876d0058..efd76618469d 100644 --- a/tests/pos-custom-args/captures/byname.scala +++ b/tests/pos-custom-args/captures/byname.scala @@ -1,12 +1,12 @@ import annotation.retainsByName class CC -type Cap = {*} CC +type Cap = CC^ class I -def test(cap1: Cap, cap2: Cap): {cap1} I = +def test(cap1: Cap, cap2: Cap): I^{cap1} = def f() = if cap1 == cap1 then I() else I() - def h(x: {cap1}-> I) = x + def h(x: ->{cap} I) = x h(f()) // OK def hh(x: -> I @retainsByName(cap1)) = x h(f()) diff --git a/tests/pos-custom-args/captures/caps-universal.scala b/tests/pos-custom-args/captures/caps-universal.scala index d84f2b7b2584..3768c640fd68 100644 --- a/tests/pos-custom-args/captures/caps-universal.scala +++ b/tests/pos-custom-args/captures/caps-universal.scala @@ -1,7 +1,7 @@ import annotation.retains val foo: Int => Int = x => x -val bar: (Int -> Int) @retains(caps.*) = foo -val baz: {*} Int -> Int = bar +val bar: (Int -> Int) @retains(caps.cap) = foo +val baz: Int => Int = bar diff --git a/tests/pos-custom-args/captures/capt-capability.scala b/tests/pos-custom-args/captures/capt-capability.scala index 4dbd6e32f2a4..830d341c7bca 100644 --- a/tests/pos-custom-args/captures/capt-capability.scala +++ b/tests/pos-custom-args/captures/capt-capability.scala @@ -1,7 +1,7 @@ import annotation.capability @capability class Cap -def f1(c: Cap): {c} () -> c.type = () => c // ok +def f1(c: Cap): () ->{c} c.type = () => c // ok def f2: Int = val g: Boolean => Int = ??? @@ -17,8 +17,8 @@ def f3: Int = def foo() = val x: Cap = ??? val y: Cap = x - val x2: {x} () -> Cap = ??? - val y2: {x} () -> Cap = x2 + val x2: () ->{x} Cap = ??? + val y2: () ->{x} Cap = x2 val z1: () => Cap = f1(x) def h[X](a: X)(b: X) = a diff --git a/tests/pos-custom-args/captures/capt-depfun.scala b/tests/pos-custom-args/captures/capt-depfun.scala index 0e9786b2ee34..e3abbe0994c5 100644 --- a/tests/pos-custom-args/captures/capt-depfun.scala +++ b/tests/pos-custom-args/captures/capt-depfun.scala @@ -1,6 +1,6 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) type T = (x: Cap) -> String @retains(x) @@ -8,7 +8,7 @@ type ID[X] = X val aa: ((x: Cap) -> String @retains(x)) = (x: Cap) => "" -def f(y: Cap, z: Cap): String @retains(caps.*) = +def f(y: Cap, z: Cap): String @retains(caps.cap) = val a: ((x: Cap) -> String @retains(x)) = (x: Cap) => "" val b = a(y) val c: String @retains(y) = b @@ -16,6 +16,6 @@ def f(y: Cap, z: Cap): String @retains(caps.*) = val d = a(g()) val ac: ((x: Cap) -> ID[String @retains(x) -> String @retains(x)]) = ??? - val bc: (({y} String) -> {y} String) = ac(y) - val dc: (String -> {y, z} String) = ac(g()) + val bc: String^{y} -> String^{y} = ac(y) + val dc: String -> String^{y, z} = ac(g()) c diff --git a/tests/pos-custom-args/captures/capt-depfun2.scala b/tests/pos-custom-args/captures/capt-depfun2.scala index 1c747d5885e6..e4645cfcc920 100644 --- a/tests/pos-custom-args/captures/capt-depfun2.scala +++ b/tests/pos-custom-args/captures/capt-depfun2.scala @@ -1,9 +1,9 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) def f(y: Cap, z: Cap) = def g(): C @retains(y, z) = ??? val ac: ((x: Cap) -> Array[String @retains(x)]) = ??? - val dc: Array[? >: String <: {y, z} String] = ac(g()) // needs to be inferred + val dc: Array[? >: String <: String]^{y, z} = ac(g()) // needs to be inferred val ec = ac(y) diff --git a/tests/pos-custom-args/captures/capt-test.scala b/tests/pos-custom-args/captures/capt-test.scala index c61577e96eb1..e229c685d846 100644 --- a/tests/pos-custom-args/captures/capt-test.scala +++ b/tests/pos-custom-args/captures/capt-test.scala @@ -19,10 +19,10 @@ def map[A, B](f: A => B)(xs: LIST[A]): LIST[B] = xs.map(f) class C -type Cap = {*} C +type Cap = C^ class Foo(x: Cap): - this: {x} Foo => + this: Foo^{x} => def test(c: Cap, d: Cap) = def f(x: Cap): Unit = if c == x then () @@ -32,7 +32,7 @@ def test(c: Cap, d: Cap) = val zs = val z = g CONS(z, ys) - val zsc: LIST[{d, y} Cap -> Unit] = zs + val zsc: LIST[Cap ->{d, y} Unit] = zs val a4 = zs.map(identity) - val a4c: LIST[{d, y} Cap -> Unit] = a4 + val a4c: LIST[Cap ->{d, y} Unit] = a4 diff --git a/tests/pos-custom-args/captures/capt0.scala b/tests/pos-custom-args/captures/capt0.scala index 52d6253af46b..013ff3a4ee19 100644 --- a/tests/pos-custom-args/captures/capt0.scala +++ b/tests/pos-custom-args/captures/capt0.scala @@ -1,7 +1,7 @@ object Test: def test() = - val x: {*} Any = "abc" + val x: Any^ = "abc" val y: Object @scala.annotation.retains(x) = ??? - val z: Object @scala.annotation.retains(x, caps.*) = y: Object @annotation.retains(x) + val z: Object @scala.annotation.retains(x, caps.cap) = y: Object @annotation.retains(x) diff --git a/tests/pos-custom-args/captures/capt1.scala b/tests/pos-custom-args/captures/capt1.scala index cc39790623d4..8d2285f1fa50 100644 --- a/tests/pos-custom-args/captures/capt1.scala +++ b/tests/pos-custom-args/captures/capt1.scala @@ -1,9 +1,9 @@ class C -type Cap = {*} C -def f1(c: Cap): {c} () -> c.type = () => c // ok +type Cap = C^ +def f1(c: Cap): () ->{c} c.type = () => c // ok def f2: Int = - val g: {*} Boolean -> Int = ??? + val g: Boolean ->{cap} Int = ??? val x = g(true) x @@ -13,11 +13,11 @@ def f3: Int = val x = g.apply(true) x -def foo(): {*} C = - val x: {*} C = ??? - val y: {x} C = x - val x2: {x} () -> C = ??? - val y2: {x} () -> {x} C = x2 +def foo(): C^ = + val x: C^ = ??? + val y: C^{x} = x + val x2: () ->{x} C = ??? + val y2: () ->{x} C^{x} = x2 val z1: () => Cap = f1(x) def h[X](a: X)(b: X) = a diff --git a/tests/pos-custom-args/captures/capt2.scala b/tests/pos-custom-args/captures/capt2.scala index 77c0caaf0f1d..45381bf602ed 100644 --- a/tests/pos-custom-args/captures/capt2.scala +++ b/tests/pos-custom-args/captures/capt2.scala @@ -1,9 +1,9 @@ import annotation.retains class C -type Cap = C @retains(caps.*) +type Cap = C @retains(caps.cap) def test1() = - val y: {*} String = "" + val y: String^ = "" def x: Object @retains(y) = y def test2() = @@ -13,8 +13,8 @@ def test2() = z: (() -> Unit) @retains(x) def z2: (() -> Unit) @retains(y) = y z2: (() -> Unit) @retains(y) - val p: {*} () -> String = () => "abc" - val q: {p} C = ??? - val _ = p: ({p} () -> String) + val p: () => String = () => "abc" + val q: C^{p} = ??? + val _ = p: (() ->{p} String) diff --git a/tests/pos-custom-args/captures/caseclass.scala b/tests/pos-custom-args/captures/caseclass.scala index a845da181e9f..ffbf878dca49 100644 --- a/tests/pos-custom-args/captures/caseclass.scala +++ b/tests/pos-custom-args/captures/caseclass.scala @@ -1,6 +1,6 @@ @annotation.capability class C object test1: - case class Ref(x: {*} String) + case class Ref(x: String^) def test(c: C) = val x1 = Ref("hello") @@ -14,7 +14,7 @@ object test2: val pure: () -> Unit = () => () val impure: () => Unit = pure - val mixed: {c} () -> Unit = pure + val mixed: () ->{c} Unit = pure val x = Ref(impure) val y0 = x.copy(pure) val yc0: Ref = y0 @@ -25,10 +25,10 @@ object test2: val yc2: Ref = y2 val x3 = Ref(mixed) - val _: {c} Ref = x3 + val _: Ref^{c} = x3 val y3 = x3.copy() - val yc3: {c} Ref = y3 + val yc3: Ref^{c} = y3 val y4 = y3 match case Ref(xx) => xx - val y4c: {x3} () -> Unit = y4 + val y4c: () ->{x3} Unit = y4 diff --git a/tests/pos-custom-args/captures/cc-expand.scala b/tests/pos-custom-args/captures/cc-expand.scala index 87b2c34caf5f..1bed7b1cf001 100644 --- a/tests/pos-custom-args/captures/cc-expand.scala +++ b/tests/pos-custom-args/captures/cc-expand.scala @@ -5,11 +5,11 @@ object Test: class B class C class CTC - type CT = CTC @retains(caps.*) + type CT = CTC @retains(caps.cap) def test(ct: CT, dt: CT) = - def x0: A -> {ct} B = ??? + def x0: A -> B^{ct} = ??? def x1: A -> B @retains(ct) = ??? def x2: A -> B -> C @retains(ct) = ??? diff --git a/tests/pos-custom-args/captures/cc-this.scala b/tests/pos-custom-args/captures/cc-this.scala index 77414fa9b8c0..2124ee494041 100644 --- a/tests/pos-custom-args/captures/cc-this.scala +++ b/tests/pos-custom-args/captures/cc-this.scala @@ -5,7 +5,7 @@ def eff(using Cap): Unit = () def test(using Cap) = class C(val x: () => Int): - val y: {*} C = this + val y: C^ = this def f = () => eff @@ -14,4 +14,4 @@ def test(using Cap) = def c1 = new C(f) def c2 = c1 def c3 = c2.y - val _ = c3: {*} C + val _ = c3: C^ diff --git a/tests/pos-custom-args/captures/classes.scala b/tests/pos-custom-args/captures/classes.scala index f14a7e6dd84e..bc827dcfc67d 100644 --- a/tests/pos-custom-args/captures/classes.scala +++ b/tests/pos-custom-args/captures/classes.scala @@ -1,22 +1,22 @@ import annotation.retains class B -type Cap = {*} B +type Cap = B^ class C(val n: Cap): - this: {n} C => - def foo(): {n} B = n + this: C^{n} => + def foo(): B^{n} = n def test(x: Cap, y: Cap, z: Cap) = val c0 = C(x) - val c1: {x} C {val n: {x} B} = c0 + val c1: C{val n: B^{x}}^{x} = c0 val d = c1.foo() - d: {x} B + d: B^{x} val c2 = if ??? then C(x) else C(y) val c2a = identity(c2) - val c3: {x, y} C { val n: {x, y} B } = c2 + val c3: C{ val n: B^{x, y} }^{x, y} = c2 val d1 = c3.foo() - d1: B @retains(x, y) + d1: B^{x, y} class Local: @@ -29,7 +29,7 @@ def test(x: Cap, y: Cap, z: Cap) = end Local val l = Local() - val l1: {x, y} Local = l + val l1: Local^{x, y} = l val l2 = Local(x) - val l3: {x, y, z} Local = l2 + val l3: Local^{x, y, z} = l2 diff --git a/tests/pos-custom-args/captures/compare-refined.scala b/tests/pos-custom-args/captures/compare-refined.scala index c60bfee602b3..306f2216ab82 100644 --- a/tests/pos-custom-args/captures/compare-refined.scala +++ b/tests/pos-custom-args/captures/compare-refined.scala @@ -2,11 +2,11 @@ abstract class LIST[+T]: def map[U](f: T => U): LIST[U] = ??? class C -type Cap = {*} C +type Cap = C^ def test(d: Cap) = - val zsc: LIST[{d} Cap -> Unit] = ??? - val a4 = zsc.map[{d} Cap -> Unit]((x: {d} Cap -> Unit) => x) - val a5 = zsc.map[{d} Cap -> Unit](identity[{d} Cap -> Unit]) - val a6 = zsc.map(identity[{d} Cap -> Unit]) + val zsc: LIST[Cap ->{d} Unit] = ??? + val a4 = zsc.map[Cap ->{d} Unit]((x: Cap ->{d} Unit) => x) + val a5 = zsc.map[Cap ->{d} Unit](identity[Cap ->{d} Unit]) + val a6 = zsc.map(identity[Cap ->{d} Unit]) val a7 = zsc.map(identity) diff --git a/tests/pos-custom-args/captures/curried-shorthands.scala b/tests/pos-custom-args/captures/curried-shorthands.scala index 7c58729a3041..c68dc4b5cdbf 100644 --- a/tests/pos-custom-args/captures/curried-shorthands.scala +++ b/tests/pos-custom-args/captures/curried-shorthands.scala @@ -10,15 +10,15 @@ object Test: val f3 = (f: Int => Int) => println(f(3)) (xs: List[Int]) => xs.map(_ + 1) - val f3c: (Int => Int) -> {} List[Int] -> List[Int] = f3 + val f3c: (Int => Int) -> List[Int] ->{} List[Int] = f3 class LL[A]: - def drop(n: Int): {this} LL[A] = ??? + def drop(n: Int): LL[A]^{this} = ??? def test(ct: CanThrow[Exception]) = - def xs: {ct} LL[Int] = ??? + def xs: LL[Int]^{ct} = ??? val ys = xs.drop(_) - val ysc: Int -> {ct} LL[Int] = ys + val ysc: Int -> LL[Int]^{ct} = ys diff --git a/tests/pos-custom-args/captures/filevar.scala b/tests/pos-custom-args/captures/filevar.scala index 17a8281c4d29..a6cc7ca9ff47 100644 --- a/tests/pos-custom-args/captures/filevar.scala +++ b/tests/pos-custom-args/captures/filevar.scala @@ -6,10 +6,10 @@ object test1: class File: def write(x: String): Unit = ??? - class Service(f: {*} File): + class Service(f: File^): def log = f.write("log") - def withFile[T](op: (f: {*} File) => T): T = + def withFile[T](op: (f: File^) => T): T = op(new File) def test = @@ -24,10 +24,10 @@ object test2: def write(x: String): Unit = ??? class Service(io: IO): - var file: {io} File = uninitialized + var file: File^{io} = uninitialized def log = file.write("log") - def withFile[T](io: IO)(op: (f: {io} File) => T): T = + def withFile[T](io: IO)(op: (f: File^{io}) => T): T = op(new File) def test(io: IO) = diff --git a/tests/pos-custom-args/captures/hk-param.scala b/tests/pos-custom-args/captures/hk-param.scala index b0e894d865e9..bf2f75f29e7f 100644 --- a/tests/pos-custom-args/captures/hk-param.scala +++ b/tests/pos-custom-args/captures/hk-param.scala @@ -1,17 +1,17 @@ /** Concrete collection type: View */ -trait View[+A] extends Itable[A], ILike[A, [X] =>> {*} View[X]]: - override def fromIterable[B](c: {*} Itable[B]): {c} View[B] = ??? +trait View[+A] extends Itable[A], ILike[A, [X] =>> View[X]^]: + override def fromIterable[B](c: Itable[B]^): View[B]^{c} = ??? trait IPolyTransforms[+A, +C[A]] extends Any: - def fromIterable[B](coll: {*} Itable[B]): C[B] + def fromIterable[B](coll: Itable[B]^): C[B] -trait ILike[+A, +C[X] <: {*} Itable[X]] extends IPolyTransforms[A, C] +trait ILike[+A, +C[X] <: Itable[X]^] extends IPolyTransforms[A, C] /** Base trait for generic collections */ -trait Itable[+A] extends ItableOnce[A] with ILike[A, {*} Itable] +trait Itable[+A] extends ItableOnce[A] with ILike[A, Itable^] /** Iterator can be used only once */ trait ItableOnce[+A] { - this: {*} ItableOnce[A] => - def iterator: {this} Iterator[A] + this: ItableOnce[A]^ => + def iterator: Iterator[A]^{this} } diff --git a/tests/pos-custom-args/captures/i15922.scala b/tests/pos-custom-args/captures/i15922.scala index 8547f7598eef..23109a3ba8f4 100644 --- a/tests/pos-custom-args/captures/i15922.scala +++ b/tests/pos-custom-args/captures/i15922.scala @@ -2,13 +2,13 @@ trait Cap { def use(): Int } type Id[X] = [T] -> (op: X => T) -> T def mkId[X](x: X): Id[X] = [T] => (op: X => T) => op(x) -def withCap[X](op: ({*} Cap) => X): X = { - val cap: {*} Cap = new Cap { def use() = { println("cap is used"); 0 } } +def withCap[X](op: (Cap^) => X): X = { + val cap: Cap^ = new Cap { def use() = { println("cap is used"); 0 } } val result = op(cap) result } -def leaking(c: {*} Cap): Id[{c} Cap] = mkId(c) +def leaking(c: Cap^): Id[Cap^{c}] = mkId(c) def test = val bad = withCap(leaking) diff --git a/tests/pos-custom-args/captures/i16116.scala b/tests/pos-custom-args/captures/i16116.scala index 2f5d5304dca5..0311e744f146 100644 --- a/tests/pos-custom-args/captures/i16116.scala +++ b/tests/pos-custom-args/captures/i16116.scala @@ -17,7 +17,7 @@ object Test { @capability class CpsTransform[F[_]] { - def await[T](ft: F[T]): { this } T = ??? + def await[T](ft: F[T]): T^{ this } = ??? } transparent inline def cpsAsync[F[_]](using m:CpsMonad[F]) = @@ -27,7 +27,7 @@ object Test { def apply[A](expr: (CpsTransform[F], C) ?=> A): F[A] = ??? } - def asyncPlus[F[_]](a:Int, b:F[Int])(using cps: CpsTransform[F]): { cps } Int = + def asyncPlus[F[_]](a:Int, b:F[Int])(using cps: CpsTransform[F]): Int^{ cps } = a + (cps.await(b).asInstanceOf[Int]) def testExample1Future(): Unit = diff --git a/tests/pos-custom-args/captures/i16226.scala b/tests/pos-custom-args/captures/i16226.scala index 8edf3f54d739..4cd7f0ceea81 100644 --- a/tests/pos-custom-args/captures/i16226.scala +++ b/tests/pos-custom-args/captures/i16226.scala @@ -1,14 +1,14 @@ @annotation.capability class Cap class LazyRef[T](val elem: () => T): - val get: {elem} () -> T = elem - def map[U](f: T => U): {f, this} LazyRef[U] = + val get: () ->{elem} T = elem + def map[U](f: T => U): LazyRef[U]^{f, this} = new LazyRef(() => f(elem())) -def map[A, B](ref: {*} LazyRef[A], f: A => B): {f, ref} LazyRef[B] = +def map[A, B](ref: LazyRef[A]^, f: A => B): LazyRef[B]^{f, ref} = new LazyRef(() => f(ref.elem())) def main(io: Cap) = { - def mapd[A, B]: ({io} LazyRef[A], A => B) => {*} LazyRef[B] = + def mapd[A, B]: (LazyRef[A]^{io}, A => B) => LazyRef[B]^ = (ref1, f1) => map[A, B](ref1, f1) } diff --git a/tests/pos-custom-args/captures/iterators.scala b/tests/pos-custom-args/captures/iterators.scala index 50be2012e25c..10a7f57cd68f 100644 --- a/tests/pos-custom-args/captures/iterators.scala +++ b/tests/pos-custom-args/captures/iterators.scala @@ -1,19 +1,19 @@ package cctest abstract class Iterator[T]: - thisIterator: {*} Iterator[T] => + thisIterator: Iterator[T]^ => def hasNext: Boolean def next: T - def map(f: {*} T => T): {f, this} Iterator[T] = new Iterator: + def map(f: T => T): Iterator[T]^{f, this} = new Iterator: def hasNext = thisIterator.hasNext def next = f(thisIterator.next) end Iterator class C -type Cap = {*} C +type Cap = C^ -def map[T, U](it: {*} Iterator[T], f: {*} T => U): {it, f} Iterator[U] = new Iterator: +def map[T, U](it: Iterator[T]^, f: T^ => U): Iterator[U]^{it, f} = new Iterator: def hasNext = it.hasNext def next = f(it.next) diff --git a/tests/pos-custom-args/captures/lazylists-exceptions.scala b/tests/pos-custom-args/captures/lazylists-exceptions.scala index 2d4ebb245dca..8f1fba2bf2dc 100644 --- a/tests/pos-custom-args/captures/lazylists-exceptions.scala +++ b/tests/pos-custom-args/captures/lazylists-exceptions.scala @@ -4,52 +4,52 @@ import scala.compiletime.uninitialized trait LzyList[+A]: def isEmpty: Boolean def head: A - def tail: {this} LzyList[A] + def tail: LzyList[A]^{this} object LzyNil extends LzyList[Nothing]: def isEmpty = true def head = ??? def tail = ??? -final class LzyCons[+A](hd: A, tl: () => {*} LzyList[A]) extends LzyList[A]: +final class LzyCons[+A](hd: A, tl: () => LzyList[A]^) extends LzyList[A]: private var forced = false - private var cache: {this} LzyList[A] = uninitialized + private var cache: LzyList[A]^{this} = uninitialized private def force = if !forced then { cache = tl(); forced = true } cache def isEmpty = false def head = hd - def tail: {this} LzyList[A] = force + def tail: LzyList[A]^{this} = force end LzyCons -extension [A](xs: {*} LzyList[A]) - def map[B](f: A => B): {xs, f} LzyList[B] = +extension [A](xs: LzyList[A]^) + def map[B](f: A => B): LzyList[B]^{xs, f} = if xs.isEmpty then LzyNil else LzyCons(f(xs.head), () => xs.tail.map(f)) - def filter(p: A => Boolean): {xs, p} LzyList[A] = + def filter(p: A => Boolean): LzyList[A]^{xs, p} = if xs.isEmpty then LzyNil else if p(xs.head) then lazyCons(xs.head, xs.tail.filter(p)) else xs.tail.filter(p) - def concat(ys: {*} LzyList[A]): {xs, ys} LzyList[A] = + def concat(ys: LzyList[A]^): LzyList[A]^{xs, ys} = if xs.isEmpty then ys else xs.head #: xs.tail.concat(ys) - def drop(n: Int): {xs} LzyList[A] = + def drop(n: Int): LzyList[A]^{xs} = if n == 0 then xs else xs.tail.drop(n - 1) end extension extension [A](x: A) - def #:(xs1: => {*} LzyList[A]): {xs1} LzyList[A] = + def #:(xs1: => LzyList[A]^): LzyList[A]^{xs1} = LzyCons(x, () => xs1) -def lazyCons[A](x: A, xs1: => {*} LzyList[A]): {xs1} LzyList[A] = +def lazyCons[A](x: A, xs1: => LzyList[A]^): LzyList[A]^{xs1} = LzyCons(x, () => xs1) -def tabulate[A](n: Int)(gen: Int => A): {gen} LzyList[A] = - def recur(i: Int): {gen} LzyList[A] = +def tabulate[A](n: Int)(gen: Int => A): LzyList[A]^{gen} = + def recur(i: Int): LzyList[A]^{gen} = if i == n then LzyNil else gen(i) #: recur(i + 1) recur(0) @@ -69,16 +69,16 @@ def test(using cap1: CanThrow[Ex1], cap2: CanThrow[Ex2]) = x * x def x1 = xs.map(f) - def x1c: {cap1} LzyList[Int] = x1 + def x1c: LzyList[Int]^{cap1} = x1 def x2 = x1.concat(xs.map(g).filter(_ > 0)) - def x2c: {cap1, cap2} LzyList[Int] = x2 + def x2c: LzyList[Int]^{cap1, cap2} = x2 val x3 = tabulate(10) { i => if i > 9 then throw Ex1() i * i } - val x3c: {cap1} LzyList[Int] = x3 + val x3c: LzyList[Int]^{cap1} = x3 class LimitExceeded extends Exception diff --git a/tests/pos-custom-args/captures/lazylists-mono.scala b/tests/pos-custom-args/captures/lazylists-mono.scala index 44ab36ded6a2..c91bedd8f1cf 100644 --- a/tests/pos-custom-args/captures/lazylists-mono.scala +++ b/tests/pos-custom-args/captures/lazylists-mono.scala @@ -1,26 +1,26 @@ class CC -type Cap = {*} CC +type Cap = CC^ //------------------------------------------------- def test(E: Cap) = trait LazyList[+A]: - protected def contents: {E} () -> (A, {E} LazyList[A]) + protected def contents: () ->{E} (A, LazyList[A]^{E}) def isEmpty: Boolean def head: A = contents()._1 - def tail: {E} LazyList[A] = contents()._2 + def tail: LazyList[A]^{E} = contents()._2 - class LazyCons[+A](override val contents: {E} () -> (A, {E} LazyList[A])) + class LazyCons[+A](override val contents: () ->{E} (A, LazyList[A]^{E})) extends LazyList[A]: def isEmpty: Boolean = false object LazyNil extends LazyList[Nothing]: - def contents: {E} () -> (Nothing, LazyList[Nothing]) = ??? + def contents: () ->{E} (Nothing, LazyList[Nothing]) = ??? def isEmpty: Boolean = true - extension [A](xs: {E} LazyList[A]) - def map[B](f: {E} A -> B): {E} LazyList[B] = + extension [A](xs: LazyList[A]^{E}) + def map[B](f: A ->{E} B): LazyList[B]^{E} = if xs.isEmpty then LazyNil else val cons = () => (f(xs.head), xs.tail.map(f)) diff --git a/tests/pos-custom-args/captures/lazylists.scala b/tests/pos-custom-args/captures/lazylists.scala index fd130c87cdea..273f21c1fcf3 100644 --- a/tests/pos-custom-args/captures/lazylists.scala +++ b/tests/pos-custom-args/captures/lazylists.scala @@ -1,26 +1,26 @@ class CC -type Cap = {*} CC +type Cap = CC^ trait LazyList[+A]: - this: {*} LazyList[A] => + this: LazyList[A]^ => def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? -extension [A](xs: {*} LazyList[A]) - def map[B](f: A => B): {xs, f} LazyList[B] = +extension [A](xs: LazyList[A]^) + def map[B](f: A => B): LazyList[B]^{xs, f} = final class Mapped extends LazyList[B]: - this: {xs, f} Mapped => + this: Mapped^{xs, f} => def isEmpty = false def head: B = f(xs.head) - def tail: {this} LazyList[B] = xs.tail.map(f) // OK + def tail: LazyList[B]^{this} = xs.tail.map(f) // OK if xs.isEmpty then LazyNil else new Mapped @@ -30,12 +30,12 @@ def test(cap1: Cap, cap2: Cap) = val xs = class Initial extends LazyList[String]: - this: {cap1} Initial => + this: Initial^{cap1} => def isEmpty = false def head = f("") def tail = LazyNil new Initial - val xsc: {cap1} LazyList[String] = xs + val xsc: LazyList[String]^{cap1} = xs val ys = xs.map(g) - val ysc: {cap1, cap2} LazyList[String] = ys + val ysc: LazyList[String]^{cap1, cap2} = ys diff --git a/tests/pos-custom-args/captures/lazylists1.scala b/tests/pos-custom-args/captures/lazylists1.scala index a59e7c0da12f..62b34f442221 100644 --- a/tests/pos-custom-args/captures/lazylists1.scala +++ b/tests/pos-custom-args/captures/lazylists1.scala @@ -1,28 +1,28 @@ class CC -type Cap = {*} CC +type Cap = CC^ trait LazyList[+A]: def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] - def concat[B >: A](other: {*} LazyList[B]): {this, other} LazyList[B] + def tail: LazyList[A]^{this} + def concat[B >: A](other: LazyList[B]^): LazyList[B]^{this, other} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? - def concat[B](other: {*} LazyList[B]): {other} LazyList[B] = other + def concat[B](other: LazyList[B]^): LazyList[B]^{other} = other -final class LazyCons[+A](x: A)(xs: () => {*} LazyList[A]) extends LazyList[A]: +final class LazyCons[+A](x: A)(xs: () => LazyList[A]^) extends LazyList[A]: def isEmpty = false def head = x - def tail: {this} LazyList[A] = xs() - def concat[B >: A](other: {*} LazyList[B]): {this, other} LazyList[B] = + def tail: LazyList[A]^{this} = xs() + def concat[B >: A](other: LazyList[B]^): LazyList[B]^{this, other} = LazyCons(head)(() => tail.concat(other)) -extension [A](xs: {*} LazyList[A]) - def map[B](f: A => B): {xs, f} LazyList[B] = +extension [A](xs: LazyList[A]^) + def map[B](f: A => B): LazyList[B]^{xs, f} = if xs.isEmpty then LazyNil else LazyCons(f(xs.head))(() => xs.tail.map(f)) @@ -31,9 +31,9 @@ def test(cap1: Cap, cap2: Cap) = def g(x: String): String = if cap2 == cap2 then "" else "a" val xs = new LazyCons("")(() => if f("") == f("") then LazyNil else LazyNil) - val xsc: {cap1} LazyList[String] = xs + val xsc: LazyList[String]^{cap1} = xs val ys = xs.map(g) - val ysc: {cap1, cap2} LazyList[String] = ys + val ysc: LazyList[String]^{cap1, cap2} = ys val zs = new LazyCons("")(() => if g("") == g("") then LazyNil else LazyNil) val as = xs.concat(zs) - val asc: {xs, zs} LazyList[String] = as + val asc: LazyList[String]^{xs, zs} = as diff --git a/tests/pos-custom-args/captures/lazyref.scala b/tests/pos-custom-args/captures/lazyref.scala index 0d988dc3e17b..3dae51b491b4 100644 --- a/tests/pos-custom-args/captures/lazyref.scala +++ b/tests/pos-custom-args/captures/lazyref.scala @@ -1,24 +1,24 @@ @annotation.capability class Cap class LazyRef[T](val elem: () => T): - val get: {elem} () -> T = elem - def map[U](f: T => U): {f, this} LazyRef[U] = + val get: () ->{elem} T = elem + def map[U](f: T => U): LazyRef[U]^{f, this} = new LazyRef(() => f(elem())) -def map[A, B](ref: {*} LazyRef[A], f: A => B): {f, ref} LazyRef[B] = +def map[A, B](ref: LazyRef[A]^, f: A => B): LazyRef[B]^{f, ref} = new LazyRef(() => f(ref.elem())) -def mapc[A, B]: (ref: {*} LazyRef[A], f: A => B) => {f, ref} LazyRef[B] = +def mapc[A, B]: (ref: LazyRef[A]^, f: A => B) => LazyRef[B]^{f, ref} = (ref1, f1) => map[A, B](ref1, f1) def test(cap1: Cap, cap2: Cap) = def f(x: Int) = if cap1 == cap1 then x else 0 def g(x: Int) = if cap2 == cap2 then x else 0 val ref1 = LazyRef(() => f(0)) - val ref1c: {cap1} LazyRef[Int] = ref1 + val ref1c: LazyRef[Int]^{cap1} = ref1 val ref2 = map(ref1, g) - val ref2c: {cap2, ref1} LazyRef[Int] = ref2 + val ref2c: LazyRef[Int]^{cap2, ref1} = ref2 val ref3 = ref1.map(g) - val ref3c: {cap2, ref1} LazyRef[Int] = ref3 + val ref3c: LazyRef[Int]^{cap2, ref1} = ref3 val ref4 = (if cap1 == cap2 then ref1 else ref2).map(g) - val ref4c: {cap1, cap2} LazyRef[Int] = ref4 + val ref4c: LazyRef[Int]^{cap1, cap2} = ref4 diff --git a/tests/pos-custom-args/captures/list-encoding.scala b/tests/pos-custom-args/captures/list-encoding.scala index 87630467023e..d959b523404b 100644 --- a/tests/pos-custom-args/captures/list-encoding.scala +++ b/tests/pos-custom-args/captures/list-encoding.scala @@ -7,7 +7,7 @@ type Op[T, C] = (v: T) => (s: C) => C type List[T] = - [C] -> (op: Op[T, C]) -> {op} (s: C) -> C + [C] -> (op: Op[T, C]) -> (s: C) ->{op} C def nil[T]: List[T] = [C] => (op: Op[T, C]) => (s: C) => s @@ -15,7 +15,7 @@ def nil[T]: List[T] = def cons[T](hd: T, tl: List[T]): List[T] = [C] => (op: Op[T, C]) => (s: C) => op(hd)(tl(op)(s)) -def foo(c: {*} Cap) = +def foo(c: Cap^) = def f(x: String @retains(c), y: String @retains(c)) = cons(x, cons(y, nil)) def g(x: String @retains(c), y: Any) = diff --git a/tests/pos-custom-args/captures/lists.scala b/tests/pos-custom-args/captures/lists.scala index 6389ec933b32..56473e68d49f 100644 --- a/tests/pos-custom-args/captures/lists.scala +++ b/tests/pos-custom-args/captures/lists.scala @@ -2,7 +2,7 @@ abstract class LIST[+T]: def isEmpty: Boolean def head: T def tail: LIST[T] - def map[U](f: {*} T -> U): LIST[U] = + def map[U](f: T => U): LIST[U] = if isEmpty then NIL else CONS(f(head), tail.map(f)) @@ -28,9 +28,9 @@ def test(c: Cap, d: Cap, e: Cap) = val zs = val z = g CONS(z, ys) - val zsc: LIST[{d, y} Cap -> Unit] = zs + val zsc: LIST[Cap ->{d, y} Unit] = zs val z1 = zs.head - val z1c: {y, d} Cap -> Unit = z1 + val z1c: Cap ->{y, d} Unit = z1 val ys1 = zs.tail val y1 = ys1.head @@ -38,53 +38,53 @@ def test(c: Cap, d: Cap, e: Cap) = def m1[A, B] = (f: A => B) => (xs: LIST[A]) => xs.map(f) - def m1c: (f: String => Int) -> {f} LIST[String] -> LIST[Int] = m1[String, Int] + def m1c: (f: String => Int) -> LIST[String] ->{f} LIST[Int] = m1[String, Int] def m2 = [A, B] => (f: A => B) => (xs: LIST[A]) => xs.map(f) - def m2c: [A, B] -> (f: A => B) -> {f} LIST[A] -> LIST[B] = m2 + def m2c: [A, B] -> (f: A => B) -> LIST[A] ->{f} LIST[B] = m2 def eff[A](x: A) = if x == e then x else x val eff2 = [A] => (x: A) => if x == e then x else x - val a0 = identity[{d, y} Cap -> Unit] - val a0c: {d, y} ({d, y} Cap -> Unit) -> {d, y} Cap -> Unit = a0 - val a1 = zs.map[{d, y} Cap -> Unit](a0) - val a1c: LIST[{d, y} Cap -> Unit] = a1 - val a2 = zs.map[{d, y} Cap -> Unit](identity[{d, y} Cap -> Unit]) - val a2c: LIST[{d, y} Cap -> Unit] = a2 - val a3 = zs.map(identity[{d, y} Cap -> Unit]) - val a3c: LIST[{d, y} Cap -> Unit] = a3 + val a0 = identity[Cap ->{d, y} Unit] + val a0c: (Cap ->{d, y} Unit) ->{d, y} Cap ->{d, y} Unit = a0 + val a1 = zs.map[Cap ->{d, y} Unit](a0) + val a1c: LIST[Cap ->{d, y} Unit] = a1 + val a2 = zs.map[Cap ->{d, y} Unit](identity[Cap ->{d, y} Unit]) + val a2c: LIST[Cap ->{d, y} Unit] = a2 + val a3 = zs.map(identity[Cap ->{d, y} Unit]) + val a3c: LIST[Cap ->{d, y} Unit] = a3 val a4 = zs.map(identity) - val a4c: LIST[{d, c} Cap -> Unit] = a4 - val a5 = map[{d, y} Cap -> Unit, {d, y} Cap -> Unit](identity)(zs) - val a5c: LIST[{d, c} Cap -> Unit] = a5 - val a6 = m1[{d, y} Cap -> Unit, {d, y} Cap -> Unit](identity)(zs) - val a6c: LIST[{d, c} Cap -> Unit] = a6 + val a4c: LIST[Cap ->{d, c} Unit] = a4 + val a5 = map[Cap ->{d, y} Unit, Cap ->{d, y} Unit](identity)(zs) + val a5c: LIST[Cap ->{d, c} Unit] = a5 + val a6 = m1[Cap ->{d, y} Unit, Cap ->{d, y} Unit](identity)(zs) + val a6c: LIST[Cap ->{d, c} Unit] = a6 - val b0 = eff[{d, y} Cap -> Unit] - val b0c: {e, d, y} ({d, y} Cap -> Unit) -> {d, y} Cap -> Unit = b0 - val b1 = zs.map[{d, y} Cap -> Unit](a0) - val b1c: {e} LIST[{d, y} Cap -> Unit] = b1 - val b2 = zs.map[{d, y} Cap -> Unit](eff[{d, y} Cap -> Unit]) - val b2c: {e} LIST[{d, y} Cap -> Unit] = b2 - val b3 = zs.map(eff[{d, y} Cap -> Unit]) - val b3c: {e} LIST[{d, y} Cap -> Unit] = b3 + val b0 = eff[Cap ->{d, y} Unit] + val b0c: (Cap ->{d, y} Unit) ->{e, d, y} Cap ->{d, y} Unit = b0 + val b1 = zs.map[Cap ->{d, y} Unit](a0) + val b1c: LIST[Cap ->{d, y} Unit]^{e} = b1 + val b2 = zs.map[Cap ->{d, y} Unit](eff[Cap ->{d, y} Unit]) + val b2c: LIST[Cap ->{d, y} Unit]^{e} = b2 + val b3 = zs.map(eff[Cap ->{d, y} Unit]) + val b3c: LIST[Cap ->{d, y} Unit]^{e} = b3 val b4 = zs.map(eff) - val b4c: {e} LIST[{d, c} Cap -> Unit] = b4 - val b5 = map[{d, y} Cap -> Unit, {d, y} Cap -> Unit](eff)(zs) - val b5c: {e} LIST[{d, c} Cap -> Unit] = b5 - val b6 = m1[{d, y} Cap -> Unit, {d, y} Cap -> Unit](eff)(zs) - val b6c: {e} LIST[{d, c} Cap -> Unit] = b6 + val b4c: LIST[Cap ->{d, c} Unit]^{e} = b4 + val b5 = map[Cap ->{d, y} Unit, Cap ->{d, y} Unit](eff)(zs) + val b5c: LIST[Cap ->{d, c} Unit]^{e} = b5 + val b6 = m1[Cap ->{d, y} Unit, Cap ->{d, y} Unit](eff)(zs) + val b6c: LIST[Cap ->{d, c} Unit]^{e} = b6 - val c0 = eff2[{d, y} Cap -> Unit] - val c0c: {e, d, y} ({d, y} Cap -> Unit) -> {d, y} Cap -> Unit = c0 - val c1 = zs.map[{d, y} Cap -> Unit](a0) - val c1c: {e} LIST[{d, y} Cap -> Unit] = c1 - val c2 = zs.map[{d, y} Cap -> Unit](eff2[{d, y} Cap -> Unit]) - val c2c: {e} LIST[{d, y} Cap -> Unit] = c2 - val c3 = zs.map(eff2[{d, y} Cap -> Unit]) - val c3c: {e} LIST[{d, y} Cap -> Unit] = c3 + val c0 = eff2[Cap ->{d, y} Unit] + val c0c: (Cap ->{d, y} Unit) ->{e, d, y} Cap ->{d, y} Unit = c0 + val c1 = zs.map[Cap ->{d, y} Unit](a0) + val c1c: LIST[Cap ->{d, y} Unit]^{e} = c1 + val c2 = zs.map[Cap ->{d, y} Unit](eff2[Cap ->{d, y} Unit]) + val c2c: LIST[Cap ->{d, y} Unit]^{e} = c2 + val c3 = zs.map(eff2[Cap ->{d, y} Unit]) + val c3c: LIST[Cap ->{d, y} Unit]^{e} = c3 diff --git a/tests/pos-custom-args/captures/logger.scala b/tests/pos-custom-args/captures/logger.scala index e5b6c834ffe0..3f417da8c1be 100644 --- a/tests/pos-custom-args/captures/logger.scala +++ b/tests/pos-custom-args/captures/logger.scala @@ -7,9 +7,9 @@ class Logger(using fs: FileSystem): def log(s: String): Unit = ??? def test(using fs: FileSystem) = - val l: {fs} Logger = Logger(using fs) + val l: Logger^{fs} = Logger(using fs) l.log("hello world!") - val xs: {l} LazyList[Int] = + val xs: LazyList[Int]^{l} = LazyList.from(1) .map { i => l.log(s"computing elem # $i") @@ -19,25 +19,25 @@ def test(using fs: FileSystem) = trait LazyList[+A]: def isEmpty: Boolean def head: A - def tail: {this} LazyList[A] + def tail: LazyList[A]^{this} object LazyNil extends LazyList[Nothing]: def isEmpty: Boolean = true def head = ??? def tail = ??? -final class LazyCons[+T](val x: T, val xs: () => {*} LazyList[T]) extends LazyList[T]: +final class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]: def isEmpty = false def head = x - def tail: {this} LazyList[T] = xs() + def tail: LazyList[T]^{this} = xs() end LazyCons extension [A](x: A) - def #::(xs1: => {*} LazyList[A]): {xs1} LazyList[A] = + def #::(xs1: => LazyList[A]^): LazyList[A]^{xs1} = LazyCons(x, () => xs1) -extension [A](xs: {*} LazyList[A]) - def map[B](f: A => B): {xs, f} LazyList[B] = +extension [A](xs: LazyList[A]^) + def map[B](f: A => B): LazyList[B]^{xs, f} = if xs.isEmpty then LazyNil else f(xs.head) #:: xs.tail.map(f) @@ -50,17 +50,17 @@ class Pair[+A, +B](x: A, y: B): def snd: B = y def test2(ct: CanThrow[Exception], fs: FileSystem) = - def x: {ct} Int -> String = ??? - def y: {fs} Logger = ??? + def x: Int ->{ct} String = ??? + def y: Logger^{fs} = ??? def p = Pair(x, y) def f = () => p.fst /* - val l1: {*} Int -> String = ??? - val l2: {c} Object = ??? + val l1: Int => String = ??? + val l2: Object^{c} = ??? val pd = () => Pair(l1, l2) - val p2: Pair[{*} Int -> String, {c} Object] = pd() + val p2: Pair[Int => String, Object]^{c} = pd() val hd = () => p2.fst */ \ No newline at end of file diff --git a/tests/pos-custom-args/captures/nested-classes.scala b/tests/pos-custom-args/captures/nested-classes.scala index 2e893b7413a5..b16fc4365183 100644 --- a/tests/pos-custom-args/captures/nested-classes.scala +++ b/tests/pos-custom-args/captures/nested-classes.scala @@ -5,10 +5,10 @@ import annotation.{capability, constructorOnly} class Blah class Pkg(using @constructorOnly io: IO): class Foo: - def m(foo: {io} Blah) = ??? + def m(foo: Blah^{io}) = ??? class Pkg2(using io: IO): class Foo: - def m(foo: {io} Blah): Any = io; ??? + def m(foo: Blah^{io}): Any = io; ??? def main(using io: IO) = val pkg = Pkg() diff --git a/tests/pos-custom-args/captures/nonvariant-inf.scala b/tests/pos-custom-args/captures/nonvariant-inf.scala index 6569f35042e8..4798f98c9fce 100644 --- a/tests/pos-custom-args/captures/nonvariant-inf.scala +++ b/tests/pos-custom-args/captures/nonvariant-inf.scala @@ -3,7 +3,7 @@ trait Iterable[+A] /** Base trait for instances that can construct a collection from an iterable */ trait FromIterable { - type C[X] <: {*} Iterable[X] - def fromIterable[B](it: {*} Iterable[B]): {it} C[B] + type C[X] <: Iterable[X]^ + def fromIterable[B](it: Iterable[B]^): C[B]^{it} def empty[A]: C[A] = fromIterable(??? : Iterable[A]) } diff --git a/tests/pos-custom-args/captures/override-adapt-box-pos-alt.scala b/tests/pos-custom-args/captures/override-adapt-box-pos-alt.scala index c7e4d38723d7..bb6b4030dbff 100644 --- a/tests/pos-custom-args/captures/override-adapt-box-pos-alt.scala +++ b/tests/pos-custom-args/captures/override-adapt-box-pos-alt.scala @@ -9,9 +9,9 @@ abstract class A[X] { class C -def test(io: {*} IO) = { - class B extends A[{io} C] { // X =:= {io} C - def foo(x: Unit): {io} C = ??? - def bar(op: ({io} C) => Int): Int = 0 +def test(io: IO^) = { + class B extends A[C^{io}] { // X =:= {io} C + def foo(x: Unit): C^{io} = ??? + def bar(op: (C^{io}) => Int): Int = 0 } } diff --git a/tests/pos-custom-args/captures/override-adapt-box-pos.scala b/tests/pos-custom-args/captures/override-adapt-box-pos.scala index 7496a138070d..9adaec6896cf 100644 --- a/tests/pos-custom-args/captures/override-adapt-box-pos.scala +++ b/tests/pos-custom-args/captures/override-adapt-box-pos.scala @@ -4,16 +4,16 @@ class IO abstract class A[X, Y] { def foo(x: Unit): X - def bar(x: Int, y: {} IO): X + def bar(x: Int, y: IO^{}): X def baz(x: Y): X } class C -def test(io: {*} IO) = { - class B extends A[{io} C, {} C] { // X =:= {io} C - override def foo(x: Unit): {io} C = ??? - override def bar(x: Int, y: {} IO): {io} C = ??? - override def baz(x: {} C): {io} C = ??? +def test(io: IO^) = { + class B extends A[C^{io}, C^{}] { // X =:= {io} C + override def foo(x: Unit): C^{io} = ??? + override def bar(x: Int, y: IO^{}): C^{io} = ??? + override def baz(x: C^{}): C^{io} = ??? } } diff --git a/tests/pos-custom-args/captures/overrides.scala b/tests/pos-custom-args/captures/overrides.scala index 7e70afe7a327..ac5b9cd9ddc4 100644 --- a/tests/pos-custom-args/captures/overrides.scala +++ b/tests/pos-custom-args/captures/overrides.scala @@ -1,4 +1,4 @@ -import caps.* +import caps.cap abstract class Foo: def foo: () => Unit = () => () diff --git a/tests/pos-custom-args/captures/pairs.scala b/tests/pos-custom-args/captures/pairs.scala index 9c8ec003d28d..bc20d20ffd92 100644 --- a/tests/pos-custom-args/captures/pairs.scala +++ b/tests/pos-custom-args/captures/pairs.scala @@ -12,21 +12,21 @@ object Generic: def g(x: Cap): Unit = if d == x then () val p = Pair(f, g) val x1 = p.fst - val x1c: {c} Cap -> Unit = x1 + val x1c: Cap ->{c} Unit = x1 val y1 = p.snd - val y1c: {d} Cap -> Unit = y1 + val y1c: Cap ->{d} Unit = y1 object Monomorphic: - class Pair(x: Cap => Unit, y: {*} Cap -> Unit): - def fst: {x} Cap -> Unit = x - def snd: {y} Cap -> Unit = y + class Pair(x: Cap => Unit, y: Cap => Unit): + def fst: Cap ->{x} Unit = x + def snd: Cap ->{y} Unit = y def test(c: Cap, d: Cap) = def f(x: Cap): Unit = if c == x then () def g(x: Cap): Unit = if d == x then () val p = Pair(f, g) val x1 = p.fst - val x1c: {c} Cap -> Unit = x1 + val x1c: Cap ->{c} Unit = x1 val y1 = p.snd - val y1c: {d} Cap -> Unit = y1 + val y1c: Cap ->{d} Unit = y1 diff --git a/tests/pos-custom-args/captures/selftype-alias.scala b/tests/pos-custom-args/captures/selftype-alias.scala new file mode 100644 index 000000000000..180c7b27b146 --- /dev/null +++ b/tests/pos-custom-args/captures/selftype-alias.scala @@ -0,0 +1,8 @@ +import language.experimental.captureChecking + +type AnyIterableOnce[A] = IterableOnce[A]^ + +/** Iterator can be used only once */ +trait IterableOnce[+A]: + this: AnyIterableOnce[A] => + def iterator: Iterator[A]^{this} diff --git a/tests/pos-custom-args/captures/stack-alloc.scala b/tests/pos-custom-args/captures/stack-alloc.scala index 03b6708a3119..7013f978c281 100644 --- a/tests/pos-custom-args/captures/stack-alloc.scala +++ b/tests/pos-custom-args/captures/stack-alloc.scala @@ -5,7 +5,7 @@ class Pooled val stack = mutable.ArrayBuffer[Pooled]() var nextFree = 0 -def withFreshPooled[T](op: ({*} Pooled) => T): T = +def withFreshPooled[T](op: Pooled^ => T): T = if nextFree >= stack.size then stack.append(new Pooled) val pooled = stack(nextFree) nextFree = nextFree + 1 diff --git a/tests/pos-custom-args/captures/trickyTrailingUpArrow.scala b/tests/pos-custom-args/captures/trickyTrailingUpArrow.scala new file mode 100644 index 000000000000..71b663de5354 --- /dev/null +++ b/tests/pos-custom-args/captures/trickyTrailingUpArrow.scala @@ -0,0 +1,9 @@ +object Test: + var x = 0 + type FreshContext = String^ + x += 1 + + inline def ctx(using c: String) = c + + val y: String^ -> Unit = ??? + val z: String^ ?-> Unit = ??? diff --git a/tests/pos-custom-args/captures/try.scala b/tests/pos-custom-args/captures/try.scala index b2dcf6f11dd0..05c41be69001 100644 --- a/tests/pos-custom-args/captures/try.scala +++ b/tests/pos-custom-args/captures/try.scala @@ -2,7 +2,7 @@ import annotation.retains import language.experimental.erasedDefinitions class CT[E <: Exception] -type CanThrow[E <: Exception] = CT[E] @retains(caps.*) +type CanThrow[E <: Exception] = CT[E] @retains(caps.cap) infix type throws[R, E <: Exception] = (erased CanThrow[E]) ?-> R diff --git a/tests/pos-custom-args/captures/vars.scala b/tests/pos-custom-args/captures/vars.scala index 12721158a2bb..ccf2cd587eb1 100644 --- a/tests/pos-custom-args/captures/vars.scala +++ b/tests/pos-custom-args/captures/vars.scala @@ -5,13 +5,13 @@ def test(cap1: Cap, cap2: Cap) = var x = f val y = x val z = () => if x("") == "" then "a" else "b" - val zc: {cap1} () -> String = z + val zc: () ->{cap1} String = z val z2 = () => { x = identity } - val z2c: {cap1} () -> Unit = z2 + val z2c: () ->{cap1} Unit = z2 class Ref: - var elem: {cap1} String -> String = null + var elem: String ->{cap1} String = null val r = Ref() r.elem = f - val fc: {cap1} String -> String = r.elem + val fc: String ->{cap1} String = r.elem diff --git a/tests/pos-with-compiler-cc/dotc/ast/Trees.scala b/tests/pos-with-compiler-cc/dotc/ast/Trees.scala index aa1c06a7ca85..0b1842603316 100644 --- a/tests/pos-with-compiler-cc/dotc/ast/Trees.scala +++ b/tests/pos-with-compiler-cc/dotc/ast/Trees.scala @@ -1394,7 +1394,7 @@ object Trees { case _ => sourced - abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { self: TreeMap @retains(caps.*) => + abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { self: TreeMap @retains(caps.cap) => def transform(tree: Tree)(using Context): Tree = { inContext(transformCtx(tree)) { Stats.record(s"TreeMap.transform/$getClass") @@ -1520,7 +1520,7 @@ object Trees { } } - abstract class TreeAccumulator[X] { self: TreeAccumulator[X] @retains(caps.*) => + abstract class TreeAccumulator[X] { self: TreeAccumulator[X] @retains(caps.cap) => // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. def apply(x: X, tree: Tree)(using Context): X diff --git a/tests/pos-with-compiler-cc/dotc/ast/untpd.scala b/tests/pos-with-compiler-cc/dotc/ast/untpd.scala index b4dc6d0622c0..a6d3bc5a072c 100644 --- a/tests/pos-with-compiler-cc/dotc/ast/untpd.scala +++ b/tests/pos-with-compiler-cc/dotc/ast/untpd.scala @@ -742,7 +742,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { } abstract class UntypedTreeAccumulator[X] extends TreeAccumulator[X] { - self: UntypedTreeAccumulator[X] @retains(caps.*) => + self: UntypedTreeAccumulator[X] @retains(caps.cap) => override def foldMoreCases(x: X, tree: Tree)(using Context): X = tree match { case ModuleDef(name, impl) => this(x, impl) diff --git a/tests/pos-with-compiler-cc/dotc/cc/CaptureAnnotation.scala b/tests/pos-with-compiler-cc/dotc/cc/CaptureAnnotation.scala index 2e750865f407..67222f07efbb 100644 --- a/tests/pos-with-compiler-cc/dotc/cc/CaptureAnnotation.scala +++ b/tests/pos-with-compiler-cc/dotc/cc/CaptureAnnotation.scala @@ -51,7 +51,7 @@ case class CaptureAnnotation(refs: CaptureSet, boxed: Boolean)(cls: Symbol) exte this.refs == refs && this.boxed == boxed && this.symbol == that.symbol case _ => false - override def mapWith(tm: TypeMap @retains(caps.*))(using Context) = + override def mapWith(tm: TypeMap @retains(caps.cap))(using Context) = val elems = refs.elems.toList val elems1 = elems.mapConserve(tm) if elems1 eq elems then this diff --git a/tests/pos-with-compiler-cc/dotc/core/Annotations.scala b/tests/pos-with-compiler-cc/dotc/core/Annotations.scala index f3fee3da78ec..f307d4a36697 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Annotations.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Annotations.scala @@ -55,7 +55,7 @@ object Annotations { * be overridden. Returns EmptyAnnotation if type type map produces a range * type, since ranges cannot be types of trees. */ - def mapWith(tm: TypeMap @retains(caps.*))(using Context) = + def mapWith(tm: TypeMap @retains(caps.cap))(using Context) = val args = arguments if args.isEmpty then this else diff --git a/tests/pos-with-compiler-cc/dotc/core/Contexts.scala b/tests/pos-with-compiler-cc/dotc/core/Contexts.scala index 2ce714937f97..37fde2d7b604 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Contexts.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Contexts.scala @@ -110,7 +110,7 @@ object Contexts { inline def inDetachedContext[T](inline op: DetachedContext ?-> T)(using ctx: Context): T = op(using ctx.detach) - type Context = ContextCls @retains(caps.*) + type Context = ContextCls @retains(caps.cap) /** A context is passed basically everywhere in dotc. * This is convenient but carries the risk of captured contexts in diff --git a/tests/pos-with-compiler-cc/dotc/core/Decorators.scala b/tests/pos-with-compiler-cc/dotc/core/Decorators.scala index a4c3938a0909..f9844c6eaab6 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Decorators.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Decorators.scala @@ -84,7 +84,7 @@ object Decorators { * on lists that avoid duplication of list nodes where feasible. */ extension [T](xs: List[T]) - final def collectCC[U](pf: PartialFunction[T, U] @retains(caps.*)): List[U] = + final def collectCC[U](pf: PartialFunction[T, U] @retains(caps.cap)): List[U] = xs.collect(pf.asInstanceOf) final def mapconserve[U](f: T => U): List[U] = { @@ -230,11 +230,11 @@ object Decorators { end extension extension [T](xs: Seq[T]) - final def collectCC[U](pf: PartialFunction[T, U] @retains(caps.*)): Seq[U] = + final def collectCC[U](pf: PartialFunction[T, U] @retains(caps.cap)): Seq[U] = xs.collect(pf.asInstanceOf) - extension [A, B](f: PartialFunction[A, B] @retains(caps.*)) - def orElseCC(g: PartialFunction[A, B] @retains(caps.*)): PartialFunction[A, B] @retains(f, g) = + extension [A, B](f: PartialFunction[A, B] @retains(caps.cap)) + def orElseCC(g: PartialFunction[A, B] @retains(caps.cap)): PartialFunction[A, B] @retains(f, g) = f.orElse(g.asInstanceOf).asInstanceOf extension (text: Text) diff --git a/tests/pos-with-compiler-cc/dotc/core/GadtConstraint.scala b/tests/pos-with-compiler-cc/dotc/core/GadtConstraint.scala index 46b7e07649b8..fcf1215c604f 100644 --- a/tests/pos-with-compiler-cc/dotc/core/GadtConstraint.scala +++ b/tests/pos-with-compiler-cc/dotc/core/GadtConstraint.scala @@ -225,7 +225,7 @@ sealed trait GadtConstraint ( // ---- Private ---------------------------------------------------------- - private def externalize(tp: Type, theMap: TypeMap @retains(caps.*) | Null = null)(using Context): Type = tp match + private def externalize(tp: Type, theMap: TypeMap @retains(caps.cap) | Null = null)(using Context): Type = tp match case param: TypeParamRef => reverseMapping(param) match case sym: Symbol => sym.typeRef case null => param @@ -238,7 +238,7 @@ sealed trait GadtConstraint ( private def tvarOrError(sym: Symbol)(using Context): TypeVar = mapping(sym).ensuring(_ != null, i"not a constrainable symbol: $sym").uncheckedNN - private def containsNoInternalTypes(tp: Type, theAcc: TypeAccumulator[Boolean] @retains(caps.*) | Null = null)(using Context): Boolean = tp match { + private def containsNoInternalTypes(tp: Type, theAcc: TypeAccumulator[Boolean] @retains(caps.cap) | Null = null)(using Context): Boolean = tp match { case tpr: TypeParamRef => !reverseMapping.contains(tpr) case tv: TypeVar => !reverseMapping.contains(tv.origin) case tp => diff --git a/tests/pos-with-compiler-cc/dotc/core/Names.scala b/tests/pos-with-compiler-cc/dotc/core/Names.scala index cb68299101ad..e6ea66f4025b 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Names.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Names.scala @@ -74,10 +74,10 @@ object Names { * Stops at DerivedNames with infos of kind QualifiedInfo. * If `f` does not apply to any part, return name unchanged. */ - def replace(f: PartialFunction[Name, Name] @retains(caps.*)): ThisName + def replace(f: PartialFunction[Name, Name] @retains(caps.cap)): ThisName /** Same as replace, but does not stop at DerivedNames with infos of kind QualifiedInfo. */ - def replaceDeep(f: PartialFunction[Name, Name] @retains(caps.*)): ThisName = + def replaceDeep(f: PartialFunction[Name, Name] @retains(caps.cap)): ThisName = replace(f.orElseCC { case DerivedName(underlying, info: QualifiedInfo) => underlying.replaceDeep(f).derived(info) @@ -340,7 +340,7 @@ object Names { override def toSimpleName: SimpleName = this override final def mangle: SimpleName = encode - override def replace(f: PartialFunction[Name, Name] @retains(caps.*)): ThisName = + override def replace(f: PartialFunction[Name, Name] @retains(caps.cap)): ThisName = if (f.isDefinedAt(this)) likeSpaced(f(this)) else this override def collect[T](f: PartialFunction[Name, T]): Option[T] = f.lift(this) override def mapLast(f: SimpleName => SimpleName): SimpleName = f(this) @@ -440,7 +440,7 @@ object Names { override def mangled: TypeName = toTermName.mangled.toTypeName override def mangledString: String = toTermName.mangledString - override def replace(f: PartialFunction[Name, Name] @retains(caps.*)): ThisName = toTermName.replace(f).toTypeName + override def replace(f: PartialFunction[Name, Name] @retains(caps.cap)): ThisName = toTermName.replace(f).toTypeName override def collect[T](f: PartialFunction[Name, T]): Option[T] = toTermName.collect(f) override def mapLast(f: SimpleName => SimpleName): TypeName = toTermName.mapLast(f).toTypeName override def mapParts(f: SimpleName => SimpleName): TypeName = toTermName.mapParts(f).toTypeName @@ -473,7 +473,7 @@ object Names { override def toSimpleName: SimpleName = termName(toString) override final def mangle: SimpleName = encode.toSimpleName - override def replace(f: PartialFunction[Name, Name] @retains(caps.*)): ThisName = + override def replace(f: PartialFunction[Name, Name] @retains(caps.cap)): ThisName = if (f.isDefinedAt(this)) likeSpaced(f(this)) else info match { case qual: QualifiedInfo => this diff --git a/tests/pos-with-compiler-cc/dotc/core/Substituters.scala b/tests/pos-with-compiler-cc/dotc/core/Substituters.scala index 1e86274f663e..6f7e02ec4dde 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Substituters.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Substituters.scala @@ -10,7 +10,7 @@ import annotation.retains */ object Substituters: - final def subst(tp: Type, from: BindingType, to: BindingType, theMap: SubstBindingMap @retains(caps.*) | Null)(using Context): Type = + final def subst(tp: Type, from: BindingType, to: BindingType, theMap: SubstBindingMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: BoundType => if (tp.binder eq from) tp.copyBoundType(to.asInstanceOf[tp.BT]) else tp @@ -26,7 +26,7 @@ object Substituters: .mapOver(tp) } - final def subst1(tp: Type, from: Symbol, to: Type, theMap: Subst1Map @retains(caps.*) | Null)(using Context): Type = + final def subst1(tp: Type, from: Symbol, to: Type, theMap: Subst1Map @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: NamedType => val sym = tp.symbol @@ -40,7 +40,7 @@ object Substituters: .mapOver(tp) } - final def subst2(tp: Type, from1: Symbol, to1: Type, from2: Symbol, to2: Type, theMap: Subst2Map @retains(caps.*) | Null)(using Context): Type = + final def subst2(tp: Type, from1: Symbol, to1: Type, from2: Symbol, to2: Type, theMap: Subst2Map @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: NamedType => val sym = tp.symbol @@ -55,7 +55,7 @@ object Substituters: .mapOver(tp) } - final def subst(tp: Type, from: List[Symbol], to: List[Type], theMap: SubstMap @retains(caps.*) | Null)(using Context): Type = + final def subst(tp: Type, from: List[Symbol], to: List[Type], theMap: SubstMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: NamedType => val sym = tp.symbol @@ -75,7 +75,7 @@ object Substituters: .mapOver(tp) } - final def substSym(tp: Type, from: List[Symbol], to: List[Symbol], theMap: SubstSymMap @retains(caps.*) | Null)(using Context): Type = + final def substSym(tp: Type, from: List[Symbol], to: List[Symbol], theMap: SubstSymMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: NamedType => val sym = tp.symbol @@ -106,7 +106,7 @@ object Substituters: .mapOver(tp) } - final def substThis(tp: Type, from: ClassSymbol, to: Type, theMap: SubstThisMap @retains(caps.*) | Null)(using Context): Type = + final def substThis(tp: Type, from: ClassSymbol, to: Type, theMap: SubstThisMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: ThisType => if (tp.cls eq from) to else tp @@ -120,7 +120,7 @@ object Substituters: .mapOver(tp) } - final def substRecThis(tp: Type, from: Type, to: Type, theMap: SubstRecThisMap @retains(caps.*) | Null)(using Context): Type = + final def substRecThis(tp: Type, from: Type, to: Type, theMap: SubstRecThisMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp @ RecThis(binder) => if (binder eq from) to else tp @@ -134,7 +134,7 @@ object Substituters: .mapOver(tp) } - final def substParam(tp: Type, from: ParamRef, to: Type, theMap: SubstParamMap @retains(caps.*) | Null)(using Context): Type = + final def substParam(tp: Type, from: ParamRef, to: Type, theMap: SubstParamMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: BoundType => if (tp == from) to else tp @@ -148,7 +148,7 @@ object Substituters: .mapOver(tp) } - final def substParams(tp: Type, from: BindingType, to: List[Type], theMap: SubstParamsMap @retains(caps.*) | Null)(using Context): Type = + final def substParams(tp: Type, from: BindingType, to: List[Type], theMap: SubstParamsMap @retains(caps.cap) | Null)(using Context): Type = tp match { case tp: ParamRef => if (tp.binder == from) to(tp.paramNum) else tp diff --git a/tests/pos-with-compiler-cc/dotc/core/TypeOps.scala b/tests/pos-with-compiler-cc/dotc/core/TypeOps.scala index ad71f3100817..717da533a439 100644 --- a/tests/pos-with-compiler-cc/dotc/core/TypeOps.scala +++ b/tests/pos-with-compiler-cc/dotc/core/TypeOps.scala @@ -128,7 +128,7 @@ object TypeOps: pre.isStable || !ctx.phase.isTyper /** Implementation of Types#simplified */ - def simplify(tp: Type, theMap: SimplifyMap @retains(caps.*) | Null)(using Context): Type = { + def simplify(tp: Type, theMap: SimplifyMap @retains(caps.cap) | Null)(using Context): Type = { def mapOver = (if (theMap != null) theMap else new SimplifyMap).mapOver(tp) tp match { case tp: NamedType => diff --git a/tests/pos-with-compiler-cc/dotc/core/Types.scala b/tests/pos-with-compiler-cc/dotc/core/Types.scala index f94e9ac6d645..e4b30888a5dc 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Types.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Types.scala @@ -115,7 +115,7 @@ object Types { private def testProvisional(using Context): Boolean = class ProAcc extends TypeAccumulator[Boolean]: override def apply(x: Boolean, t: Type) = x || test(t, this) - def test(t: Type, theAcc: TypeAccumulator[Boolean] @retains(caps.*) | Null): Boolean = + def test(t: Type, theAcc: TypeAccumulator[Boolean] @retains(caps.cap) | Null): Boolean = if t.mightBeProvisional then t.mightBeProvisional = t match case t: TypeRef => @@ -2158,8 +2158,8 @@ object Types { /** A trait for proto-types, used as expected types in typer */ trait ProtoType extends Type { def isMatchedBy(tp: Type, keepConstraint: Boolean = false)(using Context): Boolean - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T - def map(tm: TypeMap @retains(caps.*))(using Context): ProtoType + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T + def map(tm: TypeMap @retains(caps.cap))(using Context): ProtoType /** If this prototype captures a context, the same prototype except that the result * captures the given context `ctx`. @@ -3773,7 +3773,7 @@ object Types { val status = (x & StatusMask) max (y & StatusMask) val provisional = (x | y) & Provisional (if status == TrueDeps then status else status | provisional).toByte - def compute(status: DependencyStatus, tp: Type, theAcc: TypeAccumulator[DependencyStatus] @retains(caps.*) | Null): DependencyStatus = + def compute(status: DependencyStatus, tp: Type, theAcc: TypeAccumulator[DependencyStatus] @retains(caps.cap) | Null): DependencyStatus = def applyPrefix(tp: NamedType) = if tp.isInstanceOf[SingletonType] && tp.currentSymbol.isStatic then status // Note: a type ref with static symbol can still be dependent since the symbol might be refined in the enclosing type. See pos/15331.scala. @@ -4351,7 +4351,7 @@ object Types { private var myEvalRunId: RunId = NoRunId private var myEvalued: Type = uninitialized - def isGround(acc: TypeAccumulator[Boolean] @retains(caps.*))(using Context): Boolean = + def isGround(acc: TypeAccumulator[Boolean] @retains(caps.cap))(using Context): Boolean = if myGround == 0 then myGround = if acc.foldOver(true, this) then 1 else -1 myGround > 0 @@ -5552,7 +5552,7 @@ object Types { * BiTypeMaps should map capture references to capture references. */ trait BiTypeMap extends TypeMap: - thisMap: BiTypeMap @retains(caps.*) => + thisMap: BiTypeMap @retains(caps.cap) => /** The inverse of the type map as a function */ def inverse(tp: Type): Type @@ -6106,7 +6106,7 @@ object Types { abstract class TypeAccumulator[T](implicit protected val accCtx: Context) extends VariantTraversal with ((T, Type) => T) { - this: TypeAccumulator[T] @annotation.retains(caps.*) => + this: TypeAccumulator[T] @annotation.retains(caps.cap) => def apply(x: T, tp: Type): T diff --git a/tests/pos-with-compiler-cc/dotc/transform/TreeMapWithStages.scala b/tests/pos-with-compiler-cc/dotc/transform/TreeMapWithStages.scala index c721c838d316..9dd1000af954 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/TreeMapWithStages.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/TreeMapWithStages.scala @@ -18,7 +18,7 @@ import scala.annotation.constructorOnly * and `l == -1` is code inside a top level splice (in an inline method). * @param levels a stacked map from symbols to the levels in which they were defined */ -abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMapWithImplicits { this: {} TreeMapWithStages => +abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMapWithImplicits { this: TreeMapWithStages^{} => import tpd._ import TreeMapWithStages._ diff --git a/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala b/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala index 838cca3f6fa7..77fd2c1d6d66 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala @@ -125,8 +125,8 @@ object ProtoTypes { /** A trait for prototypes that match all types */ trait MatchAlways extends ProtoType, caps.Pure { def isMatchedBy(tp1: Type, keepConstraint: Boolean)(using Context): Boolean = true - def map(tm: TypeMap @retains(caps.*))(using Context): ProtoType = this - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T = x + def map(tm: TypeMap @retains(caps.cap))(using Context): ProtoType = this + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = x override def toString: String = getClass.toString } @@ -239,8 +239,8 @@ object ProtoTypes { override def unusableForInference(using Context): Boolean = memberProto.unusableForInference - def map(tm: TypeMap @retains(caps.*))(using Context): SelectionProto = derivedSelectionProto(name, tm(memberProto), compat) - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T = ta(x, memberProto) + def map(tm: TypeMap @retains(caps.cap))(using Context): SelectionProto = derivedSelectionProto(name, tm(memberProto), compat) + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = ta(x, memberProto) override def deepenProto(using Context): SelectionProto = derivedSelectionProto(name, memberProto.deepenProto, compat) @@ -542,10 +542,10 @@ object ProtoTypes { override def toString: String = s"FunProto(${args mkString ","} => $resultType)" - def map(tm: TypeMap @retains(caps.*))(using Context): FunProto = + def map(tm: TypeMap @retains(caps.cap))(using Context): FunProto = derivedFunProto(args, tm(resultType), typer) - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T = + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = ta(ta.foldOver(x, typedArgs().tpes), resultType) override def deepenProto(using Context): FunProto = @@ -600,9 +600,9 @@ object ProtoTypes { override def unusableForInference(using Context): Boolean = argType.unusableForInference || resType.unusableForInference - def map(tm: TypeMap @retains(caps.*))(using Context): ViewProto = derivedViewProto(tm(argType), tm(resultType)) + def map(tm: TypeMap @retains(caps.cap))(using Context): ViewProto = derivedViewProto(tm(argType), tm(resultType)) - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T = + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = ta(ta(x, argType), resultType) override def deepenProto(using Context): ViewProto = @@ -653,10 +653,10 @@ object ProtoTypes { override def unusableForInference(using Context): Boolean = targs.exists(_.tpe.unusableForInference) - def map(tm: TypeMap @retains(caps.*))(using Context): PolyProto = + def map(tm: TypeMap @retains(caps.cap))(using Context): PolyProto = derivedPolyProto(targs, tm(resultType)) - def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.*))(using Context): T = + def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = ta(ta.foldOver(x, targs.tpes), resultType) override def deepenProto(using Context): PolyProto = @@ -834,7 +834,7 @@ object ProtoTypes { /** Approximate occurrences of parameter types and uninstantiated typevars * by wildcard types. */ - private def wildApprox(tp: Type, theMap: WildApproxMap @retains(caps.*) | Null, seen: Set[TypeParamRef], internal: Set[TypeLambda])(using Context): Type = + private def wildApprox(tp: Type, theMap: WildApproxMap @retains(caps.cap) | Null, seen: Set[TypeParamRef], internal: Set[TypeLambda])(using Context): Type = tp match { case tp: NamedType => // default case, inlined for speed val isPatternBoundTypeRef = tp.isInstanceOf[TypeRef] && tp.symbol.isPatternBound diff --git a/tests/pos/boxmap-paper.scala b/tests/pos/boxmap-paper.scala index eb6e5f48d81c..7c2c005e6a61 100644 --- a/tests/pos/boxmap-paper.scala +++ b/tests/pos/boxmap-paper.scala @@ -13,25 +13,25 @@ def map[A, B](c: Cell[A])(f: A => B): Cell[B] def pureMap[A, B](c: Cell[A])(f: A -> B): Cell[B] = c[Cell[B]]((x: A) => cell(f(x))) -def lazyMap[A, B](c: Cell[A])(f: A => B): {f} () -> Cell[B] +def lazyMap[A, B](c: Cell[A])(f: A => B): () ->{f} Cell[B] = () => c[Cell[B]]((x: A) => cell(f(x))) trait IO: def print(s: String): Unit -def test(io: {*} IO) = +def test(io: IO^{cap}) = - val loggedOne: {io} () -> Int = () => { io.print("1"); 1 } + val loggedOne: () ->{io} Int = () => { io.print("1"); 1 } - val c: Cell[{io} () -> Int] - = cell[{io} () -> Int](loggedOne) + val c: Cell[() ->{io} Int] + = cell[() ->{io} Int](loggedOne) - val g = (f: {io} () -> Int) => + val g = (f: () ->{io} Int) => val x = f(); io.print(" + ") val y = f(); io.print(s" = ${x + y}") - val r = lazyMap[{io} () -> Int, Unit](c)(f => g(f)) - val r2 = lazyMap[{io} () -> Int, Unit](c)(g) + val r = lazyMap[() ->{io} Int, Unit](c)(f => g(f)) + val r2 = lazyMap[() ->{io} Int, Unit](c)(g) val r3 = lazyMap(c)(g) val _ = r() val _ = r2() diff --git a/tests/run-custom-args/captures/colltest5/CollectionStrawManCC5_1.scala b/tests/run-custom-args/captures/colltest5/CollectionStrawManCC5_1.scala index 796dc62bdf22..63aee49f8454 100644 --- a/tests/run-custom-args/captures/colltest5/CollectionStrawManCC5_1.scala +++ b/tests/run-custom-args/captures/colltest5/CollectionStrawManCC5_1.scala @@ -18,19 +18,21 @@ object CollectionStrawMan5 { /* ------------ Base Traits -------------------------------- */ + type AnyIterableOnce[A] = IterableOnce[A]^ + /** Iterator can be used only once */ trait IterableOnce[+A] { - this: {*} IterableOnce[A] => - def iterator: {this} Iterator[A] + this: AnyIterableOnce[A] => + def iterator: Iterator[A]^{this} } /** Base trait for instances that can construct a collection from an iterable */ trait FromIterable { - type C[X] <: {*} Iterable[X] - def fromIterable[B](it: {*} Iterable[B]): {it} C[B] + type C[X] <: Iterable[X]^ + def fromIterable[B](it: Iterable[B]^): C[B]^{it} } - type FromIterableOf[+CC[X] <: {*} Iterable[X]] = FromIterable { + type FromIterableOf[+CC[X] <: Iterable[X]^] = FromIterable { type C[X] <: CC[X] } @@ -42,9 +44,9 @@ object CollectionStrawMan5 { /** Base trait for generic collections */ trait Iterable[+A] extends IterableOnce[A] with IterableLike[A] { - this: {*} Iterable[A] => - type C[X] <: {*} Iterable[X] - protected def coll: {this} Iterable[A] = this + this: Iterable[A]^ => + type C[X] <: Iterable[X]^ + protected def coll: Iterable[A]^{this} = this def knownLength: Int = -1 } @@ -58,7 +60,7 @@ object CollectionStrawMan5 { trait SeqFactory extends IterableFactory { type C[X] <: Seq[X] - def fromIterable[B](it: {*} Iterable[B]): C[B] + def fromIterable[B](it: Iterable[B]^): C[B] } /** Base trait for strict collections */ @@ -78,7 +80,7 @@ object CollectionStrawMan5 { def +=(x: A): this.type def result: To - def ++=(xs: {*} IterableOnce[A]): this.type = { + def ++=(xs: IterableOnce[A]^): this.type = { xs.iterator.foreach(+=) this } @@ -103,7 +105,7 @@ object CollectionStrawMan5 { with IterablePolyTransforms[A] with IterableMonoTransforms[A] { // sound bcs of VarianceNote type Repr = C[A] @uncheckedVariance - protected[this] def fromLikeIterable(coll: {*} Iterable[A] @uncheckedVariance): {coll} Repr @uncheckedVariance = + protected[this] def fromLikeIterable(coll: Iterable[A] @uncheckedVariance ^): Repr @uncheckedVariance ^{coll} = fromIterable(coll) } @@ -112,50 +114,50 @@ object CollectionStrawMan5 { extends IterableLike[A], SeqMonoTransforms[A], SeqPolyTransforms[A]: // sound bcs of VarianceNote this: SeqLike[A] => type C[X] <: Seq[X] - def fromIterable[B](coll: {*} Iterable[B]): C[B] - override protected[this] def fromLikeIterable(coll: {*} Iterable[A] @uncheckedVariance): Repr = + def fromIterable[B](coll: Iterable[B]^): C[B] + override protected[this] def fromLikeIterable(coll: Iterable[A] @uncheckedVariance ^): Repr = fromIterable(coll) trait IterableOps[+A] extends Any { - this: {*} IterableOps[A] => - def iterator: {this} Iterator[A] + this: IterableOps[A]^ => + def iterator: Iterator[A]^{this} def foreach(f: A => Unit): Unit = iterator.foreach(f) def foldLeft[B](z: B)(op: (B, A) => B): B = iterator.foldLeft(z)(op) def foldRight[B](z: B)(op: (A, B) => B): B = iterator.foldRight(z)(op) def indexWhere(p: A => Boolean): Int = iterator.indexWhere(p) def isEmpty: Boolean = !iterator.hasNext def head: A = iterator.next() - def view: {this} View[A] = View.fromIterator(iterator) + def view: View[A]^{this} = View.fromIterator(iterator) } trait IterableMonoTransforms[+A] extends Any { - this: {*} IterableMonoTransforms[A] => + this: IterableMonoTransforms[A]^ => type Repr - protected def coll: {this} Iterable[A] - protected[this] def fromLikeIterable(coll: {*} Iterable[A] @uncheckedVariance): {coll} Repr - def filter(p: A => Boolean): {this, p} Repr = fromLikeIterable(View.Filter(coll, p)) + protected def coll: Iterable[A]^{this} + protected[this] def fromLikeIterable(coll: Iterable[A] @uncheckedVariance ^): Repr^{coll} + def filter(p: A => Boolean): Repr^{this, p} = fromLikeIterable(View.Filter(coll, p)) - def partition(p: A => Boolean): ({this, p} Repr, {this, p} Repr) = { + def partition(p: A => Boolean): (Repr^{this, p}, Repr^{this, p}) = { val pn = View.Partition(coll, p) (fromLikeIterable(pn.left), fromLikeIterable(pn.right)) } - def drop(n: Int): {this} Repr = fromLikeIterable(View.Drop(coll, n)) + def drop(n: Int): Repr^{this} = fromLikeIterable(View.Drop(coll, n)) - def to[C[X] <: Iterable[X]](fi: FromIterableOf[C]): {this} C[A @uncheckedVariance] = + def to[C[X] <: Iterable[X]](fi: FromIterableOf[C]): C[A @uncheckedVariance]^{this} = // variance seems sound because `to` could just as well have been added // as a decorator. We should investigate this further to be sure. fi.fromIterable(coll) } trait IterablePolyTransforms[+A] extends Any { - this: {*} IterablePolyTransforms[A] => + this: IterablePolyTransforms[A]^ => type C[A] - protected def coll: {this} Iterable[A] - def fromIterable[B](coll: {*} Iterable[B]): {coll} C[B] - def map[B](f: A => B): {this, f} C[B] = fromIterable(View.Map(coll, f)) - def flatMap[B](f: A => {*} IterableOnce[B]): {this, f} C[B] = fromIterable(View.FlatMap(coll, f)) - def ++[B >: A](xs: {*} IterableOnce[B]): {this, xs} C[B] = fromIterable(View.Concat(coll, xs)) - def zip[B](xs: {*} IterableOnce[B]): {this, xs} C[(A @uncheckedVariance, B)] = fromIterable(View.Zip(coll, xs)) + protected def coll: Iterable[A]^{this} + def fromIterable[B](coll: Iterable[B]^): C[B]^{coll} + def map[B](f: A => B): C[B]^{this, f} = fromIterable(View.Map(coll, f)) + def flatMap[B](f: A => IterableOnce[B]^): C[B]^{this, f} = fromIterable(View.FlatMap(coll, f)) + def ++[B >: A](xs: IterableOnce[B]^): C[B]^{this, xs} = fromIterable(View.Concat(coll, xs)) + def zip[B](xs: IterableOnce[B]^): C[(A @uncheckedVariance, B)]^{this, xs} = fromIterable(View.Zip(coll, xs)) // sound bcs of VarianceNote } @@ -167,7 +169,7 @@ object CollectionStrawMan5 { while (it.hasNext) xs = new Cons(it.next(), xs) fromLikeIterable(xs) - override protected[this] def fromLikeIterable(coll: {*} Iterable[A] @uncheckedVariance): Repr + override protected[this] def fromLikeIterable(coll: Iterable[A] @uncheckedVariance ^): Repr override def filter(p: A => Boolean): Repr = fromLikeIterable(View.Filter(coll, p)) @@ -186,11 +188,11 @@ object CollectionStrawMan5 { trait SeqPolyTransforms[+A] extends Any, IterablePolyTransforms[A]: this: SeqPolyTransforms[A] => type C[A] - override def fromIterable[B](coll: {*} Iterable[B]): C[B] + override def fromIterable[B](coll: Iterable[B]^): C[B] override def map[B](f: A => B): C[B] = fromIterable(View.Map(coll, f)) - override def flatMap[B](f: A => {*} IterableOnce[B]): C[B] = fromIterable(View.FlatMap(coll, f)) - override def ++[B >: A](xs: {*} IterableOnce[B]): C[B] = fromIterable(View.Concat(coll, xs)) - override def zip[B](xs: {*} IterableOnce[B]): C[(A @uncheckedVariance, B)] = fromIterable(View.Zip(coll, xs)) + override def flatMap[B](f: A => IterableOnce[B]^): C[B] = fromIterable(View.FlatMap(coll, f)) + override def ++[B >: A](xs: IterableOnce[B]^): C[B] = fromIterable(View.Concat(coll, xs)) + override def zip[B](xs: IterableOnce[B]^): C[(A @uncheckedVariance, B)] = fromIterable(View.Zip(coll, xs)) /* --------- Concrete collection types ------------------------------- */ @@ -206,7 +208,7 @@ object CollectionStrawMan5 { def hasNext = !current.isEmpty def next() = { val r = current.head; current = current.tail; r } } - def fromIterable[B](c: {*} Iterable[B]): List[B] = List.fromIterable(c) + def fromIterable[B](c: Iterable[B]^): List[B] = List.fromIterable(c) def apply(i: Int): A = { require(!isEmpty) if (i == 0) head else tail.apply(i - 1) @@ -217,7 +219,7 @@ object CollectionStrawMan5 { def ++:[B >: A](prefix: List[B]): List[B] = if (prefix.isEmpty) this else Cons(prefix.head, prefix.tail ++: this) - override def ++[B >: A](xs: {*} IterableOnce[B]): List[B] = xs match { + override def ++[B >: A](xs: IterableOnce[B]^): List[B] = xs match { case xs: List[B] => this ++: xs case _ => fromIterable(View.Concat(this, xs)) } @@ -240,7 +242,7 @@ object CollectionStrawMan5 { object List extends SeqFactory { type C[X] = List[X] - def fromIterable[B](coll: {*} Iterable[B]): List[B] = coll match { + def fromIterable[B](coll: Iterable[B]^): List[B] = coll match { case coll: List[B] => coll case _ => ListBuffer.fromIterable(coll).result } @@ -252,7 +254,7 @@ object CollectionStrawMan5 { private var first, last: List[A] = Nil private var aliased = false def iterator = first.iterator - def fromIterable[B](coll: {*} Iterable[B]): ListBuffer[B] = ListBuffer.fromIterable(coll) + def fromIterable[B](coll: Iterable[B]^): ListBuffer[B] = ListBuffer.fromIterable(coll) def apply(i: Int) = first.apply(i) def length = first.length @@ -286,7 +288,7 @@ object CollectionStrawMan5 { object ListBuffer extends SeqFactory { type C[X] = ListBuffer[X] - def fromIterable[B](coll: {*} Iterable[B]): ListBuffer[B] = new ListBuffer[B] ++= coll + def fromIterable[B](coll: Iterable[B]^): ListBuffer[B] = new ListBuffer[B] ++= coll } /** Concrete collection type: ArrayBuffer */ @@ -303,7 +305,7 @@ object CollectionStrawMan5 { override def knownLength = length override def view = new ArrayBufferView(elems, start, end) def iterator = view.iterator - def fromIterable[B](it: {*} Iterable[B]): ArrayBuffer[B] = + def fromIterable[B](it: Iterable[B]^): ArrayBuffer[B] = ArrayBuffer.fromIterable(it) def +=(elem: A): this.type = { if (end == elems.length) { @@ -324,7 +326,7 @@ object CollectionStrawMan5 { } def result = this def trimStart(n: Int): Unit = start += (n max 0) - override def ++[B >: A](xs: {*} IterableOnce[B]): ArrayBuffer[B] = xs match { + override def ++[B >: A](xs: IterableOnce[B]^): ArrayBuffer[B] = xs match { case xs: ArrayBuffer[B] @unchecked => val elems = new Array[AnyRef](length + xs.length) Array.copy(this.elems, this.start, elems, 0, this.length) @@ -338,7 +340,7 @@ object CollectionStrawMan5 { object ArrayBuffer extends SeqFactory { type C[X] = ArrayBuffer[X] - def fromIterable[B](coll: {*} Iterable[B]): ArrayBuffer[B] = + def fromIterable[B](coll: Iterable[B]^): ArrayBuffer[B] = if (coll.knownLength >= 0) { val elems = new Array[AnyRef](coll.knownLength) val it = coll.iterator @@ -368,12 +370,12 @@ object CollectionStrawMan5 { type C[X] = List[X] protected def coll = new StringView(s) def iterator = coll.iterator - protected def fromLikeIterable(coll: {*} Iterable[Char]): String = { + protected def fromLikeIterable(coll: Iterable[Char]^): String = { val sb = new StringBuilder for (ch <- coll) sb.append(ch) sb.toString } - def fromIterable[B](coll: {*} Iterable[B]): List[B] = List.fromIterable(coll) + def fromIterable[B](coll: Iterable[B]^): List[B] = List.fromIterable(coll) def map(f: Char => Char): String = { val sb = new StringBuilder for (ch <- s) sb.append(f(ch)) @@ -384,7 +386,7 @@ object CollectionStrawMan5 { for (ch <- s) sb.append(f(ch)) sb.toString } - def ++(xs: {*} IterableOnce[Char]): String = { + def ++(xs: IterableOnce[Char]^): String = { val sb = new StringBuilder(s) for (ch <- xs.iterator) sb.append(ch) sb.toString @@ -402,10 +404,10 @@ object CollectionStrawMan5 { /** Concrete collection type: View */ trait View[+A] extends Iterable[A] with IterableLike[A] { - this: {*} View[A] => - type C[X] = {this} View[X] + this: View[A]^ => + type C[X] = View[X]^{this} override def view: this.type = this - override def fromIterable[B](c: {*} Iterable[B]): {this, c} View[B] = { + override def fromIterable[B](c: Iterable[B]^): View[B]^{this, c} = { c match { case c: View[B] => c case _ => View.fromIterator(c.iterator) @@ -431,8 +433,8 @@ object CollectionStrawMan5 { } object View { - def fromIterator[A](it: => {*} Iterator[A]): {it} View[A] = new View[A]: - def iterator: {this} Iterator[A] = it + def fromIterator[A](it: => Iterator[A]^): View[A]^{it} = new View[A]: + def iterator: Iterator[A]^{this} = it case object Empty extends View[Nothing] { def iterator: Iterator[Nothing] = Iterator.empty @@ -444,43 +446,43 @@ object CollectionStrawMan5 { override def knownLength = xs.length } - case class Filter[A](val underlying: {*} Iterable[A], p: A => Boolean) extends View[A] { - this: {underlying, p} Filter[A] => - def iterator: {this} Iterator[A] = underlying.iterator.filter(p) + case class Filter[A](val underlying: Iterable[A]^, p: A => Boolean) extends View[A] { + this: Filter[A]^{underlying, p} => + def iterator: Iterator[A]^{this} = underlying.iterator.filter(p) } - case class Partition[A](val underlying: {*} Iterable[A], p: A => Boolean) { - self: {underlying, p} Partition[A] => + case class Partition[A](val underlying: Iterable[A]^, p: A => Boolean) { + self: Partition[A]^{underlying, p} => class Partitioned(expected: Boolean) extends View[A]: - this: {self} Partitioned => - def iterator: {this} Iterator[A] = + this: Partitioned^{self} => + def iterator: Iterator[A]^{this} = underlying.iterator.filter((x: A) => p(x) == expected) - val left: {self} Partitioned = Partitioned(true) - val right: {self} Partitioned = Partitioned(false) + val left: Partitioned^{self} = Partitioned(true) + val right: Partitioned^{self} = Partitioned(false) } - case class Drop[A](underlying: {*} Iterable[A], n: Int) extends View[A] { - this: {underlying} Drop[A] => - def iterator: {this} Iterator[A] = underlying.iterator.drop(n) + case class Drop[A](underlying: Iterable[A]^, n: Int) extends View[A] { + this: Drop[A]^{underlying} => + def iterator: Iterator[A]^{this} = underlying.iterator.drop(n) override def knownLength = if (underlying.knownLength >= 0) underlying.knownLength - n max 0 else -1 } - case class Map[A, B](underlying: {*} Iterable[A], f: A => B) extends View[B] { - this: {underlying, f} Map[A, B] => - def iterator: {this} Iterator[B] = underlying.iterator.map(f) + case class Map[A, B](underlying: Iterable[A]^, f: A => B) extends View[B] { + this: Map[A, B]^{underlying, f} => + def iterator: Iterator[B]^{this} = underlying.iterator.map(f) override def knownLength = underlying.knownLength } - case class FlatMap[A, B](underlying: {*} Iterable[A], f: A => {*} IterableOnce[B]) extends View[B] { - this: {underlying, f} FlatMap[A, B] => - def iterator: {this} Iterator[B] = underlying.iterator.flatMap(f) + case class FlatMap[A, B](underlying: Iterable[A]^, f: A => IterableOnce[B]^) extends View[B] { + this: FlatMap[A, B]^{underlying, f} => + def iterator: Iterator[B]^{this} = underlying.iterator.flatMap(f) } - case class Concat[A](underlying: {*} Iterable[A], other: {*} IterableOnce[A]) extends View[A] { - this: {underlying, other} Concat[A] => - def iterator: {this} Iterator[A] = underlying.iterator ++ other + case class Concat[A](underlying: Iterable[A]^, other: IterableOnce[A]^) extends View[A] { + this: Concat[A]^{underlying, other} => + def iterator: Iterator[A]^{this} = underlying.iterator ++ other override def knownLength = other match { case other: Iterable[_] if underlying.knownLength >= 0 && other.knownLength >= 0 => underlying.knownLength + other.knownLength @@ -489,9 +491,9 @@ object CollectionStrawMan5 { } } - case class Zip[A, B](underlying: {*} Iterable[A], other: {*} IterableOnce[B]) extends View[(A, B)] { - this: {underlying, other} Zip[A, B] => - def iterator: {this} Iterator[(A, B)] = underlying.iterator.zip(other) + case class Zip[A, B](underlying: Iterable[A]^, other: IterableOnce[B]^) extends View[(A, B)] { + this: Zip[A, B]^{underlying, other} => + def iterator: Iterator[(A, B)]^{this} = underlying.iterator.zip(other) override def knownLength = other match { case other: Iterable[_] if underlying.knownLength >= 0 && other.knownLength >= 0 => underlying.knownLength min other.knownLength @@ -504,7 +506,7 @@ object CollectionStrawMan5 { /* ---------- Iterators ---------------------------------------------------*/ /** A core Iterator class */ - trait Iterator[+A] extends IterableOnce[A] { self: {*} Iterator[A] => + trait Iterator[+A] extends IterableOnce[A] { self: Iterator[A]^ => def hasNext: Boolean def next(): A def iterator: this.type = this @@ -522,7 +524,7 @@ object CollectionStrawMan5 { } -1 } - def filter(p: A => Boolean): {this, p} Iterator[A] = new Iterator[A] { + def filter(p: A => Boolean): Iterator[A]^{this, p} = new Iterator[A] { private var hd: A = compiletime.uninitialized private var hdDefined: Boolean = false @@ -544,13 +546,13 @@ object CollectionStrawMan5 { else Iterator.empty.next() } - def map[B](f: A => B): {this, f} Iterator[B] = new Iterator[B] { + def map[B](f: A => B): Iterator[B]^{this, f} = new Iterator[B] { def hasNext = self.hasNext def next() = f(self.next()) } - def flatMap[B](f: A => {*} IterableOnce[B]): {this, f} Iterator[B] = new Iterator[B] { - private var myCurrent: {this} Iterator[B] = Iterator.empty + def flatMap[B](f: A => IterableOnce[B]^): Iterator[B]^{this, f} = new Iterator[B] { + private var myCurrent: Iterator[B]^{this} = Iterator.empty private def current = { while (!myCurrent.hasNext && self.hasNext) myCurrent = f(self.next()).iterator @@ -559,8 +561,8 @@ object CollectionStrawMan5 { def hasNext = current.hasNext def next() = current.next() } - def ++[B >: A](xs: {*} IterableOnce[B]): {this, xs} Iterator[B] = new Iterator[B] { - private var myCurrent: {self, xs} Iterator[B] = self + def ++[B >: A](xs: IterableOnce[B]^): Iterator[B]^{this, xs} = new Iterator[B] { + private var myCurrent: Iterator[B]^{self, xs} = self private var first = true private def current = { if (!myCurrent.hasNext && first) { @@ -572,7 +574,7 @@ object CollectionStrawMan5 { def hasNext = current.hasNext def next() = current.next() } - def drop(n: Int): {this} Iterator[A] = { + def drop(n: Int): Iterator[A]^{this} = { var i = 0 while (i < n && hasNext) { next() @@ -580,7 +582,7 @@ object CollectionStrawMan5 { } this } - def zip[B](that: {*} IterableOnce[B]): {this, that} Iterator[(A, B)] = new Iterator[(A, B)] { + def zip[B](that: IterableOnce[B]^): Iterator[(A, B)]^{this, that} = new Iterator[(A, B)] { val thatIterator = that.iterator def hasNext = self.hasNext && thatIterator.hasNext def next() = (self.next(), thatIterator.next()) diff --git a/tests/run-custom-args/captures/colltest5/Test_2.scala b/tests/run-custom-args/captures/colltest5/Test_2.scala index 8c070439db80..fbb22039c327 100644 --- a/tests/run-custom-args/captures/colltest5/Test_2.scala +++ b/tests/run-custom-args/captures/colltest5/Test_2.scala @@ -5,7 +5,7 @@ object Test { import colltest5.strawman.collections.* import CollectionStrawMan5.* - def seqOps(xs: Seq[Int]) = { // try with {*} Seq[Int] + def seqOps(xs: Seq[Int]) = { // try with Seq[Int]^{cap} val strPlusInt: (String, Int) => String = _ + _ val intPlusStr: (Int, String) => String = _ + _ val isEven: Int => Boolean = _ % 2 == 0 @@ -61,7 +61,7 @@ object Test { println(xs16) } - def viewOps(xs: {*} View[Int]) = { + def viewOps(xs: View[Int]^{cap}) = { val strPlusInt: (String, Int) => String = _ + _ val intPlusStr: (Int, String) => String = _ + _ val isEven: Int => Boolean = _ % 2 == 0 @@ -78,27 +78,27 @@ object Test { val x5 = xs.to(List) val y5: List[Int] = x5 val (xs6, xs7) = xs.partition(isEven) - val ys6: {xs6, isEven} View[Int] = xs6 - val ys7: {xs7, isEven} View[Int] = xs7 + val ys6: View[Int]^{xs6, isEven} = xs6 + val ys7: View[Int]^{xs7, isEven} = xs7 val (xs6a, xs7a) = xs.partition(_ % 2 == 0) - val ys6a: {xs6} View[Int] = xs6 - val ys7a: {xs7} View[Int] = xs7 + val ys6a: View[Int]^{xs6} = xs6 + val ys7a: View[Int]^{xs7} = xs7 val xs8 = xs.drop(2) - val ys8: {xs8} View[Int] = xs8 + val ys8: View[Int]^{xs8} = xs8 val xs9 = xs.map(isNonNeg) - val ys9: {xs9} View[Boolean] = xs9 + val ys9: View[Boolean]^{xs9} = xs9 val xs10 = xs.flatMap(flips) - val ys10: {xs10} View[Int] = xs10 + val ys10: View[Int]^{xs10} = xs10 val xs11 = xs ++ xs - val ys11: {xs11} View[Int] = xs11 + val ys11: View[Int]^{xs11} = xs11 val xs12 = xs ++ Nil - val ys12: {xs12} View[Int] = xs12 + val ys12: View[Int]^{xs12} = xs12 val xs13 = Nil ++ xs val ys13: List[Int] = xs13 val xs14 = xs ++ Cons("a", Nil) - val ys14: {xs14} View[Any] = xs14 + val ys14: View[Any]^{xs14} = xs14 val xs15 = xs.zip(xs9) - val ys15: {xs15} View[(Int, Boolean)] = xs15 + val ys15: View[(Int, Boolean)]^{xs15} = xs15 println("-------") println(x1) println(x2) diff --git a/tests/run-custom-args/captures/minicheck.scala b/tests/run-custom-args/captures/minicheck.scala index 344e021493e5..bdc591580482 100644 --- a/tests/run-custom-args/captures/minicheck.scala +++ b/tests/run-custom-args/captures/minicheck.scala @@ -83,7 +83,7 @@ abstract class Ctx: def run: Run def detached: DetachedContext -type Context = {*} Ctx +type Context = Ctx^ abstract class DetachedContext extends Ctx: def outer: DetachedContext @@ -110,9 +110,9 @@ object NoContext extends FreshCtx(-1): owner = NoSymbol scope = EmptyScope -type FreshContext = {*} FreshCtx +type FreshContext = FreshCtx^ -inline def ctx(using c: Context): {c} Ctx = c +inline def ctx(using c: Context): Ctx^{c} = c // !cc! it does not work if ctxStack is an Array[FreshContext] instead. var ctxStack = Array.tabulate(16)(new FreshCtx(_))