@@ -81,6 +81,12 @@ object Typer {
8181 */
8282 private val InsertedApply = new Property .Key [Unit ]
8383
84+ /** An attachment on a result of an implicit conversion or extension method
85+ * that was added by tryInsertImplicitOnQualifier. Needed to prevent infinite
86+ * expansions in error cases (e.g. in fuzzy/i9293.scala).
87+ */
88+ private val InsertedImplicitOnQualifier = new Property .Key [Unit ]
89+
8490 /** An attachment on a tree `t` occurring as part of a `t()` where
8591 * the `()` was dropped by the Typer.
8692 */
@@ -3141,21 +3147,30 @@ class Typer extends Namer
31413147 }
31423148
31433149 /** If this tree is a select node `qual.name` (possibly applied to type variables)
3144- * that does not conform to `pt`, try to insert an implicit conversion `c` around
3145- * `qual` so that `c(qual).name` conforms to `pt`.
3150+ * that does not conform to `pt`, try two mitigations:
3151+ * 1. Instantiate any TypeVars in the widened type of `tree` with their lower bounds.
3152+ * 2. Try to insert an implicit conversion `c` around `qual` so that
3153+ * `c(qual).name` conforms to `pt`.
31463154 */
31473155 def tryInsertImplicitOnQualifier (tree : Tree , pt : Type , locked : TypeVars )(using Context ): Option [Tree ] = trace(i " try insert impl on qualifier $tree $pt" ) {
31483156 tree match
31493157 case tree @ Select (qual, name) if name != nme.CONSTRUCTOR =>
3150- val selProto = SelectionProto (name, pt, NoViewsAllowed , privateOK = false )
3151- if selProto.isMatchedBy(qual.tpe) then None
3158+ if couldInstantiateTypeVar(qual.tpe.widen, applied = true )
3159+ then
3160+ Some (adapt(tree, pt, locked))
31523161 else
3153- tryEither {
3154- val tree1 = tryExtensionOrConversion(tree, pt, pt, qual, locked, NoViewsAllowed , inSelect = false )
3155- if tree1.isEmpty then None
3156- else Some (adapt(tree1, pt, locked))
3157- } { (_, _) => None
3158- }
3162+ val selProto = SelectionProto (name, pt, NoViewsAllowed , privateOK = false )
3163+ if selProto.isMatchedBy(qual.tpe) || tree.hasAttachment(InsertedImplicitOnQualifier ) then
3164+ None
3165+ else
3166+ tryEither {
3167+ val tree1 = tryExtensionOrConversion(tree, pt, pt, qual, locked, NoViewsAllowed , inSelect = false )
3168+ if tree1.isEmpty then None
3169+ else
3170+ tree1.putAttachment(InsertedImplicitOnQualifier , ())
3171+ Some (adapt(tree1, pt, locked))
3172+ } { (_, _) => None
3173+ }
31593174 case TypeApply (fn, args) if args.forall(_.isInstanceOf [untpd.InferredTypeTree ]) =>
31603175 tryInsertImplicitOnQualifier(fn, pt, locked)
31613176 case _ => None
0 commit comments