rust/zerocopy-derive/derive/try_from_bytes.rs

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

File Facts

System
Linux kernel
Corpus path
rust/zerocopy-derive/derive/try_from_bytes.rs
Extension
.rs
Size
32341 bytes
Lines
766
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

let (outer_tag_type, inner_tag_type) = if repr.is_c() {
        (quote! { ___ZerocopyTag }, quote! { () })
    } else if repr.is_primitive() {
        (quote! { () }, quote! { ___ZerocopyTag })
    } else {
        return Err(Error::new(
            ctx.ast.span(),
            "must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout",
        ));
    };

    let variant_structs = generate_variant_structs(ctx, data);
    let variants_union = generate_variants_union(ctx, data);

    let (impl_generics, ty_generics, where_clause) = ctx.ast.generics.split_for_impl();

    let zerocopy_crate = &ctx.zerocopy_crate;
    let has_tag = ImplBlockBuilder::new(ctx, data, Trait::HasTag, FieldBounds::None)
        .inner_extras(quote! {
            type Tag = ___ZerocopyTag;
            type ProjectToTag = #zerocopy_crate::pointer::cast::CastSized;
        })
        .build();
    let has_fields = data.variants().into_iter().flat_map(|(variant, fields)| {
        let variant_ident = &variant.unwrap().ident;
        let variants_union_field_ident = variants_union_field_ident(variant_ident);
        let field: Box<syn::Type> = parse_quote!(());
        fields.into_iter().enumerate().map(move |(idx, (vis, ident, ty))| {
            // Rust does not presently support explicit visibility modifiers on
            // enum fields, but we guard against the possibility to ensure this
            // derive remains sound.
            assert!(matches!(vis, syn::Visibility::Inherited));
            let variant_struct_field_index = Index::from(idx + 1);
            let (_, ty_generics, _) = ctx.ast.generics.split_for_impl();
            let has_field_trait = Trait::HasField {
                variant_id: parse_quote!({ #zerocopy_crate::ident_id!(#variant_ident) }),
                // Since Rust does not presently support explicit visibility
                // modifiers on enum fields, any public type is suitable here;
                // we use `()`.
                field: field.clone(),
                field_id: parse_quote!({ #zerocopy_crate::ident_id!(#ident) }),
            };
            let has_field_path = has_field_trait.crate_path(ctx);
            let has_field = ImplBlockBuilder::new(
                ctx,
                data,
                has_field_trait,
                FieldBounds::None,
            )
            .inner_extras(quote! {
                type Type = #ty;

                #[inline(always)]
                fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut <Self as #has_field_path>::Type {
                    use #zerocopy_crate::pointer::cast::{CastSized, Projection};

                    slf.project::<___ZerocopyRawEnum #ty_generics, CastSized>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(variants) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::REPR_C_UNION_VARIANT_ID }, { #zerocopy_crate::ident_id!(#variants_union_field_ident) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(value) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(#variant_struct_field_index) }>>()
                        .as_ptr()
                }
            })
            .build();

            let project = ImplBlockBuilder::new(
                ctx,
                data,
                Trait::ProjectField {
                    variant_id: parse_quote!({ #zerocopy_crate::ident_id!(#variant_ident) }),
                    // Since Rust does not presently support explicit visibility
                    // modifiers on enum fields, any public type is suitable
                    // here; we use `()`.
                    field: field.clone(),
                    field_id: parse_quote!({ #zerocopy_crate::ident_id!(#ident) }),
                    invariants: parse_quote!((Aliasing, Alignment, #zerocopy_crate::invariant::Initialized)),
                },
                FieldBounds::None,
            )
            .param_extras(vec![
                parse_quote!(Aliasing: #zerocopy_crate::invariant::Aliasing),
                parse_quote!(Alignment: #zerocopy_crate::invariant::Alignment),
            ])
            .inner_extras(quote! {
                type Error = #zerocopy_crate::util::macro_util::core_reexport::convert::Infallible;
                type Invariants = (Aliasing, Alignment, #zerocopy_crate::invariant::Initialized);
            })
            .build();

Annotation

Implementation Notes