Skip to content

iterableOnceExtensionMethods is being inserted unnecessarily, causing deprecation warnings #14244

Open
@nafg

Description

@nafg

(accidentally filed first at scala/bug#12521)

Compiler version

3.0.2 and 3.1.0 (it works in 2.13.7)

Minimized code

(SBT / REPL session with -Xprint:typer provided below)

import scala.scalajs.js
def d = js.Dictionary.empty[Int]                                                                                                                                                                                                                     
def e = d.map(_.toString)
def f = js.Any.wrapDictionary(d).map(_.toString)

Output (REPL)

def d: scala.scalajs.js.Dictionary[Int]

-- Deprecation Warning:
1 |def e = d.map(_.toString)
  |        ^^^^^
  |method map in class IterableOnceExtensionMethods is deprecated since 2.13.0: Use .iterator.map instead or consider requiring an Iterable
def e: IterableOnce[String]

def f: scala.collection.mutable.Iterable[String]
Edited SBT / REPL session with -Xprint:typer
sbt:simpleFacade> set Compile/consoleQuick/scalacOptions += "-Xprint:typer"
[info] Defining Compile / consoleQuick / scalacOptions
[info] The new value will be used by Compile / consoleQuick
[info] Reapplying settings...
[info] set current project to simpleFacade (in build file:/home/naftoli/dev/github.com/nafg/scalajs-facades/)
sbt:simpleFacade> ++ 3.1.0
[info] Setting Scala version to 3.1.0 on 11 projects.
[info] Reapplying settings...
[info] set current project to simpleFacade (in build file:/home/naftoli/dev/github.com/nafg/scalajs-facades/)
sbt:simpleFacade> consoleQuick
Welcome to Scala 3.1.0 (17.0.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                                                                                                     
scala> import scala.scalajs.js
-- Info:
[[syntax trees at end of                     typer]] // rs$line$1
package repl {
  final lazy module val rs$line$1: repl.rs$line$1 = new repl.rs$line$1()
  final module class rs$line$1() extends Object() { this: repl.rs$line$1.type =>
    import scala.scalajs.js
  }
}

                                                                                                                                                                                                                     
scala> def d = js.Dictionary.empty[Int]
-- Info:
[[syntax trees at end of                     typer]] // rs$line$2
package repl {
  final lazy module val rs$line$2: repl.rs$line$2 = new repl.rs$line$2()
  final module class rs$line$2() extends Object() { this: repl.rs$line$2.type =>
    def d: scala.scalajs.js.Dictionary[Int] = scalajs.js.Dictionary.empty[Int]
  }
}

def d: scala.scalajs.js.Dictionary[Int]
                                                                                                                                                                                                                     
scala> def e = d.map(_.toString)
-- Info:
[[syntax trees at end of                     typer]] // rs$line$3
package repl {
  final lazy module val rs$line$3: repl.rs$line$3 = new repl.rs$line$3()
  final module class rs$line$3() extends Object() { this: repl.rs$line$3.type =>
    def e: IterableOnce[String] = 
      scala.collection.IterableOnce.iterableOnceExtensionMethods[(String, Int)](
        scala.scalajs.js.Any.wrapDictionary[Int](d)
      ).map[String](
        {
          def $anonfun(_$1: (String, Int)): String = _$1.toString()
          closure($anonfun)
        }
      )
  }
}

-- Deprecation Warning:
1 |def e = d.map(_.toString)
  |        ^^^^^
  |method map in class IterableOnceExtensionMethods is deprecated since 2.13.0: Use .iterator.map instead or consider requiring an Iterable
def e: IterableOnce[String]
                                                                                                                                                                                                                     
scala> def f = js.Any.wrapDictionary(d).map(_.toString)
-- Info:
[[syntax trees at end of                     typer]] // rs$line$4
package repl {
  final lazy module val rs$line$4: repl.rs$line$4 = new repl.rs$line$4()
  final module class rs$line$4() extends Object() { this: repl.rs$line$4.type =>
    def f: scala.collection.mutable.Iterable[String] = 
      scalajs.js.Any.wrapDictionary[Int](d).map[String](
        {
          def $anonfun(_$1: (String, Int)): String = _$1.toString()
          closure($anonfun)
        }
      )
  }
}

def f: scala.collection.mutable.Iterable[String]

Expectation

There should be no warning for e, just like for f and just like e in Scala 2.12

As you can see in the REPL session, once wrapDictionary is inserted there is no need for iterableOnceExtensionMethods. Yet when the compiler inserts the former it somehow inserts the latter too. This results in the warnings like you can see when defining e.

Also, if instead of .map(_.toString) I pass certain other functions I get different results. For instance x => x and _.swap do not produce a warning or involve iterableOnceExtensionMethods. I think the pattern is that if it's producing a Map (returning a Tuple2) it is okay and if it returns something else it warns.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions