Rust: RFC 1566์— ๋Œ€ํ•œ ์ถ”์  ๋ฌธ์ œ: ์ ˆ์ฐจ์  ๋งคํฌ๋กœ

์— ๋งŒ๋“  2016๋…„ 12์›” 14์ผ  ยท  184์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: rust-lang/rust

ํ˜„์žฌ ์ƒํƒœ

์ด ๋ฌธ์ œ๋Š” ๋ณด๋‹ค ์„ธ๋ถ„ํ™”๋œ ์ถ”์  ๋ฌธ์ œ๋ฅผ ์œ„ํ•ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

~์—…๋ฐ์ดํŠธ๋œ ์„ค๋ช… ~

๋‹ค์Œ ๋‹จ๊ณ„:

  • [x] [ use_extern_macros ์•ˆ์ •ํ™” ](https://github.com/rust-lang/rust/pull/50911)

    • ๋ถ„ํ™”๊ตฌ์—์„œ ๊ธฐ๋‹ค๋ฆฌ๊ณ 

  • [ ] proc_macro ๊ธฐ๋Šฅ ์•ˆ์ •ํ™”

๊ฐ€๋Šฅํ•œ ์•ˆ์ •ํ™” ์‡ผ์Šคํ† ํผ

์›๋ณธ ์„ค๋ช…

RFC .

์ด RFC๋Š” Rust์˜ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ์‹œ์Šคํ…œ(์ผ๋ช… ๊ตฌ๋ฌธ
ํ™•์žฅ, ์ผ๋ช… ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋Ÿฌ๊ทธ์ธ). ์ด RFC๋Š” ์ •์˜์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
์ ˆ์ฐจ์  ๋งคํฌ๋กœ, ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ์˜ ๊ตฌํ˜„์— ๋Œ€ํ•œ ์ƒ์œ„ ์ˆ˜์ค€ ๋ณด๊ธฐ,
์ปดํŒŒ์ผ ํ”„๋กœ์„ธ์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ๋งคํฌ๋กœ๋Š” ๋‹ค์Œ์œผ๋กœ ํ‘œ์‹œ๋œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์—ฌ ์ •์˜๋ฉ๋‹ˆ๋‹ค.
#[macro] ์†์„ฑ. ๋งคํฌ๋กœ๋Š” ๋‹ค์Œ์—์„œ ์ œ๊ณตํ•˜๋Š” ํ† ํฐ ๋ชฉ๋ก์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋งคํฌ๋กœ ์‚ฌ์šฉ์ด ๋Œ€์ฒด๋˜๋Š” ํ† ํฐ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ
์ด๋Ÿฌํ•œ ํ† ํฐ์—์„œ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•œ ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋” ๋†’์€ ๋‹จ๊ณ„
๊ธฐ๋Šฅ(์˜ˆ: AST์— ๋Œ€ํ•œ ํ† ํฐ ๊ตฌ๋ฌธ ๋ถ„์„์šฉ)์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌ๋ ˆ์ดํŠธ๋กœ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋กœ๋“œ๋งต: https://github.com/rust-lang/rust/issues/38356#issuecomment -274377210.


์ž‘์—…

  • [x] #[proc_macro_attribute] ๊ตฌํ˜„(PR #38842).

    • [x] ์ˆ˜์ • #39347(PR #39572).

    • [x] ์ˆ˜์ • #39336(PR #44528).

  • [x] #[proc_macro] ๊ตฌํ˜„(PR #40129).
  • [x] InvocationCollector ์—์„œ proc_macro_derive ์˜ ์šฉ๋„๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค(PR #39391).
  • [x] ๋งคํฌ๋กœ ํ™•์žฅ proc_macro_derive ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

    • ์˜ˆ๋ฅผ ๋“ค์–ด:

#[derive(Trait, OtherTrait)] struct S; // Both these derives should resolve
macro_rules! m { () => {
    #[macro_use(Trait)] extern crate derives;
    use derives::OtherTrait; // this kind of import is gated behind `#![feature(proc_macro)]`
} }
m!();
  • [ ] ์ ์šฉ๋œ proc_macro_derive s(PR #48465)๋ฅผ ํ™•์žฅํ•˜๊ธฐ ์ „์— ํ•ญ๋ชฉ์„ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.
  • [x] ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ #[macro_use] ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค(PR #39060).
  • [x] ํ† ํฐ ํŠธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํŒŒ์„œ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค(PR #39118).
  • [x] ์ถ”๊ฐ€ ๋ฆฌํŒฉํ† ๋ง์„ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด TokenStream ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค(PR #39173).
  • [x] TokenTree::Sequence ์ œ๊ฑฐ(PR #39419).
  • [x] tokenstream::TokenTree ์˜ Delimited ๋ณ€ํ˜•์—์„œ tokenstream::TokenTree Vec<TokenTree> ๋Œ€์‹  TokenStream s๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(PR #40202).
  • [x] Path s์—์„œ TokenStream ast::Attribute s(PR #40346)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • [x] ์†์„ฑ/ํŒŒ์ƒ ๋งคํฌ๋กœ์—์„œ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ๋กœ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: #[foo::bar] , #[derive(foo::Bar)] ).

  • [x] ์‹๋ณ„์ž๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ํ† ํฐ๊ณผ ํ•จ๊ป˜ ์œ„์ƒ ์ •๋ณด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค(PR #40597).
  • [x] RFC(PR #40939)์— ์„ค๋ช…๋œ ๋Œ€๋กœ proc_macro::TokenStream ๋Œ€ํ•œ ์ตœ์†Œ API๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

    • [x] Token::Interpolated ํ† ํฐ์˜ ๋ณด๊ฐ„๋œ AST ์กฐ๊ฐ์— ๋Œ€ํ•œ ์†Œ์Šค TokenStream ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

    • [x] proc_macro ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ ๋’ค์— TokenStream ์ธ์šฉ์ž proc_macro::quote! ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

  • [x] proc_macro ์ž‘์„ฑ์ž๊ฐ€ ๋งคํฌ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํฌ๋ ˆ์ดํŠธ ๋ฃจํŠธ์— extern crate foo; ๋ฅผ ํฌํ•จํ•  ํ•„์š” ์—†์ด ๋ฏธ๋ฆฌ ๊ฒฐ์ •๋œ ํฌ๋ ˆ์ดํŠธ foo ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜๋Š” ํ™•์žฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค(PR # 40939).

    • [ ] ์ธ์ฒด ๊ณตํ•™์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • [ ] AST์˜ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์†Œ์Šค TokenStream ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • [ ] ์•ˆ์ •์„ฑ ๊ฒ€์‚ฌ(proc-) ๋งคํฌ๋กœ(๋ฌธ์ œ #34079).
  • [x] proc ๋งคํฌ๋กœ๊ฐ€ def_site ๊ฐ’์œผ๋กœ ๊ฐœ์ธ ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค(๋ฌธ์ œ #47311). (PR #48082)
  • [x] proc ๋งคํฌ๋กœ์—์„œ ์ค‘๊ด„ํ˜ธ ๊ตฌ์กฐ์ฒด ๋Œ€ ํŠœํ”Œ ๊ตฌ์กฐ์ฒด์˜ ํ•„๋“œ ์•ก์„ธ์Šค ๊ฐ„์˜ ๋ถˆ์ผ์น˜(๋ฌธ์ œ #47312). (PR #48083)
  • [ ] 1๋‹จ๊ณ„์—์„œ ๋งคํฌ๋กœ ๋ฃจํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ std๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค(๋ฌธ์ œ #47314).
  • [x] proc_macro::quote! ๋‚ด๋ถ€์˜ ์ž˜๋ชป๋œ ๊ตฌ๋ฌธ์œผ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค(๋ฌธ์ œ #47315).
  • [ ] ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜๋Š” TokenStream์— ๋Œ€ํ•œ Display์™€ IntoIterator ๊ฐ„์˜ ๋ถˆ์ผ์น˜(๋ฌธ์ œ #47627).
  • [x] #[cfg_attr]๋กœ ์ธํ•ด .to_string()๊ณผ TokenStream์ด ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋ฌธ์ œ #48644).
  • [x] libproc_macro์— ๋Œ€ํ•œ ์œ„์‹œ๋ฆฌ์ŠคํŠธ(#47786์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ).
A-macros A-macros-1.2 A-macros-2.0 A-plugin B-RFC-approved B-unstable C-tracking-issue T-lang T-libs finished-final-comment-period

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ข‹์•„, ์ด ๋ฌธ์ œ๋Š” ๋ฐฉ๋Œ€ ํ•˜๊ณ  ๋” ์ด์ƒ ์—ด๋ ค ์žˆ๊ณ  API๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ์œ ์šฉํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ง€์ ์— ์ด๋ฅด๋ €์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด https://github.com/rust-lang/rust/pull/54728 ์„ ์—ด์–ด ์ด ๋ฌธ์ œ๋ฅผ ๋ณด๋‹ค ์„ธ๋ถ„ํ™”๋œ ์—ฌ๋Ÿฌ ์ถ”์  ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค.

์ด ์‹œ์ ์—์„œ ๋‚˜๋Š” ์ด๊ฒƒ์„ ๋‹ซ์„ ๊ฒƒ์ด์ง€๋งŒ ๋‹ค๋ฅธ ์ถ”์  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์žŠ์€ ๊ฒฝ์šฐ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค! ๋‚˜๋Š” ํ™•์‹คํžˆ ๋” ๋งŽ์€ ํ›„์† ์กฐ์น˜๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

๋ชจ๋“  184 ๋Œ“๊ธ€

cc @nrc @jseyfried

#[proc_macro_attribute] ์ด ๊ณง ๊ตฌํ˜„๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๋ฏธ ์ปดํŒŒ์ผ๋Ÿฌ ์ง€์›์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๊ธฐ ์ „์— ์พ…์พ… ์†Œ๋ฆฌ๋ฅผ ๋‚ธ ํ”„๋กœํ† ํƒ€์ž…๊ณผ ํ…Œ์ŠคํŠธ ์‚ฌ์šฉ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค :unamused: :

ํ”„๋กœํ† ํƒ€์ž…: https://github.com/abonander/anterofit/blob/proc_macro/macros/src/lib.rs
์˜ˆ/ํ…Œ์ŠคํŠธ: https://github.com/abonander/anterofit/blob/proc_macro/examples/post_service_proc_macro.rs

์ž‘์—…

(dtolnay ํŽธ์ง‘: ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ OP๋กœ ์ด๋™)

cc @nrc @petrochenkov @durka @Ralith

@jseyfried ๋ ˆ๊ฑฐ์‹œ ๋งคํฌ๋กœ์™€ ์ด๋ฆ„์ด ๊ฐ™์€ ์†์„ฑ์„ ๋™์ผํ•œ ๋ฒ”์œ„๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋งคํฌ๋กœ๋ฅผ ์†์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ๊ฐ™์€ ๋ฒ”์œ„์— ์žˆ๊ณ  ์˜๋„ํ•œ ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@abonander ๋ชจ๋“  ๋งคํฌ๋กœ(๋ฑ…, ์†์„ฑ ๋ฐ ํŒŒ์ƒ)๋Š” ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ณต์œ ํ•˜๋ฏ€๋กœ ๋™์ผํ•œ ๋ฒ”์œ„์—์„œ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

ํŒŒํ‹ฐ์— ๋Šฆ์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. AST๊ฐ€ ์•„๋‹Œ ํ† ํฐ์„ ๋…ธ์ถœํ•˜๋Š” ๋ฐฉํ–ฅ์— ๋งŒ์กฑํ•˜์ง€๋งŒ RFC์—์„œ ์ œ์•ˆ๋œ ํŠน์ • TokenStream API์— ๋Œ€ํ•ด ๋ช‡ ๊ฐ€์ง€ ์šฐ๋ ค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

pub enum TokenKind {
    Sequence(Delimiter, TokenStream),

    // The content of the comment can be found from the span.
    Comment(CommentKind),

    // `text` is the string contents, not including delimiters. It would be nice
    // to avoid an allocation in the common case that the string is in the
    // source code. We might be able to use `&'codemap str` or something.
    // `raw_markers` is for the count of `#`s if the string is a raw string. If
    // the string is not raw, then it will be `None`.
    String { text: Symbol, raw_markers: Option<usize>, kind: StringKind },

    // char literal, span includes the `'` delimiters.
    Char(char),

    // These tokens are treated specially since they are used for macro
    // expansion or delimiting items.
    Exclamation,  // `!`
    Dollar,       // `$`
    // Not actually sure if we need this or if semicolons can be treated like
    // other punctuation.
    Semicolon,    // `;`
    Eof,          // Do we need this?

    // Word is defined by Unicode Standard Annex 31 -
    // [Unicode Identifier and Pattern Syntax](http://unicode.org/reports/tr31/)
    Word(Symbol),
    Punctuation(char),
}

pub enum StringKind {
    Regular,
    Byte,
}

์ด API๊ฐ€ RFC๊ฐ€ ๋ณ‘ํ•ฉ๋  ๋•Œ ์ˆ˜๋ฝ๋œ ์™„์ „ํ•œ ๊ณ„ํš์œผ๋กœ ์˜๋„๋œ ๊ฒƒ์ธ์ง€ ์•„๋‹ˆ๋ฉด ๋‚˜์ค‘์— ํ•ด๊ฒฐ๋  ์˜ˆ์‹œ์ผ ๋ฟ์ธ์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ด๊ฒƒ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋งคํฌ๋กœ ์™ธ๋ถ€์—์„œ ํ—ˆ์šฉํ•˜๋Š” "์ •์ƒ์ ์ธ" Rust ๊ตฌ๋ฌธ๊ณผ๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋จผ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋งคํฌ๋กœ๋Š” ์ผ๋ถ€ ์ž„์‹œ ๋„๋ฉ”์ธ ํŠน์ • ์–ธ์–ด๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋ ค๋Š” ๋ฐ˜๋ฉด ๋‹ค๋ฅธ ๋งคํฌ๋กœ๋Š” "์‹ค์ œ Rust" ๊ตฌ๋ฌธ์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. (Minor) Eof ๋Š” ํ•„์š” ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Iterator ๋Š” TokenStream ๋ฐ˜๋ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ Iterator::next ์ด๋ฏธ None ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋ฐ˜๋ณต์˜ ๋์„ ์•Œ๋ฆฌ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  2. (์‚ฌ์†Œํ•œ) Exclamation , Dollar ๋˜๋Š” Semicolon ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Punctuation('!') ์—์„œ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์€ ๋” ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  3. (์‚ฌ์†Œ) ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด RFC PR์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋ฌธ์„œ ์ฃผ์„์ด ์•„๋‹Œ ์ฃผ์„์€ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ฃผ์„์„ ๋ณด์กดํ•˜๋ ค๋Š” ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๊ณต๋ฐฑ๋„ ๋ณด์กดํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

  4. ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ, ๋‹ค์ค‘ ๋ฌธ์ž ์—ฐ์‚ฐ์ž(๊ฐ๊ฐ ๋‹จ์ผ ํ† ํฐ์ด์–ด์•ผ ํ•จ)๋กœ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€๋Š” ์—ฌ์ „ํžˆ ๋ฏธํ•ด๊ฒฐ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜ ์€ PR ์ฃผ์„์— ์„ค๋ช…๋˜์–ด ์žˆ์ง€๋งŒ RFC ํ…์ŠคํŠธ์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  5. ์ˆซ์ž ๋ฆฌํ„ฐ๋Ÿด์ด ์—†์Šต๋‹ˆ๋‹ค. ๋งคํฌ๋กœ๋Š” ๋ฆฌํ„ฐ๋Ÿด์„ ํ‰๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฒด์ ์œผ๋กœ [Punct('1'), Punct('_'), Punct('2'), Punct('3'), Punct('4'), Punct('.'), Punct('5'), Punct('e'), Punct('6')] ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ํ—ˆ์šฉํ•˜๋Š” ๊ตฌ๋ฌธ์ด Rust ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ(์˜ˆ๋ฅผ ๋“ค์–ด ์ค‘๊ฐ„์— _ ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Œ)๊ณผ ๋™์ผํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋“ค์€ ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด str::parse::<f32> ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค.

    ์—ฌ๊ธฐ์— ์•ˆ์ •์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. u128 / i128 (๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ๋ฏธ๋ž˜์—๋Š” f128 , u256 , ...)์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ์ˆซ์ž ์œ ํ˜•๊ณผ ํ•ด๋‹น ๋ฆฌํ„ฐ๋Ÿด์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํ† ํฐ API? ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    struct IntegerLiteral { negative: bool, decimal_digits: String, type_suffix: Option<String> }
    impl TryInto<u32> IntegerLiteral { type Err = OutOfRange; /* โ€ฆ */ }
    // Other impls for integer types supported in this compiler version
    
    // Something similarly for floats
    

    ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ๊ฒƒ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” "์ˆซ์ž๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฒ™"ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  6. // Word๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ํ‘œ์ค€ ๋ถ€๋ก 31์— ์˜ํ•ด ์ •์˜๋ฉ๋‹ˆ๋‹ค. -

    ์ด ์ •์˜๋Š” ๊ทธ๋ณด๋‹ค ๋” ์ •ํ™•ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. UAX 31์€ ์‹๋ณ„์ž ๊ตฌ๋ฌธ์˜ ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ณ€ํ˜•์„ ์ง€์ •ํ•˜๋ฉฐ ๊ทธ ์ค‘ ์–ด๋Š ๊ฒƒ๋„ "๋‹จ์–ด"๋ผ๊ณ  ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์ •ํ™•ํ•œ ๋ณ€ํ˜•์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ํ˜„์žฌ ๋น„ASCII ์‹๋ณ„์ž์— ๊ธฐ๋Šฅ์ด ์ œํ•œ๋œ ์ด์œ ์ž…๋‹ˆ๋‹ค.

    ๋Œ€์‹  "ํ˜„์žฌ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‹๋ณ„์ž ๋˜๋Š” ํ‚ค์›Œ๋“œ๋กœ ํ—ˆ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ"(#28979์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ)์œผ๋กœ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. libmacro์— pub fn is_identifier(&str) -> bool ๊ณต๊ฐœ API๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  7. ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž์—ด๊ณผ ๋ฐ”์ดํŠธ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์€ ๋‹จ์ผ ํ† ํฐ ๋ณ€ํ˜•์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์˜ ๋ฉ”๋ชจ๋ฆฌ ํ‘œํ˜„์ด ๋‹ค๋ฅธ ์œ ํ˜•( str vs [u8] )์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. text: Symbol ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์†Œ์Šค ์ฝ”๋“œ์˜ ๋ฆฌํ„ฐ๋Ÿด ์Šฌ๋ผ์ด์Šค์ธ์ง€ ๋˜๋Š” ๋ฐฑ์Šฌ๋ž˜์‹œ ์ด์Šค์ผ€์ดํ”„๋ฅผ ํ•ด๊ฒฐํ•œ ํ›„์˜ ๊ฐ’์ธ์ง€๋„ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์—ฐํžˆ ํ›„์ž์—ฌ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. (๋น„๊ต๋ฅผ ์œ„ํ•ด \u{A0} ๋Š” ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๋‘˜ ์ด์ƒ์˜ char ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ Char(char) ๋Š” ํ›„์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

๋†’์€ ์ˆ˜์ค€์˜ ๋งคํฌ๋กœ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๋งคํฌ๋กœ์™€ ๊ฐ™์€ lisp๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์ด๊ฒƒ์€ ์ „์ฒด rust ast์— ๋Œ€ํ•œ s-ํ‘œํ˜„์‹ ํ‘œํ˜„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@SimonSapin ,

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด RFC PR์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์šฐ๋ฆฌ๋Š” ๋ฌธ์„œ ์ฃผ์„์ด ์•„๋‹Œ ์ฃผ์„์„ ์ƒ๋žตํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (์ฃผ์„์„ ๋ณด์กดํ•˜๋ ค๋Š” ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๊ณต๋ฐฑ๋„ ๋ณด์กดํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

ํ•˜์ง€ ๋งˆ์„ธ์š”. ๊ตฌ๋ฌธ์—์„œ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(๋ณด์กด์€ ์•„๋‹ˆ์ง€๋งŒ ๋Œ€์‹  ๋ณ„๋„์˜ ์ปดํŒŒ์ผ ์ œํ’ˆ์— ์ž‘์„ฑ๋จ).

ํŠนํžˆ, ๋ณ„๋„์˜ ์†Œ์Šค ํŒŒ์ผ์—์„œ ๋ฌธ์ž์—ด ๋ฒˆ์—ญ์„ ๋กœ๋“œํ•˜๋Š” ๋ฒˆ์—ญ ๋งคํฌ๋กœ๋ฅผ ๋งŒ๋“ค๊ณ  ๋””๋ฒ„๊ทธ ๋นŒ๋“œ์—์„œ ๋ถ€์‚ฐ๋ฌผ๋กœ ๋ฒˆ์—ญ๋  ๋ฌธ์ž์—ด ๋ชฉ๋ก์„ ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ชฉ๋ก(rust-locale/rust-locale#19)์— ๋‚ด๋ณด๋‚ผ ์ฃผ์„์„ ํฌํ•จํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฃผ์„ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๋ฉฐ ๋งคํฌ๋กœ๊ฐ€ ์ฃผ์„ ๊ตฌ๋ฌธ์„ ๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ ๊ฒŒ์‹œ๋ฌผ์˜ ๋‹ค๋ฅธ ์š”์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

@jan-hudec
TokenKind::Comment ๊ฐ€ ์—†๋”๋ผ๋„ ์—ฐ์† ํ† ํฐ ์‚ฌ์ด์˜ ๋ฒ”์œ„ ๋‚ด์šฉ์„ ๋ณด๊ณ  ์ฃผ์„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ์˜๋ฏธ ์ฒด๊ณ„ ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜์ง€ ์•Š๊ณ  ๋งคํฌ๋กœ ํ˜ธ์ถœ์— ์ฃผ์„์„ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ์ฃผ์„์„ ๋ฌด์‹œํ•˜๋„๋ก ์žฅ๋ คํ•˜๊ธฐ ์œ„ํ•ด TokenKind::Comment ๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@jan-hudec ์†์„ฑ์ด ์†”๋ฃจ์…˜์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@abonander , ์†์„ฑ์€ ์ ˆ๋Œ€์ ์œผ๋กœ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ฒˆ์—ญ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž์—ด์€ ํ•ญ๋ชฉ์ด ์•„๋‹Œ ๋ฆฌํ„ฐ๋Ÿด๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผํ•˜๋Š” ๋™์•ˆ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์€ ๋‹จ์ง€ ํŽธ์˜๋ฅผ ์œ„ํ•œ ๊ฒƒ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ํ•ญ์ƒ ๋ณ„๋„์˜ ๊ตฌ๋ฌธ ๋ถ„์„์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์‚ฌ์‹ค, ๊ฒฐ๊ตญ ๊ทธ๋ ‡๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํฌ๋ ˆ์ดํŠธ์—์„œ _๋ชจ๋‘_๋ฅผ ๋ณผ ํ•„์š”๊ฐ€ ์žˆ๊ณ  ์ฆ๋ถ„ ์ปดํŒŒ์ผ์€ ์ด๋ฅผ ๊นจ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค).

๋‚˜๋Š” serde ํŒŒ์ƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์ง€๋งŒ(์ง์ ‘์ ์œผ๋กœ serde tokenstream ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ), serde ํŒŒ์ƒ์„ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ์•„๋‹Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งคํฌ๋กœ ํŒŒ์ƒ์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ  '์ผ๋ฐ˜' ์ ˆ์ฐจ ๋งคํฌ๋กœ์—๋„ ๋น„์Šทํ•œ ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋‚ด ์œ ์ผํ•œ ์†”๋ฃจ์…˜์€ serde_derive๋ฅผ ๋ถ„๊ธฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” Rustc์˜ ๋‹ค์Œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค.

error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type

๊ทธ๊ฒƒ์„ ์ œ๊ฑฐํ•˜๊ณ  ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์‰ฝ์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชจ๋ฅด๋Š” ๋ณต์žก์„ฑ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ๋Š” ๋‹ค๋ฅธ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ์—์„œ ํŒŒ์ƒ๋œ proc-macro๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์šด์ŠคํŠธ๋ฆผ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ํŒŒ์ƒ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์„๊นŒ์š”? ์†Œ๋น„ํ•˜๋Š” ์ƒ์ž์˜ ์š”์ฒญ์— ๋”ฐ๋ผ ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ์ƒ์ž๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ด์™€ ๋น„์Šทํ•œ ๊ฒƒ์ด ํ˜„์žฌ ์ฃผ๋ณ€์— ์žˆ์Šต๋‹ˆ๊นŒ?

@aidanhs

์ ˆ์ฐจ์  ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ๋Š” ๋‹ค๋ฅธ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ์—์„œ ํŒŒ์ƒ๋œ proc-macro๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค์šด์ŠคํŠธ๋ฆผ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ํŒŒ์ƒ์„ ์ƒ์„ฑํ•˜๊ธฐ๋ฅผ ์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์„๊นŒ์š”?

proc-macro ํฌ๋ ˆ์ดํŠธ์—์„œ ํ•จ์ˆ˜(๋˜๋Š” ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฒƒ)์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. TokenStream -> TokenStream ํ•จ์ˆ˜์™€ ํ•ด๋‹น ์ ˆ์ฐจ ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด TokenStream -> TokenStream ํ•จ์ˆ˜๋ฅผ proc-macro ์•„๋‹Œ ๋ณ„๋„์˜ ํฌ๋ ˆ์ดํŠธ์— ๋„ฃ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ธฐ๋Šฅ์— ์œ„์ž„ํ•˜๋Š” proc-macro ํฌ๋ ˆ์ดํŠธ์ž…๋‹ˆ๋‹ค.

์ด RFC๋Š” #40939๊ฐ€ ๋„์ฐฉํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

proc_macro ์ž‘์„ฑ์ž๊ฐ€ ๋งคํฌ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํฌ๋ ˆ์ดํŠธ ๋ฃจํŠธ์— extern crate foo; ๋ฅผ ํฌํ•จํ•  ํ•„์š” ์—†์ด ๋ฏธ๋ฆฌ ๊ฒฐ์ •๋œ ํฌ๋ ˆ์ดํŠธ foo ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜๋Š” ํ™•์žฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ œ๊ณต

๋งคํฌ๋กœ๊ฐ€ ์•„๋‹Œ ํ•ญ๋ชฉ๊ณผ ํ•ด๋‹น ํ•ญ๋ชฉ์„ ์ฐธ์กฐํ•˜๋Š” ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๋‹จ์ผ ์ƒ์ž๋ฅผ ์ œ๊ณตํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. #40939๊ฐ€ ์ฐฉ๋ฅ™ํ•˜๋ฉด ์ด 3๊ฐœ์˜ ์ƒ์ž ํŒจํ„ด์ด ์ด ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๊ด€์šฉ์  ๋ฐฉ๋ฒ•์ด ๋ ๊นŒ์š”?

  1. ๋งคํฌ๋กœ๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ํ•ญ๋ชฉ์„ foo_runtime ๋„ฃ์Šต๋‹ˆ๋‹ค.
  2. ํ•„์š”์— ๋”ฐ๋ผ foo_runtime ์˜ ๊ธฐํ˜ธ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ foo_macros ์— ์ ˆ์ฐจ ๋งคํฌ๋กœ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  3. foo_runtime ๋ฐ foo_macros ์˜ ํ•ญ๋ชฉ pub use ์ตœ์ข… "ํŒŒ์‚ฌ๋“œ" ์ƒ์ž foo foo_macros

    • ์ด๊ฒƒ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๊ฐ€์ ธ์˜ฌ ์œ ์ผํ•œ ์ƒ์ž์ž…๋‹ˆ๋‹ค.

    • ์œ„์ƒ ์‹œ์Šคํ…œ์ด ์˜ฌ๋ฐ”๋ฅธ ์ƒ์ž๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋งคํฌ๋กœ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋‘ ๊ฐœ์˜ ํฌ๋ ˆ์ดํŠธ ๋ฅผ

@lfairy "two-crate" ํŒจํ„ด์ด ๊ด€์šฉ์ ์ธ ๋ฐฉ์‹์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. ๋งคํฌ๋กœ๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ํ•ญ๋ชฉ์„ foo ๋„ฃ์Šต๋‹ˆ๋‹ค.
  2. foo_macros ์— ์ ˆ์ฐจ ๋งคํฌ๋กœ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ foo ๊ธฐํ˜ธ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ:
#[proc_macro]
fn m(_: TokenStream) -> TokenStream {
    quote! {
        extern crate foo; // due to hygiene, this is never a conflict error
        foo::f();
        // --- or just --- (if/when we get the sugar)
        $universe::foo::f();
    }
}
  1. pub use foo_macros pub use ํ•ญ๋ชฉ foo .

์œ„์ƒ ์‹œ์Šคํ…œ์ด ์˜ฌ๋ฐ”๋ฅธ ์ƒ์ž๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋งคํฌ๋กœ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ƒ์ž์—์„œ ์ ˆ์ฐจ ๋งคํฌ๋กœ๋ฅผ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๋„ ์ ˆ์ฐจ ๋งคํฌ๋กœ์˜ ์ด๋ฆ„์ด ํ™•์ธ๋˜๋Š” ๋ฐฉ์‹์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@jseyfried : ์ด ์žฌ์ˆ˜์ถœ ํŠธ๋ฆญ์ด ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ์ƒํ’ˆ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š”์ง€ ์•„์‹ญ๋‹ˆ๊นŒ? ์ด๋Ÿฌํ•œ ์ƒ์ž์—๋Š” ํ•ญ๋ชฉ์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ๊ณผ ์ •ํ™•ํžˆ ๋™์ผํ•œ ์ œํ•œ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@colin-kiegel
์ปค์Šคํ…€ ํŒŒ์ƒ ํฌ๋ ˆ์ดํŠธ๋Š” #[proc_macro_derive] ๋งŒ ์žˆ๋Š” proc ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ์ž…๋‹ˆ๋‹ค.
#[feature(proc_macro)] ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ proc ๋งคํฌ๋กœ๋ฅผ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ผ๋ฐ˜ ์ƒ์ž์—์„œ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ์ƒํ’ˆ์„ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@jseyfried ํ˜„์žฌ ์ƒํ™ฉ์„ ์ธ์ง€ํ•˜๊ณ  ์žˆ๊ณ  ์ด์ƒ์ ์ด์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์งˆ๋ฌธ์„

์ฆ‰, ํ˜ธํ™˜์„ฑ ์œ„ํ—˜์„ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค. ๋งคํฌ๋กœ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ •ํ™•ํ•œ ํ† ํฐํŠธ๋ฆฌ๋Š” ์•ˆ์ •์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€๊ฐ€ ๋˜๋ฏ€๋กœ serde๊ฐ€ ํŒจ์น˜ ๋ฒ„์ „์—์„œ Derive ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์ทจ์•ฝํ•œ ๋งคํฌ๋กœ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋งคํฌ๋กœ๋Š” ๋‚ด ์ƒ์ž์˜ ๋ชจ๋“  ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์†์ƒ๋ฉ๋‹ˆ๋‹ค(์ตœ์•…์˜ ๊ฒฝ์šฐ ํŠน์ • ์ž…๋ ฅ์— ๋Œ€ํ•ด์„œ๋งŒ ์ž‘๋™ํ•˜์ง€๋งŒ ์ผ๊ด€๋˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ํ˜„์žฌ์˜ ๊ฒฝ์šฐ ์ทจ์•ฝํ•œ ๋งคํฌ๋กœ์™€ ๋ฐ˜๋Œ€).

@jseyfried

ํ˜„์žฌ ํ™”๋ฌผ ๋ชฉ๋ก์—์„œ foo ๊ฐ€์ ธ์˜ค๋‚˜์š”? ๊ทธ๊ฒƒ์€ ๋‚˜์˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค(์ฆ‰, ํ˜„์žฌ ๋ฐ”์ด๋„ˆ๋ฆฌ์— foo ๋ผ๋Š” ์ด๋ฆ„์˜ 2๊ฐœ์˜ ํฌ๋ ˆ์ดํŠธ๊ฐ€ ๋งํฌ๋˜์–ด ์žˆ๋‹ค๋ฉด ํŠนํžˆ ์–ด๋ฆฌ์„์€ ์ผ์„ ํ•ฉ๋‹ˆ๊นŒ?).

@aidanhs ๊ทธ๊ฒƒ์€ ์ž์ฒด RFC๋ฅผ ๋ณด์ฆํ•˜๋Š” ์ฃผ์š” ์–ธ์–ด ๋ณ€๊ฒฝ/์ถ”๊ฐ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@arielb1

ํ˜„์žฌ ํ™”๋ฌผ ๋ชฉ๋ก์—์„œ foo ๊ฐ€์ ธ์˜ค๋‚˜์š”? ๋‚˜์œ ์†Œ๋ฆฌ

์˜ˆ -- ์Šฌํ”„๊ฒŒ๋„ ์ธ์šฉ๋œ extern crate ์ด๋ฆ„์€ ์œ„์ƒ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ•ด์ƒ๋„๋Š” ์ ˆ์ฐจ ๋งคํฌ๋กœ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋ฒ”์œ„์— ์žˆ๋Š” ํฌ๋ ˆ์ดํŠธ ์ด๋ฆ„์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๊ธฐ ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ(์ฆ‰, foo ์—์„œ foo_macros ๋ฅผ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด์–ด foo ๊ฐ€ ๋ฒ”์œ„ ๋‚ด์— ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Œ) foo ๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ƒ์ž๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ชจํ˜ธ์„ฑ ์˜ค๋ฅ˜์— ๋Œ€๋น„ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ๊ฐ€์žฅ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์€ --target-extern ๋ช…๋ น์ค„ ์ธ์ˆ˜๋ฅผ ํ†ตํ•ด proc-macro ์ƒ์ž์— ๋Œ€ํ•œ Cargo.toml ์— 1๋‹จ๊ณ„(์ฆ‰, ๋Œ€์ƒ wrt ํ˜ธ์ŠคํŠธ ๋Œ€ ๋Œ€์ƒ) ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๋ช…์‹œ ์ ์œผ๋กœ ๋‚˜์—ด ํ•  ์ˆ˜์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค extern crate ๋‚ด๋ถ€์˜ ๋ฒ”์œ„์—์žˆ๋Š” ์ด๋ฆ„ quote! .

@jseyfried

proc-macro ํฌ๋ ˆ์ดํŠธ๊ฐ€ "๋Œ€์ƒ" ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ์ข…์†์„ฑ์„ ๊ฐ€์งˆ ๊ฒƒ์ด๋ผ๋Š” ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

@arielb1 ๋„ค,

์ด RFC๋Š” #40939๊ฐ€ ๋„์ฐฉํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

@jseyfried PR์ด

๊ทธ PR์ด ๋„์ฐฉํ•˜๋ฉด ์•ˆ์ •ํ™”๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, ์šฐ๋ฆฌ๋Š” extern crate ์ด๋ฆ„์„ ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์ „์— API์— ๋Œ€ํ•œ ์•ฝ๊ฐ„์˜ ๊ฒฝํ—˜์„ ์–ป๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค(์˜ˆ: @arielb1์ด ์ง€์ ํ•œ ์ด ๋ฌธ์ œ ํ•ด๊ฒฐ ).

์šฐ๋ฆฌ๋Š” ์•„๋งˆ๋„ ์ด API๋ฅผ ํฌ๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. @eddyb ๋Š” OpKind ๋ฅผ ๋ชจ๋“  ํ† ํฐ ํŠธ๋ฆฌ์— ์ผ๋ฐ˜ํ™”ํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆ/๊ณ ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฌธ์„œ ์ฃผ์„, ๋ถ€๋™ ์†Œ์ˆ˜์  ๋ฆฌํ„ฐ๋Ÿด ๋“ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „๋ฐ˜์ ์œผ๋กœ ์ด PR์˜ API๋Š” ์•„์ง ์•ˆ์ •ํ™”๋ฅผ ๊ณ ๋ คํ•  ๋งŒํผ ์„ฑ์ˆ™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@bstrie ์Šฌํ”„๊ฒŒ๋„ ํŒŒ์ƒ ๋งคํฌ๋กœ ์•ˆ์ •ํ™”์™€ ๊ฐ™์ด proc ๋งคํฌ๋กœ ์•ˆ์ •ํ™”๋ฅผ ๋น ๋ฅด๊ฒŒ ์ถ”์ ํ•˜๋Š” RFC(์˜ˆ: ํ† ํฐ ์ŠคํŠธ๋ฆผ์ด ๋ฌธ์ž์—ด ํ‘œํ˜„์„ ํ†ตํ•ด์„œ๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์ œํ•œ๋œ API ์‚ฌ์šฉ)๊ฐ€ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค: https://github.com/rust-lang/rfcs/ ํ’€/1913

@est31 ์—ฐ๊ธฐ๋จ -- ์ด API์— ๋Œ€ํ•œ ์•ฝ๊ฐ„์˜ ๊ฒฝํ—˜ ํ›„์— ์šฐ๋ฆฌ๋Š” ์•ˆ์ •์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ „ํ™˜ํ•˜๋Š” ๋ฐ ๋™์˜ํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜์œ„ ์ง‘ํ•ฉ์— ๋™์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

String ๊ธฐ๋ฐ˜ API๋Š” ์„ ์–ธ์  ๋งคํฌ๋กœ 2.0๊ณผ ์‹ฌํ•˜๊ฒŒ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋ฉฐ ๋งคํฌ๋กœ 2.0์ด ์—†๊ณ  #[derive] ๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ์ด๋ฏธ ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋งคํฌ๋กœ 2.0์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด String ๊ธฐ๋ฐ˜ API์˜ ํ™•์‚ฐ์„ ์ตœ๋Œ€ํ•œ ํ”ผํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” #[proc_macro_attribute] ๋Œ€ํ•œ ์ด์Šˆ ๋ฅผ

์ด๊ฒƒ์€ ์ด์ œ proc_macro ํฌ๋ ˆ์ดํŠธ ๋ฐ ์ƒˆ API์— ๋Œ€ํ•œ ์ถ”์  ๋ฌธ์ œ์ด๋ฏ€๋กœ ๋ช‡ ๊ฐ€์ง€ ์ƒ๊ฐ๋„ ์ ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ €๋Š” proc-macro2 ๋ผ๋Š” ํฌ๋ ˆ์ดํŠธ๋ฅผ ๊ณต๊ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํฌ๋ ˆ์ดํŠธ๋Š” ์•ˆ์ •์ ์ธ Rust์—์„œ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ํŠธ๋ฆฌ์— ์žˆ๋Š” proc_macro ํฌ๋ ˆ์ดํŠธ์™€ ์™„์ „ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋” ๋‚˜์€ ๋ฒ”์œ„ ์ •๋ณด์˜ ์ด์ ์„ ์–ป๊ธฐ ์œ„ํ•ด ์•ผ๊ฐ„ Rust์—์„œ ์ปดํŒŒ์ผํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” syn ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋ฐ˜์ด ๋˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋ฉฐ syn ๊ฐœ๋ฐœ์—์„œ ์šฐ๋ฆฌ๋Š” proc_macro ์ง์ ‘ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ์€ ๋ช‡ ๊ฐ€์ง€ ๋‹จ์ ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋ช‡ ๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ๋ฆฌํ„ฐ๋Ÿด์—๋Š” Literal ์ƒ์„ฑ์ž๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌธ์ž์—ดํ™”์™€ ํŒŒ์‹ฑ์„ ํ†ตํ•ด ํ•ด๊ฒฐ๋˜์ง€๋งŒ ๋ฌธ์ž์—ด API๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์ง์ ‘ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    • ์›์‹œ ๋ฌธ์ž์—ด - r###" foo "###

    • ์›์‹œ ๋ฐ”์ดํŠธ ๋ฌธ์ž์—ด - rb#" foo "#

    • ๋ฐ”์ดํŠธ ๋ฆฌํ„ฐ๋Ÿด - b'x'

    • ๋ฌธ์„œ ์ฃผ์„ - ํ˜„์žฌ Literal ํ† ํฐ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  • Literal ๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ  ๊ฐ’์„ ์ถ”์ถœํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ์šฐ๋ฆฌ๋Š” to_string ๋ฆฌํ„ฐ๋Ÿด์— literalext ํฌ๋ ˆ์ดํŠธ ์— ์˜์กดํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ์žฌ๋ถ„์„ํ•˜์ง€๋งŒ ์ด๋ก ์ƒ ์ด ์ •๋ณด๋Š” ์ด๋ฏธ Literal ์ €์žฅ๋˜์–ด ์žˆ๊ณ  ์•ก์„ธ์Šคํ•˜์‹ญ์‹œ์˜ค.
  • ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ํ† ํฐ ๋งคํ•‘์ด ์•ฝ๊ฐ„ ์ด์ƒํ•˜๊ฒŒ ํ•ด์„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ˜„์žฌ ๋ฌธ์„œ ์ฃผ์„์€ Literal ์œ ํ˜•์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ์‹œ์ž‘๋˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ๋ฌธ์ œ๋Š” ๊ทธ ์ดํ›„๋กœ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋กœ ํ…Œ์ŠคํŠธ ํ•  ๋•Œ ๋‚˜๋Š” ํŒŒ์†์„ ๋ฐœ์ƒ #![feature(proc_macro)] ๊ฐ€ ์‚ฌ์šฉ์ž ์ •์˜ ๋„์ถœ์— ์˜ํ–ฅ์„ #[proc_macro_derive(foo, attributes(foo))] . ์ฆ‰, ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ๊ณผ ๋™์ผํ•œ ์†์„ฑ์˜ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ์ƒ์ž ์ค‘ ํ•˜๋‚˜๋Š” #[derive(error_chain)] #[error_chain(...)] struct ErrorKind { ... } ๊ฐ€ ์žˆ๋Š” mine-derivative-error-chain์ž…๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ๊ฒƒ์€ #[derive(new)] #[new] struct S; ๊ฐ€ ์žˆ๋Š” ํŒŒ์ƒ ์ƒˆ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” "foo" is a derive mode ๋‘ ๋ฒˆ์งธ ์†์„ฑ์—์„œ ๋ถˆํ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์˜๋„์ ์ธ ๊ฒƒ์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๊ณ ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์˜๋„์ ์ธ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ์ง€์ • ํŒŒ์ƒ ํ•ญ๋ชฉ์˜ ์ด๋ฆ„์„ ErrorChain ์œผ๋กœ ๋ฐ”๊ฟ€ ์ค€๋น„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@์•„๋ฅด๋‚˜๋น„์˜จ
์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์˜๋„๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. proc_macro_attribute ๋Š” ํŒŒ์ƒ ์ „์— ํ™•์žฅ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— new ์ด proc_macro_attribute ์ด๋ฉด ํ™•์žฅ์ด ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ new ๊ฐ€ proc_macro_derive ๋˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋ฏธ๋ž˜ ํ˜ธํ™˜์„ฑ ์œ„ํ—˜์ด ๋  ์ˆ˜๋„ ์žˆ์Œ).

์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์˜๋„๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. proc_macro_attributes ๋Š” ํŒŒ์ƒ ์ „์— ํ™•์žฅ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ new ๊ฐ€ proc_macro_attribute ์ด๋ฉด ํ™•์žฅ์ด ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์ข‹์•„, ๋‚ด๊ฐ€ ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค #[derive(error_chain)] ์— #[derive(ErrorChain)] .

๊ตฌ์ฒด์ ์œผ๋กœ new ๊ฐ€ proc_macro_derive ๋˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋ฏธ๋ž˜ ํ˜ธํ™˜์„ฑ ์œ„ํ—˜์ด ๋  ์ˆ˜๋„ ์žˆ์Œ).

๋ฌผ๋ก  new ์ด ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋ฅผ ์š”๊ตฌํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์•„๋Š” ๋‘ ๊ฐœ์˜ proc_macro_derive ์ค‘ ํ•˜๋‚˜์˜ ์˜ˆ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ์˜ ํ‰๊ท  ์•Š์•˜๋‹ค - ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค @Arnavion, ๋‚ด ๋งˆ์ง€๋ง‰ ์ฝ”๋ฉ˜ํŠธ๋Š” ๊นจ๋—ํ•œ ์•„๋‹ˆ์—ˆ๋‹ค new ํŠน๋ณ„ํžˆํ•˜์ง€๋งŒ ํ—ˆ์šฉํ•˜๋ ค๋ฉด #[derive(some_macro)] #[some_attr] struct S; ํ•˜๋ฉด some_attr ๊ฒฐ์˜๋ฅผ A์™€ proc_macro_derive . some_attr ๊ฐ€ proc_macro_attribute ํ•ด์„๋˜๋ฉด ์ด๋Š” ๋ชจํ˜ธ์„ฑ ์˜ค๋ฅ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋Š˜๋‚  some_attr ๋งคํฌ๋กœ๋กœ ํ•ด์„๋˜๋ฉด ๋ชจํ˜ธ์„ฑ ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.

๋„ค, ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค.

( ์ด๋Ÿฐ ์งˆ๋ฌธ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ์—ฌ๊ธฐ์˜€์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. )

์ด ์ƒํƒœ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

  • [ ] proc_macro ์ž‘์„ฑ์ž๊ฐ€ ๋งคํฌ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํฌ๋ ˆ์ดํŠธ ๋ฃจํŠธ์— extern crate foo; ๋ฅผ ํฌํ•จํ•  ํ•„์š” ์—†์ด ๋ฏธ๋ฆฌ ๊ฒฐ์ •๋œ ํฌ๋ ˆ์ดํŠธ foo ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜๋Š” ํ™•์žฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค(PR #40939 ).

PR์ด ๋„์ฐฉํ–ˆ์ง€๋งŒ ์ƒ์ž๊ฐ€ ์•„์ง ์„ ํƒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. @jseyfried ๋Š” ์—ฌ๊ธฐ์—์„œ ๋ญ”๊ฐ€๋ฅผ ์–ธ๊ธ‰ํ–ˆ์œผ๋ฉฐ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ use ์—์„œ๋Š” ์ „ํ˜€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

let call_site_self = TokenTree {
    kind: TokenNode::Term(Term::intern("self")),
    span: Span::call_site(),
};
quote! {
    extern crate foo; // due to hygiene, this is never a conflict error

    // Neither of those works    
    use foo::f;
    use self::foo::f;
    use $call_site_self::foo:f;
}

๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋งคํฌ๋กœ์—์„œ ๊ฐ€์ ธ์˜จ extern ์ƒ์ž์˜ use ๊ธฐํ˜ธ์— ๋Œ€ํ•œ ๊ด€์šฉ์  ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

use ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค( https://github.com/rust-lang/rfcs/issues/959 ์ฐธ์กฐ). ๊ทธ๋Ÿฌ๋‚˜ ๋งคํฌ๋กœ์˜ ๊ฒฝ์šฐ ๋งค๋ฒˆ ์ •๊ทœํ™”๋œ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์‹ค์ œ๋กœ ๋‹จ์ ์€ ์•„๋‹™๋‹ˆ๋‹ค. (ํŠน์„ฑ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค)

@parched ์ด ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ์—ฐ๊ฒฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚ด ๋งคํฌ๋กœ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ match-matcher์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์‚ฌ์šฉ์ž๋Š” Term ํ•˜๋ฉฐ ์ด๋Š” ์—ด๊ฑฐํ˜•์˜ ๋ณ€ํ˜• ์ด๊ฑฐ๋‚˜ ์ผ์น˜ ๊ฐ’์„ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ณ€์ˆ˜ ์ด๋ฆ„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. macro_rules! ๊ตฌ๋ฌธ์œผ๋กœ ์˜์‚ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด:

macro_rules foo {
    ($matcher:ident) => {
        match something() {
            $matcher => {}
            _ => {}
        }
    }
}

์ด์ œ ์‚ฌ์šฉ์ž๊ฐ€ ์—ด๊ฑฐํ˜• ์ด๋ฆ„ ์—†์ด ๋ณ€ํ˜• ์ด๋ฆ„ use my_crate::AnEnum::*; ๋ฌธ์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ (์ง€๊ธˆ์€) ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— $matcher ๊ฐ€ ์—ด๊ฑฐํ˜•์˜ ๋ณ€ํ˜•์ธ์ง€ ์•„๋‹Œ์ง€ ์ง์ ‘ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์„ค๋ช…์ด ์ดํ•ด๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋งคํฌ๋กœ ์ƒ์„ฑ ์ฝ”๋“œ์—์„œ use ์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

@LukasKalbertodt์€ ๊ทธ๋ƒฅ ์‚ฌ์šฉํ•  ์ˆ˜ my_crate::AnEnum::$matcher => {} ์—์„œ match ?
์‹ ๊ฒฝ์“ฐ์ง€ ๋งˆ์„ธ์š”, ์ €๋Š” ๋‹น์‹ ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค -- ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์œ„ํ•ด https://github.com/rust-lang/rfcs/issues/959 ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

@jseyfried ์•„๋‹ˆ์š”: $matcher ๋Š” ๋ณ€ํ˜• ์ด๋ฆ„(์ด ๊ฒฝ์šฐ ์†”๋ฃจ์…˜์ด ์ž‘๋™ํ•จ) ๋˜๋Š” match x { simple_var_name => {} } ์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๋ณ€์ˆ˜ ์ด๋ฆ„์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ›„์ž์˜ ๊ฒฝ์šฐ AFAICT๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (btw, use ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์–ธ๊ธ‰ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.)

@jseyfried

์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์˜๋„๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. proc_macro_attributes ๋Š” ํŒŒ์ƒ ์ „์— ํ™•์žฅ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ new ๊ฐ€ proc_macro_attribute ์ด๋ฉด ํ™•์žฅ์ด ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์ข‹์•„, ๋‚ด๊ฐ€ ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค #[derive(error_chain)] ์— #[derive(ErrorChain)] .

์‚ฌ์šฉ์ž ์ง€์ • ํŒŒ์ƒ ํ•ญ๋ชฉ์˜ ์†์„ฑ์€ ๊ฐ€์ ธ์˜ค๊ธฐ ์ˆœ์„œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ํŒŒ์ƒ ํ•ญ๋ชฉ์ฒ˜๋Ÿผ ์žฌ์ •์˜ํ•˜๋Š” ๋Œ€์‹  macro_rules ๋งคํฌ๋กœ์™€ ์ถฉ๋Œํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.

#![feature(proc_macro)]
#[macro_use] extern crate error_chain; // macro_rules! error_chain
#[macro_use] extern crate derive_error_chain; // #[proc_macro_derive(error_chain, attributes(error_chain))]

#[derive(error_chain)] // No error. Resolves to custom derive
enum ErrorKind {
    /*#[error_chain]*/ // (1) As discussed above, can't use this any more since it conflicts with the name of the custom derive
    Foo,
}

์ด๊ฒƒ์€ (1) ๊ฐ€ stable์—์„œ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ  ํ˜„์žฌ ์•ˆ์ •์ ์ธ Rust์˜ ๋™์ž‘๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚œ ๋ช…์‹œ ์ ์œผ๋กœํ•˜๊ณ ์žํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฌธ์„œํ™” ํ•œ #[macro_use] ์œผ๋กœ error-chain ๊ฐ€์ ธ ์˜ค๊ธฐ ์ „์— ๊ฐ€์ ธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค ์ƒ์ž derive-error-chain .

๊ทธ๋Ÿฌ๋‚˜ (1) ๊ฐ€ proc_macro ๊ธฐ๋Šฅ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ์ด๋ฆ„์„ ErrorChain ๋กœ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„(์ด๋ฏธ ์•ˆ์ •์ ์ธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ•œ ๊ฐ€์ง€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž„):

#![feature(proc_macro)]
#[macro_use] extern crate error_chain; // macro_rules! error_chain
#[macro_use] extern crate derive_error_chain; // #[proc_macro_derive(ErrorChain, attributes(error_chain))]

#[derive(ErrorChain)] // Unique name, so no error
enum ErrorKind {
    #[error_chain] // (2)
    Foo,
}

์—ฌ์ „ํžˆ ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (2) ์˜ ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฌ์ •์˜ ๋Œ€์‹  macro_rules ๋งคํฌ๋กœ๊ฐ€ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์— ์˜ํ•ด ๋“ฑ๋ก๋œ ์†์„ฑ๊ณผ ๋ถ„๋ช…ํžˆ ์ถฉ๋Œํ•˜๊ธฐ ๋•Œ๋ฌธ์— macro `error_chain` may not be used in attributes ์˜ค๋ฅ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ.

๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์ง€์ • ํŒŒ์ƒ ํ•ญ๋ชฉ ๊ณผ ํ•ด๋‹น ์†์„ฑ์˜ ์ด๋ฆ„์„ ๋ชจ๋‘ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์€ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ(๊ฐ ์—ด๊ฑฐํ˜•์— ํ•˜๋‚˜์”ฉ)๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์ด(์—ด๊ฑฐํ˜•์˜ ๊ฐ ๋ณ€ํ˜•์— ํ•˜๋‚˜์”ฉ) ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ์˜ˆ์ƒ๋ณด๋‹ค ๋” ํฐ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‚ด ์ž์‹ ์˜ ๊ตฌ์„ฑ์˜ ๊นŒ๋‹ค๋กœ์šด ์ƒํ™ฉ์ด๋ผ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค(์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ๋ฐ ํ•ด๋‹น ์†์„ฑ์— ๋Œ€ํ•ด macro_rules ๋งคํฌ๋กœ์˜ ์ด๋ฆ„ ์žฌ์‚ฌ์šฉ). ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์ด ์‹œ์ž‘๋œ ์ดํ›„๋กœ ์•ˆ์ •์ ์œผ๋กœ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์•ˆ์ •ํ™”๋˜์–ด 6๊ฐœ์›” ํ›„์— ๋ฌธ์ œ๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ด์œ ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ์ž์ฒด๊ฐ€ macro_rules ๋งคํฌ๋กœ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์˜ ์†์„ฑ์ด macro_rules ๋งคํฌ๋กœ๋ฅผ ์žฌ์ •์˜ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์‹ค์ œ๋กœ ๋‚˜๋Š” ๊ทธ๋“ค ์‚ฌ์ด์— ์–ด๋–ค ๋ชจํ˜ธ์„ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ๋™์ผํ•œ ์ด๋ฆ„์˜ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ ํ›„์— macro_rules ๋งคํฌ๋กœ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ์™€ ๊ฐ™์€ ์ด์œ ๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋งคํฌ๋กœ๋Š” ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋งคํฌ๋กœ์ธ์ง€ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

proc ๋งคํฌ๋กœ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ๋œ ํ˜•์‹์ ์ธ "์žฅ์†Œ"๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? #rust-proc-macro IRC ์ฑ„๋„์„ ์ข‹์•„ํ•˜์‹œ๋‚˜์š”? ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๊ฐ€๋” ์งˆ๋ฌธ์„ ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ŠคํŒธํ•˜๋Š” ๊ฒƒ์€ ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.see_no_evil: ๊ทธ๋ฆฌ๊ณ  #rust ์ฑ„๋„์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ proc-macro ๋ฐ ํŠนํžˆ ์ƒˆ๋กœ์šด proc_macro API(๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ชจ๋‘). ๊ทธ๋ž˜์„œ: ์ด ์ฃผ์ œ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•  ๊ณณ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@LukasKalbertodt #rust-internals , ์•„๋งˆ๋„ ๋˜๋Š” ๊ทธ๋ƒฅ /r/rust์—์„œ ์ƒˆ ์Šค๋ ˆ๋“œ๋ฅผ ์‹œ์ž‘ํ•˜์‹ญ์‹œ์˜ค.

TokenStream::from_str ์ ˆ์ฐจ ๋งคํฌ๋กœ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ํŒจ๋‹‰์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ์—์„œ).

thread 'main' panicked at 'proc_macro::__internal::with_sess() called before set_parse_sess()!', /checkout/src/libproc_macro/lib.rs:758:8

์ด ํŒจ๋‹‰์„ ์•”์‹œ์ ์œผ๋กœ ๋”๋ฏธ "์„ธ์…˜"์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅ/๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๊ณต์šฉ API(์•ˆ์ •ํ™” ๊ฒฝ๋กœ ํฌํ•จ)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒ์„ฑํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ์‹œ์Šคํ…œ์˜ ๋งคํฌ๋กœ์— ๋Œ€ํ•œ ๋ฌธํ—Œ์„ ๋ณธ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ด์— ๋Œ€ํ•œ ์‚ฌ๋žŒ๋“ค์˜ ์ƒ๊ฐ์„ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ Scheme์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ œ๊ฐ€ ๊ฐ€์žฅ ์ž˜ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ œ ํ”„๋กœ์ ํŠธ์—์„œ R7RS Scheme์šฉ syntax-rules ์„ ๊ตฌํ˜„ํ•˜๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ syntax-case ๊ฐ€ ๋น„์œ„์ƒ์ ์ธ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ( defmacro ๋ฐ syntax-rules ). GNU Guile์ด ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. syntax-case ๋Š” ๊ตฌ๋ฌธ ๊ฐœ์ฒด ๋ชฉ๋ก(๋˜๋Š” Scheme์˜ TokenStream ํ–‰ ์ค‘ ์ผ๋ถ€)์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์กฐ๊ฑด์ž ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” fender๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Mark ๊ฐ€ ์ž‘์—… ์ค‘์ด๊ณ  Bindings as Sets of Scopes ์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ž„์˜ ๊ณ„์‚ฐ์„ ์ง€์›ํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋„ ๋…ผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? Racket์€ ์‹ค์ œ๋กœ ์ „์ฒด "๋‹จ๊ณ„" ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ทจํ•ฉ๋‹ˆ๋‹ค. begin-for-syntax ๋Š” ๋งคํฌ๋กœ ํ™•์žฅ ๋™์•ˆ ์ปดํŒŒ์ผ ํƒ€์ž„ ์ˆ˜์ค€์—์„œ ์ •์˜ ๋ฐ ๊ณ„์‚ฐ(?)์„ ํ—ˆ์šฉ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค

Scheme์—์„œ (datum->syntax <thing-to-copy-scope-from> <thing-to-apply-scope-to>) ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์ƒ์— ๋Œ€ํ•œ ์ œ์–ด๊ฐ€ ๋งค์šฐ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋งคํฌ๋กœ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋Œ€์‹  ์ฆ‰๊ฐ์ ์ธ ๋ฒ”์œ„ ์™ธ๋ถ€์— ์žˆ๋Š” ๊ฐœ์ฒด ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

The Scheme Programming Language, 3rd ed. ์—์„œ ์ด ์˜ˆ์ œ๋ฅผ ๊ฐ€์ ธ http://www.scheme.com/tspl3/syntax.html . ์ด ์˜ˆ์—์„œ๋Š” (include "filename.scm") ๋ฅผ syntax-case ๋งคํฌ๋กœ๋กœ ํ‘œ์‹œํ•˜๊ณ  ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์—์„œ ์ฝ๊ณ  ํ‰๊ฐ€๋ฅผ ๊ณ„์†ํ•˜๋„๋ก ๋Ÿฐํƒ€์ž„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋” ๊นŠ์€ ์งˆ๋ฌธ์€ ๋งคํฌ๋กœ ํ™•์žฅ ์‹œ ์ด๋Ÿฌํ•œ ์ผ์ด ๋ฐœ์ƒํ•˜๋„๋ก ๋งคํฌ๋กœ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์„ ์›ํ•˜๊ณ  ํŒŒ์ผ ๊ฐ€์ ธ์˜ค๊ธฐ ํŠธ๋ฆฌ๊ฑฐ์™€ ๊ฐ™์€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ๊ณ„์‚ฐ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š”์ง€ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค(๋น„๋ก ์ง์ ‘ ์ปดํŒŒ์ผ๋Ÿฌ ๊ธฐ๋Šฅ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ๊ทธ๋ž˜์„œ ์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

๋งคํฌ๋กœ์˜ ํ•œ๊ณ„๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ปดํŒŒ์ผ ์‹œ๊ฐ„์„ ์ค„์ด๊ณ ์ž ํ•˜๋Š” Rust๊ฐ€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ํ‰๊ฐ€๋ฅผ ์ œํ•œํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๊ณ  ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(ํŠนํžˆ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ํ”ผํ•จ). Racket์€ Lisp in Small Pieces์—์„œ ์ฐธ์กฐ๋˜๋Š” ๋‹จ๊ณ„๋ฅผ ํ†ตํ•ด "์ค€๋น„์ž์™€ ํ™•์žฅ์ž์˜ ํƒ‘" ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ทจํ–ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ I/O ๋ฐ ์ œํ•œ๋œ ์žฌ๊ท€ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ปดํŒŒ์ผ ํƒ€์ž„ API์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ํ—ˆ์šฉ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ CSV ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ์‚ฌ์–‘์„ switch ๋ฌธ์œผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค! Template Haskell์€ AST๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ž˜ ์ •์˜๋œ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ํฅ๋ฏธ๋กœ์šด ์ ‘๊ทผ ๋ฐฉ์‹์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ Haskell์˜ ๊ฒŒ์œผ๋ฆ„์€ ์ œ์–ด ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๋งคํฌ๋กœ ์‚ฌ์šฉ์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์„ ์—์„œ ๋ฒ—์–ด๋‚˜๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

๋งคํฌ๋กœ์˜ ํ•œ๊ณ„๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด๋ฒˆ ํ˜ธ์—์„œ ๋…ผ์˜๋œ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ์˜ ๊ฒฝ์šฐ none . ์ ˆ์ฐจ ๋งคํฌ๋กœ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ํ™•์žฅ์ž…๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ C++ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ณ  clang์„ ํ†ตํ•ด ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ ๊ฐœ์ฒด๋ฅผ ์ปดํŒŒ์ผ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ SQL์„ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฟผ๋ฆฌํ•˜์—ฌ ํ•ด๋‹น ๊ฒฐ๊ณผ ์œ ํ˜•์„ ์ฐพ๊ณ  ์ ์ ˆํ•œ ๊ฒฐ๊ณผ ์„ธํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค!

Rust์—๋Š” ๋‹ค๋ฅธ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋Š” RFC 1584 ๋กœ ์Šน์ธ๋˜์—ˆ์œผ๋ฉฐ ๊ตฌํ˜„์€ https://github.com/rust-lang/rust/issues/39412์—์„œ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค

@VermillionAzure , ์ฐธ์กฐํ•œ Scheme ์–‘์‹์„

macro_rules ๋ฐ RFC 1584 ์— ๋”ฐ๋ฅธ ์—…๋ฐ์ดํŠธ๋Š” syntax-rules ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ๋Š” ๊ฒฝ์šฐ https://github.com/rust-lang/rust/issues/39412 ๊ฐ€ ์ด์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ข‹์€ ์žฅ์†Œ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ”„๋กœ์‹œ์ € ๋งคํฌ๋กœ๋Š” define-syntax ์˜ ์ผ๋ฐ˜์ ์ธ ํ˜•์‹๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด RFC( 1566 )๋Š” ๋งค์šฐ ์˜๋„์ ์œผ๋กœ syntax-case ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ •์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค . ํ† ํฐ ์ŠคํŠธ๋ฆผ์„ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋Š” syntax-case ์™€ ๊ฐ™์€ ๊ฒƒ์ด ๋ณ„๋„์˜ ํฌ๋ ˆ์ดํŠธ(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)์—์„œ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ •์˜๋˜๋ฉฐ ์˜๋„๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์„ฑํ–ฅ์ด ์žˆ๋‹ค๋ฉด ๋งˆ์Œ๊ป ๋›ฐ์–ด๋†€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์‰ฌ์šด์ง€ ๋˜๋Š” ์–ด๋ ค์šด์ง€์— ๋Œ€ํ•œ ๋ชจ๋“  ํ”„๋กœํ† ํƒ€์ž…๊ณผ ๋ณด๊ณ ์„œ๋Š” ๋ชจ๋‘ ํ™˜์˜๋ฐ›์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด ์ƒ๊ฐ์— ์•„์ด๋””์–ด๋Š” lisp์—์„œ์™€ ๊ฐ™์ด ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๋งคํฌ๋กœ๋ฅผ ์ •์˜ํ•˜์ง€๋งŒ macro_rules! ์ •์˜ํ•˜๋Š” ๋งคํฌ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋งคํฌ๋กœ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹ค์Œ์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

    macro_rules! foo {/*define macro here*/}
#[proc_macro]
pub fn foo(tokens: TokenStream) -> TokenStream {
    macro_case! tokens {/*define macro here*/} //takes `tokens` as first argument, returns a `TokenStream`
}

์ด๊ฒƒ์ด syntax-rules ๋ฐ syntax-case ๊ฐ€ ๊ณ„ํš์—์„œ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

@VermillionAzure
์ด๊ฒƒ์€, ๋‹น์‹ ์ด ์›ํ•˜๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@porky11 ์•„๋‹ˆ์š”, ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Scheme ๋งคํฌ๋กœ๊ฐ€ ํ† ๋ก ์— ์ถ”๊ฐ€ํ•  ์ ์ ˆํ•œ ์•„์ด๋””์–ด์ธ์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ Scheme์˜ syntax-case ๋งคํฌ๋กœ ์‹œ์Šคํ…œ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์†Œํ•˜๋‹ค๋Š” ๊ฒƒ์€ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ œ๊ณต๋œ ์ž„์˜์˜ ํž˜์˜ ๊ด€์ ์—์„œ ๋ชจ๋“  ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

@jan-hudec ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ณด์•ˆ ๋ณด์žฅ ์—†์ด ์ปดํŒŒ์ผ๋Ÿฌ ํ™•์žฅ์œผ๋กœ ์ž„์˜์˜ ๊ณ„์‚ฐ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ˜„๋ช…ํ•ฉ๋‹ˆ๊นŒ? ์—ฌ๊ธฐ์—์„œ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ๋งค์šฐ ๊ฐ•๋ ฅํ•  ๊ฒƒ์ด๋ผ๋Š” ์ƒ๊ฐ์— ์™„์ „ํžˆ ๊ฐ๋ช…์„ ๋ฐ›์•˜์ง€๋งŒ, Rust์˜ ์ž ์žฌ์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์ด๊ฒƒ์„ ํŒจํ‚ค์ง€ ์‚ฌ์šฉ์˜ ๋‹จ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ• ๊นŒ์š”? ์ €๋Š” ๋ณด์•ˆ ์ „๋ฌธ๊ฐ€๋Š” ์•„๋‹ˆ์ง€๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ ํ™•์žฅ ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ทจ์•ฝ์ ์ด ์•…์˜์ ์œผ๋กœ Rust ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ณต๊ฒฉ ๋ฒกํ„ฐ๋กœ ๋ฐ”๊พธ๋Š” ๋ฐ ์‰ฝ๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ, ์ ˆ์ฐจ์  ๋งคํฌ๋กœ์— ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ: ์ž˜๋ชป๋œ C ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” segfault), ์ด๋Š” segfault๊ฐ€ ๊ณ„์†ํ•ด์„œ ๋ฐœ์ƒํ•˜์—ฌ ์ ์ ˆํ•œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์—†์ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‹คํŒจํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜๋ฅผ ์บก์Šํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋˜ ๋‹ค๋ฅธ ์•„์ด๋””์–ด: ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” ์–ธ์ œ ์‹คํ–‰๋ฉ๋‹ˆ๊นŒ? ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ๊ด€๋ จ๋  ์ˆ˜ ์žˆ๋Š” ๋ถ€์ž‘์šฉ์ด ์žˆ๋Š” ์ฝ”๋“œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ(์˜ˆ: ์ƒํƒœ ์ €์žฅ ์™ธ๋ถ€ ์„œ๋ฒ„์™€์˜ ํ†ต์‹ , ์™ธ๋ถ€ SQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ, ์™ธ๋ถ€ ์‹œ์Šคํ…œ์— ๋กœ๊ทธ์ธํ•˜๊ธฐ ์œ„ํ•œ ๋ณด์•ˆ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ) ์ปดํŒŒ์ผ ํ”„๋กœ์„ธ์Šค์— ์˜ํ•ด ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๊นŒ?

@VermillionAzure Cargo ํŒจํ‚ค์ง€์—๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ž„์˜์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ด๋ฏธ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” ๊ทธ๋Ÿฐ ๋ฉด์—์„œ ์ƒํ™ฉ์„ ์•…ํ™”์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์ข…์†์„ฑ์„ ์‹ ๋ขฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ด๊ฒƒ์€ crates.io๊ฐ€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ/์ถ”๊ฐ€ ์ „์šฉ์ด ๋˜๊ณ  Cargo.lock ํŒŒ์ผ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ข…์†์„ฑ์ด ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์†Œ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ํŠน์ • ๋ฒ„์ „๋งŒ ์‹ ๋ขฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.) ๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ทธ๋ ‡์ง€ ์•Š๋”๋ผ๋„ ์กด์žฌํ•˜๋”๋ผ๋„ ์ข…์†์„ฑ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋ณธ์งˆ์ ์œผ๋กœ ๋Ÿฐํƒ€์ž„์— ์ž„์˜์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ์‹œ๊ฐ„์ด ํ›จ์”ฌ ๋” ๋‚˜์ฉ๋‹ˆ๊นŒ?

์ด ํ† ๋ก ์€ ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ์ƒ๊ฐํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

ํฌ๋ ˆ์ดํŠธ๊ฐ€ ๋‘ ๊ฐœ์˜ proc ๋งคํฌ๋กœ๋ฅผ ์ •์˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. foo!() ๋Š” ์ž„์‹œ ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๊ณ  bar!() ๋Š” ๋™์ผํ•œ ํŒŒ์ผ์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์ด ํฌ๋ ˆ์ดํŠธ์˜ ์†Œ๋น„์ž๋Š” ๋™์ผํ•œ ๋ชจ๋“ˆ์—์„œ foo!() ๋ฐ bar!() ๋ฅผ ๋ชจ๋‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ปดํŒŒ์ผ ์„ฑ๊ณต ์—ฌ๋ถ€๋Š” foo!() ๋˜๋Š” bar!() ๊ฒƒ์ด ๋จผ์ € ํ™•์žฅ๋˜๋Š”์ง€์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด ์ˆœ์„œ๋Š” ๊ตฌํ˜„์— ๋”ฐ๋ผ ์ •์˜๋˜๋ฉฐ ์ถฉ๋ถ„ํ•œ ์‚ฌ๋žŒ๋“ค์ด ์ด์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๋ฌธ์ œ์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ตฌ์กฐ ํ•„๋“œ ์ฃผ๋ฌธ ์†์ž„์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋ ์ง€ ๊ฑฑ์ •๋ฉ๋‹ˆ๋‹ค.

@SimonSapin

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ž…์žฅ์— ๋™์˜ํ•˜์ง€๋งŒ ์ปดํŒŒ์ผ ํƒ€์ž„ ์‹คํ–‰๊ณผ ๋Ÿฐํƒ€์ž„ ์‹คํ–‰ ์‚ฌ์ด์—๋Š” ํ•œ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด์ ์ด ์žˆ์Œ์„ ์ง€์ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ๋ฌผ์ด ํ•œ ๋ฒˆ ์ปดํŒŒ์ผ๋œ ๋‹ค์Œ ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์— ๋ฐฐํฌ๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์œ„ํ˜‘ ๋ชจ๋ธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: Linux ๋ฐฐํฌํŒ ๋นŒ๋“œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์œ ์ง€ ๊ด€๋ฆฌ์ž์˜ ๋ถ€์ฃผ์˜์™€ ์ƒŒ๋“œ๋ฐ•์‹ฑ์˜ ๋‹จ์ ์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค.)

@lfairy ์˜ˆ, ์ด๊ฒƒ์€ 2002๋…„์— Racket์ด ๊ฒช์—ˆ๋˜ ์ •ํ™•ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. Racket์˜ ์ตœ๊ณ  ๊ธฐ์—ฌ์ž์ธ Matthew Flatt๋Š” "๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•˜๊ณ  ์ปดํŒŒ์ผ ๊ฐ€๋Šฅํ•œ ๋งคํฌ๋กœ: ์–ธ์ œ ์›ํ•˜์‹ญ๋‹ˆ๊นŒ . R. Kent Dybvig, Chez Scheme์—์„œ ์ผํ•œ ๊ทธ๋Š” "R6RS Libraries์˜ ์•”์‹œ์  ๋‹จ๊ณ„

@SimonSapin ์ปดํŒŒ์ผ ์‹œ๊ฐ„์€ ์ž ์žฌ์ ์œผ๋กœ ํ›จ์”ฌ ๋” ๋‚˜์  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฌด์ž‘์œ„๋กœ ์ถฉ๋Œํ•˜๊ฑฐ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์œ ๋ฐœ๋˜๋Š” ์•…์˜์ ์ธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ "Rust์˜ ๋ชจ๋“ˆ์€ ๋ณธ์งˆ์ ์œผ๋กœ ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค"๋ผ๋Š” ์ œ๋ชฉ์˜ ๊ฑฐ๋Œ€ํ•œ Reddit ๊ฒŒ์‹œ๋ฌผ์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@VermillionAzure , ๋‚˜๋Š” ๊ธฐ์‚ฌ๋ฅผ ์ž์„ธํžˆ ์ฝ์ง€

Scheme์—์„œ ํ•˜๋‚˜์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ•จ์ˆ˜์™€ ๋งคํฌ๋กœ๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ํ•จ์ˆ˜์™€ ๋Ÿฐํƒ€์ž„์ด ํ•„์š”ํ•œ ํ•จ์ˆ˜๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ •๋ ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Rust์—์„œ ํฌ๋ ˆ์ดํŠธ๋Š” ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋‚˜ ๋Ÿฐํƒ€์ž„ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ์ด ๊ตฌ๋ถ„์€ (๋‹น๋ถ„๊ฐ„) ๋ช…๋ฐฑํ•ฉ๋‹ˆ๋‹ค.

(๋Ÿฐํƒ€์ž„ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํฌ๋ ˆ์ดํŠธ๋Š” ๊ทœ์น™ ๊ธฐ๋ฐ˜(์œ„์ƒ์ ์ธ) ๋งคํฌ๋กœ๋„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Š” Rust์—์„œ ๋ณ„๋„์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค)

@lfairy ๊ฐ€ ๋งํ•˜๋Š” ๋ฌธ์ œ๋Š” ํ™•์žฅ๊ธฐ ๊ธฐ๋Šฅ์˜ ์‹คํ–‰ ์ˆœ์„œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. Rust์—์„œ ์ปดํŒŒ์ผ์€ ๊ฐœ๋ณ„ ํŒŒ์ผ์— ๋Œ€ํ•ด ๋ณ‘๋ ฌ์ผ ์ˆ˜ ์žˆ๊ณ  ์ฆ๋ถ„์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ™•์žฅ๊ธฐ์˜ ์‹คํ–‰ ์ˆœ์„œ๋Š” ์ •์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๊ธฐ์‚ฌ ๋ชจ๋‘ ์‹ค์ œ๋กœ ๊ทธ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค.

@jan-hudec ๋„ค, ๋งž์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŠน์ • ๋ชจ๋“ˆ์ด ๋ถ€์ž‘์šฉ์„ ์ผ์œผํ‚ค์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ถ€์ž‘์šฉ์ด ํ—ˆ์šฉ๋œ๋‹ค๋ฉด ํ‰๊ฐ€ ์ˆœ์„œ๋Š” ํ™•์‹คํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์ด "ํƒ€์ž… ๊ฐ€๋Šฅ"ํ•ฉ๋‹ˆ๊นŒ?

์ผ๋ถ€ ์„ธ๋ถ€ ์‚ฌํ•ญ(์•„๋ž˜ ์ฐธ์กฐ)์— ์˜์กดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” "์•„๋งˆ๋„ ์—†์–ด์„  ์•ˆ ๋˜๋Š”" ๋ถ€์ž‘์šฉ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์˜.

์ด๋Ÿฌํ•œ ์„ธ๋ถ€ ์ •๋ณด์—๋Š” ๋‹ค๋ฅธ proc ๋งคํฌ๋กœ์™€ ๋น„๊ตํ•œ ์‹คํ–‰ ๋ฐ ๋™์‹œ์„ฑ ์ˆœ์„œ์™€ proc-macro๊ฐ€ ์ฆ๋ถ„ ๋นŒ๋“œ์—์„œ ๋‹ค์‹œ ์‹คํ–‰๋˜๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํ›„์ž์˜ ๊ฒฝ์šฐ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ์—์„œ rerun-if-changed ์™€ ์œ ์‚ฌํ•œ ์ข…์†์„ฑ์„ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋Ÿฌํ•œ ์„ ์–ธ์€ ๋ถˆ์™„์ „ํ•˜๊ฑฐ๋‚˜ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ฒ„๊ทธ๋ฅผ ์ •์ ์œผ๋กœ ๋ฐฉ์ง€ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋ถ€์ž‘์šฉ์— ๋Œ€ํ•œ ๋ณด์žฅ์€ ํ”ผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ๋งคํฌ๋กœ ํฌ๋ ˆ์ดํŠธ๋Š” ๋ถ€์ž‘์šฉ์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์ ์šฉ๋˜๋Š” ๋ชจ๋“ˆ์˜ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฒƒ์— ๋Œ€ํ•ด ๋‹ค์‹œ ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ๊ฒƒ์— ์˜์กดํ•˜๋Š” ๊ฒƒ๋„ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ „์—ญ ์ƒํƒœ๊ฐ€ ์—†์Œ).

๋‚˜์ค‘์— rerun-if-changed ๋ฐ ๊ธฐํƒ€ ์‚ฌํ•ญ์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ด ์š”๊ตฌ ์‚ฌํ•ญ์„ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(์—ฌ๊ธฐ์— ๋‹ค์†Œ ๋„์›€์ด ๋  ๋ฐ˜์ฏค ๊ตฌ์šด ์ผ๋ฐ˜ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ/ํ”„๋กœ์‹œ์ € ๋งคํฌ๋กœ ๋ณด์•ˆ ์ œ์•ˆ์ด ์žˆ์ง€๋งŒ ์•„์ง ์ž‘์„ฑํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค)

IMO proc ๋งคํฌ๋กœ/์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์€ ์™ธ๋ถ€์— ๋Œ€ํ•œ I/O ๋˜๋Š” ๊ธฐํƒ€ ์—ฐ๊ฒฐ ์—†์ด ์ƒŒ๋“œ๋ฐ•์Šค ํ™˜๊ฒฝ์— ๋„ฃ์–ด์•ผ ํ•˜๋ฉฐ ์•„๋งˆ๋„ ํฌ๋ ˆ์ธ ๋ฆฌํ”„ํŠธ JIT๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ์—์„œ ํ‰๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@est31 ์ข‹์€ ์•„์ด๋””์–ด์ง€๋งŒ ๋””์ ค infer_schema์™€ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค! ์ด๋ฏธ
์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ bindgen์€ ํŒŒ์ผ์„ ์ฝ๊ณ  ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋ฉฐ ์‹ฌ์ง€์–ด ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! ๊ทธ๋ฆฌ๊ณ 
ํ™˜๊ฒฝ! I/O๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 11์›” 9์ผ 06:19์— "est31" [email protected]์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

IMO proc ๋งคํฌ๋กœ/์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์€ ์ƒŒ๋“œ๋ฐ•์Šค ํ™˜๊ฒฝ์— ๋„ฃ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์™ธ๋ถ€์— ๋Œ€ํ•œ I/O ๋˜๋Š” ๊ธฐํƒ€ ์—ฐ๊ฒฐ ์—†์ด
๋ฏธ๋ฆฌ, ์•„๋งˆ๋„ ํฌ๋ ˆ์ธ ๋ฆฌํ”„ํŠธ JIT์™€ ํ•จ๊ป˜.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/rust-lang/rust/issues/38356#issuecomment-343124957 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAC3n5VOPdKBsu81Sp3tp2XlIQ05L865ks5s0t_PgaJpZM4LMWlc
.

#40939์™€ #44528์ด ์ด๋ฏธ ๋ณ‘ํ•ฉ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ...

@mark-im์ด ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ ˆ์ฐจ์  ๋งคํฌ๋กœ๊ฐ€ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@VermillionAzure ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ๋“ค์ด ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ์ด์œ ๋ฅผ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก , "๋Ÿฐํƒ€์ž„" ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” proc ๋งคํฌ๋กœ์ฒ˜๋Ÿผ, ๊ทธ๊ฒƒ๋“ค์€ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋ณ„๊ฐœ์˜ ์ƒ์ž์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

syn์—์„œ ์šฐ๋ฆฌ๋Š” ์˜ค๋Š˜ proc_macro::TokenNode์˜ ์ œํ•œ์— ๋ถ€๋”ช์ณค์Šต๋‹ˆ๋‹ค. -- ๋ธ”๋ก ๊ตฌ๋ถ„ ๊ธฐํ˜ธ { ... } ๋Š” ์ž…๋ ฅ TokenStream์—์„œ ํ•˜๋‚˜์˜ Span๊ณผ๋งŒ ์—ฐ๊ฒฐ๋˜๋ฏ€๋กœ ํŠธ๋ฆฌ๊ฑฐํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹ซ๋Š” } ๋งŒ ๊ฐ€๋ฆฌํ‚ค๋Š” ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. Rustc์—๋Š” ์ด๋Ÿฌํ•œ ์ œํ•œ์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

mod m {
    type T =
}
error: expected type, found `}`
 --> src/main.rs:3:1
  |
3 | }
  | ^

proc ๋งคํฌ๋กœ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์„ ์€ ๋ธ”๋ก ๋‚ด๋ถ€์˜ ๋งˆ์ง€๋ง‰ ํ† ํฐ์„ ๊ฐ€๋ฆฌํ‚ค๊ฑฐ๋‚˜, ์ „์ฒด ๋ธ”๋ก์„ ๊ฐ€๋ฆฌํ‚ค๊ฑฐ๋‚˜, ๋ธ”๋ก ๋’ค์˜ ๋‹ค์Œ ํ† ํฐ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ํ•ด๊ฒฐ์ฑ…์€ Span::start ๋ฐ Span::end ๊ฐ€ ํ˜„์žฌ์™€ ๊ฐ™์ด LineColumn ๋Œ€์‹  1์ž Span ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ ๋‹ค์Œ Span ์—์„œ ๋ฒ”์œ„์˜ ์ฒซ ๋ฒˆ์งธ ์ค„/์—ด๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

sp.begin().line // before
sp.line() // after

sp.end().line // before
sp.end().line() // after

sp.end() // after, not possible before

#43604์—์„œ ํ•ด๋‹น API๋ฅผ ์ถ”๊ฐ€ํ•œ @abonander ๋ฅผ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

Span::start ๋ฐ Span::end๋Š” ํ˜„์žฌ์™€ ๊ฐ™์ด LineColumn ๋Œ€์‹  1์ž Span์„ ๋ฐ˜ํ™˜ํ•œ ๋‹ค์Œ Span์—์„œ Span์˜ ์ฒซ ๋ฒˆ์งธ ์ค„/์—ด๋กœ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด Span์ด ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก์— ํ•„์š”ํ•œ ํŠน๋ณ„ํ•œ ๋™์ž‘์„ ์ฑ„ํƒํ•˜๊ฒŒ ๋˜์ง€๋งŒ ๋‹ค๋ฅธ ๋ชจ๋“  ๋ฒ”์œ„์—์„œ๋Š” ์ž˜๋ชป๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•ญ๋ชฉ์„ ๊ฒฐํ•ฉํ•˜์—ฌ foo(hi) ์™€ ๊ฐ™์€ ํ‘œํ˜„์‹์˜ ๋ฒ”์œ„๋ฅผ ์–ป๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ์ด์ œ foo ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  sp.begin() ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜์ง€๋งŒ sp.begin() ๋Š” foo ์˜ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ž๋งŒ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ์†”๋ฃจ์…˜์€ proc_macro::TokenNode::Group ์— ๋‘ ๊ฐœ์˜ ๋ฒ”์œ„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ž„์˜์˜ ๋ฒ”์œ„๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Span::begin / end ๋ฐ˜ํ™˜ ์œ ํ˜•์ด ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/rust-lang/rust/pull/43604#issuecomment -327643229

๋‚ด ์ ˆ์ฐจ ๋งคํฌ๋กœ์˜ ๋ฒ”์œ„์— ์žˆ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Span::def_site() ๋ฅผ ์–ป์œผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ด์•ผํ•˜๋Š”์ง€ ์˜คํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

Span::call_site() ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  main.rs์— MySend ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉด ๊ฑฐ์˜ ๋™์ผํ•œ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ def_site() ์ž‘๋™ํ•˜๋„๋ก ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

#![feature(proc_macro)]

extern crate proc_macro;

use std::marker::Send as MySend;
use proc_macro::{TokenStream, TokenTree, TokenNode, Term, Delimiter, Span};

#[proc_macro]
pub fn impl_mysend_for(tokens: TokenStream) -> TokenStream {
    let span = Span::def_site();
    let ident = tokens.into_iter().next().unwrap();
    vec![
        TokenTree { span, kind: TokenNode::Term(Term::intern("unsafe")) },
        TokenTree { span, kind: TokenNode::Term(Term::intern("impl")) },
        TokenTree { span, kind: TokenNode::Term(Term::intern("MySend")) },
        TokenTree { span, kind: TokenNode::Term(Term::intern("for")) },
        ident,
        TokenTree { span, kind: TokenNode::Group(Delimiter::Brace, TokenStream::empty()) }
    ].into_iter().collect()
}
#![feature(proc_macro)]

extern crate mac;

struct S;
mac::impl_mysend_for!(S);

fn main() {}
error[E0405]: cannot find trait `MySend` in this scope
 --> src/main.rs:6:1
  |
6 | mac::impl_mysend_for!(S);
  | ^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `Send`?

Syn ์ธก์—์„œ ์ถ”์ : https://github.com/dtolnay/syn/issues/290.

@dtolnay
์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” MySend ๊ฐ€ 0๋‹จ๊ณ„(์ฆ‰, ํฌ๋กœ์Šค ์ปดํŒŒ์ผ ์‹œ ํ˜ธ์ŠคํŠธ ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด)์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— 1๋‹จ๊ณ„(์ฆ‰, ๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด ์ปดํŒŒ์ผํ•  ๋•Œ)์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ํ•ด๊ฒฐ์ฑ…์€ proc-macro ํฌ๋ ˆ์ดํŠธ๊ฐ€ 1๋‹จ๊ณ„(๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜) ์ข…์†์„ฑ์„ ๊ฐ–๋„๋ก ํ•˜์—ฌ 1๋‹จ๊ณ„ ํ•ญ๋ชฉ์„ ๋ฒ”์œ„๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

quote! { // n.b. non-interpolated tokens from `quote!` have `Span::def_site()`
    mod dummy {
        extern crate std;
        use self::std::marker::Send as MySend;
        unsafe impl MySend for $ident {} // this line is equivalent to what you have above
    }
} 

์ด๊ฒƒ์„ ์ˆ˜๋™์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ํŽธ์˜์ƒ quote! ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์ƒ์ƒ์˜ ์ด์œ ๋กœ dummy / std / MySend ๋Š” ๋ฒ”์œ„ ๋‚ด์˜ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๊ณผ๋„ ์ถฉ๋Œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜ˆ๋ฅผ ๋“ค์–ด ๋™์ผํ•œ ๋ชจ๋“ˆ์—์„œ ์ด ๋งคํฌ๋กœ๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ident ๋Š” "MySend" ๋“ฑ์œผ๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์™€ mod dummy ์˜ ํ•„์š”์„ฑ๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ https://github.com/rust-lang/rust/issues/45934#issuecomment -344497531์— ์ž์„ธํžˆ ์„ค๋ช…๋˜์–ด

์Šฌํ”„๊ฒŒ๋„ 1๋‹จ๊ณ„ ์ข…์†์„ฑ์ด ๊ตฌํ˜„๋  ๋•Œ๊นŒ์ง€ ์ด๊ฒƒ์€ ์ธ์ฒด๊ณตํ•™์ ์ด์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@jseyfried ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ํ›„์† ์งˆ๋ฌธ:

  • ๋‚ด ์ด์ „ ์ฝ”๋ฉ˜ํŠธ์˜ ์ฝ”๋“œ์—์„œ, ๋‚˜๋Š” ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ impl_mysend_for ์œ„ํ•œ IMPL ์ƒ์„ฑํ•˜๊ธฐ Send ๋Œ€์‹  MySend ๋‹ค์Œ ๋ชจ๋“  ๊ฒƒ์„ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ํ•ด๊ฒฐํ•˜๋Š” Send ๋Š” ๋ฌด์—‡์ด๋ฉฐ 0๋‹จ๊ณ„์™€ 1๋‹จ๊ณ„์˜ ๊ตฌ๋ถ„์— ๋งž์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์˜๋„์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์šฐ์—ฐํžˆ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

  • Send ์™€ ๊ฐ™์ด ๋‚ด def_site() ํ† ํฐ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„์—๋Š” ์–ด๋–ค ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

  • MySend ๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ serde::Serialize ํŒŒ์ƒ) ์ตœ์ข… ์‚ฌ์šฉ์ž๋Š” Cargo.toml์— serde ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. extern crate serde ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. def_site() ident ํ™•์ธ์œผ๋กœ extern crate ์„ ์ ˆ์ฐจ ๋งคํฌ๋กœ์˜ Cargo.toml์— ๋Œ€ํ•ด ํ™•์ธํ•˜๊ณ  extern crate ์‚ฌ์šฉํ•˜์—ฌ call_site() ident ํ™•์ธ์„ ๋‹ค์šด์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํ™”๋ฌผ.ํ†ฐ?

extern ํฌ๋ ˆ์ดํŠธ์˜ ๊ฒฝ์šฐ proc ๋งคํฌ๋กœ์— ์˜ํ•ด 1๋‹จ๊ณ„์—์„œ ํฌ๋ ˆ์ดํŠธ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

#[proc_macro_derive(Serialize, attributes(serde), crates(serde))]

@dtolnay

์ด์ „ ์ฃผ์„์˜ ์ฝ”๋“œ์—์„œ MySend ๋Œ€์‹  Send์— ๋Œ€ํ•œ impl์„ ์ƒ์„ฑํ•˜๋„๋ก impl_mysend_for๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌด์—‡์œผ๋กœ ํ•ด๊ฒฐ๋˜๋ฉฐ ์™œ 0๋‹จ๊ณ„์™€ 1๋‹จ๊ณ„ ๊ตฌ๋ถ„์— ๋งž์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์˜๋„์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์šฐ์—ฐํžˆ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

์ข‹์€ ์งˆ๋ฌธ. ๋ฐ”๋กœ ์ง€๊ธˆ, ์„œ๊ณก์€ ์ •์˜ ์‚ฌ์ดํŠธ์˜ ๋ฒ”์œ„์— ์žˆ์œผ๋ฉฐ(proc-macro crate๊ฐ€ #![no_implicit_prelude] ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ) ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์ง€์ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ 0๋‹จ๊ณ„์™€ 1๋‹จ๊ณ„ ๊ตฌ๋ณ„๋กœ ์ธํ•œ ์‚ฌ๊ณ (์–ด๋–ค ์˜๋ฏธ์—์„œ)์ž…๋‹ˆ๋‹ค. .

๊ทธ๋Ÿฌ๋‚˜ ์ธ์ฒด ๊ณตํ•™์˜ ๊ฒฝ์šฐ 1๋‹จ๊ณ„๋Š” proc-macro ๋ฃจํŠธ์— ์•”์‹œ์ ์œผ๋กœ std ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(ํ•ญ์ƒ quote!(use std::...); ). 0๋‹จ๊ณ„์—์„œ. ๊ณง 1๋‹จ๊ณ„์—์„œ ๋ฃจํŠธ์— std ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ PR์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Send์™€ ๊ฐ™์€ def_site() ํ† ํฐ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„์—๋Š” ์–ด๋–ค ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์œ„์—์„œ ๋…ผ์˜ํ•œ ์„œ๊ณก๊ณผ (๊ณง) std ์™ธ์— 1๋‹จ๊ณ„์˜ ๋ฒ”์œ„์— ์žˆ๋Š” ๋‹ค๋ฅธ ์œ ์ผํ•œ ๊ฒƒ์€ proc-macro ์ž์ฒด์ž…๋‹ˆ๋‹ค(๋‹จ๊ณ„ 0์ธ proc-macro ํ•จ์ˆ˜ ๊ฐ€ ์•„๋‹˜).

์˜ˆ๋ฅผ ๋“ค์–ด,

#[proc_macro]
fn f(input: TokenStream) -> TokenStream { ... }

#[proc_macro]
fn g(_input: TokenStream) -> TokenStream {
    quote! {
        f!(); ::f!(); // These both resolve to the above proc macro
        f(); // This doesn't resolve since the function is in phase 0
    }
}

์ ˆ์ฐจ์  ๋งคํฌ๋กœ์˜ Cargo.toml์— ๋Œ€ํ•ด def_site() ident๊ฐ€ ์žˆ๋Š” extern ํฌ๋ ˆ์ดํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค์šด์ŠคํŠธ๋ฆผ Cargo.toml์— ๋Œ€ํ•ด call_site() ident๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š” extern ํฌ๋ ˆ์ดํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ, Span::def_site() ๊ฐ€ ์žˆ๋Š” extern ํฌ๋ ˆ์ดํŠธ๊ฐ€ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ Cargo.toml ์˜ 1๋‹จ๊ณ„(๋Œ€์ƒ) ์ข…์†์„ฑ์— ๋Œ€ํ•ด ํ•ด๊ฒฐ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์˜ค๋Š˜์˜ 0๋‹จ๊ณ„ ์ข…์†์„ฑ์€ ํ˜ธ์ŠคํŠธ ํ”Œ๋žซํผ์šฉ์œผ๋กœ ์ปดํŒŒ์ผ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. . 1๋‹จ๊ณ„ ์ข…์†์„ฑ์€ ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— extern crate์˜ ์ด๋ฆ„์ด ๋น„์œ„์ƒ์ ์œผ๋กœ ํ•ด์„๋˜์–ด ์ง€์ ํ•œ ๋Œ€๋กœ ์งœ์ฆ์ด ๋‚ฉ๋‹ˆ๋‹ค.

1๋‹จ๊ณ„ ์ข…์†์„ฑ์ด ์žˆ์œผ๋ฉด ์ฒ˜์Œ์—๋Š” ๊ฐ ํ™•์žฅ์—์„œ extern crate ๋ฅผ ์ธ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋ฌธ์ œ๊ฐ€ ๋œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ณ„ํš์€ ๋จผ์ € proc-macro crate์˜ ๋Œ€์ƒ ์ข…์†์„ฑ์„ ํ•ด๊ฒฐํ•œ ๋‹ค์Œ ์ดํƒˆ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‚ฎ์€ ์šฐ์„  ์ˆœ์œ„ ๊ฒฝ๊ณ  ์ฃผ๊ธฐ๋กœ ๋น„์œ„์ƒ์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ ํด๋ฐฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

extern ํฌ๋ ˆ์ดํŠธ์˜ ๊ฒฝ์šฐ proc ๋งคํฌ๋กœ์— ์˜ํ•ด 1๋‹จ๊ณ„์—์„œ ํฌ๋ ˆ์ดํŠธ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
#[proc_macro_derive(Serialize, attributes(serde), crates(serde))]

ํฅ๋ฏธ๋กญ๊ฒŒ๋„ ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  1๋‹จ๊ณ„ ํฌ๋ ˆ์ดํŠธ๊ฐ€ proc-macro ํฌ๋ ˆ์ดํŠธ ๋ฃจํŠธ(์˜ˆ: #[phase(1)] extern crate foo; )์—์„œ ์„ ์–ธ๋˜์–ด ๋ชจ๋“  proc ๋งคํฌ๋กœ(์˜ˆ: quote!(use foo::bar); )์—์„œ ์ž๋™์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  extern crate ๊ฐ€ ๋‚˜์˜ฌ ์˜ˆ์ •์ด๋ฏ€๋กœ 1๋‹จ๊ณ„ ํฌ๋ ˆ์ดํŠธ๋ฅผ ๋ชจ๋‘ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Cargo.toml์˜ ๋ชจ๋“  ๋Œ€์ƒ ์ข…์†์„ฑ์€ 1๋‹จ๊ณ„์˜ proc-macro ํฌ๋ ˆ์ดํŠธ ๋ฃจํŠธ ๋ฒ”์œ„์— ์ž๋™์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

๋‚ด ์ฝ”๋“œ์—์„œ ์ด๋ฆ„ ํ™•์ธ์„ ์ œ์–ดํ•˜๊ณ  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๋‘ ๊ฐ€์ง€ ๋ชฉ์ ์œผ๋กœ ์ŠคํŒฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€๊ฐ€ ๋ถˆ๊ฐ€๋ถ„์˜ ๊ด€๊ณ„์— ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ํ•œ ๋ฒ”์œ„์˜ ์ด๋ฆ„ ํ™•์ธ ์ธก๋ฉด๊ณผ ๋‹ค๋ฅธ ๋ฒ”์œ„์˜ ํ–‰/์—ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์œ„์น˜๋ฅผ ํ˜ผํ•ฉํ•˜๋Š” ๋ฒ”์œ„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ด๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜๋ฉด, ๋‚ด ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ์˜ def_site ๋‚ด ๋ฒ”์œ„๋กœ ํŠธ๋ ˆ์ดํŠธ๋ฅผ ๊ฐ€์ ธ์™”๊ณ  ์‚ฌ์šฉ์ž ๊ตฌ์กฐ์ฒด์˜ ํ•„๋“œ์—์„œ ํŠธ๋ ˆ์ดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•„๋“œ ์œ ํ˜•์ด ์˜ฌ๋ฐ”๋ฅธ ํŠน์„ฑ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•ด๋‹น ๊ตฌ์กฐ์ฒด ํ•„๋“œ์— ๋ฐ‘์ค„์„ ๊ธ‹๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” def_site ๋ฒ”์œ„๋กœ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์•ˆํƒ€๊น๊ฒŒ๋„ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ๋งคํฌ๋กœ 1.1์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ ํ•ญ์ƒ ํŒŒ์ƒ ์†์„ฑ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

  |
4 | #[derive(HeapSize)]
  |          ^^^^^^^^

๋˜๋Š” ๊ตฌ์กฐ์ฒด ํ•„๋“œ์˜ ident ๋˜๋Š” ์œ ํ˜•๊ณผ ๋™์ผํ•œ ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์˜ฌ๋ฐ”๋ฅธ ๋ฐ‘์ค„์„ ํ‘œ์‹œํ•˜์ง€๋งŒ def_site์˜ ๋ฒ”์œ„ ๋‚ด ํŠน์„ฑ์„ ํ™•์ธํ•˜๋Š” ๋ฐ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

  |
7 |     bad: std::thread::Thread,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•˜๊ณ  ์›ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@dtolnay ํ›Œ๋ฅญํ•œ ์ง€์ ์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

https://github.com/rust-lang/rust/issues/46489 ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์€ ์ƒ์„ฑ๋œ #[derive(โ€ฆ)] ํ† ํฐ์ด ๋™์ผํ•œ ์ด๋ฆ„-ํ•ด์ƒ๋„ ๋ฒ”์œ„๋ฅผ ๊ฐ–๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ฒ”์œ„๋ฅผ ์œ ํ˜• ์ •์˜๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•œ quote! {} ๋งคํฌ๋กœ ํ˜ธ์ถœ ์‹œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ์œ„์ƒ์— ๊ด€ํ•œ ์ด์•ผ๊ธฐ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” (4 ๊ฐœ์›” ์ „) ์ž‘๋™ํ–ˆ๋˜ ์ ˆ์ฐจ ๋งคํฌ๋กœ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ Rustc 1.24.0-nightly (b65f0bedd 2018-01-01) ํ˜„์žฌ ๋ฒ”์œ„์—์„œ ์ธ์ˆ˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๊ณ  ๋ถˆํ‰ํ•ฉ๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด์Šˆ ํŠธ๋ž˜์ปค๋ฅผ ๋จผ์ € ๊ฒ€์ƒ‰ํ–ˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ ๋ฐฉ๊ธˆ https://github.com/rust-lang/rust/issues/46489๋ฅผ ๋ฐฉ๋ฌธํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

๋‚˜๋Š” ํ˜„์žฌ ํŒŒ์ƒ(์—ญ์ง๋ ฌํ™”)์˜ ์˜ฌ๋ฐ”๋ฅธ ๊ตฌํ˜„์„ ์ฐจ๋‹จํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” #47311์„ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” ๊ฐœ์ธ ํ•„๋“œ๊ฐ€ ์žˆ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

self.0 ์™€ ๊ฐ™์€ ๋ช…๋ช…๋˜์ง€ ์•Š์€ ํŠœํ”Œ ๊ตฌ์กฐ์ฒด ํ•„๋“œ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋Š” self.x ์™€ ๊ฐ™์€ ๋ช…๋ช…๋œ ๊ตฌ์กฐ์ฒด ํ•„๋“œ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค์™€ . ํ† ํฐ์˜ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋‹ค๋ฅธ #47312๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค

#47311 ๋ฐ #47312๋Š” ๊ฐ๊ฐ #48082 ๋ฐ #48083์— ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‘ PR์ด ๊ฒ€ํ† /๋Œ“๊ธ€์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ https://github.com/rust-lang/rust/pull/41029 ๊ฐ€ ์™„๋ฃŒ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?

๊ทธ PR์€ ํฌ๊ธฐํ–ˆ์ง€๋งŒ ๋˜์‚ด์•„๋‚ฌ๊ณ  #48465์—์„œ ๊ณ„์† ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ Crater์—์„œ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@petrochenkov @nrc

syntax::ext::expand ๋ฅผ ๋ณด๋ฉด proc_macro_attribute ๊ฐ€ ํ˜„์žฌ ์—ฌ๋Ÿฌ ์ปจํ…์ŠคํŠธ์—์„œ ์ฒ˜๋ฆฌ๋˜๊ณ  ์žˆ์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

  • ๋ธ”๋ก์— ( fold_block() ๋Š” ๋ฉ์ฒญํ•œ ์ง“์ž…๋‹ˆ๋‹ค)
  • ๋ฌธ/ํ‘œํ˜„์‹(#41475, #43988)
  • extern {} ๋ธ”๋ก ๋‚ด๋ถ€(#48747)

RFC 1566์€ ์†์„ฑ ๋งคํฌ๋กœ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ • AST ๋…ธ๋“œ ์ข…๋ฅ˜๋ฅผ ๋‚˜์—ดํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์•ฝ๊ฐ„ ์šฐ์Šค๊ฝ์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜์ง€๋งŒ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๊ฒƒ๊ณผ ์†์„ฑ์ด ํ—ˆ์šฉ๋˜์–ด์„œ๋Š” ์•ˆ ๋˜์ง€๋งŒ ํ˜„์žฌ ํ—ˆ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(#43988).

@abonander ์˜๋„๋Š” proc ๋งคํฌ๋กœ ์†์„ฑ์ด ์ผ๋ฐ˜ ์†์„ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด๋ฉด ์–ด๋””๋“ ์ง€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์˜ ๋ชจ๋“  ์‚ฌํ•ญ์„ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์ผ๋ถ€๋Š” ์•ˆ์ •์ ์ด์ง€ ์•Š๊ณ  proc ๋งคํฌ๋กœ๋ฅผ ์•ˆ์ •ํ™”ํ•œ๋‹ค๋ฉด ๋‹ค๋ฅธ ์†์„ฑ์— ๋Œ€ํ•ด ์•ˆ์ •์ ์ธ ์šฉ๋„๋งŒ ์•ˆ์ •ํ™”).

@nrc ๋Š” ์†์„ฑ์ด ๋ชจ๋“  ํ•ญ๋ชฉ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ฐธ์กฐ ๋งŒ ํ‘œ์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์œ„์น˜๋ฅผ ์—ด๊ฑฐํ•˜๋Š” ๋ชจ๋“  ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฆฐํŠธ ์†์„ฑ์ด ๋ธ”๋ก๊ณผ ๋ช…๋ น๋ฌธ์—๋„ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฑฐ์˜ ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

@nrc ๋Š” ์†์„ฑ์ด ๋ชจ๋“  ํ•ญ๋ชฉ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ฐธ์กฐ์— ๋ช…์‹œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์œ„์น˜๋ฅผ ์—ด๊ฑฐํ•˜๋Š” ๋ชจ๋“  ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฆฐํŠธ ์†์„ฑ์ด ๋ธ”๋ก๊ณผ ๋ช…๋ น๋ฌธ์—๋„ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฑฐ์˜ ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

afaik์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ‘œํ˜„์‹์˜ ์†์„ฑ์— ๋Œ€ํ•ด ํ—ˆ์šฉ๋˜๋Š” RFC ๋ฐ ๋ถˆ์•ˆ์ •ํ•œ ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ์ง€๋งŒ ๋ช…๋ น๋ฌธ ๋ฐ ๋ธ”๋ก์—์„œ๋งŒ ์•ˆ์ •ํ™”๋œ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ:

์•ˆ์ •์„ฑ ๊ฒ€์‚ฌ(proc-) ๋งคํฌ๋กœ(๋ฌธ์ œ #34079).

์ด์ œ WRT ํ”„๋กœ์‹œ์ € ๋งคํฌ๋กœ๊ฐ€ ๋‹ซํž™๋‹ˆ๋‹ค. ๋‚ด PR์€ Macros 2.0 ๋งคํฌ๋กœ์— ๋Œ€ํ•œ ์•ˆ์ •์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์—ฌ์ „ํžˆ ์—ด๋ ค ์žˆ์Šต๋‹ˆ๋‹ค(๋น„๋ก ์ƒˆ๋กœ์šด ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ).

@rfcbot fcp ๋ณ‘ํ•ฉ

์ €๋Š” Rust 1.28 ๋ฆด๋ฆฌ์Šค๋ฅผ ์œ„ํ•ด ๋งคํฌ๋กœ 2.0 ์ด์•ผ๊ธฐ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ ์„ ๋งคํฌ๋กœ 1.2๋กœ ์•ˆ์ •ํ™”ํ•  ๊ฒƒ์„ ์ œ์•ˆํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. Rust 1.28์€ 2018๋…„ 5์›” 10์ผ ๋ฐค์— ์‹œ์ž‘๋˜๊ณ (์ด ๊ธ€์„ ์ž‘์„ฑํ•œ ํ›„ ~2.5์ฃผ) 2018๋…„ 8์›” 2์ผ์— ์•ˆ์ •ํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. FCP๊ฐ€ 5์›” 10์ผ ๋ฒ ํƒ€์— ๋“ค์–ด๊ฐ€๋Š” 1.27 ์ปท์˜คํ”„ ์ „์— ์™„๋ฃŒ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋ณด๋ฅ˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ปท์˜คํ”„๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๊นŒ์ง€ ์—ฌ๊ธฐ์—์„œ ๋ชจ๋“  ์•ˆ์ •ํ™”๋ฅผ ๋„๊ณ  1.28 ๋ฆด๋ฆฌ์Šค๋กœ ์—ฐ๊ธฐํ•˜์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์€ @petrochenkov์— ์˜ํ•ด ๋“ฑ๋ก๋œ ๋งŽ์€ ๋ฌธ์ œ์™€ ํ•จ๊ป˜ ์ตœ๊ทผ ๋‚ด๋ถ€ ์—์„œ

์ด๊ฒƒ์ด ๋ถ€๋ถ„์ง‘ํ•ฉ ์ด๋ผ๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์‹ญ์‹œ์˜ค. ์—ฌ๊ธฐ์— ๊ธฐ๋Šฅ์ด ์—†๋‹ค๊ณ  ํ•ด์„œ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์•ˆ์ •ํ™”๋˜๊ฑฐ๋‚˜ ์ œ๊ฑฐ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ์ด ๊ธฐ๋Šฅ์€ ์ด ์•ˆ์ •ํ™” ๋‹จ๊ณ„๊ฐ€ ์ œ์•ˆ๋œ ์ดํ›„์—๋„ ๋ถˆ์•ˆ์ •ํ•œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์—ฌ ๋‚˜์ค‘์— ์•ˆ์ •ํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งคํฌ๋กœ์™€ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ

์ฃผ๋กœ https://github.com/rust-lang/rust/issues/35896 ๋ฐ ํ˜„์žฌ ์ ์šฉ๋จ
FCP๋ฅผ ์™„๋ฃŒํ•œ ์ฃผ์š” ์•„์ด๋””์–ด๋Š” use ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ
๋งคํฌ๋กœ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ:

use some_proc_macro_crate::bar;

#[bar]
fn baz() {}

๋˜๋Š”

use some_proc_macro_crate::bar;
bar!();

๋˜๋Š”

pub use some_proc_macro_crate::bar; // reexport an attribute or macro

์ด๊ฒƒ์€ Rust์— ์„ธ ๋ฒˆ์งธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค(๊ฐ’/์œ ํ˜• ์ถ”๊ฐ€
๋„ค์ž„์ŠคํŽ˜์ด์Šค), ๋งคํฌ๋กœ ๋„ค์ž„์ŠคํŽ˜์ด์Šค. ์†์„ฑ, macro_rules ๋ฐ ์ ˆ์ฐจ
๋งคํฌ๋กœ๋Š” ๋ชจ๋‘ maro ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณธ๊ฒฉ์ ์ธ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๊ณผ์˜ ์ฐจ์ด์ ์€ ๋‹จ ํ•˜๋‚˜์˜ ์š”์†Œ ๊ฒฝ๋กœ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋งคํฌ๋กœ .
์˜ˆ๋ฅผ ๋“ค์–ด #[foo::bar] ๋˜๋Š” ::bar::baz!() ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ
์ œํ•œ์€ ์–ธ์  ๊ฐ€ ํ•ด์ œ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€
์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

ํ™•์žฅ์€ ์–ด๋””์—์„œ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์†์„ฑ ์€ ๋ชจ๋“ˆ์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ํ•ญ๋ชฉ .
์—ฌ๊ธฐ์˜ "ํ•ญ๋ชฉ"์—๋Š” ํŠน์„ฑ ํ•ญ๋ชฉ, impl ํ•ญ๋ชฉ ๋ฐ ์™ธ๋ถ€ ๋ชจ๋“ˆ๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ. ๋ชจ๋“ˆ ํ™•์žฅ์€ ์œ„์ƒ ๋ฐ
๊ตฌํ˜„ ๊ฒฐ๊ณผ. ์ด๊ฒƒ์„ ์ง€์ •ํ•˜๊ณ  ์•ˆ์ •ํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜์ค‘ ๋‚ ์งœ.

๋ช…๋ น๋ฌธ ๋ฐ ํ‘œํ˜„์‹ ์†์„ฑ ๋งคํฌ๋กœ๋Š” ์•„์ง ์•ˆ์ •์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€
์ฃผ๋กœ ํ‘œํ˜„ ์ˆ˜์ค€์—์„œ ์œ„์ƒ์ด ์‹ค์ œ๋กœ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(
์•„์ดํ…œ ๋ ˆ๋ฒจ๊ณผ ๋ฐ˜๋Œ€). ์ด๋Š” ์ถ”ํ›„ ์•ˆ์ •ํ™”๋ฅผ ์œ„ํ•ด ๋‚จ๊ฒจ๋‘ก๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์†์„ฑ ๋งคํฌ๋กœ ์—๋Š” ๋‚ด๋ถ€์— ์ธ์ˆ˜๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.๊ตฌ๋ถ„์ž .
์˜ˆ: #[foo] , #[foo(bar)] ๋ฐ #[foo { bar baz ... @ | ^ hello }]
์œ ํšจํ•œ ํ˜ธ์ถœ์ž…๋‹ˆ๋‹ค. #[foo = "baz"] , #[foo bar] , ๋˜๋Š”
#[foo ... = ( baz )] ๋Š” ์ฒ˜์Œ์—๋Š” ์•ˆ์ •์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ?

์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ proc-macro ํฌ๋ ˆ์ดํŠธ ์œ ํ˜• ํฌ๋ ˆ์ดํŠธ์— ์ •์˜๋ฉ๋‹ˆ๋‹ค.
์ ˆ์ฐจ์  ๋งคํฌ๋กœ์™€ ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋ฉ๋‹ˆ๋‹ค.

extern crate proc_macro;
use proc_macro::TokenStream;

/// Invoked as `foo!()`
///
/// When invoked as `foo!(a b ( c ))` then the `TokenStream`
/// here will be `a b ( c )`.
///
/// The invocation is replaced with the `TokenStream` returned
#[proc_macro]
pub fn foo(a: TokenStream) -> TokenStream {
    // ...
}

/// Invoked as `#[bar]`
///
/// The first argument, `attr`, is the token stream inside of the attribute
/// itself. The second argument, `item`, is the token stream corresponding to
/// the item the attribute is attached to.
///
/// An attribute of the form `#[bar ( a b [ c ] )]` will have the `attr`
/// argument look like `a b [ c ]`. Note the lack of delimiters passed to
/// `attr`! An API may later be added to learn what delimiter a macro was
/// invoked with.
///
/// The `item` here is a tokenified version of the original item.
///
/// The return value here will contain all non-expanded attributes as well for
/// this attribute to inspect. The return value replaces the original item.
#[proc_macro]
pub fn bar(attr: TokenStream, item: TokenStream) -> TokenStream {
    // ...
}

์œ„์ƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์œ„์—์„œ ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ๊ณผ ๋งคํฌ๋กœ๋Š”
ํ•ญ๋ชฉ ์ปจํ…์ŠคํŠธ, ํŠนํžˆ
์ฆ‰, ์ƒˆ๋กœ์šด AST ํ•ญ๋ชฉ์„ ์ƒ์„ฑํ•˜๋Š” ์œ„์ƒ์— ๋Œ€ํ•ด์„œ๋งŒ ๊ฑฑ์ •ํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค.
๋…ธ๋“œ.

์ƒˆ ํ’ˆ๋ชฉ์˜ ์œ„์ƒ ์ƒํƒœ๋Š” ํ˜„์žฌ macro_rules! ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ํ•  ๊ฒƒ์ด๋‹ค
์œ„์ƒ์ ์ด์ง€ ์•Š๋‹ค. AST์— ์ถ”๊ฐ€๋œ ์ƒˆ ํ•ญ๋ชฉ์€ ๋‹ค์Œ๊ณผ ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
๋ชจ๋“ˆ์˜ ๋‹ค๋ฅธ ํ•ญ๋ชฉ.

proc_macro API.

์ด ๋ชจ๋“  ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ํ‘œ๋ฉด์ ์ด ์•ˆ์ •ํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
proc_macro ์ƒ์ž:

pub struct TokenStream(_);

impl TokenStream {
    pub fn empty() -> TokenStream;
    pub fn is_empty(&self) -> bool;
}

impl Clone for TokenStream { ... }
impl Debug for TokenStream { ... }
impl Display for TokenStream { ... }
impl FromStr for TokenStream { ... }
impl From<TokenTree> for TokenStream { ... }
impl FromIterator<TokenTree> for TokenStream { ... }
impl FromIterator<TokenStream> for TokenStream { ... }
impl !Send for TokenStream { ... }
impl !Sync for TokenStream { ... }

impl IntoIterator for TokenStream {
    type Item = TokenTree;
    type Iter = token_stream::IntoIter;
}

pub mod token_stream {
    pub struct IntoIter(_);

    impl Iterator for IntoIter {
        type Item = ::TokenTree;
    }
}

pub enum TokenTree {
    Op(Op),
    Term(Term),
    Literal(Literal),
    Group(Group),
}

impl TokenTree {
    pub fn span(&self) -> Span;
    pub fn set_span(&mut self, span: Span);
}

impl Clone for TokenTree { ... }
impl Debug for TokenTree { ... }
impl Display for TokenTree { ... }
impl From<Op> for TokenTree { ... }
impl From<Term> for TokenTree { ... }
impl From<Literal> for TokenTree { ... }
impl From<Group> for TokenTree { ... }
impl !Send for TokenTree { ... }
impl !Sync for TokenTree { ... }

pub struct Span(_);

impl Span {
    pub fn call_site() -> Span;
}

impl Clone for Span { ... }
impl Copy for Span { ... }
impl Debug for Span { ... }
impl !Send for Span { ... }
impl !Sync for Span { ... }

pub struct Group(_);

pub enum Delimiter {
    Parenthesis,
    Brace,
    Bracket,
    None,
}

impl Group {
    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group;
    pub fn stream(&self) -> TokenStream;
    pub fn delimiter(&self) -> Delimiter;
    pub fn span(&self) -> Span;
    pub fn set_span(&mut self, span: Span);
}

impl Clone for Group { ... }
impl Debug for Group { ... }
impl Display for Group { ... }
impl !Send for Group { ... }
impl !Sync for Group { ... }

impl Copy for Delimiter { ... }
impl Clone for Delimiter { ... }
impl Debug for Delimiter { ... }
impl PartialEq for Delimiter { ... }
impl Eq for Delimeter { ... }

pub struct Term(_);

impl Term {
    pub fn new(s: &str, span: Span) -> Term;
    pub fn span(&self) -> Span;
    pub fn set_span(&mut self, span: Span);
}

impl Copy for Term { ... }
impl Clone for Term { ... }
impl Debug for Term { ... }
impl Display for Term { ... }
impl !Send for Term { ... }
impl !Sync for Term { ... }

pub struct Op(_);

pub enum Spacing {
   Alone,
   Joint,
}

impl Op {
    pub fn new(op: char, spacing: Spacing) -> Op;
    pub fn op(&self) -> char;
    pub fn spacing(&self) -> Spacing;
    pub fn span(&self) -> Span;
    pub fn set_span(&mut self, span: Span);
}

impl Debug for Op { ... }
impl Display for Op { ... }
impl Clone for Op { ... }
impl Copy for Op { ... }
impl !Send for Op { ... }
impl !Sync for Op { ... }

impl Copy for Spacing { ... }
impl Clone for Spacing { ... }
impl Debug for Spacing { ... }
impl PartialEq for Spacing { ... }
impl Eq for Spacing { ... }

pub struct Literal(_);

impl Literal {
  // panic on infinity and NaN
  pub fn f{32,64}_{un,}suffixed(f: f{32,64}) -> Literal;

  pub fn i{8,16,32,64,128,size}_{un,}suffixed(n: i{8,16,32,64,128,size}) -> Literal;
  pub fn u{8,16,32,64,128,size}_{un,}suffixed(n: u{8,16,32,64,128,size}) -> Literal;

  pub fn string(s: &str) -> Literal;
  pub fn character(c: char) -> Literal;
  pub fn byte_string(b: &[u8]) -> Literal;

  pub fn span(&self) -> Span;
  pub fn set_span(&mut self, span: Span) -> Span;
}

impl Clone for Literal { ... }
impl Debug for Literal { ... }
impl Display for Literal { ... }
impl !Send for Literal { ... }
impl !Sync for Literal { ... }

์ด API์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์˜จ๋ผ์ธ ๋˜๋Š” ์›๋ณธ ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ „๋žต

๋งคํฌ๋กœ 1.1 ๋ฐ ๋งคํฌ๋กœ 2.0 ์‹œ์Šคํ…œ์€ ์ „์ฒด์— ๊ฑธ์ณ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ dogfood๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฝค ์˜ค๋žซ๋™์•ˆ ์ƒํƒœ๊ณ„. ํŠนํžˆ ์ด ์ „์ฒด ์ œ์•ˆ์€
proc-macro2 ํฌ๋ ˆ์ดํŠธ ์˜ 0.3 ๋ฆด๋ฆฌ์Šค๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
syn ํฌ๋ ˆ์ดํŠธ ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๋งŽ์€ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์‹๋ณ„ ๋ฐ ๊ณ ์ •๋˜์—ˆ์œผ๋ฉฐ ํ˜„์žฌ ์‹œ์Šคํ…œ์€
์•ˆ์ •๋œ. (๋ฒ„๊ทธ๊ฐ€ ์—†๋‹ค๋Š” ๋ง์€ ์•„๋‹™๋‹ˆ๋‹ค!)

ํŒ€์› @alexcrichton ์ด ์ด๋ฅผ ๋ณ‘ํ•ฉํ•  ๊ฒƒ์„ ์ œ์•ˆํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„๋Š” ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ๋‚˜๋จธ์ง€ ํŒ€์ด ๊ฒ€ํ† ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • [x] @ํ‚ค๋ฌธ๋””
  • [ ] @์‚ฌ์ด๋จผ์‚ฌํ•€
  • [x] @alexcrichton
  • [x] @์•„ํˆฌ๋ก 
  • [x] @cramertj
  • [x] @dtolnay
  • [x] @eddyb
  • [x] @joshtriplett
  • [x] @nikomatsakis
  • [x] @nrc
  • [ ] @pnkfelix
  • [x] @scottmcm
  • [x] @sfackler
  • [x] @withoutboats

ํ˜„์žฌ ๋‚˜์—ด๋œ ์šฐ๋ ค ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ณผ๋ฐ˜์ˆ˜์˜ ๊ฒ€ํ† ์ž๊ฐ€ ์Šน์ธํ•˜๊ณ  ๋ฐ˜๋Œ€ํ•˜์ง€ ์•Š์œผ๋ฉด ์ตœ์ข… ์˜๊ฒฌ ์ œ์ถœ ๊ธฐ๊ฐ„์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค์˜ ์–ด๋Š ์‹œ์ ์—์„œ๋„ ์ œ๊ธฐ๋˜์ง€ ์•Š์€ ์ฃผ์š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”!

ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํŒ€ ๊ตฌ์„ฑ์›์ด ๋‚˜์—๊ฒŒ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ช…๋ น์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์ด ๋ฌธ์„œ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

cc @rust-lang/compiler, ์—ฌ๋Ÿฌ๋ถ„๋„ ์ด์— ๋Œ€ํ•ด ๋งค์šฐ ๊ด€์‹ฌ์ด ๋งŽ์œผ๋‹ˆ ์–ธ์ œ๋“ ์ง€ ์ด์˜๋ฅผ ์ œ๊ธฐํ•ด ์ฃผ์‹ญ์‹œ์˜ค. ์ฐจ๋‹จ ์ด์˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋“ฑ๋กํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ์ •ํ™”๋ฅผ ์œ„ํ•ด ์ œ์•ˆ๋œ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ proc ๋งคํฌ๋กœ๋Š” ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ† ํฐ์„ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์ž…๋ ฅ์—์„œ ์ถœ๋ ฅ์œผ๋กœ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ‘œ๋ฉด ์ˆ˜์ค€์—์„œ๋„ ํ† ํฐ ์ŠคํŠธ๋ฆผ์„ ์‰ฝ๊ฒŒ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Literal ๋Š” Eq ๋˜๋Š” PartialEq ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์žˆ๋‚˜์š”? (๊ทธ๊ฒƒ๋„ ๊ฐ’์„ ์ถ”์ถœํ•˜๊ณ  ์ฝ”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋Œ€์‹  ์ง€์ •๋œ ์ƒ์ˆ˜ ๊ฐ’๊ณผ์˜ ๋น„๊ต๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.)

TokenStream ์ฃผ์–ด์ง€๋ฉด proc ๋งคํฌ๋กœ ๊ตฌํ˜„ ๋‚ด๋ถ€์—์„œ proc ๋งคํฌ๋กœ๋Š” ๋ฆฌํ„ฐ๋Ÿด์„ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•ด 1์˜ ๊ฐ’์„ ์ถ”์ถœํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๋‹จ์ˆœํžˆ ์•„์ง ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ํ–ฅํ›„ ์ง€์›ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

(์ œ์•ˆ๋œ ํ•˜์œ„ ์ง‘ํ•ฉ์˜ ์•ˆ์ •ํ™”๋ฅผ ์ฐจ๋‹จํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ•ด๋‹น ํ•˜์œ„ ์ง‘ํ•ฉ๊ณผ ์˜๋„๋œ ๊ธฐ๋Šฅ์„ ๋” ์ž˜ ์ดํ•ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.)

@alexcrichton ์ƒˆ ํ•ญ๋ชฉ์€
์œ„์ƒ์ ์ด์ง€ ์•Š๋‹ค. AST์— ์ถ”๊ฐ€๋œ ์ƒˆ ํ•ญ๋ชฉ์€ ๋‹ค์Œ๊ณผ ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
๋ชจ๋“ˆ์˜ ๋‹ค๋ฅธ ํ•ญ๋ชฉ.

์ €๋Š” Rust ํ•ต์‹ฌ ํŒ€์— ์†ํ•ด ์žˆ์ง€ ์•Š๊ณ  ๊ณผ๊ฑฐ์˜ ๋ชจ๋“  ํ† ๋ก ์„ ์ฒ ์ €ํžˆ ์‚ดํŽด๋ณด์ง€๋Š” ์•Š์•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ •๋ง ๋‚˜์˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๋งคํฌ๋กœ๊ฐ€ ๋งคํฌ๋กœ์—์„œ๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋„์šฐ๋ฏธ ํ•ญ๋ชฉ์„ ์ƒ์„ฑํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ?

์œ„์ƒ์„ ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค ์™„์ „ํ•œ 100% ์œ„์ƒ์„ ์‹œํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋งคํฌ๋กœ๊ฐ€ ํŠน์ • ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์œ„์ƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ์˜ตํŠธ์•„์›ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

@joshtriplett ๋ฆฌํ„ฐ๋Ÿด์— Display impl์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@joshtriplett ์˜ˆ @dtolnay๊ฐ€ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด literalext ์™€ ๊ฐ™์€ ์ƒ์ž๊ฐ€ ๊ตฌ์ถ•๋˜๋Š” Display ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ API๋Š” ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ์ผ๋ฅ˜ API๊ฐ€ ์•„๋‹ˆ๋ผ "์ตœ์†Œํ•œ์˜" ์ˆ˜์ค€์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์€ ์•„๋งˆ๋„ ๋‚˜์ค‘์— ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์ด ์•ˆ์ •ํ™” ๋‹จ๊ณ„๋Š” ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€( Display ๊ฒฝ์šฐ Literal ๋ฐ ์ด๋ฅผ ํ•ด์„ํ•  ๋‹ค๋ฅธ ๊ฒƒ์€ ์—†์Œ)๋ฅผ ํฌํ•จํ•˜๋Š” ์ตœ์†Œํ•œ์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค๋Š” ์˜๋ฏธ์—์„œ "์ตœ๋Œ€ํ•œ ์ตœ์†Œํ™”"ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ).

@Pauan ์ข‹์ง€ ๋Š” ์•Š์ง€๋งŒ macro_rules! ์™€ ์ •ํ™•ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์•„์ง ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Span::call_site() ์ƒ์„ฑ์ž๋Š” ์—ฌ๊ธฐ์—์„œ "์œ„์ƒ ์—†์Œ"์„ ์š”์ฒญํ•˜๋Š” ํ•ต์‹ฌ ํ•€์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์šฐ๋ฆฌ๋Š” ๋” ๋งŽ์€ ์˜ต์…˜์„ ์•ˆ์ •ํ™”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ "์™„์ „ํ•œ 100% ์œ„์ƒ"์€ ๋ช‡ ๋…„์ด ๋‚จ์•˜๊ณ  ์ด ์ œ์•ˆ์˜ ๋ชฉ์ ์€ Rust 2018์—์„œ ์•ˆ์ •์ ์ธ ๊ฒƒ์„ ์–ป๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@alexcrichton ๊ทธ๋ž˜์„œ ์ง€๊ธˆ ์œ„์ƒ์ ์ธ โ€‹โ€‹๊ตฌ๋ฉ์œผ๋กœ ๊ทธ๊ฒƒ์„ ์•ˆ์ •ํ™”์‹œํ‚จ ๋‹ค์Œ ๋ช‡ ๊ฐœ์˜ ์‹œ๋Œ€/์‹œ๋Œ€/์—๋””์…˜์ด ๋‚˜์ค‘์— ๊ทธ ์œ„์ƒ์ ์ธ โ€‹โ€‹๊ตฌ๋ฉ์„ ๊ณ ์น  ๊ณ„ํš์ž…๋‹ˆ๊นŒ?

Span::call_site() ์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ ์™„์ „ํ•œ ์œ„์ƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋Š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ธ๋ ฅ/์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด RFC์—์„œ ๊ตฌ์ฒดํ™”ํ•ด์•ผ ํ•˜๋Š” ์ด๋ก ์ /์˜๋ฏธ๋ก ์  ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@Pauan ์€ ์˜ค๋Š˜๋‚  ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋Š” ์˜๋ฏธ์—์„œ ์‹ค์ œ "๊ตฌ๋ฉ"์ด ์—†์Œ์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ macro_rules! ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ๊ณผ ์ •ํ™•ํžˆ ๋™์ผํ•œ ์œ„์ƒ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ์€ ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋„์ž…ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์‹ค์ƒ ๊ทธ ํ™•์žฅ์ž…๋‹ˆ๋‹ค.

"์™„๋ฒฝํ•œ ์œ„์ƒ ์ด์•ผ๊ธฐ"๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์–ด๋–ค ํ˜•ํƒœ์˜ ์„ ํƒ ํ•ด์ œ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ํ•ด๋‹น ์˜ตํŠธ์•„์›ƒ์€ Span::call_site() (ํšจ๊ณผ์ ์œผ๋กœ). ์šฐ๋ฆฌ๋Š” ์œ„์ƒ์„ ์œ„ํ•œ ์˜ตํŠธ์•„์›ƒ ๋ฉ”์ปค๋‹ˆ์ฆ˜๋งŒ ์•ˆ์ •ํ™”ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค๋งŒ ์•ˆ์ •ํ™”ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์šฐ๋ฆฌ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ•ญ๋ชฉ์„ ์™„์ „ํžˆ ์œ„์ƒ์ ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์•ˆ์ •ํ™”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์ƒ์„ ์•ˆ์ •ํ™”ํ•˜๋Š” ๊ฒƒ์€ ํ›จ์”ฌ ๋” ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. (AFAIK) ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ์—ฐ๊ตฌ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ ฅ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

@dtolnay ์•„,

cc @rust-lang/compiler, ์—ฌ๋Ÿฌ๋ถ„๋„ ์ด์— ๋Œ€ํ•ด ๋งค์šฐ ๊ด€์‹ฌ์ด ๋งŽ์œผ๋‹ˆ ์–ธ์ œ๋“ ์ง€ ์ด์˜๋ฅผ ์ œ๊ธฐํ•ด ์ฃผ์‹ญ์‹œ์˜ค. ์ฐจ๋‹จ ์ด์˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋“ฑ๋กํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ง ๊ฒ€ํ† ํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์‚ฌํ•ญ๊ณผ ๋ช‡ ๊ฐ€์ง€ proc-macro API ์กฐ์ •์ด ์ง„ํ–‰ ์ค‘์ธ PR์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ macro_rules์™€ ๋˜‘๊ฐ™์€ ์œ„์ƒ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค! ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒ์ƒ.

๋ฌผ๋ก , ํ•˜์ง€๋งŒ ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜๋Š” ๋” ๋‚˜์€ ๋งคํฌ๋กœ ์‹œ์Šคํ…œ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด(๊ณ ์žฅ๋‚˜๊ณ  ์ œํ•œ๋œ) ์‹œ์Šคํ…œ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์ด ๋‚˜์—๊ฒŒ ๊ทธ๋‹ค์ง€ ์„ค๋“๋ ฅ์žˆ๊ฒŒ ๋“ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

"์™„๋ฒฝํ•œ ์œ„์ƒ ์ด์•ผ๊ธฐ"๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์–ด๋–ค ํ˜•ํƒœ์˜ ์„ ํƒ ํ•ด์ œ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก , ํ•˜์ง€๋งŒ ์ œ ์š”์ ์€ ์›ํ•˜๋Š” ๊ฒฝ์šฐ Span::call_site() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์ƒ์„ ๊นจ๊ณ (๋”ฐ๋ผ์„œ macro_rules! ๊ธฐ๋Šฅ์„ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ) ๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„์ƒ์ ์œผ๋กœ ๋งŒ๋“ค๋ฉด ์œ„์ƒ๊ณผ ์œ„์ƒ์— ๋ชจ๋‘ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋น„์œ„์ƒ์ . ๋ฐ˜๋ฉด ๋น„์œ„์ƒ ์ƒํƒœ๋กœ ์•ˆ์ •ํ™”๋˜๋ฉด ๋น„์œ„์ƒ ์ƒํƒœ ๋กœ๋งŒ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ ์šฐ๋ฆฌ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ•ญ๋ชฉ์„ ์™„์ „ํžˆ ์œ„์ƒ์ ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์•ˆ์ •ํ™”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜คํžˆ๋ ค ์„ฑ๊ฐ€์‹  (ํ˜ผ๋ž€) ๋ฐ˜์ฐฝ๊ณ  ๊ฐ™์€ ๊ทธ ์†Œ๋ฆฌ : PROC ๋งคํฌ๋กœ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ (ํ•˜์ง€๋งŒ ํ•ญ๋ชฉ)์—์„œ ์œ„์ƒ ๊ฒƒ์ž…๋‹ˆ๋‹ค,ํ•˜์ง€๋งŒ ๋‹น์‹ ์€ ๋‹ค์Œ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์œ„์ƒ์— ์ˆ˜์‹  ๊ฑฐ๋ถ€์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?

(AFAIK) ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ์—ฐ๊ตฌ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ ฅ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ํŽธ์˜์™€ ์‹ค์šฉ์ฃผ์˜์— ๋Œ€ํ•œ ์—ด๋ง์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์–ธ์ œ ๊นŒ์ง€๋‚˜ ๊ณ„ํš์ด ๊ฒฐ๊ตญ ๋‚˜์ค‘์— ์‹œ๋Œ€ / ์‹œ๋Œ€ / ํŒ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ณ ์ฒด ์œ„์ƒ์„ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ํ•œ, ๋‚˜๋Š” ์ผ์‹œ์ ์œผ๋กœ ๋‚˜์œ ์œ„์ƒ์„ ๊ฐ€์ง„ ๊ดœ์ฐฎ์•„. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋‚˜์ค‘์— ํ›„ํšŒํ•  ๋ฌด์–ธ๊ฐ€๋ฅผ ์•ˆ์ •ํ™”ํ•˜๊ธฐ๋ฅผ ์›ํ•˜์ง€ ์•Š์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

์–ด๋–ค ์˜๋ฏธ์—์„œ, ์ด๋ฏธ "๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„์ƒ์€,"์ด ๊ธฐ๋ณธ์ด ์•„์ง ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๋‹จ์ง€์ž…๋‹ˆ๋‹ค์ด๋‹ค. Span::call_site ๋Š” ์„ ํƒ ํ•ด์ œ์ž…๋‹ˆ๋‹ค. :)

@Pauan @alexcrichton์ด ๋งํ•œ ๊ฒƒ์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ ค๋ฉด

์‹๋ณ„์ž๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์œ„์ƒ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ Span ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ( Term::new )

์•ž์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ์œ„์ƒ ์˜ต์…˜์„ ๋ฐ˜์˜ํ•˜๋Š” Span ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๊ณต๊ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ์€ ํ˜ธ์ถœ์ž์˜ ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Span::call_site ๋งŒ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „์ฒด ์œ„์ƒ ์‹œ์Šคํ…œ์ด ์ฆ‰์‹œ ์•ˆ์ •ํ™”๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ๋‚˜์ค‘์— ์œ„์ƒ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์€ ๊ฝค ์˜๋ฆฌํ•œ ํŠธ๋ฆญ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค!

@rpjohnst ๋”ฐ๋ผ์„œ proc ๋งคํฌ๋กœ์—์„œ ์ƒˆ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ Span::call_site ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๊นŒ?

๊ทธ๋ ‡๋‹ค๋ฉด ์™„๋ฒฝํ•˜๊ฒŒ ๋“ค๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์œ„์ƒ์€ ์‹ค์ œ๋กœ ๊นจ๋—ํ•˜๊ณ  ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฏธ๋ž˜์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@lfairy ์•„, ๋‚ด๊ฐ€ ๋ณผ, ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜๋‹คํ•˜์ง€ ์•Š์•˜๋‹ค Span::call_site , ๋‚˜๋Š” ์•”์‹œ ์  ๊ธฐ๋ณธ ๋น„์œ„์ƒ์  ๋ฒ”์œ„๊ฐ€ ์ƒ๊ฐํ–ˆ๋‹ค. ์„ค๋ช… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‹น์‹ ์ด ์˜ณ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋งค์šฐ ์˜๋ฆฌํ•œ ์†์ž„์ˆ˜์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋” ์ด์ƒ ์ด์˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@alexcrichton

์†์„ฑ, macro_rules ๋ฐ ์ ˆ์ฐจ
๋งคํฌ๋กœ๋Š” ๋ชจ๋‘ maro ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ #[feature(proc_macro)] ๋กœ ํ™•์ธํ–ˆ๋Š”๋ฐ ์—ฌ๊ธฐ์— ์„ค๋ช…๋œ ๋Œ€๋กœ ํŒŒ์ƒ ์˜ค๋ฅ˜ ์ฒด์ธ ํฌ๋ ˆ์ดํŠธ์— ๋Œ€ํ•œ ์•ˆ์ •์ ์ธ ์ฝ”๋“œ์—์„œ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ธ์šฉ๋œ ๋ฌธ์žฅ์„ ๋ณด๋ฉด ๋งคํฌ๋กœ 1.2์—์„œ๋„ ๊ณ„์† ์ด์™€ ๊ฐ™์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ ๋งž์Šต๋‹ˆ๊นŒ?

@Arnavion ์˜ค ์ด๋Ÿฐ, #[derive] ํ™•์žฅ ์ดํ›„๊นŒ์ง€ "์†์„ฑ์ด ์•„๋‹™๋‹ˆ๋‹ค" ์˜ค๋ฅ˜๋ฅผ ์—ฐ๊ธฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

#48644 ๋ฐ #47786์ด ์™„๋ฃŒ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ OP๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@alexcrichton Literal ๋ฐ ์นœ๊ตฌ๋“ค์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ํ—ˆ์šฉ์— ๋Œ€ํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ๋‚˜์š”? ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๋” ์ด์ƒ ์—ด๊ฑฐํ˜•์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์ง€๋งŒ Literal ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

    impl Literal {
        pub fn as_str(&self) -> Option<&str> {}
        pub fn to_int(&self) -> Option<i64> {}
        pub fn to_uint(&self) -> Option<u64> {}
        pub fn to_float(&self) -> Option<f64> {}
    }

๋‹ค๋ฅธ ๋ฆฌํ„ฐ๋Ÿด ํ•˜์œ„ ์œ ํ˜•์— ๋Œ€ํ•ด ๋งŽ์€ TryFrom impls๋ฅผ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@abonander ๊ทธ๊ฒƒ์€ ๋…ผ์˜๋˜์—ˆ์ง€๋งŒ ๊ฒฐ๋ก ์€ ์•ˆ์ •ํ™”์˜ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์— ํ•„์š”ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Display ๊ตฌํ˜„์œผ๋กœ crates.io์— ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•  ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

:bell: ์œ„ ์˜ ์ด์ œ ์ตœ์ข… ๋Œ“๊ธ€ ๊ธฐ๊ฐ„์— ์ ‘์–ด๋“ค์—ˆ์Šต๋‹ˆ๋‹ค . :๋ฒจ:

@alexcrichton
proc ๋งคํฌ๋กœ API ์œ ํ˜•์— ๋Œ€ํ•œ !Send ๋ฐ !Sync impls๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑ๋˜์ง€ ์•Š์•˜์ง€๋งŒ ์œ ์ถ”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ผ๋ถ€ ๊ตฌ์กฐ์ฒด(์˜ˆ: Op )์˜ ๊ฒฝ์šฐ ์ถ”๋ก ๋œ impl์€ https://github.com/rust-lang/rust/issues/38356#issuecomment -383693017์— ์ง€์ •๋œ ๊ฒƒ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
impls๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•— ์ •๋ง ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค! ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด https://github.com/rust-lang/rust/pull/50453 ์„ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.

@alexcrichton Term::as_str ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—„๊ฒฉํ•œ ๋ฒ”์œ„๋กœ ์ธํ•ด &'a Term -> &'a str ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋œ ๋‚ด๋ถ€ ์ง์›์—๊ฒŒ 'a ๋ฅผ ๋นŒ๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ๋น„๊ณต์‹ ์ฆ๊ฑฐ๋ฅผ ์Šค์ผ€์น˜ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

AFAICT, Term::as_str ์€ ๊ฑด์ „ ํ•˜์ง€๋งŒ 'a ์กฐ๊ฑด ๋งŒ ๊ฐ€์ • ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด thread_local! ์˜ํ•ด ์ง€์ง€๋˜๋Š” ์ด์œ ๋Š” Term ๊ฐ’์„ ์ด์Šค์ผ€์ดํ”„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋งค์šฐ ๋‹จ๊ธฐ์ ์ธ 'a s๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Term::as_str ์„ฑ๊ณต, ๋‚ด๋ถ€ ๋ฒ”์œ„๋ณด๋‹ค ์—„๊ฒฉํ•˜๊ฒŒ ์งง์Šต๋‹ˆ๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ proc_macro ํ™•์žฅ์ด ์ผ์–ด๋‚˜๋Š” ๋ฐฉ์‹ Term ๊ฐ€ ์Šค๋ ˆ๋“œ ๋กœ์ปฌ์ด๊ธฐ ๋•Œ๋ฌธ์— Term ๋ฅผ ํƒˆ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฑฐ์˜ ์—†์œผ๋ฉฐ thread_local! ๋ผ๊ณ  ๊ฐ€์ •

ํ•˜์ง€๋งŒ Box::leak ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค! ์—ฌ์ „ํžˆ ๋ถˆ์•ˆ์ •ํ•˜์ง€๋งŒ ์˜ค๋Š˜ Box::leak(Box::new(term)).as_str() ๋Š” &'static str ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Box::leak (cc @RalfJung)์— ์˜ํ•ด ๊นจ์ง„ ๋‹ค๋ฅธ ์ถ”์ƒํ™”๊ฐ€ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

OTOH, Term Copy ์ด๋ฏ€๋กœ ๋ฌธ์ž์—ด ๋ฐ์ดํ„ฐ๋ฅผ ์†Œ์œ  ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ์ œ๊ฑฐํ•˜๋Š” ๊ฒฝ์šฐ Copy ์— Term , ์šฐ๋ฆฌ๋Š” ๊ฒŒ์œผ๋ฅธ ์œ ์ง€ํ•  ์ˆ˜ Option<Cell<Rc<String>> ์—์žˆ๋‹ค.

@eddyb oh Term::as_str ์€ ์ œ๊ฑฐ ์˜ˆ์ •์ด๋ฉฐ ์—ฌ๊ธฐ ์•ˆ์ •ํ™”์— ํฌํ•จ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค! proc-macro2 ์ค‘๋‹จ๋˜์ง€ ์•Š๋„๋ก ๊ณ ์ •๋˜์–ด ์žˆ์ง€๋งŒ ์ผ๋‹จ ์•ˆ์ •ํ™”๋˜๋ฉด proc-macro2 ๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฆด๋ฆฌ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@eddyb ์—ฌ๊ธฐ์„œ ์ปจํ…์ŠคํŠธ๋ฅผ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ Box::leak ๋Š” ๋‚ด ๊ณต์‹ ๋ชจ๋ธ์—์„œ ์ •๋‹นํ™”๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ๊ธฐ์–ต์„ ์˜์›ํžˆ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด(์ฆ‰, ์ƒ์ž ์•ˆ์—) ํ‰์ƒ์ด ์žˆ๋‹ค๊ณ  ์™„์ „ํžˆ ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. quote! ์ด ์•ˆ์ •ํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?
  2. quote! ์— proc_macro_non_items ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๊นŒ? ์ด์ œ ์ปค๋ฐ‹ 79630d4fdfc775b241cae0a209edec2687a29f0f ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ quote! ๋Š” ์—ฌ์ „ํžˆ #[unstable(feature = "proc_macro" ... ๋ฉ๋‹ˆ๋‹ค.
  3. proc_macro_path_invoc , proc_macro_mod , proc_macro_expr ๋ฐ proc_macro_non_items ์˜ ์•ˆ์ •ํ™”๋ฅผ ์œ„ํ•ด ์ถ”์  ๋ฌธ์ œ๊ฐ€ ์ œ์ถœ๋ฉ๋‹ˆ๊นŒ?

๊ด€๋ จ ์—†๋Š” ๋ถ€์ˆ˜์ ์ธ ์งˆ๋ฌธ: quote! ๋Š” ์–ด๋””์— ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?

SOOO ์žฌ๋ฏธ์žˆ๋Š” ์ด์•ผ๊ธฐ๋ฅผ @mjbshaw : ๊ทธ๊ฒƒ์€์—์„œ ๊ตฌํ˜„ proc_macro::quote .
rustc_metadata ๋Š” proc_macro ๋ผ๋Š” ์ด๋ฆ„์˜ ์ƒ์ž์— quote ๋ผ๋Š” ์ ˆ์ฐจ ๋งคํฌ๋กœ๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ€์žฅํ•˜์ง€๋งŒ ์‚ฌ์šฉ๋œ ๊ตฌํ˜„์€ proc_macro rustc_metadata ์— ๋Œ€ํ•œ ๋งํฌ.

์•„์ง ๊ฒ€ํ† ํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์‚ฌํ•ญ๊ณผ ๋ช‡ ๊ฐ€์ง€ proc-macro API ์กฐ์ •์ด ์ง„ํ–‰ ์ค‘์ธ PR์ด ์žˆ์Šต๋‹ˆ๋‹ค.

PR ๊ฒ€ํ† : https://github.com/rust-lang/rust/pull/50473

1.2 API์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ์š”์ฒญ: ๊บพ์‡  ๊ด„ํ˜ธ( < / > )์— ๋Œ€ํ•œ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ <T> ( fn foo<T>() {} )์™€ ๊ฐ™์€ ํ•ญ๋ชฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ๋ฌธ ๋ถ„์„๋ฉ๋‹ˆ๋‹ค. Group . ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ œ๋„ค๋ฆญ๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ ๋ถ„์„์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค.

@mjbshaw ๋‘ ๊ฐœ์˜ < > ๊ฐ€ ์„œ๋กœ ๊ทธ๋ฃนํ™”๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ํ† ํฐ ์ˆ˜์ค€์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ๋งคํฌ๋กœ ์ž…๋ ฅ์—์„œ:

m!($A<$B, $C>=$D);

์ด๊ฒƒ์€ ๋‘ ๊ฐœ์˜ ๋ถ€์šธ ํ‘œํ˜„์‹ $A < $B ๋ฐ $C >= $D ์ด๊ฑฐ๋‚˜, ์˜ˆ๋ฅผ ๋“ค์–ด type $A <$B,$C> = $D; ํ™•์žฅํ•˜๋Š” ์œ ํ˜• ๋ณ„์นญ์˜ ์ œ๋„ค๋ฆญ์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

assert_both!(a<AMAX, b>=BMIN);

define_type_alias!(SwappedResult<E, T>=std::result::Result<T, E>);

OP๋ฅผ ์•ฝ๊ฐ„ ์—…๋ฐ์ดํŠธํ–ˆ์ง€๋งŒ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์œ„์ƒ๊ณผ ๊ด€๋ จ๋œ ๋‘ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ ์žˆ๋Š” ๋ฒ„๊ทธ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋”ฐ๋ฅด๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด API๋Š” @petrochenkov๊ฐ€ ์ œ์•ˆํ•œ https://github.com/rust-lang/rust/pull/50473 ์˜ ์›๋ž˜ FCP ์ฃผ์„์—์„œ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€์˜ ์š”์•ฝ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ฐ”๊พธ๊ธฐ Term::new ์— Term::ident ์ƒ๊ธฐ ์ž…๋ ฅ์„ ๊ฒ€์ฆ
  • Term::lifetime ์ถ”๊ฐ€ํ•˜๊ณ  ์ž…๋ ฅ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
  • Term::raw_ident ๋ฐ ์ž…๋ ฅ ํ™•์ธ
  • Op ์„ Punct
  • Punct::new ์— ๋Œ€ํ•œ ์ž…๋ ฅ ํ™•์ธ
  • Op::op ์„ Punct::as_char

๋‚ด๊ฐ€ ๋งŒ๋“ค ์ž‘์€ API ์š”์ฒญ(#50473 -- @petrochenkov)์€ TokenStream์— ํ† ํฐ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ˜น์‹œ:

impl Extend<TokenTree> for TokenStream

๋‚˜๋Š” ์ด๊ฒƒ์ด quote::Tokens ์œ ํ˜•(๊ธฐ๋ณธ์ ์œผ๋กœ Vec<TokenTree> )์„ ์ œ๊ฑฐํ•˜๊ณ  ์ƒํƒœ๊ณ„์—์„œ "์ผ๋ถ€ ํ† ํฐ"์„ ์˜๋ฏธํ•˜๋Š” ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ํ™•์‚ฐ์„ ์ค„์ด๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค -- https ์—์„œ ์ถ”์ 

@dtolnay์˜ ์œ„ ์ œ์•ˆ์— +1.

์œ„ ์˜ ๋ณ‘ํ•ฉ ์ฒ˜๋ฆฌ๊ฐ€ ํฌํ•จ๋œ ์ตœ์ข… ์˜๊ฒฌ ์ˆ˜๋ ด ๊ธฐ๊ฐ„์ด ์ด์ œ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค .

๋‘ ๊ฐ€์ง€ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์ด๋ฏธ ์—ฌ๊ธฐ ์—์„œ ๋ฌผ์—ˆ๋“ฏ์ด quote! ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ตœ์ข… TokenStream ๋ฅผ ๋งŒ๋“œ๋Š” ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ˆ˜๋™์œผ๋กœ ํ•ด์•ผ ํ•˜๋‚˜์š”? ์•„๋‹ˆ๋ฉด quote ์ƒ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? proc_macro::quote! ๋Š” ๋ฏธ๋ž˜์˜ ์–ด๋Š ์‹œ์ ์—์„œ ์•ˆ์ •ํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

  2. ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๋งคํฌ๋กœ์™€ ์†์„ฑ๊ณผ ๊ฐ™์€ ๋งคํฌ๋กœ๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์˜ ์ฐจ์ด๋Š” ๋‹จ์ง€ ์ธ์ˆ˜์˜ ์ˆ˜์— ๋ถˆ๊ณผํ•˜๋‹ค๋Š” ์ ์—์„œ ๋‚ด๊ฐ€ ์ดํ•ดํ•œ ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ? ์ฆ‰:

    /// Invoked as `foo!()`
    #[proc_macro]
    pub fn foo(a: TokenStream) -> TokenStream {
        // ...
    }
    
    /// Invoked as `#[bar]`
    #[proc_macro]
    pub fn bar(attr: TokenStream, item: TokenStream) -> TokenStream {
        // ...
    }
    

    ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ํ•˜๋‚˜ ํ•˜๋‚˜๋ฅผ ์ทจํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค TokenStream ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š”์ด ์†Œ์š” ์ธ์ˆ˜, ๋“ฑ. ์ด๊ฑด ์ข€ ๋ฏธ๋ฌ˜ํ•˜์ง€ ์•Š์•„? ๋Œ€์‹  #[proc_macro_attribute] ๋ฐ #[proc_macro_function_like] ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์–ด๋””์„ ๊ฐ€ ๋…ผ์˜๋œ ์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ† ๋ก ์„ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ธฐ์  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ž‘์—…ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! :)

@LukasKalbertodt ์†์„ฑ์€ ํ˜„์žฌ #[proc_macro_attribute] ์„ ์–ธ๋ฉ๋‹ˆ๋‹ค. ๊ณ ์˜์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋Š” ์˜๋„๊ฐ€ ์žˆ๋Š”์ง€ FCP ์ œ์•ˆ์„œ์˜ ์˜คํƒ€์ธ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ: ๋ฌธ์ž์—ด์—์„œ ๊ตฌ๋ฌธ ๋ถ„์„๋œ ํ† ํฐ์— Span::call_site ๋ฒ”์œ„๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. https://github.com/rust-lang/rust/issues/50050#issuecomment -390520317.

ํ˜ธ์ถœ ์‚ฌ์ดํŠธ ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ์— ๋Œ€ํ•œ ๋งคํฌ๋กœ ์—ญ์ถ”์ , ํด๋ฆฌํ”ผ ๋ฐ ์—๋””์…˜ ์œ„์ƒ์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์„ ๋ณ€๊ฒฝํ•˜๊ณ  Span::call_site ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๋„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@LukasKalbertodt proc_macro ํฌ๋ ˆ์ดํŠธ์˜ quote! ๋งคํฌ๋กœ๋Š” ์ด FCP์˜ ์ผ๋ถ€๋กœ ์•ˆ์ •ํ™”๋˜์ง€ ์•Š์•˜์ง€๋งŒ crates.io์˜ quote ํฌ๋ ˆ์ดํŠธ๋Š” ์—ฌ๊ธฐ์— ์ œ์•ˆ๋œ API๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ @abonander๊ฐ€ ์ง€์ ํ–ˆ๋“ฏ์ด ์†์„ฑ ๋งคํฌ๋กœ๋Š” #[proc_macro_attribute] ๋กœ ์„ ์–ธ๋˜๊ณ  #[proc_macro] ๋Š” foo!() ์Šคํƒ€์ผ ๋งคํฌ๋กœ ์ „์šฉ์œผ๋กœ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.

#[proc_macro_attribute] ์ด๋ฆ„์„ #[proc_attribute_macro] ๋˜๋Š” #[attribute_proc_macro] ๋ฉ๋‹ˆ๊นŒ?

@Zoxc ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ #[proc_macro_derive] ์•ˆ์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์†์„ฑ ๋งคํฌ๋กœ์— ๋Œ€ํ•ด ์ด๋ฅผ ๋”ฐ๋ฅด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ด์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š”๋ฐ›์„ ์ˆ˜ PartialEq<char> ๋ฐ PartialEq<Punct> ์— ๋Œ€ํ•ด Punct (์œ ์‚ฌ Ident ์˜ PartialEq ๊ตฌํ˜„)? ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๊ฝค ์•ˆ์ „ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” PR์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•„์ด๋””์–ด๊ฐ€ ์ค‘๋‹จ๋˜๋ฉด ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@mjbshaw PartialEq<Punct> ๋„ ์ŠคํŒฌ์„ ๋น„๊ตํ• ๊นŒ์š”? PartialEq<char> ๊ดœ์ฐฎ์•„ ๋ณด์ž…๋‹ˆ๋‹ค. OTOH.

@eddyb PartialEq ์— ๋Œ€ํ•ด Ident ๋น„๊ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ์ŠคํŒฌ (๋‚˜๋Š”์ด PROC-macro2 ์†Œ์Šค๊ฐ€ ์•„๋‹Œ PROC ๋งคํฌ๋กœ ์†Œ์Šค ์•Œ๊ณ ). ์ŠคํŒฌ์ด ๋น„๊ต์— ํฌํ•จ๋˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•ด ๋ชจํ˜ธํ•˜์ง€๋งŒ Punct ๋ฐ Ident ๊ฐ€ ์ด์™€ ๊ด€๋ จํ•˜์—ฌ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. Punct ์—๋Š” ์ž์ฒด Spacing ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๊ต ๋Œ€์ƒ์— ํฌํ•จ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ๋‹ค๋ฅด๊ฒŒ ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์Œ).

์ง€๊ธˆ์€ Punct ๋Œ€ํ•ด PartialEq<char> ๋งŒ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. PartialEq<Punct> ๋Š” ๋‚˜์ค‘์— ํ•ด์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@mjbshaw proc-macro2 ํฌ๋ ˆ์ดํŠธ๋Š” proc_macro ๊ฐ€ ์—…์ŠคํŠธ๋ฆผ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ์ •ํ™•ํžˆ ๊ฐ™์ง€ ์•Š์„ proc_macro ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ proc_macro ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๋ฌผ๋ก  ์—ญํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์ตœ์†Œํ•œ์˜ ๊ฒƒ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ณ  ์ผ๋‹จ ์•ˆ์ •๋˜๋ฉด ๊ฑฐ๊ธฐ์—์„œ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Gnome ํด๋ž˜์Šค๋Š” proc_macro2/syn/quote์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ proc ๋งคํฌ๋กœ์—์„œ ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ๋กœ ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„.

์ด ์ž‘์€ ์ƒํƒœ๊ณ„์˜ ๋ณ€ํ™”๋ฅผ ํŒŒ์•…ํ•˜๋ ค๋ฉด ์–ด๋–ค ๊ฒƒ๋“ค์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์•ผ ํ•˜๋‚˜์š”?

@federicomenaquintero ๋ถˆ์•ˆ์ •ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ตœ์‹  Nightly๋กœ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํŒจํ•  ๊ฒฝ์šฐ ์•Œ๋ ค์ฃผ๋Š” ์ผ๋ฐ˜ CI ์ž‘์—…(๋งค์ผ, ๋งค์ฃผ, ๋ฌด์—‡์ด๋“  ์ ํ•ฉํ•œ ์ž‘์—…)์„ ๊ฐ–๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. (Travis-CI๋Š” ์„ค์ •์—์„œ ์ด๋Ÿฌํ•œ "ํฌ๋ก  ์ž‘์—…" ํ™œ์„ฑํ™”๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.)

@SimonSapin ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” Cargo.toml์— ํ•ด๋‹น ์ƒ์ž์˜ ๋ฒ„์ „์„ ๊ณ ์ •ํ•˜์ง€๋งŒ ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  Cargo๊ฐ€ ์ตœ์‹  ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œํ•˜๋„๋ก ํ•ด์•ผ ํ•  ๋•Œ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๊นŒ?

@federicomenaquintero ์ด๊ฒƒ์€ ์ ์  ์ฃผ์ œ์—์„œ http://users.rust-lang.org/ ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ฐ˜์ ์ธ ๊ถŒ์žฅ ์‚ฌํ•ญ์€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ( ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋ฐ˜๋Œ€) ์†Œ์Šค ์ฝ”๋“œ์™€ ํ•จ๊ป˜ Cargo.lock ๋ฅผ ์ œ๊ณตํ•ด์•ผ ์ข…์†์„ฑ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ณ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Cargo.toml ์—์„œ foo = "1.2.3" ์™€ ๊ฐ™์€ ์ข…์†์„ฑ์„ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋˜๋ฉฐ ์ด๋Š” ์•”์‹œ์ ์œผ๋กœ "SemVer์— ๋”ฐ๋ผ ํ˜ธํ™˜๋˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฒ„์ „ ์ด์ƒ"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ, ๋งŒ๋“ค๊ณ  ์‹ถ์€ ์ƒ์ž๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ ๋ฐฉํ•ด๊ฐ€ ๋˜๋Š” ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ๋ฌธ์ œ์— ๋ด‰์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ๊ณ ๋ คํ•˜์„ธ์š”:

#[my_attribute]
struct MyStruct {
  #[other_attribute]
  field: String,
}

proc_macro ๋ฐ custom_attributes ์ด ๋ชจ๋‘ ํ•„์š”ํ•˜์ง€๋งŒ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. proc ๋งคํฌ๋กœ๋ฅผ ์•ˆ์ •ํ™”ํ•˜๋ฉด ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ๊ฒƒ์€ ์ด๋Ÿฐ ์‹์œผ๋กœ #[my_attribute] ๊ฐ€ ์ž ์žฌ์ ์œผ๋กœ #[other_attribute] ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. "์™ธ๋ถ€" ์†์„ฑ์—์„œ #[derive(Foo)] ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๋‚ด๋ถ€ ์†์„ฑ์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ๋ฉ‹์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”๋ฏธ ์„ธ์…˜์— ๋Œ€ํ•œ

์ด ํŒจ๋‹‰์„ ์•”์‹œ์ ์œผ๋กœ ๋”๋ฏธ "์„ธ์…˜"์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅ/๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๊ณต์šฉ API(์•ˆ์ •ํ™” ๊ฒฝ๋กœ ํฌํ•จ)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒ์„ฑํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋”๋ฏธ ์„ธ์…˜์„ ๊ฐ–๋Š” ๊ฒƒ์ด ๋งค์šฐ ์œ ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. proc-macro ํฌ๋ ˆ์ดํŠธ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์ ์–ด๋„ ๋งค์šฐ ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ TokenStream::from_str ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์„ธ์…˜์ด ํ•„์š”ํ•œ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@alexcrichton

๋งคํฌ๋กœ 1.2์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๋ฒ„๊ทธ์— ๋Œ€ํ•ด ์ผ๋ถ€ ๋ถ„๋ฅ˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋ฒ„๊ทธ๋Š” "์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ" ๋˜๋Š” "์ „์ฒด ๋ฒ”์œ„ ๊ด€๋ จ ๋ฒ„๊ทธ"๋กœ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/rust-lang/rust/issues/50504 ๋ฅผ "์‹ฌ๊ฐํ•œ" ์ƒํƒœ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ๋ฌธ์ œ๋Š” ๋” ๊นŠ์€ ๋ฌธ์ œ์˜ ์ฆ์ƒ์ผ ๋ฟ์ด๋ผ๊ณ  ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. proc ๋งคํฌ๋กœ์˜ ํ™•์žฅ ID๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ๋“ฑ๋ก๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์–ด๋–ค ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.
๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” PR์ด ์žˆ์ง€๋งŒ(https://github.com/rust-lang/rust/pull/51952), ์ˆ˜์ • ์‚ฌํ•ญ์—์„œ ํšŒ๊ท€๊ฐ€ ์žˆ์œผ๋ฉฐ ์•„์ง ์‚ดํŽด๋ณด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

https://github.com/rust-lang/rust/pull/52081 ์—์„œ ๋” ๋งŽ์€ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์œ„ํ•œ PR์„ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

@petrochenkov ๋Š” ๋‚˜์—๊ฒŒ

๋ฐฉ๊ธˆ proc_macro_derive ํ•˜์œ„ ์†์„ฑ ๋ฌธ์ œ ๋ฐ ์ด๋ฆ„ ์ง€์ • ์‹œ์Šคํ…œ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ฐฉ์‹ ์— ๋Œ€ํ•œ ๋งคํฌ๋กœ ์ด๋ฆ„ ์ง€์ • ์ถ”์  ๋ฌธ์ œ ์— ๋Œ€ํ•ด ๊ฒŒ์‹œ proc_macro_derive ์ž์‹ ์†์„ฑ์ด ๋ฒ”์œ„ ์ง€์ • ๋ฐ ์ด๋ฆ„ ์ง€์ •๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ฐฉ์‹์— ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์—์„œ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ์ ˆํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ์†์„ฑ์˜ ๊ฒฝ๋กœ๋Š” ํ˜„์žฌ ์•ˆ์ •ํ™” ๊ณผ์ •์— ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— #[derive(foo::Parent)] ๊ฐ€ ์ž์‹ ์†์„ฑ #[foo::Child] ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ํŒŒ์ƒ ๋งคํฌ๋กœ๋Š” ํ‘œ๋ฉด์ ์œผ๋กœ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„ ์กฐํšŒ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ž์‹ ์†์„ฑ์ด ์‹ค์ œ๋กœ ์ž์‹ ์˜ ์ž์‹์ธ์ง€ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์‰ฌ์šด ํ•ด๊ฒฐ์ฑ…์ด ์—†์ง€๋งŒ ์ƒํ˜ธ ์˜์กด์ ์ธ ์†์„ฑ์˜ ๋ฏธ๋ž˜๋ฅผ ์œ„ํ•ด ๋ ˆ์ด๋”์— ์žˆ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. proc_macro_attribute ์†์„ฑ์ด ์œ ์‚ฌํ•œ ์กฐํšŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ƒํ˜ธ ์ž‘์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•˜์ง€ ์•Š์„ ์ด์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๋‚ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ปดํŒŒ์ผํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์•„๋งˆ๋„ ์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ๋œ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๊นจ์กŒ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—๋Š” "(๋ฌธ์ œ #38356 ์ฐธ์กฐ)" ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์—ฌ๊ธฐ๊นŒ์ง€ ์˜จ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์— ์ปดํŒŒ์ผํ•˜๋Š” ๋™์•ˆ ๋ฐ›์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋‚ด Cargo.toml๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ํ”„๋กœ์ ํŠธ๊ฐ€ ํŠน์ • Rust nightly ๋ฒ„์ „(rustc 1.29.0-nightly (9bd8458c9 2018-07-09))์— ๊ณ ์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ๋งค์šฐ ๋†€๋ž์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋งˆ๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

ํ™”๋ฌผ.toml

[[bin]]
name = "main"
path = "src/bin/main.rs"

[dependencies]
log = "0.4"
pretty_env_logger = "0.2"

rand = "0.4"
ring = "=0.13.0-alpha"
untrusted = "0.6"

bytes = "0.4"
futures = "0.1"
tokio-io = "0.1"
tokio-core = "0.1"
futures-await = "0.1"

capnp = "0.8"
rusqlite = "0.13"

async_mutex = { git = "https://github.com/realcr/async_mutex", rev = "a1d973ed7" }

num-bigint = "0.2.0"
num-traits = "0.2.4"

[dev-dependencies]

[dependencies.byteorder]
version = "1.1"
features = ["i128"]

[build-dependencies]
capnpc = "0.8"

[profile.release]
debug = true

์ปดํŒŒ์ผ ์˜ค๋ฅ˜

$ cargo test
    Updating git repository `https://github.com/realcr/async_mutex`
   Compiling proc-macro2 v0.4.8                                                                                                                                                                                    
   Compiling cswitch v0.1.0 (file:///home/real/projects/d/cswitch)                                                                                                                                                 
error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)8: proc-macro2                                                                                                                        
  --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:33:40
   |
33 |     let works = panic::catch_unwind(|| proc_macro::Span::call_site()).is_ok();
   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:213:13
    |
213 |     Nightly(proc_macro::token_stream::IntoIter),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:438:11
    |
438 | impl From<proc_macro::Span> for ::Span {
    |           ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:284:13
    |
284 |     Nightly(proc_macro::SourceFile, FileName),
    |             ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:332:13
    |
332 |     Nightly(proc_macro::Span),
    |             ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:461:13
    |
461 |     Nightly(proc_macro::Ident),
    |             ^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:523:13
    |
523 |     Nightly(proc_macro::Literal),
    |             ^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:116:47
    |
116 |                     Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:117:43
    |
117 |                     Delimiter::Bracket => proc_macro::Delimiter::Bracket,
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:118:41
    |
118 |                     Delimiter::Brace => proc_macro::Delimiter::Brace,
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:119:40
    |
119 |                     Delimiter::None => proc_macro::Delimiter::None,
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:122:33
    |
122 |                 let mut group = proc_macro::Group::new(delim, tt.stream.inner.unwrap_nightly());
    |                                 ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:128:39
    |
128 |                     Spacing::Joint => proc_macro::Spacing::Joint,
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:129:39
    |
129 |                     Spacing::Alone => proc_macro::Spacing::Alone,
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:131:30
    |
131 |                 let mut op = proc_macro::Punct::new(tt.as_char(), spacing);
    |                              ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:113:17
    |
113 |         let tt: proc_macro::TokenTree = match token {
    |                 ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:238:13
    |
238 |             proc_macro::TokenTree::Group(tt) => {
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:240:21
    |
240 |                     proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:241:21
    |
241 |                     proc_macro::Delimiter::Bracket => Delimiter::Bracket,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:242:21
    |
242 |                     proc_macro::Delimiter::Brace => Delimiter::Brace,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:243:21
    |
243 |                     proc_macro::Delimiter::None => Delimiter::None,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:250:13
    |
250 |             proc_macro::TokenTree::Punct(tt) => {
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:252:21
    |
252 |                     proc_macro::Spacing::Joint => Spacing::Joint,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:253:21
    |
253 |                     proc_macro::Spacing::Alone => Spacing::Alone,
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:259:13
    |
259 |             proc_macro::TokenTree::Ident(s) => ::Ident::_new(Ident::Nightly(s)).into(),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:260:13
    |
260 |             proc_macro::TokenTree::Literal(l) => ::Literal::_new(Literal::Nightly(l)).into(),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:289:20
    |
289 |     fn nightly(sf: proc_macro::SourceFile) -> Self {
    |                    ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:339:27
    |
339 |             Span::Nightly(proc_macro::Span::call_site())
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:347:27
    |
347 |             Span::Nightly(proc_macro::Span::def_site())
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:369:30
    |
369 |     pub fn unstable(self) -> proc_macro::Span {
    |                              ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:430:32
    |
430 |     fn unwrap_nightly(self) -> proc_macro::Span {
    |                                ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:439:24
    |
439 |     fn from(proc_span: proc_macro::Span) -> ::Span {
    |                        ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:468:48
    |
468 |             Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new(string, s)),
    |                                                ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:475:48
    |
475 |             Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new_raw(string, s)),
    |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:495:32
    |
495 |     fn unwrap_nightly(self) -> proc_macro::Ident {
    |                                ^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:583:30
    |
583 |             Literal::Nightly(proc_macro::Literal::f32_unsuffixed(f))
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:591:30
    |
591 |             Literal::Nightly(proc_macro::Literal::f64_unsuffixed(f))
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:599:30
    |
599 |             Literal::Nightly(proc_macro::Literal::string(t))
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:607:30
    |
607 |             Literal::Nightly(proc_macro::Literal::character(t))
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:615:30
    |
615 |             Literal::Nightly(proc_macro::Literal::byte_string(bytes))
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:636:32
    |
636 |     fn unwrap_nightly(self) -> proc_macro::Literal {
    |                                ^^^^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/lib.rs:322:30
    |
322 |     pub fn unstable(self) -> proc_macro::Span {
    |                              ^^^^^^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:531:34
    |
531 |                   Literal::Nightly(proc_macro::Literal::$name(n))
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
...
552 | /     suffixed_numbers! {
553 | |         u8_suffixed => u8,
554 | |         u16_suffixed => u16,
555 | |         u32_suffixed => u32,
...   |
565 | |         f64_suffixed => f64,
566 | |     }
    | |_____- in this macro invocation
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:543:34
    |
543 |                   Literal::Nightly(proc_macro::Literal::$name(n))
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
...
568 | /     unsuffixed_integers! {
569 | |         u8_unsuffixed => u8,
570 | |         u16_unsuffixed => u16,
571 | |         u32_unsuffixed => u32,
...   |
578 | |         isize_unsuffixed => isize,
579 | |     }
    | |_____- in this macro invocation
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
  --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:45:34
   |
45 |             TokenStream::Nightly(proc_macro::TokenStream::new())
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
  --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:53:46
   |
53 |             TokenStream::Nightly(tts) => tts.is_empty(),
   |                                              ^^^^^^^^
   |
   = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:123:23
    |
123 |                 group.set_span(span.inner.unwrap_nightly());
    |                       ^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:132:20
    |
132 |                 op.set_span(tt.span().inner.unwrap_nightly());
    |                    ^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:239:38
    |
239 |                 let delim = match tt.delimiter() {
    |                                      ^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:245:74
    |
245 |                 let stream = ::TokenStream::_new(TokenStream::Nightly(tt.stream()));
    |                                                                          ^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:247:58
    |
247 |                 g.set_span(::Span::_new(Span::Nightly(tt.span())));
    |                                                          ^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:251:40
    |
251 |                 let spacing = match tt.spacing() {
    |                                        ^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:255:43
    |
255 |                 let mut o = Punct::new(tt.as_char(), spacing);
    |                                           ^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:256:58
    |
256 |                 o.set_span(::Span::_new(Span::Nightly(tt.span())));
    |                                                          ^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:290:45
    |
290 |         let filename = stable::file_name(sf.path().to_string());
    |                                             ^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:304:44
    |
304 |             SourceFile::Nightly(a, _) => a.is_real(),
    |                                            ^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:355:69
    |
355 |             (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.resolved_at(b)),
    |                                                                     ^^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:363:69
    |
363 |             (Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.located_at(b)),
    |                                                                     ^^^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:424:55
    |
424 |             (Span::Nightly(a), Span::Nightly(b)) => a.eq(b),
    |                                                       ^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:482:50
    |
482 |             Ident::Nightly(t) => Span::Nightly(t.span()),
    |                                                  ^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:489:56
    |
489 |             (Ident::Nightly(t), Span::Nightly(s)) => t.set_span(s),
    |                                                        ^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:623:56
    |
623 |             Literal::Nightly(lit) => Span::Nightly(lit.span()),
    |                                                        ^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error[E0658]: use of unstable library feature 'proc_macro' (see issue #38356)
   --> /home/real/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.8/src/unstable.rs:630:62
    |
630 |             (Literal::Nightly(lit), Span::Nightly(s)) => lit.set_span(s),
    |                                                              ^^^^^^^^
    |
    = help: add #![feature(proc_macro)] to the crate attributes to enable

error: aborting due to 63 previous errors

For more information about this error, try `rustc --explain E0658`.
error: Could not compile `proc-macro2`. 

๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์–ด๋–ป๊ฒŒ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”!

proc-macro2 ํฌ๋ ˆ์ดํŠธ์˜ ๊ฒฝ์šฐ @realcr cargo update ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ

@alexcrichton ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @realcr์ด ์ด๋ฏธ proc-macro2 ์—…๋ฐ์ดํŠธํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ชจ๋“  ๊ณณ์—์„œ proc-macro2-0.4.8 ๋ผ๊ณ  ํ‘œ์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์•ผ๊ฐ„ ๋ฒ„์ „์ด #52081์„ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ๋ฒ„์ „์œผ๋กœ ๊ณ ์ •๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์˜ค๋Š˜ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ  ์™œ proc-macro2 ๊ฐ€ ๋ถ€ ๋ฒ„์ „๋งŒ ๋ถ€๋”ช์ณค๋Š”์ง€ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ proc-macro2 ๊ฐ€ ํ˜ธํ™˜์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ์ž˜ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

@realcr ์•ผ๊ฐ„ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ proc-macro-2 ๋ฒ„์ „ < 0.4.8 ์„ ์ ์šฉํ•˜์‹ญ์‹œ์˜ค.

@alexcrichton , @LukasKalbertodt : ๋น ๋ฅธ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๋ฐฉ๊ธˆ ์•ผ๊ฐ„ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. proc-macro-2 ๋ฌธ์ œ๋ฅผ ์ œ๊ฑฐํ–ˆ์ง€๋งŒ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋งŽ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ:

error[E0277]: the trait bound `impl futures::Future: std::future::Future` is not satisfied
   --> src/networker/messenger/handler/handle_neighbor.rs:191:25
    |
191 |         let signature = await!(self.security_module_client.request_signature(failure_signature_buffer))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `impl futures::Future`
    |
    = note: required by `std::future::poll_in_task_cx`
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

...

error[E0627]: yield statement outside of generator literal
   --> src/networker/messenger/handler/handle_neighbor.rs:403:13
    |
403 | /             await!(self.reply_with_failure(remote_public_key.clone(), 
404 | |                                            channel_index,
405 | |                                            request_send_msg.clone()))?
    | |_____________________________________________________________________^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด ํ˜„์žฌ ๋ฒ„์ „์˜ rustc:

rustc 1.29.0-nightly (1ecf6929d 2018-07-16)

๋ฌธ์ œ์˜ ์›์ธ์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด futures_await ์—์„œ ๊ธฐ๋ณธ ์˜ˆ์ œ๋ฅผ ์ปดํŒŒ์ผํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ž‘๋™์„ ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฑฐ๊ธฐ์— ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@LukasKalbertodt https://github.com/alexcrichton/proc-macro2#unstable -features

๋ถˆ์•ˆ์ •ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@realcr ๊ท€ํ•˜์˜ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ ๋ฌธ์ œ๋Š” ์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ณ„์†ํ•ด์„œ ์ฃผ์ œ๋ฅผ

@TeXitoi : ๊ด€๋ จ์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋ฉด ์ž์œ ๋กญ๊ฒŒ ํŽธ์ง‘ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค. ๋‚˜๋Š” ๋‹น์‹ ์„ ๋•๊ธฐ ์œ„ํ•ด ์ตœ์„ ์„ ๋‹คํ•˜์ง€๋งŒ ์ฃผ์ œ์— ๋ฌด์—‡์ด ์žˆ๊ณ  ๋ฌด์—‡์ด ๊ทธ๋ ‡์ง€ ์•Š์€์ง€ ์•Œ๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. "(๋ฌธ์ œ #38356 ์ฐธ์กฐ)" ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ์ €๋ฅผ ์—ฌ๊ธฐ๋กœ ๋ฐ๋ ค์˜จ ์ด์œ ์ž…๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ ๋ฒ„์ „์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ

#![no_std]
#![feature(proc_macro)]
#![feature(proc_macro_gen)]
#![feature(custom_attribute)]
#![feature(alloc)]

#[macro_use(eth_abi)]
extern crate pwasm_abi_derive;

#![feature(proc_macro)] ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜์ง€๋งŒ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค!

error[E0658]: attribute procedural macros are experimental (see issue #38356)
  --> src\lib.rs:67:5
   |
8  | #[macro_use(eth_abi)]
   |             ------- procedural macro imported here
...
67 |     #[eth_abi(TokenEndpoint, TokenClient)]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: add #![feature(proc_macro)] to the crate attributes to enable

@Pzixel #![feature(proc_macro)] ๋ฅผ #![feature(use_extern_macros)] ๋กœ ์ „ํ™˜ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ์ตœ์‹  ์•ผ๊ฐ„ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค)

@alexcrichton ๋„ค, ๊ธฐ์‚ฌ ๋•๋ถ„์— ๋ฐฉ๊ธˆ ์•Œ์•„๋ƒˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

error[E0433]: failed to resolve. Use of undeclared type or module `Vec`
  --> src\lib.rs:66:5
   |
66 |     #[eth_abi(TokenEndpoint, TokenClient)]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `Vec`

error[E0412]: cannot find type `Vec` in this scope
  --> src\lib.rs:66:5
   |
66 |     #[eth_abi(TokenEndpoint, TokenClient)]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

๋งคํฌ๋กœ์— ๋Œ€ํ•œ ๊ฐ€์ ธ์˜ค๊ธฐ ๊ทœ์น™๋„ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์™œ ์—ฌ๊ธฐ์—์„œ ๋ถˆํ‰์„ ์‹œ์ž‘ํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ ˆ์ฐจ ๋งคํฌ๋กœ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ฒ„๊ทธ์ผ ์ˆ˜ ์žˆ๋Š” @Pzixel , ์ด์— ๋Œ€ํ•œ ์ „์šฉ ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ธ€์Ž„, ๋‚˜๋Š” ์ ์–ด๋„ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ๋‚ด ์ฝ”๋“œ๋ฅผ ๋จผ์ € ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. :) ์ง€๊ธˆ์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์€ ์ด ๊ธฐ๋Šฅ์œผ๋กœ ๋งŽ์€ ๊ฒƒ์„ ๋ฐ”๊ฟจ์Šต๋‹ˆ๋‹ค. ์™„๋ฃŒ๋˜๋ฉด BRB. ์‚ฌ๋ผ์ง€์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

@alexcrichton
ํ† ํฐ์ด ์ ˆ์ฐจ ๋งคํฌ๋กœ์— ์ „๋‹ฌ๋˜๊ธฐ ์ „์— ํ† ํฐ์— ์–ด๋–ค "์‚ฌ์ „ ์ฒ˜๋ฆฌ"๊ฐ€ ์ ์šฉ๋˜๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
ํŒŒ์ƒ ์ƒํ’ˆ์—๋Š” ์ž…๋ ฅ ํ† ํฐ์„ ๋ฐ›๊ธฐ ์ „์— $crate ์ œ๊ฑฐ๋˜๊ณ  cfg ํ™•์žฅ๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๋˜ํ•œ ๋ฌธ์ž์—ด์„ ํ†ตํ•œ ์™•๋ณต์€ ์™„์ „ํžˆ ๋ฌด์†์‹ค์€ ์•„๋‹ˆ์ง€๋งŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Œ).

์ƒˆ๋กœ ์•ˆ์ •ํ™”๋œ ์ ˆ์ฐจ ๋งคํฌ๋กœ์—์„œ ์ด๋Ÿฌํ•œ ์ผ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ์ž…๋ ฅ ํ† ํฐ์„ ๋ฐ›๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๋ชจ๋“ˆ๋กœ ๋ฒ„๊ทธ).

@alexcrichton ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. cargo expand ๋Š” ์–ด๋–ค ์ด์œ ๋กœ ์ด ์ƒ์ž์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๋‚ด ์ชฝ์ธ์ง€ ์ปดํŒŒ์ผ๋Ÿฌ ์ชฝ์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ์ด ๊ฐ€๋Šฅ์„ฑ์ด ์™„์ „ํžˆ ๋ฐฐ์ œ๋˜์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ๊ณ„์† ๋‚˜ ์ž์‹ ์„ ํƒ“ํ•  ๊ฒƒ์ด๋‹ค.

@petrochenkov proc-macros์˜ ํ™•์žฅ์€ ํ˜„์žฌ๊นŒ์ง€ ๊ฝค ์ž˜ ๊ฒ€์ฆ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ด๋ฆ„ ํ™•์ธ ๋ถ€๋ถ„๋ณด๋‹ค ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ํ›จ์”ฌ ๋œ ๊ฑฑ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ „์ฒ˜๋ฆฌ์— ๋Œ€ํ•ด ๊ฐœ์ธ์ ์œผ๋กœ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ํŒŒ์ƒ ์ƒํ’ˆ์ด ๋งˆ์ง€๋ง‰์œผ๋กœ ์‹คํ–‰๋˜๊ณ  cfgs๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋Œ€๋ถ€๋ถ„ ๋ฐ˜๋ณต์ ์ธ ํ™•์žฅ ์ˆœ์„œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋Š” ์ ์—๋Š” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค!

์–ด์ฉŒ๋ฉด ๋‚ด๊ฐ€ ๋ช…๋ฐฑํ•œ ๊ฒƒ์„ ๋†“์ณค์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ ํ™•์žฅ์—์„œ proc_macro๋ฅผ ์ •์˜ํ•˜๋Š” ํฌ๋ ˆ์ดํŠธ์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ์˜ ๋ฐฉ๋ฒ•์€ ์—†๋‚˜์š”? (๋˜๋Š” proc_macro ํฌ๋ ˆ์ดํŠธ, FWIW์—์„œ ์•Œ๋ ค์ง„ ๋‹ค๋ฅธ ํฌ๋ ˆ์ดํŠธ)

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ์ด ์žˆ์ง€๋งŒ AFAIU๋Š” ์ ˆ์ฐจ ๋งคํฌ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํฌ๋ ˆ์ดํŠธ ์ด๋ฆ„์„ ๋ฐ”๊พธ๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@Ekleog proc-macro ํฌ๋ ˆ์ดํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํฌ๋ ˆ์ดํŠธ๋ฅผ ๊ตฌ์ถ• ํ•  ๋ชฉ์ ์œผ๋กœ๋งŒ ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„ ์ข…์†์„ฑ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ „์ฒด proc-macro ํฌ๋ ˆ์ดํŠธ๋ฅผ "์ผ๋ฐ˜" ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹Œ ์ผ์ข…์˜ ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํŠนํžˆ ํฌ๋กœ์Šค ์ปดํŒŒ์ผํ•  ๋•Œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ proc-๋งคํฌ๋กœ๋Š” ๋Œ€์ƒ ํ”Œ๋žซํผ์ด ์•„๋‹Œ ํ˜ธ์ŠคํŠธ ํ”Œ๋žซํผ์šฉ์œผ๋กœ ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.

@SimonSapin ๋‚˜๋Š” ๋‹น์‹ ์—๊ฒŒ ๋™์˜ํ•˜์ง€๋งŒ proc-macro ํฌ๋ ˆ์ดํŠธ๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ ํฌ๋ ˆ์ดํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์— ์ž‘์—…์˜ ์ผ๋ถ€๋ฅผ ์œ„์ž„ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์œ„์˜ ๋งํฌ์—์„œ X-derive crate๋Š” X ํฌ๋ ˆ์ดํŠธ์˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ์‹œ์ € ๋งคํฌ๋กœ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์ž์ฒด ํฌํ•จ๋˜๊ฑฐ๋‚˜ ํ˜ธ์ถœ ์‚ฌ์ดํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์ •ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ, ๋‚˜๋Š” Rustc๊ฐ€ ์•„์ง ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๊ฐ„ ๋กœ๋“œ๋งต). ํ•˜์ง€๋งŒ ํ˜„์žฌ TokenStreams ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•ˆ์ •ํ™”๋˜๋ฉด ๋‚˜์ค‘์— ์ด ๊ธฐ๋Šฅ์„ ๊ฐœ์กฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. PathToBeResolvedFromTopOfGeneratingProcMacroCrate ํ† ํฐ ์œ ํ˜•๊ณผ ๊ฐ™์€ ๊ฒƒ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? (๋‚˜์ค‘์— ์ถ”๊ฐ€๋˜๋ฉด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. afaiu)

๊ฒฐ๊ตญ์—๋Š” ์ƒํ™ฉ์„ ๋” ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด๋Š” ์ƒ๋‹นํžˆ ๋จผ ์ด์•ผ๊ธฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋™์•ˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๋ผ๋ฉด ์ ˆ์ฐจ์  ๋งคํฌ๋กœ์šฉ foo-proc-macros ๋˜๋Š” foo-derive ํฌ๋ ˆ์ดํŠธ์™€ ๋Ÿฐํƒ€์ž„์ด ํฌํ•จ๋œ "์ผ๋ฐ˜" foo ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ ˆ์ฐจ์  ๋งคํฌ๋กœ๋ฅผ ๋‹ค์‹œ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž ๋Œ€๋ฉด API๋ฅผ ๋‹จ์ผ ์ƒ์ž์— ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ serde ๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค(์ผ๋ถ€ ๊ตฌ์„ฑ์—์„œ) https://github.com/serde-rs/serde/blob/v1.0.71/serde/src/lib.rs#L304

์ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์—ฌ์ „ํžˆ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฃจํŠธ ์ƒ์ž์˜ ์ด๋ฆ„์„ ๋ฐ”๊พธ๋Š” ๋ฌธ์ œ(์˜ˆ: serde์˜ ์ถ”์  ๋ฌธ์ œ )๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ์ ์„ ์ง€์ ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@Ekleog , TokenStream ๋Š” TokenTree ์˜ ์ŠคํŠธ๋ฆผ์ด๊ณ  ๊ฐ TokenTree ์—๋Š” ๋ฒ”์œ„ ์ง€์ • ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๋Š” Span ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ "ํ˜ธ์ถœ ์‚ฌ์ดํŠธ"(๋˜๋Š” ๋น„์–ด ์žˆ์Œ) ์ด์™ธ์˜ ๋‹ค๋ฅธ ๋ฒ”์œ„์— ๋Œ€ํ•ด Span์„ ์ƒ์„ฑํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ . ๊ธฐ๋ณธ์ ์œผ๋กœ ํŠน์ • ํฌ๋ ˆ์ดํŠธ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ Span ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•ฉ๋ฆฌ์ ์ธ ์ธ์ฒด๊ณตํ•™์  ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ฌป๋Š” ์ด์œ ๋Š” ํ™•์ธ๋ž€์ด ์„ ํƒ๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ฒดํฌํ•ด์ œํ•ด์ฃผ์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”!

#![feature(proc_macro)] ์•ˆ์ •ํ™”๋˜๋ฉด ์ด ๋ฌธ์ œ์— ๋ฌด์—‡์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๊นŒ?

@jan-hudec ์˜ค, ์ดˆ๊ธฐ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ด ์—ญํ• ์„ ํ•˜๋Š” Hygiene (๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ์ด๋ฆ„) ๊ตฌ์กฐ์ฒด๋ฅผ ์–ธ๊ธ‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Span ๋Š” ์˜ค๋ฅ˜ ๋ณด๊ณ ์šฉ์ผ ๋ฟ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ๋“ค์ด ์‚ฌ๋ผ์กŒ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ณ  ๋ถ„๋ช…ํžˆ ํ‹€๋ ธ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”! :)

#![feature(proc_macro)]๊ฐ€ ์•ˆ์ •ํ™”๋˜๋ฉด์„œ ์ด ๋ฌธ์ œ์— ๋ฌด์—‡์ด ๋‚จ์•˜์Šต๋‹ˆ๊นŒ?

์ด์ƒ์ ์œผ๋กœ๋Š” ์•ˆ์ •ํ™”๋œ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ๋‚˜๋จธ์ง€ ๋ชจ๋“  ๊ฐœ๋ณ„ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•ด์•ผ ํ•˜๋ฉฐ ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ๋ฌธ์ œ๋ฅผ ๋‹ซ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(https://github.com/rust-lang/rust/issues/์—์„œ์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ). 44660).

์˜ค, ์ดˆ๊ธฐ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ด ์—ญํ• ์„ ํ•˜๋Š” Hygiene(๋˜๋Š” ์œ ์‚ฌํ•œ ์ด๋ฆ„์˜) ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Spans๋Š” ์˜ค๋ฅ˜ ๋ณด๊ณ ๋งŒ์„ ์œ„ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ๋“ค์ด ์‚ฌ๋ผ์กŒ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๊ณ  ๋ถ„๋ช…ํžˆ ํ‹€๋ ธ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”! :)

IIUC, Span์€ ์œ„์ƒ ์ปจํ…์ŠคํŠธ๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

@mark-im ์ผ์ข…์˜. ์—ฌ๊ธฐ์—๋Š” ์†Œ์Šค ์ฝ”๋“œ ์œ„์น˜ ์ •๋ณด(์‚ฌ์šฉ์ž ๋Œ€๋ฉด ๋ฉ”์‹œ์ง€/์ง„๋‹จ์šฉ)์™€ ๊ตฌ๋ฌธ ์ปจํ…์ŠคํŠธ(์ฆ‰, ์œ„์ƒ ์ •๋ณด)๊ฐ€ ๋ชจ๋‘ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ† ๋ก /ํŠธ๋ž˜ํ”ฝ์˜ ์–‘์„ ๊ฐ์•ˆํ•  ๋•Œ proc_macro_diagnostic ์„ ์ž์ฒด ์ถ”์  ๋ฌธ์ œ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋˜ํ•œ ๊ทธ ๊ธฐ๋Šฅ์˜ ์•ˆ์ •ํ™”๋ฅผ ์œ„ํ•œ ์ฐจ๋‹จ๊ธฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋””์ ค์€ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ณ , ์ง€๊ธˆ๊นŒ์ง€ ํ›Œ๋ฅญํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ˆ์ •ํŒ์— ์ด ๊ธฐ๋Šฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ compile_error! ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” syn์˜ ์ตœ์‹  ๋ฒ„์ „๊ณผ ๊ฐ™์€ ํŽ‘ํ‚คํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@sgrif ๋‚˜๋Š” ๊ทธ๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค: https://github.com/rust-lang/rust/issues/54140.

๊ทธ๋ž˜์„œ ์ €๋Š” Span ๋ฐ LineColumn ๊ตฌ์กฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์•ˆ์ •ํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์˜๊ฒฌ์—์„œ ๋ฏธํ•ด๊ฒฐ ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ดˆ๋ณด์ž์—๊ฒŒ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํŠน์ • ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +1:

proc_macro_gen ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ๋Š” ์—ฌ๊ธฐ๋ฅผ ์ง€์ ํ–ˆ์ง€๋งŒ ์ƒ๋‹จ์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ์—๋Š” ๋‹ค๋ฅธ ๋งคํฌ๋กœ ์ •์˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” (proc_) ๋งคํฌ๋กœ๋ฅผ ๋ถ„๋ช…ํžˆ ์ฐธ์กฐํ•˜๋Š” ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์„ค๋ช…๋˜์—ˆ์Šต๋‹ˆ๊นŒ(rustc์˜ ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ ์ œ์™ธ)?

@jjpe ์•„๋งˆ๋„ ํ˜„์žฌ๋กœ์„œ๋Š” ํ•ด๋‹น ๊ธฐ๋Šฅ ๊ฒŒ์ดํŠธ์— ๋Œ€ํ•œ ์ „์šฉ ์ถ”์  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ๋Œ€๋ถ€๋ถ„ ์•ˆ์ •ํ™”์˜ ์ดˆ๊ธฐ ๋ฌผ๊ฒฐ์— ์ „๋…ํ–ˆ์Šต๋‹ˆ๋‹ค.

@alexcrichton ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์™„๋ฒฝํ•˜๊ฒŒ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. proc_macro_gen ๊ธฐ๋Šฅ์„ ๋ณด๋Š” ๊ณผ์ •์—์„œ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๋งŒํผ ์ข‹์€ ๊ฒƒ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋‚˜๋ฅผ ์—ฌ๊ธฐ๋กœ ์ถ”์ฒœํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์•ฝ๊ฐ„ ์ด์ƒํ•˜๋ฏ€๋กœ ์ ์–ด๋„ ์–ธ๊ธ‰ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

@xieyuheng CodeString / Code ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์„๊นŒ ์š”? ์ฆ‰, ์˜๋ฏธ ์ฒด๊ณ„๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?
TokenStream ๋Š” ๊ท€์ฐฎ์€ ํ…์ŠคํŠธ๋ผ๊ธฐ๋ณด๋‹ค ์ผ๋ จ์˜ ํ† ํฐ ๊ฐ’์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๊ทธ๋Œ€๋กœ ์†Œ์Šค ์ฝ”๋“œ์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

TokenStream ( TokenTree )์— ๋Œ€ํ•œ ํ™•์žฅ API๋Š” 1.29์—์„œ ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ํ˜• proc ๋งคํฌ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” 1.30์—์„œ ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค.

rustc 1.30.0-nightly (63d51e89a 2018-09-28) ์ดํ›„๋กœ ๋” ์ด์ƒ ๋ณ„๋„์˜ ํŒŒ์ผ์—์„œ ๋ชจ๋“ˆ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. mod module; ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉด mod module; , WYSIWYG๋ฅผ ํฌํ•จํ•˜๋Š” TokenStream ๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ์™€์˜ ๋ฒ”์œ„, ์œ„์ƒ ๋ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ํŒŒ์ผ์— ์žˆ๋Š” ๋ชจ๋“ˆ์˜ ๋‚ด์šฉ์œผ๋กœ ์ž‘์—…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ฑฐ๋‚˜ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ๋ชจ๋“ˆ ๊ตฌ์„ฑ์˜ ์‚ฌ์†Œํ•œ ๋ฆฌํŒฉํ† ๋ง์œผ๋กœ ์ธํ•ด ๋งคํฌ๋กœ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์ตœ์ข… ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด ๊ธฐ๋Šฅ์ด ์—†์œผ๋ฉด ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์•„, ์ด ๋ฌธ์ œ๋Š” ๋ฐฉ๋Œ€ ํ•˜๊ณ  ๋” ์ด์ƒ ์—ด๋ ค ์žˆ๊ณ  API๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ์œ ์šฉํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ง€์ ์— ์ด๋ฅด๋ €์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด https://github.com/rust-lang/rust/pull/54728 ์„ ์—ด์–ด ์ด ๋ฌธ์ œ๋ฅผ ๋ณด๋‹ค ์„ธ๋ถ„ํ™”๋œ ์—ฌ๋Ÿฌ ์ถ”์  ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค.

์ด ์‹œ์ ์—์„œ ๋‚˜๋Š” ์ด๊ฒƒ์„ ๋‹ซ์„ ๊ฒƒ์ด์ง€๋งŒ ๋‹ค๋ฅธ ์ถ”์  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์žŠ์€ ๊ฒฝ์šฐ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค! ๋‚˜๋Š” ํ™•์‹คํžˆ ๋” ๋งŽ์€ ํ›„์† ์กฐ์น˜๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

@alexcrichton ์†์„ฑ๊ณผ ๊ฐ™์€ ๋งคํฌ๋กœ์˜ ํ•˜์œ„ ์†์„ฑ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?
https://github.com/rust-lang/rust/issues/38356#issuecomment -397095541
์ด์— ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@๋”๋ธ” ์—‘์Šค
์ด๋Ÿฌํ•œ ํ•˜์œ„ ์†์„ฑ์ด ๋ฐ˜๋“œ์‹œ ์–ธ์–ด ๊ธฐ๋Šฅ์ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๊นŒ?
derive ์˜ ๊ฒฝ์šฐ ํŒŒ์ƒ ๋งคํฌ๋กœ๊ฐ€ ์ž…๋ ฅ์—์„œ ์†์„ฑ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ ๋“ฑ๋ก์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(์ž…๋ ฅ์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ).
์†์„ฑ ๋งคํฌ๋กœ๋Š” ์ž…๋ ฅ์—์„œ #[other_attribute] ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด๋ฆ„ ํ™•์ธ์— ๋„๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉฐ "ํ™•์ธ๋˜์ง€ ์•Š์€ ์†์„ฑ" ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

(https://github.com/rust-lang/rust/issues/38356#issuecomment-397095541์— ์–ธ๊ธ‰๋œ ๊ณ ์ „์ ์ธ ๋ ˆ๊ฑฐ์‹œ ๋ถˆ์•ˆ์ •ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ์€ ์ด์ œ proc ๋งคํฌ๋กœ์™€ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.)

@petrochenkov ์˜ˆ, ์„ค๋ช…ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰