From 1a20c5b51422c3ed13ee5e53367d6fd6e629385a Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Thu, 15 Jun 2017 11:19:03 +0200 Subject: [PATCH 1/2] fix #2749: support implicit resolution of implicit function types --- compiler/src/dotty/tools/dotc/typer/Implicits.scala | 4 +++- compiler/src/dotty/tools/dotc/typer/Typer.scala | 1 + tests/pos/i2749.scala | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i2749.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index f0788665ca17..17d922023b17 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -123,7 +123,9 @@ object Implicits { record("discarded eligible") false } - else NoViewsAllowed.isCompatible(normalize(ref, pt), pt) + else + NoViewsAllowed.isCompatible(normalize(ref, pt), pt) || + NoViewsAllowed.isCompatible(ref, pt) // `pt` could be an implicit function type, check i2749 } } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 974c9786799a..632acca1f00d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1640,6 +1640,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (defn.isImplicitFunctionType(pt) && xtree.isTerm && !untpd.isImplicitClosure(xtree) && + !ctx.mode.is(Mode.ImplicitShadowing) && !ctx.isAfterTyper) makeImplicitFunction(xtree, pt) else xtree match { diff --git a/tests/pos/i2749.scala b/tests/pos/i2749.scala new file mode 100644 index 000000000000..946ae94b52eb --- /dev/null +++ b/tests/pos/i2749.scala @@ -0,0 +1,7 @@ +object Test { + val f: implicit (implicit Int => Char) => Boolean = ??? + implicit val n: Int = 3 + implicit val g: implicit Int => Char = ??? + + f : Boolean +} From 9ae3a1f69c797543011d4b5a1a0fc83de625cefa Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Fri, 16 Jun 2017 11:23:15 +0200 Subject: [PATCH 2/2] improve the fix to support more general cases --- .../src/dotty/tools/dotc/typer/Implicits.scala | 4 ++-- tests/pos/i2749.scala | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 17d922023b17..a9a75735c7e0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -60,6 +60,7 @@ object Implicits { /** Return those references in `refs` that are compatible with type `pt`. */ protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = track("filterMatching") { + val ptNorm = normalize(pt, pt) // `pt` could be implicit function types, check i2749 def refMatches(ref: TermRef)(implicit ctx: Context) = /*ctx.traceIndented(i"refMatches $ref $pt")*/ { @@ -124,8 +125,7 @@ object Implicits { false } else - NoViewsAllowed.isCompatible(normalize(ref, pt), pt) || - NoViewsAllowed.isCompatible(ref, pt) // `pt` could be an implicit function type, check i2749 + NoViewsAllowed.isCompatible(normalize(ref, pt), ptNorm) } } diff --git a/tests/pos/i2749.scala b/tests/pos/i2749.scala index 946ae94b52eb..5d4972421ebb 100644 --- a/tests/pos/i2749.scala +++ b/tests/pos/i2749.scala @@ -5,3 +5,19 @@ object Test { f : Boolean } + +object Test2 { + val f: implicit (implicit Int => Char) => Boolean = ??? + implicit val s: String = null + implicit val g: implicit Int => implicit String => Char = ??? + + f : Boolean +} + +object Test3 { + val f: implicit (implicit Int => implicit String => Char) => Boolean = ??? + implicit val n: Int = 3 + implicit val g: implicit Int => Char = ??? + + f : Boolean +}