Skip to content

Commit 0b27321

Browse files
committed
Fixes to erased and others
1 parent 44f7575 commit 0b27321

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+187
-282
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ class Definitions {
9898
* ErasedFunctionN traits follow this template:
9999
*
100100
* trait ErasedFunctionN[T0,...,T{N-1}, R] extends Object {
101-
* def apply erased ($x0: T0, ..., $x{N_1}: T{N-1}): R
101+
* def apply(erased $x0: T0, ..., $x{N_1}: T{N-1}): R
102102
* }
103103
*
104104
* ErasedImplicitFunctionN traits follow this template:
105105
*
106106
* trait ErasedImplicitFunctionN[T0,...,T{N-1}, R] extends Object {
107-
* def apply given erased ($x0: T0, ..., $x{N_1}: T{N-1}): R
107+
* def apply (given erased $x0: T0, ..., $x{N_1}: T{N-1}): R
108108
* }
109109
*
110110
* ErasedFunctionN and ErasedImplicitFunctionN erase to Function0.

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Standard-Section: "ASTs" TopLevelStat*
167167
METHODtype Length result_Type NamesTypes -- A method type `(NamesTypes)result`, needed for refinements
168168
ERASEDMETHODtype Length result_Type NamesTypes -- A method type `erased (NamesTypes)result`, needed for refinements
169169
GIVENMETHODtype Length result_Type NamesTypes -- A method type `given (NamesTypes)result`, needed for refinements
170-
ERASEDGIVENMETHODtype Length result_Type NamesTypes -- A method type `given erased (NamesTypes)result`, needed for refinements
170+
ERASEDGIVENMETHODtype Length result_Type NamesTypes -- A method type `given(erased NamesTypes)result`, needed for refinements
171171
IMPLICITMETHODtype Length result_Type NamesTypes -- A method type `(implicit NamesTypes)result`, needed for refinements
172172
// TODO: remove ERASEDIMPLICITMETHODtype
173173
TYPELAMBDAtype Length result_Type NamesTypes -- A type lambda `[NamesTypes] => result`, variance encoded using VARIANT names

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 34 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ object Parsers {
3333
import reporting.diagnostic.Message
3434
import reporting.diagnostic.messages._
3535

36-
private inline val allowOldGiven = true
37-
private inline val allowOldExtension = true
38-
3936
case class OpInfo(operand: Tree, operator: Ident, offset: Offset)
4037

4138
class ParensCounters {
@@ -210,8 +207,7 @@ object Parsers {
210207
} && !in.isSoftModifierInModifierPosition
211208

212209
def isExprIntro: Boolean =
213-
if (in.token == GIVEN) false
214-
else canStartExpressionTokens.contains(in.token) && !in.isSoftModifierInModifierPosition
210+
canStartExpressionTokens.contains(in.token) && !in.isSoftModifierInModifierPosition
215211

216212
def isDefIntro(allowedMods: BitSet, excludedSoftModifiers: Set[TermName] = Set.empty): Boolean =
217213
in.token == AT ||
@@ -928,11 +924,6 @@ object Parsers {
928924
}
929925
else recur(operand())
930926
}
931-
else if (in.token == GIVEN && allowOldGiven && !isType) {
932-
val top1 = reduceStack(base, top, minInfixPrec, leftAssoc = true, nme.WITHkw, isType)
933-
assert(opStack `eq` base)
934-
recur(applyGiven(top1, operand))
935-
}
936927
else reduceStack(base, top, minPrec, leftAssoc = true, in.name, isType)
937928

938929
recur(first)
@@ -1652,14 +1643,14 @@ object Parsers {
16521643
t
16531644
}
16541645

1655-
/** Expr ::= [ClosureMods] FunParams =>' Expr
1646+
/** Expr ::= [`implicit'] FunParams =>' Expr
16561647
* | Expr1
16571648
* FunParams ::= Bindings
16581649
* | id
16591650
* | `_'
16601651
* ExprInParens ::= PostfixExpr `:' Type
16611652
* | Expr
1662-
* BlockResult ::= [ClosureMods] FunParams =>' Block
1653+
* BlockResult ::= [‘implicit’] FunParams =>' Block
16631654
* | Expr1
16641655
* Expr1 ::= [‘inline’] `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
16651656
* | [‘inline’] `if' Expr `then' Expr [[semi] else Expr]
@@ -1689,10 +1680,10 @@ object Parsers {
16891680

16901681
def expr(location: Location.Value): Tree = {
16911682
val start = in.offset
1692-
if closureMods.contains(in.token) && allowOldGiven then
1693-
implicitClosure(start, location, modifiers(closureMods))
1683+
if in.token == IMPLICIT then
1684+
closure(start, location, modifiers(BitSet(IMPLICIT)))
16941685
else if in.token == LPAREN && in.lookaheadIn(funTypeArgMods) then
1695-
implicitClosure(start, location, modifiers())
1686+
closure(start, location, Modifiers())
16961687
else {
16971688
val saved = placeholderParams
16981689
placeholderParams = Nil
@@ -1951,10 +1942,10 @@ object Parsers {
19511942
}
19521943
else ident()
19531944

1954-
/** Expr ::= ClosureMods FunParams `=>' Expr
1945+
/** Expr ::= [‘implicit’] FunParams `=>' Expr
19551946
* BlockResult ::= implicit id [`:' InfixType] `=>' Block // Scala2 only
19561947
*/
1957-
def implicitClosure(start: Int, location: Location.Value, implicitMods: Modifiers): Tree =
1948+
def closure(start: Int, location: Location.Value, implicitMods: Modifiers): Tree =
19581949
closureRest(start, location, funParams(implicitMods, location))
19591950

19601951
def closureRest(start: Int, location: Location.Value, params: List[Tree]): Tree =
@@ -2615,15 +2606,6 @@ object Parsers {
26152606
normalize(loop(start))
26162607
}
26172608

2618-
/** ClosureMods ::= { ‘implicit’ | ‘erased’ | ‘given’}
2619-
* FunTypeMods ::= { ‘erased’ | ‘given’}
2620-
*/
2621-
val closureMods: BitSet =
2622-
if allowOldGiven then BitSet(GIVEN, IMPLICIT, ERASED)
2623-
else BitSet(IMPLICIT, ERASED)
2624-
2625-
val funTypeMods: BitSet = BitSet(ERASED)
2626-
26272609
val funTypeArgMods: BitSet = BitSet(GIVEN, ERASED)
26282610

26292611
/** Wrap annotation or constructor in New(...).<init> */
@@ -2735,9 +2717,9 @@ object Parsers {
27352717
ofClass: Boolean = false, // owner is a class
27362718
ofCaseClass: Boolean = false, // owner is a case class
27372719
prefix: Boolean = false, // clause precedes name of an extension method
2738-
firstClause: Boolean = false, // clause is the first in regular list of clauses
2739-
initialMods: Modifiers = EmptyModifiers): List[ValDef] = {
2740-
var impliedMods: Modifiers = initialMods
2720+
firstClause: Boolean = false // clause is the first in regular list of clauses
2721+
): List[ValDef] = {
2722+
var impliedMods: Modifiers = EmptyModifiers
27412723

27422724
def impliedModOpt(token: Token, mod: () => Mod): Boolean =
27432725
if in.token == token then
@@ -2826,47 +2808,35 @@ object Parsers {
28262808
*/
28272809
def paramClauses(ofClass: Boolean = false,
28282810
ofCaseClass: Boolean = false,
2829-
ofInstance: Boolean = false): List[List[ValDef]] = {
2811+
ofInstance: Boolean = false): List[List[ValDef]] =
28302812

2831-
def recur(firstClause: Boolean, nparams: Int, contextualOnly: Boolean): List[List[ValDef]] = {
2832-
var initialMods = EmptyModifiers
2833-
val isNewLine = in.token == NEWLINE
2834-
newLineOptWhenFollowedBy(LPAREN)
2835-
if (in.token == GIVEN && allowOldGiven) {
2836-
in.nextToken()
2837-
initialMods |= Given
2838-
}
2839-
if (in.token == ERASED && allowOldGiven) {
2840-
in.nextToken()
2841-
initialMods |= Erased
2842-
}
2843-
var isGiven = initialMods.is(Given)
2813+
def recur(firstClause: Boolean, nparams: Int, contextualOnly: Boolean): List[List[ValDef]] =
28442814
newLineOptWhenFollowedBy(LPAREN)
2845-
if in.token == LPAREN && (!isGiven || followingIsParamOrGivenType()) then
2815+
if in.token == LPAREN then
28462816
val paramsStart = in.offset
28472817
val params = paramClause(
28482818
nparams,
28492819
ofClass = ofClass,
28502820
ofCaseClass = ofCaseClass,
2851-
firstClause = firstClause,
2852-
initialMods = initialMods)
2853-
params match
2854-
case param :: _ if param.mods.flags.is(Given) => isGiven = true
2821+
firstClause = firstClause)
2822+
val isGiven = params match
2823+
case param :: _ if param.mods.flags.is(Given) => true
28552824
case _ =>
28562825
if contextualOnly then
28572826
syntaxError(
28582827
if ofInstance then em"parameters of instance definitions must be `given' clauses"
28592828
else em"normal parameters cannot come after `given' clauses",
28602829
paramsStart)
2830+
false
28612831
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit)
2862-
params :: (if (lastClause) Nil else recur(firstClause = false, nparams + params.length, isGiven))
2863-
else if isGiven then
2864-
val params = givenTypes(false, nparams, ofClass)
2865-
params :: recur(firstClause = false, nparams + params.length, isGiven)
2832+
params :: (
2833+
if lastClause then Nil
2834+
else recur(firstClause = false, nparams + params.length, isGiven))
28662835
else Nil
2867-
}
2836+
end recur
2837+
28682838
recur(firstClause = true, 0, ofInstance)
2869-
}
2839+
end paramClauses
28702840

28712841
/* -------- DEFS ------------------------------------------- */
28722842

@@ -2880,9 +2850,7 @@ object Parsers {
28802850
*/
28812851
def importClause(leading: Token, mkTree: ImportConstr): List[Tree] = {
28822852
val offset = accept(leading)
2883-
val importGiven = allowOldGiven && in.token == GIVEN
2884-
if (importGiven) in.nextToken()
2885-
commaSeparated(importExpr(importGiven, mkTree)) match {
2853+
commaSeparated(importExpr(mkTree)) match {
28862854
case t :: rest =>
28872855
// The first import should start at the start offset of the keyword.
28882856
val firstPos =
@@ -2899,12 +2867,12 @@ object Parsers {
28992867
* | ‘given’
29002868
* | ‘{’ ImportSelectors) ‘}’
29012869
*/
2902-
def importExpr(importGiven: Boolean, mkTree: ImportConstr): () => Tree = {
2870+
def importExpr(mkTree: ImportConstr): () => Tree = {
29032871

29042872
/** '_' | 'given'
29052873
*/
29062874
def wildcardSelectorId() =
2907-
val name = if importGiven || in.token == GIVEN then nme.EMPTY else nme.WILDCARD
2875+
val name = if in.token == GIVEN then nme.EMPTY else nme.WILDCARD
29082876
atSpan(in.skipToken()) { Ident(name) }
29092877

29102878
/** ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
@@ -3404,37 +3372,9 @@ object Parsers {
34043372
/** SimpleConstrApp ::= AnnotType {ParArgumentExprs}
34053373
*/
34063374
val constrApp: () => Tree = () => {
3407-
3408-
def isAnnotType(t: Tree) = t match {
3409-
case _: Ident
3410-
| _: Select
3411-
| _: AppliedTypeTree
3412-
| _: Tuple
3413-
| _: Parens
3414-
| _: RefinedTypeTree
3415-
| _: SingletonTypeTree
3416-
| _: TypSplice
3417-
| _: Annotated => true
3418-
case _ => false
3419-
}
3420-
3421-
def givenArgs(t: Tree): Tree =
3422-
if (in.token == GIVEN) givenArgs(applyGiven(t, prefixExpr)) else t
3423-
3424-
if (allowOldGiven && in.token == LPAREN)
3425-
inParens {
3426-
val t = toplevelTyp()
3427-
if (isAnnotType(t))
3428-
if (in.token == LPAREN) givenArgs(parArgumentExprss(wrapNew(t)))
3429-
else if (in.token == GIVEN) givenArgs(wrapNew(t))
3430-
else t
3431-
else Parens(t)
3432-
}
3433-
else {
3434-
val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR))
3435-
// Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
3436-
if (in.token == LPAREN) parArgumentExprss(wrapNew(t)) else t
3437-
}
3375+
val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR))
3376+
// Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
3377+
if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t
34383378
}
34393379

34403380
/** ConstrApps ::= ConstrApp {‘with’ ConstrApp} (to be deprecated in 3.1)
@@ -3682,29 +3622,12 @@ object Parsers {
36823622
setLastStatOffset()
36833623
if (in.token == IMPORT)
36843624
stats ++= importClause(IMPORT, Import)
3685-
else if (in.token == GIVEN) {
3686-
val start = in.offset
3687-
val mods = modifiers(closureMods)
3688-
mods.mods match {
3689-
case givenMod :: Nil if !isBindingIntro =>
3690-
stats += instanceDef(start, EmptyModifiers, Mod.Given().withSpan(givenMod.span))
3691-
case _ =>
3692-
stats += implicitClosure(in.offset, Location.InBlock, mods)
3693-
}
3694-
}
36953625
else if (isExprIntro)
36963626
stats += expr(Location.InBlock)
3697-
else if (isDefIntro(localModifierTokens, excludedSoftModifiers = Set(nme.`opaque`)))
3698-
if (closureMods.contains(in.token)) {
3699-
val start = in.offset
3700-
var imods = modifiers(closureMods)
3701-
if (isBindingIntro)
3702-
stats += implicitClosure(start, Location.InBlock, imods)
3703-
else
3704-
stats +++= localDef(start, imods)
3705-
}
3706-
else
3707-
stats +++= localDef(in.offset)
3627+
else if in.token == IMPLICIT && !in.inModifierPosition() then
3628+
stats += closure(in.offset, Location.InBlock, modifiers(BitSet(IMPLICIT)))
3629+
else if isDefIntro(localModifierTokens, excludedSoftModifiers = Set(nme.`opaque`)) then
3630+
stats +++= localDef(in.offset)
37083631
else if (!isStatSep && (in.token != CASE)) {
37093632
exitOnError = mustStartStat
37103633
syntaxErrorOrIncomplete(IllegalStartOfStatement(isModifier))

compiler/test-resources/repl/erased

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
scala> def f erased (a: Int): Int = ???
2-
def f erased (a: Int): Int
1+
scala> def f(erased a: Int): Int = ???
2+
def f(erased a: Int): Int
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
scala> def f given erased (a: Int): Int = ???
2-
def f given erased (a: Int): Int
1+
scala> def f(given erased a: Int): Int = ???
2+
def f(given erased a: Int): Int

docs/docs/internals/syntax.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ TypeParamBounds ::= SubtypeBounds {‘:’ Type}
180180

181181
### Expressions
182182
```ebnf
183-
Expr ::= [ClosureMods] FunParams ‘=>’ Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
183+
Expr ::= [‘implicit’] FunParams ‘=>’ Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr)
184184
| Expr1
185-
BlockResult ::= [ClosureMods] FunParams ‘=>’ Block
185+
BlockResult ::= [‘implicit’] FunParams ‘=>’ Block
186186
| Expr1
187187
FunParams ::= Bindings
188188
| id

docs/docs/reference/metaprogramming/erased-terms-spec.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ title: "Erased Terms Spec"
1616
erased val x = ...
1717
erased def f = ...
1818

19-
def g erased (x: Int) = ...
19+
def g(erased x: Int) = ...
2020

21-
erased (x: Int) => ...
22-
def h(x: erased Int => Int) = ...
21+
(erased x: Int) => ...
22+
def h(x: (erased Int) => Int) = ...
2323

24-
class K erased (x: Int) { ... }
24+
class K(erased x: Int) { ... }
2525
```
2626

2727

@@ -31,25 +31,25 @@ title: "Erased Terms Spec"
3131

3232

3333
3. Functions
34-
* `erased (x1: T1, x2: T2, ..., xN: TN) => y : erased (T1, T2, ..., TN) => R`
35-
* `given erased (x1: T1, x2: T2, ..., xN: TN) => y : given erased (T1, T2, ..., TN) => R`
36-
* `given erased T1 => R <:< erased T1 => R`
37-
* `given erased (T1, T2) => R <:< erased (T1, T2) => R`
34+
* `(erased x1: T1, x2: T2, ..., xN: TN) => y : (erased T1, T2, ..., TN) => R`
35+
* `(given erased x1: T1, x2: T2, ..., xN: TN) => y : (given erased T1, T2, ..., TN) => R`
36+
* `(given erased T1) => R <:< erased T1 => R`
37+
* `(given erased T1, T2) => R <:< (erased T1, T2) => R`
3838
* ...
3939

40-
Note that there is no subtype relation between `erased T => R` and `T => R` (or `given erased T => R` and `given T => R`)
40+
Note that there is no subtype relation between `(erased T) => R` and `T => R` (or `(given erased T) => R` and `(given T) => R`)
4141

4242

4343
4. Eta expansion
4444

45-
if `def f erased (x: T): U` then `f: erased (T) => U`.
45+
if `def f(erased x: T): U` then `f: (erased T) => U`.
4646

4747

4848
5. Erasure Semantics
4949
* All `erased` parameters are removed from the function
5050
* All argument to `erased` parameters are not passed to the function
5151
* All `erased` definitions are removed
52-
* All ` erased (T1, T2, ..., TN) => R` and `(given erased T1, T2, ..., TN) => R` become `() => R`
52+
* All `(erased T1, T2, ..., TN) => R` and `(given erased T1, T2, ..., TN) => R` become `() => R`
5353

5454

5555
6. Overloading
@@ -59,5 +59,5 @@ title: "Erased Terms Spec"
5959

6060
7. Overriding
6161
* Member definitions overriding each other must both be `erased` or not be `erased`
62-
* `def foo(x: T): U` cannot be overridden by `def foo erased (x: T): U` an vice-versa
62+
* `def foo(x: T): U` cannot be overridden by `def foo(erased x: T): U` an vice-versa
6363

0 commit comments

Comments
 (0)