Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddBounds::Fields doesn't seem to care about the lifecycle #60

Open
823984418 opened this issue Jul 27, 2023 · 0 comments
Open

AddBounds::Fields doesn't seem to care about the lifecycle #60

823984418 opened this issue Jul 27, 2023 · 0 comments

Comments

@823984418
Copy link

823984418 commented Jul 27, 2023

The following code

use proc_macro2::TokenStream;
use quote::quote;
use syn::parse_quote;
use synstructure::{decl_derive, AddBounds, Structure};

decl_derive!([GcTraget, attributes(unsafe_ignore_trace)] => derive_trace);

fn derive_trace(mut s: Structure<'_>) -> TokenStream {
    s.filter(|_| true);
    let body = s.each(|bi| quote!(::regc::GcTarget::trace(#bi, token);));
    s.add_impl_generic(parse_quote!('regc_lifetime));
    s.add_bounds(AddBounds::Fields);
    s.gen_impl(quote! {
        extern crate self as regc;
        gen impl<'regc_lifetime> ::regc::GcTarget<'regc_lifetime> for @Self {
            fn trace(&self, token: &mut ::regc::GcTraceToken<'regc_lifetime>) {
                match self {
                    #body
                }
            }
        }
    })
}

in

#[derive(GcTraget)]
struct A<'c, S> {
    x: GcRootThin<'c>,
    y: Option<S>,
}

generate

struct A<'c, S> {
    x: GcRootThin<'c>,
    y: Option<S>,
}
#[allow(non_upper_case_globals)]
const _DERIVE_regc_GcTarget_regc_lifetime_FOR_A: () = {
    extern crate self as regc;
    impl<'regc_lifetime, 'c, S> ::regc::GcTarget<'regc_lifetime> for A<'c, S>
    where
        Option<S>: ::regc::GcTarget<'regc_lifetime>,
    {
        fn trace(&self, token: &mut ::regc::GcTraceToken<'regc_lifetime>) {
            match self {
                A { x: ref __binding_0, y: ref __binding_1 } => {
                    {
                        ::regc::GcTarget::trace(__binding_0, token);
                    }
                    {
                        ::regc::GcTarget::trace(__binding_1, token);
                    }
                }
            }
        }
    }
};

Missing

GcRootThin<'c>: ...

This resulted in an implementation for any lifecycle, resulting in an error:

error: lifetime may not live long enough
   --> src\lib.rs:812:10
    |
812 | #[derive(GcTraget)]
    |          ^^^^^^^^
    |          |
    |          lifetime `'regc_lifetime` defined here
    |          argument requires that `'regc_lifetime` must outlive `'c`
813 | struct A<'c, S> {
    |          -- lifetime `'c` defined here
    |
    = help: consider adding the following bound: `'regc_lifetime: 'c`
    = note: requirement occurs because of a mutable reference to `GcTraceToken<'_>`
    = note: mutable references are invariant over their type parameter
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
    = note: this error originates in the derive macro `GcTraget` (in Nightly builds, run with -Z macro-backtrace for more info)

Error disappears after adding where GcRoot.

What I mean is, in add_trait_bounds In the implementation of boundaries', there seems to be a lack of consideration for the lifecycle,but they are also part of the type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant