Skip to content

Port tailrec spec and adjustments to annotations section #19978

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/_spec/04-basic-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,22 @@ class C extends I {

Here, it is OK to leave out the result type of `factorial` in `C`, even though the method is recursive.

### Tail-Recursive Call Elimination

Method definitions which contain self-recursive invocations in tail position are optimized for stack safety.
Self-invocations which are the last operation before returning from the method are replaced with jumps to the beginning of the method, much as in a while loop.
Sibling-invocations, in which a method calls itself but with a different instance as receiver, are also optimized.

This transform is performed automatically by the compiler whenever possible.
A method definition bearing the annotation, `scala.annotation.tailrec`, will fail to compile if the transform is not possible.
(The annotation is intended for cases where deoptimization would likely result in a stack overflow.)

```scala
@annotation.tailrec
def sum(xs: List[Int], acc: Int): Int =
xs match { case h :: t => sum(t, acc + h) case _ => acc }
```

<!-- ## Overloaded Definitions
\label{sec:overloaded-defs}
\todo{change}
Expand Down
99 changes: 54 additions & 45 deletions docs/_spec/11-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Here, ´c´ is a constructor of a class ´C´, which must conform to the class `
Annotations may apply to definitions, types, or expressions.
An annotation of a definition appears in front of that definition.
An annotation of a type appears after that type.
An annotation of an expression ´e´ appears after the expression ´e´, separated by a colon.
An annotation of an expression appears after that expression, separated by a colon.
More than one annotation clause may apply to an entity.
The order in which these annotations are given does not matter.

Expand All @@ -35,58 +35,28 @@ String @local // Type annotation

## Predefined Annotations

### Java Platform Annotations

The meaning of annotation clauses is implementation-dependent.
On the Java platform, the following annotations have a standard meaning.

* `@transient` Marks a field to be non-persistent; this is equivalent to the `transient` modifier in Java.

* `@volatile` Marks a field which can change its value outside the control of the program; this is equivalent to the `volatile` modifier in Java.
Predefined annotations are found in the `scala.annotation` package, and also in the `scala` package.

* `@SerialVersionUID(<longlit>)` Attaches a serial version identifier (a `long` constant) to a class.
This is equivalent to the following field definition in Java:

```java
private final static SerialVersionUID = <longlit>
```

* `@throws(<classlit>)` A Java compiler checks that a program contains handlers for checked exceptions by analyzing which checked exceptions can result from the execution of a method or constructor.
For each checked exception which is a possible result, the `throws` clause for the method or constructor must mention the class of that exception or one of the superclasses of the class of that exception.

### Java Beans Annotations

* `@scala.beans.BeanProperty` When prefixed to a definition of some variable `X`, this annotation causes getter and setter methods `getX`, `setX` in the Java bean style to be added in the class containing the variable.
The first letter of the variable appears capitalized after the `get` or `set`.
When the annotation is added to the definition of an immutable value definition `X`, only a getter is generated.
The construction of these methods is part of code-generation; therefore, these methods become visible only once a classfile for the containing class is generated.

* `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but the generated getter method is named `isX` instead of `getX`.

### Deprecation Annotations
### Scala Compiler Annotations

* `@deprecated(message: <stringlit>, since: <stringlit>)`<br/>
Marks a definition as deprecated.
Accesses to the defined entity will then cause a deprecated warning mentioning the _message_ `<stringlit>` to be issued from the compiler.
The argument _since_ documents since when the definition should be considered deprecated.<br/>
Deprecated warnings are suppressed in code that belongs itself to a definition that is labeled deprecated.
* `@tailrec` Marks a method which must be transformed by the compiler to eliminate self-recursive invocations in tail position.
It is an error if there are no such invocations, or a recursive call not in tail position.

* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
Marks a formal parameter name as deprecated.
Invocations of this entity using named parameter syntax referring to the deprecated parameter name cause a deprecation warning.

### Scala Compiler Annotations
* `@switch` Marks the expression submitted to a match as "switchable", such that the match can be compiled to an efficient form.
The compiler will warn if the type of the expression is not a switchable type.
Certain degenerate matches may remain unoptimized without a warning.

* `@unchecked` When applied to the selector of a `match` expression, this attribute suppresses any warnings about non-exhaustive pattern matches that would otherwise be emitted.
For instance, no warnings would be produced for the method definition below.
For instance, no warnings would be produced for the method definition below, or the similar value definition.
```scala
def f(x: Option[Int]) = (x: @unchecked) match {
case Some(y) => y
}
val Some(y) = x: @unchecked
```
Without the `@unchecked` annotation, a Scala compiler could infer that the pattern match is non-exhaustive, and could produce a warning because `Option` is a `sealed` class.
Without the `@unchecked` annotation, a Scala compiler could infer that the pattern match is non-exhaustive and issue a warning because `Option` is a `sealed` class.

* `@uncheckedStable` When applied a value definition, it allows the defined value to appear in a path, even if its type is [volatile](03-types.html#volatile-types).
* `@uncheckedStable` When applied to a value definition, it allows the defined value to appear in a path, even if its type is [volatile](03-types.html#volatile-types).
For instance, the following member definitions are legal:
```scala
type A { type T }
Expand All @@ -97,19 +67,58 @@ val y: x.T // OK since `x' is still a path
Without the `@uncheckedStable` annotation, the designator `x` would not be a path since its type `A with B` is volatile.
Hence, the reference `x.T` would be malformed.

When applied to value definitions that have non-volatile types, the annotation has no effect.
When applied to value definitions that have no volatile types, the annotation has no effect.

* `@specialized` When applied to the definition of a type parameter, this annotation causes the compiler to generate specialized definitions for primitive types.
* `@specialized` When applied to the definition of a type parameter, this annotation causes the compiler to generate definitions that are specialized for primitive types.
An optional list of primitive types may be given, in which case specialization takes into account only those types.
For instance, the following code would generate specialized traits for `Unit`, `Int` and `Double`
```scala
trait Function0[@specialized(Unit, Int, Double) T] {
def apply: T
}
```
Whenever the static type of an expression matches a specialized variant of a definition, the compiler will instead use the specialized version.
Whenever the static type of an expression matches a specialized variant of a definition, the compiler will use the specialized version instead.
See the [specialization sid](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation.

### Deprecation Annotations

* `@deprecated(message: <stringlit>, since: <stringlit>)`<br/>
Marks a definition as deprecated.
Accesses to the defined entity cause the compiler to issue a deprecation warning with the _message_ `<stringlit>`.
The argument _since_ documents since when the definition should be considered deprecated.<br/>
Deprecated warnings are suppressed in code that belongs to a deprecated definition.

* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
Marks a formal parameter name as deprecated.
Invocations of this entity using named parameter syntax referring to the deprecated parameter name cause a deprecation warning.

### Java Platform Annotations

The meaning of annotation clauses is implementation-dependent.
On the Java platform, the following annotations have a standard meaning.

* `@transient` Marks a field to be non-persistent; this is equivalent to the `transient` modifier in Java.

* `@volatile` Marks a field which can change its value outside the control of the program; this is equivalent to the `volatile` modifier in Java.

* `@SerialVersionUID(<longlit>)` Attaches a serial version identifier (a `long` constant) to a class.
This is equivalent to the following field definition in Java:

```java
private final static SerialVersionUID = <longlit>
```

* `@throws(<classlit>)` A Java compiler checks that a program contains handlers for checked exceptions by analyzing which checked exceptions can result from the execution of a method or constructor.
For each checked exception which is a possible result, the `throws` clause for the method or constructor must mention the class of that exception or one of the superclasses of the class of that exception.

### Java Beans Annotations

* `@scala.beans.BeanProperty` When prefixed to a definition of some variable `X`, this annotation causes getter and setter methods `getX`, `setX` in the Java bean style to be added in the class containing the variable.
The first letter of the variable appears capitalized after the `get` or `set`.
When the annotation is added to the definition of an immutable value definition `X`, only a getter is generated.
The construction of these methods is part of code-generation; therefore, these methods become visible only once a classfile for the containing class is generated.

* `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but the generated getter method is named `isX` instead of `getX`.

## User-defined Annotations

Expand Down
Loading