Scala 2.12 tells me Stack is deprecated, how to replace it exactly (and why I don't see the proper warning in IntelliJ)

intellij-idea, scala

Solution

Deprecated message

In general, when there are deprecated functions you see only the general response you saw. To get the detailed message you should compile with -deprecation. To change this use settings-> build, execution, deployment -> compiler -> scala compiler and check the relevant options (deprecation warnings in your case but most of the rest are probably a good idea)

Reference must be prefixed warning

This is a completely unrelated warning. When using mutable classes, the scala style is to prefix it using mutable. i.e. use this:

import collection.mutable    
val a = new mutable.Stack[Int]

instead of

import collection.mutable.Stack    
val a = new Stack[Int]

This is because the default mindset in scala should generally be to use immutable collections unless you have a good reason to do otherwise.

If this bothers you, you can always turn off this inspection.

What to do instead of stack

The reason stack was removed is that it is simply a wrapper around list. Push is simply adding a new head and pop is simply taking the tail.

This means that if you have:

val a = new mutable.Stack
a.push(XXX)
a.pop(XXX)

you can replace it with:

var a = new List
a = XXX +: a
a = a.tail

Note that in general, you can use immutable list here.

EDIT

Just to make sure it is more understandable, the List created in var a = new List should be replaced with an actual choice of list.

The standard way would be to use the standard scala creation methods e.g.:

var a = List[Int]()  
var a: List[Int] = Nil 

but it is also possible to choose another concrete list as needed if more functionality is required.

Problem

I setup a Scala project and add this snippet from http://www.scalatest.org/ ``` import collection.mutable.Stack import org.scalatest._ class ExampleSpec extends FlatSpec with Matchers { "A Stack" should "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() should be (2) stack.pop() should be (1) } it should "throw NoSuchElementException if an empty stack is popped" in { val emptyStack = new Stack[Int] a [NoSuchElementException] should be thrownBy { emptyStack.pop() } } } ``` and IntelliJ (IDEA 2017.1.2) is showing me a warning for the usage of `new Stack[Int]`: Searching for the warning showed me this issue: https://issues.scala-lang.org/browse/SI-9068 But I still have these questions: I get a popup which is splitted into two areas. Does it mean that there are two warnings, each with 2 lines. What is the real information? For the second area I see Reference must be prefixed and Under construction. Why I don't see the proper deprecated warning, like it was added here: https://github.com/scala/scala/pull/5260/files#diff-1ab096eae7e5571b6410a123567aac0aR57 On github/API docs they sai: `Use a List assigned to a var instead` But I can't just replace `Stack` with `List`, because `.push()` is not available for that class. Or should I switch to the List API completely? And what's the difference between assigning the list with `var` or `val`? Can't I add items for instance via `list.add(2)` even if it was assigned with `val`? I installed Scala 2.12.2 via Homebrew. I'm not sure if I'm IntelliJ it is using its own version, because I needed to download it via IntelliJ as well, but anyway it's the same version, so me setup looks like this: BTW: in the terminal / Scala REPL I get this output ``` scala> val stack = new Stack[Int] <console>:14: warning: class Stack in package mutable is deprecated (since 2.12.0): Stack is an inelegant and potentially poorly-performing wrapper around List. Use a List assigned to a var instead. val stack = new Stack[Int] ^ ``` So the proper deprecation warning seems to work there.

Original source

Related problems