mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-30 08:34:07 +00:00
Remove Rc's borrow method to avoid conflicts with RefCell's borrow in Rc<RefCell<T>>.
This commit is contained in:
parent
12b2607572
commit
cdc18b96d6
@ -1687,7 +1687,7 @@ let x = Rc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
let y = x.clone(); // a new owner
|
||||
let z = x; // this moves `x` into `z`, rather than creating a new owner
|
||||
|
||||
assert!(*z.borrow() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
assert!(*z == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
|
||||
// the variable is mutable, but not the contents of the box
|
||||
let mut a = Rc::new([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
|
||||
|
@ -51,11 +51,11 @@ struct Chunk {
|
||||
}
|
||||
impl Chunk {
|
||||
fn capacity(&self) -> uint {
|
||||
self.data.borrow().borrow().get().capacity()
|
||||
self.data.deref().borrow().get().capacity()
|
||||
}
|
||||
|
||||
unsafe fn as_ptr(&self) -> *u8 {
|
||||
self.data.borrow().borrow().get().as_ptr()
|
||||
self.data.deref().borrow().get().as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
ebml_w.tag(c::tag_table_capture_map, |ebml_w| {
|
||||
ebml_w.id(id);
|
||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||
ebml_w.emit_from_vec(cap_vars.borrow().as_slice(),
|
||||
ebml_w.emit_from_vec(cap_vars.deref().as_slice(),
|
||||
|ebml_w, cap_var| {
|
||||
cap_var.encode(ebml_w);
|
||||
})
|
||||
|
@ -716,7 +716,7 @@ impl<'a> CheckLoanCtxt<'a> {
|
||||
span: Span) {
|
||||
let capture_map = self.bccx.capture_map.borrow();
|
||||
let cap_vars = capture_map.get().get(&closure_id);
|
||||
for cap_var in cap_vars.borrow().iter() {
|
||||
for cap_var in cap_vars.deref().iter() {
|
||||
let var_id = ast_util::def_id_of_def(cap_var.def).node;
|
||||
let var_path = @LpVar(var_id);
|
||||
self.check_if_path_is_moved(closure_id, span,
|
||||
|
@ -49,7 +49,7 @@ pub fn gather_captures(bccx: &BorrowckCtxt,
|
||||
closure_expr: &ast::Expr) {
|
||||
let capture_map = bccx.capture_map.borrow();
|
||||
let captured_vars = capture_map.get().get(&closure_expr.id);
|
||||
for captured_var in captured_vars.borrow().iter() {
|
||||
for captured_var in captured_vars.deref().iter() {
|
||||
match captured_var.mode {
|
||||
moves::CapMove => {
|
||||
let cmt = bccx.cat_captured_var(closure_expr.id,
|
||||
|
@ -406,7 +406,7 @@ impl<'a> GatherLoanCtxt<'a> {
|
||||
closure_expr: &ast::Expr) {
|
||||
let capture_map = self.bccx.capture_map.borrow();
|
||||
let captured_vars = capture_map.get().get(&closure_expr.id);
|
||||
for captured_var in captured_vars.borrow().iter() {
|
||||
for captured_var in captured_vars.deref().iter() {
|
||||
match captured_var.mode {
|
||||
moves::CapCopy | moves::CapMove => { continue; }
|
||||
moves::CapRef => { }
|
||||
|
@ -512,7 +512,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
|
||||
match lit.node {
|
||||
LitStr(ref s, _) => const_str((*s).clone()),
|
||||
LitBinary(ref data) => {
|
||||
const_binary(Rc::new(data.borrow().iter().map(|x| *x).collect()))
|
||||
const_binary(Rc::new(data.deref().iter().map(|x| *x).collect()))
|
||||
}
|
||||
LitChar(n) => const_uint(n as u64),
|
||||
LitInt(n, _) => const_int(n),
|
||||
|
@ -298,7 +298,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
|
||||
}
|
||||
}
|
||||
};
|
||||
let type_param_defs = type_param_defs.borrow();
|
||||
let type_param_defs = type_param_defs.deref();
|
||||
if ts.len() != type_param_defs.len() {
|
||||
// Fail earlier to make debugging easier
|
||||
fail!("internal error: in kind::check_expr, length \
|
||||
|
@ -505,7 +505,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
|
||||
let capture_map = this.capture_map.borrow();
|
||||
let cvs = capture_map.get().get(&expr.id);
|
||||
let mut call_caps = Vec::new();
|
||||
for cv in cvs.borrow().iter() {
|
||||
for cv in cvs.deref().iter() {
|
||||
match moves::moved_variable_node_id_from_def(cv.def) {
|
||||
Some(rv) => {
|
||||
let cv_ln = this.add_live_node(FreeVarNode(cv.span));
|
||||
|
@ -142,7 +142,7 @@ impl<T:Subst> Subst for Rc<T> {
|
||||
fn subst_spanned(&self, tcx: ty::ctxt,
|
||||
substs: &ty::substs,
|
||||
span: Option<Span>) -> Rc<T> {
|
||||
Rc::new(self.borrow().subst_spanned(tcx, substs, span))
|
||||
Rc::new(self.deref().subst_spanned(tcx, substs, span))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,21 +397,13 @@ pub fn trans_expr_fn<'a>(
|
||||
// set an inline hint for all closures
|
||||
set_inline_hint(llfn);
|
||||
|
||||
let cap_vars = {
|
||||
let capture_map = ccx.maps.capture_map.borrow();
|
||||
capture_map.get().get_copy(&id)
|
||||
};
|
||||
let cap_vars = ccx.maps.capture_map.borrow().get().get_copy(&id);
|
||||
let ClosureResult {llbox, cdata_ty, bcx} =
|
||||
build_closure(bcx, cap_vars.borrow().as_slice(), sigil);
|
||||
build_closure(bcx, cap_vars.deref().as_slice(), sigil);
|
||||
trans_closure(ccx, decl, body, llfn,
|
||||
bcx.fcx.param_substs, id,
|
||||
[], ty::ty_fn_ret(fty),
|
||||
|bcx| {
|
||||
load_environment(bcx,
|
||||
cdata_ty,
|
||||
cap_vars.borrow().as_slice(),
|
||||
sigil)
|
||||
});
|
||||
|bcx| load_environment(bcx, cdata_ty, cap_vars.deref().as_slice(), sigil));
|
||||
fill_fn_pair(bcx, dest_addr, llfn, llbox);
|
||||
|
||||
bcx
|
||||
|
@ -76,9 +76,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
|
||||
ast::LitBool(b) => C_bool(b),
|
||||
ast::LitNil => C_nil(),
|
||||
ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
|
||||
ast::LitBinary(ref data) => {
|
||||
C_binary_slice(cx, data.borrow().as_slice())
|
||||
}
|
||||
ast::LitBinary(ref data) => C_binary_slice(cx, data.deref().as_slice()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1014,13 +1014,13 @@ pub struct Generics {
|
||||
|
||||
impl Generics {
|
||||
pub fn has_type_params(&self) -> bool {
|
||||
!self.type_param_defs.borrow().is_empty()
|
||||
!self.type_param_defs.deref().is_empty()
|
||||
}
|
||||
pub fn type_param_defs<'a>(&'a self) -> &'a [TypeParameterDef] {
|
||||
self.type_param_defs.borrow().as_slice()
|
||||
self.type_param_defs.deref().as_slice()
|
||||
}
|
||||
pub fn region_param_defs<'a>(&'a self) -> &'a [RegionParameterDef] {
|
||||
self.region_param_defs.borrow().as_slice()
|
||||
self.region_param_defs.deref().as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1030,7 @@ impl<'a> LookupContext<'a> {
|
||||
let m_regions =
|
||||
self.fcx.infcx().region_vars_for_defs(
|
||||
self.expr.span,
|
||||
candidate.method_ty.generics.region_param_defs.borrow().as_slice());
|
||||
candidate.method_ty.generics.region_param_defs.deref().as_slice());
|
||||
for &r in m_regions.iter() {
|
||||
all_regions.push(r);
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ pub fn check_item(ccx: @CrateCtxt, it: &ast::Item) {
|
||||
fn_tpt.generics.type_param_defs(),
|
||||
[],
|
||||
[],
|
||||
fn_tpt.generics.region_param_defs.borrow().as_slice(),
|
||||
fn_tpt.generics.region_param_defs.deref().as_slice(),
|
||||
body.id);
|
||||
|
||||
check_bare_fn(ccx, decl, body, it.id, fn_tpt.ty, param_env);
|
||||
@ -3732,7 +3732,7 @@ pub fn instantiate_path(fcx: @FnCtxt,
|
||||
nsupplied = num_supplied_regions));
|
||||
}
|
||||
|
||||
fcx.infcx().region_vars_for_defs(span, tpt.generics.region_param_defs.borrow().as_slice())
|
||||
fcx.infcx().region_vars_for_defs(span, tpt.generics.region_param_defs.deref().as_slice())
|
||||
};
|
||||
let regions = ty::NonerasedRegions(regions);
|
||||
|
||||
|
@ -709,15 +709,13 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
debug!("vtable resolution on parameter bounds for method call {}",
|
||||
ex.repr(fcx.tcx()));
|
||||
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, method.origin);
|
||||
if has_trait_bounds(type_param_defs.borrow().as_slice()) {
|
||||
if has_trait_bounds(type_param_defs.deref().as_slice()) {
|
||||
let substs = fcx.method_ty_substs(ex.id);
|
||||
let vcx = fcx.vtable_context();
|
||||
let vtbls = lookup_vtables(&vcx,
|
||||
&location_info_for_expr(ex),
|
||||
type_param_defs.borrow()
|
||||
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
|
||||
type_param_defs.deref()
|
||||
.as_slice(),
|
||||
&substs,
|
||||
is_early);
|
||||
&substs, is_early);
|
||||
if !is_early {
|
||||
insert_vtables(fcx, ex.id, vtbls);
|
||||
}
|
||||
@ -829,7 +827,7 @@ pub fn resolve_impl(tcx: ty::ctxt,
|
||||
pub fn trans_resolve_method(tcx: ty::ctxt, id: ast::NodeId,
|
||||
substs: &ty::substs) -> Option<vtable_res> {
|
||||
let generics = ty::lookup_item_type(tcx, ast_util::local_def(id)).generics;
|
||||
let type_param_defs = generics.type_param_defs.borrow();
|
||||
let type_param_defs = generics.type_param_defs.deref();
|
||||
if has_trait_bounds(type_param_defs.as_slice()) {
|
||||
let vcx = VtableContext {
|
||||
infcx: &infer::new_infer_ctxt(tcx),
|
||||
|
@ -342,7 +342,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
|
||||
let mut new_type_param_defs = Vec::new();
|
||||
let substd_type_param_defs =
|
||||
trait_ty_generics.type_param_defs.subst(tcx, &substs);
|
||||
new_type_param_defs.push_all(substd_type_param_defs.borrow()
|
||||
new_type_param_defs.push_all(substd_type_param_defs.deref()
|
||||
.as_slice());
|
||||
|
||||
// add in the "self" type parameter
|
||||
@ -360,7 +360,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
|
||||
|
||||
// add in the type parameters from the method
|
||||
let substd_type_param_defs = m.generics.type_param_defs.subst(tcx, &substs);
|
||||
new_type_param_defs.push_all(substd_type_param_defs.borrow()
|
||||
new_type_param_defs.push_all(substd_type_param_defs.deref()
|
||||
.as_slice());
|
||||
|
||||
debug!("static method {} type_param_defs={} ty={}, substs={}",
|
||||
|
@ -1192,7 +1192,7 @@ impl ToSource for syntax::codemap::Span {
|
||||
fn lit_to_str(lit: &ast::Lit) -> ~str {
|
||||
match lit.node {
|
||||
ast::LitStr(ref st, _) => st.get().to_owned(),
|
||||
ast::LitBinary(ref data) => format!("{:?}", data.borrow().as_slice()),
|
||||
ast::LitBinary(ref data) => format!("{:?}", data.deref().as_slice()),
|
||||
ast::LitChar(c) => ~"'" + std::char::from_u32(c).unwrap().to_str() + "'",
|
||||
ast::LitInt(i, _t) => i.to_str(),
|
||||
ast::LitUint(u, _t) => u.to_str(),
|
||||
|
@ -113,7 +113,7 @@ mod test {
|
||||
fn call(&mut self) {
|
||||
let task = match *self {
|
||||
MyCallback(ref rc, n) => {
|
||||
let mut slot = rc.borrow().borrow_mut();
|
||||
let mut slot = rc.deref().borrow_mut();
|
||||
match *slot.get() {
|
||||
(ref mut task, ref mut val) => {
|
||||
*val = n;
|
||||
@ -140,7 +140,7 @@ mod test {
|
||||
fn sleep(chan: &Chan) -> uint {
|
||||
let task: ~Task = Local::take();
|
||||
task.deschedule(1, |task| {
|
||||
let mut slot = chan.borrow().borrow_mut();
|
||||
let mut slot = chan.deref().borrow_mut();
|
||||
match *slot.get() {
|
||||
(ref mut slot, _) => {
|
||||
assert!(slot.is_none());
|
||||
@ -150,7 +150,7 @@ mod test {
|
||||
Ok(())
|
||||
});
|
||||
|
||||
let slot = chan.borrow().borrow();
|
||||
let slot = chan.deref().borrow();
|
||||
match *slot.get() { (_, n) => n }
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,7 @@ impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> {
|
||||
#[inline]
|
||||
fn encode(&self, s: &mut S) {
|
||||
self.borrow().encode(s)
|
||||
self.deref().encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
use container::Container;
|
||||
use io::Writer;
|
||||
use iter::Iterator;
|
||||
use ops::Deref;
|
||||
use option::{Option, Some, None};
|
||||
use rc::Rc;
|
||||
use str::{Str, StrSlice};
|
||||
@ -246,7 +247,7 @@ impl<S: Writer, T: Hash<S>> Hash<S> for @T {
|
||||
impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut S) {
|
||||
self.borrow().hash(state);
|
||||
self.deref().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,7 +503,7 @@ mod tests {
|
||||
#[unsafe_destructor]
|
||||
impl ::ops::Drop for R {
|
||||
fn drop(&mut self) {
|
||||
let ii = self.i.borrow();
|
||||
let ii = self.i.deref();
|
||||
ii.set(ii.get() + 1);
|
||||
}
|
||||
}
|
||||
@ -520,7 +520,7 @@ mod tests {
|
||||
let opt = Some(x);
|
||||
let _y = opt.unwrap();
|
||||
}
|
||||
assert_eq!(i.borrow().get(), 1);
|
||||
assert_eq!(i.deref().get(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -63,12 +63,6 @@ impl<T> Rc<T> {
|
||||
}
|
||||
|
||||
impl<T> Rc<T> {
|
||||
/// Borrow the value contained in the reference-counted box
|
||||
#[inline(always)]
|
||||
pub fn borrow<'a>(&'a self) -> &'a T {
|
||||
unsafe { &(*self.ptr).value }
|
||||
}
|
||||
|
||||
/// Downgrade the reference-counted pointer to a weak reference
|
||||
pub fn downgrade(&self) -> Weak<T> {
|
||||
unsafe {
|
||||
@ -93,7 +87,7 @@ impl<T> Drop for Rc<T> {
|
||||
if self.ptr != 0 as *mut RcBox<T> {
|
||||
(*self.ptr).strong -= 1;
|
||||
if (*self.ptr).strong == 0 {
|
||||
ptr::read(self.borrow()); // destroy the contained object
|
||||
ptr::read(self.deref()); // destroy the contained object
|
||||
|
||||
// remove the implicit "strong weak" pointer now
|
||||
// that we've destroyed the contents.
|
||||
@ -120,24 +114,24 @@ impl<T> Clone for Rc<T> {
|
||||
|
||||
impl<T: Eq> Eq for Rc<T> {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Rc<T>) -> bool { *self.borrow() == *other.borrow() }
|
||||
fn eq(&self, other: &Rc<T>) -> bool { *self.deref() == *other.deref() }
|
||||
|
||||
#[inline(always)]
|
||||
fn ne(&self, other: &Rc<T>) -> bool { *self.borrow() != *other.borrow() }
|
||||
fn ne(&self, other: &Rc<T>) -> bool { *self.deref() != *other.deref() }
|
||||
}
|
||||
|
||||
impl<T: Ord> Ord for Rc<T> {
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &Rc<T>) -> bool { *self.borrow() < *other.borrow() }
|
||||
fn lt(&self, other: &Rc<T>) -> bool { *self.deref() < *other.deref() }
|
||||
|
||||
#[inline(always)]
|
||||
fn le(&self, other: &Rc<T>) -> bool { *self.borrow() <= *other.borrow() }
|
||||
fn le(&self, other: &Rc<T>) -> bool { *self.deref() <= *other.deref() }
|
||||
|
||||
#[inline(always)]
|
||||
fn gt(&self, other: &Rc<T>) -> bool { *self.borrow() > *other.borrow() }
|
||||
fn gt(&self, other: &Rc<T>) -> bool { *self.deref() > *other.deref() }
|
||||
|
||||
#[inline(always)]
|
||||
fn ge(&self, other: &Rc<T>) -> bool { *self.borrow() >= *other.borrow() }
|
||||
fn ge(&self, other: &Rc<T>) -> bool { *self.deref() >= *other.deref() }
|
||||
}
|
||||
|
||||
/// Weak reference to a reference-counted box
|
||||
@ -197,30 +191,30 @@ mod tests {
|
||||
fn test_clone() {
|
||||
let x = Rc::new(RefCell::new(5));
|
||||
let y = x.clone();
|
||||
x.borrow().with_mut(|inner| {
|
||||
x.deref().with_mut(|inner| {
|
||||
*inner = 20;
|
||||
});
|
||||
assert_eq!(y.borrow().with(|v| *v), 20);
|
||||
assert_eq!(y.deref().with(|v| *v), 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
let x = Rc::new(5);
|
||||
assert_eq!(*x.borrow(), 5);
|
||||
assert_eq!(*x.deref(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple_clone() {
|
||||
let x = Rc::new(5);
|
||||
let y = x.clone();
|
||||
assert_eq!(*x.borrow(), 5);
|
||||
assert_eq!(*y.borrow(), 5);
|
||||
assert_eq!(*x.deref(), 5);
|
||||
assert_eq!(*y.deref(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_destructor() {
|
||||
let x = Rc::new(~5);
|
||||
assert_eq!(**x.borrow(), 5);
|
||||
assert_eq!(**x.deref(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -243,7 +237,7 @@ mod tests {
|
||||
// see issue #11532
|
||||
use gc::Gc;
|
||||
let a = Rc::new(RefCell::new(Gc::new(1)));
|
||||
assert!(a.borrow().try_borrow_mut().is_some());
|
||||
assert!(a.deref().try_borrow_mut().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -254,7 +248,7 @@ mod tests {
|
||||
|
||||
let a = Rc::new(Cycle { x: RefCell::new(None) });
|
||||
let b = a.clone().downgrade();
|
||||
*a.borrow().x.borrow_mut().get() = Some(b);
|
||||
*a.deref().x.borrow_mut().get() = Some(b);
|
||||
|
||||
// hopefully we don't double-free (or leak)...
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
|
||||
}
|
||||
Some(ts) => ts.clone()
|
||||
};
|
||||
op(table.borrow())
|
||||
op(table.deref())
|
||||
})
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
|
||||
}
|
||||
Some(ts) => ts.clone()
|
||||
};
|
||||
op(table.borrow().borrow_mut().get())
|
||||
op(table.deref().borrow_mut().get())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2291,7 +2291,7 @@ pub fn print_literal(s: &mut State, lit: &ast::Lit) -> io::IoResult<()> {
|
||||
ast::LitBinary(ref arr) => {
|
||||
try!(ibox(s, indent_unit));
|
||||
try!(word(&mut s.s, "["));
|
||||
try!(commasep_cmnt(s, Inconsistent, arr.borrow().as_slice(),
|
||||
try!(commasep_cmnt(s, Inconsistent, arr.deref().as_slice(),
|
||||
|s, u| word(&mut s.s, format!("{}", *u)),
|
||||
|_| lit.span));
|
||||
try!(word(&mut s.s, "]"));
|
||||
|
@ -106,13 +106,13 @@ impl TotalOrd for RcStr {
|
||||
impl Str for RcStr {
|
||||
#[inline]
|
||||
fn as_slice<'a>(&'a self) -> &'a str {
|
||||
let s: &'a str = *self.string.borrow();
|
||||
let s: &'a str = *self.string.deref();
|
||||
s
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_owned(self) -> ~str {
|
||||
self.string.borrow().to_owned()
|
||||
self.string.deref().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ fn main()
|
||||
//~^ ERROR cannot pack type `~B`, which does not fulfill `Send`
|
||||
let v = Rc::new(RefCell::new(a));
|
||||
let w = v.clone();
|
||||
let b = v.borrow();
|
||||
let b = v.deref();
|
||||
let mut b = b.borrow_mut();
|
||||
b.get().v.set(w.clone());
|
||||
}
|
||||
|
@ -20,5 +20,5 @@ pub fn main() {
|
||||
|
||||
let mut x = Rc::new(3);
|
||||
x = x;
|
||||
assert!(*x.borrow() == 3);
|
||||
assert!(*x.deref() == 3);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user