Rust: decl_macro: рдЖрдпрд╛рдд рдХреНрд░реЙрд╕-рдХреНрд░реЗрдЯ рдЗрдирд╡реЛрдХреЗрд╢рди рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ

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

рдиреНрдпреВрдирддрдо рдкреНрд░рдЬрдирди:

// src/lib.rs
#![feature(decl_macro)]

pub macro use_fmt {
    () => {
        use std::fmt;
    }
}

// examples/test.rs
#![feature(use_extern_macros)]

extern crate macro_test;

use macro_test::use_fmt;

use_fmt!();

fn main() {}
The error:
$ cargo build --example test
   Compiling macro-test v0.1.0 (file:///.../macro-test)
error[E0432]: unresolved import `std::fmt`
 --> examples/test.rs:7:1
  |
7 | use_fmt!();
  | ^^^^^^^^^^^ Could not find `std` in `{{root}}`
  |
  = note: this error originates in a macro outside of the current crate

error: aborting due to previous error(s)

error: Could not compile `macro-test`.

рдореИрдХреНрд░реЛ рдХреЛ рдЙрд╕реА рдЯреЛрдХрд░реЗ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛, рдЬреИрд╕рд╛ рдХрд┐ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рд╕реАрд╕реА @jseyfried

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

рдЗрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рджреЗрд░реА рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред #46419 рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ред

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

рдЗрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рджреЗрд░реА рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред #46419 рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рд╡рд╣реА рдореБрджреНрджрд╛ рд╣реИ (рдФрд░ рдпрджрд┐ рдкреАрдЖрд░ рдиреЗ рдЗрд╕реЗ рдареАрдХ рдХрд┐рдпрд╛ рд╣реИ), рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд╡рд╣реА рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ proc_macro ред
рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдПрдХ рдиреНрдпреВрдирддрдо рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рд╡рд╣реА рдореБрджреНрджрд╛ рд╣реИ?
рдЬрдм рдореИрдВ cargo build рдЪрд▓рд╛рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдирд┐рдореНрди рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдорд┐рд▓рддреА рд╣реИрдВ:

error[E0433]: failed to resolve. Could not find `postgres` in `{{root}}`
 --> src/lib.rs:9:17
  |
9 | #[derive(Debug, SqlTable)]
  |                 ^^^^^^^^ Could not find `postgres` in `{{root}}`

error[E0433]: failed to resolve. Could not find `std` in `{{root}}`
 --> src/lib.rs:9:17
  |
9 | #[derive(Debug, SqlTable)]
  |                 ^^^^^^^^ Could not find `std` in `{{root}}`

error[E0412]: cannot find type `Table` in this scope
 --> src/lib.rs:9:17
  |
9 | #[derive(Debug, SqlTable)]
  |                 ^^^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
  |
3 | use Table;
  |

рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХрд╛ рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рд╣реИ?
рдзрдиреНрдпрд╡рд╛рджред

@antoyo рдпрд╣ рд╕реНрд╡рдЪреНрдЫрддрд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред

рдЪреВрдВрдХрд┐ ::postgres::types::Type рдкреНрд░реЛ-рдореИрдХреНрд░реЛ рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рд╣реИ, рдпрд╣ рдореИрдХреНрд░реЛ рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рджрд╛рдпрд░реЗ рдореЗрдВ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдпрд╣ рд╡рд╣реА рд╣рд▓ рдХрд░реЗрдЧрд╛ рдЬрд╣рд╛рдВ рдореИрдХреНрд░реЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдкреНрд░реЛ-рдореИрдХреНрд░реЛ рдХреНрд░реЗрдЯ рд░реВрдЯ рдкрд░ рдХреЛрдИ extern crate postgres; , рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИред рдкреНрд░реЛ-рдореИрдХреНрд░реЛ рдХреНрд░реЗрдЯ рд░реВрдЯ рдореЗрдВ рдХреЗрд╡рд▓ extern crate postgres; рдЬреЛрдбрд╝рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЪреВрдВрдХрд┐ рдкреНрд░реЛ-рдореИрдХреНрд░реЛ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реЛрд╕реНрдЯ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо (рдЪрд░рдг 0) рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ, рди рдХрд┐ рд▓рдХреНрд╖реНрдп рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо (рдЪрд░рдг 1) рдФрд░ рдЗрд╕рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░ рдЙрдиреНрд╣реЗрдВ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддрд╛ред

рдпрд╣рд╛рдВ рд╕рдорд╛рдзрд╛рди https://github.com/rust-lang/rust/issues/45934#issuecomment -344497531 рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдкреНрд░реЛ-рдореИрдХреНрд░реЛ рдХреНрд░реЗрдЯ рдореЗрдВ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реИред

рдЕрднреА рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдореИрдХреНрд░реЛ рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ extern crate postgres; рдбрд╛рд▓рдирд╛ рд╣реЛрдЧрд╛ред рд╕реНрд╡рдЪреНрдЫрддрд╛ рдХреЗ рдХрд╛рд░рдг, рдпрд╣ рдЖрдордВрддреНрд░рдг рд╕рд╛рдЗрдЯ рдкрд░ postgres рдирд╛рдо рдХреА рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рд╕реЗ рд╡рд┐рд░реЛрдз рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдореИрдХреНрд░реЛ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдЖрджрд┐ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

            quote! {
                extern crate std;
                extern crate postgres;
                use std::io::Write;
                use postgres::types::{IsNull, ToSql, Type};

                impl ToSql for #table_ident {
                    fn to_sql<W: Write + ?Sized>(&self, ty: &Type, out: &mut W) -> postgres::Result<IsNull> {
                        self.#primary_key_ident.to_sql(ty, out)
                    }

                    fn accepts(ty: &Type) -> bool {
                        match *ty {
                            Type::Int4 => true,
                            _ => false,
                        }
                    }

                    fn to_sql_checked(&self, ty: &Type, out: &mut Write) -> postgres::Result<IsNull> {
                        if !<Self as ToSql>::accepts(ty) {
                            return Err(postgres::error::Error::WrongType(ty.clone()));
                        }
                        self.to_sql(ty, out)
                    }
                }
            }

рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдХреЙрд▓ рд╕рд╛рдЗрдЯ рдкрд░ (рдЕрд╕реНрд╡рдЪреНрдЫрддрд╛ рд╕реЗ) Span::call_site() ( quote! рд╕реЗ рдЯреЛрдХрди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ Span::def_site() рджреЗрдХрд░) рджреЗрдХрд░ ::postgres::types::Type рд╕рдорд╛рдзрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЬрд▓реНрдж рд╣реА, spanned_quote!(span, tokens...) рдЗрд╕реЗ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛ред

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

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

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

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

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

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

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