aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-01-06 20:25:21 +0100
committerMartin Odersky <odersky@gmail.com>2014-01-06 20:25:21 +0100
commitaff925e667a62af65bf0190c3318219d2218b3c1 (patch)
tree1b383cbe7ec61e983a07e348c99983ed7896782b /src/dotty/tools
parent71027f15cc9e125520c210d01a1b453f6ba45ec0 (diff)
downloaddotty-aff925e667a62af65bf0190c3318219d2218b3c1.tar.gz
dotty-aff925e667a62af65bf0190c3318219d2218b3c1.tar.bz2
dotty-aff925e667a62af65bf0190c3318219d2218b3c1.zip
Fix computation of inherited result types.
Need to take into account type parameters of inherited methods, which have to be instantiated with the type parameters of the current method.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 629910e09..fb075b40a 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -327,7 +327,7 @@ class Namer { typer: Typer =>
private def typeSig(sym: Symbol): Type = original match {
case original: ValDef =>
- valOrDefDefSig(original, sym, identity)(localContext(sym).withNewScope)
+ valOrDefDefSig(original, sym, Nil, identity)(localContext(sym).withNewScope)
case original: DefDef =>
val typer1 = new Typer
nestedTyper(sym) = typer1
@@ -417,7 +417,7 @@ class Namer { typer: Typer =>
* @param paramFn A wrapping function that produces the type of the
* defined symbol, given its final return type
*/
- def valOrDefDefSig(mdef: ValOrDefDef, sym: Symbol, paramFn: Type => Type)(implicit ctx: Context): Type = {
+ def valOrDefDefSig(mdef: ValOrDefDef, sym: Symbol, typeParams: List[Symbol], paramFn: Type => Type)(implicit ctx: Context): Type = {
val pt =
if (!mdef.tpt.isEmpty) WildcardType
else {
@@ -445,12 +445,19 @@ class Namer { typer: Typer =>
lazy val schema = paramFn(WildcardType)
val site = sym.owner.thisType
((NoType: Type) /: sym.owner.info.baseClasses.tail) { (tp, cls) =>
- val itpe = cls.info
- .nonPrivateDecl(sym.name)
- .matchingDenotation(site, schema)
- .info.finalResultType
- .asSeenFrom(site, cls)
- tp & itpe
+ val iRawInfo =
+ cls.info.nonPrivateDecl(sym.name).matchingDenotation(site, schema).info
+ val iInstInfo = iRawInfo match {
+ case iRawInfo: PolyType =>
+ if (iRawInfo.paramNames.length == typeParams.length)
+ iRawInfo.instantiate(typeParams map (_.typeRef))
+ else NoType
+ case _ =>
+ if (typeParams.isEmpty) iRawInfo
+ else NoType
+ }
+ val iResType = iInstInfo.finalResultType.asSeenFrom(site, cls)
+ tp & iResType
}
}
@@ -523,7 +530,7 @@ class Namer { typer: Typer =>
typedAheadType(ddef.tpt, defn.UnitType)
wrapMethType(sym.owner.typeRef.appliedTo(typeParams map (_.typeRef)))
}
- else valOrDefDefSig(ddef, sym, wrapMethType)
+ else valOrDefDefSig(ddef, sym, typeParams, wrapMethType)
}
def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = {