Skip to content

Commit f7d5a8d

Browse files
committed
Port tailrec spec
1 parent 11eff96 commit f7d5a8d

File tree

2 files changed

+67
-42
lines changed

2 files changed

+67
-42
lines changed

Diff for: docs/_spec/04-basic-definitions.md

+16
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,22 @@ class C extends I {
710710

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

713+
### Tail-Recursive Call Elimination
714+
715+
Method definitions which contain self-recursive invocations in tail position are optimized for stack safety.
716+
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.
717+
Sibling-invocations, in which a method calls itself but with a different instance as receiver, are also optimized.
718+
719+
This transform is performed automatically by the compiler whenever possible.
720+
A method definition bearing the annotation, `scala.annotation.tailrec`, will fail to compile if the transform is not possible.
721+
(The annotation is intended for cases where deoptimization would likely result in a stack overflow.)
722+
723+
```scala
724+
@annotation.tailrec
725+
def sum(xs: List[Int], acc: Int): Int =
726+
xs match { case h :: t => sum(t, acc + h) case _ => acc }
727+
```
728+
713729
<!-- ## Overloaded Definitions
714730
\label{sec:overloaded-defs}
715731
\todo{change}

Diff for: docs/_spec/11-annotations.md

+51-42
Original file line numberDiff line numberDiff line change
@@ -35,56 +35,26 @@ String @local // Type annotation
3535

3636
## Predefined Annotations
3737

38-
### Java Platform Annotations
39-
40-
The meaning of annotation clauses is implementation-dependent.
41-
On the Java platform, the following annotations have a standard meaning.
42-
43-
* `@transient` Marks a field to be non-persistent; this is equivalent to the `transient` modifier in Java.
44-
45-
* `@volatile` Marks a field which can change its value outside the control of the program; this is equivalent to the `volatile` modifier in Java.
38+
Predefined annotations are found in the `scala.annotation` package, and also in the `scala` package.
4639

47-
* `@SerialVersionUID(<longlit>)` Attaches a serial version identifier (a `long` constant) to a class.
48-
This is equivalent to the following field definition in Java:
49-
50-
```java
51-
private final static SerialVersionUID = <longlit>
52-
```
53-
54-
* `@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.
55-
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.
56-
57-
### Java Beans Annotations
58-
59-
* `@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.
60-
The first letter of the variable appears capitalized after the `get` or `set`.
61-
When the annotation is added to the definition of an immutable value definition `X`, only a getter is generated.
62-
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.
63-
64-
* `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but the generated getter method is named `isX` instead of `getX`.
65-
66-
### Deprecation Annotations
40+
### Scala Compiler Annotations
6741

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

74-
* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
75-
Marks a formal parameter name as deprecated.
76-
Invocations of this entity using named parameter syntax referring to the deprecated parameter name cause a deprecation warning.
77-
78-
### Scala Compiler Annotations
45+
* `@switch` Marks the expression submitted to a match as "switchable", such that the match can be compiled to an efficient form.
46+
The compiler will warn if the type of the expression is not a switchable type.
47+
Certain degenerate matches may remain unoptimized without a warning.
7948

8049
* `@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.
81-
For instance, no warnings would be produced for the method definition below.
50+
For instance, no warnings would be produced for the method definition below, or the similar value definition.
8251
```scala
8352
def f(x: Option[Int]) = (x: @unchecked) match {
8453
case Some(y) => y
8554
}
55+
val Some(y) = x: @unchecked
8656
```
87-
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.
57+
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.
8858

8959
* `@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).
9060
For instance, the following member definitions are legal:
@@ -99,17 +69,56 @@ Hence, the reference `x.T` would be malformed.
9969

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

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

83+
### Deprecation Annotations
84+
85+
* `@deprecated(message: <stringlit>, since: <stringlit>)`<br/>
86+
Marks a definition as deprecated.
87+
Accesses to the defined entity cause the compiler to issue a deprecation warning with the _message_ `<stringlit>`.
88+
The argument _since_ documents since when the definition should be considered deprecated.<br/>
89+
Deprecated warnings are suppressed in code that belongs to a deprecated definition.
90+
91+
* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
92+
Marks a formal parameter name as deprecated.
93+
Invocations of this entity using named parameter syntax referring to the deprecated parameter name cause a deprecation warning.
94+
95+
### Java Platform Annotations
96+
97+
The meaning of annotation clauses is implementation-dependent.
98+
On the Java platform, the following annotations have a standard meaning.
99+
100+
* `@transient` Marks a field to be non-persistent; this is equivalent to the `transient` modifier in Java.
101+
102+
* `@volatile` Marks a field which can change its value outside the control of the program; this is equivalent to the `volatile` modifier in Java.
103+
104+
* `@SerialVersionUID(<longlit>)` Attaches a serial version identifier (a `long` constant) to a class.
105+
This is equivalent to the following field definition in Java:
106+
107+
```java
108+
private final static SerialVersionUID = <longlit>
109+
```
110+
111+
* `@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.
112+
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.
113+
114+
### Java Beans Annotations
115+
116+
* `@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.
117+
The first letter of the variable appears capitalized after the `get` or `set`.
118+
When the annotation is added to the definition of an immutable value definition `X`, only a getter is generated.
119+
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.
120+
121+
* `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but the generated getter method is named `isX` instead of `getX`.
113122

114123
## User-defined Annotations
115124

0 commit comments

Comments
 (0)