summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-03-15 09:28:07 -0700
committerPaul Phillips <paulp@improving.org>2012-03-15 19:59:46 -0700
commitacb2c851720141982514b11b4b34ba68dc868bf2 (patch)
treec6aa85586f6f673e5975266314cc613a7d36ed05 /src/compiler/scala/tools/nsc/typechecker
parent2dd0af0675ea0c4d696a46bf36d7bd9406a64cd0 (diff)
downloadscala-acb2c851720141982514b11b4b34ba68dc868bf2.tar.gz
scala-acb2c851720141982514b11b4b34ba68dc868bf2.tar.bz2
scala-acb2c851720141982514b11b4b34ba68dc868bf2.zip
New option -Ypos-debug, and fixed range position breakage.
(Looks like there is more range position breakage yet, but this gets the outermost layer.) Channeling my struggles into a slightly easier future. % scalac -Ypos-debug -d /tmp ./src/library/scala/Predef.scala ./src/library/scala/Predef.scala:222: warning: Positioned tree has unpositioned child in phase extmethods def x = __resultOfEnsuring ^ parent: #7109 line 222 Select // (value __resultOfEnsuring in class Ensuring) child: #7108 Ident // (value $this) ./src/library/scala/Predef.scala:258: warning: Positioned tree has unpositioned child in phase extmethods def x = __leftOfArrow ^ parent: #7280 line 258 Select // (value __leftOfArrow in class ArrowAssoc) child: #7279 Ident // (value $this) two warnings found Or try this to really see some output: % scalac -Yrangepos -Ypos-debug
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala26
5 files changed, 34 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 088a56cd7b..f32ad9293c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -69,6 +69,9 @@ trait MethodSynthesis {
import synthesisUtil._
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
+ def mkThis = This(clazz) setPos clazz.pos.focus
+ def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(Select(mkThis, sym))
+
private def isOverride(name: TermName) =
clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 955d51bf8d..c5fb13a5a9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -456,7 +456,7 @@ trait Namers extends MethodSynthesis {
// The object Foo is still in scope, but because it is not compiled in current run
// it should be ditched and a new one created.
if (m != NoSymbol && currentRun.compiles(m)) m
- else enterSyntheticSym(creator(cdef))
+ else enterSyntheticSym(atPos(cdef.pos.focus)(creator(cdef)))
}
private def checkSelectors(tree: Import): Unit = {
@@ -1270,11 +1270,12 @@ trait Namers extends MethodSynthesis {
if (sym.isModule) annotate(sym.moduleClass)
def getSig = tree match {
- case cdef @ ClassDef(_, _, tparams, impl) =>
+ case cdef @ ClassDef(_, name, tparams, impl) =>
val clazz = tree.symbol
val result = createNamer(tree).classSig(tparams, impl)
clazz setInfo result
if (clazz.isDerivedValueClass) {
+ log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show)
clazz setFlag FINAL
enclosingNamerWithScope(clazz.owner.info.decls).ensureCompanionObject(cdef)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 1e17cb2e3f..ec42d251ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1523,16 +1523,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case _ => ()
}
- // verify classes extending AnyVal meet the requirements
- // (whatever those are to be, but at least: @inline annotation)
+ // Verify classes extending AnyVal meet the requirements
private def checkAnyValSubclass(clazz: Symbol) = {
- if ((clazz isSubClass AnyValClass) && (clazz ne AnyValClass) && !isPrimitiveValueClass(clazz)) {
+ if ((clazz isSubClass AnyValClass) && !isPrimitiveValueClass(clazz)) {
if (clazz.isTrait)
unit.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal")
- /* [Martin] That one is already taken care of by Typers
- if (clazz.tpe <:< AnyRefClass.tpe)
- unit.error(clazz.pos, "Classes which extend AnyVal may not have an ancestor which inherits AnyRef")
- */
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index f9d41bcc5e..2f4eff30d2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -51,11 +51,9 @@ trait SyntheticMethods extends ast.TreeDSL {
if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return {
if (clazz0.info member nme.getClass_ isDeferred) {
- val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe)) { sym =>
- // XXX dummy implementation for now
- NULL
- }
- treeCopy.Template(templ, templ.parents, templ.self, templ.body :+ getClassMethod)
+ // XXX dummy implementation for now
+ val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe))(_ => NULL)
+ deriveTemplate(templ)(_ :+ getClassMethod)
}
else templ
}
@@ -89,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(This(clazz) :: _)
+ forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(mkThis :: _)
// Any member, including private
def hasConcreteImpl(name: Name) =
@@ -109,7 +107,7 @@ trait SyntheticMethods extends ast.TreeDSL {
}
def productIteratorMethod = {
createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ =>
- gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(This(clazz)))
+ gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(mkThis))
)
}
def projectionMethod(accessor: Symbol, num: Int) = {
@@ -157,8 +155,8 @@ trait SyntheticMethods extends ast.TreeDSL {
def equalsCore(eqmeth: Symbol, accessors: List[Symbol]) = {
val otherName = context.unit.freshTermName(clazz.name + "$")
val otherSym = eqmeth.newValue(otherName, eqmeth.pos, SYNTHETIC) setInfo clazz.tpe
- val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
- val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz)))
+ val pairwise = accessors map (acc => fn(Select(mkThis, acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
+ val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(mkThis))
val tests = if (clazz.isDerivedValueClass || clazz.isFinal && syntheticCanEqual) pairwise else pairwise :+ canEq
thatTest(eqmeth) AND Block(
@@ -181,9 +179,9 @@ trait SyntheticMethods extends ast.TreeDSL {
def equalsCaseClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
if (accessors.isEmpty)
if (clazz.isFinal) thatTest(m)
- else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(This(clazz)))
+ else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(mkThis))
else
- (This(clazz) ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors)
+ (mkThis ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors)
}
/** The equality method for value classes
@@ -200,9 +198,7 @@ trait SyntheticMethods extends ast.TreeDSL {
* def hashCode(): Int = this.underlying.hashCode
*/
def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntClass.tpe) { m =>
- Select(
- Select(This(clazz), clazz.firstParamAccessor),
- nme.hashCode_)
+ Select(mkThisSelect(clazz.firstParamAccessor), nme.hashCode_)
}
/** The _1, _2, etc. methods to implement ProductN.
@@ -217,7 +213,7 @@ trait SyntheticMethods extends ast.TreeDSL {
List(
Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)),
Product_productArity -> (() => constantNullary(nme.productArity, arity)),
- Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(Select(This(clazz), _))),
+ Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(mkThisSelect)),
Product_iterator -> (() => productIteratorMethod),
Product_canEqual -> (() => canEqualMethod)
// This is disabled pending a reimplementation which doesn't add any
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9a2ef88821..973e26af41 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1295,7 +1295,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def parentTypes(templ: Template): List[Tree] =
- if (templ.parents.isEmpty) List(TypeTree(AnyRefClass.tpe))
+ if (templ.parents.isEmpty) List(atPos(templ.pos.focus)(TypeTree(AnyRefClass.tpe)))
else try {
val clazz = context.owner
// Normalize supertype and mixins so that supertype is always a class, not a trait.
@@ -1723,7 +1723,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* @param rhs ...
*/
def computeParamAliases(clazz: Symbol, vparamss: List[List[ValDef]], rhs: Tree) {
- debuglog("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
+ log("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
def decompose(call: Tree): (Tree, List[Tree]) = call match {
case Apply(fn, args) =>
val (superConstr, args1) = decompose(fn)
@@ -1902,11 +1902,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
- if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) {
- // At this point in AnyVal there is no supercall, which will blow up
- // in computeParamAliases; there's nothing to be computed for Anyval anyway.
- computeParamAliases(meth.owner, vparamss1, rhs1)
- }
+ if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) {
+ // At this point in AnyVal there is no supercall, which will blow up
+ // in computeParamAliases; there's nothing to be computed for Anyval anyway.
+ computeParamAliases(meth.owner, vparamss1, rhs1)
+ }
+
if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass)
rhs1 = checkDead(rhs1)
@@ -1925,6 +1926,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (meth.isStructuralRefinementMember)
checkMethodStructuralCompatible(meth)
+
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -3264,6 +3266,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedAnnotated(ann: Tree, arg1: Tree): Tree = {
+ def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus
/** mode for typing the annotation itself */
val annotMode = mode & ~TYPEmode | EXPRmode
@@ -3309,19 +3312,20 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
arg1 // simply drop erroneous annotations
else {
ann.tpe = atype
- TypeTree(atype) setOriginal tree
+ mkTypeTree(atype)
}
} else {
// the annotation was typechecked before
- TypeTree(ann.tpe) setOriginal tree
+ mkTypeTree(ann.tpe)
}
- } else {
+ }
+ else {
if (ann.tpe == null) {
val annotInfo = typedAnnotation(ann, annotMode)
ann.tpe = arg1.tpe.withAnnotation(annotInfo)
}
val atype = ann.tpe
- Typed(arg1, TypeTree(atype) setOriginal tree setPos tree.pos.focus) setPos tree.pos setType atype
+ Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype
}
}