Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
magarciaEPFL committed Feb 12, 2012
1 parent a9d30bf commit 4e1b169
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/reflect/internal/Trees.scala
Expand Up @@ -189,7 +189,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
DefDef(Modifiers(sym.flags),
DefDef(mods,
sym.name.toTermName,
sym.typeParams map TypeDef,
vparamss,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
Expand Up @@ -62,7 +62,7 @@ trait ExprTyper {
else Some(trees)
}
}
def tokens(line: String) = beSilentDuring(codeParser.tokens(line))
def tokens(line: String) = beQuietDuring(codeParser.tokens(line))

// TODO: integrate these into a CodeHandler[Type].

Expand Down
8 changes: 2 additions & 6 deletions src/compiler/scala/tools/nsc/interpreter/IMain.scala
Expand Up @@ -906,11 +906,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
if (!handlers.last.definesValue) ""
else handlers.last.definesTerm match {
case Some(vname) if typeOf contains vname =>
"""
|lazy val %s = {
| %s
| %s
|}""".stripMargin.format(lineRep.resultName, lineRep.printName, fullPath(vname))
"lazy val %s = %s".format(lineRep.resultName, fullPath(vname))
case _ => ""
}
// first line evaluates object to make sure constructor is run
Expand Down Expand Up @@ -956,7 +952,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
typesOfDefinedTerms

// compile the result-extraction object
beSilentDuring {
beQuietDuring {
savingSettings(_.nowarn.value = true) {
lineRep compile ResultObjectSourceCode(handlers)
}
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala
Expand Up @@ -14,7 +14,10 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
// Avoiding deadlock if the compiler starts logging before
// the lazy val is complete.
if (intp.isInitializeComplete) {
if (intp.totalSilence) ()
if (intp.totalSilence) {
if (isReplTrace)
super.printMessage("[silent] " + msg)
}
else super.printMessage(msg)
}
else Console.println("[init] " + msg)
Expand Down
43 changes: 28 additions & 15 deletions src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
Expand Up @@ -326,22 +326,35 @@ trait MethodSynthesis {

super.validate()
}
// keep type tree of original abstract field
private def fixTypeTree(dd: DefDef): DefDef = {
dd.tpt match {
case tt: TypeTree if dd.rhs == EmptyTree =>
tt setOriginal tree.tpt
case tpt =>
tpt setPos tree.tpt.pos.focus
}
dd
}
override def derivedTree: DefDef = {
fixTypeTree {
DefDef(derivedSym,
if (mods.isDeferred) EmptyTree
else gen.mkCheckInit(fieldSelection)
)
// For existentials, don't specify a type for the getter, even one derived
// from the symbol! This leads to incompatible existentials for the field and
// the getter. Let the typer do all the work. You might think "why only for
// existentials, why not always," and you would be right, except: a single test
// fails, but it looked like some work to deal with it. Test neg/t0606.scala
// starts compiling (instead of failing like it's supposed to) because the typer
// expects to be able to identify escaping locals in typedDefDef, and fails to
// spot that brand of them. In other words it's an artifact of the implementation.
val tpt = derivedSym.tpe.finalResultType match {
case ExistentialType(_, _) => TypeTree()
case tp => TypeTree(tp)
}
tpt setPos focusPos(derivedSym.pos)
// keep type tree of original abstract field
if (mods.isDeferred)
tpt setOriginal tree.tpt

// TODO - reconcile this with the DefDef creator in Trees (which
// at this writing presented no way to pass a tree in for tpt.)
atPos(derivedSym.pos) {
DefDef(
Modifiers(derivedSym.flags),
derivedSym.name.toTermName,
Nil,
Nil,
tpt,
if (mods.isDeferred) EmptyTree else gen.mkCheckInit(fieldSelection)
) setSymbol derivedSym
}
}
}
Expand Down
32 changes: 30 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Expand Up @@ -2834,7 +2834,34 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {

def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type?
sym.isTypeParameter && sym.owner.isJavaDefined

/** If we map a set of hidden symbols to their existential bounds, we
* have a problem: the bounds may themselves contain references to the
* hidden symbols. So this recursively calls existentialBound until
* the typeSymbol is not amongst the symbols being hidden.
*/
def existentialBoundsExcludingHidden(hidden: List[Symbol]): Map[Symbol, Type] = {
def safeBound(t: Type): Type =
if (hidden contains t.typeSymbol) safeBound(t.typeSymbol.existentialBound.bounds.hi) else t

def hiBound(s: Symbol): Type = safeBound(s.existentialBound.bounds.hi) match {
case tp @ RefinedType(parents, decls) =>
val parents1 = parents mapConserve safeBound
if (parents eq parents1) tp
else copyRefinedType(tp, parents1, decls)
case tp => tp
}

(hidden map { s =>
// Hanging onto lower bound in case anything interesting
// happens with it.
(s, s.existentialBound match {
case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s))
case _ => hiBound(s)
})
}).toMap
}

/** Given a set `rawSyms` of term- and type-symbols, and a type
* `tp`, produce a set of fresh type parameters and a type so that
* it can be abstracted to an existential type. Every type symbol
Expand All @@ -2852,12 +2879,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* only the type of the Ident is changed.
*/
protected def existentialTransform[T](rawSyms: List[Symbol], tp: Type)(creator: (List[Symbol], Type) => T): T = {
val allBounds = existentialBoundsExcludingHidden(rawSyms)
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
case x => newTypeName(x + ".type")
case x => nme.singletonName(x)
}
val bound = sym.existentialBound
val bound = allBounds(sym)
val sowner = if (isRawParameter(sym)) context.owner else sym.owner
val quantified = sowner.newExistential(name, sym.pos)

Expand Down

0 comments on commit 4e1b169

Please sign in to comment.