replace "cast" with "coercion" where applicable
This changes the remaining span for the cast, because the new `Cast` category has a higher priority (lower `Ord`) than the old `Coercion` category, so we no longer report the region error for the "unsizing" coercion from `*const Trait` to itself.
This commit is contained in:
parent
d1e82d438f
commit
5e60d1f87e
@ -333,7 +333,9 @@ pub(crate) fn add_explanation_to_diagnostic(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ConstraintCategory::Cast { unsize_to: Some(unsize_ty) } = category {
|
if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } =
|
||||||
|
category
|
||||||
|
{
|
||||||
self.add_object_lifetime_default_note(tcx, err, unsize_ty);
|
self.add_object_lifetime_default_note(tcx, err, unsize_ty);
|
||||||
}
|
}
|
||||||
self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
|
self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
|
||||||
|
@ -47,7 +47,8 @@ fn description(&self) -> &'static str {
|
|||||||
ConstraintCategory::Yield => "yielding this value ",
|
ConstraintCategory::Yield => "yielding this value ",
|
||||||
ConstraintCategory::UseAsConst => "using this value as a constant ",
|
ConstraintCategory::UseAsConst => "using this value as a constant ",
|
||||||
ConstraintCategory::UseAsStatic => "using this value as a static ",
|
ConstraintCategory::UseAsStatic => "using this value as a static ",
|
||||||
ConstraintCategory::Cast { .. } => "cast ",
|
ConstraintCategory::Cast { is_coercion: false, .. } => "cast ",
|
||||||
|
ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ",
|
||||||
ConstraintCategory::CallArgument(_) => "argument ",
|
ConstraintCategory::CallArgument(_) => "argument ",
|
||||||
ConstraintCategory::TypeAnnotation => "type annotation ",
|
ConstraintCategory::TypeAnnotation => "type annotation ",
|
||||||
ConstraintCategory::ClosureBounds => "closure body ",
|
ConstraintCategory::ClosureBounds => "closure body ",
|
||||||
|
@ -2007,7 +2007,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
self.prove_predicate(
|
self.prove_predicate(
|
||||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
);
|
);
|
||||||
|
|
||||||
let src_ty = self.normalize(src_ty, location);
|
let src_ty = self.normalize(src_ty, location);
|
||||||
@ -2015,7 +2015,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
src_ty,
|
src_ty,
|
||||||
*ty,
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2036,7 +2036,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
self.prove_predicate(
|
self.prove_predicate(
|
||||||
ty::ClauseKind::WellFormed(src_ty.into()),
|
ty::ClauseKind::WellFormed(src_ty.into()),
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
);
|
);
|
||||||
|
|
||||||
// The type that we see in the fcx is like
|
// The type that we see in the fcx is like
|
||||||
@ -2049,7 +2049,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
src_ty,
|
src_ty,
|
||||||
*ty,
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2074,7 +2074,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
*ty,
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2103,7 +2103,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
*ty,
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2128,6 +2128,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
trait_ref,
|
trait_ref,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast {
|
ConstraintCategory::Cast {
|
||||||
|
is_coercion: true,
|
||||||
unsize_to: Some(tcx.fold_regions(ty, |r, _| {
|
unsize_to: Some(tcx.fold_regions(ty, |r, _| {
|
||||||
if let ty::ReVar(_) = r.kind() {
|
if let ty::ReVar(_) = r.kind() {
|
||||||
tcx.lifetimes.re_erased
|
tcx.lifetimes.re_erased
|
||||||
@ -2155,7 +2156,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
|
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
);
|
);
|
||||||
|
|
||||||
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
|
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
|
||||||
@ -2166,7 +2167,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
self.prove_predicate(
|
self.prove_predicate(
|
||||||
outlives_predicate,
|
outlives_predicate,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2184,7 +2185,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
*ty_from,
|
*ty_from,
|
||||||
*ty_to,
|
*ty_to,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2246,7 +2247,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
*ty_elem,
|
*ty_elem,
|
||||||
*ty_to,
|
*ty_to,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
@ -2427,7 +2428,10 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
|
|||||||
src_obj,
|
src_obj,
|
||||||
dst_obj,
|
dst_obj,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast {
|
||||||
|
is_coercion: false,
|
||||||
|
unsize_to: None,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,9 @@ pub enum ConstraintCategory<'tcx> {
|
|||||||
UseAsStatic,
|
UseAsStatic,
|
||||||
TypeAnnotation,
|
TypeAnnotation,
|
||||||
Cast {
|
Cast {
|
||||||
/// Whether this is an unsizing cast and if yes, this contains the target type.
|
/// Whether this cast is a coercion.
|
||||||
|
is_coercion: bool,
|
||||||
|
/// Whether this is an unsizing coercion and if yes, this contains the target type.
|
||||||
/// Region variables are erased to ReErased.
|
/// Region variables are erased to ReErased.
|
||||||
#[derive_where(skip)]
|
#[derive_where(skip)]
|
||||||
unsize_to: Option<Ty<'tcx>>,
|
unsize_to: Option<Ty<'tcx>>,
|
||||||
|
@ -75,7 +75,7 @@ LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut)));
|
|||||||
| ^^^^^^^^^^^^^^^^^^-----------------------------------------^
|
| ^^^^^^^^^^^^^^^^^^-----------------------------------------^
|
||||||
| | | |
|
| | | |
|
||||||
| | | immutable borrow occurs here
|
| | | immutable borrow occurs here
|
||||||
| | cast requires that `reg.sess_mut` is borrowed for `'a`
|
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
||||||
| mutable borrow occurs here
|
| mutable borrow occurs here
|
||||||
|
|
|
|
||||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
||||||
@ -119,7 +119,7 @@ LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
|||||||
| ^^^^^^^^^^^^^^^^^^-------------------------------------------------^
|
| ^^^^^^^^^^^^^^^^^^-------------------------------------------------^
|
||||||
| | | |
|
| | | |
|
||||||
| | | first mutable borrow occurs here
|
| | | first mutable borrow occurs here
|
||||||
| | cast requires that `reg.sess_mut` is borrowed for `'a`
|
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
||||||
| second mutable borrow occurs here
|
| second mutable borrow occurs here
|
||||||
|
|
|
|
||||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
||||||
|
@ -138,7 +138,7 @@ error: lifetime may not live long enough
|
|||||||
LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | require_static(ptr as _)
|
LL | require_static(ptr as _)
|
||||||
| ^^^ cast requires that `'a` must outlive `'static`
|
| ^^^^^^^^ cast requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:111:13
|
--> $DIR/dropck_trait_cycle_checked.rs:111:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static`
|
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
|
||||||
LL | o1.set0(&o2);
|
LL | o1.set0(&o2);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
@ -15,7 +15,7 @@ error[E0597]: `o3` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:112:13
|
--> $DIR/dropck_trait_cycle_checked.rs:112:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static`
|
| -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static`
|
||||||
LL | o1.set0(&o2);
|
LL | o1.set0(&o2);
|
||||||
LL | o1.set1(&o3);
|
LL | o1.set1(&o3);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
@ -29,7 +29,7 @@ error[E0597]: `o2` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:113:13
|
--> $DIR/dropck_trait_cycle_checked.rs:113:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static`
|
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | o2.set0(&o2);
|
LL | o2.set0(&o2);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
@ -43,7 +43,7 @@ error[E0597]: `o3` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:114:13
|
--> $DIR/dropck_trait_cycle_checked.rs:114:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static`
|
| -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | o2.set1(&o3);
|
LL | o2.set1(&o3);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
@ -57,7 +57,7 @@ error[E0597]: `o1` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:115:13
|
--> $DIR/dropck_trait_cycle_checked.rs:115:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o1` declared here -------- cast requires that `o1` is borrowed for `'static`
|
| -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | o3.set0(&o1);
|
LL | o3.set0(&o1);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
@ -71,7 +71,7 @@ error[E0597]: `o2` does not live long enough
|
|||||||
--> $DIR/dropck_trait_cycle_checked.rs:116:13
|
--> $DIR/dropck_trait_cycle_checked.rs:116:13
|
||||||
|
|
|
|
||||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||||
| -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static`
|
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | o3.set1(&o2);
|
LL | o3.set1(&o2);
|
||||||
| ^^^ borrowed value does not live long enough
|
| ^^^ borrowed value does not live long enough
|
||||||
|
@ -7,7 +7,7 @@ LL | let refcell = RefCell::new(&mut foo);
|
|||||||
| ^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^ borrowed value does not live long enough
|
||||||
LL |
|
LL |
|
||||||
LL | let read = &refcell as &RefCell<dyn Read>;
|
LL | let read = &refcell as &RefCell<dyn Read>;
|
||||||
| -------- cast requires that `foo` is borrowed for `'static`
|
| -------- coercion requires that `foo` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `foo` dropped here while still borrowed
|
| - `foo` dropped here while still borrowed
|
||||||
@ -19,7 +19,7 @@ LL | fn inner(mut foo: &[u8]) {
|
|||||||
| - let's call the lifetime of this reference `'1`
|
| - let's call the lifetime of this reference `'1`
|
||||||
...
|
...
|
||||||
LL | let read = &refcell as &RefCell<dyn Read>;
|
LL | let read = &refcell as &RefCell<dyn Read>;
|
||||||
| ^^^^^^^^ cast requires that `'1` must outlive `'static`
|
| ^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ LL | cx: &dyn DebugContext,
|
|||||||
| - let's call the lifetime of this reference `'1`
|
| - let's call the lifetime of this reference `'1`
|
||||||
...
|
...
|
||||||
LL | bar.debug_with(cx);
|
LL | bar.debug_with(cx);
|
||||||
| ^^ cast requires that `'1` must outlive `'static`
|
| ^^ coercion requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ error: lifetime may not live long enough
|
|||||||
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
|
||||||
| - let's call the lifetime of this reference `'1`
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | Box::new(value) as Box<dyn Any>
|
LL | Box::new(value) as Box<dyn Any>
|
||||||
| ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
| ^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static`
|
||||||
|
|
|
|
||||||
help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound
|
help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound
|
||||||
|
|
|
|
||||||
|
@ -8,7 +8,7 @@ fn main() {
|
|||||||
//~| NOTE borrowed value does not live long enough
|
//~| NOTE borrowed value does not live long enough
|
||||||
//~| NOTE due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
|
//~| NOTE due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
|
||||||
require_box(Box::new(r));
|
require_box(Box::new(r));
|
||||||
//~^ NOTE cast requires that `local` is borrowed for `'static`
|
//~^ NOTE coercion requires that `local` is borrowed for `'static`
|
||||||
|
|
||||||
let _ = 0;
|
let _ = 0;
|
||||||
} //~ NOTE `local` dropped here while still borrowed
|
} //~ NOTE `local` dropped here while still borrowed
|
||||||
|
@ -7,7 +7,7 @@ LL | let r = &local;
|
|||||||
| ^^^^^^ borrowed value does not live long enough
|
| ^^^^^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
LL | require_box(Box::new(r));
|
LL | require_box(Box::new(r));
|
||||||
| ----------- cast requires that `local` is borrowed for `'static`
|
| ----------- coercion requires that `local` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `local` dropped here while still borrowed
|
| - `local` dropped here while still borrowed
|
||||||
|
Loading…
Reference in New Issue
Block a user