diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-19 12:30:06 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-19 12:30:06 +0100 |
commit | c0ce16a03645056016636d7cda514daed2b7ab70 (patch) | |
tree | cf7f16eef908e5ff4b4cf5820073565227e3b6d3 /src | |
parent | 6be96724899f9c34db2e6c2617534dc9c4a15528 (diff) | |
download | dotty-c0ce16a03645056016636d7cda514daed2b7ab70.tar.gz dotty-c0ce16a03645056016636d7cda514daed2b7ab70.tar.bz2 dotty-c0ce16a03645056016636d7cda514daed2b7ab70.zip |
3 changes to implicit search
1. Shadowing tree uses adaptation funProto of prototype. Previously many shadowing tries failed with errors like "need to follow with "_" to adapt to function". These early failures hid potential shadowing conflicts.
2. Shadowing conflict testing is now done using symbols instead of comparing references. Comparing references gave false negative when a shadoing tree had inferred type parameters, for instance. There were other problems as well. Generally, comparsing references seems too fragile.
3. Inferred views are now re-adapted. This is necessary if the view itself takes another implicit parameter.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 17 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 4 |
2 files changed, 15 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index c236f8335..0c2606d89 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -294,6 +294,12 @@ trait Implicits { self: Typer => /** The expected type for the searched implicit */ lazy val fullProto = implicitProto(pt) + lazy val funProto = fullProto match { + case proto: ViewProto => + FunProto(dummyTreeOfType(proto.argType) :: Nil, proto.resultType, self) + case proto => proto + } + /** The expected type where parameters and uninstantiated typevars are replaced by wildcard types */ val wildProto = implicitProto((new WildApprox) apply pt) @@ -315,10 +321,13 @@ trait Implicits { self: Typer => pt) val generated1 = adapt(generated, pt) lazy val shadowing = - typed(untpd.Ident(ref.name) withPos pos.toSynthetic, fullProto)(nestedContext.withNewTyperState).tpe - if (ctx.typerState.reporter.hasErrors) nonMatchingImplicit(ref) - else if (contextual && !(shadowing =:= ref)) shadowedImplicit(ref, shadowing) - else SearchSuccess(generated, ref, ctx.typerState) + typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.withNewTyperState) + if (ctx.typerState.reporter.hasErrors) + nonMatchingImplicit(ref) + else if (contextual && shadowing.symbol != ref.symbol) + shadowedImplicit(ref, methPart(shadowing).tpe) + else + SearchSuccess(generated, ref, ctx.typerState) }} /** Given a list of implicit references, produce a list of all implicit search successes, diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 7493fb42d..cf7d54ca6 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1113,8 +1113,8 @@ class Typer extends Namer with Applications with Implicits { } // try an implicit conversion inferView(tree, pt) match { - case SearchSuccess(adapted, _, _) => - adapted + case SearchSuccess(inferred, _, _) => + adapt(inferred, pt) case failure: SearchFailure => if (pt.isInstanceOf[ProtoType]) tree else err.typeMismatch(tree, pt, failure) |