@@ -833,64 +833,63 @@ trait Implicits { self: Typer =>
833833
834834 val isNot = wildProto.classSymbol == defn.NotClass
835835
836- /** Search a list of eligible implicit references */
837- def searchImplicits (eligible : List [Candidate ], contextual : Boolean ): SearchResult = {
838- val constr = ctx.typerState.constraint
839-
840836 // println(i"search implicits $pt / ${eligible.map(_.ref)}")
841837
842- /** Try to typecheck an implicit reference */
843- def typedImplicit (cand : Candidate )(implicit ctx : Context ): SearchResult = track(" typedImplicit" ) { trace(i " typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled }" , implicits, show = true ) {
844- assert(constr eq ctx.typerState.constraint)
845- val ref = cand.ref
846- var generated : Tree = tpd.ref(ref).withPos(pos.startPos)
847- if (! argument.isEmpty)
848- generated = typedUnadapted(
849- untpd.Apply (untpd.TypedSplice (generated), untpd.TypedSplice (argument) :: Nil ),
850- pt)
851- val generated1 = adapt(generated, pt)
852- lazy val shadowing =
853- typed(untpd.Ident (cand.implicitRef.implicitName) withPos pos.toSynthetic, funProto)(
854- nestedContext().addMode(Mode .ImplicitShadowing ).setExploreTyperState())
855- def refSameAs (shadowing : Tree ): Boolean =
856- ref.symbol == closureBody(shadowing).symbol || {
857- shadowing match {
858- case Trees .Select (qual, nme.apply) => refSameAs(qual)
859- case Trees .Apply (fn, _) => refSameAs(fn)
860- case Trees .TypeApply (fn, _) => refSameAs(fn)
861- case _ => false
862- }
838+ /** Try to typecheck an implicit reference */
839+ def typedImplicit (cand : Candidate , contextual : Boolean )(implicit ctx : Context ): SearchResult = track(" typedImplicit" ) { trace(i " typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled }" , implicits, show = true ) {
840+ val ref = cand.ref
841+ var generated : Tree = tpd.ref(ref).withPos(pos.startPos)
842+ if (! argument.isEmpty)
843+ generated = typedUnadapted(
844+ untpd.Apply (untpd.TypedSplice (generated), untpd.TypedSplice (argument) :: Nil ),
845+ pt)
846+ val generated1 = adapt(generated, pt)
847+ lazy val shadowing =
848+ typed(untpd.Ident (cand.implicitRef.implicitName) withPos pos.toSynthetic, funProto)(
849+ nestedContext().addMode(Mode .ImplicitShadowing ).setExploreTyperState())
850+ def refSameAs (shadowing : Tree ): Boolean =
851+ ref.symbol == closureBody(shadowing).symbol || {
852+ shadowing match {
853+ case Trees .Select (qual, nme.apply) => refSameAs(qual)
854+ case Trees .Apply (fn, _) => refSameAs(fn)
855+ case Trees .TypeApply (fn, _) => refSameAs(fn)
856+ case _ => false
863857 }
858+ }
864859
865- if (ctx.reporter.hasErrors) {
866- ctx.reporter.removeBufferedMessages
867- SearchFailure {
868- generated1.tpe match {
869- case _ : SearchFailureType => generated1
870- case _ => generated1.withType(new MismatchedImplicit (ref, pt, argument))
871- }
860+ if (ctx.reporter.hasErrors) {
861+ ctx.reporter.removeBufferedMessages
862+ SearchFailure {
863+ generated1.tpe match {
864+ case _ : SearchFailureType => generated1
865+ case _ => generated1.withType(new MismatchedImplicit (ref, pt, argument))
872866 }
873867 }
874- else if (contextual && ! ctx.mode.is(Mode .ImplicitShadowing ) &&
875- ! shadowing.tpe.isError && ! refSameAs(shadowing)) {
876- implicits.println(i " SHADOWING $ref in ${ref.termSymbol.maybeOwner} is shadowed by $shadowing in ${shadowing.symbol.maybeOwner}" )
877- SearchFailure (generated1.withTypeUnchecked(
878- new ShadowedImplicit (ref, methPart(shadowing).tpe, pt, argument)))
879- }
880- else
881- SearchSuccess (generated1, ref, cand.level)(ctx.typerState)
882- }}
883-
884- /** Try to type-check implicit reference, after checking that this is not
885- * a diverging search
886- */
887- def tryImplicit (cand : Candidate ): SearchResult = {
888- val history = ctx.searchHistory nest wildProto
889- if (history eq ctx.searchHistory)
890- SearchFailure (new DivergingImplicit (cand.ref, pt, argument))
891- else
892- typedImplicit(cand)(nestedContext().setNewTyperState().setSearchHistory(history))
893868 }
869+ else if (contextual && ! ctx.mode.is(Mode .ImplicitShadowing ) &&
870+ ! shadowing.tpe.isError && ! refSameAs(shadowing)) {
871+ implicits.println(i " SHADOWING $ref in ${ref.termSymbol.maybeOwner} is shadowed by $shadowing in ${shadowing.symbol.maybeOwner}" )
872+ SearchFailure (generated1.withTypeUnchecked(
873+ new ShadowedImplicit (ref, methPart(shadowing).tpe, pt, argument)))
874+ }
875+ else
876+ SearchSuccess (generated1, ref, cand.level)(ctx.typerState)
877+ }}
878+
879+ /** Try to type-check implicit reference, after checking that this is not
880+ * a diverging search
881+ */
882+ def tryImplicit (cand : Candidate , contextual : Boolean ): SearchResult = {
883+ val history = ctx.searchHistory nest wildProto
884+ if (history eq ctx.searchHistory)
885+ SearchFailure (new DivergingImplicit (cand.ref, pt, argument))
886+ else
887+ typedImplicit(cand, contextual)(nestedContext().setNewTyperState().setSearchHistory(history))
888+ }
889+
890+ /** Search a list of eligible implicit references */
891+ def searchImplicits (eligible : List [Candidate ], contextual : Boolean ): SearchResult = {
892+ val constr = ctx.typerState.constraint
894893
895894 /** Compare previous success with reference and level to determine which one would be chosen, if
896895 * an implicit starting with the reference was found.
@@ -963,7 +962,7 @@ trait Implicits { self: Typer =>
963962 def rank (pending : List [Candidate ], found : SearchResult , rfailures : List [SearchFailure ]): SearchResult =
964963 pending match {
965964 case cand :: remaining =>
966- negateIfNot(tryImplicit(cand)) match {
965+ negateIfNot(tryImplicit(cand, contextual )) match {
967966 case fail : SearchFailure =>
968967 if (fail.isAmbiguous)
969968 if (ctx.scala2Mode) {
@@ -1078,6 +1077,15 @@ trait Implicits { self: Typer =>
10781077 }
10791078
10801079 def implicitScope (tp : Type ): OfTypeImplicits = ctx.run.implicitScope(tp, ctx)
1080+
1081+ /** All available implicits, without ranking */
1082+ def allImplicits : Set [TermRef ] = {
1083+ val contextuals = ctx.implicits.eligible(wildProto).map(tryImplicit(_, contextual = true ))
1084+ val inscope = implicitScope(wildProto).eligible.map(tryImplicit(_, contextual = false ))
1085+ (contextuals.toSet ++ inscope).collect {
1086+ case success : SearchSuccess => success.ref
1087+ }
1088+ }
10811089 }
10821090}
10831091
0 commit comments