rust/zerocopy-derive/util.rs

Source file repositories/reference/linux-study-clean/rust/zerocopy-derive/util.rs

File Facts

System
Linux kernel
Corpus path
rust/zerocopy-derive/util.rs
Extension
.rs
Size
30335 bytes
Lines
846
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

if let Ok(path_lit) = lit.parse::<Ident>() {
                                    path = parse_quote!(::#path_lit);
                                    return Ok(());
                                }
                            }

                            return Err(Error::new(
                                Span::call_site(),
                                "`crate` attribute requires a path as the value",
                            ));
                        }

                        if meta.path.is_ident("on_error") {
                            on_error_span = Some(meta.path.span());
                            let value = meta.value()?;
                            let s: LitStr = value.parse()?;
                            match s.value().as_str() {
                                "skip" => skip_on_error = true,
                                "fail" => skip_on_error = false,
                                _ => return Err(Error::new(
                                    s.span(),
                                    "unrecognized value for `on_error` attribute from `zerocopy`; expected `skip` or `fail`",
                                )),
                            }
                            return Ok(());
                        }

                        Err(Error::new(
                            Span::call_site(),
                            format!(
                                "unknown attribute encountered: {}",
                                meta.path.into_token_stream()
                            ),
                        ))
                    })?;
                }
            }
        }

        Ok(Self { ast, zerocopy_crate: path, skip_on_error, on_error_span })
    }

    pub(crate) fn with_input(&self, input: &DeriveInput) -> Self {
        Self {
            ast: input.clone(),
            zerocopy_crate: self.zerocopy_crate.clone(),
            skip_on_error: self.skip_on_error,
            on_error_span: self.on_error_span,
        }
    }

    pub(crate) fn core_path(&self) -> TokenStream {
        let zerocopy_crate = &self.zerocopy_crate;
        quote!(#zerocopy_crate::util::macro_util::core_reexport)
    }

    pub(crate) fn cfg_compile_error(&self) -> TokenStream {
        // By checking both during the compilation of the proc macro *and* in
        // the generated code, we ensure that `--cfg
        // zerocopy_unstable_derive_on_error` need only be passed *either* when
        // compiling this crate *or* when compiling the user's crate. The former
        // is preferable, but in some situations (such as when cross-compiling
        // using `cargo build --target`), it doesn't get propagated to this
        // crate's build by default.
        if cfg!(zerocopy_unstable_derive_on_error) {
            quote!()
        } else if let Some(span) = self.on_error_span {
            let core = self.core_path();
            let error_message = "`on_error` is experimental; pass '--cfg zerocopy_unstable_derive_on_error' to enable";
            quote::quote_spanned! {span=>
                #[allow(unused_attributes, unexpected_cfgs)]
                const _: () = {
                    #[cfg(not(zerocopy_unstable_derive_on_error))]
                    #core::compile_error!(#error_message);
                };
            }
        } else {
            quote!()
        }
    }

    pub(crate) fn error_or_skip<E>(&self, error: E) -> Result<TokenStream, E> {
        if self.skip_on_error {
            Ok(self.cfg_compile_error())
        } else {
            Err(error)
        }
    }
}

Annotation

Implementation Notes