Rust: format_args! рдХреЗ рд╕реНрдерд┐рд░ рдбреЗрдЯрд╛ рдореЗрдВ рдЯрд╛рдЗрдк-рдорд┐рдЯрд╛ fmt fn рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП #[repr(C)] HList рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдХреЛ рдирд┐рд░реНрдорд┐рдд 5 рд╕рд┐рддре░ 2017  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: rust-lang/rust

рдЕрднреА format_args! рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП ArgumentV1::new(&runtime_data, Debug::fmt) ( {:?} ), рд░рдирдЯрд╛рдЗрдо рдкрд░, рдХреЗрд╡рд▓ рдПрдХ ( &runtime_data ) рдХреЗ рдмрдЬрд╛рдп рд░рдирдЯрд╛рдЗрдо рдкрд░ рдкреНрд░рддрд┐ рддрд░реНрдХ рджреЛ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред .

allow_internal_unsafe рдФрд░ #44240 рдХреЗ рд╕рд╛рде, рд╣рдо (рдЬреИрд╕реЗ Debug::fmt ) fn рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ (рд░рд╛рд╡рд▓реНрдпреВ-рдкреНрд░рдореЛрдЯреЗрдб) 'static рдбреЗрдЯрд╛ рдореЗрдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╢реЗрд╖ рдмрд╛рдзрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рд░рдирдЯрд╛рдЗрдо рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╛рдиреА, Debug::fmt рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ <_ as Debug>::fmt рдФрд░ _ рдХрд╛ рдЕрдиреБрдорд╛рди рдЕрднреА рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ ArgumentV1::new рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд╛рде рдЯрд╛рдЗрдк рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЕрдЧрд░ рд╡реЗ рдЕрд▓рдЧ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдХреБрдЫ рдирдпрд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдВ HList рдкреИрдЯрд░реНрди ( struct HCons<H, T>(H, T); struct HNil; рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ - рдЗрд╕рд▓рд┐рдП 3 рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП, рдкреНрд░рдХрд╛рд░ A , B рдФрд░ C рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣реЛрдЧрд╛ HCons<A, HCons<B, HCons<C, HNil>>> ), рд╕рд╛рде рдореЗрдВ #[repr(C)] , рдЬреЛ рдЗрд╕реЗ рдПрдХ рдирд┐рдпрддрд╛рддреНрдордХ рд▓реЗрдЖрдЙрдЯ рджреЗрдЧрд╛ рдЬреЛ рдПрдХ рд╕рд░рдгреА рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдпрд╛рдиреА рдпреЗ рджреЛрдиреЛрдВ:

  • &'static HCons<fn(&A), HCons<fn(&B), HCons<fn(&C), HNil>>>
  • &'static [unsafe fn(*const Opaque); 3]

рдПрдХ рд╣реА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╣реИ, рдФрд░ рдмрд╛рдж рд╡рд╛рд▓реЗ рдХреЛ рдПрдХ рд╕реНрд▓рд╛рдЗрд╕ рдореЗрдВ рдЕрдирд╕рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред HList рд╕реЗ рд╕рд░рдгреА (рдФрд░ рдлрд┐рд░ рд╕реНрд▓рд╛рдЗрд╕) рдореЗрдВ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд, рдкреНрд░рддрд┐рджреНрд╡рдВрджреНрд╡рд┐рддрд╛-рдкреНрд░рдЪрд╛рд░рд┐рдд HCons рд╢реАрд░реНрд╖ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ fn рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд╢реНрдпрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ 'static рдбреЗрдЯрд╛ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднреАред

рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╕ рдЬреИрд╕реЗ рдкреНрд░рдХрд╛рд░ рдЕрдк рдореИрдЪ рдХреЗ рд▓рд┐рдП рдЙрд╕рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ B рд╣рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ fmt::unify_fn_with_data((list.1).0, &b) рд╣реИ, рдЬреЛ рд╣реЛрдЧрд╛ B рдореЗрдВ typeof b ред

рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд "рдмрд┐рд▓реНрдбрд░" рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛрдирд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╕рд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ HList рдХреЛ HList рд░рдирдЯрд╛рдЗрдо рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЪрд┐рдВрддрд┐рдд рд╣реВрдВ рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░реЗрд╖рдг рдХреЗ рдХрд╛рд░рдг рд╕рдВрдХрд▓рди-рд╕рдордп - рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рднрд╛рд╡ рдХреЛ рдорд╛рдкрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


A-fmt C-enhancement I-heavy T-libs

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП B рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо fmt::unify_fn_with_data((list.1).0, &b) , рдЬреЛ B рдХреЛ typeof b ред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд╡рд╣рд╛рдВ рдХреНрдпрд╛ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛, рдпрд╣ рдЙрд╕рд╕реЗ рдХрд╣реАрдВ рдЬреНрдпрд╛рджрд╛ рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП!

struct ArgMetadata<T: ?Sized> {
    // Only `unsafe` because of the later cast we do from `T` to `Opaque`.
    fmt: unsafe fn(&T, &mut Formatter<'_>) -> Result,
    // ... flags, constant string fragments, etc.
}

// TODO: maybe name this something else to emphasize repr(C)?
#[repr(C)]
struct HCons<T, Rest>(T, Rest);

// This would have to be in a "sealed module" to make it impossible to implement on more types.
trait MetadataFor<D> {
    const LEN: usize;
}
impl MetadataFor<()> for () {
    const LEN: usize = 0;
}
impl<'a, T: ?Sized, D, M> MetadataFor<HCons<&'a T, D>> for HCons<ArgMetadata<T>, M>
    where M: MetadataFor<D>
{
    const LEN: usize = M::LEN;
}

impl<'a> Arguments<'a> {
    fn new<M, D>(meta: &'a M, data: &'a D) -> Self
        where M: MetadataFor<D>
    {
        Self {
            meta: unsafe { &*(meta as *const _ as *const [ArgMetadata<Opaque>; M::LEN]) },
            data: unsafe { &*(data as *const _ as *const [&Opaque; M::LEN]) },
        }
    }
}

рдпрд╛рдиреА рд╣рдо рджреЛ HList s "рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ" рдмрдирд╛рддреЗ рд╣реИрдВ, рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдерд┐рд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде, рдФрд░ рджреВрд╕рд░рд╛ рд░рдирдЯрд╛рдЗрдо рдбреЗрдЯрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде, рдФрд░ рдлрд┐рд░ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдорд╛рди where рд╕реЗ рдЖ рд╕рдХрддреЗ рд╣реИрдВ fmt::Arguments::new рдкрд░ рд╢реВрдиреНрдп рдХреЛрдбрдЬрди рдХреНрд░реЙрдлреНрдЯ рдХреЗ рд╕рд╛рде рдХреНрд▓реЙрдЬ!

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ : @ рдПрдо-рдУ-рд╕реЗ рдХреЛ рдореБрдЭреЗ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рдкрдбрд╝рд╛ рдХрд┐ рдореИрдВ рдкрд╣рд▓реА рдмрд╛рд░ рд╕реНрдкрд╖реНрдЯ рдЕрдиреБрдорд╛рди рдЪрд╛рд▓ рдХреЗ рд╕рд╛рде рдХреНрдпреЛрдВ рдЧрдпрд╛: рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЕрднрд┐рдЧрдо рддрд░реНрдХ: рдирд┐рд░рд╛рд╢:
(рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рдкреНрдд рдХреЙрдиреНрд╕ рдЬреЗрдирд░рд┐рдХ ab рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдкрд╛рд╕ D: IndexHList<i, Output = T> рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдкреНрд░рдпрд╛рд╕ рд╣реИ)

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

@rustbot рджрд╛рд╡рд╛

рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП B рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо fmt::unify_fn_with_data((list.1).0, &b) , рдЬреЛ B рдХреЛ typeof b ред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд╡рд╣рд╛рдВ рдХреНрдпрд╛ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛, рдпрд╣ рдЙрд╕рд╕реЗ рдХрд╣реАрдВ рдЬреНрдпрд╛рджрд╛ рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП!

struct ArgMetadata<T: ?Sized> {
    // Only `unsafe` because of the later cast we do from `T` to `Opaque`.
    fmt: unsafe fn(&T, &mut Formatter<'_>) -> Result,
    // ... flags, constant string fragments, etc.
}

// TODO: maybe name this something else to emphasize repr(C)?
#[repr(C)]
struct HCons<T, Rest>(T, Rest);

// This would have to be in a "sealed module" to make it impossible to implement on more types.
trait MetadataFor<D> {
    const LEN: usize;
}
impl MetadataFor<()> for () {
    const LEN: usize = 0;
}
impl<'a, T: ?Sized, D, M> MetadataFor<HCons<&'a T, D>> for HCons<ArgMetadata<T>, M>
    where M: MetadataFor<D>
{
    const LEN: usize = M::LEN;
}

impl<'a> Arguments<'a> {
    fn new<M, D>(meta: &'a M, data: &'a D) -> Self
        where M: MetadataFor<D>
    {
        Self {
            meta: unsafe { &*(meta as *const _ as *const [ArgMetadata<Opaque>; M::LEN]) },
            data: unsafe { &*(data as *const _ as *const [&Opaque; M::LEN]) },
        }
    }
}

рдпрд╛рдиреА рд╣рдо рджреЛ HList s "рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ" рдмрдирд╛рддреЗ рд╣реИрдВ, рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдерд┐рд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде, рдФрд░ рджреВрд╕рд░рд╛ рд░рдирдЯрд╛рдЗрдо рдбреЗрдЯрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде, рдФрд░ рдлрд┐рд░ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдорд╛рди where рд╕реЗ рдЖ рд╕рдХрддреЗ рд╣реИрдВ fmt::Arguments::new рдкрд░ рд╢реВрдиреНрдп рдХреЛрдбрдЬрди рдХреНрд░реЙрдлреНрдЯ рдХреЗ рд╕рд╛рде рдХреНрд▓реЙрдЬ!

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ : @ рдПрдо-рдУ-рд╕реЗ рдХреЛ рдореБрдЭреЗ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рдкрдбрд╝рд╛ рдХрд┐ рдореИрдВ рдкрд╣рд▓реА рдмрд╛рд░ рд╕реНрдкрд╖реНрдЯ рдЕрдиреБрдорд╛рди рдЪрд╛рд▓ рдХреЗ рд╕рд╛рде рдХреНрдпреЛрдВ рдЧрдпрд╛: рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЕрднрд┐рдЧрдо рддрд░реНрдХ: рдирд┐рд░рд╛рд╢:
(рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рдкреНрдд рдХреЙрдиреНрд╕ рдЬреЗрдирд░рд┐рдХ ab рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдкрд╛рд╕ D: IndexHList<i, Output = T> рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдкреНрд░рдпрд╛рд╕ рд╣реИ)

рдореЗрд░реЗ рдкрд╛рд╕ fmt::Arguments рдХрд╛ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬреЛ 'рд╕реНрдерд┐рд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛' рдХреЗ рдПрдХ рдирдП рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдХрд╛рд░ рдореЗрдВ рдХреЗрд╡рд▓ рджреЛ рдкреЙрдЗрдВрдЯрд░реНрд╕ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЯреБрдХрдбрд╝реЗ рдФрд░ рдХреЛрдИ рд╕реНрд╡рд░реВрдкрдг рд╡рд┐рдХрд▓реНрдк (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рджреЛрдиреЛрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред (рддреЛ рдЕрдм рдпрд╣ рдПрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдЬреЛрдбрд╝реА рдореЗрдВ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реИред) рдЗрд╕рдХреЗ рд▓рд┐рдП рджреЛ рдХреЗ рдмрдЬрд╛рдп рд╕реНрдЯреИрдХ рдкреНрд░рддрд┐ рддрд░реНрдХ рдкрд░ рдХреЗрд╡рд▓ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ @eddyb рдиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рддреАрди рд╕рд╛рд▓ рдкрд╣рд▓реЗ рд╣реА рд╕реБрдЭрд╛рдпрд╛ рдерд╛ред ^^ (рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрдм рддрдХ @eddyb рдиреЗ рдХрд▓ рдЗрд╕реЗ рдЗрдВрдЧрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ред ^^')

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЗрд╕ рдирдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП format_args!() рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЕрднреА рдмрд╛рдХреА рд╣реИ, рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреЙрдЗрдВрдЯрд░ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ (рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ ArgumentV1 ) рдХреЛ рдлрдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рдЪрд▓реЗрдЧрд╛ред рдЕрдм рдЗрд╕рдХреЗ рдмрдЬрд╛рдп 'рд╕реНрдерд┐рд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛' рдореЗрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рд╕реБрдЭрд╛рд╡ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд▓рдЧрддрд╛ рд╣реИред рдЬрд▓реНрдж рд╣реА рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рдкреВрд░реНрдг рд░рди рдХреЗ рд▓рд┐рдП рддрддреНрдкрд░ рд╣реИрдВ :)

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

Robbepop picture Robbepop  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

drewcrawford picture drewcrawford  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dtolnay picture dtolnay  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dwrensha picture dwrensha  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dnsl48 picture dnsl48  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ