FE: forbid extension calls on inline functional parameters
Extension receivers are currently implicitly noinline, and changing that would require modifying the syntax to allow marking them noinline or crossinline. ^KT-5837 Open ^KT-25787 Fixed ^KT-47965 Fixed ^KT-50107 Fixed ^KT-52403 Fixed
This commit is contained in:
+3
-2
@@ -187,7 +187,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
|
||||
if (receiverSymbol in inalienableParameters) {
|
||||
if (!isInvokeOrInlineExtension(targetSymbol)) {
|
||||
reporter.reportOn(
|
||||
qualifiedAccessExpression.source,
|
||||
receiverExpression.source ?: qualifiedAccessExpression.source,
|
||||
FirErrors.USAGE_IS_NOT_INLINABLE,
|
||||
receiverSymbol,
|
||||
context
|
||||
@@ -198,7 +198,8 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
|
||||
|
||||
private fun isInvokeOrInlineExtension(targetSymbol: FirBasedSymbol<*>?): Boolean {
|
||||
if (targetSymbol !is FirNamedFunctionSymbol) return false
|
||||
if (targetSymbol.isInline) return true
|
||||
// TODO: receivers are currently not inline (KT-5837)
|
||||
// if (targetSymbol.isInline) return true
|
||||
return targetSymbol.name == OperatorNameConventions.INVOKE &&
|
||||
targetSymbol.dispatchReceiverType?.isBuiltinFunctionalType(session) == true
|
||||
}
|
||||
|
||||
@@ -238,12 +238,12 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
if (descriptor !is SimpleFunctionDescriptor) {
|
||||
return false
|
||||
}
|
||||
// TODO: receivers are currently not inline (KT-5837)
|
||||
// if (InlineUtil.isInline(descriptor)) return true
|
||||
|
||||
val containingDeclaration = descriptor.getContainingDeclaration()
|
||||
val isInvoke = descriptor.getName() == OperatorNameConventions.INVOKE &&
|
||||
return descriptor.getName() == OperatorNameConventions.INVOKE &&
|
||||
containingDeclaration is ClassDescriptor && containingDeclaration.defaultType.isBuiltinFunctionalType
|
||||
|
||||
return isInvoke || InlineUtil.isInline(descriptor)
|
||||
}
|
||||
|
||||
private fun checkVisibilityAndAccess(
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||
operator inline fun <T, U> Function1<T, U>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s[1]
|
||||
}
|
||||
|
||||
//noinline
|
||||
operator fun <T, U, V> Function2<T, U, V>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>s[1]<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext[1]<!>
|
||||
}
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||
operator inline fun <T, U> Function1<T, U>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s[1]
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>[1]
|
||||
}
|
||||
|
||||
//noinline
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
|
||||
operator fun <T, U> Function1<T, U>.minusAssign(p: Function1<T, U>) {}
|
||||
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
|
||||
this += p
|
||||
p += this
|
||||
}
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
|
||||
this -= <!USAGE_IS_NOT_INLINABLE!>p<!>
|
||||
p <!USAGE_IS_NOT_INLINABLE!>-=<!> this
|
||||
}
|
||||
|
||||
operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {}
|
||||
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
|
||||
this += ext
|
||||
ext += this
|
||||
}
|
||||
|
||||
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {
|
||||
this -= <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext <!USAGE_IS_NOT_INLINABLE!>-=<!> this
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
s += s
|
||||
ext += ext
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
|
||||
operator fun <T, U> Function1<T, U>.minusAssign(p: Function1<T, U>) {}
|
||||
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
|
||||
this += p
|
||||
p += this
|
||||
<!USAGE_IS_NOT_INLINABLE!>p<!> += this
|
||||
}
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
|
||||
@@ -16,7 +17,7 @@ operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minusAssign(ext
|
||||
|
||||
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
|
||||
this += ext
|
||||
ext += this
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> += this
|
||||
}
|
||||
|
||||
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {
|
||||
@@ -25,6 +26,6 @@ inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plusAssi
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
s += s
|
||||
ext += ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> += s
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> += ext
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.compareTo(p: Function1<T, U>) = 1
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s < s
|
||||
s <= s
|
||||
s > s
|
||||
s >= s
|
||||
}
|
||||
|
||||
//noinline
|
||||
operator fun <T, U, V> Function2<T, U, V>.compareTo(index : Function2<T, U, V>) = 1
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.compareTo(index : @ExtensionFunctionType Function3<T, U, V, W>) = 1
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
s <!USAGE_IS_NOT_INLINABLE!><<!> <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s <!USAGE_IS_NOT_INLINABLE!><=<!> <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s <!USAGE_IS_NOT_INLINABLE!>><!> <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s <!USAGE_IS_NOT_INLINABLE!>>=<!> <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
|
||||
ext <!USAGE_IS_NOT_INLINABLE!><<!> <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext <!USAGE_IS_NOT_INLINABLE!>><!> <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext <!USAGE_IS_NOT_INLINABLE!><=<!> <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext <!USAGE_IS_NOT_INLINABLE!>>=<!> <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.compareTo(p: Function1<T, U>) = 1
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s < s
|
||||
s <= s
|
||||
s > s
|
||||
s >= s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> < s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> <= s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> > s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> >= s
|
||||
}
|
||||
|
||||
//noinline
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ inline operator fun <T, U> Function1<T, U>.component1() = 1
|
||||
inline operator fun <T, U> Function1<T, U>.component2() = 2
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
val (d1, e1) = s
|
||||
val (d1, e1) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
}
|
||||
|
||||
operator fun <T, U, V> Function2<T, U, V>.component1() = 1
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
operator inline fun <T, U> Function1<T, U>.contains(p: Function1<T, U>): Boolean {
|
||||
this in p
|
||||
p in this
|
||||
return false
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s in s
|
||||
s !in s
|
||||
}
|
||||
|
||||
|
||||
operator fun <T, U, V> Function2<T, U, V>.contains(p: Function2<T, U, V>): Boolean = false
|
||||
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.contains(ext: @ExtensionFunctionType Function3<T, U, V, W>): Boolean = false
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> U, ext: T.(p: U, l: U) -> V) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> <!USAGE_IS_NOT_INLINABLE!>in<!> s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> <!USAGE_IS_NOT_INLINABLE!>!in<!> s
|
||||
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> <!USAGE_IS_NOT_INLINABLE!>in<!> ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> <!USAGE_IS_NOT_INLINABLE!>!in<!> ext
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
operator inline fun <T, U> Function1<T, U>.contains(p: Function1<T, U>): Boolean {
|
||||
this in p
|
||||
this in <!USAGE_IS_NOT_INLINABLE!>p<!>
|
||||
p in this
|
||||
return false
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s in s
|
||||
s !in s
|
||||
s in <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s !in <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -17,13 +17,13 @@ inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plus(p:
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
s + s
|
||||
ext + ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> + s
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> + ext
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
s + s
|
||||
ext + ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> + s
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> + ext
|
||||
}
|
||||
|
||||
inline fun <T, U> Function1<T, U>.submit() {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.rangeTo(p: Function1<T, U>): ClosedRange<Int> {
|
||||
this..p
|
||||
p..this
|
||||
return 1..2
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s..s
|
||||
s..s
|
||||
}
|
||||
|
||||
|
||||
operator fun <T, U, V> Function2<T, U, V>.rangeTo(p: Function2<T, U, V>): ClosedRange<Int> {
|
||||
return 1..2
|
||||
}
|
||||
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.rangeTo(ext: @ExtensionFunctionType Function3<T, U, V, W>): ClosedRange<Int> {
|
||||
return 1..2
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> U, ext: T.(p: U, l: U) -> V) {
|
||||
s<!USAGE_IS_NOT_INLINABLE!>..<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s<!USAGE_IS_NOT_INLINABLE!>..<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
|
||||
ext<!USAGE_IS_NOT_INLINABLE!>..<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext<!USAGE_IS_NOT_INLINABLE!>..<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
|
||||
inline operator fun <T, U> Function1<T, U>.rangeTo(p: Function1<T, U>): ClosedRange<Int> {
|
||||
this..p
|
||||
p..this
|
||||
<!USAGE_IS_NOT_INLINABLE!>p<!>..this
|
||||
return 1..2
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s..s
|
||||
s..s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>..s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>..s
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
|
||||
infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
|
||||
|
||||
inline infix fun Function1<Int, Unit>.inlineExt2(p: Int) {
|
||||
{
|
||||
noInlineExt(11)
|
||||
this.noInlineExt(11)
|
||||
this noInlineExt 11
|
||||
this
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
{
|
||||
inlineExt2(1)
|
||||
this.inlineExt2(1)
|
||||
this inlineExt2 1
|
||||
this(11)
|
||||
}()
|
||||
}
|
||||
|
||||
inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
|
||||
{
|
||||
s(11)
|
||||
s.invoke(11)
|
||||
s <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
}()
|
||||
}
|
||||
|
||||
inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit) {
|
||||
{
|
||||
s(11)
|
||||
s.invoke(11)
|
||||
s <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
inline fun testExtension(s: (p: Int) -> Unit) {
|
||||
{
|
||||
s.inlineExt()
|
||||
} ()
|
||||
}
|
||||
|
||||
inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) {
|
||||
{
|
||||
s.<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
|
||||
} ()
|
||||
}
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -NON_LOCAL_RETURN_NOT_ALLOWED
|
||||
|
||||
infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
|
||||
@@ -40,7 +41,7 @@ inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit) {
|
||||
|
||||
inline fun testExtension(s: (p: Int) -> Unit) {
|
||||
{
|
||||
s.inlineExt()
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>.inlineExt()
|
||||
} ()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
|
||||
|
||||
infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
|
||||
|
||||
inline infix fun Function1<Int, Unit>.inlineExt2(p: Int) {
|
||||
noInlineExt(11)
|
||||
this.noInlineExt(11)
|
||||
this noInlineExt 11
|
||||
this
|
||||
}
|
||||
|
||||
inline fun Function1<Int, Unit>.inlineExt() {
|
||||
inlineExt2(1)
|
||||
this.inlineExt2(1)
|
||||
this inlineExt2 1
|
||||
}
|
||||
|
||||
inline fun testExtension(s: (p: Int) -> Unit) {
|
||||
s.inlineExt()
|
||||
}
|
||||
|
||||
inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) {
|
||||
s.<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
|
||||
}
|
||||
|
||||
inline fun inlineFunNoInline(noinline s: (p: Int) -> Unit) {
|
||||
s.noInlineExt(11)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE
|
||||
|
||||
infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
|
||||
@@ -16,7 +17,7 @@ inline fun Function1<Int, Unit>.inlineExt() {
|
||||
}
|
||||
|
||||
inline fun testExtension(s: (p: Int) -> Unit) {
|
||||
s.inlineExt()
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>.inlineExt()
|
||||
}
|
||||
|
||||
inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) {
|
||||
|
||||
+8
-8
@@ -11,18 +11,18 @@ inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.inc() = thi
|
||||
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.dec() = this
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
|
||||
+s
|
||||
<!USAGE_IS_NOT_INLINABLE!>-<!>s
|
||||
+<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>++
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!>s
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>--
|
||||
<!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>--<!>s
|
||||
+ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>-<!>ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>--<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
+<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>++
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!>ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>--
|
||||
<!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>--<!>ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>--<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
|
||||
inline fun <T, V> Function1<T, V>.inlineFunWithInvoke() {
|
||||
|
||||
+6
-6
@@ -11,16 +11,16 @@ inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.inc() = thi
|
||||
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.dec() = this
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
|
||||
+s
|
||||
+<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
s++
|
||||
++s
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>++
|
||||
++<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>--
|
||||
--<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
+ext
|
||||
+<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
ext++
|
||||
++ext
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>++
|
||||
++<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>--
|
||||
--<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
inline operator fun <T, V> Function1<T, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V) {
|
||||
!s
|
||||
}
|
||||
|
||||
operator fun <T, U, V> Function2<T, U, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
operator fun <T, U, V, W> @ExtensionFunctionType Function3<T, U, V, W>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: T, l : U) -> V) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>!<!>s
|
||||
<!USAGE_IS_NOT_INLINABLE!>!<!>ext
|
||||
}
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -RECURSION_IN_INLINE
|
||||
inline operator fun <T, V> Function1<T, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V) {
|
||||
!s
|
||||
!<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
}
|
||||
|
||||
operator fun <T, U, V> Function2<T, U, V>.not() : Boolean {
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ inline fun test(crossinline c: () -> Unit) {
|
||||
}
|
||||
}
|
||||
val l = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
suspend fun calculate() = "OK"
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
|
||||
// SKIP_TXT
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import helpers.*
|
||||
|
||||
interface SuspendRunnable {
|
||||
suspend fun run()
|
||||
}
|
||||
|
||||
// Function is NOT suspend
|
||||
// parameter is crossinline
|
||||
// parameter is suspend
|
||||
// Block is NOT allowed to be called inside the body of owner inline function
|
||||
// Block is allowed to be called from nested classes/lambdas (as common crossinlines)
|
||||
// It is NOT possible to call startCoroutine on the parameter
|
||||
// suspend calls possible inside lambda matching to the parameter
|
||||
|
||||
inline fun test(crossinline c: suspend () -> Unit) {
|
||||
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>c<!>()
|
||||
val o = object : SuspendRunnable {
|
||||
override suspend fun run() {
|
||||
c()
|
||||
}
|
||||
}
|
||||
val l: suspend () -> Unit = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
}
|
||||
|
||||
suspend fun calculate() = "OK"
|
||||
|
||||
fun box() {
|
||||
test {
|
||||
calculate()
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
|
||||
// SKIP_TXT
|
||||
// WITH_COROUTINES
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ inline fun test(c: () -> Unit) {
|
||||
}
|
||||
}
|
||||
val l = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ inline fun test(<!INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED!>c: suspend () -> Uni
|
||||
}
|
||||
}
|
||||
val l: suspend () -> Unit = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ suspend inline fun test(crossinline c: () -> Unit) {
|
||||
}
|
||||
}
|
||||
val l = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
|
||||
// SKIP_TXT
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import helpers.*
|
||||
|
||||
interface SuspendRunnable {
|
||||
suspend fun run()
|
||||
}
|
||||
|
||||
// Function is suspend
|
||||
// parameter is crossinline
|
||||
// parameter is suspend
|
||||
// Block is allowed to be called inside the body of owner inline function
|
||||
// Block is allowed to be called from nested classes/lambdas (as common crossinlines)
|
||||
// It is NOT possible to call startCoroutine on the parameter
|
||||
// suspend calls possible inside lambda matching to the parameter
|
||||
suspend inline fun test(crossinline c: suspend () -> Unit) {
|
||||
c()
|
||||
val o = object : SuspendRunnable {
|
||||
override suspend fun run() {
|
||||
c()
|
||||
}
|
||||
}
|
||||
val l: suspend () -> Unit = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {}
|
||||
|
||||
suspend fun calculate() = "OK"
|
||||
|
||||
fun box() {
|
||||
builder {
|
||||
test {
|
||||
calculate()
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
|
||||
// SKIP_TXT
|
||||
// WITH_COROUTINES
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ suspend inline fun test(c: () -> Unit) {
|
||||
}
|
||||
}
|
||||
val l = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
suspend fun calculate() = "OK"
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ suspend inline fun test(c: <!REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE!>suspend<!>
|
||||
}
|
||||
}
|
||||
val l: suspend () -> Unit = { c() }
|
||||
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
|
||||
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
|
||||
Reference in New Issue
Block a user