Rust: رفض_macro: لا تعمل الواردات في الاستدعاءات عبر الصناديق

تم إنشاؤها على ٣١ مايو ٢٠١٧  ·  3تعليقات  ·  مصدر: rust-lang/rust

الحد الأدنى من التكاثر:

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

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

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

extern crate macro_test;

use macro_test::use_fmt;

use_fmt!();

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

error: aborting due to previous error(s)

error: Could not compile `macro-test`.

استدعاء الماكرو في نفس الصندوق كما هو محدد يعمل كما هو متوقع.

MustafaHosny اللهم امين

A-macros-2.0 C-bug

التعليق الأكثر فائدة

آسف للتأخير في الوصول إلى هذا. ثابت في # 46419.

ال 3 كومينتر

آسف للتأخير في الوصول إلى هذا. ثابت في # 46419.

لا أعرف ما إذا كانت هي نفس المشكلة (وإذا تم إصلاحها من قِبل العلاقات العامة) ، لكنني أحصل على نفس الخطأ مع proc_macro .
إليك مثال بسيط لإعادة إظهار هذه المشكلة.
هل هي نفس المشكلة؟
عند تشغيل cargo build ، تظهر لي الأخطاء التالية:

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

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

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

هل هناك أي حل بديل لهذه المشكلة؟
شكرا لك.

antoyo هذا نتيجة للنظافة.

نظرًا لأن ::postgres::types::Type موجود في تعريف proc-macro ، فإنه يتم حله في نطاق تعريف الماكرو. على وجه الخصوص ، سيتم حل نفس المشكلة بغض النظر عن مكان استدعاء الماكرو.

لا يوجد extern crate postgres; في جذر صندوق proc-macro ، لذلك تحصل على خطأ في الدقة. إن مجرد إضافة extern crate postgres; إلى جذر صندوق proc-macro ليس كافيًا أيضًا ، نظرًا لأن تبعيات proc-macro يتم تجميعها لمنصة المضيف (المرحلة 0) ، وليس النظام الأساسي المستهدف (المرحلة 1) وهكذا التوسع لا يمكن رؤيتهم.

الحل هنا هو إضافة تبعيات الهدف إلى صناديق proc-macro كما هو موضح في https://github.com/rust-lang/rust/issues/45934#issuecomment -344497531.

في الوقت الحالي ، تحتاج إلى وضع extern crate postgres; في توسيع الماكرو. بسبب النظافة ، لن يتعارض هذا مع أي شيء يسمى postgres في موقع الاستدعاء ، ولن يؤثر على دقة وسيطات الماكرو ، إلخ. على سبيل المثال:

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

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

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

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

بدلاً من ذلك ، يمكنك جعل حل ::postgres::types::Type في موقع الاتصال (بشكل غير صحي) من خلال إعطائه Span::call_site() (الرموز المميزة من quote! تملك Span::def_site() افتراضيًا). قريباً ، spanned_quote!(span, tokens...) سيجعل هذا أسهل.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات