Skip to content

Commit

Permalink
Get rid of compilation warnings in tests and tools using Scala 3 (sca…
Browse files Browse the repository at this point in the history
…la-native#2966)

* Extract UnboxEntry class from local scope of Hashtable.entrySet
* Extract local class from ArrayTest
* Reenable fatal warnigns for JVM tests, accept warnings when compiling native tests
* Fix handling deprecations in tools for Scala3
* Supress more warning in tests using Scala3
  • Loading branch information
WojciechMazur committed Oct 31, 2022
1 parent d8fd989 commit 396c163
Show file tree
Hide file tree
Showing 38 changed files with 158 additions and 141 deletions.
24 changes: 12 additions & 12 deletions javalib/src/main/scala/java/util/Hashtable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,20 @@ class Hashtable[K, V] private (inner: mutable.HashMap[Box[Any], V])
b
}

def entrySet(): ju.Set[ju.Map.Entry[K, V]] = {
class UnboxedEntry(
private[UnboxedEntry] val boxedEntry: ju.Map.Entry[Box[Any], V]
) extends ju.Map.Entry[K, V] {
def getKey(): K = boxedEntry.getKey().inner.asInstanceOf[K]
def getValue(): V = boxedEntry.getValue()
def setValue(value: V): V = boxedEntry.setValue(value)
override def equals(o: Any): Boolean = o match {
case o: UnboxedEntry => boxedEntry.equals(o.boxedEntry)
case _ => false
}
override def hashCode(): Int = boxedEntry.hashCode()
private class UnboxedEntry(
private[UnboxedEntry] val boxedEntry: ju.Map.Entry[Box[Any], V]
) extends ju.Map.Entry[K, V] {
def getKey(): K = boxedEntry.getKey().inner.asInstanceOf[K]
def getValue(): V = boxedEntry.getValue()
def setValue(value: V): V = boxedEntry.setValue(value)
override def equals(o: Any): Boolean = o match {
case o: UnboxedEntry => boxedEntry.equals(o.boxedEntry)
case _ => false
}
override def hashCode(): Int = boxedEntry.hashCode()
}

def entrySet(): ju.Set[ju.Map.Entry[K, V]] = {
val entries = new LinkedHashSet[ju.Map.Entry[K, V]]
inner.foreach {
case (key, value) =>
Expand Down
30 changes: 13 additions & 17 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,25 +87,21 @@ object Build {
.settings(
libraryDependencies ++= Deps.Tools(scalaVersion.value),
Test / fork := true,
scalacOptions := {
val prev = scalacOptions.value
scalacOptions ++= {
val scala213StdLibDeprecations = Seq(
// In 2.13 lineStream_! was replaced with lazyList_!.
"method lineStream_!",
// OpenHashMap is used with value class parameter type, we cannot replace it with AnyRefMap or LongMap
// Should not be replaced with HashMap due to performance reasons.
"class|object OpenHashMap",
"class Stream"
).map(msg => s"-Wconf:cat=deprecation&msg=$msg:s")
CrossVersion
.partialVersion(scalaVersion.value)
.fold(prev) {
case (2, 11 | 12) => prev
case (2, 13) =>
// 2.13 and 2.11 tools are only used in partest.
// It looks like it's impossible to provide alternative sources - it fails to compile plugin sources,
// before attaching them to other build projects. We disable unsolvable fatal-warnings with filters below
prev ++ Seq(
// In 2.13 lineStream_! was replaced with lazyList_!.
"-Wconf:cat=deprecation&msg=lineStream_!:s",
// OpenHashMap is used with value class parameter type, we cannot replace it with AnyRefMap or LongMap
// Should not be replaced with HashMap due to performance reasons.
"-Wconf:cat=deprecation&msg=OpenHashMap:s"
)
case _ =>
prev.diff(Seq("-Xfatal-warnings"))
.fold(Seq.empty[String]) {
case (2, 11 | 12) => Nil
case (2, 13) => scala213StdLibDeprecations
case (3, _) => scala213StdLibDeprecations
}
},
// Running tests in parallel results in `FileSystemAlreadyExistsException`
Expand Down
4 changes: 1 addition & 3 deletions project/MultiScalaProject.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ final case class MultiScalaProject private (
lazy val v2_11: Project = project("2.11")
lazy val v2_12: Project = project("2.12")
lazy val v2_13: Project = project("2.13")
lazy val v3: Project = project("3").settings(
scalacOptions -= "-Xfatal-warnings"
)
lazy val v3: Project = project("3")

override def componentProjects: Seq[Project] = Seq(v2_11, v2_12, v2_13, v3)

Expand Down
10 changes: 9 additions & 1 deletion project/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,15 @@ object Settings {
lazy val testsCommonSettings = Def.settings(
scalacOptions -= "-deprecation",
scalacOptions ++= Seq("-deprecation:false"),
scalacOptions -= "-Xfatal-warnings",
scalacOptions --= {
if (
// Disable fatal warnings when
// Scala 3, becouse null.isInstanceOf[String] warning cannot be supressed
scalaVersion.value.startsWith("3.") ||
// Scala Native - due to specific warnings for unsafe ops in IssuesTest
!moduleName.value.contains("jvm")) Seq("-Xfatal-warnings")
else Nil
},
Test / testOptions ++= Seq(
Tests.Argument(TestFrameworks.JUnit, "-a", "-s", "-v")
),
Expand Down
2 changes: 1 addition & 1 deletion tools/src/main/scala/scala/scalanative/checker/Check.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ final class Check(implicit linked: linker.Result) {
}

def checkMethod(meth: Method): Unit = {
val Type.Function(_, methRetty) = meth.ty
val Type.Function(_, methRetty) = meth.ty: @unchecked
retty = methRetty

val insts = meth.insts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private[codegen] abstract class AbstractCodeGen(
)(implicit sb: ShowBuilder): Unit = {
import sb._

val Type.Function(argtys, retty) = sig
val Type.Function(argtys, retty) = sig: @unchecked

val isDecl = insts.isEmpty

Expand Down Expand Up @@ -323,7 +323,8 @@ private[codegen] abstract class AbstractCodeGen(
str(edge.from.splitCount)
}
def genUnwindEdge(unwind: Next.Unwind): Unit = {
val Next.Unwind(Val.Local(exc, _), Next.Label(_, vals)) = unwind
val Next.Unwind(Val.Local(exc, _), Next.Label(_, vals)) =
unwind: @unchecked
genJustVal(vals(n))
str(", %")
genLocal(exc)
Expand Down Expand Up @@ -505,7 +506,7 @@ private[codegen] abstract class AbstractCodeGen(
case Global.None =>
unsupported(g)
case Global.Member(_, sig) if sig.isExtern =>
val Sig.Extern(id) = sig.unmangled
val Sig.Extern(id) = sig.unmangled: @unchecked
id
case _ =>
"_S" + g.mangle
Expand Down Expand Up @@ -774,7 +775,7 @@ private[codegen] abstract class AbstractCodeGen(
import sb._
call match {
case Op.Call(ty, Val.Global(pointee, _), args) if lookup(pointee) == ty =>
val Type.Function(argtys, _) = ty
val Type.Function(argtys, _) = ty: @unchecked

touch(pointee)

Expand All @@ -801,7 +802,7 @@ private[codegen] abstract class AbstractCodeGen(
}

case Op.Call(ty, ptr, args) =>
val Type.Function(_, resty) = ty
val Type.Function(_, resty) = ty: @unchecked

val pointee = fresh()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object GenerateReflectiveProxies {
implicit val fresh: Fresh = Fresh()

private def genReflProxy(defn: Defn.Define): Defn.Define = {
val Global.Member(owner, sig) = defn.name
val Global.Member(owner, sig) = defn.name: @unchecked
val defnType = defn.ty.asInstanceOf[Type.Function]
implicit val pos: Position = defn.pos

Expand Down
22 changes: 11 additions & 11 deletions tools/src/main/scala/scala/scalanative/codegen/Lower.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ object Lower {

override def onDefn(defn: Defn): Defn = defn match {
case defn: Defn.Define =>
val Type.Function(_, ty) = defn.ty
val Type.Function(_, ty) = defn.ty: @unchecked
ScopedVar.scoped(
fresh := Fresh(defn.insts)
) {
Expand Down Expand Up @@ -431,7 +431,7 @@ object Lower {
) = {
import buf._
val v = genVal(buf, obj)
val FieldRef(cls: Class, fld) = name
val FieldRef(cls: Class, fld) = name: @unchecked

val layout = meta.layout(cls)
val ty = layout.struct
Expand Down Expand Up @@ -462,7 +462,7 @@ object Lower {
def genFieldOp(buf: Buffer, n: Local, op: Op)(implicit
pos: Position
) = {
val Op.Field(obj, name) = op
val Op.Field(obj, name) = op: @unchecked
val elem = genFieldElemOp(buf, obj, name)
buf.let(n, Op.Copy(elem), unwind)
}
Expand Down Expand Up @@ -766,7 +766,7 @@ object Lower {
def genClassallocOp(buf: Buffer, n: Local, op: Op.Classalloc)(implicit
pos: Position
): Unit = {
val Op.Classalloc(ClassRef(cls)) = op
val Op.Classalloc(ClassRef(cls)) = op: @unchecked

val size = MemoryLayout.sizeOf(layout(cls).struct, is32BitPlatform)
val allocMethod =
Expand Down Expand Up @@ -888,7 +888,7 @@ object Lower {
// the case when the divisor is zero and fail gracefully
// by throwing an arithmetic exception.
def checkDivisionByZero(op: Op.Bin): Unit = {
val Op.Bin(bin, ty: Type.I, dividend, divisor) = op
val Op.Bin(bin, ty: Type.I, dividend, divisor) = op: @unchecked

val thenL, elseL = fresh()

Expand Down Expand Up @@ -921,7 +921,7 @@ object Lower {
// which computes both quotient and remainder at once
// and quotient can overflow.
def checkDivisionOverflow(op: Op.Bin): Unit = {
val Op.Bin(bin, ty: Type.I, dividend, divisor) = op
val Op.Bin(bin, ty: Type.I, dividend, divisor) = op: @unchecked

val mayOverflowL, noOverflowL, didOverflowL, resultL = fresh()

Expand Down Expand Up @@ -967,7 +967,7 @@ object Lower {
// Shifts are undefined if the bits shifted by are >= bits in the type.
// We mask the right hand side with bits in type - 1 to make it defined.
def maskShift(op: Op.Bin) = {
val Op.Bin(_, ty: Type.I, _, r) = op
val Op.Bin(_, ty: Type.I, _, r) = op: @unchecked
val mask = ty match {
case Type.Int => Val.Int(31)
case Type.Long => Val.Int(63)
Expand Down Expand Up @@ -1254,7 +1254,7 @@ object Lower {

val arrayAlloc = Type.typeToArray.map {
case (ty, arrname) =>
val Global.Top(id) = arrname
val Global.Top(id) = arrname: @unchecked
val arrcls = Type.Ref(arrname)
ty -> Global.Member(
Global.Top(id + "$"),
Expand All @@ -1263,15 +1263,15 @@ object Lower {
}.toMap
val arrayAllocSig = Type.typeToArray.map {
case (ty, arrname) =>
val Global.Top(id) = arrname
val Global.Top(id) = arrname: @unchecked
ty -> Type.Function(
Seq(Type.Ref(Global.Top(id + "$")), Type.Int),
Type.Ref(arrname)
)
}.toMap
val arraySnapshot = Type.typeToArray.map {
case (ty, arrname) =>
val Global.Top(id) = arrname
val Global.Top(id) = arrname: @unchecked
val arrcls = Type.Ref(arrname)
ty -> Global.Member(
Global.Top(id + "$"),
Expand All @@ -1280,7 +1280,7 @@ object Lower {
}.toMap
val arraySnapshotSig = Type.typeToArray.map {
case (ty, arrname) =>
val Global.Top(id) = arrname
val Global.Top(id) = arrname: @unchecked
ty -> Type.Function(
Seq(Type.Ref(Global.Top(id + "$")), Type.Int, Type.Ptr),
Type.Ref(arrname)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class TraitDispatchTable(meta: Metadata) {
var bucket = size
while (bucket <= maxSize) {
if (free(bucket).nonEmpty) {
val head :: tail = free(bucket)
val head :: tail = free(bucket): @unchecked
free(bucket) = tail
val leftoverSize = bucket - size
if (leftoverSize != 0) {
Expand Down
15 changes: 7 additions & 8 deletions tools/src/main/scala/scala/scalanative/interflow/Eval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,16 @@ trait Eval { self: Interflow =>
Next.Label(defaultTarget, defaultArgs.map(eval))
eval(scrut) match {
case value if value.isCanonical =>
cases
val next = cases
.collectFirst {
case Next.Case(caseValue, Next.Label(caseTarget, caseArgs))
if caseValue == value =>
val evalArgs = caseArgs.map(eval)
val next = Next.Label(caseTarget, evalArgs)
return Inst.Jump(next)
}
.getOrElse {
return Inst.Jump(defaultNext)
next
}
.getOrElse(defaultNext)
return Inst.Jump(next)
case scrut =>
return Inst.Switch(materialize(scrut), defaultNext, cases)
}
Expand Down Expand Up @@ -438,10 +437,10 @@ trait Eval { self: Interflow =>
case Op.Var(ty) =>
Val.Local(state.newVar(ty), Type.Var(ty))
case Op.Varload(slot) =>
val Val.Local(local, _) = eval(slot)
val Val.Local(local, _) = eval(slot): @unchecked
state.loadVar(local)
case Op.Varstore(slot, value) =>
val Val.Local(local, _) = eval(slot)
val Val.Local(local, _) = eval(slot): @unchecked
state.storeVar(local, eval(value))
Val.Unit
case _ => util.unreachable
Expand Down Expand Up @@ -957,7 +956,7 @@ trait Eval { self: Interflow =>
}

def isPureModuleCtor(defn: Defn.Define): Boolean = {
val Inst.Label(_, Val.Local(self, _) +: _) = defn.insts.head
val Inst.Label(_, Val.Local(self, _) +: _) = defn.insts.head: @unchecked

val canStoreTo = mutable.Set(self)
val arrayLength = mutable.Map.empty[Local, Int]
Expand Down
8 changes: 4 additions & 4 deletions tools/src/main/scala/scala/scalanative/interflow/Inline.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ trait Inline { self: Interflow =>
}

def adapt(args: Seq[Val], sig: Type)(implicit state: State): Seq[Val] = {
val Type.Function(argtys, _) = sig
val Type.Function(argtys, _) = sig: @unchecked

// Varargs signature might appear to have less
// argument types than arguments at the call site.
Expand Down Expand Up @@ -143,7 +143,7 @@ trait Inline { self: Interflow =>
case _: build.Mode.Release =>
getDone(name)
}
val Type.Function(_, origRetTy) = defn.ty
val Type.Function(_, origRetTy) = defn.ty: @unchecked

val inlineArgs = adapt(args, defn.ty)
val inlineInsts = defn.insts.toArray
Expand Down Expand Up @@ -198,7 +198,7 @@ trait Inline { self: Interflow =>
rest
.collectFirst {
case block if block.cf.isInstanceOf[Inst.Ret] =>
val Inst.Ret(value) = block.cf
val Inst.Ret(value) = block.cf: @unchecked
emit ++= block.toInsts().init
(value, block.end)
}
Expand All @@ -210,7 +210,7 @@ trait Inline { self: Interflow =>
state.emit ++= emit
state.inherit(endState, res +: args)

val Type.Function(_, retty) = defn.ty
val Type.Function(_, retty) = defn.ty: @unchecked
adapt(res, retty)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ trait Intrinsics { self: Interflow =>
state: State,
origPos: Position
): Option[Val] = {
val Global.Member(_, sig) = name
val Global.Member(_, sig) = name: @unchecked

val args = rawArgs.map(eval)

Expand Down Expand Up @@ -145,11 +145,11 @@ trait Intrinsics { self: Interflow =>
}
case _ if arrayApplyIntrinsics.contains(name) =>
val Seq(arr, idx) = rawArgs
val Type.Function(_, elemty) = ty
val Type.Function(_, elemty) = ty: @unchecked
Some(eval(Op.Arrayload(elemty, arr, idx)))
case _ if arrayUpdateIntrinsics.contains(name) =>
val Seq(arr, idx, value) = rawArgs
val Type.Function(Seq(_, _, elemty), _) = ty
val Type.Function(Seq(_, _, elemty), _) = ty: @unchecked
Some(eval(Op.Arraystore(elemty, arr, idx, value)))
case _ if name == arrayLengthIntrinsic =>
val Seq(arr) = rawArgs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ final class MergeProcessor(
// we must merge them together using a synthetic block.
if (doInline && retMergeBlocks.size > 1) {
val tys = retMergeBlocks.map { block =>
val Inst.Ret(v) = block.cf
val Inst.Ret(v) = block.cf: @unchecked
implicit val state: State = block.end
v match {
case InstanceRef(ty) => ty
Expand All @@ -443,7 +443,7 @@ final class MergeProcessor(
// Update all returning blocks to jump to result block,
// and update incoming/outgoing edges to include result block.
retMergeBlocks.foreach { block =>
val Inst.Ret(v) = block.cf
val Inst.Ret(v) = block.cf: @unchecked
block.cf = Inst.Jump(Next.Label(syntheticLabel.name, Seq(v)))
block.outgoing(syntheticLabel.name) = resultMergeBlock
resultMergeBlock.incoming(block.label.name) = (Seq(v), block.end)
Expand Down

0 comments on commit 396c163

Please sign in to comment.