diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-06 20:25:21 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-06 20:25:21 +0100 |
commit | aff925e667a62af65bf0190c3318219d2218b3c1 (patch) | |
tree | 1b383cbe7ec61e983a07e348c99983ed7896782b /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 71027f15cc9e125520c210d01a1b453f6ba45ec0 (diff) | |
download | dotty-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/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 25 |
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 = { |