summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-08-14 18:36:02 +0000
committerMartin Odersky <odersky@gmail.com>2003-08-14 18:36:02 +0000
commitdf43fa3f64f2bff8321246684e731243b0fe93ea (patch)
treeab5d83cce3ad2c22f213cb60dac4e47f3d842d8f
parentf92d38c415f89214dfea5e86f79e091b2c573551 (diff)
downloadscala-df43fa3f64f2bff8321246684e731243b0fe93ea.tar.gz
scala-df43fa3f64f2bff8321246684e731243b0fe93ea.tar.bz2
scala-df43fa3f64f2bff8321246684e731243b0fe93ea.zip
*** empty log message ***
-rw-r--r--doc/reference/reference.verb.tex440
-rw-r--r--sources/meta/scalac/ast/Tree.java17
-rw-r--r--sources/scala/List.scala2
-rw-r--r--sources/scala/Predef.scala10
-rw-r--r--sources/scala/Some.scala2
-rw-r--r--sources/scalac/Global.java3
-rw-r--r--sources/scalac/ast/SubstTransformer.java4
-rw-r--r--sources/scalac/ast/TreeGen.java57
-rw-r--r--sources/scalac/ast/TreeInfo.java11
-rw-r--r--sources/scalac/ast/parser/Parser.java20
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java34
-rw-r--r--sources/scalac/backend/jvm/GenJVM.java6
-rw-r--r--sources/scalac/backend/jvm/GenJVMBCEL.java3
-rw-r--r--sources/scalac/checkers/CheckOwners.java17
-rw-r--r--sources/scalac/symtab/Definitions.java14
-rw-r--r--sources/scalac/symtab/EntryTags.java2
-rw-r--r--sources/scalac/symtab/Symbol.java275
-rw-r--r--sources/scalac/symtab/Type.java2
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java2
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java11
-rw-r--r--sources/scalac/transformer/AddAccessors.java2
-rw-r--r--sources/scalac/transformer/AddInterfaces.java2
-rw-r--r--sources/scalac/transformer/AddInterfacesPhase.java2
-rw-r--r--sources/scalac/transformer/Erasure.java14
-rw-r--r--sources/scalac/transformer/LambdaLift.java34
-rw-r--r--sources/scalac/transformer/OwnerTransformer.java27
-rw-r--r--sources/scalac/transformer/UnCurry.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java193
-rw-r--r--sources/scalac/typechecker/DeSugarize.java12
-rw-r--r--sources/scalac/typechecker/Infer.java4
-rw-r--r--sources/scalac/typechecker/RefCheck.java25
31 files changed, 752 insertions, 499 deletions
diff --git a/doc/reference/reference.verb.tex b/doc/reference/reference.verb.tex
index 4e6ddda520..1a72c7d9d7 100644
--- a/doc/reference/reference.verb.tex
+++ b/doc/reference/reference.verb.tex
@@ -20,11 +20,11 @@
Martin Odersky \\
Philippe Altherr \\
Vincent Cremet \\
-Burak Emir \\
+Burak Emir \\ \\
+St\'ephane Micheloud
Nikolay Mihaylov \\
Michel Schinz \\
-Matthias Zenger \\
-St\'ephane Micheloud
+Matthias Zenger
\\ \
\\
EPFL}
@@ -293,19 +293,6 @@ Here are examples of identifiers:
+ \> +_field
\end{verbatim}
-\section{Symbols}
-
-\syntax\begin{verbatim}
-symbolLit ::= `\'` id
-\end{verbatim}
-
-A symbol literal has the form \verb@'x@ where $x$ is an identifier.
-Such a symbol literal is a shorthand for the application
-\begin{verbatim}
-scala.Symbol("x")
-\end{verbatim}
-of the facotry method for the standard case class \verb@Symbol@ to the string "x".
-
\section{Braces and Semicolons}
A semicolon `\verb@;@' is implicitly inserted after every closing brace
@@ -336,7 +323,15 @@ intLit \>::= \> ``as in Java''
floatLit \>::= \> ``as in Java''
charLit \>::= \> ``as in Java''
stringLit \>::= \> ``as in Java''
+symbolLit ::= `\'` id
+\end{verbatim}
+
+A symbol literal has the form \verb@'x@ where \verb@x@ is an identifier.
+Such a symbol literal is a shorthand for the application
+\begin{verbatim}
+scala.Symbol("x")
\end{verbatim}
+of the facotry method for the standard case class \verb@Symbol@ to the string "x".
\section{Whitespace and Comments}
@@ -352,11 +347,6 @@ A multi-line comment is a sequence of characters between \verb@/*@ and
\chapter{\label{sec:names}Identifiers, Names and Scopes}
-\syntax\begin{verbatim}
- Id \=::= \= id | `+' | `-' | `!'
- QualId \>::> \= Id {`.' Id}
-\end{verbatim}
-
Names in Scala identify types, values, functions, and classes which
are collectively called {\em entities}. Names are introduced by
definitions, declarations (\sref{sec:defs}) or import clauses
@@ -375,8 +365,6 @@ introduced by a preceding import clause, even if the import clause is
in the same block. Import clauses, on the other hand, only shadow
bindings introduced by other import clauses in outer blocks.
-\todo{Examples}
-
A reference to an unqualified (type- or term-) identifier $x$ is bound
by the unique binder, which
\begin{itemize}
@@ -391,6 +379,25 @@ then $x$ refers to the entity introduced by that
binder. In that case, the type of $x$ is the type of the referenced
entity.
+\example Consider the following nested definitions and imports:
+
+\begin{verbatim}
+object m1 {
+ object m2 { val x: int = 1; val y: int = 2 }
+ object m3 { val x: boolean = true; val y: String = "" }
+ val x: int = 3;
+ { import m2._; \= // shadows nothing
+ \> // reference to `x' is ambiguous here
+ val x: String = "abc"; \> // shadows preceding import and val
+ \> // `x' refers to latest val definition
+ { import m3._ \> // shadows only preceding import m2
+ \> // reference to `x' is ambiguous here
+ \> // `y' refers to latest import clause
+ }
+ }
+}
+\end{verbatim}
+
A reference to a qualified (type- or term-) identifier $e.x$ refers to
the member of the type $T$ of $e$ which has the name $x$ in the same
namespace as the identifier. It is an error if $T$ is not an object type
@@ -405,7 +412,7 @@ referenced entity in $T$.
\> |\> Type1
Type1 \>::= \> SimpleType {with SimpleType} [Refinement]
SimpleType \>::= \> StableId
- \> |\> SimpleType `#' Id
+ \> |\> SimpleType `#' id
\> |\> Path `.' type
\> |\> SimpleType TypeArgs
\> |\> `(' Type ')'
@@ -439,11 +446,10 @@ types directly in Scala.
\section{Paths}\label{sec:paths}
\syntax\begin{verbatim}
- StableId \=::= \= Id
- \> |\> Path `.' Id
- \> |\> [Ident '.'] super `.' Id
+ StableId \=::= \= id
+ \> |\> Path `.' id \> |\> [id '.'] super `.' id
Path \>::=\> StableId
- \> |\> [Ident `.'] this
+ \> |\> [id `.'] this
\end{verbatim}
Paths are not types themselves, but they can be a part of named types
@@ -487,7 +493,7 @@ exactly the value denoted by \verb@p@.
\label{sec:type-project}
\syntax\begin{verbatim}
-SimpleType ::= SimpleType `#' Id
+SimpleType ::= SimpleType `#' id
\end{verbatim}
A type projection \verb@T#x@ references the type member named
@@ -633,14 +639,14 @@ report as the internal types of defined identifiers.
\subsection{Method Types}
\label{sec:method-types}
-A method type is denoted internally as $(ps)U$, where $(ps)$ is a
-parameter section $(x_1: T_1 \commadots x_n: T_n)$ for some $n \geq 0$
+A method type is denoted internally as $(Ts)U$, where $(Ts)$ is a
+sequence of types $(T_1 \commadots T_n)$ for some $n \geq 0$
and $U$ is a (value or method) type. This type represents named
-methods that take arguments $x_1 \commadots x_n$ of types $T_1
-\commadots T_n$ and that return a result of type $U$.
+methods that take arguments of types $T_1 \commadots T_n$
+and that return a result of type $U$.
-Method types associate to the right: $(ps_1)(ps_2)U$ is treated as
-$(ps_1)((ps_2)U)$.
+Method types associate to the right: $(Ts_1)(Ts_2)U$ is treated as
+$(Ts_1)((Ts_2)U)$.
A special case are types of methods without any parameters. They are
written here $[]T$, following the syntax for polymorphic method types
@@ -661,8 +667,8 @@ def c (x: Int) (y: String, z: String): String
produce the typings
\begin{verbatim}
a: [] Int
-b: (x: Int) Boolean
-c: (x: Int) (y: String, z: String) String
+b: (Int) Boolean
+c: (Int) (String, String) String
\end{verbatim}
\subsection{Polymorphic Method Types}
@@ -703,20 +709,20 @@ T_n$ $(n \geq 2)$ is denoted internally $T_1 \overload \ldots
\example The definitions
\begin{verbatim}
-def println: Unit;
-def println(s: String): Unit = ...;
-def println(x: Float): Unit = ...;
-def println(x: Float, width: Int): Unit = ...;
-def println[a](x: a)(tostring: a => String): Unit = ...
+def println: unit;
+def println(s: string): unit = ...;
+def println(x: float): unit = ...;
+def println(x: float, width: int): unit = ...;
+def println[a](x: a)(tostring: a => String): unit = ...
\end{verbatim}
define a single function \verb@println@ which has an overloaded
type.
\begin{verbatim}
-println: \= [] Unit $\overload$
- \> (s: String) Unit $\overload$
- \> (x: Float) Unit $\overload$
- \> (x: Float, width: Int) Unit $\overload$
- \> [a] (x: a) (tostring: a => String) Unit
+println: \= [] unit $\overload$
+ \> (String) unit $\overload$
+ \> (float) unit $\overload$
+ \> (float, int) unit $\overload$
+ \> [a] (a) (a => String) unit
\end{verbatim}
\example The definitions
@@ -904,8 +910,8 @@ transitive relation that satisfies the following conditions.
the compound type \verb@T$_1$ with ... with T$_n$ {R}@.
\item If
$T'_i$ conforms to $T_i$ for $i = 1 \commadots n$ and $U$ conforms to $U'$
- then the method type $(x_1: T_1 \commadots x_n: T_n) U$ conforms to
- $(x_1: T'_1 \commadots x_n: T'_n) U'$.
+ then the method type $(T_1 \commadots T_n) U$ conforms to
+ $(T'_1 \commadots T'_n) U'$.
\item If, assuming
$L'_1 \conforms a_1 \conforms U'_1 \commadots L'_n \conforms a_n \conforms U'_n$
one has $L_i \conforms L'_i$ and $U'_i \conforms U_i$
@@ -966,11 +972,11 @@ The erasure mapping is defined as follows.
If $S \conforms T$, then values of type $S$ are implicitly {\em
converted} to values type of $T$ in situations where a value of type
-$T$ is required. A conversion between two number types in \verb@Int@,
-\verb@Long@, \verb@Float@, \verb@Double@ creates a value of the target
+$T$ is required. A conversion between two number types in \verb@int@,
+\verb@long@, \verb@float@, \verb@double@ creates a value of the target
type representing the same number as the source. When used in an
-expression, a value of type \verb@Byte@, \verb@Char@, \verb@Short@ is
-always implicitly converted to a value of type \verb@Int@.
+expression, a value of type \verb@byte@, \verb@char@, \verb@short@ is
+always implicitly converted to a value of type \verb@int@.
The following implicit conversions are applied to expressions of
method type that are used as values, rather than being applied to some
@@ -991,10 +997,11 @@ implicitly embedding \verb@e@ in the type application
\verb@e[U$_1$, ..., U$_n$]@ (\sref{sec:type-app}).
\item
An expression \verb@e@ of monomorphic method type
-$(ps_1) \ldots (ps_n) U$ of arity $n > 0$
+$(Ts_1) \ldots (Ts_n) U$ of arity $n > 0$
which does not appear as the function part of an application is
converted to a function type by implicitly embedding $e$ in
-the following term, where $x$ is a fresh variable:
+the following term, where $x$ is a fresh variable and each $ps_i$ is a
+parameter section with fresh parameter names of types $Ts_i$.
\begin{verbatim}
(val $x$ = $e$ ; $(ps_1) \ldots \Arrow \ldots \Arrow (ps_n) \Arrow x;(ps_1);\ldots;(ps_n)$)
\end{verbatim}
@@ -1035,14 +1042,9 @@ The scope of a name introduced by a declaration or definition is the
whole statement sequence containing the binding. However, there is a
restriction on forward references: In a statement sequence $s_1 \ldots
s_n$, if a simple name in $s_i$ refers to an entity defined by $s_j$
-where $j \geq i$, then all non-empty statements between and including
-$s_i$ and $s_j$ must be imports or pure definitions (\sref{sec:statements}).
-
-A {\em pure} definition can be evaluated without any side effect.
-Function, type, class, or object definitions are always pure. A value
-definition is pure if its right-hand side expression is pure. Pure
-expressions are paths, literals, as well as typed expressions
-\verb@e: T@ where \verb@e@ is pure.
+where $j \geq i$, then every non-empty statement between and including
+$s_i$ and $s_j$ must be an import clause,
+or a function, type, class, or object definition.
\comment{
Every basic definition may introduce several defined names, separated
@@ -1081,7 +1083,7 @@ the type definition
\syntax\begin{verbatim}
Dcl \=::= \= val ValDcl {`,' ValDcl}
- ValDcl \>::= \> Id `:' Type
+ ValDcl \>::= \> id `:' Type
Def \>::= \> val PatDef {`,' PatDef}
PatDef \>::= \> Pattern `=' Expr
\end{verbatim}
@@ -1089,11 +1091,11 @@ the type definition
A value declaration \verb@val x: T@ introduces \verb@x@ as a name of a value of
type \verb@T@.
-A value definition \verb@val x: T = e@ defines $x$ as a name of the value
-that results from the evaluation of $e$. The type $T$ may be omitted
-if it can be determined using local type inference
-(\sref{sec:local-type-inf}). The type of the expression $e$ must
-conform to type $T$.
+A value definition \verb@val x: T = e@ defines $x$ as a name of the
+value that results from the evaluation of $e$. The type $T$ may be
+omitted, in which case the type of expression $e$ is assumed.
+If a type $T$ is given, then $e$ is expected to conform to it.
+\todo{explain is expected to conform}
Evaluation of the value definition implies evaluation of its
right-hand side $e$. The effect of the value definition is to bind
@@ -1150,9 +1152,9 @@ val xs = x$\Dollar$._2;
\syntax\begin{verbatim}
Dcl \=::= \= var VarDcl {`,' VarDcl}
Def \>::= \> var ValDef {`,' ValDef}
- VarDcl \>::=\> Id `:' Type
- VarDef \>::=\> Id [`:' Type] `=' Expr
- \> |\> Id `:' Type `=' `_'
+ VarDcl \>::=\> id `:' Type
+ VarDef \>::=\> id [`:' Type] `=' Expr
+ \> |\> id `:' Type `=' `_'
\end{verbatim}
A variable declaration \verb@var x: T@ is equivalent to declarations
@@ -1160,7 +1162,7 @@ of a {\em getter function} \verb@x@ and a {\em setter function}
\verb@x_=@, defined as follows:
\begin{verbatim}
- def x: T
+ def x: T;
def x_= (y: T): unit
\end{verbatim}
@@ -1171,7 +1173,8 @@ define setter and getter functions directly.
A variable definition \verb@var x: T = e@ introduces a mutable
variable with type \verb@T@ and initial value as given by the
expression \verb@e@. The type $T$ can be omitted,
-in which case the type of $e$ is assumed.
+in which case the type of $e$ is assumed. If $T$ is given, then \verb@e@
+is expected to conform to it.
A variable definition \verb@var x: T = _@ introduces a mutable
variable with type \verb@T@ and a default initial value.
@@ -1179,7 +1182,7 @@ The default value depends on the type \verb@T@ as follows:
\begin{quote}\begin{tabular}{ll}
\verb@0@ & if $T$ is \verb@int@ or one of its subrange types, \\
\verb@0L@ & if $T$ is \verb@long@,\\
-\verb@0.0f@ & if $T$ is \verb@Float@,\\
+\verb@0.0f@ & if $T$ is \verb@float@,\\
\verb@0.0d@ & if $T$ is \verb@double@,\\
\verb@false@ & if $T$ is \verb@boolean@,\\
\verb@()@ & if $T$ is \verb@unit@, \\
@@ -1191,6 +1194,8 @@ defintion also introduce a getter function \verb@x@ which returns the
value currently assigned to the variable, as well as a setter function
\verb@x_=@ which changes the value currently assigned to the variable.
The functions have the same signatures as for a variable declaration.
+The getter and setter functions, are then members of the template
+instead of the variable accessed by them.
\example The following example shows how {\em properties} can be
simulated in Scala. It defines a class \verb@TimeOfDayVar@ of time
@@ -1223,9 +1228,9 @@ d.hours = 25; \=// throws a DateError exception
\syntax\begin{verbatim}
Dcl \=::= \= type TypeDcl {`,' TypeDcl}
- TypeDcl \>::= \> Id [>: Type] [<: Type]
+ TypeDcl \>::= \> id [>: Type] [<: Type]
Def \>::= \> type TypeDef {`,' TypeDef}
- TypeDef \>::= \> Id `=' Type
+ TypeDef \>::= \> id [TypeParamClause] `=' Type
\end{verbatim}
A {\em type declaration} \verb@type t >: L <: U@ declares \verb@t@ to
@@ -1244,15 +1249,16 @@ collectively called {\em type bindings}.
The scope rules for definitions (\sref{sec:defs}) and type parameters
(\sref{sec:funsigs}) make it possible that a type name appears in its
own bound or in its right-hand side. However, it is a static error if
-a type alias refers recursively to the defined type itself. That is,
-the type \verb@T@ in a type alias \verb@type t = T@ may not refer
+a type alias refers recursively to the defined type constructor itself.
+That is, the type \verb@T@ in a type alias \verb@type t[tps] = T@ may not refer
directly or indirectly to the name \verb@t@. It is also an error if
an abstract type is directly or indirectly its own bound.
\example The following are legal type declarations and definitions:
\begin{verbatim}
type IntList = List[Integer];
-type T extends Comparable[T];
+type T <: Comparable[T];
+type Two[a] = Tuple2[a, a];
\end{verbatim}
The following are illegal:
@@ -1269,14 +1275,14 @@ type T >: Comparable[T.That]; \>// Cannot select from T.
\>// T is a type, not a value
\end{verbatim}
-Neither type declarations nor type aliases may carry type
-parameters. However, it is possible to alias a type constructor of a
-parameterized type, as is shown in the following example.
+If a type alias \verb@type t[tps] = S@ refers to a class type
+\verb@S@, the name \verb@t@ can also be used as a constructor for
+objects of type \verb@S@.
\example The \verb@Predef@ module contains a definition which establishes \verb@Pair@
as an alias of the parameterized class \verb@Tuple2@:
\begin{verbatim}
-type Pair = Tuple2;
+type Pair[+a, +b] = Tuple2[a, b];
\end{verbatim}
As a consequence, for any two types \verb@S@ and \verb@T@, the type
\verb@Pair[S, T]@ is equivalent to the type \verb@Tuple2[S, T]@.
@@ -1285,19 +1291,146 @@ As a consequence, for any two types \verb@S@ and \verb@T@, the type
new Pair[Int, Int](1, 2) .
\end{verbatim}
+\section{Type Parameters}
+
+\syntax\begin{verbatim}
+ TypeParamClause \>::=\> `[' TypeParam {`,' TypeParam} `]'
+ TypeParam \>::=\> [`+' | `-'] TypeDcl
+\end{verbatim}
+
+Type parameters appear in type definitions, class definitions, and
+function definitions. The most general for of a type parameter is
+\verb@$\plusminus$ t >: L <: U@. Here, \verb@L@, and \verb@U@ are lower
+and upper bounds that constrain possible type arguments for the
+parameter. $\plusminus$ is a {\em variance}, i.e.\ an optional prefix
+of either \verb@+@, or \verb@-@.
+
+The names of all type parameters in one type parameter clause must be
+pairwise different. The scope of a type parameter includes in each
+case the whole type parameter clause. Therefore it is possible that a
+type parameter appears as part of its own bounds or the bounds of
+other type parameters in the same clause. However, a type parameter
+may not be bounded directly or indirectly by itself.
+
+\example Here are some well-formed type parameter clauses:
+\begin{verbatim}
+[s, t]
+[ex <: Throwable]
+[a <: Ord[b], b <: a]
+[a, b, c >: a <: b]
+\end{verbatim}
+The following type parameter clauses since some type parameter is bounded by itself.
+\begin{verbatim}
+[a >: a]
+[a <: b, b <: c, c <: a]
+\end{verbatim}
+
+Variance annotations indicate how type instances with the given type
+parameters vary with respect to subtyping (\sref{sec:subtyping}). A
+\verb@+@ variance indicates a covariant dependency, a \verb@-@
+variance indicates a contravariant dependency, and a missing variance
+indication indicates a nonvariant dependency.
+
+A variance annotation constrains the way the annotated type variable
+may appear in the type or class which binds the type parameter. In a
+type definition \verb@type t[tps] = S@, type parameters labelled
+\verb@+@ must only appear in covariant position in \verb@S@ whereas
+type parameters labelled \verb@-@ must only appear in contravariant
+position. Analogously, for a class definition
+\verb@class c[tps](ps): s extends t@, type parameters labelled
+\verb@+@ must only appear in covariant position in the self type
+\verb@s@ and the type of the template \verb@t@, whereas type
+parameters labelled \verb@-@ must only appear in contravariant
+position.
+
+The variance position of a type parameter of a type is defined as
+follows. Let the opposite of covariance be contravariance, and the
+opposite of novariance be itself. The top-level of a type is always
+in covariant position. The variance position changes at for following
+constructs.
+\item
+The variance position of method parameter is the opposite of the
+variance position of the enclosing parameter clause.
+\item
+The variance position of a type parameter is the opposite of the
+variance position of the enclosing type parameter clause.
+\item
+The variance position of the lower bound of a type declaration or type parameter
+is the opposite of the variance position of the type declaration or parameter.
+\item
+The right hand side \verb@S@ of a type alias \verb@type t[tps] = S@
+is always in nonvariant position.
+\item
+The type of a mutable variable is always in nonvariant position.
+\item
+The prefix verb@S@ of a type selection \verb@S#T@ is always in nonvariant position.
+\item
+For a type argument \verb@T@ of a type \verb@S[... T ... ]@: If the
+corresponding type parameter is nonvariant, then \verb@T@ is in
+nonvariant position. If the corresponding type parameter is
+contravariant, the variance position of \verb@T@ is the opposite of
+the variance position of the enclosing type \verb@S[... T ... ]@.
+\end{itemize}
+
+\example The following variance annotation is legal.
+\begin{verbatim}
+class P[+a, +b] {
+ val fst: a, snd: b
+}
+\end{verbatim}
+With this variance annotation, elements
+of type \verb@P@ subtype covariantly with respect to their arguments.
+For instance, \verb@P[IOExeption, String] <: P[Throwable, Object]@.
+
+If we make the elements of \verb@P@ mutable, the variance annotation becomes illegal.
+\begin{verbatim}
+class Q[+a, +b] {
+ var fst: a, snd: b // illegal variance: a, b occur in non-variant position.
+}
+\end{verbatim}
+
+\example The following variance annotation is illegal, since \verb@a@ appears
+in contravariant position in the parameter of \verb@append@:
+
+\begin{verbatim}
+class Vector[+a] {
+ def append(x: Vector[a]): Vector[a];
+}
+\end{verbatim}
+The problem can be avoided by generalizing the type of \verb@append@
+by means of a lower bound:
+
+\begin{verbatim}
+class Vector[+a] {
+ def append[b >: a](x: Vector[b]): Vector[b];
+}
+\end{verbatim}
+
+\example Here is a case where a contravariant type parameter is useful.
+
+\begin{verbatim}
+class OutputChannel[-a] {
+ def write(x: a): unit
+}
+\end{verbatim}
+With that annotation, we have
+\verb@OutputChannel[Object] <: OutputChannel[String]@. That is, a
+channel on which one can write any object can substitute for a channel
+on which one can write only strings.
+
\section{Function Declarations and Definitions}
\label{sec:defdef}
\label{sec:funsigs}
-\syntax\begin{verbatim}
- Dcl \=::= \= def FunDcl {`,' FunDcl}
- FunDcl \>::= \> Id [FunTypeParamClause] {ParamClause} `:' Type
- Def \>::= \> def FunDef {`,' FunDef}
- FunDef \>::= \> Id [FunTypeParamClause] {ParamClause} [`:' Type]
- \>\> `=' Expr
- FunTypeParamClause \>::=\> `[' TypeDcl {`,' TypeDcl} `]'
- ParamClause \>::=\> `(' [Param {`,' Param}] `)'
- Param \>::= \> [def] Id `:' Type [*]
+\syntax\begin{verbatim}
+Dcl \=::= \= def FunDcl {`,' FunDcl}
+FunDcl \>::= \> id [FunTypeParamClause] {ParamClause} `:' Type
+Def \>::= \> def FunDef {`,' FunDef}
+FunDef \>::= \> id [FunTypeParamClause] {ParamClause} [`:' Type]
+ \> \> `=' Expr
+FunTypeParamClause \>::=\> `[' TypeDcl {`,' TypeDcl} `]'
+ParamClause \>::=\> `(' [Param {`,' Param}] `)'
+Param \>::= \> [def] id `:' Type [*]
\end{verbatim}
A function declaration has the form \verb@def f psig: T@, where
@@ -1309,7 +1442,7 @@ signature consists of an optional type parameter clause \verb@[tps]@,
followed by zero or more value parameter clauses
\verb@(ps_1) \ldots (ps_n)@. Such a declaration or definition
introduces a value with a (possibly polymorphic) method type whose
-parameters and result type are as given.
+parameter types and result type are as given.
A type parameter clause \verb@tps@ consists of one or more type
declarations (\sref{sec:typedcl}), which introduce type parameters,
@@ -1347,7 +1480,6 @@ result type, if one is given. If the function definition is not
recursive, the result type may be omitted, in which case it is
determined from the type of the function body.
-
\section{Overloaded Definitions}
\label{sec:overloaded-defs}
\todo{change}
@@ -1370,9 +1502,9 @@ entity, of type \verb@T_1 $\overload$ ... $\overload$ T_n@
\syntax\begin{verbatim}
Import \=::=\= import ImportExpr {`,' ImportExpr}
- ImportExpr \>::=\> StableId `.' (Id | `_' | ImportSelectors)
+ ImportExpr \>::=\> StableId `.' (id | `_' | ImportSelectors)
ImportSelectors \>::=\> `{' {ImportSelector `,'} (ImportSelector | `_') `}'
- ImportSelector \>::=\> Id [`=>' Id | `=>' `_']
+ ImportSelector \>::=\> id [`=>' id | `=>' `_']
\end{verbatim}
An import clause has the form \verb@import p.I@ where \verb@p@ is a stable
@@ -1820,7 +1952,7 @@ object; it is not possible for clients to create objects of class
\syntax\begin{verbatim}
ClsDef \=::=\= class ClassDef {`,' ClassDef}
- ClassDef \>::=\> Id [TypeParamClause] [ParamClause] [`:' SimpleType]
+ ClassDef \>::=\> id [TypeParamClause] [ParamClause] [`:' SimpleType]
\> \> ClassTemplate
ClassTemplate \>::=\> extends Template
\> |\> TemplateBody
@@ -1867,7 +1999,7 @@ can be omitted, in which case
\verb@{}@ is assumed.
\end{itemize}
This class definition defines a type \verb@c[tps]@ and a constructor
-which when applied to parameters conforming to typles \verb@ps@
+which when applied to parameters conforming to types \verb@ps@
initializes instances of type \verb@c[tps]@ by evaluating the template
\verb@t@.
@@ -2045,6 +2177,11 @@ three restrictions.
\item All non-empty statements in the template are either imports or pure definitions
\sref{sec:defs}
\end{enumerate}
+A {\em pure} definition can be evaluated without any side effect.
+Function, type, class, or object definitions are always pure. A value
+definition is pure if its right-hand side expression is pure. Pure
+expressions are paths, literals, as well as typed expressions
+\verb@e: T@ where \verb@e@ is pure.
These restrictions ensure that the evaluation of the mixin constructor
of a trait has no effect. Therefore, traits may appear several times
@@ -2072,7 +2209,7 @@ trait Ord[t <: Ord[t]]: t {
\label{sec:object-defs}
\syntax\begin{verbatim}
- ObjectDef \=::=\= Id [`:' SimpleType] ClassTemplate
+ ObjectDef \=::=\= id [`:' SimpleType] ClassTemplate
\end{verbatim}
An object definition defines a single object of a new class. Its
@@ -2173,20 +2310,20 @@ module FileSystem with {
\> |\> while '(' Expr ')' Expr
\> |\> do Expr [`;'] while `(' Expr ')'
\> |\> for `(' Enumerators `)' (do | yield) Expr
- \> |\> [SimpleExpr `.'] Id `=' Expr
+ \> |\> [SimpleExpr `.'] id `=' Expr
\> |\> SimpleExpr ArgumentExpr `=' Expr
\> |\> PostfixExpr [`:' Type1]
- PostfixExpr \>::=\> InfixExpr [Id]
+ PostfixExpr \>::=\> InfixExpr [id]
InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr Id InfixExpr
+ \> |\> InfixExpr id InfixExpr
PrefixExpr \>::=\> [`-' | `+' | `~' | `!'] SimpleExpr
SimpleExpr \>::=\> literal
\> |\> Path
\> |\> `(' [Expr] `)'
\> |\> BlockExpr
\> |\> new Template
- \> |\> SimpleExpr `.' Id
- \> |\> Id `#' Id
+ \> |\> SimpleExpr `.' id
+ \> |\> id `#' id
\> |\> SimpleExpr TypeArgs
\> |\> SimpleExpr ArgumentExpr
ArgumentExpr \>::=\> `(' Expr ')'
@@ -2266,7 +2403,7 @@ A reference to any other member of the ``null'' object causes a
\syntax\begin{verbatim}
Designator \=::= \= Path
- \> | \> SimpleExpr `.' Id
+ \> | \> SimpleExpr `.' id
\end{verbatim}
A designator refers to a named term. It can be a {\em simple name} or
@@ -2291,8 +2428,8 @@ selector identifier is bound in the selected object designated by $e$.
\label{sec:this-super}
\syntax\begin{verbatim}
- SimpleExpr \=::= \= [Ident `.'] $\This$
- \> | \> [Ident `.'] super `.' Id
+ SimpleExpr \=::= \= [id `.'] $\This$
+ \> | \> [id `.'] super `.' id
\end{verbatim}
The expression \verb@this@ can appear in the statement part of a
@@ -2347,7 +2484,7 @@ depending on whether \verb@B@ is used as defining class or as a mixin class.
\label{sec:this-mxin-super}
\syntax\begin{verbatim}
- SimpleExpr \=::= \= Id `#' Id
+ SimpleExpr \=::= \= id `#' id
\end{verbatim}
In the statement part of a template
@@ -2400,7 +2537,7 @@ class BorderedColoredShape extends Shape with Bordered with Colored {
An application \verb@f(e$_1$, ..., e$_n$)@ applies the function \verb@f@ to the
argument expressions \verb@e$_1$, ..., e$_n$@. If \verb@f@ has a method type
-\verb@(x$_1$: T$_1$, ..., x$_n$: T$_n$)U@, the type of each argument
+\verb@(T$_1$, ..., T$_n$)U@, the type of each argument
expression \verb@e$_i$@ must conform to the corresponding parameter type
\verb@T$_i$@. If \verb@f@ has some value type, the application is taken to be
equivalent to \verb@f.apply(e$_1$, ..., e$_n$)@, i.e.\ the
@@ -2487,7 +2624,7 @@ following three clauses applies:
\verb@T@ is a parameterless method type \verb@[]T'@ and \verb@T'@
conforms to \verb@U@.
\item
-\verb@T@ is a monomorphic method type \verb@(ps$_1$) ... (ps$_n$)S@ which
+\verb@T@ is a monomorphic method type \verb@(Ts$_1$) ... (Ts$_n$)S@ which
can be converted to a function type \verb@T'@ by using the rules for
implicit conversions \sref{sec:impl-conv} and \verb@T'@ conforms to
\verb@U@.
@@ -2499,12 +2636,13 @@ alternative among the alternatives in $\BB$, according to the
following definition of being ``more specific''.
\begin{itemize}
\item
-A method type \verb@(ps)T@ is more specific than some other
-type \verb@S@ if \verb@S@ is applicable to arguments \verb@(ps)@.
+A method type \verb@(Ts)U@ is more specific than some other
+type \verb@S@ if \verb@S@ is applicable to arguments \verb@(ps)@ of
+types \verb@Ts@.
\item
A polymorphic method type
-\verb@[a$_1$ >: L$_1$ <: U$_1$, ..., a$_n$ >: L$_n$ <: U$_n$](ps)T@ is
-more specific than some other type \verb@S@ if \verb@(ps)T@ is more
+\verb@[a$_1$ >: L$_1$ <: U$_1$, ..., a$_n$ >: L$_n$ <: U$_n$]T@ is
+more specific than some other type \verb@S@ if \verb@T@ is more
specific than \verb@S@ under the assumption that for
\verb@i = 1, ..., n@ each \verb@a$_i$@ is an abstract type name
bounded from below by \verb@L$_i$@ and from above by \verb@U$_i$@.
@@ -2643,9 +2781,9 @@ replaced by the expected type \verb@B@.
\label{sec:infix-operations}
\syntax\begin{verbatim}
- PostfixExpr \=::=\= InfixExpr [Id]
+ PostfixExpr \=::=\= InfixExpr [id]
InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr Id InfixExpr
+ \> |\> InfixExpr id InfixExpr
PrefixExpr \>::=\> [`-' | `+' | `!' | `~'] SimpleExpr
\end{verbatim}
@@ -3088,8 +3226,8 @@ for \verb@try { try { b } catch e$_1$ } finally e$_2$@.
\syntax\begin{verbatim}
Expr \=::= \= [Bindings `=>'] Expr
Bindings \>::=\> `(' Binding {`,' Binding `)'
- \> |\> Id [`:' Type1]
- Binding \>::= \> Id [`:' Type]
+ \> |\> id [`:' Type1]
+ Binding \>::= \> id [`:' Type]
\end{verbatim}
The anonymous function \verb@(x$_1$: T$_1$, ..., x$_n$: T$_n$) => e@
@@ -3182,7 +3320,7 @@ Pattern \=::= \= TreePattern { `|' TreePattern }
TreePattern \>::= \> varid `:' Type
\> | \> `_' `:' Type
\> | \> SimplePattern [ '*' | '?' | '+' ]
- \> | \> SimplePattern { Id SimplePattern }
+ \> | \> SimplePattern { id SimplePattern }
SimplePattern \=::= \> varid [ '@' SimplePattern ]
\> | \> `_'
@@ -3417,6 +3555,7 @@ that order hide members of an earlier import.
\syntax\begin{verbatim}
Packaging \=::= \= package QualId `{' {TopStat `;'} TopStat `}'
+ QualId \>::=\> id {`.' id}
\end{verbatim}
A package is a special object which defines a set of member classes,
@@ -4275,25 +4414,21 @@ grammar.
\> |\> charLit
\> |\> stringLit
\> |\> symbolLit
-
- Id \>::=\> id | `+' | `-' | `!'
- QualId \>::=\> Id {`.' Id}
- Ids \>::=\> Id {`,' Id}
\end{verbatim}
\begin{verbatim}
- StableId \=::= \= Id
- \> |\> Path `.' Id
- \> |\> [Ident '.'] super `.' Id
+ StableId \=::= \= id
+ \> |\> Path `.' id
+ \> |\> [id '.'] super `.' id
Path \>::=\> StableId
- \> |\> [Ident `.'] this
+ \> |\> [id `.'] this
Type \>::= \> Type1 `=>' Type
\> |\> `(' [Types] `)' `=>' Type
\> |\> Type1
Type1 \>::= \> SimpleType {with SimpleType} [Refinement]
SimpleType \>::= \> SimpleType TypeArgs
- \> |\> SimpleType `#' Id
+ \> |\> SimpleType `#' id
\> |\> StableId
\> |\> Path `.' type
\> |\> `(' Type ')'
@@ -4310,12 +4445,12 @@ grammar.
\> |\> try `{' block `}' [catch Expr] [finally Expr]
\> |\> do Expr [`;'] while `(' Expr ')'
\> |\> for `(' Enumerators `)' (do | yield) Expr
- \> |\> [SimpleExpr `.'] Id `=' Expr
+ \> |\> [SimpleExpr `.'] id `=' Expr
\> |\> SimpleExpr ArgumentExpr `=' Expr
\> |\> PostfixExpr [`:' Type1]
- PostfixExpr \>::=\> InfixExpr [Id]
+ PostfixExpr \>::=\> InfixExpr [id]
InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr Id InfixExpr
+ \> |\> InfixExpr id InfixExpr
PrefixExpr \>::=\> [`-' | `+' | `~' | `!'] SimpleExpr
SimpleExpr \>::=\> literal
\> |\> true
@@ -4325,8 +4460,8 @@ grammar.
\> |\> `(' [Expr] `)'
\> |\> BlockExpr
\> |\> new Template
- \> |\> SimpleExpr `.' Id
- \> |\> Id `#' Id
+ \> |\> SimpleExpr `.' id
+ \> |\> id `#' id
\> |\> SimpleExpr TypeArgs
\> |\> SimpleExpr ArgumentExpr
ArgumentExpr \>::=\> `(' Expr ')'
@@ -4357,7 +4492,7 @@ grammar.
TreePattern \>::= \> varid `:' Type
\> | \> `_' `:' Type
\> | \> SimplePattern [ '*' | '?' | '+' ]
- \> | \> SimplePattern { Id SimplePattern }
+ \> | \> SimplePattern { id SimplePattern }
SimplePattern \>::= \> varid [ '@' SimplePattern ]
\> | \> `_'
@@ -4372,10 +4507,10 @@ grammar.
FunTypeParamClause \>::=\> `[' TypeDcl {`,' TypeDcl} `]'
TypeParam \>::=\> [`+' | `-'] TypeDcl
ParamClause \>::=\> `(' [Param {`,' Param}] `)'
- Param \>::=\> [def] Id `:' Type [`*']
- Bindings \>::=\> Id [`:' Type1]
+ Param \>::=\> [def] id `:' Type [`*']
+ Bindings \>::=\> id [`:' Type1]
\> |\> `(' Binding {`,' Binding `)'
- Binding \>::=\> Id [`:' Type]
+ Binding \>::=\> id [`:' Type]
Modifier \>::=\> LocalModifier
\> |\> private
@@ -4396,18 +4531,18 @@ grammar.
\> |\>
Import \>::=\> import ImportExpr {`,' ImportExpr}
- ImportExpr \>::=\> StableId `.' (Id | `_' | ImportSelectors)
+ ImportExpr \>::=\> StableId `.' (id | `_' | ImportSelectors)
ImportSelectors \>::=\> `{' {ImportSelector `,'} (ImportSelector | `_') `}'
- ImportSelector \>::=\> Id [`=>' Id | `=>' `_']
+ ImportSelector \>::=\> id [`=>' id | `=>' `_']
Dcl \>::=\> val ValDcl {`,' ValDcl}
\> |\> var VarDcl {`,' VarDcl}
\> |\> def FunDcl {`,' FunDcl}
\> |\> type TypeDcl {`,' TypeDcl}
- ValDcl \>::=\> Id `:' Type
- VarDcl \>::=\> Id `:' Type
- FunDcl \>::=\> Id [FunTypeParamClause] {ParamClause} `:' Type
- TypeDcl \>::=\> Id [`>:' Type] [`<:' Type]
+ ValDcl \>::=\> id `:' Type
+ VarDcl \>::=\> id `:' Type
+ FunDcl \>::=\> id [FunTypeParamClause] {ParamClause} `:' Type
+ TypeDcl \>::=\> id [`>:' Type] [`<:' Type]
Def \>::=\> val PatDef {`,' PatDef}
\> |\> var VarDef {`,' VarDef}
@@ -4415,15 +4550,15 @@ grammar.
\> |\> type TypeDef {`,' TypeDef}
\> |\> ClsDef
PatDef \>::=\> Pattern `=' Expr
- VarDef \>::=\> Id [`:' Type] `=' Expr
- \> |\> Id `:' Type `=' `_'
- FunDef \>::=\> Id [FunTypeParamClause] {ParamClause} [`:' Type] `=' Expr
+ VarDef \>::=\> id [`:' Type] `=' Expr
+ \> |\> id `:' Type `=' `_'
+ FunDef \>::=\> id [FunTypeParamClause] {ParamClause} [`:' Type] `=' Expr
| this ParamClause `=' ConstrExpr
- TypeDef \>::=\> Id `=' Type
+ TypeDef \>::=\> id [TypeParamClause] `=' Type
ClsDef \>::=\> ([case] class | trait) ClassDef {`,' ClassDef}
\> |\> [case] object ObjectDef {`,' ObjectDef}
- ClassDef \>::=\> Id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate
- ObjectDef \>::=\> Id [`:' SimpleType] ClassTemplate
+ ClassDef \>::=\> id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate
+ ObjectDef \>::=\> id [`:' SimpleType] ClassTemplate
ClassTemplate \>::=\> extends Template
\> |\> TemplateBody
\> |\>
@@ -4436,6 +4571,7 @@ grammar.
\> |\> Import
\> |\>
Packaging \>::=\> package QualId `{' {TopStat `;'} TopStat `}'
+ QualId \>::=\> id {`.' id}
\end{verbatim}
case class extends { ... }
@@ -4483,7 +4619,7 @@ class Cons
\syntax\begin{verbatim}
ClassDef \=::= \= ClassAlias
InterfaceDef \>::= \> ClassAlias
- ClassAlias \>::= \> Id [TypeParamClause] `=' SimpleType
+ ClassAlias \>::= \> id [TypeParamClause] `=' SimpleType
\end{verbatim}
Classes may also be defined to be aliases for other classes. A class
@@ -4738,7 +4874,7 @@ if it were permitted to execute in spite of being not well-typed.
\syntax\begin{verbatim}
PureDef \=::= \= $\LET$ ValDef {`,' ValDef}
- ValDef \>::= \> Id [`:' Type] `=' Expr
+ ValDef \>::= \> id [`:' Type] `=' Expr
\end{verbatim}
A let definition $\LET;x: T = e$ defines $x$ as a name of the value
diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java
index b84f6f8ba3..44fe88f9d2 100644
--- a/sources/meta/scalac/ast/Tree.java
+++ b/sources/meta/scalac/ast/Tree.java
@@ -75,7 +75,8 @@ public class Tree {
n_ValDef = node("ValDef" , None, DefSym),
n_PatDef = node("PatDef" , None, NoSym),
n_DefDef = node("DefDef" , None, DefSym),
- n_TypeDef = node("TypeDef" , None, DefSym),
+ n_AbsTypeDef = node("AbsTypeDef" , None, DefSym),
+ n_AliasTypeDef = node("AliasTypeDef" , None, DefSym),
n_Import = node("Import" , None, HasSym),
n_CaseDef = node("CaseDef" , None, NoSym),
n_Template = node("Template" , None, HasSym),
@@ -128,7 +129,7 @@ public class Tree {
setRange(Phase.PARSER, Phase.END).
addField(t_int, "mods", SymFlags).
addField(t_TypeName, "name", SymName).
- addField(n_TypeDef.getType(1), "tparams").
+ addField(n_AbsTypeDef.getType(1), "tparams").
addField(n_ValDef.getType(2), "vparams").
addField(t_TypeTree, "tpe").
addField(n_Template.getType(0), "impl");
@@ -168,12 +169,12 @@ public class Tree {
setRange(Phase.PARSER, Phase.END).
addField(t_int, "mods", SymFlags).
addField(t_TermName, "name", SymName).
- addField(n_TypeDef.getType(1), "tparams").
+ addField(n_AbsTypeDef.getType(1), "tparams").
addField(n_ValDef.getType(2), "vparams").
addField(t_TypeTree, "tpe").
addField(t_TermTree, "rhs");
- n_TypeDef.
+ n_AbsTypeDef.
setDescription("Type declaration").
setRange(Phase.PARSER, Phase.ERASURE). // !!! could/should be removed earlier?)
addField(t_int, "mods", SymFlags).
@@ -181,6 +182,14 @@ public class Tree {
addField(t_TypeTree, "rhs").
addField(t_TypeTree, "lobound");
+ n_AliasTypeDef.
+ setDescription("Type alias").
+ setRange(Phase.PARSER, Phase.ERASURE). // !!! could/should be removed earlier?)
+ addField(t_int, "mods", SymFlags).
+ addField(t_TypeName, "name", SymName).
+ addField(n_AbsTypeDef.getType(1), "tparams").
+ addField(t_TypeTree, "rhs");
+
n_Import.
setDescription("Import declaration").
setRange(Phase.START, Phase.ANALYZER).
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 194d32a6eb..85800af09f 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -84,7 +84,7 @@ object List {
* @author Martin Odersky and others
* @version 1.0, 16/07/2003
*/
-trait List[+a] extends Seq[a] with StructuralEquality[List[a]] {
+trait List[+a] extends Seq[a]/* with StructuralEquality[List[a]]*/ {
/** Tests if this list is empty.
* @return true, iff the list contains no element.
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 035a178a15..6ca233ab8c 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -38,14 +38,14 @@ object Predef {
def synchronized[A](obj: AnyRef)(def body: A) =
scala.runtime.NativeMonitor.synchronised(obj, body);
- type Pair = Tuple2;
+ type Pair[p, q] = Tuple2[p, q];
def Pair[a, b](x: a, y: b) = Tuple2(x, y);
- type Triple = Tuple3;
+ type Triple[a, b, c] = Tuple3[a, b, c];
def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
// temporary
- type Trace = SeqTrace;
- type consTrace = SeqTraceCons;
- type emptyTrace = SeqTraceNil;
+ type Trace[a] = SeqTrace[a];
+ type consTrace[a] = SeqTraceCons[a];
+ type emptyTrace[a] = SeqTraceNil[a];
}
diff --git a/sources/scala/Some.scala b/sources/scala/Some.scala
index 7c276ac332..4f0bd7ea3c 100644
--- a/sources/scala/Some.scala
+++ b/sources/scala/Some.scala
@@ -16,4 +16,4 @@ package scala;
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
-final case class Some[+A](x: A) extends Option[A];
+final case class Some[+A1](x: A1) extends Option[A1];
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java
index 53c5d05061..0ae1923b0d 100644
--- a/sources/scalac/Global.java
+++ b/sources/scalac/Global.java
@@ -466,7 +466,8 @@ public class Global {
case PackageDef(_, _):
case ModuleDef(_, _, _, _):
case DefDef(_, _, _, _, _, _):
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
if (!mustShow(tree.symbol())) return;
body.append(
treeGen.Apply(tree.pos,
diff --git a/sources/scalac/ast/SubstTransformer.java b/sources/scalac/ast/SubstTransformer.java
index ee8541dbb0..99c8e4f787 100644
--- a/sources/scalac/ast/SubstTransformer.java
+++ b/sources/scalac/ast/SubstTransformer.java
@@ -181,7 +181,7 @@ public class SubstTransformer extends Transformer {
switch (tree) {
case ClassDef(_, // fix Emacs :
_,
- Tree.TypeDef[] tparams,
+ Tree.AbsTypeDef[] tparams,
Tree.ValDef[][] vparams,
Tree tpe,
Tree.Template impl) :
@@ -202,7 +202,7 @@ public class SubstTransformer extends Transformer {
case DefDef(_, // fix for Emacs :
Name name,
- Tree.TypeDef[] tparams,
+ Tree.AbsTypeDef[] tparams,
Tree.ValDef[][] vparams,
Tree tpe,
Tree rhs):
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index 137e76c6fa..863c652090 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -112,7 +112,7 @@ public class TreeGen implements Kinds, Modifiers {
case SingleType(Type pre1, Symbol sym):
return mkStable(mkRef(pos, pre1, sym));
default:
- throw new ApplicationError();
+ throw new ApplicationError(pre);
}
}
@@ -144,8 +144,10 @@ public class TreeGen implements Kinds, Modifiers {
switch (sym.kind) {
case ERROR:
return make.Bad(pos, Symbol.ERROR).setType(Type.ErrorType);
- case TYPE: case ALIAS:
- return TypeDef(pos, sym);
+ case TYPE:
+ return AbsTypeDef(pos, sym);
+ case ALIAS:
+ return AliasTypeDef(pos, sym);
case VAL:
if (sym.isMethod()) return DefDef(pos, sym, Tree.Empty);
else return ValDef(pos, sym, Tree.Empty);
@@ -265,8 +267,8 @@ public class TreeGen implements Kinds, Modifiers {
/** Build type parameter section corresponding to given array of symbols .
*/
- public TypeDef[] mkTypeParams(int pos, Symbol[] symbols) {
- TypeDef[] res = new TypeDef[symbols.length];
+ public AbsTypeDef[] mkTypeParams(int pos, Symbol[] symbols) {
+ AbsTypeDef[] res = new AbsTypeDef[symbols.length];
for (int i = 0; i < symbols.length; i++) {
res[i] = mkTypeParam(pos, symbols[i]);
}
@@ -275,28 +277,47 @@ public class TreeGen implements Kinds, Modifiers {
/** Build type parameter corresponding to given symbol .
*/
- public TypeDef mkTypeParam(int pos, Symbol sym) {
- return TypeDef(pos, sym);
+ public AbsTypeDef mkTypeParam(int pos, Symbol sym) {
+ return AbsTypeDef(pos, sym);
}
- public TypeDef mkTypeParam(Symbol sym) {
+ public AbsTypeDef mkTypeParam(Symbol sym) {
return mkTypeParam(sym.pos, sym);
}
- /** Build type definition corresponding to given symbol .
+ /** Build abstract type definition corresponding to given symbol .
*/
- public TypeDef TypeDef(int pos, Symbol sym) {
+ public AbsTypeDef AbsTypeDef(int pos, Symbol sym) {
Global.instance.nextPhase();
Type symtype = sym.info();
Global.instance.prevPhase();
- TypeDef res = make.TypeDef(
+ AbsTypeDef res = make.AbsTypeDef(
pos, sym, TypeTerm(pos, symtype), TypeTerm(pos, sym.loBound()));
res.setType(definitions.UNIT_TYPE);
return res;
}
- public TypeDef TypeDef(Symbol sym) {
- return TypeDef(sym.pos, sym);
+ public AbsTypeDef AbsTypeDef(Symbol sym) {
+ return AbsTypeDef(sym.pos, sym);
+ }
+
+ /** Build type definition corresponding to given symbol .
+ */
+ public AliasTypeDef AliasTypeDef(int pos, Symbol sym) {
+ Global.instance.nextPhase();
+ Type symtype = sym.info();
+ Global.instance.prevPhase();
+ AliasTypeDef res = make.AliasTypeDef(
+ pos,
+ sym,
+ mkTypeParams(pos, sym.typeParams()),
+ TypeTerm(pos, symtype));
+ res.setType(definitions.UNIT_TYPE);
+ return res;
+ }
+
+ public AliasTypeDef AliasTypeDef(Symbol sym) {
+ return AliasTypeDef(sym.pos, sym);
}
/** Build and attribute block with given statements, starting
@@ -633,8 +654,9 @@ public class TreeGen implements Kinds, Modifiers {
changeOwner(body, owner, applyMeth);
Tree applyDef = DefDef(applyMeth, body);
Tree classDef = ClassDef(clazz, new Tree[]{applyDef});
- Tree alloc = New(pos, Type.localThisType, clazz, Tree.EMPTY_ARRAY);
- return Block(new Tree[]{classDef, alloc}).setType(ft);
+ Tree alloc = New(pos, Type.localThisType, clazz, Tree.EMPTY_ARRAY)
+ .setType(ft);
+ return Block(new Tree[]{classDef, alloc});
}
public Tree mkPartialFunction(int pos, Tree applyVisitor, Tree isDefinedAtVisitor,
@@ -652,8 +674,9 @@ public class TreeGen implements Kinds, Modifiers {
pattype, restype, clazz, owner),
makeVisitorMethod(pos, Names.isDefinedAt, isDefinedAtVisitor,
pattype, definitions.BOOLEAN_TYPE, clazz, owner)});
- Tree alloc = New(pos, Type.localThisType, clazz, Tree.EMPTY_ARRAY);
- return Block(new Tree[]{classDef, alloc}).setType(pft);
+ Tree alloc = New(pos, Type.localThisType, clazz, Tree.EMPTY_ARRAY)
+ .setType(pft);
+ return Block(new Tree[]{classDef, alloc});
}
//where
private Tree makeVisitorMethod(int pos, Name name, Tree visitor,
diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java
index 637928188f..bc5e03f9b8 100644
--- a/sources/scalac/ast/TreeInfo.java
+++ b/sources/scalac/ast/TreeInfo.java
@@ -47,7 +47,8 @@ public class TreeInfo {
case ModuleDef(_, _, _, _):
case DefDef(_, _, _, _, _, _):
case ValDef(_, _, _, _):
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
case Import(_, _):
return true;
default:
@@ -61,7 +62,8 @@ public class TreeInfo {
return rhs == Tree.Empty;
case ValDef(_, _, _, Tree rhs):
return rhs == Tree.Empty;
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
return true;
default:
return false;
@@ -76,7 +78,8 @@ public class TreeInfo {
case ClassDef(_, _, _, _, _, _):
case ModuleDef(_, _, _, _):
case DefDef(_, _, _, _, _, _):
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
case Import(_, _):
return true;
case ValDef(int mods, _, _, Tree rhs):
@@ -154,6 +157,8 @@ public class TreeInfo {
return methSymbol(fn);
case TypeApply(Tree fn, _):
return methSymbol(fn);
+ case AppliedType(Tree fn, _):
+ return methSymbol(fn);
default:
if (tree.hasSymbol()) return tree.symbol();
else return Symbol.NONE;
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 8c01c53b41..7212745657 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -1441,7 +1441,7 @@ public class Parser implements Tokens {
/** TypeParamClauseOpt ::= [`[' TypeParam {`,' TypeParam} `]']
* FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]']
*/
- TypeDef[] typeParamClauseOpt(boolean variant) {
+ AbsTypeDef[] typeParamClauseOpt(boolean variant) {
TreeList params = new TreeList();
if (s.token == LBRACKET) {
s.nextToken();
@@ -1452,7 +1452,7 @@ public class Parser implements Tokens {
}
accept(RBRACKET);
}
- return (TypeDef[])params.copyTo(new TypeDef[params.length()]);
+ return (AbsTypeDef[])params.copyTo(new AbsTypeDef[params.length()]);
}
/** TypeParam ::= [`+' | `-'] FunTypeParam
@@ -1491,7 +1491,7 @@ public class Parser implements Tokens {
} else {
hibound = scalaDot(pos, Names.Any.toTypeName());
}
- return make.TypeDef(pos, mods, name.toTypeName(), hibound, lobound);
+ return make.AbsTypeDef(pos, mods, name.toTypeName(), hibound, lobound);
}
//////// DEFS ////////////////////////////////////////////////////////////////
@@ -1726,11 +1726,11 @@ public class Parser implements Tokens {
accept(EQUALS);
return make.DefDef(
pos, mods, Names.this_.toTypeName(),
- Tree.TypeDef_EMPTY_ARRAY, vparams, Tree.Empty,
+ Tree.AbsTypeDef_EMPTY_ARRAY, vparams, Tree.Empty,
convertToSelfConstr(expr()));
} else {
Name name = ident();
- TypeDef[] tparams = typeParamClauseOpt(false);
+ AbsTypeDef[] tparams = typeParamClauseOpt(false);
ValDef[][] vparams = paramClauses();
Tree restype = typedOpt();
if (s.token == EQUALS || restype == Tree.Empty)
@@ -1749,9 +1749,13 @@ public class Parser implements Tokens {
int pos = s.pos;
Name name = ident().toTypeName();
switch (s.token) {
+ case LBRACKET:
+ AbsTypeDef[] tparams = typeParamClauseOpt(true);
+ accept(EQUALS);
+ return make.AliasTypeDef(pos, mods, name, tparams, type());
case EQUALS:
s.nextToken();
- return make.TypeDef(pos, mods, name, type(), Tree.Empty);
+ return make.AliasTypeDef(pos, mods, name, Tree.AbsTypeDef_EMPTY_ARRAY, type());
case SUPERTYPE:
case SUBTYPE:
case SEMI:
@@ -1768,7 +1772,7 @@ public class Parser implements Tokens {
Tree classDef(int mods) {
int pos = s.pos;
Name clazzname = ident().toTypeName();
- TypeDef[] tparams = typeParamClauseOpt(true);
+ AbsTypeDef[] tparams = typeParamClauseOpt(true);
ValDef[][] params = paramClauseOpt();
TreeList result = new TreeList();
return popComment(make.ClassDef(pos, mods, clazzname, tparams, params,
@@ -1830,7 +1834,7 @@ public class Parser implements Tokens {
Tree constr() {
Tree t = convertToConstr(stableId());
if (s.token == LBRACKET)
- t = make.TypeApply(s.pos, t, typeArgs());
+ t = make.AppliedType(s.pos, t, typeArgs());
if (s.token == LPAREN)
t = make.Apply(s.pos, t, argumentExprs());
return applyConstr(t);
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index 39b312f4a7..20013c0711 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -254,7 +254,7 @@ public class TextTreePrinter implements TreePrinter {
case ClassDef(int mods, // :
Name name,
- Tree.TypeDef[] tparams,
+ Tree.AbsTypeDef[] tparams,
Tree.ValDef[][] vparams,
Tree tpe,
Tree.Template impl):
@@ -316,7 +316,7 @@ public class TextTreePrinter implements TreePrinter {
case DefDef(int mods,
Name name,
- Tree.TypeDef[] tparams,
+ Tree.AbsTypeDef[] tparams,
Tree.ValDef[][] vparams,
Tree tpe,
Tree rhs):
@@ -331,19 +331,27 @@ public class TextTreePrinter implements TreePrinter {
printOpt(TXT_EQUAL, rhs, true);
break;
- case TypeDef(int mods,
- Name name,
- Tree rhs,
- Tree lobound):
+ case AbsTypeDef(int mods,
+ Name name,
+ Tree rhs,
+ Tree lobound):
printModifiers(mods);
print(KW_TYPE);
print(Text.Space);
printSymbolDefinition(tree.symbol(), name);
- if ((mods & (Modifiers.DEFERRED | Modifiers.PARAM)) != 0) {
- printBounds(lobound, rhs);
- } else {
- printOpt(TXT_EQUAL, rhs, true);
- }
+ printBounds(lobound, rhs);
+ break;
+
+ case AliasTypeDef(int mods,
+ Name name,
+ Tree.AbsTypeDef[] tparams,
+ Tree rhs):
+ printModifiers(mods);
+ print(KW_TYPE);
+ print(Text.Space);
+ printSymbolDefinition(tree.symbol(), name);
+ printParams(tparams);
+ printOpt(TXT_EQUAL, rhs, true);
break;
case Import(Tree expr, Name[] selectors):
@@ -688,7 +696,7 @@ public class TextTreePrinter implements TreePrinter {
}
}
- protected void printParams(Tree.TypeDef[] tparams) {
+ protected void printParams(Tree.AbsTypeDef[] tparams) {
if (tparams.length > 0) {
print(TXT_LEFT_BRACKET);
for (int i = 0; i < tparams.length; i++) {
@@ -715,7 +723,7 @@ public class TextTreePrinter implements TreePrinter {
protected void printParam(Tree tree) {
switch (tree) {
- case TypeDef(int mods, Name name, Tree bound, Tree lobound):
+ case AbsTypeDef(int mods, Name name, Tree bound, Tree lobound):
printModifiers(mods);
printSymbolDefinition(tree.symbol(), name);
printBounds(lobound, bound);
diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java
index 5059a4f9ed..980cc7e23f 100644
--- a/sources/scalac/backend/jvm/GenJVM.java
+++ b/sources/scalac/backend/jvm/GenJVM.java
@@ -190,7 +190,8 @@ class GenJVM {
break;
case Empty:
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
case TypeApply(_, _):
case FunType(_, _):
case CompoundType(_, _):
@@ -513,7 +514,8 @@ class GenJVM {
break;
case Empty:
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
case TypeApply(_, _):
case FunType(_, _):
case CompoundType(_, _):
diff --git a/sources/scalac/backend/jvm/GenJVMBCEL.java b/sources/scalac/backend/jvm/GenJVMBCEL.java
index 0708cdd3d0..c9a2ed5031 100644
--- a/sources/scalac/backend/jvm/GenJVMBCEL.java
+++ b/sources/scalac/backend/jvm/GenJVMBCEL.java
@@ -470,7 +470,8 @@ class GenJVMBCEL {
break;
case Empty:
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
case TypeApply(_, _):
case FunType(_, _):
case CompoundType(_, _):
diff --git a/sources/scalac/checkers/CheckOwners.java b/sources/scalac/checkers/CheckOwners.java
index 8ebd0b9f8f..2bc09016f8 100644
--- a/sources/scalac/checkers/CheckOwners.java
+++ b/sources/scalac/checkers/CheckOwners.java
@@ -67,7 +67,8 @@ public class CheckOwners extends Checker {
case ModuleDef(_,_,_,_):
case DefDef(_,_,_,_,_,_):
case ValDef(_,_,_,_):
- case TypeDef(_,_,_, _):
+ case AbsTypeDef(_,_,_, _):
+ case AliasTypeDef(_,_,_, _):
traverse(body[i], owner);
break;
default:
@@ -98,7 +99,7 @@ public class CheckOwners extends Checker {
case ClassDef(int mods,
Name name,
- TypeDef[] tparams,
+ AbsTypeDef[] tparams,
ValDef[][] vparams,
Tree tpe,
Template impl): {
@@ -117,7 +118,7 @@ public class CheckOwners extends Checker {
case DefDef(int mods,
Name name,
- TypeDef[] tparams,
+ AbsTypeDef[] tparams,
ValDef[][] vparams,
Tree tpe,
Tree rhs): {
@@ -134,10 +135,16 @@ public class CheckOwners extends Checker {
traverse(rhs, tree.symbol());
} break;
- case TypeDef(int mods, Name name, Tree rhs, Tree lobound): {
+ case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): {
check(tree);
traverse(rhs, tree.symbol());
- // todo: we should do something about lobound here.
+ traverse(lobound, tree.symbol());
+ } break;
+
+ case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): {
+ check(tree);
+ traverse(tparams, tree.symbol());
+ traverse(rhs, tree.symbol());
} break;
default:
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java
index e8450ef265..fcafabc1aa 100644
--- a/sources/scalac/symtab/Definitions.java
+++ b/sources/scalac/symtab/Definitions.java
@@ -218,12 +218,13 @@ public class Definitions {
PARTIALFUNCTION_CLASS = getClass(Names.scala_PartialFunction);
// the scala.ANYREF class
- ANYREF_CLASS = new TypeSymbol(
- Kinds.ALIAS, Position.NOPOS, Names.AnyRef.toTypeName(),
+ ANYREF_CLASS = new AliasTypeSymbol(
+ Position.NOPOS, Names.AnyRef.toTypeName(),
SCALA_CLASS, Modifiers.JAVA)
.setInfo(JAVA_OBJECT_TYPE);
+ SCALA_CLASS.members().enter(ANYREF_CLASS);
ANYREF_TYPE = ANYREF_CLASS.typeConstructor().unalias();
- SCALA.members().enter(ANYREF_CLASS);
+ ANYREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ANYREF_TYPE));
// the scala.OBJECT class
OBJECT_CLASS = getClass(Names.scala_Object);
@@ -284,11 +285,12 @@ public class Definitions {
// add the java.lang.String class to the scala package
JAVA_STRING_CLASS = getClass(Names.java_lang_String);
JAVA_STRING_TYPE = JAVA_STRING_CLASS.typeConstructor();
- STRING_CLASS = new TypeSymbol(
- Kinds.ALIAS, Position.NOPOS, Names.String.toTypeName(), SCALA_CLASS, 0)
+ STRING_CLASS = new AliasTypeSymbol(
+ Position.NOPOS, Names.String.toTypeName(), SCALA_CLASS, 0)
.setInfo(JAVA_STRING_TYPE);
+ SCALA_CLASS.members().enter(STRING_CLASS);
STRING_TYPE = STRING_CLASS.typeConstructor();
- SCALA.members().enter(STRING_CLASS);
+ STRING_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, STRING_TYPE));
SEQ_CLASS = getClass(Names.scala_Seq);
diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java
index 512027944b..236733b8bc 100644
--- a/sources/scalac/symtab/EntryTags.java
+++ b/sources/scalac/symtab/EntryTags.java
@@ -17,7 +17,7 @@ public interface EntryTags {
* | 2 TYPENAME len_Nat NameInfo
* | 3 NONEsym len_Nat
* | 4 TYPEsym len_Nat SymbolInfo lobound_Ref
- * | 5 ALIASsym len_Nat SymbolInfo
+ * | 5 ALIASsym len_Nat SymbolInfo constrsym_Ref
* | 6 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref
* | 7 VALsym len_Nat SymbolInfo [classsym_Ref]
* | 8 EXTref len_Nat name_Ref [owner_Ref]
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 751aa93863..2e3ebbbf90 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -145,8 +145,7 @@ public abstract class Symbol implements Modifiers, Kinds {
|| info == Type.ErrorType
|| info instanceof Type.MethodType
|| info instanceof Type.OverloadedType
- || info instanceof Type.PolyType &&
- ((Type.PolyType)info).result instanceof Type.MethodType
+ || info instanceof Type.PolyType
: "illegal type for " + this + ": " + info;
if (infos == TypeIntervalList.EMPTY) {
infos = new TypeIntervalList(TypeIntervalList.EMPTY);
@@ -1125,42 +1124,111 @@ public class TermSymbol extends Symbol {
}
}
-/** A class for (abstract and alias) type symbols. It has ClassSymbol as a subclass.
+/** A base class for all type symbols.
+ * It has AliasTypeSymbol, AbsTypeSymbol, ClassSymbol as subclasses.
*/
-public class TypeSymbol extends Symbol {
+public abstract class TypeSymbol extends Symbol {
/** A cache for closures
*/
private ClosureIntervalList closures = ClosureIntervalList.EMPTY;
+ /** The symbol's type template */
+ private Type template = null;
+
/** A cache for type constructors
*/
private Type tycon = null;
+ /** The primary constructor of this type */
+ private Symbol constructor;
+
/** Constructor */
public TypeSymbol(int kind, int pos, Name name, Symbol owner, int flags) {
super(kind, pos, name, owner, flags);
+ if (kind != TYPE)
+ this.constructor = TermSymbol.newConstructor(this, flags & ~MODUL);
}
- public static TypeSymbol define(
- int pos, Name name, Symbol owner, int flags, Scope scope) {
- Scope.Entry e = scope.lookupEntry(name);
- if (e.owner == scope && e.sym.isExternal() && e.sym.kind == ALIAS) {
- TypeSymbol sym = (TypeSymbol) e.sym;
- sym.update(pos, flags);
- return sym;
- } else {
- return new TypeSymbol(ALIAS, pos, name, owner, flags);
+ protected void update(int pos, int flags) {
+ super.update(pos, flags);
+ this.template = null;
+ }
+
+ /** copy all fields to `sym'
+ */
+ public void copyTo(Symbol sym) {
+ super.copyTo(sym);
+ if (kind != TYPE) {
+ Symbol symconstr = ((TypeSymbol) sym).constructor;
+ constructor.copyTo(symconstr);
+ if (constructor.isInitialized())
+ symconstr.setInfo(fixConstrType(symconstr.type(), sym));
}
}
- /** Return a fresh symbol with the same fields as this one.
+ protected void copyConstructorInfo(TypeSymbol other) {
+ other.primaryConstructor().setInfo(
+ fixConstrType(
+ primaryConstructor().info().cloneType(
+ primaryConstructor(), other.primaryConstructor()),
+ other));
+ Symbol[] alts = allConstructors().alternativeSymbols();
+ for (int i = 1; i < alts.length; i++) {
+ Symbol constr = other.addConstructor();
+ constr.setInfo(
+ fixConstrType(
+ alts[i].info().cloneType(alts[i], constr),
+ other));
+ }
+ }
+
+ private Type fixConstrType(Type type, Symbol clone) {
+ switch (type) {
+ case MethodType(Symbol[] vparams, Type result):
+ result = fixConstrType(result, clone);
+ return new Type.MethodType(vparams, result);
+ case PolyType(Symbol[] tparams, Type result):
+ result = fixConstrType(result, clone);
+ return new Type.PolyType(tparams, result);
+ case TypeRef(Type pre, Symbol sym, Type[] args):
+ assert sym == this : Debug.show(sym) + " != " + Debug.show(this);
+ return new Type.TypeRef(pre, clone, args);
+ case LazyType():
+ return type;
+ default:
+ throw Debug.abort("unexpected constructor type:" + clone + ":" + type);
+ }
+ }
+
+ /** add a constructor
*/
- public Symbol cloneSymbol(Symbol owner) {
- TypeSymbol other = new TypeSymbol(kind, pos, name, owner, flags);
- if (Global.instance.debug) System.out.println("cloning " + this + this.locationString() + " to " + other + " in phase " + Global.instance.currentPhase.name());
- other.setInfo(info());
- return other;
+ public Symbol addConstructor() {
+ Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL);
+ constructor = constructor.overloadWith(constr);
+ return constr;
+ }
+
+ /** Get primary constructor */
+ public Symbol primaryConstructor() {
+ return (kind == TYPE) ? Symbol.NONE : constructor.firstAlternative();
+ }
+
+ /** Get all constructors */
+ public Symbol allConstructors() {
+ return (kind == TYPE) ? Symbol.NONE : constructor;
+ }
+
+ /** Get type parameters */
+ public Symbol[] typeParams() {
+ return (kind == TYPE) ? Symbol.EMPTY_ARRAY
+ : primaryConstructor().info().typeParams();
+ }
+
+ /** Get value parameters */
+ public Symbol[] valueParams() {
+ return (kind == CLASS) ? primaryConstructor().info().valueParams()
+ : Symbol.EMPTY_ARRAY;
}
/** Get type constructor */
@@ -1172,12 +1240,26 @@ public class TypeSymbol extends Symbol {
public Symbol setOwner(Symbol owner) {
tycon = null;
+ template = null;
return super.setOwner(owner);
}
/** Get type */
public Type type() {
- return typeConstructor();
+ Symbol[] tparams = typeParams();
+ if (template != null) {
+ switch (template) {
+ case TypeRef(_, _, Type[] targs):
+ if (targs.length == tparams.length)
+ return template;
+ }
+ }
+ if (tparams.length == 0)
+ template = typeConstructor();
+ else
+ template = Type.TypeRef(
+ owner().thisType(), this, type(tparams));
+ return template;
}
/** Get type at phase id */
@@ -1185,20 +1267,6 @@ public class TypeSymbol extends Symbol {
return type();
}
- public Symbol[] typeParams() {
- return type().unalias().typeParams();
- }
-
- /** Get all constructors of class */
- public Symbol allConstructors() {
- return type().unalias().symbol().allConstructors();
- }
-
- /** Get primary constructor of class */
- public Symbol primaryConstructor() {
- return type().unalias().symbol().primaryConstructor();
- }
-
public Type[] closure() {
if (kind == ALIAS) return info().symbol().closure();
int id = currentPhaseId();
@@ -1256,7 +1324,7 @@ public class TypeSymbol extends Symbol {
closures.closure = Symbol.type(closureClasses);
//System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
adjustType(type());
- //System.out.println("closure(" + this + ") at " + Global.instance.currentPhase.name() + " = " + ArrayApply.toString(closures.closure));//DEBUG
+ //System.out.println("closure(" + this + ") = " + ArrayApply.toString(closures.closure));//DEBUG
}
//where
@@ -1301,6 +1369,36 @@ public class TypeSymbol extends Symbol {
super.reset(completer);
closures = ClosureIntervalList.EMPTY;
tycon = null;
+ template = null;
+ }
+}
+
+public class AliasTypeSymbol extends TypeSymbol {
+
+ /** Constructor */
+ public AliasTypeSymbol(int pos, Name name, Symbol owner, int flags) {
+ super(ALIAS, pos, name, owner, flags);
+ }
+
+ public static AliasTypeSymbol define(
+ int pos, Name name, Symbol owner, int flags, Scope scope) {
+ Scope.Entry e = scope.lookupEntry(name);
+ if (e.owner == scope && e.sym.isExternal() && e.sym.kind == ALIAS) {
+ AliasTypeSymbol sym = (AliasTypeSymbol) e.sym;
+ sym.update(pos, flags);
+ return sym;
+ } else {
+ return new AliasTypeSymbol(pos, name, owner, flags);
+ }
+ }
+
+ /** Return a fresh symbol with the same fields as this one.
+ */
+ public Symbol cloneSymbol(Symbol owner) {
+ AliasTypeSymbol other = new AliasTypeSymbol(pos, name, owner, flags);
+ other.setInfo(info());
+ copyConstructorInfo(other);
+ return other;
}
}
@@ -1329,24 +1427,16 @@ public class AbsTypeSymbol extends TypeSymbol {
*/
public Symbol cloneSymbol(Symbol owner) {
TypeSymbol other = new AbsTypeSymbol(pos, name, owner, flags);
- if (Global.instance.debug) System.out.println("cloning " + this + this.locationString() + " to " + other + " in phase " + Global.instance.currentPhase.name());
other.setInfo(info());
other.setLoBound(loBound());
return other;
}
- public Symbol[] typeParams() {
- return Symbol.EMPTY_ARRAY;
- }
-
- /** Get all constructors of class */
- public Symbol allConstructors() {
- return Symbol.NONE;
- }
-
- /** Get primary constructor of class */
- public Symbol primaryConstructor() {
- return Symbol.NONE;
+ /** copy all fields to `sym'
+ */
+ public void copyTo(Symbol sym) {
+ super.copyTo(sym);
+ ((AbsTypeSymbol) sym).lobound = lobound;
}
public Type loBound() {
@@ -1367,12 +1457,6 @@ public class ClassSymbol extends TypeSymbol {
/** The mangled class name */
private Name mangled;
- /** The symbol's type template */
- private Type template;
-
- /** The primary constructor of this type */
- private Symbol constructor;
-
/** The module belonging to the class. This means:
* For Java classes, its statics parts.
* For module classes, the corresponding module.
@@ -1394,7 +1478,6 @@ public class ClassSymbol extends TypeSymbol {
*/
public ClassSymbol(int pos, Name name, Symbol owner, int flags) {
super(CLASS, pos, name, owner, flags);
- this.constructor = TermSymbol.newConstructor(this, flags & ~MODUL);
this.mangled = name;
}
@@ -1404,7 +1487,6 @@ public class ClassSymbol extends TypeSymbol {
if (e.owner == scope && e.sym.isExternal() && e.sym.kind == CLASS) {
ClassSymbol sym = (ClassSymbol) e.sym;
sym.update(pos, flags);
- sym.template = null;
return sym;
} else {
return new ClassSymbol(pos, name, owner, flags);
@@ -1433,49 +1515,16 @@ public class ClassSymbol extends TypeSymbol {
ClassSymbol other = new ClassSymbol(pos, name, owner, flags);
other.module = module;
other.setInfo(info());
- other.primaryConstructor().setInfo(
- fixConstrType(
- primaryConstructor().info().cloneType(
- primaryConstructor(), other.primaryConstructor()),
- other));
- Symbol[] alts = allConstructors().alternativeSymbols();
- for (int i = 1; i < alts.length; i++) {
- Symbol constr = other.addConstructor();
- constr.setInfo(
- fixConstrType(
- alts[i].info().cloneType(alts[i], constr),
- other));
- }
+ copyConstructorInfo(other);
other.mangled = mangled;
if (thisSym != this) other.setTypeOfThis(typeOfThis());
return other;
}
- private Type fixConstrType(Type type, Symbol clone) {
- switch (type) {
- case MethodType(Symbol[] vparams, Type result):
- result = fixConstrType(result, clone);
- return new Type.MethodType(vparams, result);
- case PolyType(Symbol[] tparams, Type result):
- result = fixConstrType(result, clone);
- return new Type.PolyType(tparams, result);
- case TypeRef(Type pre, Symbol sym, Type[] args):
- assert sym == this : Debug.show(sym) + " != " + Debug.show(this);
- return new Type.TypeRef(pre, clone, args);
- case LazyType():
- return type;
- default:
- throw Debug.abort("unexpected constructor type:" + clone + ":" + type);
- }
- }
/** copy all fields to `sym'
*/
public void copyTo(Symbol sym) {
super.copyTo(sym);
- Symbol symconstr = ((ClassSymbol) sym).constructor;
- constructor.copyTo(symconstr);
- if (constructor.isInitialized())
- symconstr.setInfo(fixConstrType(symconstr.type(), sym));
if (thisSym != this) sym.setTypeOfThis(typeOfThis());
}
@@ -1522,33 +1571,6 @@ public class ClassSymbol extends TypeSymbol {
}
}
- /** Get type parameters */
- public Symbol[] typeParams() {
- return primaryConstructor().info().typeParams();
- }
-
- public Symbol[] valueParams() {
- return primaryConstructor().info().valueParams();
- }
-
- /** Get type */
- public Type type() {
- if (template == null || template.typeArgs().length != typeParams().length) {
- Symbol[] tparams = typeParams();
- if (tparams.length == 0)
- template = typeConstructor();
- else
- template = Type.TypeRef(
- owner().thisType(), this, type(typeParams()));
- }
- return template;
- }
-
- public Symbol setOwner(Symbol owner) {
- template = null;
- return super.setOwner(owner);
- }
-
public Type thisType() {
return thistp;
}
@@ -1563,24 +1585,6 @@ public class ClassSymbol extends TypeSymbol {
return this;
}
- /** add a constructor
- */
- public Symbol addConstructor() {
- Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL);
- constructor = constructor.overloadWith(constr);
- return constr;
- }
-
- /** Get primary constructor */
- public Symbol primaryConstructor() {
- return constructor.firstAlternative();
- }
-
- /** Get all constructors */
- public Symbol allConstructors() {
- return constructor;
- }
-
/** Return the next enclosing class */
public Symbol enclClass() {
return this;
@@ -1603,7 +1607,6 @@ public class ClassSymbol extends TypeSymbol {
public void reset(Type completer) {
super.reset(completer);
module().reset(completer);
- template = null;
thisSym = this;
}
}
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index b23b9448f9..e64848858d 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -988,7 +988,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
for (int i = 0; i < baseparams.length; i++) {
if (sym == baseparams[i]) return baseargs[i];
}
- //System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//DEBUG
+ System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//debug
break;
case ErrorType:
return ErrorType;
diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java
index ec75241842..58b2888d79 100644
--- a/sources/scalac/symtab/classfile/Pickle.java
+++ b/sources/scalac/symtab/classfile/Pickle.java
@@ -121,6 +121,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
putType(sym.loBound());
break;
case ALIAS:
+ putSymbol(sym.allConstructors());
break;
case CLASS:
putType(sym.typeOfThis());
@@ -308,6 +309,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
writeRef(sym.loBound());
break;
case ALIAS:
+ writeRef(sym.allConstructors());
break;
case CLASS:
writeRef(sym.typeOfThis());
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 07c30a60c4..f7f039c8c8 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -235,9 +235,10 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
break;
case ALIASsym:
- entries[n] = sym = new TypeSymbol(
- ALIAS, Position.NOPOS, name, owner, flags);
+ entries[n] = sym = new AliasTypeSymbol(
+ Position.NOPOS, name, owner, flags);
sym.setInfo(getType(inforef), Symbol.FIRST_ID);
+ Symbol constr = readSymbolRef();
break;
case CLASSsym:
@@ -262,15 +263,15 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
case VALsym:
if (bp < end) {
- ClassSymbol clazz = (ClassSymbol) readSymbolRef();
+ Symbol tsym = readSymbolRef();
if (name.isTypeName()) {
- entries[n] = sym = clazz.primaryConstructor();
+ entries[n] = sym = tsym.primaryConstructor();
sym.flags = flags;
} else {
assert (flags & MODUL) != 0 : name;
entries[n] = sym = new TermSymbol(
Position.NOPOS, name, owner, flags)
- .makeModule(clazz);
+ .makeModule((ClassSymbol) tsym);
}
} else {
entries[n] = sym = new TermSymbol(
diff --git a/sources/scalac/transformer/AddAccessors.java b/sources/scalac/transformer/AddAccessors.java
index 3d3c5a9ba8..aaed700b89 100644
--- a/sources/scalac/transformer/AddAccessors.java
+++ b/sources/scalac/transformer/AddAccessors.java
@@ -57,7 +57,7 @@ public class AddAccessors extends Transformer {
switch (tree) {
case ClassDef(_, // :
_,
- Tree.TypeDef[] tparams,
+ Tree.AbsTypeDef[] tparams,
Tree.ValDef[][] vparams,
Tree tpe,
Tree.Template impl): {
diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java
index 69c9bf0a58..18d7f296e3 100644
--- a/sources/scalac/transformer/AddInterfaces.java
+++ b/sources/scalac/transformer/AddInterfaces.java
@@ -114,7 +114,7 @@ class AddInterfaces extends Transformer {
case DefDef(int mods,
Name name,
- TypeDef[] tparams,
+ AbsTypeDef[] tparams,
ValDef[][] vparams,
Tree tpe,
Tree rhs): {
diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java
index 77b9fdb5b2..fbbed6a98d 100644
--- a/sources/scalac/transformer/AddInterfacesPhase.java
+++ b/sources/scalac/transformer/AddInterfacesPhase.java
@@ -42,7 +42,7 @@ public class AddInterfacesPhase extends PhaseDescriptor {
public Type transformInfo(Symbol sym, Type tp) {
if (sym.isPrimaryConstructor()) {
Symbol clazz = sym.primaryConstructorClass();
- if (clazz.isPackage() || !needInterface(clazz)) return tp;
+ if (!(clazz.isClass() && needInterface(clazz))) return tp;
// The symbol is a constructor of a class which needs
// an interface. All its value arguments have to be
// removed.
diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java
index 5e855c2cd3..aceb0b03f1 100644
--- a/sources/scalac/transformer/Erasure.java
+++ b/sources/scalac/transformer/Erasure.java
@@ -15,7 +15,8 @@ import scalac.Global;
import scalac.Unit;
import scalac.ast.Tree;
import scalac.ast.Tree.Template;
-import scalac.ast.Tree.TypeDef;
+import scalac.ast.Tree.AbsTypeDef;
+import scalac.ast.Tree.AliasTypeDef;
import scalac.ast.Tree.ValDef;
import scalac.ast.TreeList;
import scalac.ast.Transformer;
@@ -329,22 +330,22 @@ public class Erasure extends Transformer implements Modifiers {
assert tree.type != null : tree;
Type owntype = eraseFully ? tree.type.fullErasure() : tree.type.erasure();
switch (tree) {
- case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
+ case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
Symbol oldCurrentClass = currentClass;
currentClass = tree.symbol();
Tree newTree =
- copy.ClassDef(tree, new TypeDef[0],
+ copy.ClassDef(tree, new AbsTypeDef[0],
transform(vparams), tpe, transform(impl, tree.symbol()))
.setType(owntype);
currentClass = oldCurrentClass;
return newTree;
- case DefDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
addBridges(tree.symbol());
Tree tpe1 = gen.mkType(tpe.pos, tpe.type.fullErasure());
Tree rhs1 = (rhs == Tree.Empty) ? rhs : transform(rhs, tpe1.type);
return copy.DefDef(
- tree, new TypeDef[0], transform(vparams), tpe1, rhs1)
+ tree, new AbsTypeDef[0], transform(vparams), tpe1, rhs1)
.setType(owntype);
case ValDef(_, _, Tree tpe, Tree rhs):
@@ -352,7 +353,8 @@ public class Erasure extends Transformer implements Modifiers {
Tree rhs1 = (rhs == Tree.Empty) ? rhs : transform(rhs, tpe1.type);
return copy.ValDef(tree, tpe1, rhs1).setType(owntype);
- case TypeDef(_, _, _, _):
+ case AbsTypeDef(_, _, _, _):
+ case AliasTypeDef(_, _, _, _):
// eliminate
return Tree.Empty;
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 6193af3fa3..8651abb0c7 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -209,15 +209,24 @@ public class LambdaLift extends OwnerTransformer
}
return super.transform(tree);
- case TypeDef(int mods, Name name, Tree rhs, Tree lobound):
+ case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound):
// ignore type definition as owner.
// reason: it might be in a refinement
// todo: handle type parameters?
- return copy.TypeDef(
+ return copy.AbsTypeDef(
tree, sym,
transform(rhs, currentOwner),
transform(lobound, currentOwner));
+ case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs):
+ // ignore type definition as owner.
+ // reason: it might be in a refinement
+ // todo: handle type parameters?
+ return copy.AliasTypeDef(
+ tree, sym,
+ transform(tparams, currentOwner),
+ transform(rhs, currentOwner));
+
case Ident(_):
if (sym.isLocal()) {
if (sym.isMethod()) {
@@ -321,7 +330,7 @@ public class LambdaLift extends OwnerTransformer
liftSymbol(stats[i]);
return copy.Block(tree, transform(stats));
- case ClassDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
+ case ClassDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
Symbol sym = tree.symbol();
if ((mods & LIFTED) != 0) {
((ClassDef) tree).mods &= ~LIFTED;
@@ -344,7 +353,7 @@ public class LambdaLift extends OwnerTransformer
transform(impl, sym));
}
- case DefDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
Symbol sym = tree.symbol();
if ((mods & LIFTED) != 0) {
((DefDef) tree).mods &= ~LIFTED;
@@ -365,15 +374,24 @@ public class LambdaLift extends OwnerTransformer
transform(rhs, sym));
}
- case TypeDef(int mods, Name name, Tree rhs, Tree lobound):
+ case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound):
// ignore type definition as owner.
// reason: it might be in a refinement
// todo: handle type parameters?
- return copy.TypeDef(
+ return copy.AbsTypeDef(
tree, tree.symbol(),
transform(rhs, currentOwner),
transform(lobound, currentOwner));
+ case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs):
+ // ignore type definition as owner.
+ // reason: it might be in a refinement
+ // todo: handle type parameters?
+ return copy.AliasTypeDef(
+ tree, tree.symbol(),
+ transform(tparams, currentOwner),
+ transform(rhs, currentOwner));
+
case ValDef(_, _, Tree tpe, Tree rhs):
Symbol sym = tree.symbol();
Tree tpe1 = transform(tpe);
@@ -587,9 +605,9 @@ public class LambdaLift extends OwnerTransformer
}
}
- TypeDef[] addTypeParams(TypeDef[] tparams, Symbol[] newtparams) {
+ AbsTypeDef[] addTypeParams(AbsTypeDef[] tparams, Symbol[] newtparams) {
if (newtparams.length == 0) return tparams;
- TypeDef[] tparams1 = new TypeDef[tparams.length + newtparams.length];
+ AbsTypeDef[] tparams1 = new AbsTypeDef[tparams.length + newtparams.length];
System.arraycopy(tparams, 0, tparams1, 0, tparams.length);
for (int i = 0; i < newtparams.length; i++) {
tparams1[tparams.length + i] = gen.mkTypeParam(newtparams[i]);
diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java
index 587362e345..bb7ab098c7 100644
--- a/sources/scalac/transformer/OwnerTransformer.java
+++ b/sources/scalac/transformer/OwnerTransformer.java
@@ -43,10 +43,10 @@ public class OwnerTransformer extends Transformer {
return tree1;
}
- public TypeDef[] transform(TypeDef[] params, Symbol owner) {
+ public AbsTypeDef[] transform(AbsTypeDef[] params, Symbol owner) {
Symbol prevOwner = currentOwner;
currentOwner = owner;
- TypeDef[] res = transform(params);
+ AbsTypeDef[] res = transform(params);
currentOwner = prevOwner;
return res;
}
@@ -95,7 +95,7 @@ public class OwnerTransformer extends Transformer {
transform(packaged),
transform(impl, packaged.symbol()));
- case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
+ case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
Symbol symbol = tree.symbol();
return copy.ClassDef(
tree, symbol,
@@ -111,7 +111,7 @@ public class OwnerTransformer extends Transformer {
transform(tpe),
transform(impl, symbol.moduleClass()));
- case DefDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
Symbol symbol = tree.symbol();
return copy.DefDef(
tree, symbol,
@@ -127,12 +127,19 @@ public class OwnerTransformer extends Transformer {
transform(tpe),
transform(rhs, symbol));
- case TypeDef(int mods, Name name, Tree rhs, Tree lobound):
- Symbol sym = tree.symbol();
- return copy.TypeDef(
- tree, sym,
- transform(rhs, sym),
- transform(lobound, sym));
+ case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound):
+ Symbol symbol = tree.symbol();
+ return copy.AbsTypeDef(
+ tree, symbol,
+ transform(rhs, symbol),
+ transform(lobound, symbol));
+
+ case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs):
+ Symbol symbol = tree.symbol();
+ return copy.AliasTypeDef(
+ tree, symbol,
+ transform(tparams, symbol),
+ transform(rhs, symbol));
default:
return super.transform(tree);
diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java
index ff81672940..3d9d46c9cf 100644
--- a/sources/scalac/transformer/UnCurry.java
+++ b/sources/scalac/transformer/UnCurry.java
@@ -72,14 +72,14 @@ public class UnCurry extends OwnerTransformer
//uncurry type and symbol
if (tree.type != null) tree.type = descr.uncurry(tree.type);
switch (tree) {
- case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
+ case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl):
return copy.ClassDef(
tree, tree.symbol(), tparams,
uncurry(transform(vparams, tree.symbol())),
tpe,
transform(impl, tree.symbol()));
- case DefDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
Tree rhs1 = transform(rhs, tree.symbol());
return copy.DefDef(
tree, tree.symbol(), tparams,
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 91be325a8a..8ee5cd2b20 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -167,7 +167,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
static final int SEQUENCEmode = 0x1000; // orthogonal to above. When set
// we turn "x" into "x@_"
// and allow args to be of type Seq[ a ] instead of a
- static final int notSEQUENCEmode = Integer.MAX_VALUE - SEQUENCEmode;
// Diagnostics ----------------------------------------------------------------
@@ -700,7 +699,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
throw new ApplicationError();
}
- case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, _, Tree.Template templ):
+ case ClassDef(int mods, Name name, AbsTypeDef[] tparams, ValDef[][] vparams, _, Tree.Template templ):
ClassSymbol clazz = ClassSymbol.define(
tree.pos, name, owner, mods, context.scope);
if (clazz.isLocalClass()) unit.mangler.setMangledName(clazz);
@@ -752,11 +751,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
return enterSym(tree, sym);
- case TypeDef(int mods, Name name, _, _):
- Symbol tsym = ((mods & (DEFERRED | PARAM)) != 0)
- ? AbsTypeSymbol.define(tree.pos, name, owner, mods, context.scope)
- : TypeSymbol.define(tree.pos, name, owner, mods, context.scope);
- return enterSym(tree, tsym);
+ case AliasTypeDef(int mods, Name name, _, _):
+ return enterSym(
+ tree,
+ AliasTypeSymbol.define(tree.pos, name, owner, mods, context.scope));
+
+ case AbsTypeDef(int mods, Name name, _, _):
+ return enterSym(
+ tree,
+ AbsTypeSymbol.define(tree.pos, name, owner, mods, context.scope));
case Import(Tree expr, Name[] selectors):
return enterImport(tree,
@@ -888,17 +891,23 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Re-enter type parameters in current scope.
*/
- void reenterParams(TypeDef[] tparams, ValDef[][] vparamss, Type mt) {
+ void reenterParams(AbsTypeDef[] tparams, Symbol[] tsyms) {
+ for (int i = 0; i < tparams.length; i++) {
+ tsyms[i].pos = tparams[i].pos;
+ tsyms[i].name = tparams[i].name;
+ //necessary since tsyms might have been unpickled
+ tparams[i].setSymbol(tsyms[i]);
+ context.scope.enter(tsyms[i]);
+ }
+ }
+
+ /** Re-enter type and value parameters in current scope.
+ */
+ void reenterParams(AbsTypeDef[] tparams, ValDef[][] vparamss, Type mt) {
Type rest = mt;
switch (rest) {
case PolyType(Symbol[] tsyms, Type restp):
- for (int i = 0; i < tparams.length; i++) {
- tsyms[i].pos = tparams[i].pos;
- tsyms[i].name = tparams[i].name;
- //necessary since tsyms might have been unpickled
- tparams[i].setSymbol(tsyms[i]);
- context.scope.enter(tsyms[i]);
- }
+ reenterParams(tparams, tsyms);
rest = restp;
}
for (int j = 0; j < vparamss.length; j++) {
@@ -930,15 +939,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.mode = EXPRmode;
Type savedPt = this.pt;
this.pt = Type.AnyType;
- int savedId = global.currentPhase.id;
- global.currentPhase.id = descr.id;
try {
Symbol sym = tree.symbol();
if (global.debug) global.log("defining " + sym);
Type owntype;
switch (tree) {
- case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
+ case ClassDef(int mods, Name name, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
pushContext(
tree, sym.primaryConstructor(), new Scope(context.scope));
Symbol[] tparamSyms = enterParams(tparams);
@@ -974,7 +981,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
owntype = (tpe == Tree.Empty) ? clazz.type() : tpe.type;
break;
- case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(int mods, Name name, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
Symbol[] tparamSyms;
Symbol[][] vparamSyms;
Type restype;
@@ -1031,25 +1038,28 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
popContext();
}
- //checkNonCyclic(tree.pos, tpe.type);
break;
- case TypeDef(int mods, Name name, Tree rhs, Tree lobound):
- if (sym.kind == TYPE) {
- //can't have `sym' as owner since checkNonCyclic would fail.
- ((TypeDef) tree).rhs = rhs = transform(rhs, TYPEmode);
- ((TypeDef) tree).lobound = lobound = transform(lobound, TYPEmode);
- owntype = rhs.type;
- sym.setLoBound(lobound.type);
- owntype.symbol().initialize();//to detect cycles todo: needed?
- } else { // sym.kind == ALIAS
- pushContext(tree, sym, context.scope);
- ((TypeDef) tree).rhs = rhs = transform(rhs, TYPEmode | FUNmode);
- owntype = rhs.type;
- popContext();
- }
+ case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs):
+ pushContext(tree, sym.primaryConstructor(), new Scope(context.scope));
+ Symbol[] tparamSyms = enterParams(tparams);
+ ((AliasTypeDef) tree).rhs = rhs = transform(rhs, TYPEmode);
+ owntype = rhs.type;
+ sym.primaryConstructor().setInfo(
+ Type.PolyType(tparamSyms, sym.typeConstructor()));
+ // necessary so that we can access tparams
+ sym.primaryConstructor().flags |= INITIALIZED;
- //checkNonCyclic(tree.pos, owntype);
+ popContext();
+ break;
+
+ case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound):
+ //can't have `sym' as owner since checkNonCyclic would fail.
+ ((AbsTypeDef) tree).rhs = rhs = transform(rhs, TYPEmode);
+ ((AbsTypeDef) tree).lobound = lobound = transform(lobound, TYPEmode);
+ owntype = rhs.type;
+ sym.setLoBound(lobound.type);
+ owntype.symbol().initialize();//to detect cycles todo: needed?
break;
case Import(Tree expr, Name[] selectors):
@@ -1081,7 +1091,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.context = savedContext;
this.mode = savedMode;
this.pt = savedPt;
- global.currentPhase.id = savedId;
}
/** Definition phase for a template. This enters all symbols in template
@@ -1198,6 +1207,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case PolyType(Symbol[] tparams, Type restp):
try {
infer.constructorInstance(tree, tparams, restp, pt);
+ //System.out.println("constr inst " + ArrayApply.toString(tparams) + restp + " against " + pt + " = " + tree.type);//DEBUG
} catch (Type.Error ex) {
if (pt != Type.ErrorType) error(tree.pos, ex.msg);
return tree.setType(Type.ErrorType);
@@ -1298,22 +1308,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return Type.MethodType(new Symbol[]{param}, resulttp);
}
- Symbol typeToConstructor(int pos, Symbol sym) {
- if (sym.kind == ERROR)
- return sym;
- else if ((mode & CONSTRmode) != 0) {
- assert sym.isType() : sym;
- sym.initialize();
- Symbol constr = sym.allConstructors();
- if (constr.kind == NONE)
- error(pos, sym + " is abstract type; cannot be instantiated");
- //System.out.println(sym + ":" + constr + ":" + constr.rawInfo() + " --toconstr--> " + constr.info());//DEBUG
- return constr;
- } else {
- return sym;
- }
- }
-
/** Attribute an identifier consisting of a simple name or an outer reference.
* @param tree The tree representing the identifier.
* @param name The name of the identifier.
@@ -1409,7 +1403,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
//new TextTreePrinter().print(name + " => ").print(lastimports.tree).print("." + name).println().end();//DEBUG
tree = make.Select(tree.pos, qual, name);
}
- sym = typeToConstructor(tree.pos, sym);
if (qual != Tree.Empty) checkAccessible(tree.pos, sym, qual);
Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type())
.asSeenFrom(pre, sym.owner());
@@ -1439,7 +1432,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return error(tree.pos,
decode(name) + " is not a member of " + qual.type.widen());
} else {
- sym = typeToConstructor(tree.pos, sym);
checkAccessible(tree.pos, sym, qual);
sym.flags |= ACCESSED;
if (!TreeInfo.isSelf(qual, context.enclClass.owner))
@@ -1785,11 +1777,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
return tree.setType(Type.ErrorType);
- case ClassDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
+ case ClassDef(_, _, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
pushContext(
tree, sym.primaryConstructor(), new Scope(context.scope));
reenterParams(tparams, vparams, sym.primaryConstructor().type());
- Tree.TypeDef[] tparams1 = transform(tparams);
+ Tree.AbsTypeDef[] tparams1 = transform(tparams);
Tree.ValDef[][] vparams1 = transform(vparams);
Tree tpe1 = transform(tpe, TYPEmode);
if ((sym.flags & CASE) != 0 && vparams.length > 0 && templ.type == null)
@@ -1808,7 +1800,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return copy.ModuleDef(tree, sym, tpe1, templ1)
.setType(definitions.UNIT_TYPE);
- case DefDef(_, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
+ case DefDef(_, Name name, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
Context prevContext = context;
if (name.isTypeName()) {
Symbol clazz = context.enclClass.owner;
@@ -1816,7 +1808,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
pushContext(tree, sym, new Scope(context.scope));
reenterParams(tparams, vparams, sym.type());
- Tree.TypeDef[] tparams1 = transform(tparams);
+ Tree.AbsTypeDef[] tparams1 = transform(tparams);
Tree.ValDef[][] vparams1 = transform(vparams);
Tree tpe1 = (tpe == Tree.Empty)
? gen.mkType(tree.pos, sym.type().resultType())
@@ -1849,17 +1841,21 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return copy.ValDef(tree, sym, tpe1, rhs1)
.setType(definitions.UNIT_TYPE);
- case TypeDef(_, _, Tree rhs, Tree lobound):
- Tree rhs1, lobound1;
- if (sym.kind == TYPE) {
- rhs1 = transform(rhs, TYPEmode);
- lobound1 = transform(lobound, TYPEmode);
- } else { // sym.kind == ALIAS
- rhs1 = transform(rhs, TYPEmode | FUNmode);
- lobound1 = lobound;
- }
+ case AbsTypeDef(_, _, Tree rhs, Tree lobound):
+ Tree rhs1 = transform(rhs, TYPEmode);
+ Tree lobound1 = transform(lobound, TYPEmode);
+ checkNonCyclic(tree.pos, sym.type());
+ return copy.AbsTypeDef(tree, sym, rhs1, lobound1)
+ .setType(definitions.UNIT_TYPE);
+
+ case AliasTypeDef(_, _, AbsTypeDef[] tparams, Tree rhs):
+ pushContext(tree, sym.primaryConstructor(), new Scope(context.scope));
+ reenterParams(tparams, sym.typeParams());
+ AbsTypeDef[] tparams1 = transform(tparams);
+ Tree rhs1 = transform(rhs, TYPEmode);
+ popContext();
checkNonCyclic(tree.pos, sym.type());
- return copy.TypeDef(tree, sym, rhs1, lobound1)
+ return copy.AliasTypeDef(tree, sym, tparams1, rhs1)
.setType(definitions.UNIT_TYPE);
case Import(Tree expr, Name[] selectors):
@@ -2009,7 +2005,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
templ.pos,
0,
Names.ANON_CLASS_NAME.toTypeName(),
- Tree.TypeDef_EMPTY_ARRAY,
+ Tree.AbsTypeDef_EMPTY_ARRAY,
new ValDef[][]{Tree.ValDef_EMPTY_ARRAY},
Tree.Empty,
templ);
@@ -2105,22 +2101,61 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
ArrayApply.toString(argtypes, "[", ",", "]"));
case Apply(Tree fn, Tree[] args):
- mode = mode & notSEQUENCEmode;
+ mode = mode & ~SEQUENCEmode;
Tree fn1;
int argMode;
//todo: Should we pass in both cases a methodtype with
// AnyType's for args as a prototype?
- if ((mode & (EXPRmode | CONSTRmode)) != 0) {
+ if ((mode & EXPRmode) != 0) {
fn1 = transform(fn, mode | FUNmode, Type.AnyType);
argMode = EXPRmode;
- } else {
- assert (mode & PATTERNmode) != 0;
+ } else if ((mode & PATTERNmode) != 0) {
fn1 = transform(fn, mode | FUNmode, pt);
argMode = PATTERNmode;
+ } else {
+ assert (mode & CONSTRmode) != 0;
+ fn1 = transform(fn, mode | FUNmode, Type.AnyType);
+ argMode = EXPRmode;
+
+ // convert type to constructor
+ Symbol tsym = TreeInfo.methSymbol(fn1);
+ assert tsym.isType() : tsym;
+ Type tp = fn1.type.unalias();
+ switch (tp) {
+ case TypeRef(Type pre, Symbol c, Type[] argtypes):
+ if (c.kind == CLASS) {
+ c.initialize();
+ Tree fn0 = fn1;
+ fn1 = gen.mkRef(tree.pos, pre, c.allConstructors());
+ if (tsym == c) {
+ switch (fn0) {
+ case AppliedType(_, Tree[] targs):
+ fn1 = gen.TypeApply(fn1, targs);
+ }
+ } else {
+ // it was an alias type
+ // todo: handle overloaded constructors
+ fn1 = gen.TypeApply(
+ fn1, gen.mkTypes(tree.pos, argtypes));
+ if (tsym.typeParams().length != 0 &&
+ !(fn0 instanceof AppliedType))
+ fn1.type = Type.PolyType(
+ tsym.typeParams(), fn1.type);
+ }
+ //System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.type + " of " + fn1);//DEBUG
+ } else {
+ error(tree.pos,
+ tsym + " is not a class; cannot be instantiated");
+ }
+ break;
+ default:
+ error(tree.pos,
+ tsym + " is not a class; cannot be instantiated");
+ }
}
- // if function is overloaded with one alternative whose arity matches
- // argument length, preselect this alternative.
+ // if function is overloaded with one alternative
+ // whose arity matches argument length, preselect this alternative.
switch (fn1.type) {
case OverloadedType(Symbol[] alts, Type[] alttypes):
int matching1 = -1;
@@ -2332,16 +2367,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
.setType(self);
case AppliedType(Tree tpe, Tree[] args):
- Tree tpe1 = transform(tpe, TYPEmode | FUNmode);
+ Tree tpe1 = transform(tpe, mode | FUNmode);
Tree[] args1 = transform(args, TYPEmode);
Type[] argtypes = Tree.typeOf(args);
Symbol[] tparams = tpe1.type.symbol().typeParams();
- /*
- //todo: this needs to be refined. (same code in RefCheck.transform)
- (Type.isSameAs(tpe1.type.typeArgs(), Symbol.type(tpe1.type.unalias().symbol().typeParams())))
- ?
- : Symbol.EMPTY_ARRAY;
- */
Type owntype = Type.ErrorType;
if (tpe1.type != Type.ErrorType) {
if (tparams.length == args.length)
diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java
index 87cea76d13..1de733b798 100644
--- a/sources/scalac/typechecker/DeSugarize.java
+++ b/sources/scalac/typechecker/DeSugarize.java
@@ -215,12 +215,12 @@ public class DeSugarize implements Kinds, Modifiers {
Tree applyDef = make.DefDef(
tree.pos, 0, Names.apply,
- Tree.TypeDef_EMPTY_ARRAY, new ValDef[][]{vparams},
+ Tree.AbsTypeDef_EMPTY_ARRAY, new ValDef[][]{vparams},
restpe, body);
Tree toStringDef = make.DefDef(
tree.pos, Modifiers.OVERRIDE, Names.toString,
- Tree.TypeDef_EMPTY_ARRAY,
+ Tree.AbsTypeDef_EMPTY_ARRAY,
new ValDef[][]{Tree.ValDef_EMPTY_ARRAY},
gen.mkType(tree.pos, global.definitions.JAVA_STRING_TYPE),
make.Literal(tree.pos, "<function>"));
@@ -267,14 +267,14 @@ public class DeSugarize implements Kinds, Modifiers {
make.Select(tree.pos,
make.Ident(tree.pos, x), Names.match), new Tree[]{tree});
Tree applyDef = make.DefDef(
- tree.pos, 0, Names.apply, Tree.TypeDef_EMPTY_ARRAY, vparams,
+ tree.pos, 0, Names.apply, Tree.AbsTypeDef_EMPTY_ARRAY, vparams,
gen.mkType(tree.pos, restpe), body);
Tree tree1 = isDefinedAtVisitor(tree);
Tree body1 = make.Apply(tree.pos,
make.Select(tree.pos,
make.Ident(tree.pos, x), Names.match), new Tree[]{tree1});
Tree isDefinedAtDef = make.DefDef(
- tree.pos, 0, Names.isDefinedAt, Tree.TypeDef_EMPTY_ARRAY,
+ tree.pos, 0, Names.isDefinedAt, Tree.AbsTypeDef_EMPTY_ARRAY,
Tree.duplicator.transform(vparams),
gen.mkType(tree.pos, global.definitions.BOOLEAN_TYPE), body1);
Tree result = make.New(tree.pos,
@@ -539,7 +539,7 @@ public class DeSugarize implements Kinds, Modifiers {
if ((mods1 & MUTABLE) == 0) mods1 |= STABLE;
Tree getter = make.DefDef(
tree.pos, mods1, name,
- Tree.TypeDef_EMPTY_ARRAY, Tree.ValDef_EMPTY_ARRAY_ARRAY,
+ Tree.AbsTypeDef_EMPTY_ARRAY, Tree.ValDef_EMPTY_ARRAY_ARRAY,
tpe,
((mods & DEFERRED) != 0) ? Tree.Empty
: make.Ident(tree.pos, valname));
@@ -549,7 +549,7 @@ public class DeSugarize implements Kinds, Modifiers {
} else {
Tree setter = make.DefDef(
tree.pos, mods1, setterName(name),
- Tree.TypeDef_EMPTY_ARRAY,
+ Tree.AbsTypeDef_EMPTY_ARRAY,
new ValDef[][]{{
(ValDef) make.ValDef(
tree.pos, SYNTHETIC | PARAM, parameterName(0), tpe, Tree.Empty)}},
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index b3a6babae5..30ed7086a4 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -449,8 +449,8 @@ public class Infer implements Modifiers, Kinds {
: !upper;
tvars[i] = Type.NoType;
Type bound = up ? tparams[i].info() : tparams[i].loBound();
- if (up && bound != Global.instance.definitions.ANY_TYPE ||
- !up && bound != Global.instance.definitions.ALL_TYPE) {
+ if (up && bound.symbol() != Global.instance.definitions.ANY_CLASS ||
+ !up && bound.symbol() != Global.instance.definitions.ALL_CLASS) {
boolean cyclic = false;
for (int j = 0; j < tvars.length; j++) {
if (bound.contains(tparams[j]) ||
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 00279759ec..08f1539eb8 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -424,7 +424,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
tree.pos,
mods | FINAL | MODUL,
name.toTypeName(),
- Tree.TypeDef_EMPTY_ARRAY,
+ Tree.AbsTypeDef_EMPTY_ARRAY,
Tree.ValDef_EMPTY_ARRAY_ARRAY,
Tree.Empty,
templ)
@@ -828,7 +828,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
public Tree transform(Tree tree) {
Symbol sym = tree.symbol();
switch (tree) {
- case ClassDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
+ case ClassDef(_, _, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):
validateVariance(sym, sym.info(), CoVariance);
validateVariance(sym, sym.typeOfThis(), CoVariance);
return super.transform(
@@ -844,13 +844,13 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
((sym.flags & MUTABLE) != 0) ? NoVariance : CoVariance);
return super.transform(tree);
- case TypeDef(_, _, _, _):
- if (sym.kind == ALIAS) {
- validateVariance(sym, sym.info(), NoVariance);
- } else {
- validateVariance(sym, sym.info(), CoVariance);
- validateVariance(sym, sym.loBound(), ContraVariance);
- }
+ case AbsTypeDef(_, _, _, _):
+ validateVariance(sym, sym.info(), CoVariance);
+ validateVariance(sym, sym.loBound(), ContraVariance);
+ return super.transform(tree);
+
+ case AliasTypeDef(_, _, _, _):
+ validateVariance(sym, sym.info(), NoVariance);
return super.transform(tree);
case Template(Tree[] bases, Tree[] body):
@@ -894,13 +894,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
case AppliedType(Tree tpe, Tree[] args):
Symbol[] tparams = tpe.type.symbol().typeParams();
- /*
- //todo: this needs to be refined. (same code in Analyzer.transform)
- Symbol[] tparams =
- (Type.isSameAs(
- tpe.type.typeArgs(), Symbol.type(tpe.type.unalias().symbol().typeParams())))
- ? tpe.type.unalias().symbol().typeParams() : Symbol.EMPTY_ARRAY;
- */
checkBounds(tree.pos, tparams, Tree.typeOf(args));
return elimTypeNode(super.transform(tree));