diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 362b7815db6a..b804a11a6ede 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -457,7 +457,6 @@ object StdNames { val eval: N = "eval" val eqlAny: N = "eqlAny" val ex: N = "ex" - val extended: N = "extended" val extension: N = "extension" val experimental: N = "experimental" val f: N = "f" diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index e9e20394a86d..2c848aa5728e 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -913,7 +913,10 @@ object Parsers { lookahead.nextToken() if lookahead.token == IDENTIFIER then lookahead.nextToken() - lookahead.token == COLON + if lookahead.token == COLON then + lookahead.nextToken() + !lookahead.isAfterLineEnd + else false else false else false @@ -943,7 +946,10 @@ object Parsers { lookahead.nextToken() while lookahead.token == LPAREN || lookahead.token == LBRACKET do lookahead.skipParens() - lookahead.token == COLON || lookahead.token == SUBTYPE + if lookahead.token == COLON then + lookahead.nextToken() + !lookahead.isAfterLineEnd + else lookahead.token == SUBTYPE def followingIsExtension() = val lookahead = in.LookaheadScanner() @@ -1304,7 +1310,12 @@ object Parsers { } def possibleTemplateStart(isNew: Boolean = false): Unit = - if in.token == WITH then + in.observeColonEOL() + if in.token == COLONEOL then + in.nextToken() + if in.token != INDENT then + syntaxError(i"indented definitions expected") + else if in.token == WITH then in.nextToken() if in.token != LBRACE && in.token != INDENT then syntaxError(i"indented definitions or `{` expected") @@ -1458,7 +1469,7 @@ object Parsers { def infixTypeRest(t: Tree): Tree = infixOps(t, canStartTypeTokens, refinedType, isType = true, isOperator = !isPostfixStar) - /** RefinedType ::= WithType {[nl | `with'] Refinement} + /** RefinedType ::= WithType {[nl] Refinement} */ val refinedType: () => Tree = () => refinedTypeRest(withType()) @@ -2082,7 +2093,8 @@ object Parsers { } else simpleExpr() - /** SimpleExpr ::= ‘new’ (ConstrApp [[‘with’] TemplateBody] | TemplateBody) + /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody] + * | ‘new’ TemplateBody * | BlockExpr * | ‘$’ ‘{’ Block ‘}’ * | Quoted @@ -2177,7 +2189,7 @@ object Parsers { } } - /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [[‘with’] TemplateBody] + /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody] * | ‘new’ TemplateBody */ def newExpr(): Tree = @@ -3352,7 +3364,7 @@ object Parsers { syntaxError(s"Only access modifiers are allowed on enum $where") mods1 - /** EnumDef ::= id ClassConstr InheritClauses [‘with’] EnumBody + /** EnumDef ::= id ClassConstr InheritClauses EnumBody */ def enumDef(start: Offset, mods: Modifiers): TypeDef = atSpan(start, nameStart) { val mods1 = checkAccessOnly(mods, "definitions") @@ -3415,8 +3427,7 @@ object Parsers { } /** GivenDef ::= [GivenSig (‘:’ | <:)] {FunArgTypes ‘=>’} AnnotType ‘=’ Expr - * | [GivenSig ‘:’] {FunArgTypes ‘=>’} ConstrApps [[‘with’] TemplateBody] - * | [id ‘:’] ExtParamClause {GivenParamClause} ‘extended’ ‘with’ ExtMethods + * | [GivenSig ‘:’] {FunArgTypes ‘=>’} ConstrApps [TemplateBody] * GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} * ExtParamClause ::= [DefTypeParamClause] DefParamClause * ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’ @@ -3458,83 +3469,68 @@ object Parsers { if in.token == LPAREN && followingIsParamOrGivenType() then paramClauses() // todo: ONLY admit a single paramClause else Nil - val isExtension = isIdent(nme.extended) def checkAllGivens(vparamss: List[List[ValDef]], what: String) = vparamss.foreach(_.foreach(vparam => if !vparam.mods.is(Given) then syntaxError(em"$what must be `given`", vparam.span))) - if isExtension then - if !name.isEmpty && !hasLabel then - syntaxError(em"name $name of extension clause must be followed by `:`", nameStart) - vparamss match - case (vparam :: Nil) :: vparamss1 if !vparam.mods.is(Given) => - checkAllGivens(vparamss1, "follow-on parameter in extension clause") - case _ => - syntaxError("extension clause must start with a single regular parameter", paramsStart) - in.nextToken() - accept(WITH) - val (self, stats) = templateBody() - stats.foreach(checkExtensionMethod(tparams, _)) - ModuleDef(name, Template(makeConstructor(tparams, vparamss), Nil, Nil, self, stats)) - else - def makeGiven(params: List[ValDef]): List[ValDef] = - params.map(param => param.withMods(param.mods | Given)) - def conditionalParents(): List[Tree] = - accept(ARROW) - if in.token == LPAREN && followingIsParam() then - vparamss = vparamss :+ makeGiven(paramClause(vparamss.flatten.length)) - conditionalParents() - else - val constrs = constrApps(commaOK = true, templateCanFollow = true) - if in.token == ARROW && constrs.forall(_.isType) then - vparamss = vparamss - :+ typesToGivenParams(constrs, ofClass = false, vparamss.flatten.length) - conditionalParents() - else constrs - - val isConditional = - in.token == ARROW - && vparamss.length == 1 - && (hasLabel || name.isEmpty && tparams.isEmpty) - if !isConditional then checkAllGivens(vparamss, "parameter of given instance") - val parents = - if in.token == SUBTYPE && !hasLabel then - if !mods.is(Inline) then - syntaxError("`<:` is only allowed for given with `inline` modifier") - in.nextToken() - TypeBoundsTree(EmptyTree, annotType()) :: Nil - else if isConditional then - vparamss = vparamss.map(makeGiven) + def makeGiven(params: List[ValDef]): List[ValDef] = + params.map(param => param.withMods(param.mods | Given)) + def conditionalParents(): List[Tree] = + accept(ARROW) + if in.token == LPAREN && followingIsParam() then + vparamss = vparamss :+ makeGiven(paramClause(vparamss.flatten.length)) + conditionalParents() + else + val constrs = constrApps(commaOK = true, templateCanFollow = true) + if in.token == ARROW && constrs.forall(_.isType) then + vparamss = vparamss + :+ typesToGivenParams(constrs, ofClass = false, vparamss.flatten.length) conditionalParents() - else - if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then - accept(COLON) - val constrs = constrApps(commaOK = true, templateCanFollow = true) - if in.token == ARROW && vparamss.isEmpty && constrs.forall(_.isType) then - vparamss = typesToGivenParams(constrs, ofClass = false, 0) :: Nil - conditionalParents() - else - constrs - - if in.token == EQUALS && parents.length == 1 && parents.head.isType then + else constrs + + val isConditional = + in.token == ARROW + && vparamss.length == 1 + && (hasLabel || name.isEmpty && tparams.isEmpty) + if !isConditional then checkAllGivens(vparamss, "parameter of given instance") + val parents = + if in.token == SUBTYPE && !hasLabel then + if !mods.is(Inline) then + syntaxError("`<:` is only allowed for given with `inline` modifier") in.nextToken() - mods1 |= Final - DefDef(name, tparams, vparamss, parents.head, subExpr()) + TypeBoundsTree(EmptyTree, annotType()) :: Nil + else if isConditional then + vparamss = vparamss.map(makeGiven) + conditionalParents() else - parents match - case TypeBoundsTree(_, _) :: _ => syntaxError("`=` expected") - case _ => - possibleTemplateStart() - val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal)) - val vparamss1 = vparamss.map(_.map(vparam => - vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal))) - val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil) - if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ) - else TypeDef(name.toTypeName, templ) + if !hasLabel && !(name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then + accept(COLON) + val constrs = constrApps(commaOK = true, templateCanFollow = true) + if in.token == ARROW && vparamss.isEmpty && constrs.forall(_.isType) then + vparamss = typesToGivenParams(constrs, ofClass = false, 0) :: Nil + conditionalParents() + else + constrs + + if in.token == EQUALS && parents.length == 1 && parents.head.isType then + in.nextToken() + mods1 |= Final + DefDef(name, tparams, vparamss, parents.head, subExpr()) + else + parents match + case TypeBoundsTree(_, _) :: _ => syntaxError("`=` expected") + case _ => + possibleTemplateStart() + val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal)) + val vparamss1 = vparamss.map(_.map(vparam => + vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal))) + val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil) + if tparams.isEmpty && vparamss.isEmpty then ModuleDef(name, templ) + else TypeDef(name.toTypeName, templ) } finalizeDef(gdef, mods1, start) } - /** ExtensionDef ::= [id] ‘of’ ExtParamClause {GivenParamClause} ‘with’ ExtMethods + /** ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods */ def extensionDef(start: Offset, mods: Modifiers): ModuleDef = in.nextToken() @@ -3580,7 +3576,7 @@ object Parsers { else Nil t :: ts - /** Template ::= InheritClauses [[‘with’] TemplateBody] + /** Template ::= InheritClauses [TemplateBody] * InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] */ def template(constr: DefDef, isEnum: Boolean = false): Template = { @@ -3650,7 +3646,7 @@ object Parsers { case x: RefTree => atSpan(start, pointOffset(pkg))(PackageDef(x, stats)) } - /** Packaging ::= package QualId [nl | `with'] `{' TopStatSeq `}' + /** Packaging ::= package QualId [nl] `{' TopStatSeq `}' */ def packaging(start: Int): Tree = { val pkg = qualId() diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index a3d49fa09322..58deda8268dc 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -550,6 +550,13 @@ object Scanners { |Previous indent : $lastWidth |Latest indent : $nextWidth""" + def observeColonEOL(): Unit = + if token == COLON then + lookahead() + val atEOL = isAfterLineEnd + reset() + if atEOL then token = COLONEOL + def observeIndented(): Unit = if indentSyntax && isNewLine then val nextWidth = indentWidth(next.offset) @@ -575,19 +582,21 @@ object Scanners { insert(OUTDENT, offset) case _ => + def lookahead() = { + prev.copyFrom(this) + lastOffset = lastCharOffset + fetchToken() + } + + def reset() = { + next.copyFrom(this) + this.copyFrom(prev) + } + /** - Join CASE + CLASS => CASECLASS, CASE + OBJECT => CASEOBJECT, SEMI + ELSE => ELSE, COLON + => COLONEOL * - Insert missing OUTDENTs at EOF */ def postProcessToken(): Unit = { - def lookahead() = { - prev.copyFrom(this) - lastOffset = lastCharOffset - fetchToken() - } - def reset() = { - next.copyFrom(this) - this.copyFrom(prev) - } def fuse(tok: Int) = { token = tok offset = prev.offset @@ -611,10 +620,7 @@ object Scanners { /* skip the trailing comma */ } else reset() case COLON => - lookahead() - val atEOL = isAfterLineEnd - reset() - if (colonSyntax && atEOL) token = COLONEOL + if colonSyntax then observeColonEOL() case EOF | RBRACE => currentRegion match { case r: Indented if !r.isOutermost => diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index e688e554584b..3f6470833a08 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -149,7 +149,7 @@ FunArgTypes ::= InfixType TypedFunParam ::= id ‘:’ Type MatchType ::= InfixType `match` ‘{’ TypeCaseClauses ‘}’ InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2) -RefinedType ::= WithType {[nl | ‘with’] Refinement} RefinedTypeTree(t, ds) +RefinedType ::= WithType {[nl] Refinement} RefinedTypeTree(t, ds) WithType ::= AnnotType {‘with’ AnnotType} (deprecated) AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleType TypeArgs AppliedTypeTree(t, args) @@ -214,7 +214,7 @@ SimpleExpr ::= Path | ‘$’ ‘{’ Block ‘}’ | Quoted | quoteId // only inside splices - | ‘new’ ConstrApp {‘with’ ConstrApp} [[‘with’] TemplateBody] New(constr | templ) + | ‘new’ ConstrApp {‘with’ ConstrApp} [TemplateBody] New(constr | templ) | ‘new’ TemplateBody | ‘(’ ExprsInParens ‘)’ Parens(exprs) | SimpleExpr ‘.’ id Select(expr, id) @@ -383,16 +383,16 @@ ClassDef ::= id ClassConstr [Template] ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses with DefDef(_, , Nil, vparamss, EmptyTree, EmptyTree) as first stat ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor -EnumDef ::= id ClassConstr InheritClauses [‘with’] EnumBody EnumDef(mods, name, tparams, template) +EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template) GivenDef ::= [GivenSig (‘:’ | <:)] {FunArgTypes ‘=>’} AnnotType ‘=’ Expr | [GivenSig ‘:’] {FunArgTypes ‘=>’} - ConstrApps [[‘with’] TemplateBody] + ConstrApps [TemplateBody] GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} -ExtensionDef ::= [id] ‘of’ ExtParamClause {GivenParamClause} ExtMethods +ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’ ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ -Template ::= InheritClauses [[‘with’] TemplateBody] Template(constr, parents, self, stats) +Template ::= InheritClauses [TemplateBody] Template(constr, parents, self, stats) InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp} ConstrApp ::= AnnotType {ParArgumentExprs} Apply(tp, args) @@ -410,7 +410,7 @@ TemplateStat ::= Import SelfType ::= id [‘:’ InfixType] ‘=>’ ValDef(_, name, tpt, _) | ‘this’ ‘:’ InfixType ‘=>’ -EnumBody ::= [nl | ‘with’] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’ +EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’ EnumStat ::= TemplateStat | {Annotation [nl]} {Modifier} EnumCase EnumCase ::= ‘case’ (id ClassConstr [‘extends’ ConstrApps]] | ids) @@ -422,7 +422,7 @@ TopStat ::= Import | Packaging | PackageObject | -Packaging ::= ‘package’ QualId [nl | ‘with’] ‘{’ TopStatSeq ‘}’ Package(qid, stats) +Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ Package(qid, stats) PackageObject ::= ‘package’ ‘object’ ObjectDef object with package in mods. CompilationUnit ::= {‘package’ QualId semi} TopStatSeq Package(qid, stats) diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index 1390fadd2559..c24aa1cf81df 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -20,7 +20,7 @@ object Logarithms { } // Extension methods define opaque types' public APIs - given logarithmOps: (x: Logarithm) extended with { + extension logarithmOps on (x: Logarithm) { def toDouble: Double = math.exp(x) def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y)) def * (y: Logarithm): Logarithm = x + y diff --git a/tests/neg-custom-args/explicit-nulls/byname-nullables.scala b/tests/neg-custom-args/explicit-nulls/byname-nullables.scala index ada838b269f6..4da2659bbde6 100644 --- a/tests/neg-custom-args/explicit-nulls/byname-nullables.scala +++ b/tests/neg-custom-args/explicit-nulls/byname-nullables.scala @@ -1,4 +1,4 @@ -object Test1 with +object Test1: def f(x: String) = x ++ x @@ -9,7 +9,7 @@ object Test1 with else x -object Test2 with +object Test2: def f(x: => String) = x ++ x @@ -19,7 +19,7 @@ object Test2 with if x != null then f(x) // error: f is call-by-name else x -object Test3 with +object Test3: def f(x: String, y: String) = x @@ -31,7 +31,7 @@ object Test3 with if x != null then f(x, 1) // OK: not-null check successfully dropped else x -object Test4 with +object Test4: def f(x: String, y: String) = x @@ -43,7 +43,7 @@ object Test4 with if x != null then f(identity(x), 1) // error: dropping not null check fails typing else x -object Test5 with +object Test5: import compiletime.byName def f(x: String, y: String) = x @@ -56,7 +56,7 @@ object Test5 with if x != null then f(byName(identity(x)), 1) // OK, byName avoids the flow typing else x -object Test6 with +object Test6: def f(x: String, y: String) = x @@ -68,7 +68,7 @@ object Test6 with if x != null then f(x, 1) // error: dropping not null check typechecks OK, but gives incompatible result type else x -object Test7 with +object Test7: import compiletime.byName def f(x: String, y: String) = x diff --git a/tests/neg-custom-args/explicit-nulls/byname-nullables1.scala b/tests/neg-custom-args/explicit-nulls/byname-nullables1.scala index eb28a5af96c0..a1c1924c545e 100644 --- a/tests/neg-custom-args/explicit-nulls/byname-nullables1.scala +++ b/tests/neg-custom-args/explicit-nulls/byname-nullables1.scala @@ -1,7 +1,7 @@ def f(op: => Boolean): Unit = () def f(op: Int): Unit = () -class C with +class C: var fld: String | Null = null def test() = diff --git a/tests/neg/case-semi.scala b/tests/neg/case-semi.scala index d05919805fa6..b7dfe0a7e524 100644 --- a/tests/neg/case-semi.scala +++ b/tests/neg/case-semi.scala @@ -1,4 +1,4 @@ -object Test with +object Test: type X = Int val x: X = 1 diff --git a/tests/neg/endmarkers1.scala b/tests/neg/endmarkers1.scala index ad670862bf3f..9de2f9746522 100644 --- a/tests/neg/endmarkers1.scala +++ b/tests/neg/endmarkers1.scala @@ -4,7 +4,7 @@ def f7[T](x: Option[T]) = x match case None => end if // error: misaligned end marker -object Test4 with +object Test4: def f[T](x: Option[T]) = x match case Some(y) => case None => diff --git a/tests/neg/i6900.scala b/tests/neg/i6900.scala index b021af2a9d7e..c9ead6a99051 100644 --- a/tests/neg/i6900.scala +++ b/tests/neg/i6900.scala @@ -1,7 +1,7 @@ object Test2 { // Works with extension method - extension on [A](a: A) with + extension on [A](a: A): def foo[C]: C => A = _ => a // error: extension method cannot have type parameters 1.foo.foo diff --git a/tests/neg/i7526.scala b/tests/neg/i7526.scala index 146e8850995d..46266ca8bde6 100644 --- a/tests/neg/i7526.scala +++ b/tests/neg/i7526.scala @@ -1,9 +1,9 @@ type Tr[-I, +O, +A] = I => (O, A) -trait NetApi with +trait NetApi: type Comp -trait NetDB extends NetApi with +trait NetDB extends NetApi: class Comp trait NetHelper extends NetApi diff --git a/tests/neg/i7529.scala b/tests/neg/i7529.scala index c42fa39c43cc..55aa2902e348 100644 --- a/tests/neg/i7529.scala +++ b/tests/neg/i7529.scala @@ -1,4 +1,4 @@ -extension fooOps on [A](a: A) with +extension fooOps on [A](a: A): @nonsense // error: not found: nonsense def foo = ??? \ No newline at end of file diff --git a/tests/neg/missing-implicit1.scala b/tests/neg/missing-implicit1.scala index 19b6728c10c1..b985e99532fa 100644 --- a/tests/neg/missing-implicit1.scala +++ b/tests/neg/missing-implicit1.scala @@ -1,4 +1,4 @@ -object testObjectInstance with +object testObjectInstance: trait Zip[F[_]] trait Traverse[F[_]] { def [A, B, G[_] : Zip](fa: F[A]) traverse(f: A => G[B]): G[F[B]] @@ -7,7 +7,7 @@ object testObjectInstance with object instances { given zipOption: Zip[Option] = ??? given traverseList: Traverse[List] = ??? - extension listExtension on [T](xs: List[T]) with + extension listExtension on [T](xs: List[T]): def second: T = xs.tail.head def [T](xs: List[T]) first: T = xs.head } diff --git a/tests/neg/missing-implicit2.scala b/tests/neg/missing-implicit2.scala index e9ad60a2d368..429fc3b81a61 100644 --- a/tests/neg/missing-implicit2.scala +++ b/tests/neg/missing-implicit2.scala @@ -1,6 +1,6 @@ trait X trait Y -object test with +object test: def f(given x: X) = ??? object instances { given y: Y = ??? diff --git a/tests/neg/name-hints.scala b/tests/neg/name-hints.scala index aca20e067e0f..cb4cb8884087 100644 --- a/tests/neg/name-hints.scala +++ b/tests/neg/name-hints.scala @@ -1,8 +1,8 @@ -object O with +object O: val abcde: Int = 0 val xy: Int = 1 -object Test with +object Test: val x1 = Int.maxvalue // error val x2 = Int.MxValue // error val x3 = Int.MaxxValue // error diff --git a/tests/pos-special/notNull.scala b/tests/pos-special/notNull.scala index bcc0154b0a80..11a506d8184d 100644 --- a/tests/pos-special/notNull.scala +++ b/tests/pos-special/notNull.scala @@ -1,4 +1,4 @@ -object Test with +object Test: def notNull[A](x: A | Null): x.type & A = assert(x != null) x.asInstanceOf // TODO: drop the .asInstanceOf when explicit nulls are implemented diff --git a/tests/pos-special/sourcepath/outer/nested/indent1.scala b/tests/pos-special/sourcepath/outer/nested/indent1.scala index 896ebedc8d4c..1c344ae12e6c 100644 --- a/tests/pos-special/sourcepath/outer/nested/indent1.scala +++ b/tests/pos-special/sourcepath/outer/nested/indent1.scala @@ -2,7 +2,7 @@ package outer package nested object indent1 - object inner with + object inner: def x: Int = 1 end inner val y: Int = 2 diff --git a/tests/pos/consume.scala b/tests/pos/consume.scala index 3f8b1fe36878..05662f6821ea 100644 --- a/tests/pos/consume.scala +++ b/tests/pos/consume.scala @@ -1,4 +1,4 @@ -object Test1 with +object Test1: def consume(xs: List[Int], limit: Int): List[Int] = xs match case x :: xs1 if limit > 0 => consume(xs1, limit - x) case _ => xs @@ -16,18 +16,18 @@ object Test2 { } } -object math3 with - trait Ord[T] with +object math3: + trait Ord[T]: def (x: T) > (t: T): Boolean = ??? def (x: T) <= (t: T): Boolean = ??? - trait Numeric[T] extends Ord[T] with + trait Numeric[T] extends Ord[T]: def (x: T) + (y: T): T = ??? def (x: T) - (y: T): T = ??? def (x: Int).numeric: T = ??? end math3 -object Test3 with +object Test3: import math3.Numeric import collection.immutable.Seq diff --git a/tests/pos/end-given.scala b/tests/pos/end-given.scala index 359d7d1b6a6b..0aacfb379c3c 100644 --- a/tests/pos/end-given.scala +++ b/tests/pos/end-given.scala @@ -1,3 +1,3 @@ -given Conversion[Int, String] with +given Conversion[Int, String]: def apply(x: Int) = "" end given diff --git a/tests/pos/end-nested.scala b/tests/pos/end-nested.scala index 96c25c2b1ea2..38e8cce6c8a9 100644 --- a/tests/pos/end-nested.scala +++ b/tests/pos/end-nested.scala @@ -3,7 +3,7 @@ def f[T](x: Option[T]) = x match case None => end f -object Test with +object Test: try List(1, 2, 3) match case x :: xs => println(x) case Nil => println("Nil") diff --git a/tests/pos/i6900.scala b/tests/pos/i6900.scala index 71a3c0e3c1ac..4c13f90e55f5 100644 --- a/tests/pos/i6900.scala +++ b/tests/pos/i6900.scala @@ -1,15 +1,15 @@ object Test1 { - trait Foo[A] with + trait Foo[A]: def foo[C]: C => A // Works with old-style conversion - implicit def i2f[A](a: A): Foo[A] = new Foo[A] with + implicit def i2f[A](a: A): Foo[A] = new Foo[A]: def foo[C]: C => A = _ => a // But not with newstyle /* - given [A]: Conversion[A, Foo[A]] with - def apply(a: A) = new Foo[A] with + given [A]: Conversion[A, Foo[A]]: + def apply(a: A) = new Foo[A]: def foo[C]: C => A = _ => a */ @@ -21,7 +21,7 @@ object Test1 { object Test2 { // Works with extension method - extension on [A, C](a: A) with + extension on [A, C](a: A): def foo: C => A = _ => a 1.foo.foo diff --git a/tests/pos/i6938.scala b/tests/pos/i6938.scala index 04ebf7cc440a..d592a0498d40 100644 --- a/tests/pos/i6938.scala +++ b/tests/pos/i6938.scala @@ -1,5 +1,5 @@ trait Foo[T] -object Foo with +object Foo: given [T]: Foo[Tuple1[T]] given [T, U]: Foo[(T, U)] given [T, U, V]: Foo[(T, U, V)] \ No newline at end of file diff --git a/tests/pos/i7401.scala b/tests/pos/i7401.scala index fea4bc18e04b..3d90bed0cfab 100644 --- a/tests/pos/i7401.scala +++ b/tests/pos/i7401.scala @@ -1,5 +1,5 @@ object Test { - given ops: (a: Int) extended with { + extension ops on (a: Int) { def foo(i: Int): Unit = () def foo: Unit = () } diff --git a/tests/pos/i7413.scala b/tests/pos/i7413.scala index cf0b9bec5eee..d546b2c8a132 100644 --- a/tests/pos/i7413.scala +++ b/tests/pos/i7413.scala @@ -12,7 +12,7 @@ trait Greeter { case class MyFixture(name: String, greeter: Greeter) -object Test1 with +object Test1: given conv: Conversion[0, Greeter] def apply(x: 0): Greeter = ??? val g: Greeter = 0 diff --git a/tests/pos/i7648.scala b/tests/pos/i7648.scala index 13dd1376c9e5..12e4a025f859 100644 --- a/tests/pos/i7648.scala +++ b/tests/pos/i7648.scala @@ -11,7 +11,7 @@ class Stream[+F[_], +A] { } } -object Test with +object Test: implicit val ioMonad: Monad[IO] = null diff --git a/tests/pos/i7700.scala b/tests/pos/i7700.scala index 2c7a1f3a1ff9..07e822e1e141 100644 --- a/tests/pos/i7700.scala +++ b/tests/pos/i7700.scala @@ -1,12 +1,12 @@ package test -trait Show[-A] with +trait Show[-A]: def show(a: A): String -object Macros with +object Macros: inline def (sc: StringContext).show(args: =>Any*): String = ??? -object Show with +object Show: def[A] (a: A) show(given S: Show[A]): String = S.show(a) export Macros.show \ No newline at end of file diff --git a/tests/pos/i7807.scala b/tests/pos/i7807.scala index 36193f26a972..df8a41ddcf8d 100644 --- a/tests/pos/i7807.scala +++ b/tests/pos/i7807.scala @@ -1,4 +1,4 @@ -object Test with +object Test: def flip: (x: 0 | 1) => x.type match { case 0 => 1 case 1 => 0 } = ??? diff --git a/tests/pos/matches.scala b/tests/pos/matches.scala index 7f42addbe491..a4c1ab4f6287 100644 --- a/tests/pos/matches.scala +++ b/tests/pos/matches.scala @@ -1,5 +1,5 @@ package matches -object Test with +object Test: 2 min 3 match case 2 => "OK" case 3 => "?" diff --git a/tests/pos/matrixOps.scala b/tests/pos/matrixOps.scala index 4d3d0891c604..28ea3c4d2013 100644 --- a/tests/pos/matrixOps.scala +++ b/tests/pos/matrixOps.scala @@ -1,9 +1,9 @@ -object Test with +object Test: type Matrix = Array[Array[Double]] type Vector = Array[Double] - extension on (m: Matrix) with + extension on (m: Matrix): def nRows = m.length def nCols = m(0).length def row(i: Int): Vector = m(i) diff --git a/tests/pos/packagings.scala b/tests/pos/packagings.scala index e78ed31b4b5d..47e1df204b34 100644 --- a/tests/pos/packagings.scala +++ b/tests/pos/packagings.scala @@ -1,10 +1,10 @@ -package foo with - package bar with - object A with +package foo: + package bar: + object A: def foo = 1 end bar end foo -package baz with - object B with +package baz: + object B: def f = foo.bar.A.foo end baz diff --git a/tests/pos/postconditions.scala b/tests/pos/postconditions.scala index bb80d9b8f6c9..d84f28f4e584 100644 --- a/tests/pos/postconditions.scala +++ b/tests/pos/postconditions.scala @@ -1,4 +1,4 @@ -object PostConditions with +object PostConditions: opaque type WrappedResult[T] = T def result[T](given r: WrappedResult[T]): T = r @@ -8,6 +8,6 @@ object PostConditions with assert(condition) x -object Test with +object Test: import PostConditions.{ensuring, result} val s = List(1, 2, 3).sum.ensuring(result == 6) diff --git a/tests/pos/reference/adts.scala b/tests/pos/reference/adts.scala index 5dc81823d9eb..8c5e1c2fd5cc 100644 --- a/tests/pos/reference/adts.scala +++ b/tests/pos/reference/adts.scala @@ -1,25 +1,25 @@ package adts -object t1 with +object t1: - enum Option[+T] with + enum Option[+T]: case Some(x: T) case None -object t2 with +object t2: - enum Option[+T] with + enum Option[+T]: case Some(x: T) extends Option[T] case None extends Option[Nothing] -enum Color(val rgb: Int) with +enum Color(val rgb: Int): case Red extends Color(0xFF0000) case Green extends Color(0x00FF00) case Blue extends Color(0x0000FF) case Mix(mix: Int) extends Color(mix) -object t3 with +object t3: - enum Option[+T] with + enum Option[+T]: case Some(x: T) extends Option[T] case None @@ -27,6 +27,6 @@ object t3 with case None => false case some => true - object Option with + object Option: def apply[T >: Null](x: T): Option[T] = if (x == null) None else Some(x) diff --git a/tests/pos/reference/auto-param-tupling.scala b/tests/pos/reference/auto-param-tupling.scala index c2dd9889fa98..c32173867fe6 100644 --- a/tests/pos/reference/auto-param-tupling.scala +++ b/tests/pos/reference/auto-param-tupling.scala @@ -1,6 +1,6 @@ package autoParamTupling -object t1 with +object t1: val xs: List[(Int, Int)] = ??? xs.map { diff --git a/tests/pos/reference/compile-time.scala b/tests/pos/reference/compile-time.scala index cc4eb57688f5..14b3d08b2a7c 100644 --- a/tests/pos/reference/compile-time.scala +++ b/tests/pos/reference/compile-time.scala @@ -1,6 +1,6 @@ package compiletime -class Test with +class Test: import scala.compiletime.{constValue, erasedValue, S} trait Nat diff --git a/tests/pos/reference/delegate-match.scala b/tests/pos/reference/delegate-match.scala index acc2f1fdcf60..511ef597bd39 100644 --- a/tests/pos/reference/delegate-match.scala +++ b/tests/pos/reference/delegate-match.scala @@ -1,6 +1,6 @@ package implicitmatch -class Test extends App with +class Test extends App: import scala.collection.immutable.{TreeSet, HashSet} import scala.compiletime.summonFrom diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 5bafa162bc20..abc125da9021 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -1,35 +1,35 @@ -class Common with +class Common: - trait Ord[T] with + trait Ord[T]: def (x: T).compareTo(y: T): Int def (x: T) < (y: T) = x.compareTo(y) < 0 def (x: T) > (y: T) = x.compareTo(y) > 0 - trait Convertible[From, To] with + trait Convertible[From, To]: def (x: From).convert: To - trait SemiGroup[T] with + trait SemiGroup[T]: def (x: T).combine(y: T): T - trait Monoid[T] extends SemiGroup[T] with + trait Monoid[T] extends SemiGroup[T]: def unit: T - trait Functor[F[_]] with + trait Functor[F[_]]: def [A, B](x: F[A]) map (f: A => B): F[B] - trait Monad[F[_]] extends Functor[F] with + trait Monad[F[_]] extends Functor[F]: def [A, B](x: F[A]) flatMap (f: A => F[B]): F[B] def [A, B](x: F[A]) map (f: A => B) = x.flatMap(f `andThen` pure) def pure[A](x: A): F[A] -object Instances extends Common with +object Instances extends Common: - given intOrd: Ord[Int] with + given intOrd: Ord[Int]: def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - given listOrd[T]: Ord[T] => Ord[List[T]] with + given listOrd[T]: Ord[T] => Ord[List[T]]: def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -39,22 +39,22 @@ object Instances extends Common with if (fst != 0) fst else xs1.compareTo(ys1) end listOrd - extension stringOps on (xs: Seq[String]) with + extension stringOps on (xs: Seq[String]): def longestStrings: Seq[String] = val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) - extension on [T](xs: List[T]) with + extension on [T](xs: List[T]): def second = xs.tail.head def third = xs.tail.tail.head - given listMonad: Monad[List] with + given listMonad: Monad[List]: def [A, B](xs: List[A]) flatMap (f: A => List[B]): List[B] = xs.flatMap(f) def pure[A](x: A): List[A] = List(x) - given readerMonad[Ctx]: Monad[[X] =>> Ctx => X] with + given readerMonad[Ctx]: Monad[[X] =>> Ctx => X]: def [A, B](r: Ctx => A) flatMap (f: A => Ctx => B): Ctx => B = ctx => f(r(ctx))(ctx) def pure[A](x: A): Ctx => A = @@ -63,7 +63,7 @@ object Instances extends Common with def maximum[T](xs: List[T])(given Ord[T]): T = xs.reduceLeft((x, y) => if (x < y) y else x) - def descending[T](given asc: Ord[T]): Ord[T] = new Ord[T] with + def descending[T](given asc: Ord[T]): Ord[T] = new Ord[T]: def (x: T).compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(given Ord[T]) = @@ -84,21 +84,21 @@ object Instances extends Common with class B val ab: (given x: A, y: B) => Int = (given a: A, b: B) => 22 - trait TastyAPI with + trait TastyAPI: type Symbol - trait SymDeco with + trait SymDeco: def (sym: Symbol).name: String def symDeco: SymDeco given SymDeco = symDeco - object TastyImpl extends TastyAPI with + object TastyImpl extends TastyAPI: type Symbol = String - val symDeco = new SymDeco with + val symDeco = new SymDeco: def (sym: Symbol).name = sym class D[T] - class C(given ctx: Context) with + class C(given ctx: Context): def f() = locally { given Context = this.ctx @@ -121,30 +121,30 @@ object Instances extends Common with class Token(str: String) - object Token with - given StringToToken : Conversion[String, Token] with + object Token: + given StringToToken : Conversion[String, Token]: def apply(str: String): Token = new Token(str) val x: Token = "if" end Instances -object PostConditions with +object PostConditions: opaque type WrappedResult[T] = T def result[T](given x: WrappedResult[T]): T = x - extension on [T](x: T) with + extension on [T](x: T): def ensuring(condition: (given WrappedResult[T]) => Boolean): T = assert(condition(given x)) x end PostConditions -object AnonymousInstances extends Common with - given Ord[Int] with +object AnonymousInstances extends Common: + given Ord[Int]: def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - given [T: Ord] : Ord[List[T]] with + given [T: Ord] : Ord[List[T]]: def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -153,18 +153,18 @@ object AnonymousInstances extends Common with val fst = x.compareTo(y) if (fst != 0) fst else xs1.compareTo(ys1) - extension on (xs: Seq[String]) with + extension on (xs: Seq[String]): def longestStrings: Seq[String] = val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) - extension on [T](xs: List[T]) with + extension on [T](xs: List[T]): def second = xs.tail.head - given [From, To]: (c: Convertible[From, To]) => Convertible[List[From], List[To]] with + given [From, To]: (c: Convertible[From, To]) => Convertible[List[From], List[To]]: def (x: List[From]).convert: List[To] = x.map(c.convert) - given Monoid[String] with + given Monoid[String]: def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" @@ -172,12 +172,12 @@ object AnonymousInstances extends Common with xs.foldLeft(summon[Monoid[T]].unit)(_.combine(_)) end AnonymousInstances -object Implicits extends Common with - implicit object IntOrd extends Ord[Int] with +object Implicits extends Common: + implicit object IntOrd extends Ord[Int]: def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 - class ListOrd[T: Ord] extends Ord[List[T]] with + class ListOrd[T: Ord] extends Ord[List[T]]: def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -188,7 +188,7 @@ object Implicits extends Common with implicit def ListOrd[T: Ord]: Ord[List[T]] = new ListOrd[T] class given_Convertible_List_List[From, To](implicit c: Convertible[From, To]) - extends Convertible[List[From], List[To]] with + extends Convertible[List[From], List[To]]: def (x: List[From]).convert: List[To] = x.map(c.convert) implicit def given_Convertible_List_List[From, To](implicit c: Convertible[From, To]) : Convertible[List[From], List[To]] = @@ -198,13 +198,13 @@ object Implicits extends Common with (implicit cmp: Ord[T]): T = xs.reduceLeft((x, y) => if (x < y) y else x) - def descending[T](implicit asc: Ord[T]): Ord[T] = new Ord[T] with + def descending[T](implicit asc: Ord[T]): Ord[T] = new Ord[T]: def (x: T).compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(implicit cmp: Ord[T]) = maximum(xs)(descending) -object Test extends App with +object Test extends App: Instances.test() import PostConditions.result import PostConditions.given @@ -212,18 +212,18 @@ object Test extends App with s.ensuring(result == 6) end Test -object Completions with +object Completions: class Future[T] class HttpResponse class StatusCode // The argument "magnet" type - enum CompletionArg with + enum CompletionArg: case Error(s: String) case Response(f: Future[HttpResponse]) case Status(code: Future[StatusCode]) - object CompletionArg with + object CompletionArg: // conversions defining the possible arguments to pass to `complete` // these always come with CompletionArg diff --git a/tests/pos/reference/extension-methods.scala b/tests/pos/reference/extension-methods.scala index d70104184d5d..2a543cf33fb3 100644 --- a/tests/pos/reference/extension-methods.scala +++ b/tests/pos/reference/extension-methods.scala @@ -1,4 +1,4 @@ -object ExtMethods with +object ExtMethods: case class Circle(x: Double, y: Double, radius: Double) @@ -48,12 +48,12 @@ object ExtMethods with } } - extension listOps on [T](xs: List[T]) with + extension listOps on [T](xs: List[T]): def second = xs.tail.head def third: T = xs.tail.tail.head - extension on [T](xs: List[T])(given Ordering[T]) with + extension on [T](xs: List[T])(given Ordering[T]): def largest(n: Int) = xs.sorted.takeRight(n) given stringOps1: AnyRef { diff --git a/tests/run/LazyLists.scala b/tests/run/LazyLists.scala index 51e648104388..c13949ce8454 100644 --- a/tests/run/LazyLists.scala +++ b/tests/run/LazyLists.scala @@ -1,7 +1,7 @@ -package xcollections with +package xcollections: import annotation.unchecked.uncheckedVariance - abstract class LazyList[+T] with + abstract class LazyList[+T]: private var myHead: T = _ private var myTail: LazyList[T] = _ @@ -40,39 +40,38 @@ package xcollections with case xs: LazyList[T] @unchecked => xs case _ => LazyList.fromIterator(xs.iterator) - object LazyList with + object LazyList: - val empty: LazyList[Nothing] = new with + val empty: LazyList[Nothing] = new: protected def force(): LazyList[Nothing] = this - object #:: with + object #:: : def unapply[T](xs: LazyList[T]): Option[(T, LazyList[T])] = if xs.isEmpty then None else Some((xs.head, xs.tail)) - def fromIterator[T](it: Iterator[T]): LazyList[T] = new with + def fromIterator[T](it: Iterator[T]): LazyList[T] = new: protected def force() = if it.hasNext then set(it.next, fromIterator (it)) else empty - given [T, U >: T](xs: LazyList[T]) extended with - - def #::(x: U): LazyList[U] = new with + extension on [T, U >: T](xs: LazyList[T]): + def #::(x: U): LazyList[U] = new: protected def force(): LazyList[U] = set(x, xs) - def ++(ys: LazyList[U]): LazyList[U] = new with + def ++(ys: LazyList[U]): LazyList[U] = new: protected def force() = if xs.isEmpty then ys.forced() else set(xs.head, xs.tail ++ ys) - given [T, U](xs: LazyList[T]) extended with - def map(f: T => U): LazyList[U] = new with + extension on [T, U](xs: LazyList[T]): + def map(f: T => U): LazyList[U] = new: protected def force() = if xs.isEmpty then empty else set(f(xs.head), xs.tail.map(f)) - def flatMap(f: T => LazyList[U]): LazyList[U] = new with + def flatMap(f: T => LazyList[U]): LazyList[U] = new: protected def force(): LazyList[U] = if xs.isEmpty then empty else f(xs.head) ++ xs.tail.flatMap(f) @@ -81,8 +80,8 @@ package xcollections with if xs.isEmpty then z else xs.tail.foldLeft(f(z, xs.head))(f) - given [T](xs: LazyList[T]) extended with - def filter(p: T => Boolean): LazyList[T] = new with + extension on [T](xs: LazyList[T]): + def filter(p: T => Boolean): LazyList[T] = new: protected def force(): LazyList[T] = if xs.isEmpty then empty else if p(xs.head) then set(xs.head, xs.tail.filter(p)) @@ -90,19 +89,20 @@ package xcollections with def take(n: Int): LazyList[T] = if n <= 0 then empty - else new with + else new: protected def force(): LazyList[T] = if xs.isEmpty then xs else set(xs.head, xs.tail.take(n - 1)) def drop(n: Int): LazyList[T] = if n <= 0 then xs - else new with + else new: protected def force(): LazyList[T] = def advance(xs: LazyList[T], n: Int): LazyList[T] = if n <= 0 || xs.isEmpty then xs else advance(xs.tail, n - 1) advance(xs, n) + end LazyList end xcollections diff --git a/tests/run/Pouring.scala b/tests/run/Pouring.scala index add83608862a..a27f2e8f5f94 100644 --- a/tests/run/Pouring.scala +++ b/tests/run/Pouring.scala @@ -1,8 +1,8 @@ -class Pouring(capacity: Vector[Int]) with +class Pouring(capacity: Vector[Int]): type Glass = Int type Content = Vector[Int] - enum Move with + enum Move: def apply(content: Content): Content = this match case Empty(g) => content.updated(g, 0) case Fill(g) => content.updated(g, capacity(g)) @@ -22,7 +22,7 @@ class Pouring(capacity: Vector[Int]) with ++ (for g <- glasses yield Move.Fill(g)) ++ (for g1 <- glasses; g2 <- glasses if g1 != g2 yield Move.Pour(g1, g2)) - class Path(history: List[Move], val endContent: Content) with + class Path(history: List[Move], val endContent: Content): def extend(move: Move) = Path(move :: history, move(endContent)) override def toString = s"${history.reverse.mkString(" ")} --> $endContent" end Path diff --git a/tests/run/Signals.scala b/tests/run/Signals.scala index e320b579ad41..0a0862815068 100644 --- a/tests/run/Signals.scala +++ b/tests/run/Signals.scala @@ -1,8 +1,8 @@ import annotation.unchecked._ -package frp with +package frp: - sealed class Signal[+T](expr: (given Signal.Caller) => T) with + sealed class Signal[+T](expr: (given Signal.Caller) => T): private var myExpr: Signal.Caller => T = _ private var myValue: T = _ private var observers: Set[Signal.Caller] = Set() @@ -26,19 +26,19 @@ package frp with observers = Set() obs.foreach(_.computeValue()) - object Signal with + object Signal: type Caller = Signal[?] - given noCaller: Caller(???) with + given noCaller: Caller(???): override def computeValue() = () end Signal - class Var[T](expr: (given Signal.Caller) => T) extends Signal[T](expr) with + class Var[T](expr: (given Signal.Caller) => T) extends Signal[T](expr): def update(expr: (given Signal.Caller) => T): Unit = changeTo(expr) end Var end frp import frp._ -class BankAccount with +class BankAccount: def balance: Signal[Int] = myBalance private var myBalance: Var[Int] = Var(0) diff --git a/tests/run/Signals1.scala b/tests/run/Signals1.scala index 0c461652af4e..978c85b3b4e8 100644 --- a/tests/run/Signals1.scala +++ b/tests/run/Signals1.scala @@ -1,13 +1,13 @@ import annotation.unchecked._ -package frp with +package frp: - trait Signal[+T] with + trait Signal[+T]: def apply()(given caller: Signal.Caller): T - object Signal with + object Signal: - abstract class AbstractSignal[+T] extends Signal[T] with + abstract class AbstractSignal[+T] extends Signal[T]: private var currentValue: T = _ private var observers: Set[Caller] = Set() @@ -29,11 +29,11 @@ package frp with end AbstractSignal def apply[T](expr: (given Caller) => T): Signal[T] = - new AbstractSignal[T] with + new AbstractSignal[T]: protected val eval = expr(given _) computeValue() - class Var[T](expr: (given Caller) => T) extends AbstractSignal[T] with + class Var[T](expr: (given Caller) => T) extends AbstractSignal[T]: protected var eval: Caller => T = expr(given _) computeValue() @@ -43,7 +43,7 @@ package frp with end Var opaque type Caller = AbstractSignal[?] - given noCaller: Caller = new AbstractSignal[Nothing] with + given noCaller: Caller = new AbstractSignal[Nothing]: override def eval = ??? override def computeValue() = () @@ -51,7 +51,7 @@ package frp with end frp import frp._ -class BankAccount with +class BankAccount: def balance: Signal[Int] = myBalance private val myBalance: Signal.Var[Int] = Signal.Var(0) diff --git a/tests/run/defunctionalized.check b/tests/run/defunctionalized.check new file mode 100644 index 000000000000..f44f5b7ef143 --- /dev/null +++ b/tests/run/defunctionalized.check @@ -0,0 +1,3 @@ +List(2, 4) +List(1, 2, 3, 5) +List(1, 2, 3) diff --git a/tests/run/defunctionalized.scala b/tests/run/defunctionalized.scala new file mode 100644 index 000000000000..aa236b8d22fb --- /dev/null +++ b/tests/run/defunctionalized.scala @@ -0,0 +1,26 @@ +enum Filter: + case IsOdd + case IsPrime + case LessThan(bound: Int) + case And(f1: Filter, f2: Filter) + + def apply(x: Int): Boolean = this match + case IsOdd => x % 2 == 0 + case IsPrime => (2 until x).forall(y => x % y != 0) + case LessThan(bound) => x < bound + case And(f1, f2) => f1(x) && f2(x) + +def filter(f: Filter, elems: List[Int]): List[Int] = elems match + case Nil => Nil + case x :: xs => + if f(x) then x :: filter(f, xs) + else filter(f, xs) + +val xs = List(1, 2, 3, 4, 5) + +import Filter._ + +@main def Test = + println(filter(IsOdd , xs)) + println(filter(IsPrime , xs)) + println(filter(LessThan(4), xs)) \ No newline at end of file diff --git a/tests/run/extension-specificity.scala b/tests/run/extension-specificity.scala index ce62c1244d8f..e60f22637ce8 100644 --- a/tests/run/extension-specificity.scala +++ b/tests/run/extension-specificity.scala @@ -1,10 +1,10 @@ class A class B extends A -extension a on (x: A) with +extension a on (x: A): def foo: Int = 1 -extension b on (x: B) with +extension b on (x: B): def foo: Int = 2 @main def Test = diff --git a/tests/run/i7788.scala b/tests/run/i7788.scala index d8144f3d25e4..74950b73ede1 100644 --- a/tests/run/i7788.scala +++ b/tests/run/i7788.scala @@ -1,4 +1,4 @@ -trait Show[-A] with +trait Show[-A]: def show(a:A): String given Show[String] = x => x diff --git a/tests/run/instances.scala b/tests/run/instances.scala index 7a197b38496c..cb6c562a35c3 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -8,14 +8,14 @@ object Test extends App { case class Circle(x: Double, y: Double, radius: Double) - extension circleOps on (c: Circle) with + extension circleOps on (c: Circle): def circumference: Double = c.radius * math.Pi * 2 val circle = new Circle(1, 1, 2.0) assert(circle.circumference == circleOps.circumference(circle)) - extension stringOps on (xs: Seq[String]) with + extension stringOps on (xs: Seq[String]): def longestStrings: Seq[String] = val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) @@ -23,12 +23,12 @@ object Test extends App { val names = List("hi", "hello", "world") assert(names.longestStrings == List("hello", "world")) - extension on [T](xs: Seq[T]) with + extension on [T](xs: Seq[T]): def second = xs.tail.head assert(names.longestStrings.second == "world") - extension listListOps on [T](xs: List[List[T]]) with + extension listListOps on [T](xs: List[List[T]]): def flattened = xs.foldLeft[List[T]](Nil)(_ ++ _) // A right associative op. Note: can't use given extension for this! @@ -43,13 +43,13 @@ object Test extends App { assert(List(names, List("!")).flattened == names :+ "!") assert(Nil.flattened == Nil) - trait SemiGroup[T] with + trait SemiGroup[T]: def (x: T).combine(y: T): T - trait Monoid[T] extends SemiGroup[T] with + trait Monoid[T] extends SemiGroup[T]: def unit: T - given StringMonoid : Monoid[String] with + given StringMonoid : Monoid[String]: def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" @@ -59,19 +59,19 @@ object Test extends App { println(sum(names)) - trait Ord[T] with + trait Ord[T]: def (x: T).compareTo(y: T): Int def (x: T) < (y: T) = x.compareTo(y) < 0 def (x: T) > (y: T) = x.compareTo(y) > 0 val minimum: T end Ord - given Ord[Int] with + given Ord[Int]: def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 val minimum = Int.MinValue - given listOrd[T: Ord]: Ord[List[T]] with + given listOrd[T: Ord]: Ord[List[T]]: def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -91,24 +91,24 @@ object Test extends App { println(max(List(1, 2, 3), List(2))) - trait Functor[F[_]] with + trait Functor[F[_]]: def [A, B](x: F[A]) map (f: A => B): F[B] end Functor - trait Monad[F[_]] extends Functor[F] with + trait Monad[F[_]] extends Functor[F]: def [A, B](x: F[A]) flatMap (f: A => F[B]): F[B] def [A, B](x: F[A]) map (f: A => B) = x.flatMap(f `andThen` pure) def pure[A](x: A): F[A] end Monad - given listMonad: Monad[List] with + given listMonad: Monad[List]: def [A, B](xs: List[A]) flatMap (f: A => List[B]): List[B] = xs.flatMap(f) def pure[A](x: A): List[A] = List(x) - given readerMonad[Ctx]: Monad[[X] =>> Ctx => X] with + given readerMonad[Ctx]: Monad[[X] =>> Ctx => X]: def [A, B](r: Ctx => A) flatMap (f: A => Ctx => B): Ctx => B = ctx => f(r(ctx))(ctx) def pure[A](x: A): Ctx => A = diff --git a/tests/semanticdb/expect/Enums.expect.scala b/tests/semanticdb/expect/Enums.expect.scala index 5e4fdccc826d..440a96d85f2d 100644 --- a/tests/semanticdb/expect/Enums.expect.scala +++ b/tests/semanticdb/expect/Enums.expect.scala @@ -1,17 +1,17 @@ -object Enums/*<-_empty_::Enums.*/ with +object Enums/*<-_empty_::Enums.*/: import <:_empty_::Enums.`<:<`.*/._ - enum Colour/*<-_empty_::Enums.Colour#*/ with + enum Colour/*<-_empty_::Enums.Colour#*/: import Colour/*->_empty_::Enums.Colour.*/.Red/*->_empty_::Enums.Colour.Red.*/ case Red/*<-_empty_::Enums.Colour.Red.*/, Green/*<-_empty_::Enums.Colour.Green.*/, Blue/*<-_empty_::Enums.Colour.Blue.*/ - enum Directions/*<-_empty_::Enums.Directions#*/ with + enum Directions/*<-_empty_::Enums.Directions#*/: case North/*<-_empty_::Enums.Directions.North.*/, East/*<-_empty_::Enums.Directions.East.*/, South/*<-_empty_::Enums.Directions.South.*/, West/*<-_empty_::Enums.Directions.West.*/ - enum Suits/*<-_empty_::Enums.Suits#*/ derives /*->scala::Eql.derived.*/Eql with + enum Suits/*<-_empty_::Enums.Suits#*/ derives /*->scala::Eql.derived.*/Eql: case Hearts/*<-_empty_::Enums.Suits.Hearts.*/, Spades/*<-_empty_::Enums.Suits.Spades.*/, Clubs/*<-_empty_::Enums.Suits.Clubs.*/, Diamonds/*<-_empty_::Enums.Suits.Diamonds.*/ - object Suits/*<-_empty_::Enums.Suits.*/ with + object Suits/*<-_empty_::Enums.Suits.*/: def (suit/*<-_empty_::Enums.Suits.isRed().*//*<-_empty_::Enums.Suits.isRed().(suit)*/: Suits/*->_empty_::Enums.Suits#*/).isRed: Boolean/*->scala::Boolean#*/ = suit/*->_empty_::Enums.Suits.isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Hearts/*->_empty_::Enums.Suits.Hearts.*/ ||/*->scala::Boolean#`||`().*/ suit/*->_empty_::Enums.Suits.isRed().(suit)*/ ==/*->scala::Any#`==`().*/ Diamonds/*->_empty_::Enums.Suits.Diamonds.*/ @@ -19,7 +19,7 @@ object Enums/*<-_empty_::Enums.*/ with case Spades/*->_empty_::Enums.Suits.Spades.*/ | Diamonds/*->_empty_::Enums.Suits.Diamonds.*/ => true case _ => false - enum WeekDays/*<-_empty_::Enums.WeekDays#*/ with + enum WeekDays/*<-_empty_::Enums.WeekDays#*/: case Monday/*<-_empty_::Enums.WeekDays.Monday.*/ case Tuesday/*<-_empty_::Enums.WeekDays.Tuesday.*/ case Wednesday/*<-_empty_::Enums.WeekDays.Wednesday.*/ @@ -28,25 +28,25 @@ object Enums/*<-_empty_::Enums.*/ with case Saturday/*<-_empty_::Enums.WeekDays.Saturday.*/ case Sunday/*<-_empty_::Enums.WeekDays.Sunday.*/ - enum Coin/*<-_empty_::Enums.Coin#*/(value/*<-_empty_::Enums.Coin#value.*/: Int/*->scala::Int#*/) with + enum Coin/*<-_empty_::Enums.Coin#*/(value/*<-_empty_::Enums.Coin#value.*/: Int/*->scala::Int#*/): case Penny/*<-_empty_::Enums.Coin.Penny.*/ extends Coin/*->_empty_::Enums.Coin#*/(1) case Nickel/*<-_empty_::Enums.Coin.Nickel.*/ extends Coin/*->_empty_::Enums.Coin#*/(5) case Dime/*<-_empty_::Enums.Coin.Dime.*/ extends Coin/*->_empty_::Enums.Coin#*/(10) case Quarter/*<-_empty_::Enums.Coin.Quarter.*/ extends Coin/*->_empty_::Enums.Coin#*/(25) case Dollar/*<-_empty_::Enums.Coin.Dollar.*/ extends Coin/*->_empty_::Enums.Coin#*/(100) - enum Maybe/*<-_empty_::Enums.Maybe#*/[+A/*<-_empty_::Enums.Maybe#[A]*/] with + enum Maybe/*<-_empty_::Enums.Maybe#*/[+A/*<-_empty_::Enums.Maybe#[A]*/]: case Just/*<-_empty_::Enums.Maybe.Just#*/(value/*<-_empty_::Enums.Maybe.Just#value.*/: A/*->_empty_::Enums.Maybe.Just#[A]*/) case None/*<-_empty_::Enums.Maybe.None.*/ - enum Tag/*<-_empty_::Enums.Tag#*/[A/*<-_empty_::Enums.Tag#[A]*/] with + enum Tag/*<-_empty_::Enums.Tag#*/[A/*<-_empty_::Enums.Tag#[A]*/]: case IntTag/*<-_empty_::Enums.Tag.IntTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Int/*->scala::Int#*/] case BooleanTag/*<-_empty_::Enums.Tag.BooleanTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Boolean/*->scala::Boolean#*/] - enum <:_empty_::Enums.`<:<`.Refl#[C]*/ <:_empty_::Enums.`<:<`#*/ C/*->_empty_::Enums.`<:<`.Refl#[C]*/) - object <:_empty_::Enums.`<:<`.given_T().[T]*/ <:_empty_::Enums.`<:<`#*/ T/*->_empty_::Enums.`<:<`.given_T().[T]*/) = Refl/*->_empty_::Enums.`<:<`.Refl.*//*->_empty_::Enums.`<:<`.Refl.apply().*/() def [A, B]/*<-_empty_::Enums.unwrap().*//*<-_empty_::Enums.unwrap().[A]*//*<-_empty_::Enums.unwrap().[B]*/(opt/*<-_empty_::Enums.unwrap().(opt)*/: Option/*->scala::Option#*/[A/*->_empty_::Enums.unwrap().[A]*/]) unwrap(given ev/*<-_empty_::Enums.unwrap().(ev)*/: A/*->_empty_::Enums.unwrap().[A]*/ <:_empty_::Enums.`<:<`#*/ Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/]): Option/*->scala::Option#*/[B/*->_empty_::Enums.unwrap().[B]*/] = ev/*->_empty_::Enums.unwrap().(ev)*/ match @@ -54,7 +54,7 @@ object Enums/*<-_empty_::Enums.*/ with val some1/*<-_empty_::Enums.some1.*/ = /*->_empty_::Enums.unwrap().*/Some/*->scala::Some.*//*->scala::Some.apply().*/(Some/*->scala::Some.*//*->scala::Some.apply().*/(1))/*->_empty_::Enums.`<:<`.given_T().*/.unwrap - enum Planet/*<-_empty_::Enums.Planet#*/(mass/*<-_empty_::Enums.Planet#mass.*/: Double/*->scala::Double#*/, radius/*<-_empty_::Enums.Planet#radius.*/: Double/*->scala::Double#*/) extends java.lang.Enum/*->java::lang::Enum#*/[Planet/*->_empty_::Enums.Planet#*/]/*->java::lang::Enum#``().*/ with + enum Planet/*<-_empty_::Enums.Planet#*/(mass/*<-_empty_::Enums.Planet#mass.*/: Double/*->scala::Double#*/, radius/*<-_empty_::Enums.Planet#radius.*/: Double/*->scala::Double#*/) extends java.lang.Enum/*->java::lang::Enum#*/[Planet/*->_empty_::Enums.Planet#*/]/*->java::lang::Enum#``().*/: private final val G/*<-_empty_::Enums.Planet#G.*/ = 6.67300E-11 def surfaceGravity/*<-_empty_::Enums.Planet#surfaceGravity().*/ = G/*->_empty_::Enums.Planet#G.*/ */*->scala::Double#`*`(+6).*/ mass/*->_empty_::Enums.Planet#mass.*/ //*->scala::Double#`::`(+6).*/ (radius/*->_empty_::Enums.Planet#radius.*/ */*->scala::Double#`*`(+6).*/ radius/*->_empty_::Enums.Planet#radius.*/) def surfaceWeight/*<-_empty_::Enums.Planet#surfaceWeight().*/(otherMass/*<-_empty_::Enums.Planet#surfaceWeight().(otherMass)*/: Double/*->scala::Double#*/) = otherMass/*->_empty_::Enums.Planet#surfaceWeight().(otherMass)*/ */*->scala::Double#`*`(+6).*/ surfaceGravity/*->_empty_::Enums.Planet#surfaceGravity().*/ diff --git a/tests/semanticdb/expect/Enums.scala b/tests/semanticdb/expect/Enums.scala index 6ccd2a1fdf8d..94f4a56e3c1b 100644 --- a/tests/semanticdb/expect/Enums.scala +++ b/tests/semanticdb/expect/Enums.scala @@ -1,17 +1,17 @@ -object Enums with +object Enums: import <:<._ - enum Colour with + enum Colour: import Colour.Red case Red, Green, Blue - enum Directions with + enum Directions: case North, East, South, West - enum Suits derives Eql with + enum Suits derives Eql: case Hearts, Spades, Clubs, Diamonds - object Suits with + object Suits: def (suit: Suits).isRed: Boolean = suit == Hearts || suit == Diamonds @@ -19,7 +19,7 @@ object Enums with case Spades | Diamonds => true case _ => false - enum WeekDays with + enum WeekDays: case Monday case Tuesday case Wednesday @@ -28,25 +28,25 @@ object Enums with case Saturday case Sunday - enum Coin(value: Int) with + enum Coin(value: Int): case Penny extends Coin(1) case Nickel extends Coin(5) case Dime extends Coin(10) case Quarter extends Coin(25) case Dollar extends Coin(100) - enum Maybe[+A] with + enum Maybe[+A]: case Just(value: A) case None - enum Tag[A] with + enum Tag[A]: case IntTag extends Tag[Int] case BooleanTag extends Tag[Boolean] - enum <:<[-A, B] with + enum <:<[-A, B]: case Refl[C]() extends (C <:< C) - object <:< with + object <:< : given [T]: (T <:< T) = Refl() def [A, B](opt: Option[A]) unwrap(given ev: A <:< Option[B]): Option[B] = ev match @@ -54,7 +54,7 @@ object Enums with val some1 = Some(Some(1)).unwrap - enum Planet(mass: Double, radius: Double) extends java.lang.Enum[Planet] with + enum Planet(mass: Double, radius: Double) extends java.lang.Enum[Planet]: private final val G = 6.67300E-11 def surfaceGravity = G * mass / (radius * radius) def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity