summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ScalaByExample.tex36
-rw-r--r--doc/reference/ScalaReference.tex90
-rw-r--r--sources/scala/Symbol.scala25
-rw-r--r--sources/scala/concurrent/pilib.scala2
-rw-r--r--sources/scala/tools/scalac/ast/parser/Parser.scala26
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala13
-rw-r--r--sources/scala/tools/scalac/typechecker/Infer.scala24
-rw-r--r--sources/scalac/ast/parser/Parser.java22
-rw-r--r--sources/scalac/symtab/Type.java37
-rw-r--r--sources/scalac/transformer/UnCurry.java28
-rw-r--r--sources/scalac/transformer/matching/AlgebraicMatcher.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java14
-rw-r--r--sources/scalac/typechecker/Infer.java21
-rw-r--r--test/files/neg/bug38.check11
-rw-r--r--test/neg/bug38.check11
15 files changed, 189 insertions, 175 deletions
diff --git a/doc/reference/ScalaByExample.tex b/doc/reference/ScalaByExample.tex
index c7659ff25c..a5eaf71c41 100644
--- a/doc/reference/ScalaByExample.tex
+++ b/doc/reference/ScalaByExample.tex
@@ -271,6 +271,24 @@ its incoming messages which is represented as a queue. It can work
sequentially through the messages in its mailbox, or search for
messages matching some pattern.
+\begin{lstlisting}[style=floating,label=fig:simple-auction-msgs,caption=Implementation of an Auction Service]
+trait AuctionMessage;
+
+/** make a bid */
+case class Offer(bid: int, client: Actor) extends AuctionMessage;
+
+/** inquire status */
+case class Inquire(client: Actor) extends AuctionMessage;
+
+trait AuctionReply;
+case class Status(asked: int, expiration: Date) extends AuctionReply;
+case object BestOffer extends AuctionReply;
+case class BeatenOffer(maxBid: int) extends AuctionReply;
+case class AuctionConcluded(seller: Actor, client: Actor) extends AuctionReply;
+case object AuctionFailed extends AuctionReply;
+case object AuctionOver extends AuctionReply;
+\end{lstlisting}
+
For every traded item there is an auctioneer process that publishes
information about the traded item, that accepts offers from clients
and that communicates with the seller and winning bidder to close the
@@ -281,22 +299,8 @@ As a first step, we define the messages that are exchanged during an
auction. There are two abstract base classes (called {\em traits}):
\code{AuctionMessage} for messages from clients to the auction
service, and \code{AuctionReply} for replies from the service to the
-clients. These are defined as follows.
-\begin{lstlisting}
-trait AuctionMessage;
-case class
- Offer(bid: int, client: Actor), // make a bid
- Inquire(client: Actor) extends AuctionMessage; // inquire status
-
-trait AuctionReply;
-case class
- Status(asked: int, expiration: Date), // asked sum, expiration date
- BestOffer, // yours is the best offer
- BeatenOffer(maxBid: int), // offer beaten by maxBid
- AuctionConcluded(seller: Actor, client: Actor), // auction concluded
- AuctionFailed, // failed with no bids
- AuctionOver extends AuctionReply; // bidding is closed
-\end{lstlisting}
+clients. For both base classes there exists a number of cases, which
+are defined in Figure~\ref{fig:simple-auction-msgs}.
\begin{lstlisting}[style=floating,label=fig:simple-auction,caption=Implementation of an Auction Service]
class Auction(seller: Actor, minBid: int, closing: Date) extends Actor {
diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex
index 9b3c4096c7..c128f40bd6 100644
--- a/doc/reference/ScalaReference.tex
+++ b/doc/reference/ScalaReference.tex
@@ -1577,7 +1577,7 @@ are the base classes of $T$.
The notions of mixin base classes and base classes are extended from
classes to arbitrary types following the definitions of
\sref{sec:base-classes}.
-
+
If two types in the base class sequence of a template refer to the
same class definition, then that definition must define a trait
(\sref{sec:traits}), and the type that comes later in the sequence must
@@ -1626,32 +1626,33 @@ represented by the constructor invocation.
The object resulting from evaluation of a template has directly bound
members and inherited members. Members can be abstract or concrete.
-These are defined as follows.
+For a template $T$ these categories are defined as follows.
\begin{enumerate}
\item
-A {\em directly bound} member is an entity introduced by a member
-definition or declaration in the template's statement sequence. The
+A {\em directly bound} member of $T$ is an entity introduced by a member
+definition or declaration in the $T$'s statement sequence. The
member is called {\em abstract} if it is introduced by a declaration,
{\em concrete} otherwise.
\item
-A {\em concrete inherited} member is a non-private, concrete member of
-one of the template's base classes $B$, except if a member with the
-same \ifqualified{qualified} name is already directly bound in the template, or is
-directly bound in a base class of the template which is a subclass of
-$B$, or is a directly bound, non-private, concrete member of a base
-class which succeeds $B$ in the base class sequence of the template.
+A {\em concrete inherited} member of $T$ is a non-private, concrete member of
+one of $T$'s parent classes, except if a member with the same name is
+already directly bound in $T$ or the member is mixin-overridden in
+$T$. A member $m$ of $T$'s superclass is {\em mixin-overridden} in $T$
+if there is a concrete member of a mixin base class of $T$ which
+either overrides $m$ itself or overrides a member named $m$ of a base
+class of $T$'s superclass.
\item
-An {\em abstract inherited} member is a non-private, abstract member
-of one of the template's base classes $B$, except if a member with the
-same \ifqualified{qualified} name is already directly bound in the template, or is a
-concrete inherited member, or is a directly bound, non-private member
-of a base class which succeeds $B$ in the base class sequence of the
-template.
+An {\em abstract inherited} member of $T$ is a non-private, abstract member
+of one of $T$'s parent classes $P$, except if the template has a
+directly bound or concrete inherited member with the same name, or the
+template has an abstract member inherited from a parent class which
+precedes $P$, and which has the same modifiers and type as the member
+inherited from $P$ would have in $T$.
\end{enumerate}
+It is an error if a template has more than one member with
+the same name.
+
-If two mixin classes of a template each have a concrete member
-with the same name, then the template itself must also declare or
-define a member with the same name.
\comment{
The type of a member $m$ is determined as follows: If $m$ is defined
@@ -1951,9 +1952,9 @@ $t$.
\subsection{Constructor Definitions}
\syntax\begin{lstlisting}
- FunDef ::= this ParamClause `=' ConstrExpr
- ConstrExpr ::= this ArgumentExpr
- | `{' this ArgumentExpr {`;' BlockStat} `}'
+ FunDef ::= this ParamClause`=' ConstrExpr
+ ConstrExpr ::= this ArgumentExprs
+ | `{' this ArgumentExprs {`;' BlockStat} `}'
\end{lstlisting}
A class may have additional constructors besides the primary
@@ -2267,11 +2268,11 @@ module FileSystem with {
| return [Expr]
| throw Expr
| [SimpleExpr `.'] id `=' Expr
- | SimpleExpr ArgumentExpr `=' Expr
+ | SimpleExpr ArgumentExprs `=' Expr
| PostfixExpr [`:' Type1]
PostfixExpr ::= InfixExpr [id]
InfixExpr ::= PrefixExpr
- | InfixExpr id InfixExpr
+ | InfixExpr id PrefixExpr
PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
SimpleExpr ::= Literal
| Path
@@ -2280,8 +2281,8 @@ module FileSystem with {
| new Template
| SimpleExpr `.' id
| SimpleExpr TypeArgs
- | SimpleExpr ArgumentExpr
- ArgumentExpr ::= `(' Expr ')'
+ | SimpleExpr ArgumentExprs
+ ArgumentExprs ::= `(' [Exprs] ')'
| BlockExpr
BlockExpr ::= `{' CaseClause {CaseClause} `}'
| `{' Block `}'
@@ -2326,10 +2327,10 @@ character literal denotes a Unicode character. A string literal
denotes a member of \lstinline@scala.Predef.String@.
A symbol literal ~\lstinline@'$x$@~ is a shorthand for the expression
-~\lstinline@scala.Symbol("$x$")@. If the symbol literal is followed by an
-actual parameters, as in ~\lstinline@'$x$($\args\,$)@, then the whole expression
-is taken to be a shorthand for
-~\lstinline@scala.Labelled(scala.Symbol("$x$"), $\args\,$)@.
+~\lstinline@scala.Symbol("$x$")@. If the symbol literal is followed by
+actual parameters, as in ~\lstinline@'$x$($\args\,$)@, then the whole
+expression is taken to be a shorthand for
+~\lstinline@scala.Symbol("$x$", $\args\,$)@.
\subsection{Boolean constants}
@@ -2499,7 +2500,7 @@ trait BorderedColoredShape extends Shape with Bordered with Colored {
\label{sec:apply}
\syntax\begin{lstlisting}
- SimpleExpr ::= SimpleExpr ArgumentExpr
+ SimpleExpr ::= SimpleExpr ArgumentExprs
\end{lstlisting}
An application \lstinline@$f$($e_1 \commadots e_n$)@ applies the function $f$ to the
@@ -2757,7 +2758,7 @@ replaced by the expected type $B$.
\syntax\begin{lstlisting}
PostfixExpr ::= InfixExpr [id]
InfixExpr ::= PrefixExpr
- | InfixExpr id InfixExpr
+ | InfixExpr id PrefixExpr
PrefixExpr ::= [`-' | `+' | `!' | `~'] SimpleExpr
\end{lstlisting}
@@ -2848,7 +2849,7 @@ the expression is the value of $e$ converted to type $T$.
\syntax\begin{lstlisting}
Expr1 ::= Designator `=' Expr
- | SimpleExpr ArgumentExpr `=' Expr
+ | SimpleExpr ArgumentExprs `=' Expr
\end{lstlisting}
The interpretation of assignment to a simple variable ~\lstinline@$x$ = $e$@~
@@ -4233,11 +4234,11 @@ grammar.
| return [Expr]
| throw Expr
| [SimpleExpr `.'] id `=' Expr
- | SimpleExpr ArgumentExpr `=' Expr
+ | SimpleExpr ArgumentExprs `=' Expr
| PostfixExpr [`:' Type1]
PostfixExpr ::= InfixExpr [id]
InfixExpr ::= PrefixExpr
- | InfixExpr id InfixExpr
+ | InfixExpr id PrefixExpr
PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
SimpleExpr ::= Literal
| Path
@@ -4245,10 +4246,9 @@ grammar.
| BlockExpr
| new Template
| SimpleExpr `.' id
- | id `#' id
| SimpleExpr TypeArgs
- | SimpleExpr ArgumentExpr
- ArgumentExpr ::= `(' Expr ')'
+ | SimpleExpr ArgumentExprs
+ ArgumentExprs ::= `(' [Exprs] ')'
| BlockExpr
BlockExpr ::= `{' CaseClause {CaseClause} `}'
| `{' Block `}'
@@ -4344,8 +4344,8 @@ grammar.
ClassTemplate ::= extends Template
| TemplateBody
|
- ConstrExpr ::= this ArgumentExpr
- | `{' this ArgumentExpr {`;' BlockStat} `}'
+ ConstrExpr ::= this ArgumentExprs
+ | `{' this ArgumentExprs {`;' BlockStat} `}'
CompilationUnit ::= [package QualId `;'] {TopStat `;'} TopStat
TopStat ::= {Modifier} ClsDef
@@ -5033,3 +5033,13 @@ package scala.List[a extends Comparable[a]] with Comparable[List[a]] with {
}
+
+}
+\end{lstlisting}
+}
+
+
+nd{lstlisting}
+}
+
+
diff --git a/sources/scala/Symbol.scala b/sources/scala/Symbol.scala
index dbb5ddac4a..ad98a0eff0 100644
--- a/sources/scala/Symbol.scala
+++ b/sources/scala/Symbol.scala
@@ -22,32 +22,9 @@ import scala.collection.immutable.ListMap ;
* @author Martin Odersky
* @version 1.0, 08/08/2003
*/
-case class Symbol(name: String) {
-
- var map : ListMap[String,String] = ListMap.Empty;
+case class Symbol(name: String, elems: Any*) {
override def toString() = "'" + name;
- /* WAITING FOR SCALADOC BUG TO BE FIXED
- def % (ch:Node*) = new Element(this, List.fromIterator(ch.elements)) {
- override def attributes = map;
- };
- */
-
- def % (a:Attribute) = {
- map = map.update(a.name, a.value);
- this
- }
- def -> (value:String) = new Attribute( name, value );
-
- def apply( ch:Node* ) = new Element(this, List.fromIterator(ch.elements)) {
- override def attributes = map;
- };
-
- class Attribute( n:String, v:String ) {
- final val name = n;
- final val value = v;
- };
-
}
diff --git a/sources/scala/concurrent/pilib.scala b/sources/scala/concurrent/pilib.scala
index 546c105741..1ebd88a5ac 100644
--- a/sources/scala/concurrent/pilib.scala
+++ b/sources/scala/concurrent/pilib.scala
@@ -141,7 +141,7 @@ object pilib with Monitor {
*/
private def compare(s1: Sum, ss: List[Sum]): List[Sum] =
ss match {
- case Nil => ss ::: (s1 :: Nil)
+ case Nil => ss ::: Predef.List(s1)
case s2 :: rest => matches(s1.gs, s2.gs) match {
case None => s2 :: compare(s1, rest)
case Some(Triple(log, c1, c2)) => {
diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala
index adca0088a1..0c2452579b 100644
--- a/sources/scala/tools/scalac/ast/parser/Parser.scala
+++ b/sources/scala/tools/scalac/ast/parser/Parser.scala
@@ -576,7 +576,7 @@ class Parser(unit: Unit) {
make.Literal(s.pos, new Float(s.floatVal.asInstanceOf[float]))
case DOUBLELIT =>
make.Literal(s.pos, new Double(s.floatVal))
- case STRINGLIT =>
+ case STRINGLIT | SYMBOLLIT =>
make.Literal(s.pos, s.name.toString())
case TRUE =>
make.Literal(s.pos, java.lang.Boolean.TRUE)
@@ -584,11 +584,6 @@ class Parser(unit: Unit) {
make.Literal(s.pos, java.lang.Boolean.FALSE)
case NULL =>
make.Ident(s.pos, Names.null_)
- case SYMBOLLIT =>
- var symt = scalaDot(s.pos, Names.Symbol);
- if (isPattern) symt = convertToTypeId(symt);
- make.Apply(
- s.pos, symt, NewArray.Tree(make.Literal(s.pos, s.name.toString())));
case _ =>
syntaxError("illegal literal", true)
}
@@ -596,15 +591,18 @@ class Parser(unit: Unit) {
val isSymLit = s.token == SYMBOLLIT;
val t = litToTree();
s.nextToken();
- if (isSymLit && (s.token == LPAREN || s.token == LBRACE)) {
- var labt = scalaDot(s.pos, Names.Labelled);
- if (isPattern) labt = convertToTypeId(labt);
- val listt = if (isPattern) scalaDot(s.pos, Names.List.toTypeName())
- else make.Select(s.pos, scalaDot(s.pos, Names.Predef), Names.List);
- make.Apply(
- s.pos, labt, NewArray.Tree(t, make.Apply(s.pos, listt, argumentExprs())));
+ if (isSymLit) {
+ val pos = s.pos;
+ var symt = scalaDot(s.pos, Names.Symbol);
+ if (isPattern) symt = convertToTypeId(symt);
+ val ts = new myTreeList();
+ ts.append(t);
+ if (s.token == LPAREN || s.token == LBRACE)
+ ts.append(argumentExprs());
+ make.Apply(pos, symt, ts.toArray());
+ } else {
+ t
}
- t
}
//////// TYPES ///////////////////////////////////////////////////////////////
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index 00f7f1f029..b164d54100 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -885,9 +885,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
enterSym(params(i));
(params(i) : Tree) match {
case Tree$ValDef(mods, _, _, _) =>
- if ((mods & REPEATED) != 0 && params.length > 1)
+ if ((mods & REPEATED) != 0 && i != params.length - 1)
error(params(i).pos,
- "`*' parameter must be the only parameter of a `('...`)' section");
+ "`*' parameter must be the last parameter of a `('...`)' section");
case _ =>
}
i = i + 1
@@ -1767,7 +1767,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
}}
}
// desugarizing ident patterns
- if (params.length == 1 && (params(0).flags & REPEATED) != 0) {
+ if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) {
if ((mode & PATTERNmode) != 0) {
def desug_allIdentPatterns(trees: Array[Tree], currentOwner: Symbol): unit = {
var i = 0; while (i < trees.length) {
@@ -1787,7 +1787,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
}
desug_allIdentPatterns(args, context.owner);
} else {
- assert(args.length != 1 || !(args(0).isInstanceOf[Tree$Sequence]));
+ assert(args.length != params.length ||
+ !(args(params.length-1).isInstanceOf[Tree$Sequence]));
}
}
argtypes;
@@ -2450,7 +2451,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
alttp match {
case Type$MethodType(params, _) =>
if (params.length == args.length ||
- params.length == 1 && (params(0).flags & REPEATED) != 0) {
+ params.length > 0 &&
+ args.length > params.length - 1 &&
+ (params(params.length-1).flags & REPEATED) != 0) {
matching2 = matching1;
matching1 = i;
}
diff --git a/sources/scala/tools/scalac/typechecker/Infer.scala b/sources/scala/tools/scalac/typechecker/Infer.scala
index e1a9825f11..11214aec1e 100644
--- a/sources/scala/tools/scalac/typechecker/Infer.scala
+++ b/sources/scala/tools/scalac/typechecker/Infer.scala
@@ -206,20 +206,24 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) {
}
/** The formal parameter types corresponding to `params'.
- * If `params' is a repeated parameter, a list of `length' copies
- * of its type is returned.
+ * If `params' has a repeated last parameter, a list of
+ * (nargs - params.length + 1) copies of its type is returned.
*/
- def formalTypes(params: Array[Symbol], length: int): Array[Type] = {
- if (params.length == 1 && (params(0).flags & REPEATED) != 0) {
- val formals: Array[Type] = new Array[Type](length);
- val args: Array[Type] = params(0).getType().typeArgs();
+ def formalTypes(params: Array[Symbol], nargs: int): Array[Type] = {
+ if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) {
+ val args: Array[Type] = params(params.length-1).getType().typeArgs();
if (args.length == 1) {
- val ft: Type = args(0);
- // params(0) has type Seq[T], we need T here
- { var i = 0; while (i < length) {
+ val ft: Type = args(0); // last param has type Seq[T], we need T here
+ val formals: Array[Type] = new Array[Type](nargs);
+ var i = 0;
+ while (i < params.length-1) {
+ formals(i) = params(i).getType();
+ i = i + 1;
+ }
+ while (i < nargs) {
formals(i) = ft;
i = i + 1;
- }}
+ }
return formals;
}
}
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 9fa2e92dda..0f5a0b6a1f 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -642,22 +642,15 @@ public class Parser implements Tokens {
t = make.Ident(s.pos, Names.null_);
break;
case SYMBOLLIT:
+ int pos = s.pos;
Tree symt = scalaDot(s.pos, Names.Symbol);
if (isPattern) symt = convertToTypeId(symt);
- t = make.Apply(s.pos,
- symt,
- new Tree[]{make.Literal(s.pos, s.name.toString())});
- s.nextToken();
- if (s.token == LPAREN || s.token == LBRACE) {
- Tree labt = scalaXmlNoBindingDot(s.pos, Names.Element);
- if (isPattern) labt = convertToTypeId(labt);
- Tree listt = isPattern ? scalaDot(s.pos, Names.List.toTypeName())
- : make.Select(s.pos, scalaDot(s.pos, Names.Predef), Names.List);
- t = make.Apply(s.pos,
- labt,
- new Tree[]{t, make.Apply(s.pos, listt, argumentExprs())});
- }
- return t;
+ TreeList ts = new TreeList();
+ ts.append(make.Literal(s.pos, s.name.toString()));
+ s.nextToken();
+ if (s.token == LPAREN || s.token == LBRACE)
+ ts.append(argumentExprs());
+ return make.Apply(pos, symt, ts.toArray());
default:
return syntaxError("illegal literal", true);
}
@@ -2087,4 +2080,3 @@ public class Parser implements Tokens {
}
}
}
-
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index e7b7fd98f5..8b858cbb96 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -821,6 +821,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* inherited members of this type; return Symbol.NONE if not found.
*/
public Symbol lookupNonPrivate(Name name) {
+ return lookupNonPrivate(name, 0);
+ }
+
+ /** Same as before, but with additional parameter `start'.
+ * If start == 0, lookup in all basetypes of a compound type.
+ * If start == 1, lookup only in mixin classes.
+ */
+ private Symbol lookupNonPrivate(Name name, int start) {
switch (this) {
case ErrorType:
return Symbol.ERROR;
@@ -829,26 +837,25 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case ConstantType(_, _):
return singleDeref().lookupNonPrivate(name);
case TypeRef(_, Symbol sym, _):
- return sym.info().lookupNonPrivate(name);
+ return sym.info().lookupNonPrivate(name, start);
case CompoundType(Type[] parts, Scope members):
Symbol sym = members.lookup(name);
if (sym.kind != NONE && (sym.flags & PRIVATE) == 0)
return sym;
- // search base types in closure; non-abstract members
- // take precedence over abstract ones.
- Type[] cls = closure();
- int i = 1;
- while (i < cls.length &&
- (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
- Symbol sym1 = cls[i].members().lookup(name);
- if (sym1.kind != NONE &&
- (sym1.flags & PRIVATE) == 0 &&
- (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
- sym = sym1;
- i++;
- }
- return sym;
+ // search base types in reverse; non-abstract members
+ // take precedence over abstract ones.
+ int i = parts.length;
+ sym = Symbol.NONE;
+ while (i > start && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
+ i--;
+ Symbol sym1 = parts[i].lookupNonPrivate(name, i == 0 ? 0 : 1);
+ if (sym1.kind != NONE &&
+ (sym1.flags & PRIVATE) == 0 &&
+ (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
+ sym = sym1;
+ }
+ return sym;
default:
return Symbol.NONE;
}
diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java
index 2293e5e8f2..1f17e47a49 100644
--- a/sources/scalac/transformer/UnCurry.java
+++ b/sources/scalac/transformer/UnCurry.java
@@ -213,7 +213,8 @@ public class UnCurry extends OwnerTransformer
switch (methtype) {
case MethodType(Symbol[] params, _):
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ if (params.length > 0 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
args = toSequence(pos, params, args);
}
Tree[] args1 = args;
@@ -240,16 +241,27 @@ public class UnCurry extends OwnerTransformer
* escaping
*/
private Tree[] toSequence(int pos, Symbol[] params, Tree[] args) {
- assert (args.length != 1
- || !(args[0] instanceof Tree.Sequence)
- || TreeInfo.isSequenceValued( args[0]));
- if (args.length == 1) {
- switch (args[0]) {
+ Tree[] result = new Tree[params.length];
+ for (int i = 0; i < params.length - 1; i++)
+ result[i] = args[i];
+ assert (args.length != params.length
+ || !(args[params.length-1] instanceof Tree.Sequence)
+ || TreeInfo.isSequenceValued(args[params.length-1]));
+ if (args.length == params.length) {
+ switch (args[params.length-1]) {
case Typed(Tree arg, Ident(TypeNames.WILDCARD_STAR)):
- return new Tree[]{arg};
+ result[params.length-1] = arg;
+ return result;
}
}
- return new Tree[]{make.Sequence( pos, args ).setType(params[0].type())};
+ Tree[] args1 = args;
+ if (params.length != 1) {
+ args1 = new Tree[args.length - (params.length - 1)];
+ System.arraycopy(args, params.length - 1, args1, 0, args1.length);
+ }
+ result[params.length-1] =
+ make.Sequence(pos, args1).setType(params[params.length-1].type());
+ return result;
}
/** for every argument to a def parameter `def x: T':
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java
index 4708dd6258..7c564882b3 100644
--- a/sources/scalac/transformer/matching/AlgebraicMatcher.java
+++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java
@@ -110,8 +110,8 @@ public class AlgebraicMatcher extends PatternMatcher {
//System.err.println( tree.fun.type.resultType().symbol() );
return (tree.args.length == 1)
&& (tree.type.symbol().flags & Modifiers.CASE) != 0
- && params.length == 1
- && (params[ 0 ].flags & Modifiers.REPEATED) != 0;
+ && params.length > 0
+ && (params[params.length-1].flags & Modifiers.REPEATED) != 0;
}
//////////// generator methods
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index b11f3ac85a..3457499228 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -917,9 +917,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
enterSym(params[i]);
switch (params[i]) {
case ValDef(int mods, _, _, _):
- if ((mods & REPEATED) != 0 && params.length > 1)
+ if ((mods & REPEATED) != 0 && i != params.length - 1)
error(params[i].pos,
- "`*' parameter must be the only parameter of a `('...`)' section");
+ "`*' parameter must be the last parameter of a `('...`)' section");
}
}
return Tree.symbolOf(params);
@@ -1782,11 +1782,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
// desugarizing ident patterns
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ if (params.length > 0 &&
+ (params[params.length - 1].flags & REPEATED) != 0) {
if (( mode & PATTERNmode ) != 0 ) {
desug_allIdentPatterns( args, context.owner );
} else {
- assert (args.length != 1 || !(args[0] instanceof Tree.Sequence));
+ assert (args.length != params.length ||
+ !(args[params.length-1] instanceof Tree.Sequence));
}
}
return argtypes;
@@ -2392,7 +2394,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
switch (alttp) {
case MethodType(Symbol[] params, _):
if (params.length == args.length ||
- params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ params.length > 0 &&
+ args.length >= params.length - 1 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
matching2 = matching1;
matching1 = i;
}
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index ea6cb4ddc4..b2b38ef2da 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -333,15 +333,24 @@ public class Infer implements Modifiers, Kinds {
* If `params' is a repeated parameter, a list of `length' copies
* of its type is returned.
*/
- public Type[] formalTypes(Symbol[] params, int length) {
+ public Type[] formalTypes(Symbol[] params, int nargs) {
Type[] result;
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
- Type[] formals = new Type[length];
- Type[] args = params[0].type().typeArgs();
+ if (params.length > 0 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
+ Type[] args = params[params.length-1].type().typeArgs();
if (args.length == 1) {
Type ft = args[0];
- // params[0] has type Seq[T], we need T here
- for (int i = 0; i < length; i++) formals[i] = ft;
+ // last param has type Seq[T], we need T here
+ Type[] formals = new Type[nargs];
+ int i = 0;
+ while (i < params.length-1) {
+ formals[i] = params[i].type();
+ i++;
+ }
+ while (i < nargs) {
+ formals[i] = ft;
+ i++;
+ }
return formals;
}
}
diff --git a/test/files/neg/bug38.check b/test/files/neg/bug38.check
index 8f053cfaa8..6c1b463d68 100644
--- a/test/files/neg/bug38.check
+++ b/test/files/neg/bug38.check
@@ -1,7 +1,4 @@
-bug38.scala:3: * is not a member of scala.xml
- import scala.xml.* ; // does not work
- ^
-bug38.scala:7: not found: type Element
- val foo = new Element { def getName = "hallo"; def getChildren = Nil; def getAttribs = new HashMap[String,String] };
- ^
-two errors found
+bug236.scala:4: constructor A of type ()A cannot be applied to (scala.Int)
+ class B extends A(1) {
+ ^
+one error found
diff --git a/test/neg/bug38.check b/test/neg/bug38.check
index 8f053cfaa8..6c1b463d68 100644
--- a/test/neg/bug38.check
+++ b/test/neg/bug38.check
@@ -1,7 +1,4 @@
-bug38.scala:3: * is not a member of scala.xml
- import scala.xml.* ; // does not work
- ^
-bug38.scala:7: not found: type Element
- val foo = new Element { def getName = "hallo"; def getChildren = Nil; def getAttribs = new HashMap[String,String] };
- ^
-two errors found
+bug236.scala:4: constructor A of type ()A cannot be applied to (scala.Int)
+ class B extends A(1) {
+ ^
+one error found