Skip to content

Commit efe28eb

Browse files
authored
Merge pull request #33 from oleg-py/implicit-patterns
Fixes
2 parents b76a89c + 532617d commit efe28eb

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

better-monadic-for/src/main/scala/com/olegpy/bm4/BetterMonadicFor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class BetterMonadicFor(val global: Global) extends Plugin {
6666
case "implicit-patterns" => implicitPatterns = toBoolean(value)
6767
}
6868

69-
noUncheckedFilter || noMapIdentity || noTupling
69+
noUncheckedFilter || noMapIdentity || noTupling || implicitPatterns
7070
}
7171
}
7272

better-monadic-for/src/main/scala/com/olegpy/bm4/ImplicitPatterns.scala

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,13 @@ trait ImplicitPatterns extends TreeUtils { self =>
5757
replacement
5858
))
5959

60-
case Block((matcher @ NonLocalImplicits(valdefs)) :: stats, expr) =>
61-
val m = StripImplicitZero.transform(matcher)
62-
val replacement = embedImplicitDefs(Block(m :: stats, expr), valdefs)
60+
case Block(stats, expr) if stats.exists(NonLocalImplicits.defined) =>
61+
val defns = stats.flatMap {
62+
case NonLocalImplicits(vals) => vals
63+
case _ => Nil
64+
}
65+
val newBody = stats.map(StripImplicitZero.transform)
66+
val replacement = embedImplicitDefs(Block(newBody, expr), defns)
6367
Some(replaceTree(tree, replacement))
6468

6569

@@ -147,16 +151,23 @@ trait ImplicitPatterns extends TreeUtils { self =>
147151
}
148152

149153
object NonLocalImplicits {
150-
def unapply(vd: ValDef): Option[List[ValDef]] = {
151-
vd.rhs match {
152-
case Match(_, CaseDef(pat, _, _) :: Nil) if vd.mods.hasFlag(Flag.ARTIFACT) =>
153-
val vd = pat.collect {
154-
case q"implicit0(${Bind(TermName(nm), Typed(_, tpt))})" =>
155-
mkValDef(nm, tpt)
156-
}
157-
if (vd.nonEmpty) Some(vd) else None
158-
case _ => None
159-
}
154+
val pf: PartialFunction[Tree, List[ValDef]] = {
155+
case ValDef(mods, _, _, Match(_, CaseDef(pat, _, _) :: Nil))
156+
if mods.hasFlag(Flag.ARTIFACT) &&
157+
pat.exists {
158+
case q"implicit0(${Bind(TermName(_), Typed(_, _))})" => true
159+
case _ => false
160+
}
161+
=>
162+
pat.collect {
163+
case q"implicit0(${Bind(TermName(nm), Typed(_, tpt))})" =>
164+
mkValDef(nm, tpt)
165+
}
160166
}
167+
168+
private[this] val lifted = pf.lift
169+
val defined = pf.isDefinedAt _
170+
171+
def unapply(vd: ValDef): Option[List[ValDef]] = lifted(vd)
161172
}
162173
}

plugin-tests/src/test/scala/com/olegpy/bm4/TestImplicitPatterns.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@ class TestImplicitPatterns extends FreeSpec {
5858
}
5959

6060
"with multiple implicit variables" - {
61+
"= bindings after non-implicit = bindings" in {
62+
case class One()
63+
case class Two()
64+
case class Three()
65+
66+
def dummy(): Int = 42
67+
def foo(implicit a: Two): Three = Three()
68+
69+
for {
70+
_ <- Option(1)
71+
implicit0(one: One) <- Option(One())
72+
x = dummy()
73+
implicit0(two: Two) = Two()
74+
_ = foo
75+
} yield "ok"
76+
}
77+
6178
"mixed bindings" in {
6279
for {
6380
_ <- Option("dummy")

0 commit comments

Comments
 (0)