diff --git a/docs/_spec/01-lexical-syntax.md b/docs/_spec/01-lexical-syntax.md index de11de10402f..370d80955545 100644 --- a/docs/_spec/01-lexical-syntax.md +++ b/docs/_spec/01-lexical-syntax.md @@ -27,8 +27,6 @@ The principle of optional braces is that any keyword that can be followed by `{` The lexical analyzer inserts `indent` and `outdent` tokens that represent regions of indented code [at certain points](./other-new-features/indentation.md). -´\color{red}{\text{TODO SCALA3: Port soft-modifier.md and link it here.}}´ - In the context-free productions below we use the notation `<<< ts >>>` to indicate a token sequence `ts` that is either enclosed in a pair of braces `{ ts }` or that constitutes an indented region `indent ts outdent`. Analogously, the notation `:<<< ts >>>` indicates a token sequence `ts` that is either enclosed in a pair of braces `{ ts }` or that constitutes an indented region `indent ts outdent` that follows a `colon` token. @@ -121,12 +119,35 @@ type val var while with yield Additionally, the following soft keywords are reserved only in some situations. -´\color{red}{\text{TODO SCALA3: Port soft-modifier.md and link it here.}}´ - ``` -as derives end extension infix inline opaque open transparent using | * + - +as derives end extension infix inline opaque +open transparent using +| * + - ``` +A soft modifier is one of the identifiers `infix`, `inline`, `opaque`, `open` and `transparent`. + +A soft keyword is a soft modifier, or one of `as`, `derives`, `end`, `extension`, `using`, `|`, `+`, `-`, `*`. + +A soft modifier is treated as an actual modifier of a definition if it is followed by a hard modifier or a keyword combination starting a definition (`def`, `val`, `var`, `type`, `given`, `class`, `trait`, `object`, `enum`, `case class`, `case object`). +Between the two words, there may be a sequence of newline tokens and/or other soft modifiers. + +Otherwise, soft keywords are treated as actual keywords in the following situations: + + - `as`, if it appears in a renaming import clause. + - `derives`, if it appears after an extension clause or after the name and possibly parameters of a class, trait, object, or enum definition. + - `end`, if it appears at the start of a line following a statement (i.e. definition or toplevel expression) and is followed on the same line by a single non-comment token that is: + - one of the keywords `for`, `given`, `if`, `match`, `new`, `this`, `throw`, `try`, `val`, `while`, or + - an identifier. + - `extension`, if it appears at the start of a statement and is followed by `(` or `[`. + - `inline`, if it is followed by any token that can start an expression. + - `using`, if it appears at the start of a parameter or argument list. + - `|`, if it separates two patterns in an alternative. + - `+`, `-`, if they appear in front of a type parameter. + - `*`, if it appears in a wildcard import, or if it follows the type of a parameter, or if it appears in a vararg splice `x*`. + +Everywhere else, a soft keyword is treated as a normal identifier. + > When one needs to access Java identifiers that are reserved words in Scala, use backquote-enclosed strings. @@ -143,7 +164,7 @@ Scala is a line-oriented language where statements may be terminated by semi-col A newline in a Scala source text is treated as the special token “nl” if the three following criteria are satisfied: 1. The token immediately preceding the newline can terminate a statement. -1. The token immediately following the newline can begin a statement. +1. The token immediately following the newline can begin a statement and is not a _leading infix operator_. 1. The token appears in a region where newlines are enabled. The tokens that can terminate a statement are: literals, identifiers and the following delimiters and reserved words: @@ -164,6 +185,14 @@ with yield , . ; : = => <- <: <% A `case` token can begin a statement only if followed by a `class` or `object` token. +A _leading infix operator_ is a symbolic identifier such as `+`, or `approx_==`, or an identifier in backticks that: + +- starts a new line, and +- is not following a blank line, and +- is followed by at least one whitespace character (including new lines) and a token that can start an expression. + +Furthermore, if the operator appears on its own line, the next line must have at least the same indentation width as the operator. + Newlines are enabled in: 1. all of a Scala source file, except for nested regions where newlines are disabled, and diff --git a/docs/_spec/02-identifiers-names-and-scopes.md b/docs/_spec/02-identifiers-names-and-scopes.md index 2ffa8af995d3..9d52cb1654b5 100644 --- a/docs/_spec/02-identifiers-names-and-scopes.md +++ b/docs/_spec/02-identifiers-names-and-scopes.md @@ -74,11 +74,11 @@ The compiler supplies imports in a preamble to every source file. This preamble conceptually has the following form, where braces indicate nested scopes: ```scala -import java.lang._ +import java.lang.* { - import scala._ + import scala.* { - import Predef._ + import Predef.* { /* source */ } } } @@ -95,8 +95,8 @@ This allows redundant type aliases to be imported without introducing an ambigui object X { type T = annotation.tailrec } object Y { type T = annotation.tailrec } object Z { - import X._, Y._, annotation.{tailrec => T} // OK, all T mean tailrec - @T def f: Int = { f ; 42 } // error, f is not tail recursive + import X.*, Y.*, annotation.tailrec as T // OK, all T mean tailrec + @T def f: Int = { f ; 42 } // error, f is not tail recursive } ``` @@ -107,7 +107,7 @@ Similarly, imported aliases of names introduced by package statements are allowe package p { class C } // xy.scala -import p._ +import p.* package p { class X extends C } package q { class Y extends C } ``` @@ -132,27 +132,32 @@ package q { The following program illustrates different kinds of bindings and precedences between them. ```scala -package p { // `X' bound by package clause -import Console._ // `println' bound by wildcard import -object Y { - println(s"L4: $X") // `X' refers to `p.X' here - locally { - import q._ // `X' bound by wildcard import - println(s"L7: $X") // `X' refers to `q.X' here - import X._ // `x' and `y' bound by wildcard import - println(s"L9: $x") // `x' refers to `q.X.x' here +package p { // `X' bound by package clause + import Console.* // `println' bound by wildcard import + object Y { + println(s"L4: $X") // `X' refers to `p.X' here locally { - val x = 3 // `x' bound by local definition - println(s"L12: $x") // `x' refers to constant `3' here + import q.* // `X' bound by wildcard import + println(s"L7: $X") // `X' refers to `q.X' here + import X.* // `x' and `y' bound by wildcard import + println(s"L9: $x") // `x' refers to `q.X.x' here locally { - import q.X._ // `x' and `y' bound by wildcard import -// println(s"L15: $x") // reference to `x' is ambiguous here - import X.y // `y' bound by explicit import - println(s"L17: $y") // `y' refers to `q.X.y' here + val x = 3 // `x' bound by local definition + println(s"L12: $x") // `x' refers to constant `3' here locally { - val x = "abc" // `x' bound by local definition - import p.X._ // `x' and `y' bound by wildcard import -// println(s"L21: $y") // reference to `y' is ambiguous here - println(s"L22: $x") // `x' refers to string "abc" here -}}}}}} + import q.X.* // `x' and `y' bound by wildcard import +// println(s"L15: $x") // reference to `x' is ambiguous here + import X.y // `y' bound by explicit import + println(s"L17: $y") // `y' refers to `q.X.y' here + locally { + val x = "abc" // `x' bound by local definition + import p.X.* // `x' and `y' bound by wildcard import +// println(s"L21: $y") // reference to `y' is ambiguous here + println(s"L22: $x") // `x' refers to string "abc" here + } + } + } + } + } +} ``` diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index 7513eb2d782d..809999bbcdaf 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -172,6 +172,8 @@ Type operators ending in a colon ‘:’ are right-associative; all other operat In a sequence of consecutive type infix operations ´t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, ... \, \mathit{op_n} \, t_n´, all operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ must have the same associativity. If they are all left-associative, the sequence is interpreted as ´(... (t_0 \mathit{op_1} t_1) \mathit{op_2} ...) \mathit{op_n} t_n´, otherwise it is interpreted as ´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( ... \mathit{op_n} t_n) ...)´. +Under `-source:future`, if the type name is alphanumeric and the target type is not marked [`infix`](./05-classes-and-objects.html#infix), a deprecation warning is emitted. + The type operators `|` and `&` are not really special. Nevertheless, unless shadowed, they resolve to [the fundamental type aliases `scala.|` and `scala.&`](./12-the-scala-standard-library.html#fundamental-type-aliases), which represent [union and intersection types](#union-and-intersection-types), respectively. @@ -493,6 +495,9 @@ All parameterized class types are value types. In the concrete syntax of wildcard type arguments, if both bounds are omitted, the real bounds are inferred from the bounds of the corresponding type parameter in the target type constructor (which must be concrete). If only one bound is omitted, `Nothing` or `Any` is used, as usual. +Also in the concrete syntax, `_` can be used instead of `?` for compatibility reasons, with the same meaning. +This alternative will be deprecated in the future, and is already deprecated under `-source:future`. + #### Simplification Rules Wildcard type arguments used in covariant or contravariant positions can always be simplified to regular types. diff --git a/docs/_spec/04-basic-declarations-and-definitions.md b/docs/_spec/04-basic-declarations-and-definitions.md index bd73dbd7a666..4feeb34eebe5 100644 --- a/docs/_spec/04-basic-declarations-and-definitions.md +++ b/docs/_spec/04-basic-declarations-and-definitions.md @@ -164,7 +164,7 @@ A variable definition `var ´p´ = ´e´` where ´p´ is a pattern other than a The name of any declared or defined variable may not end in `_=`. -A variable definition `var ´x´: ´T´ = _` can appear only as a member of a template. +The right-hand-side of a mutable variable definition that is a member of a template can be the special reference `scala.compiletime.uninitialized`: `var ´x´: ´T´ = scala.compiletime.uninitialized`. It introduces a mutable field with type ´T´ and a default initial value. The default value depends on the type ´T´ as follows: @@ -178,6 +178,9 @@ The default value depends on the type ´T´ as follows: |`()` | `Unit` | |`null` | all other types | +`scala.compiletime.uninitialized` can never appear anywhere else. +For compatibility with Scala 2, the syntax `var ´x´: ´T´ = _` is accepted as equivalent to using `uninitialized`. + When they occur as members of a template, both forms of variable definition also introduce a getter method ´x´ which returns the value currently assigned to the variable, as well as a setter method `´x´_=` which changes the value currently assigned to the variable. The methods have the same signatures as for a variable declaration. The template then has these getter and setter methods as members, whereas the original variable cannot be accessed directly as a template member. @@ -572,6 +575,9 @@ The scope of a type parameter includes the whole signature, including any of the A _value parameter clause_ ´\mathit{ps}´ consists of zero or more formal parameter bindings such as `´x´: ´T´` or `´x: T = e´`, which bind value parameters and associate them with their types. +A unary operator must not have explicit parameter lists even if they are empty. +A unary operator is a method named `"unary_´op´"` where ´op´ is one of `+`, `-`, `!`, or `~`. + ### Default Arguments Each value parameter declaration may optionally define a default argument. @@ -729,52 +735,69 @@ completely. It is an error if the types of two alternatives ´T_i´ and ## Import Clauses -```ebnf -Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} -ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) -ImportSelectors ::= ‘{’ {ImportSelector ‘,’} - (ImportSelector | ‘_’) ‘}’ -ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] ``` +Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpecifier + | SimpleRef `as` id +ImportSpecifier ::= NamedSelector + | WildcardSelector + | ‘{’ ImportSelectors ‘}’ +NamedSelector ::= id [(‘as’ | ’=>’) (id | ‘_’)] +WildcardSelector ::= ‘*’ | ’_’ | ‘given’ [InfixType] +ImportSelectors ::= NamedSelector [‘,’ ImportSelectors] + | WildCardSelector {‘,’ WildcardSelector} +``` + +- In a `NamedSelector`, `=>` can only be used when inside an `ImportSelectors` and is then equivalent to `as`, to be deprecated in the future. +- In a `WildcardSelector`, `_` is equivalent to `*`, to be deprecated in the future. + +An `ImportSpecifier` that is a single `NamedSelector` or `WildcardSelector` is equivalent to an `‘{‘ ImportSelectors ‘}‘` list with that single selector. + +An import clause with multiple import expressions `import ´p_1´.´I_1, ..., p_n´.´I_n´` is interpreted as a sequence of import clauses `import ´p_1´.´I_1´; ...; import ´p_n´.´I_n´`. -An import clause has the form `import ´p´.´I´` where ´p´ is a [stable identifier](03-types.html#paths) and ´I´ is an import expression. -The import expression determines a set of names of importable members of ´p´ which are made available without qualification. +An import clause with a single import expression has the form `import ´p´.´I´` where ´p´ is a [prefix](03-types.html#designator-types) and ´I´ is an import specifier. +The import specifier determines a set of names of importable members of ´p´ which are made available without qualification as well as a set of importable `given` members which are made available in the implicit scope. A member ´m´ of ´p´ is _importable_ if it is [accessible](05-classes-and-objects.html#modifiers). -The most general form of an import expression is a list of _import selectors_ +The most general form of an import specifier is a list of _import selectors_ ```scala -{ ´x_1´ => ´y_1, ..., x_n´ => ´y_n´, _ } +{ ´x_1´ as ´y_1, ..., x_n´ as ´y_n´, *, given ´T_1´, ..., given ´T_m´, given } ``` -for ´n \geq 0´, where the final wildcard `‘_’` may be absent. -It makes available each importable member `´p´.´x_i´` under the unqualified name ´y_i´. I.e. every import selector `´x_i´ => ´y_i´` renames `´p´.´x_i´` to -´y_i´. -If a final wildcard is present, all importable members ´z´ of ´p´ other than `´x_1, ..., x_n,y_1, ..., y_n´` are also made available under their own unqualified names. +for ´n \geq 0´ and ´m \geq 0´, where the wildcards `‘*’` and `’given’` may be absent. +They are decomposed into non-given selectors and given selectors. + +### Non-given Imports -Import selectors work in the same way for type and term members. -For instance, an import clause `import ´p´.{´x´ => ´y\,´}` renames the term -name `´p´.´x´` to the term name ´y´ and the type name `´p´.´x´` to the type name ´y´. +Non-given selectors make available each importable member `´p´.´x_i´` under the unqualified name ´y_i´. +In other words, every import selector `´x_i´ as ´y_i´` renames `´p´.´x_i´` to ´y_i´. +When `as ´y_i´` is omitted, ´y_i´ is assumed to be ´x_i´. +If a final wildcard `‘*’` is present, all non-`given` importable members ´z´ of ´p´ other than `´x_1, ..., x_n, y_1, ..., y_n´` are also made available under their own unqualified names. + +Non-given import selectors work in the same way for type and term members. +For instance, an import clause `import ´p´.´x´ as ´y´` renames the term name `´p´.´x´` to the term name ´y´ and the type name `´p´.´x´` to the type name ´y´. At least one of these two names must reference an importable member of ´p´. -If the target in an import selector is a wildcard, the import selector hides access to the source member. -For instance, the import selector `´x´ => _` “renames” ´x´ to the wildcard symbol (which is unaccessible as a name in user programs), and thereby effectively prevents unqualified access to ´x´. +If the target in an import selector is an underscore `as _`, the import selector hides access to the source member instead of importing it. +For instance, the import selector `´x´ as _` “renames” ´x´ to the underscore symbol (which is not accessible as a name in user programs), and thereby effectively prevents unqualified access to ´x´. This is useful if there is a final wildcard in the same import selector list, which imports all members not mentioned in previous import selectors. -The scope of a binding introduced by an import-clause starts immediately after the import clause and extends to the end of the enclosing block, template, package clause, or compilation unit, whichever comes first. +The scope of a binding introduced by a non-given import clause starts immediately after the import clause and extends to the end of the enclosing block, template, package clause, or compilation unit, whichever comes first. -Several shorthands exist. An import selector may be just a simple name ´x´. -In this case, ´x´ is imported without renaming, so the import selector is equivalent to `´x´ => ´x´`. -Furthermore, it is possible to replace the whole import selector list by a single identifier or wildcard. -The import clause `import ´p´.´x´` is equivalent to `import ´p´.{´x\,´}`, i.e. it makes available without qualification the member ´x´ of ´p´. The import clause `import ´p´._` is equivalent to `import ´p´.{_}`, i.e. it makes available without qualification all members of ´p´ (this is analogous to `import ´p´.*` in Java). +### Given Imports -An import clause with multiple import expressions `import ´p_1´.´I_1, ..., p_n´.´I_n´` is interpreted as a sequence of import clauses `import ´p_1´.´I_1´; ...; import ´p_n´.´I_n´`. +Given selectors make available in the implicit scope all the importable `given` and `implicit` members `´p´.´x´` such that `´p.x´` is a subtype of ´T_i´. +A bare `given` selector without type is equivalent to `given scala.Any`. + +The names of the given members are irrelevant for the selection, and are not made available in the normal scope of unqualified names. ###### Example Consider the object definition: ```scala object M { - def z = 0, one = 1 + def z = 0 + def one = 1 def add(x: Int, y: Int): Int = x + y } ``` @@ -782,11 +805,16 @@ object M { Then the block ```scala -{ import M.{one, z => zero, _}; add(zero, one) } +{ + import M.{one, z as zero, *} + add(zero, one) +} ``` is equivalent to the block ```scala -{ M.add(M.z, M.one) } +{ + M.add(M.z, M.one) +} ``` diff --git a/docs/_spec/05-classes-and-objects.md b/docs/_spec/05-classes-and-objects.md index 6feda780417a..581ba7552104 100644 --- a/docs/_spec/05-classes-and-objects.md +++ b/docs/_spec/05-classes-and-objects.md @@ -310,6 +310,7 @@ LocalModifier ::= ‘abstract’ | ‘sealed’ | ‘implicit’ | ‘lazy’ + | ‘infix’ AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’ ``` @@ -401,6 +402,31 @@ happen at all). Attempting to access a lazy value during its initialization might lead to looping behavior. If an exception is thrown during initialization, the value is considered uninitialized, and a later access will retry to evaluate its right hand side. +### `infix` +The `infix` modifier applies to method definitions and type definitions. +It signals that the method or type is intended for use in infix position, even if it has an alphanumeric name. + +If a method overrides another, their `infix` annotations must agree. Either both are annotated with `infix`, or none of them are. + +The first non-receiver parameter list of an `infix` method must define exactly one parameter. Examples: + +```scala +infix def op1(x: S): R // ok +infix def op2[T](x: T)(y: S): R // ok +infix def op3[T](x: T, y: S): R // error: two parameters +extension (x: A) + infix def op4(y: B): R // ok + infix def op5(y1: B, y2: B): R // error: two parameters +``` + +`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] +``` + +can be applied using infix syntax, i.e., `A op B`. + ###### Example The following code illustrates the use of qualified private: @@ -1211,4 +1237,4 @@ A correctly typed version would use an _explicit_, _invariant_ type parameter ` ```scala enum View[-´T´]: case Refl[´R´](f: ´R´ => ´R´) extends View[´R´] -``` \ No newline at end of file +``` diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md index ceb7dc4c36e5..063c41e4e907 100644 --- a/docs/_spec/06-expressions.md +++ b/docs/_spec/06-expressions.md @@ -10,22 +10,26 @@ chapter: 6 Expr ::= (Bindings | id | ‘_’) ‘=>’ Expr | Expr1 Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] + | ‘if‘ Expr ‘then‘ Expr [[semi] ‘else‘ Expr] | ‘while’ ‘(’ Expr ‘)’ {nl} Expr - | ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] - | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr + | ‘while’ Expr ‘do’ Expr + | ‘try’ Expr [Catches] [‘finally’ Expr] + | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘do‘ | ‘yield’] Expr + | ‘for’ Enumerators (‘do‘ | ‘yield’) Expr | ‘throw’ Expr | ‘return’ [Expr] | [SimpleExpr ‘.’] id ‘=’ Expr | SimpleExpr1 ArgumentExprs ‘=’ Expr | PostfixExpr | PostfixExpr Ascription - | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ PostfixExpr ::= InfixExpr [id [nl]] InfixExpr ::= PrefixExpr | InfixExpr id [nl] InfixExpr + | InfixExpr MatchClause PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody) | BlockExpr + | SimpleExpr ‘.’ MatchClause | SimpleExpr1 [‘_’] SimpleExpr1 ::= Literal | Path @@ -36,6 +40,7 @@ SimpleExpr1 ::= Literal | SimpleExpr1 ArgumentExprs | XmlExpr Exprs ::= Expr {‘,’ Expr} +MatchClause ::= ‘match’ ‘{’ CaseClauses ‘}’ BlockExpr ::= ‘{’ CaseClauses ‘}’ | ‘{’ Block ‘}’ Block ::= BlockStat {semi BlockStat} [ResultExpr] @@ -44,6 +49,7 @@ ResultExpr ::= Expr1 Ascription ::= ‘:’ InfixType | ‘:’ Annotation {Annotation} | ‘:’ ‘_’ ‘*’ +Catches ::= ‘catch‘ (Expr | ExprCaseClause) ``` Expressions are composed of operators and operands. @@ -545,6 +551,8 @@ This expression is then interpreted as ´e.\mathit{op}(e_1,...,e_n)´. A left-associative binary operation ´e_1;\mathit{op};e_2´ is interpreted as ´e_1.\mathit{op}(e_2)´. If ´\mathit{op}´ is right-associative and its parameter is passed by name, the same operation is interpreted as ´e_2.\mathit{op}(e_1)´. If ´\mathit{op}´ is right-associative and its parameter is passed by value, it is interpreted as `{ val ´x´=´e_1´; ´e_2´.´\mathit{op}´(´x\,´) }`, where ´x´ is a fresh name. +Under `-source:future`, if the method name is alphanumeric and the target method is not marked [`infix`](./05-classes-and-objects.html#infix), a deprecation warning is emitted. + ### Assignment Operators An _assignment operator_ is an operator symbol (syntax category `op` in [Identifiers](01-lexical-syntax.html#identifiers)) that ends in an equals character “`=`”, with the following exceptions: @@ -677,6 +685,7 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { ```ebnf Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] + | ‘if‘ Expr ‘then‘ Expr [[semi] ‘else‘ Expr] ``` The _conditional expression_ `if (´e_1´) ´e_2´ else ´e_3´` chooses one of the values of ´e_2´ and ´e_3´, depending on the value of ´e_1´. @@ -696,6 +705,7 @@ The conditional expression `if (´e_1´) ´e_2´` is evaluated as if it was `if ```ebnf Expr1 ::= ‘while’ ‘(’ Expr ‘)’ {nl} Expr + | ‘while’ Expr ‘do’ Expr ``` The _while loop expression_ `while (´e_1´) ´e_2´` is typed and evaluated as if it was an application of `whileLoop (´e_1´) (´e_2´)` where the hypothetical method `whileLoop` is defined as follows. @@ -866,15 +876,19 @@ The type of a throw expression is `scala.Nothing`. ## Try Expressions ```ebnf -Expr1 ::= ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] +Expr1 ::= ‘try’ Expr [Catches] [‘finally’ Expr] + +Catches ::= ‘catch‘ (Expr | ExprCaseClause) ``` -A _try expression_ is of the form `try { ´b´ } catch ´h´` where the handler ´h´ is usually a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) +A _try expression_ is of the form `try ´b´ catch ´h´` where the handler ´h´ is usually a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) ```scala { case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` +If the handler is a single `ExprCaseClause`, it is a shorthand for that `ExprCaseClause` wrapped in a pattern matching anonymous function. + This expression is evaluated by evaluating the block ´b´. If evaluation of ´b´ does not cause an exception to be thrown, the result of ´b´ is returned. Otherwise the handler ´h´ is applied to the thrown exception. @@ -883,11 +897,11 @@ If the handler contains no case matching the thrown exception, the exception is More generally, if the handler is a `PartialFunction`, it is applied only if it is defined at the given exception. Let ´\mathit{pt}´ be the expected type of the try expression. -The block ´b´ is expected to conform to ´\mathit{pt}´. +The expression ´b´ is expected to conform to ´\mathit{pt}´. The handler ´h´ is expected conform to type `scala.Function[scala.Throwable, ´\mathit{pt}\,´]`. The type of the try expression is the [least upper bound](03-types.html#least-upper-bounds-and-greatest-lower-bounds) of the type of ´b´ and the result type of ´h´. -A try expression `try { ´b´ } finally ´e´` evaluates the block ´b´. +A try expression `try ´b´ finally ´e´` evaluates the expression ´b´. If evaluation of ´b´ does not cause an exception to be thrown, the expression ´e´ is evaluated. If an exception is thrown during evaluation of ´e´, the evaluation of the try expression is aborted with the thrown exception. If no exception is thrown during evaluation of ´e´, the result of ´b´ is returned as the result of the try expression. @@ -895,10 +909,10 @@ If no exception is thrown during evaluation of ´e´, the result of ´b´ is ret If an exception is thrown during evaluation of ´b´, the finally block ´e´ is also evaluated. If another exception ´e´ is thrown during evaluation of ´e´, evaluation of the try expression is aborted with the thrown exception. If no exception is thrown during evaluation of ´e´, the original exception thrown in ´b´ is re-thrown once evaluation of ´e´ has completed. -The block ´b´ is expected to conform to the expected type of the try expression. +The expression ´b´ is expected to conform to the expected type of the try expression. The finally expression ´e´ is expected to conform to type `Unit`. -A try expression `try { ´b´ } catch ´e_1´ finally ´e_2´` is a shorthand for `try { try { ´b´ } catch ´e_1´ } finally ´e_2´`. +A try expression `try ´b´ catch ´e_1´ finally ´e_2´` is a shorthand for `try { try ´b´ catch ´e_1´ } finally ´e_2´`. ## Anonymous Functions diff --git a/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md index 3c75d1136ac7..6646b67ad39e 100644 --- a/docs/_spec/08-pattern-matching.md +++ b/docs/_spec/08-pattern-matching.md @@ -484,9 +484,12 @@ Therefore, the right hand side of the case clause, `y.n`, of type `Int`, is foun ## Pattern Matching Expressions ```ebnf + InfixExpr ::= InfixExpr MatchClause + SimpleExpr ::= SimpleExpr ‘.’ MatchClause Expr ::= PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ CaseClauses ::= CaseClause {CaseClause} CaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Block + ExprCaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Expr ``` A _pattern matching expression_ diff --git a/docs/_spec/TODOreference/changed-features/imports.md b/docs/_spec/APPLIEDreference/changed-features/imports.md similarity index 100% rename from docs/_spec/TODOreference/changed-features/imports.md rename to docs/_spec/APPLIEDreference/changed-features/imports.md diff --git a/docs/_spec/TODOreference/changed-features/interpolation-escapes.md b/docs/_spec/APPLIEDreference/changed-features/interpolation-escapes.md similarity index 100% rename from docs/_spec/TODOreference/changed-features/interpolation-escapes.md rename to docs/_spec/APPLIEDreference/changed-features/interpolation-escapes.md diff --git a/docs/_spec/TODOreference/changed-features/match-syntax.md b/docs/_spec/APPLIEDreference/changed-features/match-syntax.md similarity index 100% rename from docs/_spec/TODOreference/changed-features/match-syntax.md rename to docs/_spec/APPLIEDreference/changed-features/match-syntax.md diff --git a/docs/_spec/TODOreference/changed-features/operators.md b/docs/_spec/APPLIEDreference/changed-features/operators.md similarity index 100% rename from docs/_spec/TODOreference/changed-features/operators.md rename to docs/_spec/APPLIEDreference/changed-features/operators.md diff --git a/docs/_spec/TODOreference/changed-features/wildcards.md b/docs/_spec/APPLIEDreference/changed-features/wildcards.md similarity index 100% rename from docs/_spec/TODOreference/changed-features/wildcards.md rename to docs/_spec/APPLIEDreference/changed-features/wildcards.md diff --git a/docs/_spec/TODOreference/contextual/given-imports.md b/docs/_spec/APPLIEDreference/contextual/given-imports.md similarity index 100% rename from docs/_spec/TODOreference/contextual/given-imports.md rename to docs/_spec/APPLIEDreference/contextual/given-imports.md diff --git a/docs/_spec/TODOreference/dropped-features/wildcard-init.md b/docs/_spec/APPLIEDreference/dropped-features/wildcard-init.md similarity index 100% rename from docs/_spec/TODOreference/dropped-features/wildcard-init.md rename to docs/_spec/APPLIEDreference/dropped-features/wildcard-init.md diff --git a/docs/_spec/TODOreference/other-new-features/control-syntax.md b/docs/_spec/APPLIEDreference/other-new-features/control-syntax.md similarity index 100% rename from docs/_spec/TODOreference/other-new-features/control-syntax.md rename to docs/_spec/APPLIEDreference/other-new-features/control-syntax.md diff --git a/docs/_spec/TODOreference/soft-modifier.md b/docs/_spec/TODOreference/soft-modifier.md deleted file mode 100644 index c1329ebab1f0..000000000000 --- a/docs/_spec/TODOreference/soft-modifier.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: doc-page -title: "Soft Keywords" -nightlyOf: https://docs.scala-lang.org/scala3/reference/soft-modifier.html ---- - -A soft modifier is one of the identifiers `infix`, `inline`, `opaque`, `open` and `transparent`. - -A soft keyword is a soft modifier, or one of `as`, `derives`, `end`, `extension`, `throws`, `using`, `|`, `+`, `-`, `*` - -A soft modifier is treated as potential modifier of a definition if it is followed by a hard modifier or a keyword combination starting a definition (`def`, `val`, `var`, `type`, `given`, `class`, `trait`, `object`, `enum`, `case class`, `case object`). Between the two words there may be a sequence of newline tokens and soft modifiers. - -Otherwise, soft keywords are treated specially in the following situations: - - - `inline`, if it is followed by any token that can start an expression. - - `derives`, if it appears after an extension clause or after - the name and possibly parameters of a class, trait, object, or enum definition. - - `end`, if it appears at the start of a line following a statement (i.e. definition or toplevel expression) - - `extension`, if it appears at the start of a statement and is followed by `(` or `[`. - - `using`, if it appears at the start of a parameter or argument list. - - `as`, in a renaming import clause - - `|`, if it separates two patterns in an alternative. - - `+`, `-`, if they appear in front of a type parameter. - - `*`, in a wildcard import, or it follows the type of a parameter, or if it appears in - a vararg splice `x*`. - -Everywhere else a soft keyword is treated as a normal identifier.