Skip to content

Fix #3590: look for implicits in WhilcardType #3592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ trait ImplicitRunInfo { self: RunInfo =>
case tp: AppliedType if !tp.tycon.typeSymbol.isClass =>
def applyArg(arg: Type) = arg match {
case TypeBounds(lo, hi) => AndType.make(lo, hi)
case _: WildcardType => defn.AnyType
case WildcardType(TypeBounds(lo, hi)) => AndType.make(lo, hi)
case _ => arg
}
(apply(tp.tycon) /: tp.args)((tc, arg) => AndType.make(tc, applyArg(arg)))
Expand Down
39 changes: 39 additions & 0 deletions tests/pos/i3590.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
trait Tagged[T]

object Tagged {
type Aux[T, UNUSED] = Tagged[T]
}

trait Fun[R] {
type Out
}

object Fun extends Fun0 {
// In Dotty there is a difference between asking for Tagged.Aux[T, Int]
// and asking for Tagged[T]. In the former case the companion of T is
// not considered as a valid scope during implicit search. In scalac
// both cases are treated equally.
implicit def tagged[T](implicit t: Tagged.Aux[T, Int]): Fun[T] { type Out = Int } = ???
}

trait Fun0 {
implicit def default[T]: Fun[T] { type Out = String } = ???
}

object FunDemo extends App {
case class A(x: Int, y: String)
object A {
implicit val tag: Tagged[A] = ???
}

// Precise version of implicitly that keeps type members
def the[T <: AnyRef](implicit ev: T): ev.type = ev

val adhl = the[Fun[A]]

// Compiles in scalac: the tagged case wins the implicit search using A.tag
// Does not compile in Dotty: because of Tagged.Aux[T, _] the companion
// object of T is not explored during the search,
// it fallbacks to default (type Out = String)
identity[Fun[A] { type Out = Int }](adhl)
}