Auto merge of #44474 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 13 pull requests - Successful merges: #44262, #44329, #44332, #44347, #44372, #44384, #44387, #44396, #44449, #44451, #44457, #44464, #44467 - Failed merges:
This commit is contained in:
@@ -297,6 +297,34 @@ impl str {
|
|||||||
/// [`str::from_utf8_mut`] function.
|
/// [`str::from_utf8_mut`] function.
|
||||||
///
|
///
|
||||||
/// [`str::from_utf8_mut`]: ./str/fn.from_utf8_mut.html
|
/// [`str::from_utf8_mut`]: ./str/fn.from_utf8_mut.html
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut s = String::from("Hello");
|
||||||
|
/// let bytes = unsafe { s.as_bytes_mut() };
|
||||||
|
///
|
||||||
|
/// assert_eq!(b"Hello", bytes);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Mutability:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut s = String::from("🗻∈🌏");
|
||||||
|
///
|
||||||
|
/// unsafe {
|
||||||
|
/// let bytes = s.as_bytes_mut();
|
||||||
|
///
|
||||||
|
/// bytes[0] = 0xF0;
|
||||||
|
/// bytes[1] = 0x9F;
|
||||||
|
/// bytes[2] = 0x8D;
|
||||||
|
/// bytes[3] = 0x94;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// assert_eq!("🍔∈🌏", s);
|
||||||
|
/// ```
|
||||||
#[stable(feature = "str_mut_extras", since = "1.20.0")]
|
#[stable(feature = "str_mut_extras", since = "1.20.0")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||||
@@ -362,16 +390,25 @@ impl str {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut v = String::from("🗻∈🌏");
|
/// use std::ascii::AsciiExt;
|
||||||
///
|
|
||||||
/// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v));
|
|
||||||
///
|
|
||||||
/// // indices not on UTF-8 sequence boundaries
|
|
||||||
/// assert!(v.get_mut(1..).is_none());
|
|
||||||
/// assert!(v.get_mut(..8).is_none());
|
|
||||||
///
|
///
|
||||||
|
/// let mut v = String::from("hello");
|
||||||
|
/// // correct length
|
||||||
|
/// assert!(v.get_mut(0..5).is_some());
|
||||||
/// // out of bounds
|
/// // out of bounds
|
||||||
/// assert!(v.get_mut(..42).is_none());
|
/// assert!(v.get_mut(..42).is_none());
|
||||||
|
/// assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v));
|
||||||
|
///
|
||||||
|
/// assert_eq!("hello", v);
|
||||||
|
/// {
|
||||||
|
/// let s = v.get_mut(0..2);
|
||||||
|
/// let s = s.map(|s| {
|
||||||
|
/// s.make_ascii_uppercase();
|
||||||
|
/// &*s
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(Some("HE"), s);
|
||||||
|
/// }
|
||||||
|
/// assert_eq!("HEllo", v);
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
|
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -743,6 +743,16 @@ impl String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts a string slice containing the entire string.
|
/// Extracts a string slice containing the entire string.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let s = String::from("foo");
|
||||||
|
///
|
||||||
|
/// assert_eq!("foo", s.as_str());
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "string_as_str", since = "1.7.0")]
|
#[stable(feature = "string_as_str", since = "1.7.0")]
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ mod platform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "redox"))]
|
#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||||
// On android we currently target API level 9 which unfortunately
|
// On android we currently target API level 9 which unfortunately
|
||||||
@@ -244,7 +244,7 @@ mod platform {
|
|||||||
libc::memalign(layout.align(), layout.size()) as *mut u8
|
libc::memalign(layout.align(), layout.size()) as *mut u8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "redox")))]
|
#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||||
let mut out = ptr::null_mut();
|
let mut out = ptr::null_mut();
|
||||||
|
|||||||
Submodule src/libcompiler_builtins updated: 6b9281d2b2...38ffaf97aa
@@ -383,16 +383,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
let msg_str = Symbol::intern(str).as_str();
|
let msg_str = Symbol::intern(str).as_str();
|
||||||
let msg_str = C_str_slice(bcx.ccx, msg_str);
|
let msg_str = C_str_slice(bcx.ccx, msg_str);
|
||||||
let msg_file_line = C_struct(bcx.ccx,
|
let msg_file_line_col = C_struct(bcx.ccx,
|
||||||
&[msg_str, filename, line],
|
&[msg_str, filename, line, col],
|
||||||
false);
|
false);
|
||||||
let align = llalign_of_min(bcx.ccx, common::val_ty(msg_file_line));
|
let align = llalign_of_min(bcx.ccx, common::val_ty(msg_file_line_col));
|
||||||
let msg_file_line = consts::addr_of(bcx.ccx,
|
let msg_file_line_col = consts::addr_of(bcx.ccx,
|
||||||
msg_file_line,
|
msg_file_line_col,
|
||||||
align,
|
align,
|
||||||
"panic_loc");
|
"panic_loc");
|
||||||
(lang_items::PanicFnLangItem,
|
(lang_items::PanicFnLangItem,
|
||||||
vec![msg_file_line],
|
vec![msg_file_line_col],
|
||||||
None)
|
None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1554,9 +1554,12 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let repr_type_ty = def.repr.discr_type().to_ty(tcx);
|
let repr_type_ty = def.repr.discr_type().to_ty(tcx);
|
||||||
if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
|
if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
|
||||||
if !tcx.sess.features.borrow().i128_type {
|
if !tcx.sess.features.borrow().repr128 {
|
||||||
emit_feature_err(&tcx.sess.parse_sess,
|
emit_feature_err(&tcx.sess.parse_sess,
|
||||||
"i128_type", sp, GateIssue::Language, "128-bit type is unstable");
|
"repr128",
|
||||||
|
sp,
|
||||||
|
GateIssue::Language,
|
||||||
|
"repr with 128-bit type is unstable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -606,12 +606,20 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A short, single-line view of `s`.
|
// A short, single-line view of `s`.
|
||||||
fn concise_str(s: &str) -> String {
|
fn concise_str(mut s: &str) -> String {
|
||||||
if s.contains('\n') {
|
if s.contains('\n') {
|
||||||
return format!("{}...", s.lines().next().expect("Impossible! We just found a newline"));
|
s = s.lines().next().expect("Impossible! We just found a newline");
|
||||||
}
|
}
|
||||||
if s.len() > 70 {
|
if s.len() > 70 {
|
||||||
return format!("{} ... {}", &s[..50], &s[s.len()-20..]);
|
let mut lo = 50;
|
||||||
|
let mut hi = s.len() - 20;
|
||||||
|
while !s.is_char_boundary(lo) {
|
||||||
|
lo -= 1;
|
||||||
|
}
|
||||||
|
while !s.is_char_boundary(hi) {
|
||||||
|
hi += 1;
|
||||||
|
}
|
||||||
|
return format!("{} ... {}", &s[..lo], &s[hi..]);
|
||||||
}
|
}
|
||||||
s.to_owned()
|
s.to_owned()
|
||||||
}
|
}
|
||||||
@@ -660,10 +668,14 @@ fn render_difference(diff: &html_diff::Difference) {
|
|||||||
elem.path, elem.element_name, elem_attributes, opposite_elem_attributes);
|
elem.path, elem.element_name, elem_attributes, opposite_elem_attributes);
|
||||||
}
|
}
|
||||||
html_diff::Difference::NodeText { ref elem, ref elem_text, ref opposite_elem_text, .. } => {
|
html_diff::Difference::NodeText { ref elem, ref elem_text, ref opposite_elem_text, .. } => {
|
||||||
|
if elem_text.split("\n")
|
||||||
|
.zip(opposite_elem_text.split("\n"))
|
||||||
|
.any(|(a, b)| a.trim() != b.trim()) {
|
||||||
let (s1, s2) = concise_compared_strs(elem_text, opposite_elem_text);
|
let (s1, s2) = concise_compared_strs(elem_text, opposite_elem_text);
|
||||||
println!(" {} Text differs:\n expected: `{}`\n found: `{}`",
|
println!(" {} Text differs:\n expected: `{}`\n found: `{}`",
|
||||||
elem.path, s1, s2);
|
elem.path, s1, s2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
html_diff::Difference::NotPresent { ref elem, ref opposite_elem } => {
|
html_diff::Difference::NotPresent { ref elem, ref opposite_elem } => {
|
||||||
if let Some(ref elem) = *elem {
|
if let Some(ref elem) = *elem {
|
||||||
println!(" {} One element is missing: expected: `{}`",
|
println!(" {} One element is missing: expected: `{}`",
|
||||||
@@ -1756,18 +1768,18 @@ fn render_markdown(w: &mut fmt::Formatter,
|
|||||||
// We only emit warnings if the user has opted-in to Pulldown rendering.
|
// We only emit warnings if the user has opted-in to Pulldown rendering.
|
||||||
let output = if render_type == RenderType::Pulldown {
|
let output = if render_type == RenderType::Pulldown {
|
||||||
let pulldown_output = format!("{}", Markdown(md_text, RenderType::Pulldown));
|
let pulldown_output = format!("{}", Markdown(md_text, RenderType::Pulldown));
|
||||||
let differences = html_diff::get_differences(&pulldown_output, &hoedown_output);
|
let mut differences = html_diff::get_differences(&pulldown_output, &hoedown_output);
|
||||||
let differences = differences.into_iter()
|
differences.retain(|s| {
|
||||||
.filter(|s| {
|
|
||||||
match *s {
|
match *s {
|
||||||
html_diff::Difference::NodeText { ref elem_text,
|
html_diff::Difference::NodeText { ref elem_text,
|
||||||
ref opposite_elem_text,
|
ref opposite_elem_text,
|
||||||
.. }
|
.. }
|
||||||
if match_non_whitespace(elem_text, opposite_elem_text) => false,
|
if elem_text.split_whitespace().eq(opposite_elem_text.split_whitespace()) => {
|
||||||
|
false
|
||||||
|
}
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if !differences.is_empty() {
|
if !differences.is_empty() {
|
||||||
scx.markdown_warnings.borrow_mut().push((span, md_text.to_owned(), differences));
|
scx.markdown_warnings.borrow_mut().push((span, md_text.to_owned(), differences));
|
||||||
@@ -1781,40 +1793,6 @@ fn render_markdown(w: &mut fmt::Formatter,
|
|||||||
write!(w, "<div class='docblock'>{}{}</div>", prefix, output)
|
write!(w, "<div class='docblock'>{}{}</div>", prefix, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true iff s1 and s2 match, ignoring whitespace.
|
|
||||||
fn match_non_whitespace(s1: &str, s2: &str) -> bool {
|
|
||||||
let s1 = s1.trim();
|
|
||||||
let s2 = s2.trim();
|
|
||||||
let mut cs1 = s1.chars();
|
|
||||||
let mut cs2 = s2.chars();
|
|
||||||
while let Some(c1) = cs1.next() {
|
|
||||||
if c1.is_whitespace() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if let Some(c2) = cs2.next() {
|
|
||||||
if !c2.is_whitespace() {
|
|
||||||
if c1 != c2 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(c2) = cs2.next() {
|
|
||||||
if !c2.is_whitespace() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink,
|
fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink,
|
||||||
cx: &Context, prefix: &str) -> fmt::Result {
|
cx: &Context, prefix: &str) -> fmt::Result {
|
||||||
if let Some(s) = item.doc_value() {
|
if let Some(s) = item.doc_value() {
|
||||||
@@ -3791,35 +3769,3 @@ fn test_name_sorting() {
|
|||||||
sorted.sort_by_key(|&s| name_key(s));
|
sorted.sort_by_key(|&s| name_key(s));
|
||||||
assert_eq!(names, sorted);
|
assert_eq!(names, sorted);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[test]
|
|
||||||
fn test_match_non_whitespace() {
|
|
||||||
assert!(match_non_whitespace("", ""));
|
|
||||||
assert!(match_non_whitespace(" ", ""));
|
|
||||||
assert!(match_non_whitespace("", " "));
|
|
||||||
|
|
||||||
assert!(match_non_whitespace("a", "a"));
|
|
||||||
assert!(match_non_whitespace(" a ", "a"));
|
|
||||||
assert!(match_non_whitespace("a", " a"));
|
|
||||||
assert!(match_non_whitespace("abc", "abc"));
|
|
||||||
assert!(match_non_whitespace("abc", " abc "));
|
|
||||||
assert!(match_non_whitespace("abc ", "abc"));
|
|
||||||
assert!(match_non_whitespace("abc xyz", "abc xyz"));
|
|
||||||
assert!(match_non_whitespace("abc xyz", "abc\nxyz"));
|
|
||||||
assert!(match_non_whitespace("abc xyz", "abcxyz"));
|
|
||||||
assert!(match_non_whitespace("abcxyz", "abc xyz"));
|
|
||||||
assert!(match_non_whitespace("abc xyz ", " abc xyz\n"));
|
|
||||||
|
|
||||||
assert!(!match_non_whitespace("a", "b"));
|
|
||||||
assert!(!match_non_whitespace(" a ", "c"));
|
|
||||||
assert!(!match_non_whitespace("a", " aa"));
|
|
||||||
assert!(!match_non_whitespace("abc", "ac"));
|
|
||||||
assert!(!match_non_whitespace("abc", " adc "));
|
|
||||||
assert!(!match_non_whitespace("abc ", "abca"));
|
|
||||||
assert!(!match_non_whitespace("abc xyz", "abc xy"));
|
|
||||||
assert!(!match_non_whitespace("abc xyz", "bc\nxyz"));
|
|
||||||
assert!(!match_non_whitespace("abc xyz", "abc.xyz"));
|
|
||||||
assert!(!match_non_whitespace("abcxyz", "abc.xyz"));
|
|
||||||
assert!(!match_non_whitespace("abc xyz ", " abc xyz w"));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ pub fn resolve_symname<F>(frame: Frame,
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut info: Dl_info = intrinsics::init();
|
let mut info: Dl_info = intrinsics::init();
|
||||||
let symname = if dladdr(frame.exact_position, &mut info) == 0 {
|
let symname = if dladdr(frame.exact_position, &mut info) == 0 ||
|
||||||
|
info.dli_sname.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
CStr::from_ptr(info.dli_sname).to_str().ok()
|
CStr::from_ptr(info.dli_sname).to_str().ok()
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ use mem;
|
|||||||
/// within a thread, and values that implement [`Drop`] get destructed when a
|
/// within a thread, and values that implement [`Drop`] get destructed when a
|
||||||
/// thread exits. Some caveats apply, which are explained below.
|
/// thread exits. Some caveats apply, which are explained below.
|
||||||
///
|
///
|
||||||
|
/// A `LocalKey`'s initializer cannot recursively depend on itself, and using
|
||||||
|
/// a `LocalKey` in this way will cause the initializer to infinitely recurse
|
||||||
|
/// on the first call to `with`.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -312,6 +312,9 @@ declare_features! (
|
|||||||
// The `i128` type
|
// The `i128` type
|
||||||
(active, i128_type, "1.16.0", Some(35118)),
|
(active, i128_type, "1.16.0", Some(35118)),
|
||||||
|
|
||||||
|
// The `repr(i128)` annotation for enums
|
||||||
|
(active, repr128, "1.16.0", Some(35118)),
|
||||||
|
|
||||||
// The `unadjusted` ABI. Perma unstable.
|
// The `unadjusted` ABI. Perma unstable.
|
||||||
(active, abi_unadjusted, "1.16.0", None),
|
(active, abi_unadjusted, "1.16.0", None),
|
||||||
|
|
||||||
|
|||||||
@@ -4699,7 +4699,7 @@ impl<'a> Parser<'a> {
|
|||||||
SeqSep::trailing_allowed(token::Comma),
|
SeqSep::trailing_allowed(token::Comma),
|
||||||
|p| p.parse_fn_block_arg()
|
|p| p.parse_fn_block_arg()
|
||||||
);
|
);
|
||||||
self.bump();
|
self.expect(&token::BinOp(token::Or))?;
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
17
src/test/compile-fail/feature-gate-repr128.rs
Normal file
17
src/test/compile-fail/feature-gate-repr128.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[repr(u128)]
|
||||||
|
enum A { //~ ERROR repr with 128-bit type is unstable
|
||||||
|
//~| HELP: add #![feature(repr128)]
|
||||||
|
A(u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
16
src/test/compile-fail/issue-41229-ref-str.rs
Normal file
16
src/test/compile-fail/issue-41229-ref-str.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
pub fn example(ref s: str) {}
|
||||||
|
//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
|
||||||
|
//~| `str` does not have a constant size known at compile-time
|
||||||
|
//~| the trait `std::marker::Sized` is not implemented for `str`
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
16
src/test/compile-fail/issue-44021.rs
Normal file
16
src/test/compile-fail/issue-44021.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct MyStruct;
|
||||||
|
impl MyStruct {
|
||||||
|
fn f() {|x, y} //~ ERROR expected one of `:`, `@`, or `|`, found `}`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
Reference in New Issue
Block a user