<commit_before>package dotty.tools
package dotc
package typer

import core._
import ast.{Trees, untpd, tpd, TreeInfo}
import util.Positions._
import util.Stats.{track, record, monitored}
import printing.{Showable, Printer}
import printing.Texts._
import Contexts._
import Types._
import Flags._
import TypeErasure.{erasure, hasStableErasure}
import Mode.ImplicitsEnabled
import Denotations._
import NameOps._
import SymDenotations._
import Symbols._
import Types._
import Decorators._
import Names._
import StdNames._
import Constants._
import Applications._
import ProtoTypes._
import ErrorReporting._
import reporting.diagnostic.MessageContainer
import Inferencing.fullyDefinedType
import Trees._
import Hashable._
import util.Property
import config.Config
import config.Printers.{implicits, implicitsDetailed, typr}
import collection.mutable

/** Implicit resolution */
object Implicits {

  /** A reference to an implicit value to be made visible on the next nested call to
   *  inferImplicitArg with a by-name expected type.
   */
  val DelayedImplicit = new Property.Key[TermRef]

  /** An eligible implicit candidate, consisting of an implicit reference and a nesting level */
  case class Candidate(ref: TermRef, level: Int)

  /** A common base class of contextual implicits and of-type implicits which
   *  represents a set of implicit references.
   */
  abstract class ImplicitRefs(initctx: Context) {
    implicit val ctx: Context =
      if (initctx == NoContext) initctx else initctx retractMode Mode.ImplicitsEnabled

    /** The nesting level of this context. Non-zero only in ContextialImplicits */
    def level: Int = 0

    /** The implicit references */
    def refs: List[TermRef]

    /** Return those references in `refs` that are compatible with type `pt`. */
    protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = track("filterMatching") {

      def refMatches(ref: TermRef)(implicit ctx: Context) = /*ctx.traceIndented(i"refMatches $ref $pt")*/ {

        def discardForView(tpw: Type, argType: Type): Boolean = tpw match {
          case mt: MethodType =>
            mt.isImplicit ||
            mt.paramTypes.length != 1 ||
            !(argType relaxed_<:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
          case poly: PolyType =>
            // We do not need to call ProtoTypes#constrained on `poly` because
            // `refMatches` is always called with mode TypevarsMissContext enabled.
            poly.resultType match {
              case mt: MethodType =>
                mt.isImplicit ||
                mt.paramTypes.length != 1 ||
                !(argType relaxed_<:< wildApprox(mt.paramTypes.head, null, Set.empty)(ctx.fresh.setExploreTyperState))
              case rtp =>
                discardForView(wildApprox(rtp, null, Set.empty), argType)
            }
          case tpw: TermRef =>
            false // can't discard overloaded refs
          case tpw =>
            // Only direct instances of Function1 and direct or indirect instances of <:< are eligible as views.
            // However, Predef.$conforms is not eligible, because it is a no-op.
            //
            // In principle, it would be cleanest if only implicit methods qualified
            // as implicit conversions. The reasons for deviating are as follows:
            // Keeping Function1: It's still used quite often (for instance, view
            // bounds map to implicits of function types) and there is no feasible workaround.
            // One tempting workaround would be to add a global def
            //
            //    implicit def convertIfFuntion1[A, B](x: A)(implicit ev: A => B): B = ev(a)
            //
            // But that would throw out the baby with the bathwater. Now, every subtype of
            // function gives again rise to an implicit conversion. So it's better to just accept
            // function types in their dual roles.
            //
            // The reason for the treatment of <:< and conforms is similar. We could
            // avoid the clause by having a standard conversion like this in Predef:
            //
            //    implicit def convertIfConforms[A, B](x: A)(implicit ev: A <:< B): B = ev(a)
            //
            // But that would slow down implicit search a lot, because this conversion is
            // eligible for all pairs of types, and therefore is tried a lot. So we
            // emulate the existence of a such a conversion directly in the search.
            // The reason for leaving out `Predef_conforms` is that we know it adds
            // nothing since it only relates subtype with supertype.
            //
            // We keep the old behavior under -language:Scala2.
            val isFunction =
              if (ctx.scala2Mode) tpw.derivesFrom(defn.FunctionClass(1))
              else tpw.isRef(defn.FunctionClass(1))
            val isConforms =
              tpw.derivesFrom(defn.Predef_Conforms) || ref.symbol == defn.Predef_conforms
            !(isFunction || isConforms)
        }

        def discardForValueType(tpw: Type): Boolean = tpw match {
          case mt: MethodType => !mt.isImplicit
          case mt: PolyType => discardForValueType(tpw.resultType)
          case _ => false
        }

        def discard = pt match {
          case pt: ViewProto => discardForView(ref.widen, pt.argType)<commit_msg>Fix condition logic<commit_after>package dotty.tools
package dotc
package typer

import core._
import ast.{Trees, untpd, tpd, TreeInfo}
import util.Positions._
import util.Stats.{track, record, monitored}
import printing.{Showable, Printer}
import printing.Texts._
import Contexts._
import Types._
import Flags._
import TypeErasure.{erasure, hasStableErasure}
import Mode.ImplicitsEnabled
import Denotations._
import NameOps._
import SymDenotations._
import Symbols._
import Types._
import Decorators._
import Names._
import StdNames._
import Constants._
import Applications._
import ProtoTypes._
import ErrorReporting._
import reporting.diagnostic.MessageContainer
import Inferencing.fullyDefinedType
import Trees._
import Hashable._
import util.Property
import config.Config
import config.Printers.{implicits, implicitsDetailed, typr}
import collection.mutable

/** Implicit resolution */
object Implicits {

  /** A reference to an implicit value to be made visible on the next nested call to
   *  inferImplicitArg with a by-name expected type.
   */
  val DelayedImplicit = new Property.Key[TermRef]

  /** An eligible implicit candidate, consisting of an implicit reference and a nesting level */
  case class Candidate(ref: TermRef, level: Int)

  /** A common base class of contextual implicits and of-type implicits which
   *  represents a set of implicit references.
   */
  abstract class ImplicitRefs(initctx: Context) {
    implicit val ctx: Context =
      if (initctx == NoContext) initctx else initctx retractMode Mode.ImplicitsEnabled

    /** The nesting level of this context. Non-zero only in ContextialImplicits */
    def level: Int = 0

    /** The implicit references */
    def refs: List[TermRef]

    /** Return those references in `refs` that are compatible with type `pt`. */
    protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = track("filterMatching") {

      def refMatches(ref: TermRef)(implicit ctx: Context) = /*ctx.traceIndented(i"refMatches $ref $pt")*/ {

        def discardForView(tpw: Type, argType: Type): Boolean = tpw match {
          case mt: MethodType =>
            mt.isImplicit ||
            mt.paramTypes.length != 1 ||
            !(argType relaxed_<:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
          case poly: PolyType =>
            // We do not need to call ProtoTypes#constrained on `poly` because
            // `refMatches` is always called with mode TypevarsMissContext enabled.
            poly.resultType match {
              case mt: MethodType =>
                mt.isImplicit ||
                mt.paramTypes.length != 1 ||
                !(argType relaxed_<:< wildApprox(mt.paramTypes.head, null, Set.empty)(ctx.fresh.setExploreTyperState))
              case rtp =>
                discardForView(wildApprox(rtp, null, Set.empty), argType)
            }
          case tpw: TermRef =>
            false // can't discard overloaded refs
          case tpw =>
            // Only direct instances of Function1 and direct or indirect instances of <:< are eligible as views.
            // However, Predef.$conforms is not eligible, because it is a no-op.
            //
            // In principle, it would be cleanest if only implicit methods qualified
            // as implicit conversions. The reasons for deviating are as follows:
            // Keeping Function1: It's still used quite often (for instance, view
            // bounds map to implicits of function types) and there is no feasible workaround.
            // One tempting workaround would be to add a global def
            //
            //    implicit def convertIfFuntion1[A, B](x: A)(implicit ev: A => B): B = ev(a)
            //
            // But that would throw out the baby with the bathwater. Now, every subtype of
            // function gives again rise to an implicit conversion. So it's better to just accept
            // function types in their dual roles.
            //
            // The reason for the treatment of <:< and conforms is similar. We could
            // avoid the clause by having a standard conversion like this in Predef:
            //
            //    implicit def convertIfConforms[A, B](x: A)(implicit ev: A <:< B): B = ev(a)
            //
            // But that would slow down implicit search a lot, because this conversion is
            // eligible for all pairs of types, and therefore is tried a lot. So we
            // emulate the existence of a such a conversion directly in the search.
            // The reason for leaving out `Predef_conforms` is that we know it adds
            // nothing since it only relates subtype with supertype.
            //
            // We keep the old behavior under -language:Scala2.
            val isFunction =
              if (ctx.scala2Mode) tpw.derivesFrom(defn.FunctionClass(1))
              else tpw.isRef(defn.FunctionClass(1))
            val isConforms =
              tpw.derivesFrom(defn.Predef_Conforms) && ref.symbol != defn.Predef_conforms
            !(isFunction || isConforms)
        }

        def discardForValueType(tpw: Type): Boolean = tpw match {
          case mt: MethodType => !mt.isImplicit
          case mt: PolyType => discardForValueType(tpw.resultType)
          case _ => false
        }

        def discard = pt match {
          case pt: ViewProto => discardForView(ref.widen, pt.argType)
{'fraction_non_alphanumeric': 0.08333333333333333, 'fraction_numerical': 0.001851851851851852, 'mean_word_length': 2.391208791208791, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6810228', 'n_tokens_mistral': 2941, 'n_tokens_neox': 2839, 'n_words': 1071}