Skip to content

Missing warning for Infinite recursive call in object #23277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
drewfeelsblue opened this issue May 28, 2025 · 3 comments · May be fixed by #23278
Open

Missing warning for Infinite recursive call in object #23277

drewfeelsblue opened this issue May 28, 2025 · 3 comments · May be fixed by #23278
Assignees
Labels
area:transform better-errors Issues concerned with improving confusing/unhelpful diagnostic messages itype:enhancement

Comments

@drewfeelsblue
Copy link

Compiler version

3.7.0

reproduced also for nightly version (currently 3.7.2-RC1-bin-20250527-2703b6b-NIGHTLY)

Minimized code

//> using scala 3.7.0

enum Test:
  case One
  case Two(i: Int)

object Test:
  object Two:
    def apply(i: Int): Test.Two = Test.Two(i)


object app extends App:
  Test.Two(1)

Output

run of above code snippet leads to "lock" (execution is stuck)

Expectation

I expected to see at least compiler warning for such code

@drewfeelsblue drewfeelsblue added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 28, 2025
@som-snytt
Copy link
Contributor

som-snytt commented May 28, 2025

enum is not involved, as the method recurses trivially.

It works as

def apply(i: Int): Test.Two = new Test.Two(i)

It's normal to write a custom apply method where one might be generated, such as in a case class companion.

The check in Scala 2 warns for only the most trivial definition:

warning: method g in object Test does nothing other than call itself recursively
  def g: Int = g
               ^
1 warning

Actually, Scala 3 makes an effort now:

7 |  def f(i: Int): Int = f(i)
  |  ^^^^^^^^^^^^^^^^^^^^^^^^^
  |  Infinite recursive call
8 |  def g: Int = g
  |  ^^^^^^^^^^^^^^
  |  Infinite recursive call
2 warnings found

The check in tailrec could be more expansive or forgiving:

    final module class Two() extends Object {
      def apply(i: Int): Test.Two =
        {
          var $this$tailLocal1: (Test.Two : Test.Two) = this
          while <empty> do
            tailLabel1[Unit]:
              return
                {
                  $this$tailLocal1 = Test.Two
                  (return[tailLabel1] ()):Test.Two
                }
        }
    }
    def f(i: Int): Int =
      {
        while <empty> do tailLabel2[Unit]: return (return[tailLabel2] ()):Int
      }

The usual observation is, "No one writes code like that, until they do." What does the A.I. say about it?

@drewfeelsblue
Copy link
Author

ah, I see now, @som-snytt thank you for the reply

so

//> using scala 3.7.0

object Test {
  object Two {
    def apply(i: Int): Test.Two.type = Test.Two(i)
  }
}

object app extends App {
  Test.Two(1)
}

compiles just fine

while

//> using scala 3.7.0

object Test {
  object Two {
    def apply(i: Int): Two.type = Two(i)
  }
}

object app extends App {
  Test.Two(1)
}

warns about recursive call

[warn] Infinite recursive call
[warn]     def apply(i: Int): Two.type = Two(i)
[warn]     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@som-snytt som-snytt linked a pull request May 28, 2025 that will close this issue
@som-snytt som-snytt added itype:enhancement area:transform better-errors Issues concerned with improving confusing/unhelpful diagnostic messages and removed itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 28, 2025
@som-snytt
Copy link
Contributor

The PR warns despite an assignment to this that is a stable (but impure) value; then avoids emitting the assignment for an object.

@som-snytt som-snytt changed the title Conflicting definitions lead to the endless run Missing warning for Infinite recursive call in object May 28, 2025
@som-snytt som-snytt self-assigned this May 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:transform better-errors Issues concerned with improving confusing/unhelpful diagnostic messages itype:enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants