Skip to content

Commit 0a85207

Browse files
authored
Merge pull request #13709 from SethTisue/issue-9880
lint trivially self-recursive extension methods
2 parents 82172ed + f518eaa commit 0a85207

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

compiler/src/dotty/tools/dotc/transform/CheckLoopingImplicits.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ class CheckLoopingImplicits extends MiniPhase:
4646
case Apply(fn, args) =>
4747
checkNotLooping(fn)
4848
fn.tpe.widen match
49-
case mt: MethodType =>
49+
case mt: MethodType
50+
// Boolean && and || aren't defined with by-name parameters
51+
// and therefore their type isn't an ExprType, so we exempt them by symbol name
52+
if t.symbol != defn.Boolean_&& && t.symbol != defn.Boolean_|| =>
5053
args.lazyZip(mt.paramInfos).foreach { (arg, pinfo) =>
5154
if !pinfo.isInstanceOf[ExprType] then checkNotLooping(arg)
5255
}
@@ -80,8 +83,8 @@ class CheckLoopingImplicits extends MiniPhase:
8083
checkNotLooping(t.rhs)
8184
case _ =>
8285

83-
if sym.isOneOf(GivenOrImplicit | Lazy) then
86+
if sym.isOneOf(GivenOrImplicit | Lazy | ExtensionMethod) then
8487
checkNotLooping(mdef.rhs)
8588
mdef
8689
end transform
87-
end CheckLoopingImplicits
90+
end CheckLoopingImplicits
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
opaque type Bytes = Array[Byte]
2+
object Bytes:
3+
extension (self: Bytes)
4+
def size: Int = (self: Array[Byte]).size // error
5+
6+
//
7+
8+
object Module1:
9+
opaque type State[S, +A] = S => (S, A)
10+
object State:
11+
extension [S, A](self: State[S, A])
12+
def map[B](f: A => B): State[S, B] =
13+
s => { val (s2, a) = self(s); (s2, f(a)) }
14+
object Module2:
15+
import Module1.State
16+
trait RNG
17+
opaque type Gen[+A] = State[RNG, A]
18+
object Gen:
19+
extension [A](self: Gen[A])
20+
def map[B](f: A => B): Gen[B] =
21+
self.map(f) // error
22+
23+
//
24+
25+
class Sym(val owner: Sym)
26+
27+
extension (sym: Sym)
28+
def isSomething: Boolean = false
29+
def isFoo: Boolean = sym.isSomething && sym.owner.isFoo // was: Infinite loop in function body
30+
def isBar: Boolean = sym.isSomething || sym.owner.isBar // was: Infinite loop in function body

0 commit comments

Comments
 (0)