K2: support implicit integer to unsigned conversions...
with dedicated opt-in language feature and special annotation or module capability. Not intended for a general use, solves specific K/N scenario with interop libs. #KT-55902 fixed
This commit is contained in:
committed by
Space Team
parent
3e2f8b834c
commit
be2a85be71
@@ -0,0 +1,57 @@
|
||||
// WITH_STDLIB
|
||||
// !LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
|
||||
// IGNORE_BACKEND_K1: JVM
|
||||
// FILE: signedToUnsignedConversions_annotation.kt
|
||||
|
||||
package kotlin.internal
|
||||
|
||||
annotation class ImplicitIntegerCoercion
|
||||
|
||||
// FILE: signedToUnsignedConversions_test.kt
|
||||
|
||||
import kotlin.internal.ImplicitIntegerCoercion
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val IMPLICIT_INT = 255
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val EXPLICIT_INT: Int = 255
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val LONG_CONST = 255L
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
val NON_CONST = 255
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val BIGGER_THAN_UBYTE = 256
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val UINT_CONST = 42u
|
||||
|
||||
fun takeUByte(@ImplicitIntegerCoercion u: UByte) {}
|
||||
fun takeUShort(@ImplicitIntegerCoercion u: UShort) {}
|
||||
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {}
|
||||
fun takeULong(@ImplicitIntegerCoercion u: ULong) {}
|
||||
|
||||
fun takeUBytes(@ImplicitIntegerCoercion vararg u: UByte) {}
|
||||
|
||||
fun takeLong(@ImplicitIntegerCoercion l: Long) {}
|
||||
|
||||
fun box(): String {
|
||||
takeUByte(IMPLICIT_INT)
|
||||
takeUByte(EXPLICIT_INT)
|
||||
|
||||
takeUShort(IMPLICIT_INT)
|
||||
takeUShort(BIGGER_THAN_UBYTE)
|
||||
|
||||
takeUInt(IMPLICIT_INT)
|
||||
|
||||
takeULong(IMPLICIT_INT)
|
||||
|
||||
takeUBytes(IMPLICIT_INT, EXPLICIT_INT, 42u)
|
||||
|
||||
// such kind of conversions (Int <-> Long) actually are not supported
|
||||
// takeLong(IMPLICIT_INT)
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+12
-11
@@ -35,6 +35,7 @@ fun takeUShort(@ImplicitIntegerCoercion u: UShort) {}
|
||||
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {}
|
||||
fun takeULong(@ImplicitIntegerCoercion u: ULong) {}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun takeUBytes(@ImplicitIntegerCoercion vararg u: <!OPT_IN_USAGE!>UByte<!>) {}
|
||||
|
||||
fun takeLong(@ImplicitIntegerCoercion l: Long) {}
|
||||
@@ -44,27 +45,27 @@ fun takeUIntWithoutAnnotaion(u: UInt) {}
|
||||
fun takeIntWithoutAnnotation(i: Int) {}
|
||||
|
||||
fun test() {
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>EXPLICIT_INT<!>)
|
||||
takeUByte(IMPLICIT_INT)
|
||||
takeUByte(EXPLICIT_INT)
|
||||
|
||||
takeUShort(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
takeUShort(<!ARGUMENT_TYPE_MISMATCH!>BIGGER_THAN_UBYTE<!>)
|
||||
takeUShort(IMPLICIT_INT)
|
||||
takeUShort(BIGGER_THAN_UBYTE)
|
||||
|
||||
takeUInt(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
takeUInt(IMPLICIT_INT)
|
||||
|
||||
takeULong(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
takeULong(IMPLICIT_INT)
|
||||
|
||||
<!OPT_IN_USAGE!>takeUBytes<!>(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>, <!ARGUMENT_TYPE_MISMATCH!>EXPLICIT_INT<!>, 42u)
|
||||
<!OPT_IN_USAGE!>takeUBytes<!>(IMPLICIT_INT, EXPLICIT_INT, 42u)
|
||||
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
takeLong(IMPLICIT_INT)
|
||||
|
||||
takeIntWithoutAnnotation(IMPLICIT_INT)
|
||||
|
||||
takeUIntWithoutAnnotaion(UINT_CONST)
|
||||
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>LONG_CONST<!>)
|
||||
takeUByte(LONG_CONST)
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>NON_CONST<!>)
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>BIGGER_THAN_UBYTE<!>)
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>UINT_CONST<!>)
|
||||
takeUByte(BIGGER_THAN_UBYTE)
|
||||
takeUByte(UINT_CONST)
|
||||
takeUIntWithoutAnnotaion(<!ARGUMENT_TYPE_MISMATCH!>IMPLICIT_INT<!>)
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -35,6 +35,7 @@ fun takeUShort(@ImplicitIntegerCoercion u: UShort) {}
|
||||
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {}
|
||||
fun takeULong(@ImplicitIntegerCoercion u: ULong) {}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun takeUBytes(@ImplicitIntegerCoercion vararg u: UByte) {}
|
||||
|
||||
fun takeLong(@ImplicitIntegerCoercion l: Long) {}
|
||||
|
||||
Vendored
+1
-1
@@ -9,7 +9,7 @@ package
|
||||
public fun takeIntWithoutAnnotation(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||
public fun takeLong(/*0*/ @kotlin.internal.ImplicitIntegerCoercion l: kotlin.Long): kotlin.Unit
|
||||
public fun takeUByte(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.UByte): kotlin.Unit
|
||||
public fun takeUBytes(/*0*/ @kotlin.internal.ImplicitIntegerCoercion vararg u: kotlin.UByte /*kotlin.UByteArray*/): kotlin.Unit
|
||||
@kotlin.ExperimentalUnsignedTypes public fun takeUBytes(/*0*/ @kotlin.internal.ImplicitIntegerCoercion vararg u: kotlin.UByte /*kotlin.UByteArray*/): kotlin.Unit
|
||||
public fun takeUInt(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.UInt): kotlin.Unit
|
||||
public fun takeUIntWithoutAnnotaion(/*0*/ u: kotlin.UInt): kotlin.Unit
|
||||
public fun takeULong(/*0*/ @kotlin.internal.ImplicitIntegerCoercion u: kotlin.ULong): kotlin.Unit
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
FILE fqName:kotlin.internal fileName:/signedToUnsignedConversions_annotation.kt
|
||||
CLASS ANNOTATION_CLASS name:ImplicitIntegerCoercion modality:OPEN visibility:public superTypes:[kotlin.Annotation]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:kotlin.internal.ImplicitIntegerCoercion
|
||||
CONSTRUCTOR visibility:public <> () returnType:kotlin.internal.ImplicitIntegerCoercion [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:ImplicitIntegerCoercion modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FILE fqName:<root> fileName:/signedToUnsignedConversions_test.kt
|
||||
PROPERTY name:IMPLICIT_INT visibility:public modality:FINAL [const,val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:IMPLICIT_INT type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value=255
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-IMPLICIT_INT> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:IMPLICIT_INT visibility:public modality:FINAL [const,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-IMPLICIT_INT> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:IMPLICIT_INT type:kotlin.Int visibility:public [final,static]' type=kotlin.Int origin=null
|
||||
PROPERTY name:EXPLICIT_INT visibility:public modality:FINAL [const,val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:EXPLICIT_INT type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value=255
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-EXPLICIT_INT> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:EXPLICIT_INT visibility:public modality:FINAL [const,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-EXPLICIT_INT> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:EXPLICIT_INT type:kotlin.Int visibility:public [final,static]' type=kotlin.Int origin=null
|
||||
PROPERTY name:LONG_CONST visibility:public modality:FINAL [const,val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:LONG_CONST type:kotlin.Long visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Long type=kotlin.Long value=255
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-LONG_CONST> visibility:public modality:FINAL <> () returnType:kotlin.Long
|
||||
correspondingProperty: PROPERTY name:LONG_CONST visibility:public modality:FINAL [const,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-LONG_CONST> (): kotlin.Long declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:LONG_CONST type:kotlin.Long visibility:public [final,static]' type=kotlin.Long origin=null
|
||||
PROPERTY name:NON_CONST visibility:public modality:FINAL [val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:NON_CONST type:kotlin.Int visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value=255
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-NON_CONST> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:NON_CONST visibility:public modality:FINAL [val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-NON_CONST> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:NON_CONST type:kotlin.Int visibility:private [final,static]' type=kotlin.Int origin=null
|
||||
PROPERTY name:BIGGER_THAN_UBYTE visibility:public modality:FINAL [const,val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:BIGGER_THAN_UBYTE type:kotlin.Int visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value=256
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-BIGGER_THAN_UBYTE> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:BIGGER_THAN_UBYTE visibility:public modality:FINAL [const,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-BIGGER_THAN_UBYTE> (): kotlin.Int declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:BIGGER_THAN_UBYTE type:kotlin.Int visibility:public [final,static]' type=kotlin.Int origin=null
|
||||
PROPERTY name:UINT_CONST visibility:public modality:FINAL [const,val]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
FIELD PROPERTY_BACKING_FIELD name:UINT_CONST type:kotlin.UInt visibility:public [final,static]
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.UInt value=42
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-UINT_CONST> visibility:public modality:FINAL <> () returnType:kotlin.UInt
|
||||
correspondingProperty: PROPERTY name:UINT_CONST visibility:public modality:FINAL [const,val]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-UINT_CONST> (): kotlin.UInt declared in <root>'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:UINT_CONST type:kotlin.UInt visibility:public [final,static]' type=kotlin.UInt origin=null
|
||||
FUN name:takeUByte visibility:public modality:FINAL <> (u:kotlin.UByte) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:u index:0 type:kotlin.UByte
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:takeUShort visibility:public modality:FINAL <> (u:kotlin.UShort) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:u index:0 type:kotlin.UShort
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:takeUInt visibility:public modality:FINAL <> (u:kotlin.UInt) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:u index:0 type:kotlin.UInt
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:takeULong visibility:public modality:FINAL <> (u:kotlin.ULong) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:u index:0 type:kotlin.ULong
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:takeUBytes visibility:public modality:FINAL <> (u:kotlin.UByteArray) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:u index:0 type:kotlin.UByteArray varargElementType:kotlin.UByte [vararg]
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:takeLong visibility:public modality:FINAL <> (l:kotlin.Long) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:l index:0 type:kotlin.Long
|
||||
annotations:
|
||||
ImplicitIntegerCoercion
|
||||
BLOCK_BODY
|
||||
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun takeUByte (u: kotlin.UByte): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toUByte (): kotlin.UByte [inline] declared in kotlin.UByteKt' type=kotlin.UByte origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun takeUByte (u: kotlin.UByte): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toUByte (): kotlin.UByte [inline] declared in kotlin.UByteKt' type=kotlin.UByte origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun takeUShort (u: kotlin.UShort): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toUShort (): kotlin.UShort [inline] declared in kotlin.UShortKt' type=kotlin.UShort origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun takeUShort (u: kotlin.UShort): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toUShort (): kotlin.UShort [inline] declared in kotlin.UShortKt' type=kotlin.UShort origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=256
|
||||
CALL 'public final fun takeUInt (u: kotlin.UInt): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toUInt (): kotlin.UInt [inline] declared in kotlin.UIntKt' type=kotlin.UInt origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun takeULong (u: kotlin.ULong): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: CALL 'public final fun toULong (): kotlin.ULong [inline] declared in kotlin.ULongKt' type=kotlin.ULong origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun takeUBytes (vararg u: kotlin.UByte): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
u: VARARG type=kotlin.UByteArray varargElementType=kotlin.UByte
|
||||
CALL 'public final fun toUByte (): kotlin.UByte [inline] declared in kotlin.UByteKt' type=kotlin.UByte origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CALL 'public final fun toUByte (): kotlin.UByte [inline] declared in kotlin.UByteKt' type=kotlin.UByte origin=null
|
||||
$receiver: CONST Int type=kotlin.Int value=255
|
||||
CONST Byte type=kotlin.UByte value=42
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// FILE: signedToUnsignedConversions_annotation.kt
|
||||
package kotlin.internal
|
||||
|
||||
open annotation class ImplicitIntegerCoercion : Annotation {
|
||||
constructor() /* primary */ {
|
||||
super/*Any*/()
|
||||
/* <init>() */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FILE: signedToUnsignedConversions_test.kt
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val IMPLICIT_INT: Int
|
||||
field = 255
|
||||
get
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val EXPLICIT_INT: Int
|
||||
field = 255
|
||||
get
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val LONG_CONST: Long
|
||||
field = 255L
|
||||
get
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
val NON_CONST: Int
|
||||
field = 255
|
||||
get
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val BIGGER_THAN_UBYTE: Int
|
||||
field = 256
|
||||
get
|
||||
|
||||
@ImplicitIntegerCoercion
|
||||
const val UINT_CONST: UInt
|
||||
field = 42
|
||||
get
|
||||
|
||||
fun takeUByte(@ImplicitIntegerCoercion u: UByte) {
|
||||
}
|
||||
|
||||
fun takeUShort(@ImplicitIntegerCoercion u: UShort) {
|
||||
}
|
||||
|
||||
fun takeUInt(@ImplicitIntegerCoercion u: UInt) {
|
||||
}
|
||||
|
||||
fun takeULong(@ImplicitIntegerCoercion u: ULong) {
|
||||
}
|
||||
|
||||
fun takeUBytes(@ImplicitIntegerCoercion vararg u: UByte) {
|
||||
}
|
||||
|
||||
fun takeLong(@ImplicitIntegerCoercion l: Long) {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
takeUByte(u = 255.toUByte())
|
||||
takeUByte(u = 255.toUByte())
|
||||
takeUShort(u = 255.toUShort())
|
||||
takeUShort(u = 256.toUShort())
|
||||
takeUInt(u = 255.toUInt())
|
||||
takeULong(u = 255.toULong())
|
||||
takeUBytes(u = [255.toUByte(), 255.toUByte(), 42B])
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
// WITH_STDLIB
|
||||
// !LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user