mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 12:18:33 +00:00
Auto merge of #74957 - Manishearth:rollup-3wudwlg, r=Manishearth
Rollup of 9 pull requests Successful merges: - #74751 (Clean up E0730 explanation) - #74782 (Don't use "weak count" around Weak::from_raw_ptr) - #74835 (Clean up E0734 explanation) - #74871 (Enable docs on dist-x86_64-musl) - #74905 (Avoid bool-like naming) - #74907 (Clean up E0740 explanation) - #74915 (rustc: Ignore fs::canonicalize errors in metadata) - #74934 (Improve diagnostics when constant pattern is too generic) - #74951 (Cherry-pick the release notes for 1.45.1) Failed merges: r? @ghost
This commit is contained in:
commit
cfc572cae2
13
RELEASES.md
13
RELEASES.md
@ -1,3 +1,16 @@
|
|||||||
|
Version 1.45.1 (2020-07-30)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
* [Fix const propagation with references.][73613]
|
||||||
|
* [rustfmt accepts rustfmt_skip in cfg_attr again.][73078]
|
||||||
|
* [Avoid spurious implicit region bound.][74509]
|
||||||
|
* [Install clippy on x.py install][74457]
|
||||||
|
|
||||||
|
[73613]: https://github.com/rust-lang/rust/pull/73613
|
||||||
|
[73078]: https://github.com/rust-lang/rust/issues/73078
|
||||||
|
[74509]: https://github.com/rust-lang/rust/pull/74509
|
||||||
|
[74457]: https://github.com/rust-lang/rust/pull/74457
|
||||||
|
|
||||||
Version 1.45.0 (2020-07-16)
|
Version 1.45.0 (2020-07-16)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -1692,8 +1692,9 @@ impl<T> Weak<T> {
|
|||||||
|
|
||||||
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
||||||
///
|
///
|
||||||
/// This converts the weak pointer into a raw pointer, preserving the original weak count. It
|
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
|
||||||
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
/// one weak reference (the weak count is not modified by this operation). It can be turned
|
||||||
|
/// back into the `Weak<T>` with [`from_raw`].
|
||||||
///
|
///
|
||||||
/// The same restrictions of accessing the target of the pointer as with
|
/// The same restrictions of accessing the target of the pointer as with
|
||||||
/// [`as_ptr`] apply.
|
/// [`as_ptr`] apply.
|
||||||
@ -1728,17 +1729,18 @@ impl<T> Weak<T> {
|
|||||||
/// This can be used to safely get a strong reference (by calling [`upgrade`]
|
/// This can be used to safely get a strong reference (by calling [`upgrade`]
|
||||||
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
|
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
|
||||||
///
|
///
|
||||||
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
|
/// It takes ownership of one weak reference (with the exception of pointers created by [`new`],
|
||||||
/// as these don't have any corresponding weak count).
|
/// as these don't own anything; the method still works on them).
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
||||||
/// weak reference count.
|
/// weak reference.
|
||||||
///
|
///
|
||||||
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
|
/// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this
|
||||||
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
|
/// takes ownership of one weak reference currently represented as a raw pointer (the weak
|
||||||
/// by [`new`]).
|
/// count is not modified by this operation) and therefore it must be paired with a previous
|
||||||
|
/// call to [`into_raw`].
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -1462,8 +1462,9 @@ impl<T> Weak<T> {
|
|||||||
|
|
||||||
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
/// Consumes the `Weak<T>` and turns it into a raw pointer.
|
||||||
///
|
///
|
||||||
/// This converts the weak pointer into a raw pointer, preserving the original weak count. It
|
/// This converts the weak pointer into a raw pointer, while still preserving the ownership of
|
||||||
/// can be turned back into the `Weak<T>` with [`from_raw`].
|
/// one weak reference (the weak count is not modified by this operation). It can be turned
|
||||||
|
/// back into the `Weak<T>` with [`from_raw`].
|
||||||
///
|
///
|
||||||
/// The same restrictions of accessing the target of the pointer as with
|
/// The same restrictions of accessing the target of the pointer as with
|
||||||
/// [`as_ptr`] apply.
|
/// [`as_ptr`] apply.
|
||||||
@ -1493,24 +1494,23 @@ impl<T> Weak<T> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a raw pointer previously created by [`into_raw`] back into
|
/// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`.
|
||||||
/// `Weak<T>`.
|
|
||||||
///
|
///
|
||||||
/// This can be used to safely get a strong reference (by calling [`upgrade`]
|
/// This can be used to safely get a strong reference (by calling [`upgrade`]
|
||||||
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
|
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
|
||||||
///
|
///
|
||||||
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
|
/// It takes ownership of one weak reference (with the exception of pointers created by [`new`],
|
||||||
/// as these don't have any corresponding weak count).
|
/// as these don't own anything; the method still works on them).
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
/// The pointer must have originated from the [`into_raw`] and must still own its potential
|
||||||
/// weak reference count.
|
/// weak reference.
|
||||||
///
|
|
||||||
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
|
|
||||||
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
|
|
||||||
/// by [`new`]).
|
|
||||||
///
|
///
|
||||||
|
/// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this
|
||||||
|
/// takes ownership of one weak reference currently represented as a raw pointer (the weak
|
||||||
|
/// count is not modified by this operation) and therefore it must be paired with a previous
|
||||||
|
/// call to [`into_raw`].
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -33,7 +33,6 @@ ENV HOSTS=x86_64-unknown-linux-musl
|
|||||||
ENV RUST_CONFIGURE_ARGS \
|
ENV RUST_CONFIGURE_ARGS \
|
||||||
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
|
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
|
||||||
--enable-extended \
|
--enable-extended \
|
||||||
--disable-docs \
|
|
||||||
--enable-lld \
|
--enable-lld \
|
||||||
--set target.x86_64-unknown-linux-musl.crt-static=false \
|
--set target.x86_64-unknown-linux-musl.crt-static=false \
|
||||||
--build $HOSTS
|
--build $HOSTS
|
||||||
|
@ -195,9 +195,8 @@ def main():
|
|||||||
global MAILBOX
|
global MAILBOX
|
||||||
tests = [os.path.splitext(f)[0] for f in glob('*.rs')
|
tests = [os.path.splitext(f)[0] for f in glob('*.rs')
|
||||||
if not f.startswith('_')]
|
if not f.startswith('_')]
|
||||||
listed = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
if listed:
|
tests = [test for test in tests if test in args]
|
||||||
tests = [test for test in tests if test in listed]
|
|
||||||
if not tests:
|
if not tests:
|
||||||
print("Error: No tests to run")
|
print("Error: No tests to run")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
An array without a fixed length was pattern-matched.
|
An array without a fixed length was pattern-matched.
|
||||||
|
|
||||||
Example of erroneous code:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0730
|
```compile_fail,E0730
|
||||||
#![feature(const_generics)]
|
#![feature(const_generics)]
|
||||||
@ -14,14 +14,28 @@ fn is_123<const N: usize>(x: [u32; N]) -> bool {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Ensure that the pattern is consistent with the size of the matched
|
To fix this error, you have two solutions:
|
||||||
array. Additional elements can be matched with `..`:
|
1. Use an array with a fixed length.
|
||||||
|
2. Use a slice.
|
||||||
|
|
||||||
|
Example with an array with a fixed length:
|
||||||
|
|
||||||
```
|
```
|
||||||
let r = &[1, 2, 3, 4];
|
fn is_123(x: [u32; 3]) -> bool { // We use an array with a fixed size
|
||||||
match r {
|
match x {
|
||||||
&[a, b, ..] => { // ok!
|
[1, 2, ..] => true, // ok!
|
||||||
println!("a={}, b={}", a, b);
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Example with a slice:
|
||||||
|
|
||||||
|
```
|
||||||
|
fn is_123(x: &[u32]) -> bool { // We use a slice
|
||||||
|
match x {
|
||||||
|
[1, 2, ..] => true, // ok!
|
||||||
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
A stability attribute has been used outside of the standard library.
|
A stability attribute has been used outside of the standard library.
|
||||||
|
|
||||||
Erroneous code examples:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0734
|
```compile_fail,E0734
|
||||||
#[rustc_deprecated(since = "b", reason = "text")] // invalid
|
#[rustc_deprecated(since = "b", reason = "text")] // invalid
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
A `union` cannot have fields with destructors.
|
A `union` was declared with fields with destructors.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
@ -14,3 +14,5 @@ impl Drop for A {
|
|||||||
fn drop(&mut self) { println!("A"); }
|
fn drop(&mut self) { println!("A"); }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A `union` cannot have fields with destructors.
|
||||||
|
@ -248,9 +248,9 @@ impl<'a> CrateLoader<'a> {
|
|||||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||||
if let Some(mut files) = entry.files() {
|
if let Some(mut files) = entry.files() {
|
||||||
if files.any(|l| {
|
if files.any(|l| {
|
||||||
let l = fs::canonicalize(l).ok();
|
let l = fs::canonicalize(l).unwrap_or(l.clone().into());
|
||||||
source.dylib.as_ref().map(|p| &p.0) == l.as_ref()
|
source.dylib.as_ref().map(|p| &p.0) == Some(&l)
|
||||||
|| source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
|
|| source.rlib.as_ref().map(|p| &p.0) == Some(&l)
|
||||||
}) {
|
}) {
|
||||||
ret = Some(cnum);
|
ret = Some(cnum);
|
||||||
}
|
}
|
||||||
|
@ -426,20 +426,17 @@ impl<'a> CrateLocator<'a> {
|
|||||||
info!("lib candidate: {}", spf.path.display());
|
info!("lib candidate: {}", spf.path.display());
|
||||||
|
|
||||||
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
|
let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
|
||||||
fs::canonicalize(&spf.path)
|
let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
|
||||||
.map(|p| {
|
if seen_paths.contains(&path) {
|
||||||
if seen_paths.contains(&p) {
|
return FileDoesntMatch;
|
||||||
return FileDoesntMatch;
|
};
|
||||||
};
|
seen_paths.insert(path.clone());
|
||||||
seen_paths.insert(p.clone());
|
match found_kind {
|
||||||
match found_kind {
|
CrateFlavor::Rlib => rlibs.insert(path, kind),
|
||||||
CrateFlavor::Rlib => rlibs.insert(p, kind),
|
CrateFlavor::Rmeta => rmetas.insert(path, kind),
|
||||||
CrateFlavor::Rmeta => rmetas.insert(p, kind),
|
CrateFlavor::Dylib => dylibs.insert(path, kind),
|
||||||
CrateFlavor::Dylib => dylibs.insert(p, kind),
|
};
|
||||||
};
|
FileMatches
|
||||||
FileMatches
|
|
||||||
})
|
|
||||||
.unwrap_or(FileDoesntMatch)
|
|
||||||
});
|
});
|
||||||
self.rejected_via_kind.extend(staticlibs);
|
self.rejected_via_kind.extend(staticlibs);
|
||||||
|
|
||||||
@ -688,12 +685,13 @@ impl<'a> CrateLocator<'a> {
|
|||||||
&& file.ends_with(&self.target.options.dll_suffix)
|
&& file.ends_with(&self.target.options.dll_suffix)
|
||||||
{
|
{
|
||||||
// Make sure there's at most one rlib and at most one dylib.
|
// Make sure there's at most one rlib and at most one dylib.
|
||||||
|
let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone());
|
||||||
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
||||||
rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
rlibs.insert(loc, PathKind::ExternFlag);
|
||||||
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
|
} else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
|
||||||
rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
rmetas.insert(loc, PathKind::ExternFlag);
|
||||||
} else {
|
} else {
|
||||||
dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
|
dylibs.insert(loc, PathKind::ExternFlag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.rejected_via_filename
|
self.rejected_via_filename
|
||||||
|
@ -16,7 +16,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
|||||||
use rustc_hir::RangeEnd;
|
use rustc_hir::RangeEnd;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::mir::interpret::{get_slice_bytes, sign_extend, ConstValue};
|
use rustc_middle::mir::interpret::{get_slice_bytes, sign_extend, ConstValue};
|
||||||
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
|
use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput};
|
||||||
use rustc_middle::mir::UserTypeProjection;
|
use rustc_middle::mir::UserTypeProjection;
|
||||||
use rustc_middle::mir::{BorrowKind, Field, Mutability};
|
use rustc_middle::mir::{BorrowKind, Field, Mutability};
|
||||||
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
|
||||||
@ -834,6 +834,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||||||
pattern
|
pattern
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(ErrorHandled::TooGeneric) => {
|
||||||
|
// While `Reported | Linted` cases will have diagnostics emitted already
|
||||||
|
// it is not true for TooGeneric case, so we need to give user more information.
|
||||||
|
self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter");
|
||||||
|
pat_from_kind(PatKind::Wild)
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.tcx.sess.span_err(span, "could not evaluate constant pattern");
|
self.tcx.sess.span_err(span, "could not evaluate constant pattern");
|
||||||
pat_from_kind(PatKind::Wild)
|
pat_from_kind(PatKind::Wild)
|
||||||
|
@ -117,28 +117,22 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
|||||||
|
|
||||||
pub fn get_or_default_sysroot() -> PathBuf {
|
pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||||
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
|
fn canonicalize(path: PathBuf) -> PathBuf {
|
||||||
path.and_then(|path| {
|
let path = fs::canonicalize(&path).unwrap_or(path);
|
||||||
match fs::canonicalize(&path) {
|
// See comments on this target function, but the gist is that
|
||||||
// See comments on this target function, but the gist is that
|
// gcc chokes on verbatim paths which fs::canonicalize generates
|
||||||
// gcc chokes on verbatim paths which fs::canonicalize generates
|
// so we try to avoid those kinds of paths.
|
||||||
// so we try to avoid those kinds of paths.
|
fix_windows_verbatim_for_gcc(&path)
|
||||||
Ok(canon) => Some(fix_windows_verbatim_for_gcc(&canon)),
|
|
||||||
Err(e) => panic!("failed to get realpath: {}", e),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match env::current_exe() {
|
match env::current_exe() {
|
||||||
Ok(exe) => match canonicalize(Some(exe)) {
|
Ok(exe) => {
|
||||||
Some(mut p) => {
|
let mut p = canonicalize(exe);
|
||||||
p.pop();
|
p.pop();
|
||||||
p.pop();
|
p.pop();
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
None => panic!("can't determine value for sysroot"),
|
Err(e) => panic!("failed to get current_exe: {}", e),
|
||||||
},
|
|
||||||
Err(ref e) => panic!(format!("failed to get current_exe: {}", e)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ impl<T: 'static> GetTypeId<T> {
|
|||||||
|
|
||||||
const fn check_type_id<T: 'static>() -> bool {
|
const fn check_type_id<T: 'static>() -> bool {
|
||||||
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
||||||
//~^ ERROR could not evaluate constant pattern
|
//~^ ERROR constant pattern depends on a generic parameter
|
||||||
//~| ERROR could not evaluate constant pattern
|
//~| ERROR constant pattern depends on a generic parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GetTypeNameLen<T>(T);
|
pub struct GetTypeNameLen<T>(T);
|
||||||
@ -29,8 +29,8 @@ impl<T: 'static> GetTypeNameLen<T> {
|
|||||||
|
|
||||||
const fn check_type_name_len<T: 'static>() -> bool {
|
const fn check_type_name_len<T: 'static>() -> bool {
|
||||||
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||||
//~^ ERROR could not evaluate constant pattern
|
//~^ ERROR constant pattern depends on a generic parameter
|
||||||
//~| ERROR could not evaluate constant pattern
|
//~| ERROR constant pattern depends on a generic parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
error: could not evaluate constant pattern
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/issue-73976-polymorphic.rs:19:37
|
--> $DIR/issue-73976-polymorphic.rs:19:37
|
||||||
|
|
|
|
||||||
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/issue-73976-polymorphic.rs:31:42
|
--> $DIR/issue-73976-polymorphic.rs:31:42
|
||||||
|
|
|
|
||||||
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/issue-73976-polymorphic.rs:19:37
|
--> $DIR/issue-73976-polymorphic.rs:19:37
|
||||||
|
|
|
|
||||||
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: constant pattern depends on a generic parameter
|
||||||
--> $DIR/issue-73976-polymorphic.rs:31:42
|
--> $DIR/issue-73976-polymorphic.rs:31:42
|
||||||
|
|
|
|
||||||
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||||
|
Loading…
Reference in New Issue
Block a user