Rust: рдЧрд▓рдд рддреНрд░реБрдЯрд┐: 'FnMut' рдХреНрд▓реЛрдЬрд░ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд┐рдП рдЧрдП рдмрд╛рд╣рд░реА рдЪрд░ рд╕реЗ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛

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

рддреНрд░реБрдЯрд┐: рдПрдХ FnMut рдХреНрд▓реЛрдЬрд░ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд┐рдП рдЧрдП рдмрд╛рд╣рд░реА рдЪрд░ рд╕реЗ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

struct Foo {
    a: i32,
    b: i32,
    bar: Bar,
}

struct Bar;

impl Bar {
    fn f<F: FnMut()>(&self, mut f: F) {
        f();
    }
}

fn main() {
    let mut foo = Foo { a: 1, b: 2, bar: Bar };
    let a = &mut foo.a;
    let b = &mut foo.b;
    (|| { // works
        *if true {a} else {b} = 42;
    })();

    let mut foo = Foo { a: 1, b: 2, bar: Bar };
    let a = &mut foo.a;
    let b = &mut foo.b;
    foo.bar.f(|| { // doesn't work
        *if true {a} else {b} = 42;
    });
}

https://play.rust-lang.org/?gist=4ce6948a92c2fcb281b3cade8574691d&version=nightly

рд▓реЗрдХрд┐рди рджреВрд╕рд░рд╛ рдорд╛рдорд▓рд╛ рднреА рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП!

A-borrow-checker A-diagnostics C-enhancement T-compiler

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

@ рдмреЙрд╕реНрдХреЛрдк рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЪреАрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ FnMut рдмрдВрдж рдХреЛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

(рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ, рддреНрд░реБрдЯрд┐ рдпрд╣ рдХрд╣рдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕реЗ FnOnce рддрдм рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред)

рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрд╕рд╣рдордд рднреА рдирд╣реАрдВ рд╣реВрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рдХрд╛ рдирд┐рджрд╛рди рдХрд░рдирд╛ рдЕрдХреНрд╕рд░ рдХрдард┐рди рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдПрдХ рддрд░рд╣ рдХрд╛ рддрдирд╛рд╡ рд╣реИ: рдХреНрд▓реЛрдЬрд░ рдПрдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ (рдПрдХ рдЪрд╛рд▓) рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди f рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ (рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд▓реЛрдЬрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рддреНрд░реБрдЯрд┐ рдореЗрдВ рд╣реИ (рдЗрд╕реЗ FnOnce рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП) рдпрд╛ рдмрдВрдж рдХрд░рдирд╛ рдЧрд▓рдд рд╣реИ (рдпрд╣ рдЙрди рдЪреАрдЬреЛрдВ рдХреЛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП)ред рдХрдо рд╕реЗ рдХрдо, рд╣рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рджрд╛рди рдореЗрдВ рдЗрд╕ 'рддрдирд╛рд╡' рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХреНрд▓реЛрдЬрд░ рдХреЛ рд╕реАрдзреЗ f рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╣рдо рдХреБрдЫ рд╣рдж рддрдХ рдмреЗрд╣рддрд░ рддреНрд░реБрдЯрд┐ рджреЗрддреЗ рд╣реИрдВ :

error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
  --> src/main.rs:19:19
   |
19 |       let closure = || { // doesn't work
   |  ___________________^
20 | |         *if true {a} else {b} = 42;
21 | |     };
   | |_____^
22 |       foo.bar.f(closure);
   |               - the requirement to implement `FnMut` derives from here
   |
note: closure is `FnOnce` because it moves the variable `a` out of its environment
  --> src/main.rs:20:19
   |
20 |         *if true {a} else {b} = 42;
   |                

рдпрд╣ рдПрдХ рдмрдВрдж рд╣реИ "рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛" рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдо рддрдп рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ @estebank (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐? рдпрд╛ рдпрд╣ рдХрд┐рд╕реА рдФрд░ рдерд╛ ...) рдореЗрдВ рдбрд╛рд▓ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рдХрд╛рд░рдг рд╣реИред рдЕрднреА, рд╡рд╣ рдЬрд╛рдБрдЪ рдЪрд▓рди рдореЗрдВ рдирд╣реАрдВ рдЖ рд░рд╣реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рддрдп рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдмрдВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП FnMut рдХреЗрд╡рд▓ f рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдХрд╛рд░рдгред

рдЗрд╕ рдХреЛрдб рдореЗрдВ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ:

https://github.com/rust-lang/rust/blob/70f7d5842f29d4900f24420b030f144d21f3c5fc/src/librustc_typeck/check/closure.rs#L151 -L155

рдЬрдм рд╣рдо рдЙрд╕ рд░рд╛рд╕реНрддреЗ рд╕реЗ рдиреАрдЪреЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрднреА рднреА рдЗрд╕ рддрд░рд╣ рдХреЗ "рдореВрд▓" рдХреЛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдкрд╡рд░ рдЕрдиреБрдорд╛рди рдЬреЛ рдЕрдиреНрдпрдерд╛ рдХрд┐рдХ рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ:

https://github.com/rust-lang/rust/blob/70f7d5842f29d4900f24420b030f144d21f3c5fc/src/librustc_typeck/check/upvar.rs#L182 -L188

рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╕рдВрднрд╡рдд: closure_kind_origins_mut рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рдЙрдзрд╛рд░ рдЬрд╛рдВрдЪ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддрдм рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ:

error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
  --> src/main.rs:20:19
   |
17 |     let a = &mut foo.a;
   |         - captured outer variable
...
20 |         *if true {a} else {b} = 42;
   |                   ^ cannot move out of captured outer variable in an `FnMut` closure
note: closure is `FnMut` because of the requirements of `f()`
  --> src/main.rs:19:19
   |
19 |         foo.bar.f(||
   |         ^^^^^^^^^
   |            

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

рдпрджрд┐ рдЖрдк FnMut рдХреЛ FnOnce рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдпрд╣ FnMut рдХреЗ рд╕рд╛рде рднреА рдХрд╛рдо рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛?

(рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ, рддреНрд░реБрдЯрд┐ рдпрд╣ рдХрд╣рдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕реЗ FnOnce рддрдм рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред)

@ рдмреЙрд╕реНрдХреЛрдк рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЪреАрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ FnMut рдмрдВрдж рдХреЛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

(рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ, рддреНрд░реБрдЯрд┐ рдпрд╣ рдХрд╣рдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕реЗ FnOnce рддрдм рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред)

рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрд╕рд╣рдордд рднреА рдирд╣реАрдВ рд╣реВрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рдХрд╛ рдирд┐рджрд╛рди рдХрд░рдирд╛ рдЕрдХреНрд╕рд░ рдХрдард┐рди рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдПрдХ рддрд░рд╣ рдХрд╛ рддрдирд╛рд╡ рд╣реИ: рдХреНрд▓реЛрдЬрд░ рдПрдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ (рдПрдХ рдЪрд╛рд▓) рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди f рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ (рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд▓реЛрдЬрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред рдпрд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рддреНрд░реБрдЯрд┐ рдореЗрдВ рд╣реИ (рдЗрд╕реЗ FnOnce рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП) рдпрд╛ рдмрдВрдж рдХрд░рдирд╛ рдЧрд▓рдд рд╣реИ (рдпрд╣ рдЙрди рдЪреАрдЬреЛрдВ рдХреЛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП)ред рдХрдо рд╕реЗ рдХрдо, рд╣рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рджрд╛рди рдореЗрдВ рдЗрд╕ 'рддрдирд╛рд╡' рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХреНрд▓реЛрдЬрд░ рдХреЛ рд╕реАрдзреЗ f рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд╣рдо рдХреБрдЫ рд╣рдж рддрдХ рдмреЗрд╣рддрд░ рддреНрд░реБрдЯрд┐ рджреЗрддреЗ рд╣реИрдВ :

error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
  --> src/main.rs:19:19
   |
19 |       let closure = || { // doesn't work
   |  ___________________^
20 | |         *if true {a} else {b} = 42;
21 | |     };
   | |_____^
22 |       foo.bar.f(closure);
   |               - the requirement to implement `FnMut` derives from here
   |
note: closure is `FnOnce` because it moves the variable `a` out of its environment
  --> src/main.rs:20:19
   |
20 |         *if true {a} else {b} = 42;
   |                

рдпрд╣ рдПрдХ рдмрдВрдж рд╣реИ "рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛" рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдо рддрдп рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ @estebank (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐? рдпрд╛ рдпрд╣ рдХрд┐рд╕реА рдФрд░ рдерд╛ ...) рдореЗрдВ рдбрд╛рд▓ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рдХрд╛рд░рдг рд╣реИред рдЕрднреА, рд╡рд╣ рдЬрд╛рдБрдЪ рдЪрд▓рди рдореЗрдВ рдирд╣реАрдВ рдЖ рд░рд╣реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рддрдп рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдмрдВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП FnMut рдХреЗрд╡рд▓ f рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдХрд╛рд░рдгред

рдЗрд╕ рдХреЛрдб рдореЗрдВ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ:

https://github.com/rust-lang/rust/blob/70f7d5842f29d4900f24420b030f144d21f3c5fc/src/librustc_typeck/check/closure.rs#L151 -L155

рдЬрдм рд╣рдо рдЙрд╕ рд░рд╛рд╕реНрддреЗ рд╕реЗ рдиреАрдЪреЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрднреА рднреА рдЗрд╕ рддрд░рд╣ рдХреЗ "рдореВрд▓" рдХреЛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдкрд╡рд░ рдЕрдиреБрдорд╛рди рдЬреЛ рдЕрдиреНрдпрдерд╛ рдХрд┐рдХ рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ:

https://github.com/rust-lang/rust/blob/70f7d5842f29d4900f24420b030f144d21f3c5fc/src/librustc_typeck/check/upvar.rs#L182 -L188

рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд╕рдВрднрд╡рдд: closure_kind_origins_mut рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рдЙрдзрд╛рд░ рдЬрд╛рдВрдЪ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддрдм рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ:

error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
  --> src/main.rs:20:19
   |
17 |     let a = &mut foo.a;
   |         - captured outer variable
...
20 |         *if true {a} else {b} = 42;
   |                   ^ cannot move out of captured outer variable in an `FnMut` closure
note: closure is `FnMut` because of the requirements of `f()`
  --> src/main.rs:19:19
   |
19 |         foo.bar.f(||
   |         ^^^^^^^^^
   |            
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

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

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

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

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

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

lambda-fairy picture lambda-fairy  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ