-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Port -Wnonunit-statement
setting for dotty
#16936
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
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 198 additions & 0 deletions
198
tests/neg-custom-args/fatal-warnings/nonunit-statement.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
// scalac: -Wnonunit-statement -Wvalue-discard | ||
import collection.ArrayOps | ||
import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} | ||
import concurrent._ | ||
import scala.reflect.ClassTag | ||
|
||
class C { | ||
import ExecutionContext.Implicits._ | ||
def c = { | ||
def improved = Future(42) | ||
def stale = Future(27) | ||
improved // error | ||
stale | ||
} | ||
} | ||
class D { | ||
def d = { | ||
class E | ||
new E().toString // error | ||
new E().toString * 2 | ||
} | ||
} | ||
class F { | ||
import ExecutionContext.Implicits._ | ||
Future(42) // error | ||
} | ||
// unused template expression uses synthetic method of class | ||
case class K(s: String) { | ||
copy() // error | ||
} | ||
// mutations returning this are ok | ||
class Mutate { | ||
val b = ListBuffer.empty[Int] | ||
b += 42 // nowarn, returns this.type | ||
val xs = List(42) | ||
27 +: xs // error | ||
|
||
def f(x: Int): this.type = this | ||
def g(): Unit = f(42) // nowarn | ||
} | ||
// some uninteresting expressions may warn for other reasons | ||
class WhoCares { | ||
null // error for purity | ||
??? // nowarn for impurity | ||
} | ||
// explicit Unit ascription to opt out of warning, even for funky applies | ||
class Absolution { | ||
def f(i: Int): Int = i+1 | ||
import ExecutionContext.Implicits._ | ||
// Future(42): Unit // nowarn { F(42)(ctx) }: Unit where annot is on F(42) | ||
// f(42): Unit // nowarn | ||
} | ||
// warn uni-branched unless user disables it with -Wnonunit-if:false | ||
class Boxed[A](a: A) { | ||
def isEmpty = false | ||
def foreach[U](f: A => U): Unit = | ||
if (!isEmpty) f(a) // error (if) | ||
def forall(f: A => Boolean): Unit = | ||
if (!isEmpty) { | ||
println(".") | ||
f(a) // error (if) | ||
} | ||
def take(p: A => Boolean): Option[A] = { | ||
while (isEmpty || !p(a)) () | ||
Some(a).filter(p) | ||
} | ||
} | ||
class Unibranch[A, B] { | ||
def runWith[U](action: B => U): A => Boolean = { x => | ||
val z = null.asInstanceOf[B] | ||
val fellback = false | ||
if (!fellback) action(z) // error (if) | ||
!fellback | ||
} | ||
def f(i: Int): Int = { | ||
def g = 17 | ||
if (i < 42) { | ||
g // error block statement | ||
println("uh oh") | ||
g // error (if) | ||
} | ||
while (i < 42) { | ||
g // error | ||
println("uh oh") | ||
g // error | ||
} | ||
42 | ||
} | ||
} | ||
class Dibranch { | ||
def i: Int = ??? | ||
def j: Int = ??? | ||
def f(b: Boolean): Int = { | ||
// if-expr might have an uninteresting LUB | ||
if (b) { // error, at least one branch looks interesting | ||
println("true") | ||
i | ||
} | ||
else { | ||
println("false") | ||
j | ||
} | ||
42 | ||
} | ||
} | ||
class Next[A] { | ||
val all = ListBuffer.empty[A] | ||
def f(it: Iterator[A], g: A => A): Unit = | ||
while (it.hasNext) | ||
all += g(it.next()) // nowarn | ||
} | ||
class Setting[A] { | ||
def set = LinkedHashSet.empty[A] | ||
def f(a: A): Unit = { | ||
set += a // error because cannot know whether the `set` was supposed to be consumed or assigned | ||
println(set) | ||
} | ||
} | ||
// neither StringBuilder warns, because either append is Java method or returns this.type | ||
// while loop looks like if branch with block1(block2, jump to label), where block2 typed as non-unit | ||
class Strung { | ||
def iterator = Iterator.empty[String] | ||
def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = { | ||
val jsb = b.underlying | ||
if (start.length != 0) jsb.append(start) // error (value-discard) | ||
val it = iterator | ||
if (it.hasNext) { | ||
jsb.append(it.next()) | ||
while (it.hasNext) { | ||
jsb.append(sep) // nowarn (java) | ||
jsb.append(it.next()) // error (value-discard) | ||
} | ||
} | ||
if (end.length != 0) jsb.append(end) // error (value-discard) | ||
b | ||
} | ||
def f(b: java.lang.StringBuilder, it: Iterator[String]): String = { | ||
while (it.hasNext) { | ||
b.append("\n") // nowarn (java) | ||
b.append(it.next()) // error (value-discard) | ||
} | ||
b.toString | ||
} | ||
def g(b: java.lang.StringBuilder, it: Iterator[String]): String = { | ||
while (it.hasNext) it.next() // error | ||
b.toString | ||
} | ||
} | ||
class J { | ||
import java.util.Collections | ||
def xs: java.util.List[Int] = ??? | ||
def f(): Int = { | ||
Collections.checkedList[Int](xs, classOf[Int]) | ||
42 | ||
} | ||
} | ||
class Variant { | ||
var bs = ListBuffer.empty[Int] | ||
val xs = ListBuffer.empty[Int] | ||
private[this] val ys = ListBuffer.empty[Int] | ||
private[this] var zs = ListBuffer.empty[Int] | ||
def f(i: Int): Unit = { | ||
bs.addOne(i) | ||
xs.addOne(i) | ||
ys.addOne(i) | ||
zs.addOne(i) | ||
println("done") | ||
} | ||
} | ||
final class ArrayOops[A](private val xs: Array[A]) extends AnyVal { | ||
def other: ArrayOps[A] = ??? | ||
def transpose[B](implicit asArray: A => Array[B]): Array[Array[B]] = { | ||
val aClass = xs.getClass.getComponentType | ||
val bb = new ArrayBuilder.ofRef[Array[B]]()(ClassTag[Array[B]](aClass)) | ||
if (xs.length == 0) bb.result() | ||
else { | ||
def mkRowBuilder() = ArrayBuilder.make[B](ClassTag[B](aClass.getComponentType)) | ||
val bs = new ArrayOps(asArray(xs(0))).map((x: B) => mkRowBuilder()) | ||
for (xs <- other) { | ||
var i = 0 | ||
for (x <- new ArrayOps(asArray(xs))) { | ||
bs(i) += x | ||
i += 1 | ||
} | ||
} | ||
for (b <- new ArrayOps(bs)) bb += b.result() | ||
bb.result() | ||
} | ||
} | ||
} | ||
class Depends { | ||
def f[A](a: A): a.type = a | ||
def g() = { | ||
val d = new Depends | ||
f(d) | ||
() | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.