Revert "Rollup merge of #124099 - voidc:disallow-ambiguous-expr-attrs, r=davidtwco"
This reverts commit57dad1d75e
, reversing changes made to36316df9fe
.
This commit is contained in:
parent
e1ac0fa95b
commit
216424da32
@ -622,8 +622,6 @@ parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allo
|
|||||||
parse_out_of_range_hex_escape = out of range hex escape
|
parse_out_of_range_hex_escape = out of range hex escape
|
||||||
.label = must be a character in the range [\x00-\x7f]
|
.label = must be a character in the range [\x00-\x7f]
|
||||||
|
|
||||||
parse_outer_attr_ambiguous = ambiguous outer attributes
|
|
||||||
|
|
||||||
parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
|
parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
|
||||||
|
|
||||||
parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches
|
parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches
|
||||||
|
@ -495,15 +495,6 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse {
|
|||||||
pub attributes: Span,
|
pub attributes: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(parse_outer_attr_ambiguous)]
|
|
||||||
pub(crate) struct AmbiguousOuterAttributes {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
#[subdiagnostic]
|
|
||||||
pub sugg: WrapInParentheses,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_missing_in_in_for_loop)]
|
#[diag(parse_missing_in_in_for_loop)]
|
||||||
pub(crate) struct MissingInInForLoop {
|
pub(crate) struct MissingInInForLoop {
|
||||||
|
@ -328,9 +328,7 @@ pub(super) fn parse_expr_assoc_with(
|
|||||||
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
|
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
|
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
|
||||||
let span = lhs_span.to(rhs.span);
|
|
||||||
|
|
||||||
lhs = match op {
|
lhs = match op {
|
||||||
AssocOp::Add
|
AssocOp::Add
|
||||||
| AssocOp::Subtract
|
| AssocOp::Subtract
|
||||||
@ -429,18 +427,6 @@ fn error_found_expr_would_be_stmt(&self, lhs: &Expr) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_ambiguous_outer_attrs(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) {
|
|
||||||
if let Some(attr) = lhs.attrs.iter().find(|a| a.style == AttrStyle::Outer) {
|
|
||||||
self.dcx().emit_err(errors::AmbiguousOuterAttributes {
|
|
||||||
span: attr.span.to(rhs_span),
|
|
||||||
sugg: errors::WrapInParentheses::Expression {
|
|
||||||
left: attr.span.shrink_to_lo(),
|
|
||||||
right: lhs_span.shrink_to_hi(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Possibly translate the current token to an associative operator.
|
/// Possibly translate the current token to an associative operator.
|
||||||
/// The method does not advance the current token.
|
/// The method does not advance the current token.
|
||||||
///
|
///
|
||||||
@ -520,8 +506,7 @@ fn parse_expr_range(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
|
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
|
||||||
self.error_ambiguous_outer_attrs(&lhs, lhs.span, rhs_span);
|
let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span);
|
||||||
let span = lhs.span.to(rhs_span);
|
|
||||||
let limits =
|
let limits =
|
||||||
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
|
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
|
||||||
let range = self.mk_range(Some(lhs), rhs, limits);
|
let range = self.mk_range(Some(lhs), rhs, limits);
|
||||||
@ -739,8 +724,7 @@ fn parse_assoc_op_cast(
|
|||||||
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
|
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
|
let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
|
||||||
this.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
|
this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
|
||||||
this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save the state of the parser before parsing type normally, in case there is a
|
// Save the state of the parser before parsing type normally, in case there is a
|
||||||
@ -3858,6 +3842,16 @@ pub(super) fn mk_expr_err(&self, span: Span, guar: ErrorGuaranteed) -> P<Expr> {
|
|||||||
self.mk_expr(span, ExprKind::Err(guar))
|
self.mk_expr(span, ExprKind::Err(guar))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create expression span ensuring the span of the parent node
|
||||||
|
/// is larger than the span of lhs and rhs, including the attributes.
|
||||||
|
fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) -> Span {
|
||||||
|
lhs.attrs
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.style == AttrStyle::Outer)
|
||||||
|
.map_or(lhs_span, |a| a.span)
|
||||||
|
.to(rhs_span)
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_tokens_for_expr(
|
fn collect_tokens_for_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
attrs: AttrWrapper,
|
attrs: AttrWrapper,
|
||||||
|
@ -16,7 +16,7 @@ fn foo(
|
|||||||
|
|
||||||
fn skip_on_statements() {
|
fn skip_on_statements() {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
{ 5+3; }
|
5+3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -33,11 +33,11 @@ mod foo {
|
|||||||
#[clippy::msrv = "1.29"]
|
#[clippy::msrv = "1.29"]
|
||||||
fn msrv_1_29() {
|
fn msrv_1_29() {
|
||||||
#[cfg_attr(rustfmt, rustfmt::skip)]
|
#[cfg_attr(rustfmt, rustfmt::skip)]
|
||||||
{ 1+29; }
|
1+29;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[clippy::msrv = "1.30"]
|
#[clippy::msrv = "1.30"]
|
||||||
fn msrv_1_30() {
|
fn msrv_1_30() {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
{ 1+30; }
|
1+30;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ fn foo(
|
|||||||
|
|
||||||
fn skip_on_statements() {
|
fn skip_on_statements() {
|
||||||
#[cfg_attr(rustfmt, rustfmt::skip)]
|
#[cfg_attr(rustfmt, rustfmt::skip)]
|
||||||
{ 5+3; }
|
5+3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
@ -33,11 +33,11 @@ pub fn f() {}
|
|||||||
#[clippy::msrv = "1.29"]
|
#[clippy::msrv = "1.29"]
|
||||||
fn msrv_1_29() {
|
fn msrv_1_29() {
|
||||||
#[cfg_attr(rustfmt, rustfmt::skip)]
|
#[cfg_attr(rustfmt, rustfmt::skip)]
|
||||||
{ 1+29; }
|
1+29;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[clippy::msrv = "1.30"]
|
#[clippy::msrv = "1.30"]
|
||||||
fn msrv_1_30() {
|
fn msrv_1_30() {
|
||||||
#[cfg_attr(rustfmt, rustfmt::skip)]
|
#[cfg_attr(rustfmt, rustfmt::skip)]
|
||||||
{ 1+30; }
|
1+30;
|
||||||
}
|
}
|
||||||
|
@ -214,8 +214,8 @@ pub struct Params {
|
|||||||
// #3313
|
// #3313
|
||||||
fn stmt_expr_attributes() {
|
fn stmt_expr_attributes() {
|
||||||
let foo ;
|
let foo ;
|
||||||
(#[must_use]
|
#[must_use]
|
||||||
foo) = false ;
|
foo = false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #3509
|
// #3509
|
||||||
|
@ -248,8 +248,8 @@ pub struct Params {
|
|||||||
// #3313
|
// #3313
|
||||||
fn stmt_expr_attributes() {
|
fn stmt_expr_attributes() {
|
||||||
let foo;
|
let foo;
|
||||||
(#[must_use]
|
#[must_use]
|
||||||
foo) = false;
|
foo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #3509
|
// #3509
|
||||||
|
@ -13,17 +13,17 @@ fn syntax() {
|
|||||||
let _ = #[attr] ();
|
let _ = #[attr] ();
|
||||||
let _ = #[attr] (#[attr] 0,);
|
let _ = #[attr] (#[attr] 0,);
|
||||||
let _ = #[attr] (#[attr] 0, 0);
|
let _ = #[attr] (#[attr] 0, 0);
|
||||||
let _ = (#[attr] 0) + #[attr] 0;
|
let _ = #[attr] 0 + #[attr] 0;
|
||||||
let _ = (#[attr] 0) / #[attr] 0;
|
let _ = #[attr] 0 / #[attr] 0;
|
||||||
let _ = (#[attr] 0) & #[attr] 0;
|
let _ = #[attr] 0 & #[attr] 0;
|
||||||
let _ = (#[attr] 0) % #[attr] 0;
|
let _ = #[attr] 0 % #[attr] 0;
|
||||||
let _ = #[attr] (0 + 0);
|
let _ = #[attr] (0 + 0);
|
||||||
let _ = #[attr] !0;
|
let _ = #[attr] !0;
|
||||||
let _ = #[attr] -0;
|
let _ = #[attr] -0;
|
||||||
let _ = #[attr] false;
|
let _ = #[attr] false;
|
||||||
let _ = #[attr] 0;
|
let _ = #[attr] 0;
|
||||||
let _ = #[attr] 'c';
|
let _ = #[attr] 'c';
|
||||||
let _ = (#[attr] x) as Y;
|
let _ = #[attr] x as Y;
|
||||||
let _ = #[attr] (x as Y);
|
let _ = #[attr] (x as Y);
|
||||||
let _ =
|
let _ =
|
||||||
#[attr] while true {
|
#[attr] while true {
|
||||||
@ -88,9 +88,9 @@ fn syntax() {
|
|||||||
let _ = ();
|
let _ = ();
|
||||||
foo
|
foo
|
||||||
};
|
};
|
||||||
let _ = (#[attr] x) = y;
|
let _ = #[attr] x = y;
|
||||||
let _ = #[attr] (x = y);
|
let _ = #[attr] (x = y);
|
||||||
let _ = (#[attr] x) += y;
|
let _ = #[attr] x += y;
|
||||||
let _ = #[attr] (x += y);
|
let _ = #[attr] (x += y);
|
||||||
let _ = #[attr] foo.bar;
|
let _ = #[attr] foo.bar;
|
||||||
let _ = (#[attr] foo).bar;
|
let _ = (#[attr] foo).bar;
|
||||||
@ -98,8 +98,8 @@ fn syntax() {
|
|||||||
let _ = (#[attr] foo).0;
|
let _ = (#[attr] foo).0;
|
||||||
let _ = #[attr] foo[bar];
|
let _ = #[attr] foo[bar];
|
||||||
let _ = (#[attr] foo)[bar];
|
let _ = (#[attr] foo)[bar];
|
||||||
let _ = (#[attr] 0)..#[attr] 0;
|
let _ = #[attr] 0..#[attr] 0;
|
||||||
let _ = (#[attr] 0)..;
|
let _ = #[attr] 0..;
|
||||||
let _ = #[attr] (0..0);
|
let _ = #[attr] (0..0);
|
||||||
let _ = #[attr] (0..);
|
let _ = #[attr] (0..);
|
||||||
let _ = #[attr] (..0);
|
let _ = #[attr] (..0);
|
||||||
|
@ -147,13 +147,13 @@ fn _11() {
|
|||||||
let _ = #[rustc_dummy] (0);
|
let _ = #[rustc_dummy] (0);
|
||||||
let _ = #[rustc_dummy] (0,);
|
let _ = #[rustc_dummy] (0,);
|
||||||
let _ = #[rustc_dummy] (0, 0);
|
let _ = #[rustc_dummy] (0, 0);
|
||||||
let _ = (#[rustc_dummy] 0) + #[rustc_dummy] 0;
|
let _ = #[rustc_dummy] 0 + #[rustc_dummy] 0;
|
||||||
let _ = #[rustc_dummy] !0;
|
let _ = #[rustc_dummy] !0;
|
||||||
let _ = #[rustc_dummy] -0i32;
|
let _ = #[rustc_dummy] -0i32;
|
||||||
let _ = #[rustc_dummy] false;
|
let _ = #[rustc_dummy] false;
|
||||||
let _ = #[rustc_dummy] 'c';
|
let _ = #[rustc_dummy] 'c';
|
||||||
let _ = #[rustc_dummy] 0;
|
let _ = #[rustc_dummy] 0;
|
||||||
let _ = (#[rustc_dummy] 0) as usize;
|
let _ = #[rustc_dummy] 0 as usize;
|
||||||
let _ =
|
let _ =
|
||||||
#[rustc_dummy] while false {
|
#[rustc_dummy] while false {
|
||||||
#![rustc_dummy]
|
#![rustc_dummy]
|
||||||
@ -208,8 +208,8 @@ fn _11() {
|
|||||||
};
|
};
|
||||||
let const {} = #[rustc_dummy] const {};
|
let const {} = #[rustc_dummy] const {};
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let _ = (#[rustc_dummy] x) = 15;
|
let _ = #[rustc_dummy] x = 15;
|
||||||
let _ = (#[rustc_dummy] x) += 15;
|
let _ = #[rustc_dummy] x += 15;
|
||||||
let s = Foo { data: () };
|
let s = Foo { data: () };
|
||||||
let _ = #[rustc_dummy] s.data;
|
let _ = #[rustc_dummy] s.data;
|
||||||
let _ = (#[rustc_dummy] s).data;
|
let _ = (#[rustc_dummy] s).data;
|
||||||
@ -219,8 +219,8 @@ fn _11() {
|
|||||||
let v = vec!(0);
|
let v = vec!(0);
|
||||||
let _ = #[rustc_dummy] v[0];
|
let _ = #[rustc_dummy] v[0];
|
||||||
let _ = (#[rustc_dummy] v)[0];
|
let _ = (#[rustc_dummy] v)[0];
|
||||||
let _ = (#[rustc_dummy] 0)..#[rustc_dummy] 0;
|
let _ = #[rustc_dummy] 0..#[rustc_dummy] 0;
|
||||||
let _ = (#[rustc_dummy] 0)..;
|
let _ = #[rustc_dummy] 0..;
|
||||||
let _ = #[rustc_dummy] (0..0);
|
let _ = #[rustc_dummy] (0..0);
|
||||||
let _ = #[rustc_dummy] (0..);
|
let _ = #[rustc_dummy] (0..);
|
||||||
let _ = #[rustc_dummy] (..0);
|
let _ = #[rustc_dummy] (..0);
|
||||||
|
@ -20,10 +20,10 @@ fn doc_comment_between_if_else(num: u8) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn doc_comment_on_expr(num: u8) -> bool {
|
fn doc_comment_on_expr(num: u8) -> bool {
|
||||||
(/// useless doc comment
|
/// useless doc comment
|
||||||
//~^ ERROR: attributes on expressions are experimental
|
//~^ ERROR: attributes on expressions are experimental
|
||||||
//~| ERROR: unused doc comment
|
//~| ERROR: unused doc comment
|
||||||
num) == 3
|
num == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
fn doc_comment_on_expr_field() -> bool {
|
fn doc_comment_on_expr_field() -> bool {
|
||||||
|
@ -5,10 +5,10 @@ LL | else {
|
|||||||
| ^^^^ expected expression
|
| ^^^^ expected expression
|
||||||
|
|
||||||
error[E0658]: attributes on expressions are experimental
|
error[E0658]: attributes on expressions are experimental
|
||||||
--> $DIR/unused-doc-comments-edge-cases.rs:23:6
|
--> $DIR/unused-doc-comments-edge-cases.rs:23:5
|
||||||
|
|
|
|
||||||
LL | (/// useless doc comment
|
LL | /// useless doc comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||||
@ -32,12 +32,12 @@ LL | #![deny(unused_doc_comments)]
|
|||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unused doc comment
|
error: unused doc comment
|
||||||
--> $DIR/unused-doc-comments-edge-cases.rs:23:6
|
--> $DIR/unused-doc-comments-edge-cases.rs:23:5
|
||||||
|
|
|
|
||||||
LL | (/// useless doc comment
|
LL | /// useless doc comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
...
|
...
|
||||||
LL | num) == 3
|
LL | num == 3
|
||||||
| --- rustdoc does not generate documentation for expressions
|
| --- rustdoc does not generate documentation for expressions
|
||||||
|
|
|
|
||||||
= help: use `//` for a plain comment
|
= help: use `//` for a plain comment
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
//@ run-rustfix
|
|
||||||
#![feature(stmt_expr_attributes)]
|
|
||||||
#![allow(unused_assignments, unused_attributes)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut x = (#[deprecated] 1) + 2; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
(#[deprecated] x) = 4; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
x = (#[deprecated] 5) as i32; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
let _r = (#[deprecated] 1)..6; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
//@ run-rustfix
|
|
||||||
#![feature(stmt_expr_attributes)]
|
|
||||||
#![allow(unused_assignments, unused_attributes)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut x = #[deprecated] 1 + 2; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
#[deprecated] x = 4; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
x = #[deprecated] 5 as i32; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
let _r = #[deprecated] 1..6; //~ ERROR ambiguous
|
|
||||||
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
error: ambiguous outer attributes
|
|
||||||
--> $DIR/attr-binary-expr-ambigous.rs:6:17
|
|
||||||
|
|
|
||||||
LL | let mut x = #[deprecated] 1 + 2;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: wrap the expression in parentheses
|
|
||||||
|
|
|
||||||
LL | let mut x = (#[deprecated] 1) + 2;
|
|
||||||
| + +
|
|
||||||
|
|
||||||
error: ambiguous outer attributes
|
|
||||||
--> $DIR/attr-binary-expr-ambigous.rs:8:5
|
|
||||||
|
|
|
||||||
LL | #[deprecated] x = 4;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: wrap the expression in parentheses
|
|
||||||
|
|
|
||||||
LL | (#[deprecated] x) = 4;
|
|
||||||
| + +
|
|
||||||
|
|
||||||
error: ambiguous outer attributes
|
|
||||||
--> $DIR/attr-binary-expr-ambigous.rs:10:9
|
|
||||||
|
|
|
||||||
LL | x = #[deprecated] 5 as i32;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: wrap the expression in parentheses
|
|
||||||
|
|
|
||||||
LL | x = (#[deprecated] 5) as i32;
|
|
||||||
| + +
|
|
||||||
|
|
||||||
error: ambiguous outer attributes
|
|
||||||
--> $DIR/attr-binary-expr-ambigous.rs:12:14
|
|
||||||
|
|
|
||||||
LL | let _r = #[deprecated] 1..6;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
help: wrap the expression in parentheses
|
|
||||||
|
|
|
||||||
LL | let _r = (#[deprecated] 1)..6;
|
|
||||||
| + +
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
@ -10,5 +10,6 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let _x;
|
let _x;
|
||||||
let y = ();
|
let y = ();
|
||||||
(#[identity_attr] _x) = y;
|
#[identity_attr]
|
||||||
|
_x = y;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user