* Backport PR #4730 that fix issue #4689 * Test files for each Verion One and Two * Simplify per review comment - use defer and matches! * Changes per reviewer comments for reducing indentations
This commit is contained in:
parent
a67d909627
commit
ea017d7f84
5 changed files with 639 additions and 4 deletions
43
src/types.rs
43
src/types.rs
|
|
@ -941,6 +941,28 @@ fn join_bounds_inner(
|
|||
ast::GenericBound::Trait(..) => last_line_extendable(s),
|
||||
};
|
||||
|
||||
// Whether a GenericBound item is a PathSegment segment that includes internal array
|
||||
// that contains more than one item
|
||||
let is_item_with_multi_items_array = |item: &ast::GenericBound| match item {
|
||||
ast::GenericBound::Trait(ref poly_trait_ref, ..) => {
|
||||
let segments = &poly_trait_ref.trait_ref.path.segments;
|
||||
if segments.len() > 1 {
|
||||
true
|
||||
} else {
|
||||
if let Some(args_in) = &segments[0].args {
|
||||
matches!(
|
||||
args_in.deref(),
|
||||
ast::GenericArgs::AngleBracketed(bracket_args)
|
||||
if bracket_args.args.len() > 1
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let result = items.iter().enumerate().try_fold(
|
||||
(String::new(), None, false),
|
||||
|(strs, prev_trailing_span, prev_extendable), (i, item)| {
|
||||
|
|
@ -1035,10 +1057,23 @@ fn join_bounds_inner(
|
|||
},
|
||||
)?;
|
||||
|
||||
if !force_newline
|
||||
&& items.len() > 1
|
||||
&& (result.0.contains('\n') || result.0.len() > shape.width)
|
||||
{
|
||||
// Whether retry the function with forced newline is needed:
|
||||
// Only if result is not already multiline and did not exceed line width,
|
||||
// and either there is more than one item;
|
||||
// or the single item is of type `Trait`,
|
||||
// and any of the internal arrays contains more than one item;
|
||||
let retry_with_force_newline =
|
||||
if force_newline || (!result.0.contains('\n') && result.0.len() <= shape.width) {
|
||||
false
|
||||
} else {
|
||||
if items.len() > 1 {
|
||||
true
|
||||
} else {
|
||||
is_item_with_multi_items_array(&items[0])
|
||||
}
|
||||
};
|
||||
|
||||
if retry_with_force_newline {
|
||||
join_bounds_inner(context, shape, items, need_indent, true)
|
||||
} else {
|
||||
Some(result.0)
|
||||
|
|
|
|||
149
tests/source/issue-4689/one.rs
Normal file
149
tests/source/issue-4689/one.rs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// rustfmt-version: One
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1 + fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
)
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
||||
149
tests/source/issue-4689/two.rs
Normal file
149
tests/source/issue-4689/two.rs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// rustfmt-version: Two
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1 + fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write + Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
)
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: for<> FnMut(
|
||||
&mut ProbeContext<>,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff<>,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
||||
150
tests/target/issue-4689/one.rs
Normal file
150
tests/target/issue-4689/one.rs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
// rustfmt-version: One
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
),
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd,
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
||||
152
tests/target/issue-4689/two.rs
Normal file
152
tests/target/issue-4689/two.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
// rustfmt-version: Two
|
||||
|
||||
// Based on the issue description
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
pub trait PrettyPrinter<'tcx>:
|
||||
fmt::Write
|
||||
+ Printer1<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
> + Printer2<
|
||||
'tcx,
|
||||
Error = fmt::Error,
|
||||
Path = Self,
|
||||
Region = Self,
|
||||
Type = Self,
|
||||
DynExistential = Self,
|
||||
Const = Self,
|
||||
>
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// Some test cases to ensure other cases formatting were not changed
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
>,
|
||||
> {
|
||||
}
|
||||
fn f() -> Box<
|
||||
FnMut() -> Thing<
|
||||
WithType = LongItemName,
|
||||
Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger,
|
||||
> + fmt::Write1
|
||||
+ fmt::Write2,
|
||||
> {
|
||||
}
|
||||
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
),
|
||||
{
|
||||
}
|
||||
fn foo<F>(foo2: F)
|
||||
where
|
||||
F: Fn(
|
||||
// this comment is deleted
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
),
|
||||
{
|
||||
}
|
||||
fn elaborate_bounds<F>(mut mk_cand: F)
|
||||
where
|
||||
F: FnMut(
|
||||
&mut ProbeContext,
|
||||
ty::PolyTraitRefffffffffffffffffffffffffffffffff,
|
||||
tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem,
|
||||
) + fmt::Write,
|
||||
{
|
||||
}
|
||||
|
||||
fn build_sorted_static_get_entry_names(
|
||||
mut entries: entryyyyyyyy,
|
||||
) -> (
|
||||
impl Fn(
|
||||
AlphabeticalTraversal,
|
||||
Seconddddddddddddddddddddddddddddddddddd,
|
||||
) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
|
||||
+ Sendddddddddddddddddddddddddddddddddddddddddddd
|
||||
) {
|
||||
}
|
||||
|
||||
pub trait SomeTrait:
|
||||
Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||
{
|
||||
}
|
||||
|
||||
trait B = where
|
||||
for<'b> &'b Self: Send
|
||||
+ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
+ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy;
|
||||
Loading…
Add table
Add a link
Reference in a new issue