From a336ec0a700c0902c74d5318ab47929bc28c5413 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 29 Sep 2015 19:15:56 +0200 Subject: Refine atSignature atSignature should also check result type names, except - if one of the result is a wildcard - a boolean flag relaxed is explicitly set --- src/dotty/tools/dotc/core/Denotations.scala | 16 ++++++++++------ src/dotty/tools/dotc/core/Signature.scala | 10 ++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index cd46918cf..3bab19ea9 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -125,8 +125,9 @@ object Denotations { /** Resolve overloaded denotation to pick the one with the given signature * when seen from prefix `site`. + * @param relaxed When true, consider only parameter signatures for a match. */ - def atSignature(sig: Signature, site: Type = NoPrefix)(implicit ctx: Context): SingleDenotation + def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): SingleDenotation /** The variant of this denotation that's current in the given context, or * `NotDefinedHereDenotation` if this denotation does not exist at current phase, but @@ -221,7 +222,7 @@ object Denotations { */ def matchingDenotation(site: Type, targetType: Type)(implicit ctx: Context): SingleDenotation = if (isOverloaded) - atSignature(targetType.signature, site).matchingDenotation(site, targetType) + atSignature(targetType.signature, site, relaxed = true).matchingDenotation(site, targetType) else if (exists && !site.memberInfo(symbol).matchesLoosely(targetType)) NoDenotation else @@ -398,8 +399,8 @@ object Denotations { final def validFor = denot1.validFor & denot2.validFor final def isType = false final def signature(implicit ctx: Context) = Signature.OverloadedSignature - def atSignature(sig: Signature, site: Type)(implicit ctx: Context): SingleDenotation = - denot1.atSignature(sig, site) orElse denot2.atSignature(sig, site) + def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation = + denot1.atSignature(sig, site, relaxed) orElse denot2.atSignature(sig, site, relaxed) def currentIfExists(implicit ctx: Context): Denotation = derivedMultiDenotation(denot1.currentIfExists, denot2.currentIfExists) def current(implicit ctx: Context): Denotation = @@ -469,9 +470,12 @@ object Denotations { def accessibleFrom(pre: Type, superAccess: Boolean)(implicit ctx: Context): Denotation = if (!symbol.exists || symbol.isAccessibleFrom(pre, superAccess)) this else NoDenotation - def atSignature(sig: Signature, site: Type)(implicit ctx: Context): SingleDenotation = { + def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation = { val situated = if (site == NoPrefix) this else asSeenFrom(site) - if (sig matches situated.signature) this else NoDenotation + val matches = + if (relaxed) sig.matches(situated.signature) + else sig.matchesFully(situated.signature) + if (matches) this else NoDenotation } def matches(other: SingleDenotation)(implicit ctx: Context): Boolean = diff --git a/src/dotty/tools/dotc/core/Signature.scala b/src/dotty/tools/dotc/core/Signature.scala index 4d83a7963..317f45e65 100644 --- a/src/dotty/tools/dotc/core/Signature.scala +++ b/src/dotty/tools/dotc/core/Signature.scala @@ -35,6 +35,16 @@ case class Signature(paramsSig: List[TypeName], resSig: TypeName) { final def matches(that: Signature)(implicit ctx: Context) = if (ctx.erasedTypes) equals(that) else sameParams(that) + /** A signature matches fully another if it has the same parameter type names + * and either one of the result type names is a wildcard or both agree. + */ + final def matchesFully(that: Signature)(implicit ctx: Context) = + this.paramsSig == that.paramsSig && + (isWildcard(this.resSig) || isWildcard(that.resSig) || this.resSig == that.resSig) + + /** name.toString == "" or name.toString == "_" */ + private def isWildcard(name: TypeName) = name.isEmpty || name == tpnme.WILDCARD + /** Construct a signature by prepending the signature names of the given `params` * to the parameter part of this signature. */ -- cgit v1.2.3