@@ -132,23 +132,81 @@ trait Migrations:
132132 if tp.companion == ImplicitMethodType && pt.applyKind != ApplyKind .Using && pt.args.nonEmpty then
133133 // The application can only be rewritten if it uses parentheses syntax.
134134 // See issue #22927 and related tests.
135- val hasParentheses =
136- ctx.source.content
137- .slice(tree.span.end, pt.args.head.span.start)
138- .exists(_ == '(' )
135+ val hasParentheses = checkParentheses(tree, pt)
139136 val rewriteMsg =
140137 if hasParentheses then
141138 Message .rewriteNotice(" This code" , mversion.patchFrom)
142139 else
143140 " "
144141 report.errorOrMigrationWarning(
145142 em """ Implicit parameters should be provided with a `using` clause. $rewriteMsg
146- |To disable the warning, please use the following option:
143+ |To disable the warning, please use the following option:
147144 | "-Wconf:msg=Implicit parameters should be provided with a `using` clause:s"
148- | """ ,
145+ | """ ,
149146 pt.args.head.srcPos, mversion)
150147 if hasParentheses && mversion.needsPatch then
151- patch( Span (pt.args.head.span.start), " using " )
148+ patchImplicitParams(tree, pt )
152149 end implicitParams
153150
151+ private def checkParentheses (tree : Tree , pt : FunProto )(using Context ): Boolean =
152+ ctx.source.content
153+ .slice(tree.span.end, pt.args.head.span.start)
154+ .exists(_ == '(' )
155+
156+ private def patchImplicitParams (tree : Tree , pt : FunProto )(using Context ): Unit =
157+ patch(Span (pt.args.head.span.start), " using " )
158+
159+ object ImplicitToGiven :
160+ def valDef (vdef : ValDef )(using Context ): Unit =
161+ if ctx.settings.YimplicitToGiven .value
162+ && vdef.symbol.is(Implicit )
163+ && ! vdef.symbol.isParamOrAccessor
164+ then
165+ val implicitSpan =
166+ vdef.mods.mods.collectFirst {
167+ case mod : untpd.Mod .Implicit => mod.span
168+ }.get
169+ patch(
170+ Span (implicitSpan.start, implicitSpan.end + 1 ),
171+ " "
172+ )
173+ patch(
174+ Span (vdef.mods.mods.last.span.end + 1 , vdef.namePos.span.start), " given "
175+ )
176+
177+ def defDef (ddef : DefDef )(using Context ): Unit =
178+ if
179+ ctx.settings.YimplicitToGiven .value
180+ && ddef.symbol.is(Implicit )
181+ && ! ddef.symbol.isParamOrAccessor
182+ && ! ddef.symbol.isOldStyleImplicitConversion()
183+ then
184+ val implicitSpan =
185+ ddef.mods.mods.collectFirst {
186+ case mod : untpd.Mod .Implicit => mod.span
187+ }.get
188+ patch(
189+ Span (implicitSpan.start, implicitSpan.end + 1 ), " "
190+ )
191+ patch(
192+ Span (ddef.mods.mods.last.span.end + 1 , ddef.namePos.span.start), " given "
193+ )
194+ ddef.tpt match
195+ case refinedType : untpd.RefinedTypeTree =>
196+ patch(refinedType.span.startPos, " (" )
197+ patch(refinedType.span.endPos, " )" )
198+ case _ =>
199+
200+ def implicitParams (tree : Tree , tp : MethodOrPoly , pt : FunProto )(using Context ): Unit =
201+ if
202+ ctx.settings.YimplicitToGiven .value
203+ && ! mv.ExplicitContextBoundArgument .needsPatch // let's not needlessly repeat the patch
204+ && tp.companion == ImplicitMethodType
205+ && pt.applyKind != ApplyKind .Using
206+ && pt.args.nonEmpty
207+ && checkParentheses(tree, pt)
208+ then
209+ patchImplicitParams(tree, pt)
210+
211+
154212end Migrations
0 commit comments