rust/macros/for_lt.rs

Source file repositories/reference/linux-study-clean/rust/macros/for_lt.rs

File Facts

System
Linux kernel
Corpus path
rust/macros/for_lt.rs
Extension
.rs
Size
7979 bytes
Lines
249
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

fn visit_lifetime_mut(&mut self, lifetime: &mut Lifetime) {
                // Expand explicit `'_`
                if lifetime.ident == "_" {
                    *lifetime = self.0.clone();
                }
            }

            fn visit_type_reference_mut(&mut self, reference: &mut syn::TypeReference) {
                syn::visit_mut::visit_type_reference_mut(self, reference);

                if reference.lifetime.is_none() {
                    reference.lifetime = Some(self.0.clone());
                }
            }
        }

        let mut ret = self.clone();
        ElidedLifetimeExpander(explicit_lt).visit_type_mut(&mut ret);
        ret
    }

    fn replace_lifetime(&self, src: &Lifetime, dst: &Lifetime) -> Type {
        struct LifetimeReplacer<'a>(&'a Lifetime, &'a Lifetime);

        impl VisitMut for LifetimeReplacer<'_> {
            fn visit_lifetime_mut(&mut self, lifetime: &mut Lifetime) {
                if lifetime.ident == self.0.ident {
                    *lifetime = self.1.clone();
                }
            }
        }

        let mut ret = self.clone();
        LifetimeReplacer(src, dst).visit_type_mut(&mut ret);
        ret
    }

    fn has_lifetime(&self, lt: &Lifetime) -> bool {
        struct HasLifetime<'a>(&'a Lifetime, bool);

        impl Visit<'_> for HasLifetime<'_> {
            fn visit_lifetime(&mut self, lifetime: &Lifetime) {
                if lifetime.ident == self.0.ident {
                    self.1 = true;
                }
            }

            // Macro invocations are opaque; conservatively assume they may
            // reference the lifetime.
            fn visit_macro(&mut self, _: &syn::Macro) {
                self.1 = true;
            }
        }

        let mut visitor = HasLifetime(lt, false);
        visitor.visit_type(self);
        visitor.1
    }
}

struct Prover<'a>(&'a Lifetime, Vec<&'a Type>);

impl<'a> Prover<'a> {
    /// Prove that `ty` is covariant over `'lt`.
    ///
    /// This also needs to prove that it'll be wellformed for any instance of `'lt`.
    /// It can be assumed that `ty` will be wellformed if `'lt` is substituted to `'static`.
    fn prove(&mut self, ty: &'a Type) {
        match ty {
            Type::Paren(ty) => self.prove(&ty.elem),
            Type::Group(ty) => self.prove(&ty.elem),

            // No lifetime involved
            Type::Never(_) => {}

            // `[T; N]` and `[T]` is covariant over `T`.
            Type::Array(ty) => self.prove(&ty.elem),
            Type::Slice(ty) => self.prove(&ty.elem),

            Type::Tuple(ty) => {
                for elem in &ty.elems {
                    self.prove(elem);
                }
            }

            // `*const T` is covariant over `T`
            Type::Ptr(ty) if ty.const_token.is_some() => self.prove(&ty.elem),

            // `&T` is covariant over `T` and lifetime.
            //

Annotation

Implementation Notes