6
votes

According to http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#volatile-types, types are volatile when they adhere to specific conditions. Is it possible to make a type volatile (e.g. by an annotation) which is not of that form? What possible alternatives are there?

My use case is the following: I want to write a library, which exposes types A and B with A <: B and B is volatile. Then as a user of this library, I want to be able to overwrite a value of type A with one of type B:

trait TraitB {
  def doSomething: Unit
}

trait Library {
  type A
  type B <: A with TraitB
}

object LibraryUser {
  val library: Library = ???

  trait T {
    val x: library.A
  }

  object U extends T {
    val x: library.B = ???
  }
}

This fails with the error:

error: overriding value x in trait T of type LibraryUser.library.A; value x has a volatile type; cannot override a member with non-volatile type

But when I make A volatile, this succeeds. Currently, I make A volatile by making it a subclass of an abstract type Abstract which will just be Any in the implementation and otherwise not used:

trait TraitB {
  def doSomething: Unit
}

trait Library2 {
  protected type Abstract
  type A <: Any with Abstract
  type B <: A with TraitB
}

trait Library2ImplementationHelper {
  this: Library2 =>
  override type Abstract = Any
}

object Library2User {
  val library: Library2 = ???

  trait T {
    val x: library.A
  }

  object U extends T {
    val x: library.B = ???
  }
}

This compiles and works fine, but Abstract is a little bit artificial and I wonder if there's an other way.

1

1 Answers

-2
votes

You are looking for the @volatile annotation, which will let the compiler know the var should be volatile. It should behave the same way as the equivalent Java annotation.

We can prove this by building a simple class in a file SoVolatile.scala:

class SoVolatile {
  @volatile var boom = 5
}

Then on the command line, go to the directory with that class and run:

$ scalac SoVolatile.scala
$ javap -verbose -private SoVolatile

Inside that we find the line private volatile int boom;. This is a little easier to find if you run this on the command line:

$ javap -verbose -private SoVolatile | grep "private volatile"