Skip to content

Implicit not found for the result of match type, although it's declared in the companion object #17395

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

Closed
neko-kai opened this issue May 2, 2023 · 2 comments · Fixed by #17457

Comments

@neko-kai
Copy link
Contributor

neko-kai commented May 2, 2023

Compiler version

3.3.0-RC5

Minimized code

https://scastie.scala-lang.org/2FKUlvnQTQaY6iZceg9tug

trait TC[T]

object TC {
  def optionTCForPart[T](implicit tc: TC[ExtractPart[T]]): TC[Option[ExtractPart[T]]] = new TC[Option[ExtractPart[T]]] {}
}

type ExtractPart[T] = T match {
  case PartField[t] => t
}
type PartField[T] = Any { type Part = T }

class ValuePartHolder {
  type Part = Value
}

class Value
object Value {
  implicit val tcValue: TC[Value] = new {}
}

@main def main(): Unit = {
//  import Value.tcValue // explicit import works around the issue, but shouldn't be necessary
  val tc = TC.optionTCForPart[ValuePartHolder]
  println(tc)
}

Output

val tc = TC.optionTCForPart[ValuePartHolder]
^
  No given instance of type TC[ExtractPart[ValuePartHolder]]
  was found for parameter tc of method optionTCForPart in object TC

  The following import might fix the problem:
  import Value.tcValue

Expectation

Expected to work, since ExtractPart[ValuePartHolder]] evaluates to Value and Value companion object already contains the instance, making explicit import redundant.

@neko-kai neko-kai added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 2, 2023
@mbovel mbovel added area:match-types and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 4, 2023
@odersky
Copy link
Contributor

odersky commented May 5, 2023

I think this is another cart-before-horse problem. The compiler looks for implicits in the type scope of the match type. It does not reduce the match type at this point. Should it? I am not sure, reducing match types eagerly could cause other problems. For instance, the implicit might force a type variable that is needed to make the match type reduce. The whole area is very finely balanced and everything is a tradeoff in the end.

@neko-kai
Copy link
Contributor Author

neko-kai commented May 8, 2023

@odersky
Intuitively I believe it should, e.g. consider a trivial match type type Id[A] = A match { case _ => A }, we'd expect it to behave the same as an equivalent type alias in as much as that's reasonably implementable.

Also, practically, I'm using match types written in the style above - that extract type members - to cross-compile code that uses type projections in Scala 2. So far, I've been able to substitute all usages of general type projections with match types, except for this case - when used together with implicits where the search must find implicits for the extracted type member.

@dwijnand dwijnand linked a pull request May 10, 2023 that will close this issue
@Kordyjan Kordyjan added this to the 3.3.1 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants