Skip to content

Fix/datarace flags #607

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

Merged
merged 5 commits into from
May 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 25 additions & 30 deletions src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -329,55 +329,50 @@ object ClassfileConstants {
final val impdep1 = 0xfe
final val impdep2 = 0xff

import Flags._
abstract class FlagTranslation {
import Flags._

private var isAnnotation = false
private var isClass = false
private def initFields(flags: Int) = {
isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0
isClass = false
}
protected def baseFlags(jflags: Int) = EmptyFlags
protected def isClass: Boolean = false

private def translateFlag(jflag: Int): FlagSet = (jflag: @switch) match {
case JAVA_ACC_PRIVATE => Private
case JAVA_ACC_PROTECTED => Protected
case JAVA_ACC_FINAL => Final
case JAVA_ACC_SYNTHETIC => Synthetic
case JAVA_ACC_STATIC => JavaStatic
case JAVA_ACC_ABSTRACT => if (isAnnotation) EmptyFlags else if (isClass) Abstract else Deferred
case JAVA_ACC_INTERFACE => if (isAnnotation) EmptyFlags else PureInterfaceCreationFlags | JavaDefined
case JAVA_ACC_ABSTRACT => if (isClass) Abstract else Deferred
case JAVA_ACC_INTERFACE => PureInterfaceCreationFlags | JavaDefined
case _ => EmptyFlags
}

private def addFlag(base: FlagSet, jflag: Int): FlagSet =
if (jflag == 0) base else base | translateFlag(jflag)

private def translateFlags(jflags: Int, baseFlags: FlagSet): FlagSet = {
val nflags =
if ((jflags & JAVA_ACC_ANNOTATION) == 0) jflags
else jflags & ~(JAVA_ACC_ABSTRACT | JAVA_ACC_INTERFACE) // annotations are neither abstract nor interfaces
var res: FlagSet = baseFlags | JavaDefined
res = addFlag(res, jflags & JAVA_ACC_PRIVATE)
res = addFlag(res, jflags & JAVA_ACC_PROTECTED)
res = addFlag(res, jflags & JAVA_ACC_FINAL)
res = addFlag(res, jflags & JAVA_ACC_SYNTHETIC)
res = addFlag(res, jflags & JAVA_ACC_STATIC)
res = addFlag(res, jflags & JAVA_ACC_ABSTRACT)
res = addFlag(res, jflags & JAVA_ACC_INTERFACE)
res = addFlag(res, nflags & JAVA_ACC_PRIVATE)
res = addFlag(res, nflags & JAVA_ACC_PROTECTED)
res = addFlag(res, nflags & JAVA_ACC_FINAL)
res = addFlag(res, nflags & JAVA_ACC_SYNTHETIC)
res = addFlag(res, nflags & JAVA_ACC_STATIC)
res = addFlag(res, nflags & JAVA_ACC_ABSTRACT)
res = addFlag(res, nflags & JAVA_ACC_INTERFACE)
res
}

def classFlags(jflags: Int): FlagSet = {
initFields(jflags)
isClass = true
translateFlags(jflags, EmptyFlags)
}
def fieldFlags(jflags: Int): FlagSet = {
initFields(jflags)
translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) Mutable else EmptyFlags)
}
def methodFlags(jflags: Int): FlagSet = {
initFields(jflags)
translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) Bridge else EmptyFlags)
}
def flags(jflags: Int): FlagSet = translateFlags(jflags, baseFlags(jflags))
}
val classTranslation = new FlagTranslation {
override def isClass = true
}
val fieldTranslation = new FlagTranslation {
override def baseFlags(jflags: Int) = if ((jflags & JAVA_ACC_FINAL) == 0) Mutable else EmptyFlags
}
val methodTranslation = new FlagTranslation {
override def baseFlags(jflags: Int) = if ((jflags & JAVA_ACC_BRIDGE) != 0) Bridge else EmptyFlags
}
object FlagTranslation extends FlagTranslation { }
}
8 changes: 4 additions & 4 deletions src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class ClassfileParser(
def parseClass()(implicit ctx: Context): Option[Embedded] = {
val jflags = in.nextChar
val isAnnotation = hasAnnotation(jflags)
val sflags = FlagTranslation.classFlags(jflags)
val sflags = classTranslation.flags(jflags)
val nameIdx = in.nextChar
currentClassName = pool.getClassName(nameIdx)

Expand Down Expand Up @@ -163,8 +163,8 @@ class ClassfileParser(
val start = indexCoord(in.bp)
val jflags = in.nextChar
val sflags =
if (method) Flags.Method | FlagTranslation.methodFlags(jflags)
else FlagTranslation.fieldFlags(jflags)
if (method) Flags.Method | methodTranslation.flags(jflags)
else fieldTranslation.flags(jflags)
val name = pool.getName(in.nextChar)
if (!(sflags is Flags.Private) || name == nme.CONSTRUCTOR || ctx.settings.optimise.value) {
val member = ctx.newSymbol(
Expand Down Expand Up @@ -632,7 +632,7 @@ class ClassfileParser(
getOwner(jflags),
entry.originalName,
new ClassfileLoader(file),
FlagTranslation.classFlags(jflags),
classTranslation.flags(jflags),
getScope(jflags))
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
19 changes: 19 additions & 0 deletions tests/pos/intersection.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
object intersection {

class A
class B

val x: A => Unit = ???
val y: B => Unit = ???

val z = if (???) x else y

val a: A & B => Unit = z
val b: (A => Unit) | (B => Unit) = z




type needsA = A => Nothing
type needsB = B => Nothing
}
8 changes: 8 additions & 0 deletions tests/pos/jon.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// This one blows up with a huge type in Scala 2.
// Reported by Jon Pretty in his talk on Scala type inference.
object Test {

val x = List(List, Vector)

val y: List[scala.collection.generic.SeqFactory] = x
}
21 changes: 21 additions & 0 deletions tests/pos/pets.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Representing the current type
trait Pet {
type This <: Pet
def name: String
def renamed(newName: String): This
}

case class Fish(name: String, age: Int) extends Pet {
type This = Fish
def renamed(newName: String): Fish = copy(name = newName)
}

case class Kitty(name: String, age: Int) extends Pet {
type This = Kitty
def renamed(newName: String): Kitty = copy(name = newName)
}

object Test {
def esquire[A <: Pet](a: A): a.This = a.renamed(a.name + ", Esq.")
val f: Fish = esquire(new Fish("bob", 22))
}
7 changes: 7 additions & 0 deletions tests/pos/sort.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object sorting {

val xs: Array[String] = ???

java.util.Arrays.sort(xs, ???)

}
7 changes: 7 additions & 0 deletions tests/pos/staleSymbol.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object intersection {

class A
class B

val x: A => Unit = ???
}