summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-08-18 17:24:36 +0000
committerMartin Odersky <odersky@gmail.com>2009-08-18 17:24:36 +0000
commitec18f148e8afc4101878cd8b05eadac92d26b64c (patch)
tree7602e12f0a5cab24fea2f73d91a794fbde52bf5b /src/compiler
parent6b5b635f095e29b37fa30487c5a1cf5804107795 (diff)
downloadscala-ec18f148e8afc4101878cd8b05eadac92d26b64c.tar.gz
scala-ec18f148e8afc4101878cd8b05eadac92d26b64c.tar.bz2
scala-ec18f148e8afc4101878cd8b05eadac92d26b64c.zip
Fixed memory leaks for streams.
Diffstat (limited to 'src/compiler')
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/Parsers.scala73
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala33
4 files changed, 78 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index bb0fa89b29..34338eaf03 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -166,8 +166,9 @@ self =>
}
import treeBuilder.{global => _, _}
- /** The implicit view parameters of the surrounding class */
- var implicitClassViews: List[Tree] = Nil
+ /** The types of the context bounds of type parameters of the surrounding class
+ */
+ var classContextBounds: List[Tree] = Nil
/** this is the general parse method
*/
@@ -1661,7 +1662,7 @@ self =>
* ClassParams ::= ClassParam {`,' ClassParam}
* ClassParam ::= {Annotation} [{Modifier} (`val' | `var')] Id [`:' ParamType] [`=' Expr]
*/
- def paramClauses(owner: Name, implicitViews: List[Tree], ofCaseClass: Boolean): List[List[ValDef]] = {
+ def paramClauses(owner: Name, contextBounds: List[Tree], ofCaseClass: Boolean): List[List[ValDef]] = {
var implicitmod = 0
var caseParam = ofCaseClass
def param(): ValDef = {
@@ -1715,8 +1716,8 @@ self =>
val params = new ListBuffer[ValDef]
if (in.token != RPAREN) {
if (in.token == IMPLICIT) {
- if (!implicitViews.isEmpty)
- syntaxError("cannot have both view bounds `<%' and implicit parameters", false)
+ if (!contextBounds.isEmpty)
+ syntaxError("cannot have both implicit parameters and context bounds `: ...' on type parameters", false)
in.nextToken()
implicitmod = Flags.IMPLICIT
}
@@ -1750,18 +1751,18 @@ self =>
incompleteInputError("auxiliary constructor needs non-implicit parameter list")
else
syntaxError(start, "auxiliary constructor needs non-implicit parameter list", false)
- addImplicitViews(owner, result, implicitViews)
+ addEvidenceParams(owner, result, contextBounds)
}
/** ParamType ::= Type | `=>' Type | Type `*'
*/
def paramType(): Tree =
- if (in.token == ARROW)
+ if (in.token == ARROW) {
atPos(in.skipToken()) {
AppliedTypeTree(
rootScalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName), List(typ()))
}
- else {
+ } else {
val t = typ()
if (isIdent && in.name == STAR) {
in.nextToken()
@@ -1777,9 +1778,9 @@ self =>
* VariantTypeParam ::= {Annotation} [`+' | `-'] TypeParam
* FunTypeParamClauseOpt ::= [FunTypeParamClause]
* FunTypeParamClause ::= `[' TypeParam {`,' TypeParam} `]']
- * TypeParam ::= Id TypeParamClauseOpt TypeBounds [<% Type]
+ * TypeParam ::= Id TypeParamClauseOpt TypeBounds {<% Type} {":" Type}
*/
- def typeParamClauseOpt(owner: Name, implicitViewBuf: ListBuffer[Tree]): List[TypeDef] = {
+ def typeParamClauseOpt(owner: Name, contextBoundBuf: ListBuffer[Tree]): List[TypeDef] = {
def typeParam(ms: Modifiers): TypeDef = {
var mods = ms | Flags.PARAM
val start = in.offset
@@ -1799,16 +1800,21 @@ self =>
nme.WILDCARD
} else ident()).toTypeName
val param = atPos(start, nameOffset) {
- val tparams = typeParamClauseOpt(pname, null) // @M TODO null --> no higher-order view bounds for now
+ val tparams = typeParamClauseOpt(pname, null) // @M TODO null --> no higher-order context bounds for now
TypeDef(mods, pname, tparams, typeBounds())
}
- if (in.token == VIEWBOUND && (implicitViewBuf ne null))
- implicitViewBuf += atPos(start, in.skipToken()) {
- val t = typ()
- atPos(t.pos) {
- makeFunctionTypeTree(List(Ident(pname)), t)
+ if (contextBoundBuf ne null) {
+ while (in.token == VIEWBOUND) {
+ contextBoundBuf += atPos(in.skipToken()) {
+ makeFunctionTypeTree(List(Ident(pname)), typ())
}
}
+ while (in.token == COLON) {
+ contextBoundBuf += atPos(in.skipToken()) {
+ AppliedTypeTree(typ(), List(Ident(pname)))
+ }
+ }
+ }
param
}
val params = new ListBuffer[TypeDef]
@@ -2050,7 +2056,7 @@ self =>
val start = in.skipToken()
if (in.token == THIS) {
atPos(start, in.skipToken()) {
- val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.duplicate), false)
+ val vparamss = paramClauses(nme.CONSTRUCTOR, classContextBounds map (_.duplicate), false)
newLineOptWhenFollowedBy(LBRACE)
val rhs = if (in.token == LBRACE) {
atPos(in.offset) { constrBlock(vparamss) }
@@ -2065,11 +2071,12 @@ self =>
val nameOffset = in.offset
val name = ident()
atPos(start, if (name == nme.ERROR) start else nameOffset) {
- // implicitViewBuf is for view bounded type parameters of the form
- // [T <% B]; it contains the equivalent implicit parameter, i.e. (implicit p: T => B)
- val implicitViewBuf = new ListBuffer[Tree]
- val tparams = typeParamClauseOpt(name, implicitViewBuf)
- val vparamss = paramClauses(name, implicitViewBuf.toList, false)
+ // contextBoundBuf is for context bounded type parameters of the form
+ // [T : B] or [T : => B]; it contains the equivalent implicit parameter type,
+ // i.e. (B[T] or T => B)
+ val contextBoundBuf = new ListBuffer[Tree]
+ val tparams = typeParamClauseOpt(name, contextBoundBuf)
+ val vparamss = paramClauses(name, contextBoundBuf.toList, false)
newLineOptWhenFollowedBy(LBRACE)
var restype = typedOpt()
val rhs =
@@ -2105,7 +2112,7 @@ self =>
t = Apply(t, argumentExprs())
newLineOptWhenFollowedBy(LBRACE)
}
- if (implicitClassViews.isEmpty) t
+ if (classContextBounds.isEmpty) t
else Apply(t, vparamss.last.map(vp => Ident(vp.name)))
}
@@ -2183,19 +2190,19 @@ self =>
val nameOffset = in.offset
val name = ident().toTypeName
atPos(start, if (name == nme.ERROR.toTypeName) start else nameOffset) {
- val savedViews = implicitClassViews
- val implicitViewBuf = new ListBuffer[Tree]
- val tparams = typeParamClauseOpt(name, implicitViewBuf)
- implicitClassViews = implicitViewBuf.toList
- val tstart = (in.offset::implicitClassViews.map(_.pos.startOrPoint)).min
- if (!implicitClassViews.isEmpty && mods.hasFlag(Flags.TRAIT)) {
- syntaxError("traits cannot have type parameters with <% bounds", false)
- implicitClassViews = List()
+ val savedContextBounds = classContextBounds
+ val contextBoundBuf = new ListBuffer[Tree]
+ val tparams = typeParamClauseOpt(name, contextBoundBuf)
+ classContextBounds = contextBoundBuf.toList
+ val tstart = (in.offset::classContextBounds.map(_.pos.startOrPoint)).min
+ if (!classContextBounds.isEmpty && mods.hasFlag(Flags.TRAIT)) {
+ syntaxError("traits cannot have type parameters with context bounds `: ...'", false)
+ classContextBounds = List()
}
val constrAnnots = annotations(false, true)
val (constrMods, vparamss) =
if (mods.hasFlag(Flags.TRAIT)) (Modifiers(Flags.TRAIT), List())
- else (accessModifierOpt(), paramClauses(name, implicitClassViews, mods.hasFlag(Flags.CASE)))
+ else (accessModifierOpt(), paramClauses(name, classContextBounds, mods.hasFlag(Flags.CASE)))
var mods1 = mods
if (mods hasFlag Flags.TRAIT) {
if (settings.Xexperimental.value && in.token == SUBTYPE) mods1 |= Flags.DEFERRED
@@ -2205,7 +2212,7 @@ self =>
val template = templateOpt(mods1, name, constrMods withAnnotations constrAnnots, vparamss, tstart)
if (isInterface(mods1, template.body)) mods1 |= Flags.INTERFACE
val result = ClassDef(mods1, name, tparams, template)
- implicitClassViews = savedViews
+ classContextBounds = savedContextBounds
result
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index a8ecf9aab3..aa057c43b5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -507,12 +507,13 @@ abstract class TreeBuilder {
def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =
AppliedTypeTree(rootScalaDot(newTypeName("Function" + argtpes.length)), argtpes ::: List(restpe))
- /** Append implicit view section if for `implicitViews' if nonempty */
- def addImplicitViews(owner: Name, vparamss: List[List[ValDef]], implicitViews: List[Tree]): List[List[ValDef]] = {
- val mods = Modifiers(if (owner.isTypeName) PARAMACCESSOR | LOCAL | PRIVATE else PARAM)
- def makeViewParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName("view$"), tpt, EmptyTree)
- if (implicitViews.isEmpty) vparamss
- else vparamss ::: List(implicitViews map makeViewParam)
+ /** Append implicit parameter section if `contextBounds' nonempty */
+ def addEvidenceParams(owner: Name, vparamss: List[List[ValDef]], contextBounds: List[Tree]): List[List[ValDef]] =
+ if (contextBounds.isEmpty) vparamss
+ else {
+ val mods = Modifiers(if (owner.isTypeName) PARAMACCESSOR | LOCAL | PRIVATE else PARAM)
+ def makeEvidenceParam(tpt: Tree) = ValDef(mods | IMPLICIT, freshName("man$"), tpt, EmptyTree)
+ vparamss ::: List(contextBounds map makeEvidenceParam)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 9295ba261d..1fe8220dc2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -130,7 +130,7 @@ self: Analyzer =>
class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context)
extends Typer(context0) {
- assert(tree.isEmpty || tree.pos.isDefined)
+ assert(tree.isEmpty || tree.pos.isDefined, tree)
import infer._
@@ -599,7 +599,7 @@ self: Analyzer =>
def manifestFactoryCall(constructor: String, args: Tree*): Tree =
if (args contains EmptyTree) EmptyTree
else
- typed(atPos(tree.pos.focus) {
+ typed { atPos(tree.pos.focus) {
Apply(
TypeApply(
Select(gen.mkAttributedRef(ManifestModule), constructor),
@@ -607,7 +607,7 @@ self: Analyzer =>
),
args.toList
)
- })
+ }}
/** Re-wraps a type in a manifest before calling inferImplicit on the result */
def findManifest(tp: Type): Tree =
@@ -619,7 +619,12 @@ self: Analyzer =>
case ConstantType(value) =>
findManifest(tp.deconst)
case TypeRef(pre, sym, args) =>
- if (sym.isClass) {
+ if (isValueClass(sym)) {
+ typed { atPos(tree.pos.focus) {
+ Select(gen.mkAttributedRef(ManifestModule), sym.name.toString)
+ }}
+ }
+ else if (sym.isClass) {
val suffix = gen.mkClassOf(tp) :: (args map findManifest)
manifestFactoryCall(
"classType",
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 94d3aae091..745d1c8241 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -301,7 +301,7 @@ trait Typers { self: Analyzer =>
case t => t
}
"\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile."
- } else ""))
+ } else ""))
/** Would tree be a stable (i.e. a pure expression) if the type
* of its symbol was not volatile?
@@ -1265,7 +1265,11 @@ trait Typers { self: Analyzer =>
r
} else {
val rhs = gen.mkCheckInit(Select(This(value.owner), value))
- val r = DefDef(getter, typed(rhs, EXPRmode, value.tpe))
+ val r = typed {
+ atPos(getter.pos.focus) {
+ DefDef(getter, rhs)
+ }
+ }.asInstanceOf[DefDef]
r.tpt.setPos(tpt.pos.focus)
r
}
@@ -1273,15 +1277,22 @@ trait Typers { self: Analyzer =>
checkNoEscaping.privates(getter, getterDef.tpt)
def setterDef(setter: Symbol): DefDef = {
setter.setAnnotations(value.annotations)
- val result = atPos(vdef.pos.focus)(
- DefDef(setter,
- if ((mods hasFlag DEFERRED) || (setter hasFlag OVERLOADED))
- EmptyTree
- else
- typed(Assign(Select(This(value.owner), value),
- Ident(setter.paramss.head.head)))))
- treeCopy.DefDef(result, result.mods, result.name, result.tparams,
- result.vparamss, result.tpt, result.rhs)
+ val result = typed {
+ atPos(vdef.pos.focus) {
+ DefDef(
+ setter,
+ if ((mods hasFlag DEFERRED) || (setter hasFlag OVERLOADED))
+ EmptyTree
+ else
+ Assign(Select(This(value.owner), value),
+ Ident(setter.paramss.head.head)))
+ }
+ }
+ result.asInstanceOf[DefDef]
+ // Martin: was
+ // treeCopy.DefDef(result, result.mods, result.name, result.tparams,
+ // result.vparamss, result.tpt, result.rhs)
+ // but that's redundant, no?
}
val gs = new ListBuffer[DefDef]