summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-19 10:22:22 -0700
committerPaul Phillips <paulp@improving.org>2012-09-19 10:27:23 -0700
commitbeb08c206b24e00167a11ea13d1cd998b8e3b067 (patch)
tree1bde617daddd0206fd512904c3f15a02dd801b4b /src
parent8c69f4da333f17290da26c3951fa9c8805014e47 (diff)
downloadscala-beb08c206b24e00167a11ea13d1cd998b8e3b067.tar.gz
scala-beb08c206b24e00167a11ea13d1cd998b8e3b067.tar.bz2
scala-beb08c206b24e00167a11ea13d1cd998b8e3b067.zip
Error message improvement for SI-6336.
Position error messages about structural type members at the problematic parameter or type.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6ecd7911fd..ac02b67463 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1980,32 +1980,39 @@ trait Typers extends Modes with Adaptations with Tags {
* - an instance of a value class
* Furthermore, the result type may not be a value class either
*/
- def checkMethodStructuralCompatible(meth: Symbol): Unit = {
- def fail(msg: String) = unit.error(meth.pos, msg)
+ def checkMethodStructuralCompatible(ddef: DefDef): Unit = {
+ val meth = ddef.symbol
+ def fail(pos: Position, msg: String) = unit.error(pos, msg)
val tp: Type = meth.tpe match {
case mt @ MethodType(_, _) => mt
case NullaryMethodType(restpe) => restpe // TODO_NMT: drop NullaryMethodType from resultType?
case PolyType(_, restpe) => restpe
case _ => NoType
}
- def failStruct(what: String, where: String = "Parameter") =
- fail(s"$where type in structural refinement may not refer to $what")
- for (paramType <- tp.paramTypes) {
+ def nthParamPos(n: Int) = ddef.vparamss match {
+ case xs :: _ if xs.length > n => xs(n).pos
+ case _ => meth.pos
+ }
+ def failStruct(pos: Position, what: String, where: String = "Parameter") =
+ fail(pos, s"$where type in structural refinement may not refer to $what")
+
+ foreachWithIndex(tp.paramTypes) { (paramType, idx) =>
val sym = paramType.typeSymbol
+ def paramPos = nthParamPos(idx)
if (sym.isAbstractType) {
if (!sym.hasTransOwner(meth.owner))
- failStruct("an abstract type defined outside that refinement")
+ failStruct(paramPos, "an abstract type defined outside that refinement")
else if (!sym.hasTransOwner(meth))
- failStruct("a type member of that refinement")
+ failStruct(paramPos, "a type member of that refinement")
}
if (sym.isDerivedValueClass)
- failStruct("a user-defined value class")
+ failStruct(paramPos, "a user-defined value class")
if (paramType.isInstanceOf[ThisType] && sym == meth.owner)
- failStruct("the type of that refinement (self type)")
+ failStruct(paramPos, "the type of that refinement (self type)")
}
if (tp.resultType.typeSymbol.isDerivedValueClass)
- failStruct("a user-defined value class", where = "Result")
+ failStruct(ddef.tpt.pos, "a user-defined value class", where = "Result")
}
def typedUseCase(useCase: UseCase) {
@@ -2124,7 +2131,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
if (meth.isStructuralRefinementMember)
- checkMethodStructuralCompatible(meth)
+ checkMethodStructuralCompatible(ddef)
if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match {
case List(param) :: _ if !param.isImplicit =>