diff --git a/docs/docs/reference/changed-features/operators.md b/docs/docs/reference/changed-features/operators.md index 70155e77330e..55c416753007 100644 --- a/docs/docs/reference/changed-features/operators.md +++ b/docs/docs/reference/changed-features/operators.md @@ -5,20 +5,19 @@ title: Rules for Operators The rules for infix operators have changed in some parts: -First, an alphanumeric method can be used as an infix operator only if its definition carries an `@infix` annotation. Second, it is recommended (but not enforced) to +First, an alphanumeric method can be used as an infix operator only if its definition carries an `infix` modifier. Second, it is recommended (but not enforced) to augment definitions of symbolic operators with `@targetName` annotations. Finally, a syntax change allows infix operators to be written on the left in a multi-line expression. -## The @infix Annotation +## The `infix` Modifier -An `@infix` annotation on a method definition allows using the method as an infix operation. Example: +An `infix` modifier on a method definition allows using the method as an infix operation. Example: ```scala -import scala.annotation.{infix, targetName} +import scala.annotation.targetName trait MultiSet[T] { - @infix - def union(other: MultiSet[T]): MultiSet[T] + infix def union(other: MultiSet[T]): MultiSet[T] def difference(other: MultiSet[T]): MultiSet[T] @@ -43,46 +42,46 @@ s1.*(s2) // also OK, but unusual Infix operations involving alphanumeric operators are deprecated, unless one of the following conditions holds: - - the operator definition carries an `@infix` annotation, or + - the operator definition carries an `infix` modifier, or - the operator was compiled with Scala 2, or - the operator is followed by an opening brace. An alphanumeric operator is an operator consisting entirely of letters, digits, the `$` and `_` characters, or any unicode character `c` for which `java.lang.Character.isIdentifierPart(c)` returns `true`. -Infix operations involving symbolic operators are always allowed, so `@infix` is redundant for methods with symbolic names. +Infix operations involving symbolic operators are always allowed, so `infix` is redundant for methods with symbolic names. -The `@infix` annotation can also be given to a type: +The `infix` modifier can also be given to a type: ``` -@infix type or[X, Y] +infix type or[X, Y] val x: String or Int = ... ``` ### Motivation -The purpose of the `@infix` annotation is to achieve consistency across a code base in how a method or type is applied. The idea is that the author of a method decides whether that method should be applied as an infix operator or in a regular application. Use sites then implement that decision consistently. +The purpose of the `infix` modifier is to achieve consistency across a code base in how a method or type is applied. The idea is that the author of a method decides whether that method should be applied as an infix operator or in a regular application. Use sites then implement that decision consistently. ### Details - 1. `@infix` is defined in package `scala.annotation`. + 1. `infix` is a soft modifier. It is treated as a normal identifier except when in modifier position. - 2. If a method overrides another, their infix annotations must agree. Either both are annotated with `@infix`, or none of them are. + 2. If a method overrides another, their infix annotations must agree. Either both are annotated with `infix`, or none of them are. - 3. `@infix` annotations can be given to method definitions. The first non-receiver parameter list of an `@infix` method must define exactly one parameter. Examples: + 3. `infix` modifiers can be given to method definitions. The first non-receiver parameter list of an `infix` method must define exactly one parameter. Examples: ```scala - @infix def op(x: S): R // ok - @infix def op[T](x: T)(y: S): R // ok - @infix def op[T](x: T, y: S): R // error: two parameters + infix def op(x: S): R // ok + infix def op[T](x: T)(y: S): R // ok + infix def op[T](x: T, y: S): R // error: two parameters - @infix def (x: A) op (y: B): R // ok - @infix def (x: A) op (y1: B, y2: B): R // error: two parameters + infix def (x: A) op (y: B): R // ok + infix def (x: A) op (y1: B, y2: B): R // error: two parameters ``` - 4. `@infix` annotations can also be given to type, trait or class definitions that have exactly two type parameters. An infix type like + 4. `infix` modifiers can also be given to type, trait or class definitions that have exactly two type parameters. An infix type like ```scala - @infix type op[X, Y] + infix type op[X, Y] ``` can be applied using infix syntax, i.e. `A op B`. diff --git a/docs/docs/reference/features-classification.md b/docs/docs/reference/features-classification.md index f831aca713dc..f237aa9f730f 100644 --- a/docs/docs/reference/features-classification.md +++ b/docs/docs/reference/features-classification.md @@ -73,7 +73,7 @@ These constructs are restricted to make the language safer. - [Given Imports](contextual/import-delegate.md): implicits now require a special form of import, to make the import clearly visible. - [Type Projection](dropped-features/type-projection.md): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. - [Multiversal Equality](contextual/multiversal-equality.md) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. - - [@infix](https://github.com/lampepfl/dotty/pull/5975) + - [infix](https://github.com/lampepfl/dotty/pull/5975) makes method application syntax uniform across code bases. Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`. diff --git a/docs/docs/reference/metaprogramming/inline.md b/docs/docs/reference/metaprogramming/inline.md index ecbd2325611e..9c8252affa71 100644 --- a/docs/docs/reference/metaprogramming/inline.md +++ b/docs/docs/reference/metaprogramming/inline.md @@ -500,7 +500,7 @@ val multiplication: 3 * 5 = 15 Many of these singleton operation types are meant to be used infix (as in [SLS ยง 3.2.8](https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#infix-types)), -and are annotated with [`@infix`](scala.annotation.infix) accordingly. +and are annotated accordingly with [`infix`] modifiers. Since type aliases have the same precedence rules as their term-level equivalents, the operations compose with the expected precedence rules: @@ -518,9 +518,8 @@ match type can dispatch to the correct implementation: ```scala import scala.compiletime.ops._ -import scala.annotation.infix -@infix type +[X <: Int | String, Y <: Int | String] = (X, Y) match { +infix type +[X <: Int | String, Y <: Int | String] = (X, Y) match { case (Int, Int) => int.+[X, Y] case (String, String) => string.+[X, Y] } diff --git a/docs/docs/reference/overview.md b/docs/docs/reference/overview.md index 84f5714fd192..211b34a1e7eb 100644 --- a/docs/docs/reference/overview.md +++ b/docs/docs/reference/overview.md @@ -58,7 +58,7 @@ These constructs are restricted to make the language safer. - [Given Imports](contextual/given-imports.md): implicits now require a special form of import, to make the import clearly visible. - [Type Projection](dropped-features/type-projection.md): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. - [Multiversal Equality](contextual/multiversal-equality.md) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. - - [@infix annotations](changed-features/operators.md) + - [infix](changed-features/operators.md) make method application syntax uniform across code bases. Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`.