FIR: introduce ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL diagnostics

This commit is contained in:
Mikhail Glukhikh
2021-07-23 16:17:36 +03:00
committed by teamcityserver
parent 2397650c24
commit 391c4db87c
21 changed files with 107 additions and 443 deletions
@@ -1,128 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
interface SuperInterface
@kotlin.coroutines.RestrictsSuspension
open class RestrictedController : SuperInterface
class SubClass : RestrictedController()
suspend fun Any?.extAny() {}
suspend fun SuperInterface.extSuper() {}
suspend fun RestrictedController.ext() {}
suspend fun SubClass.extSub() {}
class A {
suspend fun Any?.memExtAny() {}
suspend fun SuperInterface.memExtSuper() {}
suspend fun RestrictedController.memExt() {}
suspend fun SubClass.memExtSub() {}
}
fun generate1(f: suspend SuperInterface.() -> Unit) {}
fun generate2(f: suspend RestrictedController.() -> Unit) {}
fun generate3(f: suspend SubClass.() -> Unit) {}
fun A.test() {
generate1 {
extAny()
memExtAny()
extSuper()
memExtSuper()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
}
}
generate2 {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
}
}
generate3 {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
extSub()
memExtSub()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
extSub()
memExtSub()
}
}
suspend fun SuperInterface.fun1() {
extAny()
memExtAny()
extSuper()
memExtSuper()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
}
}
suspend fun RestrictedController.fun2() {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
}
}
suspend fun SubClass.fun3() {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
extSub()
memExtSub()
with(A()) {
extAny()
memExtAny()
extSuper()
memExtSuper()
ext()
memExt()
extSub()
memExtSub()
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
interface SuperInterface
@@ -1,61 +0,0 @@
// SKIP_TXT
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {
suspend fun member() {
ext()
member()
memberExt()
}
suspend fun RestrictedController.memberExt() {
ext()
member()
memberExt()
}
}
suspend fun RestrictedController.ext() {
ext()
member()
memberExt()
}
fun generate(c: suspend RestrictedController.() -> Unit) {}
fun runBlocking(x: suspend () -> Unit) {}
fun test() {
generate a@{
ext()
member()
memberExt()
this@a.ext()
this@a.member()
this@a.memberExt()
generate b@{
ext()
member()
memberExt()
this@a.ext()
this@a.member()
this@a.memberExt()
this@b.ext()
this@b.member()
this@b.memberExt()
}
runBlocking {
ext()
member()
memberExt()
this@a.ext()
this@a.member()
this@a.memberExt()
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// SKIP_TXT
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {
@@ -1,71 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
interface SuperInterface
@kotlin.coroutines.RestrictsSuspension
open class RestrictedController : SuperInterface
class SubClass : RestrictedController()
suspend fun topLevel() {}
class A {
suspend fun member() {}
}
fun generate1(f: suspend SuperInterface.() -> Unit) {}
fun generate2(f: suspend RestrictedController.() -> Unit) {}
fun generate3(f: suspend SubClass.() -> Unit) {}
fun A.test() {
generate1 {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
generate2 {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
generate3 {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
suspend fun SuperInterface.fun1() {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
suspend fun RestrictedController.fun2() {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
suspend fun SubClass.fun3() {
topLevel()
member()
with(A()) {
topLevel()
member()
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
interface SuperInterface
@@ -1,99 +0,0 @@
// !LANGUAGE: +ReleaseCoroutines +ExperimentalBuilderInference
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// SKIP_TXT
@file:OptIn(ExperimentalTypeInference::class)
import kotlin.experimental.ExperimentalTypeInference
@kotlin.coroutines.RestrictsSuspension
class RestrictedController<T> {
suspend fun yield(x: T) {}
suspend fun anotherYield(x: T) {
yield(x)
this.yield(x)
yield2(x)
this.yield2(x)
with(this) {
yield(x)
this@with.yield(x)
yield2(x)
this@with.yield2(x)
}
}
}
fun <T> buildSequence(@BuilderInference c: suspend RestrictedController<T>.() -> Unit) {}
@BuilderInference
suspend fun <T> RestrictedController<T>.yield2(x: T) {}
fun test() {
buildSequence<Int> a@{
buildSequence<Int> b@{
yield(1)
yield2(1)
this@b.yield(1)
this@b.yield2(1)
this@a.yield(2) // Should be error
this@a.yield2(2) // Should be error
with(this) {
yield(3)
this@with.yield(3)
yield2(3)
this@with.yield2(3)
}
}
}
buildSequence<Int> {
buildSequence<String> {
yield("a")
yield2("a")
this.yield("b")
this.yield2("b")
yield(1) // Should be error
yield2(1) // Should be error
with(this) {
yield("")
this@with.yield("")
yield2("")
this@with.yield2("")
}
}
}
buildSequence<Int> a@{
yield(1)
yield2(1)
buildSequence {
yield("")
yield2("")
this@a.yield(1)
this@a.yield2(1)
with(this) {
yield("")
this@with.yield("")
yield2("")
this@with.yield2("")
}
}
}
buildSequence<String> {
yield("")
RestrictedController<String>().yield("1")
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +ReleaseCoroutines +ExperimentalBuilderInference
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// SKIP_TXT
@@ -1,52 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {
suspend fun member() {}
}
suspend fun RestrictedController.extension() {}
fun generate(f: suspend RestrictedController.() -> Unit) {}
fun test() {
generate() l@ {
member()
extension()
this.member()
this.extension()
val foo = this
foo.member()
foo.extension()
this@l.member()
this@l.extension()
with(1) {
this@l.member()
this@l.extension()
}
}
}
suspend fun RestrictedController.l() {
member()
extension()
this.member()
this.extension()
val foo = this
foo.member()
foo.extension()
this@l.member()
this@l.extension()
with(1) {
this@l.member()
this@l.extension()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {
@@ -1,14 +0,0 @@
@kotlin.coroutines.RestrictsSuspension
class RestrictedController
suspend fun Any?.extFun() {}
suspend fun suspendFun() {}
fun generate(c: suspend RestrictedController.() -> Unit) {}
fun test() {
generate {
extFun()
suspendFun()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@kotlin.coroutines.RestrictsSuspension
class RestrictedController
@@ -1,17 +0,0 @@
// SKIP_TXT
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {
suspend fun yield() {}
}
fun generate(c: suspend RestrictedController.() -> Unit) {}
fun runBlocking(x: suspend () -> Unit) {}
fun test() {
generate {
runBlocking {
yield()
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// SKIP_TXT
@kotlin.coroutines.RestrictsSuspension
class RestrictedController {