diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index e5231018126a..6eedc729c226 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -954,10 +954,6 @@ object desugar { else tree } - /** Invent a name for an anonympus given of type or template `impl`. */ - def inventGivenName(impl: Tree)(implicit ctx: Context): SimpleName = - s"given_${inventName(impl)}".toTermName.asSimpleName - /** The normalized name of `mdef`. This means * 1. Check that the name does not redefine a Scala core class. * If it does redefine, issue an error and return a mangled name instead of the original one. @@ -965,7 +961,7 @@ object desugar { */ def normalizeName(mdef: MemberDef, impl: Tree)(implicit ctx: Context): Name = { var name = mdef.name - if (name.isEmpty) name = name.likeSpaced(inventGivenName(impl)) + if (name.isEmpty) name = name.likeSpaced(inventGivenOrExtensionName(impl)) if (ctx.owner == defn.ScalaPackageClass && defn.reservedScalaClassNames.contains(name.toTypeName)) { def kind = if (name.isTypeName) "class" else "object" ctx.error(em"illegal redefinition of standard $kind $name", mdef.sourcePos) @@ -974,27 +970,26 @@ object desugar { name } - /** Invent a name for an anonymous instance with template `impl`. - */ - private def inventName(impl: Tree)(implicit ctx: Context): String = impl match { - case impl: Template => - if (impl.parents.isEmpty) - impl.body.find { - case dd: DefDef if dd.mods.is(Extension) => true - case _ => false - } - match { - case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) => - s"${name}_of_${inventTypeName(vparam.tpt)}" - case _ => - ctx.error(i"anonymous instance must implement a type or have at least one extension method", impl.sourcePos) - nme.ERROR.toString - } - else - impl.parents.map(inventTypeName(_)).mkString("_") - case impl: Tree => - inventTypeName(impl) - } + /** Invent a name for an anonympus given or extension of type or template `impl`. */ + def inventGivenOrExtensionName(impl: Tree)(given ctx: Context): SimpleName = + val str = impl match + case impl: Template => + if impl.parents.isEmpty then + impl.body.find { + case dd: DefDef if dd.mods.is(Extension) => true + case _ => false + } + match + case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) => + s"extension_${name}_${inventTypeName(vparam.tpt)}" + case _ => + ctx.error(i"anonymous instance must implement a type or have at least one extension method", impl.sourcePos) + nme.ERROR.toString + else + impl.parents.map(inventTypeName(_)).mkString("given_", "_", "") + case impl: Tree => + "given_" ++ inventTypeName(impl) + str.toTermName.asSimpleName private class NameExtractor(followArgs: Boolean) extends UntypedTreeAccumulator[String] { private def extractArgs(args: List[Tree])(implicit ctx: Context): String = diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index f4179577ad90..362b7815db6a 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -530,6 +530,7 @@ object StdNames { val null_ : N = "null" val nullExpr: N = "nullExpr" val ofDim: N = "ofDim" + val on: N = "on" val opaque: N = "opaque" val open: N = "open" val ordinal: N = "ordinal" diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index f64f627b15d9..85c3e21f1358 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -188,7 +188,7 @@ object Parsers { /* -------------- TOKEN CLASSES ------------------------------------------- */ def isIdent = in.isIdent - def isIdent(name: Name) = in.token == IDENTIFIER && in.name == name + def isIdent(name: Name) = in.isIdent(name) def isSimpleLiteral = simpleLiteralTokens contains in.token def isLiteral = literalTokens contains in.token def isNumericLit = numericLitTokens contains in.token @@ -216,10 +216,11 @@ object Parsers { in.canStartExprTokens.contains(in.token) && !in.isSoftModifierInModifierPosition def isDefIntro(allowedMods: BitSet, excludedSoftModifiers: Set[TermName] = Set.empty): Boolean = - in.token == AT || - (defIntroTokens `contains` in.token) || - (allowedMods `contains` in.token) || - in.isSoftModifierInModifierPosition && !excludedSoftModifiers.contains(in.name) + in.token == AT + || defIntroTokens.contains(in.token) + || allowedMods.contains(in.token) + || in.isSoftModifierInModifierPosition && !excludedSoftModifiers.contains(in.name) + || isIdent(nme.extension) && followingIsExtension() def isStatSep: Boolean = in.isNewLine || in.token == SEMI @@ -944,6 +945,13 @@ object Parsers { lookahead.skipParens() lookahead.token == COLON || lookahead.token == SUBTYPE + def followingIsExtension() = + val lookahead = in.LookaheadScanner() + lookahead.nextToken() + if lookahead.isIdent && !lookahead.isIdent(nme.on) then + lookahead.nextToken() + lookahead.isIdent(nme.on) + /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ var opStack: List[OpInfo] = Nil @@ -3105,7 +3113,7 @@ object Parsers { * | this ParamClause ParamClauses `=' ConstrExpr * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] DefParamClauses - * | ExtParamClause [nl] id DefParamClauses + * | ExtParamClause [nl] [‘.’] id DefParamClauses */ def defDefOrDcl(start: Offset, mods: Modifiers): Tree = atSpan(start, nameStart) { def scala2ProcedureSyntax(resultTypeStr: String) = { @@ -3134,7 +3142,11 @@ object Parsers { makeConstructor(Nil, vparamss, rhs).withMods(mods).setComment(in.getDocComment(start)) } else { - def extParamss() = try paramClause(0, prefix = true) :: Nil finally newLineOpt() + def extParamss() = + try paramClause(0, prefix = true) :: Nil + finally + if in.token == DOT then in.nextToken() + else newLineOpt() val (leadingTparams, leadingVparamss, flags) = if in.token == LBRACKET then (typeParamClause(ParamOwner.Def), extParamss(), Method | Extension) @@ -3271,6 +3283,7 @@ object Parsers { * | [‘case’] ‘object’ ObjectDef * | ‘enum’ EnumDef * | ‘given’ GivenDef + * | ‘extension’ ExtensionDef */ def tmplDef(start: Int, mods: Modifiers): Tree = in.token match { @@ -3289,8 +3302,11 @@ object Parsers { case GIVEN => givenDef(start, mods, atSpan(in.skipToken()) { Mod.Given() }) case _ => - syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition()) - EmptyTree + if isIdent(nme.extension) && followingIsExtension() then + extensionDef(start, mods) + else + syntaxErrorOrIncomplete(ExpectedStartOfTopLevelDefinition()) + EmptyTree } /** ClassDef ::= id ClassConstr TemplateOpt @@ -3518,6 +3534,23 @@ object Parsers { finalizeDef(gdef, mods1, start) } + /** ExtensionDef ::= [id] ‘of’ ExtParamClause {GivenParamClause} ‘with’ ExtMethods + */ + def extensionDef(start: Offset, mods: Modifiers): ModuleDef = + in.nextToken() + val name = if isIdent && !isIdent(nme.on) then ident() else EmptyTermName + if !isIdent(nme.on) then syntaxErrorOrIncomplete("`on` expected") + if isIdent(nme.on) then in.nextToken() + val tparams = typeParamClauseOpt(ParamOwner.Def) + val extParams = paramClause(0, prefix = true) + val givenParamss = paramClauses(givenOnly = true) + possibleTemplateStart() + if !in.isNestedStart then syntaxError("Extension without extension methods") + val templ = templateBodyOpt(makeConstructor(tparams, extParams :: givenParamss), Nil, Nil) + templ.body.foreach(checkExtensionMethod(tparams, _)) + val edef = ModuleDef(name, templ) + finalizeDef(edef, addFlag(mods, Given), start) + /* -------- TEMPLATES ------------------------------------------- */ /** SimpleConstrApp ::= AnnotType {ParArgumentExprs} @@ -3677,7 +3710,7 @@ object Parsers { def templateStatSeq(): (ValDef, List[Tree]) = checkNoEscapingPlaceholders { var self: ValDef = EmptyValDef val stats = new ListBuffer[Tree] - if (isExprIntro) { + if (isExprIntro && !isDefIntro(modifierTokens)) { val first = expr1() if (in.token == ARROW) { first match { @@ -3703,10 +3736,10 @@ object Parsers { stats ++= importClause(IMPORT, Import) else if (in.token == EXPORT) stats ++= importClause(EXPORT, Export.apply) - else if (isExprIntro) - stats += expr1() else if (isDefIntro(modifierTokensOrCase)) stats +++= defOrDcl(in.offset, defAnnotsMods(modifierTokens)) + else if (isExprIntro) + stats += expr1() else if (!isStatSep) { exitOnError = mustStartStat syntaxErrorOrIncomplete("illegal start of definition") diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 0d3024a8ccee..a3d49fa09322 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -1017,6 +1017,7 @@ object Scanners { def isNewLine = token == NEWLINE || token == NEWLINES def isIdent = token == IDENTIFIER || token == BACKQUOTED_IDENT + def isIdent(name: Name) = token == IDENTIFIER && this.name == name def isNestedStart = token == LBRACE || token == INDENT def isNestedEnd = token == RBRACE || token == OUTDENT diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index da56757fc755..107eb7eb0f57 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1541,7 +1541,7 @@ class Typer extends Namer var name = tree.name if (name == nme.WILDCARD && tree.mods.is(Given)) { val Typed(_, tpt): @unchecked = tree.body - name = desugar.inventGivenName(tpt) + name = desugar.inventGivenOrExtensionName(tpt) } if (name == nme.WILDCARD) body1 else { diff --git a/docs/blog/_posts/2019-12-20-21th-dotty-milestone-release.md b/docs/blog/_posts/2019-12-20-21th-dotty-milestone-release.md index b409cc8c417b..e1d5cc8835a7 100644 --- a/docs/blog/_posts/2019-12-20-21th-dotty-milestone-release.md +++ b/docs/blog/_posts/2019-12-20-21th-dotty-milestone-release.md @@ -183,7 +183,7 @@ given extension (s: String) { ... } ``` or ```scala -given listOps: [T](xs: List[T]) extended with { ... } +extension listOps of [T](xs: List[T]) with { ... } given (s: String) extended with { ... } ``` diff --git a/docs/docs/contributing/debugging.md b/docs/docs/contributing/debugging.md index 5d3f7d96a9cc..62d1244002cd 100644 --- a/docs/docs/contributing/debugging.md +++ b/docs/docs/contributing/debugging.md @@ -88,7 +88,7 @@ But you can also do: assertPositioned(tree.reporting(s"Tree is: $result")) ``` -`def (a: A) reporting(f: given WrappedResult[T] => String, p: Printer = Printers.default): A` is defined on all types. The function `f` can be written without the argument since the argument is `given`. The `result` variable is a part of the `WrapperResult` – a tiny framework powering the `reporting` function. Basically, whenever you are using `reporting` on an object `A`, you can use the `result: A` variable from this function and it will be equal to the object you are calling `reporting` on. +`def (a: A).reporting(f: given WrappedResult[T] => String, p: Printer = Printers.default): A` is defined on all types. The function `f` can be written without the argument since the argument is `given`. The `result` variable is a part of the `WrapperResult` – a tiny framework powering the `reporting` function. Basically, whenever you are using `reporting` on an object `A`, you can use the `result: A` variable from this function and it will be equal to the object you are calling `reporting` on. ## Printing out trees after phases To print out the trees you are compiling after the FrontEnd (scanner, parser, namer, typer) phases: diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 6bbd74a65153..e688e554584b 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -103,7 +103,7 @@ yield ### Soft keywords ``` -as derives inline opaque open +derives extension inline opaque open ~ * | & + - ``` @@ -358,7 +358,7 @@ ValDcl ::= ids ‘:’ Type VarDcl ::= ids ‘:’ Type PatDef(_, ids, tpe, EmptyTree) DefDcl ::= DefSig ‘:’ Type DefDef(_, name, tparams, vparamss, tpe, EmptyTree) DefSig ::= id [DefTypeParamClause] DefParamClauses - | ExtParamClause [nl] id DefParamClauses + | ExtParamClause [nl] [‘.’] id DefParamClauses TypeDcl ::= id [TypeParamClause] SubtypeBounds [‘=’ Type] TypeDefTree(_, name, tparams, bound Def ::= ‘val’ PatDef @@ -378,7 +378,7 @@ TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef | [‘case’] ‘object’ ObjectDef | ‘enum’ EnumDef | ‘given’ GivenDef - | Export + | ‘extension’ ExtensionDef ClassDef ::= id ClassConstr [Template] ClassDef(mods, name, tparams, templ) ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses with DefDef(_, , Nil, vparamss, EmptyTree, EmptyTree) as first stat ConstrMods ::= {Annotation} [AccessModifier] @@ -388,11 +388,10 @@ GivenDef ::= [GivenSig (‘:’ | <:)] {FunArgTypes ‘=>’} AnnotType ‘=’ Expr | [GivenSig ‘:’] {FunArgTypes ‘=>’} ConstrApps [[‘with’] TemplateBody] - | [id ‘:’] ExtParamClause {GivenParamClause} - ‘extended’ ‘with’ ExtMethods GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause} -ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ +ExtensionDef ::= [id] ‘of’ ExtParamClause {GivenParamClause} ExtMethods ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’ +ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ Template ::= InheritClauses [[‘with’] TemplateBody] Template(constr, parents, self, stats) InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp} diff --git a/docs/docs/reference/contextual/extension-methods-new.md b/docs/docs/reference/contextual/extension-methods-new.md new file mode 100644 index 000000000000..bdca8071881c --- /dev/null +++ b/docs/docs/reference/contextual/extension-methods-new.md @@ -0,0 +1,182 @@ +--- +layout: doc-page +title: "Extension Methods" +--- + +Extension methods allow one to add methods to a type after the type is defined. Example: + +```scala +case class Circle(x: Double, y: Double, radius: Double) + +def (c: Circle).circumference: Double = c.radius * math.Pi * 2 +``` + +Like regular methods, extension methods can be invoked with infix `.`: + +```scala +val circle = Circle(0, 0, 1) +circle.circumference +``` + +### Translation of Extension Methods + +Extension methods are methods that have a parameter clause in front of the defined +identifier. They translate to methods where the leading parameter section is moved +to after the defined identifier. So, the definition of `circumference` above translates +to the plain method, and can also be invoked as such: +```scala +def circumference(c: Circle): Double = c.radius * math.Pi * 2 + +assert(circle.circumference == circumference(circle)) +``` + +### Translation of Calls to Extension Methods + +When is an extension method applicable? There are two possibilities. + + - An extension method is applicable if it is visible under a simple name, by being defined + or inherited or imported in a scope enclosing the application. + - An extension method is applicable if it is a member of some given instance at the point of the application. + +As an example, consider an extension method `longestStrings` on `Seq[String]` defined in a trait `StringSeqOps`. + +```scala +trait StringSeqOps { + def (xs: Seq[String]).longestStrings = { + val maxLength = xs.map(_.length).max + xs.filter(_.length == maxLength) + } +} +``` +We can make the extension method available by defining a given `StringSeqOps` instance, like this: +```scala +given ops1: StringSeqOps +``` +Then +```scala +List("here", "is", "a", "list").longestStrings +``` +is legal everywhere `ops1` is available. Alternatively, we can define `longestStrings` as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method. + +```scala +object ops2 extends StringSeqOps +import ops2.longestStrings +List("here", "is", "a", "list").longestStrings +``` +The precise rules for resolving a selection to an extension method are as follows. + +Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type arguments `[Ts]` are optional, +and where `T` is the expected type. The following two rewritings are tried in order: + + 1. The selection is rewritten to `m[Ts](e)`. + 2. If the first rewriting does not typecheck with expected type `T`, and there is a given instance `i` + in either the current scope or in the implicit scope of `T`, and `i` defines an extension + method named `m`, then selection is expanded to `i.m[Ts](e)`. + This second rewriting is attempted at the time where the compiler also tries an implicit conversion + from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results. + +So `circle.circumference` translates to `CircleOps.circumference(circle)`, provided +`circle` has type `Circle` and `CircleOps` is given (i.e. it is visible at the point of call or it is defined in the companion object of `Circle`). + +### Operators + +The extension method syntax also applies to the definition of operators. +In this case it is allowed and preferable to omit the period between the leading parameter list +and the operator. In each case the definition syntax mirrors the way the operator is applied. +Examples: +```scala +def (x: String) < (y: String) = ... +def (x: Elem) +: (xs: Seq[Elem]) = ... +def (x: Number) min (y: Number) = ... + +"ab" < "c" +1 +: List(2, 3) +x min 3 +``` +The three definitions above translate to +```scala +def < (x: String)(y: String) = ... +def +: (xs: Seq[Elem])(x: Elem) = ... +def min(x: Number)(y: Number) = ... +``` +Note the swap of the two parameters `x` and `xs` when translating +the right-binding operator `+:` to an extension method. This is analogous +to the implementation of right binding operators as normal methods. + +### Generic Extensions + +The `StringSeqOps` examples extended a specific instance of a generic type. It is also possible to extend a generic type by adding type parameters to an extension method. Examples: + +```scala +def [T](xs: List[T]) second = + xs.tail.head + +def [T](xs: List[List[T]]) flattened = + xs.foldLeft[List[T]](Nil)(_ ++ _) + +def [T: Numeric](x: T) + (y: T): T = + summon[Numeric[T]].plus(x, y) +``` + +If an extension method has type parameters, they come immediately after the `def` and are followed by the extended parameter. When calling a generic extension method, any explicitly given type arguments follow the method name. So the `second` method can be instantiated as follows: +```scala +List(1, 2, 3).second[Int] +``` +### Collective Extensions + +A collective extension defines one or more concrete methods that have the same type parameters +and prefix parameter. Examples: + +```scala +extension stringOps on (xs: Seq[String]) { + def longestStrings: Seq[String] = { + val maxLength = xs.map(_.length).max + xs.filter(_.length == maxLength) + } +} + +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]) { + def largest(n: Int) = xs.sorted.takeRight(n) +} +``` +If a given extension is anonymous (as in the last clause), its name is synthesized from the name of the first defined extension method. + +The extensions above are equivalent to the following regular given instances where the implemented parent is `AnyRef` and the parameters in the `extension` clause are repeated in each extension method definition: +```scala +given stringOps: AnyRef { + def (xs: Seq[String]).longestStrings: Seq[String] = { + val maxLength = xs.map(_.length).max + xs.filter(_.length == maxLength) + } +} +given listOps: AnyRef { + def [T](xs: List[T]) second = xs.tail.head + def [T](xs: List[T]) third: T = xs.tail.tail.head +} +given extension_largest_List_T: AnyRef { + def [T](xs: List[T]) largest (given Ordering[T])(n: Int) = + xs.sorted.takeRight(n) +} +``` + +`extension` and `on` are soft keywords. They can also be used as a regular identifiers. + +### Syntax + +Here are the syntax changes for extension methods and given extensions relative +to the [current syntax](../../internals/syntax.md). `extension` is a soft keyword, recognized only in tandem with `on`. It can be used as an identifier everywhere else. + +``` +DefSig ::= ... + | ExtParamClause [nl] [‘.’] id DefParamClauses +ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’ +TmplDef ::= ... + | ‘extension’ ExtensionDef +ExtensionDef ::= [id] ‘on’ ExtParamClause {GivenParamClause} ExtMethods +ExtMethods ::= ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’ +``` diff --git a/docs/docs/reference/contextual/extension-methods.md b/docs/docs/reference/contextual/extension-methods.md index 036f669ffe55..7ad12fe80bdb 100644 --- a/docs/docs/reference/contextual/extension-methods.md +++ b/docs/docs/reference/contextual/extension-methods.md @@ -3,6 +3,9 @@ layout: doc-page title: "Extension Methods" --- +**Note:** The syntax of extension methods is about to change. Here is the +[doc page with the new syntax](./extension-methods-new.html), supported from Dotty 0.22 onwards. + Extension methods allow one to add methods to a type after the type is defined. Example: ```scala diff --git a/docs/docs/reference/contextual/implicit-function-types.md b/docs/docs/reference/contextual/implicit-function-types.md index 49f3bae729f1..6ceaa6114a35 100644 --- a/docs/docs/reference/contextual/implicit-function-types.md +++ b/docs/docs/reference/contextual/implicit-function-types.md @@ -120,7 +120,7 @@ object PostConditions { def result[T](given r: WrappedResult[T]): T = r - def (x: T) ensuring[T](condition: (given WrappedResult[T]) => Boolean): T = { + def (x: T).ensuring[T](condition: (given WrappedResult[T]) => Boolean): T = { assert(condition(given x)) x } diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index e30ca53f421b..0d6f39eefdad 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -61,15 +61,23 @@ The synthesized type names are formed from Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthesized name `F_X_Y`. Directly implemented function types `A => B` are represented as `A_to_B`. Function types used as arguments to other type constructors are represented as `Function`. -Anonymous given instances that define extension methods -get their name from the name of the first extension method and the toplevel type -constructor of its first parameter. For example, the given instance +### Anonymous Collective Extensions + +Anonymous collective extensions also get compiler synthesized names, which are formed from + + - the prefix `extension_` + - the name of the first defined extension method + - the simple name of the first parameter type of this extension method + - the simple name(s) of the toplevel argument type constructors to this type. + +For example, the extension ```scala -given [T] (xs: List[T]) extended with { +extension on [T] (xs: List[T]) { def second = ... } ``` -gets the synthesized name `given_second_of_List_T`. +gets the synthesized name `extension_second_List_T`. + ### Given Clauses @@ -104,7 +112,7 @@ will map to given clauses instead. Extension methods have no direct counterpart in Scala 2, but they can be simulated with implicit classes. For instance, the extension method ```scala -def (c: Circle) circumference: Double = c.radius * math.Pi * 2 +def (c: Circle).circumference: Double = c.radius * math.Pi * 2 ``` could be simulated to some degree by ```scala diff --git a/docs/docs/reference/contextual/typeclasses.md b/docs/docs/reference/contextual/typeclasses.md index 01b2fd048a32..3f82ee269231 100644 --- a/docs/docs/reference/contextual/typeclasses.md +++ b/docs/docs/reference/contextual/typeclasses.md @@ -11,7 +11,7 @@ with canonical implementations defined by given instances. Here are some example ```scala trait SemiGroup[T] with - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T trait Monoid[T] extends SemiGroup[T] with def unit: T @@ -20,11 +20,11 @@ object Monoid with def apply[T](given Monoid[T]) = summon[Monoid[T]] given Monoid[String] with - def (x: String) combine (y: String): String = x.concat(y) + def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" given Monoid[Int] with - def (x: Int) combine (y: Int): Int = x + y + def (x: Int).combine(y: Int): Int = x + y def unit: Int = 0 def sum[T: Monoid](xs: List[T]): T = diff --git a/docs/docs/reference/dropped-features/package-objects.md b/docs/docs/reference/dropped-features/package-objects.md index 2e0f51b25fb1..22ba96eb5f86 100644 --- a/docs/docs/reference/dropped-features/package-objects.md +++ b/docs/docs/reference/dropped-features/package-objects.md @@ -22,7 +22,7 @@ def b = a._2 case class C() implicit object Cops { - def (x: C) pair (y: C) = (x, y) + def (x: C).pair(y: C) = (x, y) } ``` There may be several source files in a package containing such toplevel definitions, and source files can freely mix toplevel value, method, and type definitions with classes and objects. diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 984a0550c794..13f3cf953ee0 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -707,7 +707,7 @@ This might be used to then perform an implicit search as in: ```scala -inline def (sc: StringContext) showMe(args: =>Any*): String = ${ showMeExpr('sc, 'args) } +inline def (sc: StringContext).showMe(args: =>Any*): String = ${ showMeExpr('sc, 'args) } private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(given qctx: QuoteContext): Expr[String] = { argsExpr match { diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index c15d439a5351..1390fadd2559 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -71,8 +71,8 @@ object Access { def (x: Permissions) & (y: Permissions): Permissions = x | y def (x: PermissionChoice) | (y: PermissionChoice): PermissionChoice = x | y - def (x: Permissions) is (y: Permissions) = (x & y) == y - def (x: Permissions) isOneOf (y: PermissionChoice) = (x & y) != 0 + def (x: Permissions).is(y: Permissions) = (x & y) == y + def (x: Permissions).isOneOf(y: PermissionChoice) = (x & y) != 0 val NoPermission: Permission = 0 val ReadOnly: Permission = 1 diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 7dff362febd7..f2e836803662 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -43,7 +43,7 @@ Examples * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ -def (f: F) tupled[F, Args <: Tuple, R](given tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) +def [F, Args <: Tuple, R](f: F).tupled(given tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) ``` `TupledFunction` can be used to generalize the `Function.untupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala)) @@ -58,7 +58,7 @@ def (f: F) tupled[F, Args <: Tuple, R](given tf: TupledFunction[F, Args => R]): * @tparam Args the tuple type with the same types as the function arguments of F * @tparam R the return type of F */ -def (f: Args => R) untupled[F, Args <: Tuple, R](given tf: TupledFunction[F, Args => R]): F = tf.untupled(f) +def [F, Args <: Tuple, R](f: Args => R).untupled(given tf: TupledFunction[F, Args => R]): F = tf.untupled(f) ``` `TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. @@ -72,7 +72,7 @@ def (f: Args => R) untupled[F, Args <: Tuple, R](given tf: TupledFunction[F, Arg * @tparam GArgs the tuple type with the same types as the function arguments of G * @tparam R the return type of F */ -def (f: F) compose[F, G, FArgs <: Tuple, GArgs <: Tuple, R](g: G)(given tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { +def [F, G, FArgs <: Tuple, GArgs <: Tuple, R](f: F).compose(g: G)(given tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { (x: GArgs) => tf.tupled(f)(tg.tupled(g)(x)) } ``` diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 7a2d2f68c39b..73c58dad7531 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -16,13 +16,13 @@ object opaques * @param n the index of the element to select * @return the element of the array at the given index */ - def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n) - def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n) - def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n) - def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n) - def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n) - def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n) - def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n) + def (arr: IArray[Byte]) apply(n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n) + def (arr: IArray[Short]) apply(n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n) + def (arr: IArray[Char]) apply(n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n) + def (arr: IArray[Int]) apply(n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n) + def (arr: IArray[Long]) apply(n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n) + def (arr: IArray[Float]) apply(n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n) + def (arr: IArray[Double]) apply(n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n) def [T <: Object](arr: IArray[T]) apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) def [T](arr: IArray[T]) apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) diff --git a/tests/neg-custom-args/extmethods-tparams.scala b/tests/neg-custom-args/extmethods-tparams.scala index e6bd6ebe7485..59a9780a7abf 100644 --- a/tests/neg-custom-args/extmethods-tparams.scala +++ b/tests/neg-custom-args/extmethods-tparams.scala @@ -1,2 +1,2 @@ -def (self: T) foo[T] = ??? // error +def (self: T).foo[T] = ??? // error def [T1](self: T1) bar[T2] = ??? // error // error \ No newline at end of file diff --git a/tests/neg-macros/i6432/Macro_1.scala b/tests/neg-macros/i6432/Macro_1.scala index 501926e3537c..2ca399dc7a1b 100644 --- a/tests/neg-macros/i6432/Macro_1.scala +++ b/tests/neg-macros/i6432/Macro_1.scala @@ -4,7 +4,7 @@ import scala.quoted.autolift.given import scala.quoted.matching._ object Macro { - inline def (sc: => StringContext) foo (args: String*): Unit = ${ impl('sc) } + inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) } def impl(sc: Expr[StringContext])(given qctx: QuoteContext): Expr[Unit] = { import qctx.tasty.{_, given} diff --git a/tests/neg-macros/i6432b/Macro_1.scala b/tests/neg-macros/i6432b/Macro_1.scala index 501926e3537c..2ca399dc7a1b 100644 --- a/tests/neg-macros/i6432b/Macro_1.scala +++ b/tests/neg-macros/i6432b/Macro_1.scala @@ -4,7 +4,7 @@ import scala.quoted.autolift.given import scala.quoted.matching._ object Macro { - inline def (sc: => StringContext) foo (args: String*): Unit = ${ impl('sc) } + inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) } def impl(sc: Expr[StringContext])(given qctx: QuoteContext): Expr[Unit] = { import qctx.tasty.{_, given} diff --git a/tests/neg-macros/reflect-inline/assert_1.scala b/tests/neg-macros/reflect-inline/assert_1.scala index eec9852b53d9..cdae0f37b43b 100644 --- a/tests/neg-macros/reflect-inline/assert_1.scala +++ b/tests/neg-macros/reflect-inline/assert_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ object api { - inline def (inline x: String) stripMargin2: String = + inline def (inline x: String).stripMargin2: String = ${ stripImpl(x) } private def stripImpl(x: String)(given qctx: QuoteContext): Expr[String] = diff --git a/tests/neg-macros/tasty-string-interpolator-position-a/Macro_1.scala b/tests/neg-macros/tasty-string-interpolator-position-a/Macro_1.scala index bf05adc5122d..d0865fd34833 100644 --- a/tests/neg-macros/tasty-string-interpolator-position-a/Macro_1.scala +++ b/tests/neg-macros/tasty-string-interpolator-position-a/Macro_1.scala @@ -3,7 +3,7 @@ import scala.language.implicitConversions object Macro { - implicit inline def (strCtx: => StringContext) f2 (args: =>Any*): String = ${FIntepolator.apply('strCtx, 'args)} + implicit inline def (strCtx: => StringContext).f2(args: =>Any*): String = ${FIntepolator.apply('strCtx, 'args)} } diff --git a/tests/neg-macros/tasty-string-interpolator-position-b/Macro_1.scala b/tests/neg-macros/tasty-string-interpolator-position-b/Macro_1.scala index a4de659aee3d..4cb7ad8570ac 100644 --- a/tests/neg-macros/tasty-string-interpolator-position-b/Macro_1.scala +++ b/tests/neg-macros/tasty-string-interpolator-position-b/Macro_1.scala @@ -3,7 +3,7 @@ import scala.language.implicitConversions object Macro { - implicit inline def (strCtx: => StringContext) f3 (args: =>Any*): String = ${FIntepolator.apply('strCtx, 'args)} + implicit inline def (strCtx: => StringContext).f3(args: =>Any*): String = ${FIntepolator.apply('strCtx, 'args)} } diff --git a/tests/neg/extension-methods.scala b/tests/neg/extension-methods.scala index 4eefd041f624..8396070e3282 100644 --- a/tests/neg/extension-methods.scala +++ b/tests/neg/extension-methods.scala @@ -1,7 +1,7 @@ object Test { implicit object O { - def (x: String) l1 = x.length + def (x: String).l1 = x.length def l1(x: Int) = x * x def l2(x: String) = x.length } @@ -10,8 +10,8 @@ object Test { "".l2 // error 1.l1 // error - given [T](xs: List[T]) extended with { - def (x: Int) f1: T = ??? // error: No extension method allowed here, since collective parameters are given + extension on [T](xs: List[T]) { + def (x: Int).f1: T = ??? // error: No extension method allowed here, since collective parameters are given def f2[T]: T = ??? // error: T is already defined as type T def f3(xs: List[T]) = ??? // error: xs is already defined as value xs } diff --git a/tests/neg/extmethod-overload.scala b/tests/neg/extmethod-overload.scala index ecf6afc73402..33fafb70ddd1 100644 --- a/tests/neg/extmethod-overload.scala +++ b/tests/neg/extmethod-overload.scala @@ -1,8 +1,9 @@ object Test { - given a: (x: Int) extended with + extension a on (x: Int) { def |+| (y: Int) = x + y + } - given b: (x: Int) extended with { + extension b on (x: Int) { def |+| (y: String) = x + y.length } assert((1 |+| 2) == 3) // error ambiguous diff --git a/tests/neg/extmethod-override.scala b/tests/neg/extmethod-override.scala index 3395460ecfab..9b2e809f9baa 100644 --- a/tests/neg/extmethod-override.scala +++ b/tests/neg/extmethod-override.scala @@ -1,8 +1,8 @@ class A { def f(x: Int)(y: Int): Int = 0 - def (x: Int) g (y: Int): Int = 1 + def (x: Int).g(y: Int): Int = 1 } class B extends A { - override def (x: Int) f (y: Int): Int = 1 // error + override def (x: Int).f(y: Int): Int = 1 // error override def g(x: Int)(y: Int): Int = 0 // error } \ No newline at end of file diff --git a/tests/neg/i5455.scala b/tests/neg/i5455.scala index c73da95e2062..e496cd68541f 100644 --- a/tests/neg/i5455.scala +++ b/tests/neg/i5455.scala @@ -11,9 +11,10 @@ object Library { def toInt(n: Nat): Int = n } - given (x: Nat) extended with + extension on (x: Nat) { def * (y: Nat): Nat = x * y def toInt: Int = x + } } object User extends App { diff --git a/tests/neg/i5773.scala b/tests/neg/i5773.scala index 6e98d5e0c93e..4ae1fa220599 100644 --- a/tests/neg/i5773.scala +++ b/tests/neg/i5773.scala @@ -1,16 +1,16 @@ trait Semigroup[T] { - def (lhs: T) append (rhs: T): T - def (lhs: Int) appendS (rhs: T): T = ??? + def (lhs: T).append(rhs: T): T + def (lhs: Int).appendS(rhs: T): T = ??? } object Semigroup { implicit object stringAppend extends Semigroup[String] { - override def (lhs: String) append (rhs: String): String = lhs + rhs + override def (lhs: String).append(rhs: String): String = lhs + rhs } implicit def sumSemigroup[N](implicit N: Numeric[N]): Semigroup[N] = new { - override def (lhs: N) append (rhs: N): N = N.plus(lhs, rhs) - def (lhs: Int) appendS (rhs: N): N = ??? // N.plus(lhs, rhs) + override def (lhs: N).append(rhs: N): N = N.plus(lhs, rhs) + def (lhs: Int).appendS(rhs: N): N = ??? // N.plus(lhs, rhs) } } diff --git a/tests/neg/i6762b.scala b/tests/neg/i6762b.scala index 9a12fffd6dbe..2d7bf0aacef3 100644 --- a/tests/neg/i6762b.scala +++ b/tests/neg/i6762b.scala @@ -9,5 +9,5 @@ type Liftable given Liftable = ??? implicit object ExprOps { - def (x: T) toExpr[T](given Liftable): Expr[T] = ??? + def (x: T).toExpr[T](given Liftable): Expr[T] = ??? } diff --git a/tests/neg/i6779.scala b/tests/neg/i6779.scala index 5a24e0763317..54998ba378fe 100644 --- a/tests/neg/i6779.scala +++ b/tests/neg/i6779.scala @@ -3,7 +3,7 @@ type G[T] type Stuff given Stuff = ??? -def (x: T) f[T](given Stuff): F[T] = ??? +def (x: T).f[T](given Stuff): F[T] = ??? def g1[T](x: T): F[G[T]] = x.f(given summon[Stuff]) // error diff --git a/tests/neg/i6801.scala b/tests/neg/i6801.scala index 94e417e7719c..0793f0757ad4 100644 --- a/tests/neg/i6801.scala +++ b/tests/neg/i6801.scala @@ -1,4 +1,4 @@ -given myNumericOps: [T](x: T) extended with { +extension myNumericOps on [T](x: T) { def + (y: T)(given n: Numeric[T]): T = n.plus(x,y) } def foo[T: Numeric](x: T) = 1f + x // error: no implicit argument of type Numeric[Any] diff --git a/tests/neg/i6900.scala b/tests/neg/i6900.scala index 7e696e320828..b021af2a9d7e 100644 --- a/tests/neg/i6900.scala +++ b/tests/neg/i6900.scala @@ -1,7 +1,7 @@ object Test2 { // Works with extension method - given [A](a: A) extended with + extension on [A](a: A) with def foo[C]: C => A = _ => a // error: extension method cannot have type parameters 1.foo.foo diff --git a/tests/neg/i7438.scala b/tests/neg/i7438.scala index c9e74ae31f5a..a263a5fe2f24 100644 --- a/tests/neg/i7438.scala +++ b/tests/neg/i7438.scala @@ -1,7 +1,7 @@ type Tr[+A] -inline def (tr: Tr[A]) map[A, B](f: A => B): Tr[B] = ??? +inline def (tr: Tr[A]).map[A, B](f: A => B): Tr[B] = ??? -def (d: Double) func: None.type => Some[Double] = ??? +def (d: Double).func: None.type => Some[Double] = ??? def run[A](query: None.type => Some[A]): Some[A] = ??? diff --git a/tests/neg/i7529.scala b/tests/neg/i7529.scala index 974d59b268b0..c42fa39c43cc 100644 --- a/tests/neg/i7529.scala +++ b/tests/neg/i7529.scala @@ -1,4 +1,4 @@ -given fooOps: [A](a: A) extended with +extension fooOps on [A](a: A) with @nonsense // error: not found: nonsense def foo = ??? \ No newline at end of file diff --git a/tests/neg/indent.scala b/tests/neg/indent.scala index b38ff81221f1..2bac87c9efb7 100644 --- a/tests/neg/indent.scala +++ b/tests/neg/indent.scala @@ -1,6 +1,6 @@ object Test { - def (x: Int) gt (y: Int) = x > y + def (x: Int).gt(y: Int) = x > y val y3 = if (1) max 10 gt 0 // error: end of statement expected but integer literal found // error // error // error 1 diff --git a/tests/neg/missing-implicit1.scala b/tests/neg/missing-implicit1.scala index 88d5bb23a51d..19b6728c10c1 100644 --- a/tests/neg/missing-implicit1.scala +++ b/tests/neg/missing-implicit1.scala @@ -7,7 +7,7 @@ object testObjectInstance with object instances { given zipOption: Zip[Option] = ??? given traverseList: Traverse[List] = ??? - given listExtension: [T](xs: List[T]) extended with + extension listExtension on [T](xs: List[T]) with def second: T = xs.tail.head def [T](xs: List[T]) first: T = xs.head } diff --git a/tests/neg/opaque-bounds.scala b/tests/neg/opaque-bounds.scala index 4755f58bd70b..acaebccbb6fb 100644 --- a/tests/neg/opaque-bounds.scala +++ b/tests/neg/opaque-bounds.scala @@ -21,8 +21,8 @@ object Access { def (x: Permissions) & (y: Permissions): Permissions = x & y def (x: PermissionChoice) | (y: PermissionChoice): PermissionChoice = x | y - def (x: Permissions) is (y: Permissions) = (x & y) == y - def (x: Permissions) isOneOf (y: PermissionChoice) = (x & y) != 0 + def (x: Permissions).is(y: Permissions) = (x & y) == y + def (x: Permissions).isOneOf(y: PermissionChoice) = (x & y) != 0 val NoPermission: Permission = 0 val ReadOnly: Permission = 1 diff --git a/tests/pos/combine.scala b/tests/pos/combine.scala index df69ac6bb3e9..7728b443c245 100644 --- a/tests/pos/combine.scala +++ b/tests/pos/combine.scala @@ -1,5 +1,5 @@ trait Semigroup[A] { - def (x: A) combine (y: A): A + def (x: A).combine(y: A): A } given Semigroup[Int] = ??? given [A, B]: Semigroup[A], Semigroup[B] => Semigroup[(A, B)] = ??? diff --git a/tests/pos/consume.scala b/tests/pos/consume.scala index e8d5e15be4a7..3f8b1fe36878 100644 --- a/tests/pos/consume.scala +++ b/tests/pos/consume.scala @@ -24,7 +24,7 @@ object math3 with trait Numeric[T] extends Ord[T] with def (x: T) + (y: T): T = ??? def (x: T) - (y: T): T = ??? - def (x: Int) numeric: T = ??? + def (x: Int).numeric: T = ??? end math3 object Test3 with diff --git a/tests/pos/i5773.scala b/tests/pos/i5773.scala index e799691a249d..76f1e491a63e 100644 --- a/tests/pos/i5773.scala +++ b/tests/pos/i5773.scala @@ -1,18 +1,18 @@ trait Semigroup[T] { - def (lhs: T) append (rhs: T): T + def (lhs: T).append(rhs: T): T } object Semigroup { implicit object stringAppend extends Semigroup[String] { - override def (lhs: String) append (rhs: String): String = lhs + rhs + override def (lhs: String).append(rhs: String): String = lhs + rhs } implicit def sumSemigroup[N](implicit N: Numeric[N]): Semigroup[N] = new { - override def (lhs: N) append (rhs: N): N = ??? // N.plus(lhs, rhs) + override def (lhs: N).append(rhs: N): N = ??? // N.plus(lhs, rhs) } implicit class SumSemiGroupDeco[N](implicit N: Numeric[N]) extends Semigroup[N] { - override def (lhs: N) append (rhs: N): N = ??? // N.plus(lhs, rhs) + override def (lhs: N).append(rhs: N): N = ??? // N.plus(lhs, rhs) } } @@ -26,7 +26,7 @@ object Main { def f2 = { implicit val intSumAppend: Semigroup[Int] = sumSemigroup[Int] - println(3 append 4) + println(3 append 4) } def f3 = { diff --git a/tests/pos/i5773a.scala b/tests/pos/i5773a.scala index 2071402609c3..801fa10f3f3f 100644 --- a/tests/pos/i5773a.scala +++ b/tests/pos/i5773a.scala @@ -1,12 +1,12 @@ trait Semigroup[T] { - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T } object Test { implicit val IntSemigroup: Semigroup[Int] = new { - def (x: Int) combine (y: Int): Int = x + y + def (x: Int).combine(y: Int): Int = x + y } implicit def OptionSemigroup[T: Semigroup]: Semigroup[Option[T]] = new { - def (x: Option[T]) combine (y: Option[T]): Option[T] = for { + def (x: Option[T]).combine(y: Option[T]): Option[T] = for { x0 <- x y0 <- y } yield x0.combine(y0) diff --git a/tests/pos/i6395.scala b/tests/pos/i6395.scala index 26faf3f52109..1e75d9ea42e7 100644 --- a/tests/pos/i6395.scala +++ b/tests/pos/i6395.scala @@ -1,5 +1,5 @@ object Foo { - inline def (self: Int) foo (that: Int): Int = 5 - def (self: Int) bar: Int = self + inline def (self: Int).foo(that: Int): Int = 5 + def (self: Int).bar: Int = self 1.foo(2).bar } \ No newline at end of file diff --git a/tests/pos/i6900.scala b/tests/pos/i6900.scala index 3c3b23c11b9f..71a3c0e3c1ac 100644 --- a/tests/pos/i6900.scala +++ b/tests/pos/i6900.scala @@ -21,7 +21,7 @@ object Test1 { object Test2 { // Works with extension method - given [A, C](a: A) extended with + extension on [A, C](a: A) with def foo: C => A = _ => a 1.foo.foo diff --git a/tests/pos/i7070.scala b/tests/pos/i7070.scala index 07b2fa7be9c4..0f65b8a3f418 100644 --- a/tests/pos/i7070.scala +++ b/tests/pos/i7070.scala @@ -2,7 +2,7 @@ object Test { class C - def (str: String) foo: (given C) => Int = ??? + def (str: String).foo: (given C) => Int = ??? given C = ??? diff --git a/tests/pos/i7084.scala b/tests/pos/i7084.scala index b76042ee431c..bb6ddb96428e 100644 --- a/tests/pos/i7084.scala +++ b/tests/pos/i7084.scala @@ -2,7 +2,7 @@ object Test { type Foo - given (y: Any) extended with { + extension on (y: Any) { def g(given Foo): Any = ??? } diff --git a/tests/pos/i7087.scala b/tests/pos/i7087.scala index c6340d61730f..8550ffd3e1aa 100644 --- a/tests/pos/i7087.scala +++ b/tests/pos/i7087.scala @@ -6,7 +6,7 @@ type F[T] = T match { case G[a] => String } -given [T](tup: T) extended with { +extension on [T](tup: T) { def g(given Foo: F[T]) = ??? } diff --git a/tests/pos/i7119.scala b/tests/pos/i7119.scala index 1911068bc52f..0124dafb155d 100644 --- a/tests/pos/i7119.scala +++ b/tests/pos/i7119.scala @@ -1,6 +1,6 @@ class Impl -def (impl: Impl) prop(given Int) = ???//summon[Int] +def (impl: Impl).prop(given Int) = ???//summon[Int] def main(args: Array[String]): Unit = { diff --git a/tests/pos/i7413.scala b/tests/pos/i7413.scala index 58c95529a8c2..cf0b9bec5eee 100644 --- a/tests/pos/i7413.scala +++ b/tests/pos/i7413.scala @@ -3,7 +3,7 @@ import scala.language.implicitConversions trait Fixture[A] extends Conversion[0, A] trait TestFramework[A] { - def (testName: String) in (test: (given Fixture[A]) => Unit): Unit = ??? + def (testName: String).in(test: (given Fixture[A]) => Unit): Unit = ??? } trait Greeter { diff --git a/tests/pos/i7700.scala b/tests/pos/i7700.scala index bdca41ff87ce..2c7a1f3a1ff9 100644 --- a/tests/pos/i7700.scala +++ b/tests/pos/i7700.scala @@ -4,7 +4,7 @@ trait Show[-A] with def show(a: A): String object Macros with - inline def (sc: StringContext) show(args: =>Any*): String = ??? + inline def (sc: StringContext).show(args: =>Any*): String = ??? object Show with def[A] (a: A) show(given S: Show[A]): String = S.show(a) diff --git a/tests/pos/implicit-scope.scala b/tests/pos/implicit-scope.scala index 813b6b42775f..5e013de27cda 100644 --- a/tests/pos/implicit-scope.scala +++ b/tests/pos/implicit-scope.scala @@ -9,7 +9,7 @@ object A { type FlagSet = opaques.FlagSet def FlagSet(bits: Long): FlagSet = opaques.FlagSet(bits) - given (xs: FlagSet) extended with { + extension on (xs: FlagSet) { def bits: Long = opaques.toBits(xs) def | (ys: FlagSet): FlagSet = FlagSet(xs.bits | ys.bits) } diff --git a/tests/pos/indent.scala b/tests/pos/indent.scala index c15a85cb4e82..1a562dab29e1 100644 --- a/tests/pos/indent.scala +++ b/tests/pos/indent.scala @@ -28,7 +28,7 @@ object Test 1 else 2 - def (x: Int) gt (y: Int) = x > y + def (x: Int).gt(y: Int) = x > y val y3 = if (1) max 10 gt 0 diff --git a/tests/pos/matrixOps.scala b/tests/pos/matrixOps.scala index 067d23830877..4d3d0891c604 100644 --- a/tests/pos/matrixOps.scala +++ b/tests/pos/matrixOps.scala @@ -3,7 +3,7 @@ object Test with type Matrix = Array[Array[Double]] type Vector = Array[Double] - given (m: Matrix) extended with + extension on (m: Matrix) with def nRows = m.length def nCols = m(0).length def row(i: Int): Vector = m(i) diff --git a/tests/pos/mirror-implicit-scope.scala b/tests/pos/mirror-implicit-scope.scala index a4c2dbcd7b3a..295fbcb61bde 100644 --- a/tests/pos/mirror-implicit-scope.scala +++ b/tests/pos/mirror-implicit-scope.scala @@ -3,14 +3,14 @@ import scala.deriving._ object Test { object K0 { type Generic[T] = Mirror { type Scope = K0.type ; type MirroredType = T ; type MirroredElemTypes } - given [T <: Product](gen: Generic[T]) extended with { + extension on [T <: Product](gen: Generic[T]) { inline def toRepr (t: T): gen.MirroredElemTypes = Tuple.fromProduct(t).asInstanceOf } } object K1 { type Generic[F[_]] = Mirror { type Scope = K1.type ; type MirroredType = F ; type MirroredElemTypes[_] } - given [F[_] <: Product, T](gen: Generic[F]) extended with { + extension on [F[_] <: Product, T](gen: Generic[F]) { inline def toRepr (t: F[T]): gen.MirroredElemTypes[T] = Tuple.fromProduct(t).asInstanceOf } } diff --git a/tests/pos/opaque-propability-xm.scala b/tests/pos/opaque-propability-xm.scala index 2025994eacbb..28b431e74a43 100644 --- a/tests/pos/opaque-propability-xm.scala +++ b/tests/pos/opaque-propability-xm.scala @@ -19,17 +19,17 @@ object prob { implicit val ordering: Ordering[Probability] = implicitly[Ordering[Double]] - def (p1: Probability) unary_~ : Probability = Certain - p1 + def (p1: Probability).unary_~ : Probability = Certain - p1 def (p1: Probability) & (p2: Probability): Probability = p1 * p2 def (p1: Probability) | (p2: Probability): Probability = p1 + p2 - (p1 * p2) - def (p1: Probability) isImpossible: Boolean = p1 == Never - def (p1: Probability) isCertain: Boolean = p1 == Certain + def (p1: Probability).isImpossible: Boolean = p1 == Never + def (p1: Probability).isCertain: Boolean = p1 == Certain import scala.util.Random - def (p1: Probability) sample (r: Random = Random): Boolean = r.nextDouble <= p1 - def (p1: Probability) toDouble: Double = p1 + def (p1: Probability).sample(r: Random = Random): Boolean = r.nextDouble <= p1 + def (p1: Probability).toDouble: Double = p1 } val caughtTrain = Probability.unsafe(0.3) diff --git a/tests/pos/opaque-xm.scala b/tests/pos/opaque-xm.scala index 2a936787219d..a8619c287f58 100644 --- a/tests/pos/opaque-xm.scala +++ b/tests/pos/opaque-xm.scala @@ -16,7 +16,7 @@ object opaquetypes { // Extension methods define opaque types' public APIs // This is the second way to unlift the logarithm type - def (x: Logarithm) toDouble: Double = math.exp(x) + def (x: Logarithm).toDouble: Double = math.exp(x) def (x: Logarithm) + (y: Logarithm) = Logarithm(math.exp(x) + math.exp(y)) def (x: Logarithm) * (y: Logarithm): Logarithm = Logarithm(x + y) } diff --git a/tests/pos/reference/delegates.scala b/tests/pos/reference/delegates.scala index 71303fc14513..5bafa162bc20 100644 --- a/tests/pos/reference/delegates.scala +++ b/tests/pos/reference/delegates.scala @@ -1,15 +1,15 @@ class Common with trait Ord[T] with - def (x: T) compareTo (y: T): Int + 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 - def (x: From) convert: To + def (x: From).convert: To trait SemiGroup[T] with - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T trait Monoid[T] extends SemiGroup[T] with def unit: T @@ -26,11 +26,11 @@ class Common with object Instances extends Common with given intOrd: Ord[Int] with - def (x: Int) compareTo (y: 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 - def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match + def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 case (_, Nil) => +1 @@ -39,12 +39,12 @@ object Instances extends Common with if (fst != 0) fst else xs1.compareTo(ys1) end listOrd - given stringOps: (xs: Seq[String]) extended with + extension stringOps on (xs: Seq[String]) with def longestStrings: Seq[String] = val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) - given [T](xs: List[T]) extended with + extension on [T](xs: List[T]) with def second = xs.tail.head def third = xs.tail.tail.head @@ -64,7 +64,7 @@ object Instances extends Common with xs.reduceLeft((x, y) => if (x < y) y else x) def descending[T](given asc: Ord[T]): Ord[T] = new Ord[T] with - def (x: T) compareTo (y: T) = asc.compareTo(y)(x) + def (x: T).compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(given Ord[T]) = maximum(xs)(given descending) @@ -87,14 +87,14 @@ object Instances extends Common with trait TastyAPI with type Symbol trait SymDeco with - def (sym: Symbol) name: String + def (sym: Symbol).name: String def symDeco: SymDeco given SymDeco = symDeco object TastyImpl extends TastyAPI with type Symbol = String val symDeco = new SymDeco with - def (sym: Symbol) name = sym + def (sym: Symbol).name = sym class D[T] @@ -133,7 +133,7 @@ object PostConditions with def result[T](given x: WrappedResult[T]): T = x - given [T](x: T) extended with + extension on [T](x: T) with def ensuring(condition: (given WrappedResult[T]) => Boolean): T = assert(condition(given x)) x @@ -141,11 +141,11 @@ end PostConditions object AnonymousInstances extends Common with given Ord[Int] with - def (x: Int) compareTo (y: 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 - def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match + def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 case (_, Nil) => +1 @@ -153,19 +153,19 @@ object AnonymousInstances extends Common with val fst = x.compareTo(y) if (fst != 0) fst else xs1.compareTo(ys1) - given (xs: Seq[String]) extended with + extension on (xs: Seq[String]) with def longestStrings: Seq[String] = val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) - given [T](xs: List[T]) extended with + extension on [T](xs: List[T]) with def second = xs.tail.head given [From, To]: (c: Convertible[From, To]) => Convertible[List[From], List[To]] with - def (x: List[From]) convert: List[To] = x.map(c.convert) + def (x: List[From]).convert: List[To] = x.map(c.convert) given Monoid[String] with - def (x: String) combine (y: String): String = x.concat(y) + def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" def sum[T: Monoid](xs: List[T]): T = @@ -174,11 +174,11 @@ end AnonymousInstances object Implicits extends Common with implicit object IntOrd extends Ord[Int] with - def (x: Int) compareTo (y: 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 - def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match + def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 case (_, Nil) => +1 @@ -189,7 +189,7 @@ object Implicits extends Common with class given_Convertible_List_List[From, To](implicit c: Convertible[From, To]) extends Convertible[List[From], List[To]] with - def (x: List[From]) convert: List[To] = x.map(c.convert) + 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]] = new given_Convertible_List_List[From, To] @@ -199,7 +199,7 @@ object Implicits extends Common with xs.reduceLeft((x, y) => if (x < y) y else x) def descending[T](implicit asc: Ord[T]): Ord[T] = new Ord[T] with - def (x: T) compareTo (y: T) = asc.compareTo(y)(x) + def (x: T).compareTo(y: T) = asc.compareTo(y)(x) def minimum[T](xs: List[T])(implicit cmp: Ord[T]) = maximum(xs)(descending) diff --git a/tests/pos/reference/extension-methods.scala b/tests/pos/reference/extension-methods.scala index d8e3d566a615..d70104184d5d 100644 --- a/tests/pos/reference/extension-methods.scala +++ b/tests/pos/reference/extension-methods.scala @@ -2,14 +2,14 @@ object ExtMethods with case class Circle(x: Double, y: Double, radius: Double) - def (c: Circle) circumference: Double = c.radius * math.Pi * 2 + def (c: Circle).circumference: Double = c.radius * math.Pi * 2 val circle = Circle(0, 0, 1) circle.circumference assert(circle.circumference == circumference(circle)) trait StringSeqOps { - def (xs: Seq[String]) longestStrings = { + def (xs: Seq[String]).longestStrings = { val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) } @@ -41,23 +41,23 @@ object ExtMethods with List(1, 2, 3).second[Int] - given stringOps: (xs: Seq[String]) extended with { + extension stringOps on (xs: Seq[String]) { def longestStrings: Seq[String] = { val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) } } - given listOps: [T](xs: List[T]) extended with + extension listOps on [T](xs: List[T]) with def second = xs.tail.head def third: T = xs.tail.tail.head - given [T](xs: List[T])(given Ordering[T]) extended with + extension on [T](xs: List[T])(given Ordering[T]) with def largest(n: Int) = xs.sorted.takeRight(n) given stringOps1: AnyRef { - def (xs: Seq[String]) longestStrings: Seq[String] = { + def (xs: Seq[String]).longestStrings: Seq[String] = { val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) } diff --git a/tests/pos/reference/opaque.scala b/tests/pos/reference/opaque.scala index 617fbbe17b2d..69ce019b6aee 100644 --- a/tests/pos/reference/opaque.scala +++ b/tests/pos/reference/opaque.scala @@ -12,7 +12,7 @@ object Logarithms { } // Extension methods define opaque types' public APIs - given (x: Logarithm) extended with { + extension on (x: Logarithm) { def toDouble: Double = math.exp(x) def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y)) def * (y: Logarithm): Logarithm = Logarithm(x + y) @@ -38,8 +38,8 @@ object Access { def (x: Permissions) & (y: Permissions): Permissions = x & y def (x: PermissionChoice) | (y: PermissionChoice): PermissionChoice = x | y - def (x: Permissions) is (y: Permissions) = (x & y) == y - def (x: Permissions) isOneOf (y: PermissionChoice) = (x & y) != 0 + def (x: Permissions).is(y: Permissions) = (x & y) == y + def (x: Permissions).isOneOf(y: PermissionChoice) = (x & y) != 0 val NoPermission: Permission = 0 val ReadOnly: Permission = 1 diff --git a/tests/pos/tasty-reflect-opaque-api-proto.scala b/tests/pos/tasty-reflect-opaque-api-proto.scala index 089e3c28437d..563a43598e61 100644 --- a/tests/pos/tasty-reflect-opaque-api-proto.scala +++ b/tests/pos/tasty-reflect-opaque-api-proto.scala @@ -10,7 +10,7 @@ class Reflect(val internal: CompilerInterface) { opaque type Term <: Tree = internal.Term object Tree { - given ops: (tree: Tree) extended with { + extension ops on (tree: Tree) { def show: String = ??? } } diff --git a/tests/pos/toplevel-opaque-xm/Logarithm_1.scala b/tests/pos/toplevel-opaque-xm/Logarithm_1.scala index 88f280a7f4a1..c9e4e439713b 100644 --- a/tests/pos/toplevel-opaque-xm/Logarithm_1.scala +++ b/tests/pos/toplevel-opaque-xm/Logarithm_1.scala @@ -16,7 +16,7 @@ implicit object Logarithm { // Extension methods define opaque types' public APIs // This is the second way to unlift the logarithm type - def (x: Logarithm) toDouble: Double = math.exp(x) + def (x: Logarithm).toDouble: Double = math.exp(x) def (x: Logarithm) + (y: Logarithm) = Logarithm(math.exp(x) + math.exp(y)) def (x: Logarithm) * (y: Logarithm): Logarithm = Logarithm(x + y) } diff --git a/tests/run-macros/f-interpolator-neg/Macros_1.scala b/tests/run-macros/f-interpolator-neg/Macros_1.scala index 8a852f3a3e4c..d21875d53c98 100644 --- a/tests/run-macros/f-interpolator-neg/Macros_1.scala +++ b/tests/run-macros/f-interpolator-neg/Macros_1.scala @@ -6,7 +6,7 @@ import scala.language.implicitConversions object TestFooErrors { // Defined in tests implicit object StringContextOps { - inline def (ctx: => StringContext) foo (args: => Any*): List[(Boolean, Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } + inline def (ctx: => StringContext).foo(args: => Any*): List[(Boolean, Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) } } } diff --git a/tests/run/Pouring.scala b/tests/run/Pouring.scala index b61d54bf1a3f..add83608862a 100644 --- a/tests/run/Pouring.scala +++ b/tests/run/Pouring.scala @@ -8,7 +8,7 @@ class Pouring(capacity: Vector[Int]) with case Fill(g) => content.updated(g, capacity(g)) case Pour(from, to) => val amount = content(from) min (capacity(to) - content(to)) - def (s: Content) adjust (g: Glass, delta: Int) = s.updated(g, s(g) + delta) + def (s: Content).adjust(g: Glass, delta: Int) = s.updated(g, s(g) + delta) content.adjust(from, -amount).adjust(to, amount) case Empty(glass: Glass) diff --git a/tests/run/eq-xmethod.scala b/tests/run/eq-xmethod.scala index 6e9bfa5dd855..5231063bf62b 100644 --- a/tests/run/eq-xmethod.scala +++ b/tests/run/eq-xmethod.scala @@ -6,7 +6,7 @@ object Test extends App { class N object N extends N - def (x: N) _eq (y: R | N) = y eq N + def (x: N)._eq(y: R | N) = y eq N val r1, r2 = new R assert(r1 _eq r1) diff --git a/tests/run/exports.scala b/tests/run/exports.scala index fe978ea2f375..54ca2235fee7 100644 --- a/tests/run/exports.scala +++ b/tests/run/exports.scala @@ -12,7 +12,7 @@ object Test extends App { class Scanner { def scan() = println("scanning") - def (x: Any) scanned = scan() + def (x: Any).scanned = scan() } object Scanner extends Scanner diff --git a/tests/run/extension-methods.scala b/tests/run/extension-methods.scala index 538b7bd7dffa..82552aaf9e82 100644 --- a/tests/run/extension-methods.scala +++ b/tests/run/extension-methods.scala @@ -1,18 +1,18 @@ object Test extends App { - def (x: Int) em: Boolean = x > 0 + def (x: Int).em: Boolean = x > 0 assert(1.em == em(1)) case class Circle(x: Double, y: Double, radius: Double) - def (c: Circle) circumference: Double = c.radius * math.Pi * 2 + def (c: Circle).circumference: Double = c.radius * math.Pi * 2 val circle = new Circle(1, 1, 2.0) assert(circle.circumference == circumference(circle)) - def (xs: Seq[String]) longestStrings: Seq[String] = { + def (xs: Seq[String]).longestStrings: Seq[String] = { val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) } @@ -29,7 +29,7 @@ object Test extends App { assert(Nil.flattened == Nil) trait SemiGroup[T] { - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T } trait Monoid[T] extends SemiGroup[T] { def unit: T @@ -37,7 +37,7 @@ object Test extends App { // An instance declaration: implicit object StringMonoid extends Monoid[String] { - def (x: String) combine (y: String): String = x.concat(y) + def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" } @@ -48,14 +48,14 @@ object Test extends App { println(sum(names)) trait Ord[T] { - def (x: T) compareTo (y: T): Int + 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 } implicit object IntOrd extends Ord[Int] { - def (x: Int) compareTo (y: Int) = + def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 val minimum = Int.MinValue } diff --git a/tests/run/extension-specificity.scala b/tests/run/extension-specificity.scala index 35ac40ff1e3a..ce62c1244d8f 100644 --- a/tests/run/extension-specificity.scala +++ b/tests/run/extension-specificity.scala @@ -1,10 +1,10 @@ class A class B extends A -given a: (x: A) extended with +extension a on (x: A) with def foo: Int = 1 -given b: (x: B) extended with +extension b on (x: B) with def foo: Int = 2 @main def Test = diff --git a/tests/run/extmethod-overload.scala b/tests/run/extmethod-overload.scala index fe80ccebf54a..463cee98cc6e 100644 --- a/tests/run/extmethod-overload.scala +++ b/tests/run/extmethod-overload.scala @@ -88,16 +88,16 @@ object Test extends App { class C { def xx (x: Any) = 2 } - def (c: C) xx (x: Int) = 1 + def (c: C).xx(x: Int) = 1 val c = new C assert(c.xx(1) == 2) // member method takes precedence object D { - def (x: Int) yy (y: Int) = x + y + def (x: Int).yy(y: Int) = x + y } - given (x: Int) extended with { + extension on (x: Int) { def yy (y: Int) = x - y } @@ -114,8 +114,8 @@ object Test extends App { def b: Long = a } - def (rectangle: Rectangle) area: Long = 0 - def (square: Square) area: Long = square.a * square.a + def (rectangle: Rectangle).area: Long = 0 + def (square: Square).area: Long = square.a * square.a val rectangles = List(GenericRectangle(2, 3), Square(5)) val areas = rectangles.map(_.area) assert(areas.sum == 0) diff --git a/tests/run/extmethods2.scala b/tests/run/extmethods2.scala index 9ed54f3a39b7..a45a4b5abfdd 100644 --- a/tests/run/extmethods2.scala +++ b/tests/run/extmethods2.scala @@ -4,8 +4,8 @@ object Test extends App { given stringListOps: TC => Object { type T = List[String] - def (x: T) foo (y: T) = (x ++ y, summon[TC]) - def (x: T) bar (y: Int) = (x(0)(y), summon[TC]) + def (x: T).foo(y: T) = (x ++ y, summon[TC]) + def (x: T).bar(y: Int) = (x(0)(y), summon[TC]) } def test(given TC) = { @@ -16,15 +16,15 @@ object Test extends App { test(given TC()) object A { - given listOps: [T](xs: List[T]) extended with { + extension listOps on [T](xs: List[T]) { def second: T = xs.tail.head def third: T = xs.tail.tail.head def concat(ys: List[T]) = xs ++ ys } - given polyListOps: [T, U](xs: List[T]) extended with { + extension polyListOps on [T, U](xs: List[T]) { def zipp(ys: List[U]): List[(T, U)] = xs.zip(ys) } - given (xs: List[Int]) extended with { + extension on (xs: List[Int]) { def prod = (1 /: xs)(_ * _) } } diff --git a/tests/run/i6902.scala b/tests/run/i6902.scala index e3a40dd02f1e..18729d1df937 100644 --- a/tests/run/i6902.scala +++ b/tests/run/i6902.scala @@ -1,6 +1,6 @@ object Test { - given [A](a: A) extended with { def <<< : A = a } - given (b: Int) extended with { def <<<< : Int = b } + extension on [A](a: A) { def <<< : A = a } + extension on (b: Int) { def <<<< : Int = b } def main(args: Array[String]): Unit = { 1.<<< diff --git a/tests/run/instances-anonymous.scala b/tests/run/instances-anonymous.scala index 4d4774e98bf1..986e81980d90 100644 --- a/tests/run/instances-anonymous.scala +++ b/tests/run/instances-anonymous.scala @@ -1,14 +1,14 @@ object Test extends App { implicit object O { - def (x: Int) em: Boolean = x > 0 + def (x: Int).em: Boolean = x > 0 } assert(1.em == O.em(1)) case class Circle(x: Double, y: Double, radius: Double) - given (c: Circle) extended with { + extension on (c: Circle) { def circumference: Double = c.radius * math.Pi * 2 } @@ -17,7 +17,7 @@ object Test extends App { println(circle.circumference) given AnyRef { - def (xs: Seq[String]) longestStrings: Seq[String] = { + def (xs: Seq[String]).longestStrings: Seq[String] = { val maxLength = xs.map(_.length).max xs.filter(_.length == maxLength) } @@ -25,13 +25,13 @@ object Test extends App { val names = List("hi", "hello", "world") assert(names.longestStrings == List("hello", "world")) - given [T](xs: Seq[T]) extended with { + extension on [T](xs: Seq[T]) { def second = xs.tail.head } assert(names.longestStrings.second == "world") - given [T](xs: List[List[T]]) extended with { + extension on [T](xs: List[List[T]]) { def flattened = xs.foldLeft[List[T]](Nil)(_ ++ _) } @@ -39,14 +39,14 @@ object Test extends App { assert(Nil.flattened == Nil) trait SemiGroup[T] { - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T } trait Monoid[T] extends SemiGroup[T] { def unit: T } given Monoid[String] { - def (x: String) combine (y: String): String = x.concat(y) + def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" } @@ -57,20 +57,20 @@ object Test extends App { println(sum(names)) trait Ord[T] { - def (x: T) compareTo (y: T): Int + 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 } given Ord[Int] { - def (x: Int) compareTo (y: Int) = + def (x: Int).compareTo(y: Int) = if (x < y) -1 else if (x > y) +1 else 0 val minimum = Int.MinValue } given [T: Ord] : Ord[List[T]] { - def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match { + def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match { case (Nil, Nil) => 0 case (Nil, _) => -1 case (_, Nil) => +1 diff --git a/tests/run/instances.scala b/tests/run/instances.scala index 0778d8a4fed5..7a197b38496c 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -1,21 +1,21 @@ object Test extends App { implicit object O { - def (x: Int) em: Boolean = x > 0 + def (x: Int).em: Boolean = x > 0 } assert(1.em == O.em(1)) case class Circle(x: Double, y: Double, radius: Double) - given circleOps: (c: Circle) extended with + extension circleOps on (c: Circle) with def circumference: Double = c.radius * math.Pi * 2 val circle = new Circle(1, 1, 2.0) assert(circle.circumference == circleOps.circumference(circle)) - given stringOps: (xs: Seq[String]) extended with + extension stringOps on (xs: Seq[String]) with 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")) - given [T](xs: Seq[T]) extended with + extension on [T](xs: Seq[T]) with def second = xs.tail.head assert(names.longestStrings.second == "world") - given listListOps: [T](xs: List[List[T]]) extended with + extension listListOps on [T](xs: List[List[T]]) with def flattened = xs.foldLeft[List[T]](Nil)(_ ++ _) // A right associative op. Note: can't use given extension for this! @@ -44,13 +44,13 @@ object Test extends App { assert(Nil.flattened == Nil) trait SemiGroup[T] with - def (x: T) combine (y: T): T + def (x: T).combine(y: T): T trait Monoid[T] extends SemiGroup[T] with def unit: T given StringMonoid : Monoid[String] with - def (x: String) combine (y: String): String = x.concat(y) + def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" // Abstracting over a typeclass with a context bound: @@ -60,19 +60,19 @@ object Test extends App { println(sum(names)) trait Ord[T] with - def (x: T) compareTo (y: T): Int + 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 - def (x: Int) compareTo (y: 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 - def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match + def (xs: List[T]).compareTo(ys: List[T]): Int = (xs, ys).match case (Nil, Nil) => 0 case (Nil, _) => -1 case (_, Nil) => +1 diff --git a/tests/run/string-context-implicits-with-conversion.scala b/tests/run/string-context-implicits-with-conversion.scala index 4f3e3eb5d314..f72d96989c3a 100644 --- a/tests/run/string-context-implicits-with-conversion.scala +++ b/tests/run/string-context-implicits-with-conversion.scala @@ -1,6 +1,6 @@ object Lib { - def (sc: StringContext) showMe(args: Showed*): String = sc.s(args: _*) + def (sc: StringContext).showMe(args: Showed*): String = sc.s(args: _*) opaque type Showed = String diff --git a/tests/run/toplevel-implicits/a.b.scala b/tests/run/toplevel-implicits/a.b.scala index bfa0051d546a..a360f4d6e491 100644 --- a/tests/run/toplevel-implicits/a.b.scala +++ b/tests/run/toplevel-implicits/a.b.scala @@ -3,7 +3,7 @@ package implicits case class C() implicit object Cops { - def (x: C) pair (y: C) = (x, y) + def (x: C).pair(y: C) = (x, y) } class D { diff --git a/tests/semanticdb/expect/Enums.expect.scala b/tests/semanticdb/expect/Enums.expect.scala index 47e3d493ba28..5e4fdccc826d 100644 --- a/tests/semanticdb/expect/Enums.expect.scala +++ b/tests/semanticdb/expect/Enums.expect.scala @@ -12,10 +12,10 @@ object Enums/*<-_empty_::Enums.*/ with 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 - def (suit/*<-_empty_::Enums.Suits.isRed().*//*<-_empty_::Enums.Suits.isRed().(suit)*/: Suits/*->_empty_::Enums.Suits#*/) isRed: Boolean/*->scala::Boolean#*/ = + 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.*/ - def (suit: /*<-_empty_::Enums.Suits.isBlack().*//*<-_empty_::Enums.Suits.isBlack().(suit)*/Suits/*->_empty_::Enums.Suits#*/) isBlack: Boolean/*->scala::Boolean#*/ = suit/*->_empty_::Enums.Suits.isBlack().(suit)*/ match + def (suit: /*<-_empty_::Enums.Suits.isBlack().*//*<-_empty_::Enums.Suits.isBlack().(suit)*/Suits/*->_empty_::Enums.Suits#*/).isBlack: Boolean/*->scala::Boolean#*/ = suit/*->_empty_::Enums.Suits.isBlack().(suit)*/ match case Spades/*->_empty_::Enums.Suits.Spades.*/ | Diamonds/*->_empty_::Enums.Suits.Diamonds.*/ => true case _ => false diff --git a/tests/semanticdb/expect/Enums.scala b/tests/semanticdb/expect/Enums.scala index 28f2a8a4372e..6ccd2a1fdf8d 100644 --- a/tests/semanticdb/expect/Enums.scala +++ b/tests/semanticdb/expect/Enums.scala @@ -12,10 +12,10 @@ object Enums with case Hearts, Spades, Clubs, Diamonds object Suits with - def (suit: Suits) isRed: Boolean = + def (suit: Suits).isRed: Boolean = suit == Hearts || suit == Diamonds - def (suit: Suits) isBlack: Boolean = suit match + def (suit: Suits).isBlack: Boolean = suit match case Spades | Diamonds => true case _ => false diff --git a/tests/semanticdb/expect/Givens.expect.scala b/tests/semanticdb/expect/Givens.expect.scala index d827c41f7e86..433e1fe1ec96 100644 --- a/tests/semanticdb/expect/Givens.expect.scala +++ b/tests/semanticdb/expect/Givens.expect.scala @@ -3,24 +3,24 @@ package b object Givens/*<-a::b::Givens.*/ - given extension [A](any: /*<-a::b::Givens.given_sayHello_of_A.*//*<-a::b::Givens.given_sayHello_of_A.sayHello().[A]*//*<-a::b::Givens.given_sayHello_of_A.sayHello().(any)*/A/*->a::b::Givens.given_sayHello_of_A.sayHello().[A]*/) - def sayHello/*<-a::b::Givens.given_sayHello_of_A.sayHello().*/ = s"/*->scala::StringContext.apply().*/Hello, I am $any/*->a::b::Givens.given_sayHello_of_A.sayHello().(any)*//*->scala::StringContext#s().*/" + given extension [A](any: A/*<-a::b::Givens.extension_sayHello_A.*//*<-a::b::Givens.extension_sayHello_A.sayHello().[A]*//*<-a::b::Givens.extension_sayHello_A.sayHello().(any)*//*->a::b::Givens.extension_sayHello_A.sayHello().[A]*/) + def sayHello/*<-a::b::Givens.extension_sayHello_A.sayHello().*/ = s"/*->scala::StringContext.apply().*/Hello, I am $any/*->a::b::Givens.extension_sayHello_A.sayHello().(any)*//*->scala::StringContext#s().*/" - given extension [B](any: B)/*<-a::b::Givens.given_sayGoodbye_of_B.*//*<-a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().[B]*//*<-a::b::Givens.given_sayGoodbye_of_B.saySoLong().[B]*//*<-a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().(any)*//*<-a::b::Givens.given_sayGoodbye_of_B.saySoLong().(any)*//*->a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().[B]*//*->a::b::Givens.given_sayGoodbye_of_B.saySoLong().[B]*/ - def sayGoodbye/*<-a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().*/ = s"/*->scala::StringContext.apply().*/Goodbye, from $any/*->a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().(any)*//*->scala::StringContext#s().*/" - def saySoLong/*<-a::b::Givens.given_sayGoodbye_of_B.saySoLong().*/ = s"/*->scala::StringContext.apply().*/So Long, from $any/*->a::b::Givens.given_sayGoodbye_of_B.saySoLong().(any)*//*->scala::StringContext#s().*/" + given extension [B](any: B) +/*<-a::b::Givens.extension_sayGoodbye_B.*//*<-a::b::Givens.extension_sayGoodbye_B.sayGoodbye().[B]*//*<-a::b::Givens.extension_sayGoodbye_B.saySoLong().[B]*//*<-a::b::Givens.extension_sayGoodbye_B.sayGoodbye().(any)*//*<-a::b::Givens.extension_sayGoodbye_B.saySoLong().(any)*//*->a::b::Givens.extension_sayGoodbye_B.sayGoodbye().[B]*//*->a::b::Givens.extension_sayGoodbye_B.saySoLong().[B]*/ def sayGoodbye/*<-a::b::Givens.extension_sayGoodbye_B.sayGoodbye().*/ = s"/*->scala::StringContext.apply().*/Goodbye, from $any/*->a::b::Givens.extension_sayGoodbye_B.sayGoodbye().(any)*//*->scala::StringContext#s().*/" + def saySoLong/*<-a::b::Givens.extension_sayGoodbye_B.saySoLong().*/ = s"/*->scala::StringContext.apply().*/So Long, from $any/*->a::b::Givens.extension_sayGoodbye_B.saySoLong().(any)*//*->scala::StringContext#s().*/" - val hello1/*<-a::b::Givens.hello1.*/ = /*->a::b::Givens.given_sayHello_of_A.sayHello().*/1.sayHello - val goodbye1/*<-a::b::Givens.goodbye1.*/ = /*->a::b::Givens.given_sayGoodbye_of_B.sayGoodbye().*/1.sayGoodbye - val soLong1/*<-a::b::Givens.soLong1.*/ = /*->a::b::Givens.given_sayGoodbye_of_B.saySoLong().*/1.saySoLong + val hello1/*<-a::b::Givens.hello1.*/ = /*->a::b::Givens.extension_sayHello_A.sayHello().*/1.sayHello + val goodbye1/*<-a::b::Givens.goodbye1.*/ = /*->a::b::Givens.extension_sayGoodbye_B.sayGoodbye().*/1.sayGoodbye + val soLong1/*<-a::b::Givens.soLong1.*/ = /*->a::b::Givens.extension_sayGoodbye_B.saySoLong().*/1.saySoLong trait Monoid/*<-a::b::Givens.Monoid#*/[A/*<-a::b::Givens.Monoid#[A]*/] def empty/*<-a::b::Givens.Monoid#empty().*/: A/*->a::b::Givens.Monoid#[A]*/ - def (x: A) /*<-a::b::Givens.Monoid#combine().*//*<-a::b::Givens.Monoid#combine().(x)*//*->a::b::Givens.Monoid#[A]*/combine (y/*<-a::b::Givens.Monoid#combine().(y)*/: A/*->a::b::Givens.Monoid#[A]*/): A/*->a::b::Givens.Monoid#[A]*/ + def (x: A)./*<-a::b::Givens.Monoid#combine().*//*<-a::b::Givens.Monoid#combine().(x)*//*->a::b::Givens.Monoid#[A]*/combine(y/*<-a::b::Givens.Monoid#combine().(y)*/: A/*->a::b::Givens.Monoid#[A]*/): A/*->a::b::Givens.Monoid#[A]*/ given Monoid[String] /*<-a::b::Givens.given_Monoid_String.*//*->a::b::Givens.Monoid#*//*->scala::Predef.String#*/def empty/*<-a::b::Givens.given_Monoid_String.empty().*/ = "" - def (x: Str/*<-a::b::Givens.given_Monoid_String.combine().*//*<-a::b::Givens.given_Monoid_String.combine().(x)*/ing/*->scala::Predef.String#*/) combine (y/*<-a::b::Givens.given_Monoid_String.combine().(y)*/: String/*->scala::Predef.String#*/) = x/*->a::b::Givens.given_Monoid_String.combine().(x)*/ +/*->java::lang::String#`+`().*/ y/*->a::b::Givens.given_Monoid_String.combine().(y)*/ + def (x: Str/*<-a::b::Givens.given_Monoid_String.combine().*//*<-a::b::Givens.given_Monoid_String.combine().(x)*/ing/*->scala::Predef.String#*/).combine(y/*<-a::b::Givens.given_Monoid_String.combine().(y)*/: String/*->scala::Predef.String#*/) = x/*->a::b::Givens.given_Monoid_String.combine().(x)*/ +/*->java::lang::String#`+`().*/ y/*->a::b::Givens.given_Monoid_String.combine().(y)*/ inline given int2String/*<-a::b::Givens.int2String().*/: Conversion/*->scala::Conversion#*/[Int/*->scala::Int#*/, String/*->scala::Predef.String#*/] = _.toString/*->scala::Any#toString().*/ diff --git a/tests/semanticdb/expect/Givens.scala b/tests/semanticdb/expect/Givens.scala index 9460d5cba0fd..b5b5548a0b00 100644 --- a/tests/semanticdb/expect/Givens.scala +++ b/tests/semanticdb/expect/Givens.scala @@ -16,11 +16,11 @@ object Givens trait Monoid[A] def empty: A - def (x: A) combine (y: A): A + def (x: A).combine(y: A): A given Monoid[String] def empty = "" - def (x: String) combine (y: String) = x + y + def (x: String).combine(y: String) = x + y inline given int2String: Conversion[Int, String] = _.toString diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 23fce826a326..7b59a7ccb38b 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -1280,6 +1280,17 @@ a/b/Givens.Monoid#combine(). => abstract method combine a/b/Givens.Monoid#combine().(x) => param x a/b/Givens.Monoid#combine().(y) => param y a/b/Givens.Monoid#empty(). => abstract method empty +a/b/Givens.extension_sayGoodbye_B. => final implicit object extension_sayGoodbye_B +a/b/Givens.extension_sayGoodbye_B.sayGoodbye(). => method sayGoodbye +a/b/Givens.extension_sayGoodbye_B.sayGoodbye().(any) => param any +a/b/Givens.extension_sayGoodbye_B.sayGoodbye().[B] => typeparam B +a/b/Givens.extension_sayGoodbye_B.saySoLong(). => method saySoLong +a/b/Givens.extension_sayGoodbye_B.saySoLong().(any) => param any +a/b/Givens.extension_sayGoodbye_B.saySoLong().[B] => typeparam B +a/b/Givens.extension_sayHello_A. => final implicit object extension_sayHello_A +a/b/Givens.extension_sayHello_A.sayHello(). => method sayHello +a/b/Givens.extension_sayHello_A.sayHello().(any) => param any +a/b/Givens.extension_sayHello_A.sayHello().[A] => typeparam A a/b/Givens.foo(). => method foo a/b/Givens.foo().(A) => implicit param A a/b/Givens.foo().[A] => typeparam A @@ -1288,17 +1299,6 @@ a/b/Givens.given_Monoid_String.combine(). => method combine a/b/Givens.given_Monoid_String.combine().(x) => param x a/b/Givens.given_Monoid_String.combine().(y) => param y a/b/Givens.given_Monoid_String.empty(). => method empty -a/b/Givens.given_sayGoodbye_of_B. => final implicit object given_sayGoodbye_of_B -a/b/Givens.given_sayGoodbye_of_B.sayGoodbye(). => method sayGoodbye -a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().(any) => param any -a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().[B] => typeparam B -a/b/Givens.given_sayGoodbye_of_B.saySoLong(). => method saySoLong -a/b/Givens.given_sayGoodbye_of_B.saySoLong().(any) => param any -a/b/Givens.given_sayGoodbye_of_B.saySoLong().[B] => typeparam B -a/b/Givens.given_sayHello_of_A. => final implicit object given_sayHello_of_A -a/b/Givens.given_sayHello_of_A.sayHello(). => method sayHello -a/b/Givens.given_sayHello_of_A.sayHello().(any) => param any -a/b/Givens.given_sayHello_of_A.sayHello().[A] => typeparam A a/b/Givens.goodbye1. => val method goodbye1 a/b/Givens.hello1. => val method hello1 a/b/Givens.int2String(). => final implicit macro int2String @@ -1308,46 +1308,46 @@ Occurrences: [0:8..0:9): a <- a/ [1:8..1:9): b <- a/b/ [3:7..3:13): Givens <- a/b/Givens. -[5:8..5:27): extension [A](any: <- a/b/Givens.given_sayHello_of_A. -[5:19..5:20): A <- a/b/Givens.given_sayHello_of_A.sayHello().[A] -[5:22..5:25): any <- a/b/Givens.given_sayHello_of_A.sayHello().(any) -[5:27..5:28): A -> a/b/Givens.given_sayHello_of_A.sayHello().[A] -[6:8..6:16): sayHello <- a/b/Givens.given_sayHello_of_A.sayHello(). +[5:8..5:28): extension [A](any: A <- a/b/Givens.extension_sayHello_A. +[5:19..5:20): A <- a/b/Givens.extension_sayHello_A.sayHello().[A] +[5:22..5:25): any <- a/b/Givens.extension_sayHello_A.sayHello().(any) +[5:27..5:28): A -> a/b/Givens.extension_sayHello_A.sayHello().[A] +[6:8..6:16): sayHello <- a/b/Givens.extension_sayHello_A.sayHello(). [6:21..6:21): -> scala/StringContext.apply(). -[6:34..6:37): any -> a/b/Givens.given_sayHello_of_A.sayHello().(any) +[6:34..6:37): any -> a/b/Givens.extension_sayHello_A.sayHello().(any) [6:37..6:37): -> scala/StringContext#s(). -[8:8..8:29): extension [B](any: B) <- a/b/Givens.given_sayGoodbye_of_B. -[8:19..8:20): B <- a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().[B] -[8:19..8:20): B <- a/b/Givens.given_sayGoodbye_of_B.saySoLong().[B] -[8:22..8:25): any <- a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().(any) -[8:22..8:25): any <- a/b/Givens.given_sayGoodbye_of_B.saySoLong().(any) -[8:27..8:28): B -> a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().[B] -[8:27..8:28): B -> a/b/Givens.given_sayGoodbye_of_B.saySoLong().[B] -[9:8..9:18): sayGoodbye <- a/b/Givens.given_sayGoodbye_of_B.sayGoodbye(). +[8:8..9:0): <- a/b/Givens.extension_sayGoodbye_B. +[8:19..8:20): B <- a/b/Givens.extension_sayGoodbye_B.sayGoodbye().[B] +[8:19..8:20): B <- a/b/Givens.extension_sayGoodbye_B.saySoLong().[B] +[8:22..8:25): any <- a/b/Givens.extension_sayGoodbye_B.sayGoodbye().(any) +[8:22..8:25): any <- a/b/Givens.extension_sayGoodbye_B.saySoLong().(any) +[8:27..8:28): B -> a/b/Givens.extension_sayGoodbye_B.sayGoodbye().[B] +[8:27..8:28): B -> a/b/Givens.extension_sayGoodbye_B.saySoLong().[B] +[9:8..9:18): sayGoodbye <- a/b/Givens.extension_sayGoodbye_B.sayGoodbye(). [9:23..9:23): -> scala/StringContext.apply(). -[9:38..9:41): any -> a/b/Givens.given_sayGoodbye_of_B.sayGoodbye().(any) +[9:38..9:41): any -> a/b/Givens.extension_sayGoodbye_B.sayGoodbye().(any) [9:41..9:41): -> scala/StringContext#s(). -[10:8..10:17): saySoLong <- a/b/Givens.given_sayGoodbye_of_B.saySoLong(). +[10:8..10:17): saySoLong <- a/b/Givens.extension_sayGoodbye_B.saySoLong(). [10:22..10:22): -> scala/StringContext.apply(). -[10:37..10:40): any -> a/b/Givens.given_sayGoodbye_of_B.saySoLong().(any) +[10:37..10:40): any -> a/b/Givens.extension_sayGoodbye_B.saySoLong().(any) [10:40..10:40): -> scala/StringContext#s(). [12:6..12:12): hello1 <- a/b/Givens.hello1. -[12:15..12:15): -> a/b/Givens.given_sayHello_of_A.sayHello(). +[12:15..12:15): -> a/b/Givens.extension_sayHello_A.sayHello(). [13:6..13:14): goodbye1 <- a/b/Givens.goodbye1. -[13:17..13:17): -> a/b/Givens.given_sayGoodbye_of_B.sayGoodbye(). +[13:17..13:17): -> a/b/Givens.extension_sayGoodbye_B.sayGoodbye(). [14:6..14:13): soLong1 <- a/b/Givens.soLong1. -[14:16..14:16): -> a/b/Givens.given_sayGoodbye_of_B.saySoLong(). +[14:16..14:16): -> a/b/Givens.extension_sayGoodbye_B.saySoLong(). [16:8..16:14): Monoid <- a/b/Givens.Monoid# [16:14..16:17): <- a/b/Givens.Monoid#``(). [16:15..16:16): A <- a/b/Givens.Monoid#[A] [17:8..17:13): empty <- a/b/Givens.Monoid#empty(). [17:15..17:16): A -> a/b/Givens.Monoid#[A] -[18:8..18:15): (x: A) <- a/b/Givens.Monoid#combine(). +[18:8..18:15): (x: A). <- a/b/Givens.Monoid#combine(). [18:9..18:10): x <- a/b/Givens.Monoid#combine().(x) [18:12..18:13): A -> a/b/Givens.Monoid#[A] -[18:24..18:25): y <- a/b/Givens.Monoid#combine().(y) -[18:27..18:28): A -> a/b/Givens.Monoid#[A] -[18:31..18:32): A -> a/b/Givens.Monoid#[A] +[18:23..18:24): y <- a/b/Givens.Monoid#combine().(y) +[18:26..18:27): A -> a/b/Givens.Monoid#[A] +[18:30..18:31): A -> a/b/Givens.Monoid#[A] [20:8..21:4): <- a/b/Givens.given_Monoid_String. [20:8..20:14): Monoid -> a/b/Givens.Monoid# [20:15..20:21): String -> scala/Predef.String# @@ -1355,11 +1355,11 @@ Occurrences: [22:8..22:15): (x: Str <- a/b/Givens.given_Monoid_String.combine(). [22:9..22:10): x <- a/b/Givens.given_Monoid_String.combine().(x) [22:12..22:18): String -> scala/Predef.String# -[22:29..22:30): y <- a/b/Givens.given_Monoid_String.combine().(y) -[22:32..22:38): String -> scala/Predef.String# -[22:42..22:43): x -> a/b/Givens.given_Monoid_String.combine().(x) -[22:44..22:45): + -> java/lang/String#`+`(). -[22:46..22:47): y -> a/b/Givens.given_Monoid_String.combine().(y) +[22:28..22:29): y <- a/b/Givens.given_Monoid_String.combine().(y) +[22:31..22:37): String -> scala/Predef.String# +[22:41..22:42): x -> a/b/Givens.given_Monoid_String.combine().(x) +[22:43..22:44): + -> java/lang/String#`+`(). +[22:45..22:46): y -> a/b/Givens.given_Monoid_String.combine().(y) [24:15..24:25): int2String <- a/b/Givens.int2String(). [24:27..24:37): Conversion -> scala/Conversion# [24:38..24:41): Int -> scala/Int# @@ -3565,3 +3565,4 @@ Occurrences: [2:46..2:47): z -> _empty_/toplevel$package.combine(+1).(z) [3:4..3:11): combine <- _empty_/toplevel$package.combine(+2). [4:4..4:7): foo <- _empty_/toplevel$package.foo(). +