Skip to main content

pin_init_internal/
pin_data.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use std::collections::{BTreeMap, BTreeSet};
4
5use proc_macro2::{Span, TokenStream};
6use quote::{format_ident, quote, quote_spanned, ToTokens};
7use syn::{
8    parse::{End, Nothing, Parse, ParseStream},
9    parse_quote, parse_quote_spanned,
10    punctuated::Punctuated,
11    spanned::Spanned,
12    visit::Visit,
13    visit_mut::VisitMut,
14    Attribute, Field, Fields, GenericArgument, GenericParam, Generics, Ident, Index, Item,
15    ItemStruct, Lifetime, LifetimeParam, Member, Meta, PathArguments, PathSegment, Token, Type,
16    TypeParamBound, TypePath, WhereClause, WherePredicate,
17};
18
19use crate::{
20    diagnostics::{DiagCtxt, ErrorGuaranteed},
21    util::*,
22};
23
24pub(crate) mod kw {
25    syn::custom_keyword!(covariant);
26    syn::custom_keyword!(invariant);
27    syn::custom_keyword!(contravariant);
28    syn::custom_keyword!(PinnedDrop);
29}
30
31pub(crate) enum Args {
32    Nothing(Nothing),
33    #[allow(dead_code)]
34    PinnedDrop(kw::PinnedDrop),
35}
36
37impl Parse for Args {
38    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
39        let lh = input.lookahead1();
40        if lh.peek(End) {
41            input.parse().map(Self::Nothing)
42        } else if lh.peek(kw::PinnedDrop) {
43            input.parse().map(Self::PinnedDrop)
44        } else {
45            Err(lh.error())
46        }
47    }
48}
49
50impl ToTokens for Args {
51    fn to_tokens(&self, tokens: &mut TokenStream) {
52        match self {
53            Self::Nothing(_) => (),
54            Self::PinnedDrop(kw) => kw.to_tokens(tokens),
55        }
56    }
57}
58
59/// Description of how a field is borrowed.
60#[derive(Clone, Copy, Default, PartialEq, Eq)]
61enum BorrowedKind {
62    /// `#[borrowed]`, or implicitly inferreed.
63    #[default]
64    Shared,
65    // `#[borrowed(mut)]`.
66    Mutable,
67}
68
69impl BorrowedKind {
70    fn parse(dcx: &mut DiagCtxt, attrs: &mut Vec<Attribute>) -> Option<Self> {
71        let attr = attrs.extract_single_attr(dcx, "borrowed")?;
72
73        Some(if let Meta::Path(_) = attr.meta {
74            BorrowedKind::Shared
75        } else {
76            match attr.parse_args_with(|input: ParseStream<'_>| {
77                let _: Token![mut] = input.parse()?;
78                Ok(BorrowedKind::Mutable)
79            }) {
80                Ok(v) => v,
81                Err(err) => {
82                    // Swallow the error and recover by inferring shared.
83                    dcx.error(attr.path(), err);
84                    BorrowedKind::Shared
85                }
86            }
87        })
88    }
89}
90
91/// Information about a borrowed field.
92struct BorrowedInfo {
93    kind: BorrowedKind,
94    /// Field lifetime for this field.
95    lifetime: Lifetime,
96    // Variance of the field lifetime, as captured by other fields.
97    lt_variance: Variance,
98}
99
100#[derive(Clone, Copy, Default, PartialEq, Eq)]
101enum Variance {
102    /// `covariant` annotation, or implicitly inferred.
103    #[default]
104    Covariant,
105    // `invariant` annotation.
106    Invariant,
107}
108
109impl Parse for Variance {
110    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
111        let lh = input.lookahead1();
112        Ok(if lh.peek(kw::covariant) {
113            let _: kw::covariant = input.parse()?;
114            Variance::Covariant
115        } else if lh.peek(kw::invariant) {
116            let _: kw::invariant = input.parse()?;
117            Variance::Invariant
118        } else if lh.peek(kw::contravariant) {
119            // Field lifetimes are inherently covariant, so combining with contravariance,
120            // we would constrain it to be invariant.
121            let token: kw::contravariant = input.parse()?;
122            DiagCtxt::current(|dcx| {
123                dcx.error(
124                    token,
125                    "field lifetimes cannot be `contravariant`; use `invariant` instead",
126                )
127            });
128            Variance::Invariant
129        } else {
130            Err(lh.error())?
131        })
132    }
133}
134
135/// Information about field lifetimes captured in a type.
136struct Capture {
137    variance: Variance,
138    /// Lifetime to be captured.
139    lifetime: Lifetime,
140}
141
142impl std::borrow::Borrow<Lifetime> for Capture {
143    fn borrow(&self) -> &Lifetime {
144        &self.lifetime
145    }
146}
147
148impl PartialEq for Capture {
149    fn eq(&self, other: &Self) -> bool {
150        self.lifetime == other.lifetime
151    }
152}
153
154impl Eq for Capture {}
155
156impl PartialOrd for Capture {
157    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
158        Some(self.cmp(other))
159    }
160}
161
162impl Ord for Capture {
163    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
164        self.lifetime.cmp(&other.lifetime)
165    }
166}
167
168impl Parse for Capture {
169    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
170        let lifetime = input.parse()?;
171        let variance = if input.peek(Token![:]) {
172            let _: Token![:] = input.parse()?;
173            input.parse()?
174        } else {
175            // If variance is not explicitly specified, infer covariance by default.
176            Variance::Covariant
177        };
178        Ok(Capture { variance, lifetime })
179    }
180}
181
182impl Capture {
183    fn parse_list(
184        dcx: &mut DiagCtxt,
185        attrs: &mut Vec<Attribute>,
186        bound_lifetimes: &BTreeSet<&Lifetime>,
187        exist_lifetimes: &BTreeSet<ExistLt>,
188        field_idx_map: &BTreeMap<Ident, usize>,
189    ) -> Option<(BTreeSet<Capture>, Variance)> {
190        let attr = attrs.extract_single_attr(dcx, "uses")?;
191        let punctuated: Punctuated<Capture, Token![,]> = attr
192            .parse_args_with(Punctuated::parse_terminated)
193            .map_err(ErrorGuaranteed::from)
194            .ok()?;
195
196        // Check for misuses inside attribute.
197        let mut set = BTreeSet::new();
198        for borrow in punctuated {
199            let lt = &borrow.lifetime;
200            if set.contains(&borrow) {
201                dcx.error(lt, format!("lifetime `{lt}` is mentioned more than once"));
202                continue;
203            }
204
205            if bound_lifetimes.contains(lt) {
206                dcx.error(
207                    lt,
208                    format!("`{lt}` is a struct generics and cannot be used in `#[uses]`"),
209                );
210                continue;
211            }
212
213            if lt.ident != "_"
214                && !exist_lifetimes.contains(lt)
215                && !field_idx_map.contains_key(&lt.ident)
216            {
217                dcx.error(lt, format!("`{lt}` is not a field name"));
218                continue;
219            }
220
221            set.insert(borrow);
222        }
223
224        let wildcard = Lifetime::new("'_", Span::mixed_site());
225        let wildcard_variance = set.take(&wildcard).map(|b| b.variance).unwrap_or_default();
226        Some((set, wildcard_variance))
227    }
228}
229
230#[allow(unused)]
231struct FieldInfo {
232    field: Field,
233    member: Member,
234    pinned: bool,
235    borrowed: Option<BorrowedInfo>,
236    captures: BTreeSet<Capture>,
237    generic_lt_captures: BTreeSet<Lifetime>,
238    generic_ty_captures: BTreeSet<Ident>,
239}
240
241struct StructInfo {
242    args: Args,
243    struct_: ItemStruct,
244    fields: Vec<FieldInfo>,
245    field_idx_map: BTreeMap<Ident, usize>,
246    is_tuple_struct: bool,
247    self_referential: bool,
248    /// Existential lifetimes defined.
249    exist_lts: BTreeSet<ExistLt>,
250    /// Field lifetime genercis with outlive chain.
251    field_lts_outlive_chain: Generics,
252    /// Field lifetime genercis with outlive chain, with one chain for covariant fields and one
253    /// chain for invariant fields.
254    field_lts_split_variance_outlive_chain: Generics,
255    /// Existential lifetime with their outlives bounds.
256    exist_lts_generics: Generics,
257}
258
259pub(crate) fn expand_with_cfg(
260    args: Args,
261    input: Item,
262    dcx: &mut DiagCtxt,
263) -> Result<TokenStream, ErrorGuaranteed> {
264    let mut struct_ = match input {
265        Item::Struct(struct_) => struct_,
266        Item::Enum(enum_) => {
267            return Err(dcx.error(
268                enum_.enum_token,
269                "`#[pin_data]` only supports structs for now",
270            ));
271        }
272        Item::Union(union) => {
273            return Err(dcx.error(
274                union.union_token,
275                "`#[pin_data]` only supports structs for now",
276            ));
277        }
278        rest => {
279            return Err(dcx.error(
280                rest,
281                "`#[pin_data]` can only be applied to struct, enum and union definitions",
282            ));
283        }
284    };
285
286    // Handling cfg can gets very complicated, especially for tuple structs. Therefore, resolve all
287    // field cfgs first before continuing.
288    //
289    // We need to perform this after parsing so we can reliably detect field cfgs.
290    for (field_idx, field) in struct_.fields.iter_mut().enumerate() {
291        let cfg = field.attrs.extract_cfg_attrs();
292        if cfg.is_empty() {
293            continue;
294        }
295
296        let cfg_true_struct = quote!(#struct_);
297
298        let punctuated = match &mut struct_.fields {
299            Fields::Named(fields) => &mut fields.named,
300            Fields::Unnamed(fields) => &mut fields.unnamed,
301            Fields::Unit => unreachable!(),
302        };
303        *punctuated = std::mem::take(punctuated)
304            .into_pairs()
305            .enumerate()
306            .filter(|&(i, _)| i != field_idx)
307            .map(|(_, p)| p)
308            .collect();
309        let cfg_false_struct = quote!(#struct_);
310
311        // Resolve one field at a time until we've got no more field cfgs.
312        //
313        // This is linear time because macro invocations with false cfg will not be expanded.
314        return Ok(quote!(
315            #[cfg(all(#(#cfg,)*))]
316            #[::pin_init::pin_data(#args)]
317            #cfg_true_struct
318
319            #[cfg(not(all(#(#cfg,)*)))]
320            #[::pin_init::pin_data(#args)]
321            #cfg_false_struct
322        ));
323    }
324
325    expand(args, struct_, dcx)
326}
327
328fn expand(
329    args: Args,
330    mut struct_: ItemStruct,
331    dcx: &mut DiagCtxt,
332) -> Result<TokenStream, ErrorGuaranteed> {
333    // The generics might contain the `Self` type. Since this macro will define a new type with the
334    // same generics and bounds, this poses a problem: `Self` will refer to the new type as opposed
335    // to this struct definition. Therefore we have to replace `Self` with the concrete name.
336    let mut replacer = {
337        let name = &struct_.ident;
338        let (_, ty_generics, _) = struct_.generics.split_for_impl();
339        SelfReplacer(parse_quote!(#name #ty_generics))
340    };
341    replacer.visit_generics_mut(&mut struct_.generics);
342    replacer.visit_fields_mut(&mut struct_.fields);
343
344    let is_tuple_struct = matches!(struct_.fields, Fields::Unnamed(_));
345
346    let exist_lts = if let Some(whr) = &mut struct_.generics.where_clause {
347        ExistLt::parse(dcx, whr)
348    } else {
349        BTreeSet::new()
350    };
351
352    // Collect all bound lifetimes from generics.
353    let bound_lifetimes: BTreeSet<&Lifetime> =
354        struct_.generics.lifetimes().map(|x| &x.lifetime).collect();
355    // Collect all type parameters from generics.
356    let type_params: BTreeSet<&Ident> = struct_.generics.type_params().map(|x| &x.ident).collect();
357    // Collect all fields.
358    let field_idx_map: BTreeMap<Ident, usize> = struct_
359        .fields
360        .iter()
361        .enumerate()
362        .filter_map(|(index, field)| Some((field.ident.clone()?, index)))
363        .collect();
364
365    for l in &exist_lts {
366        let lt = &l.lifetime;
367        if bound_lifetimes.contains(&lt) {
368            dcx.error(
369                lt,
370                format!("existential `{lt}` conflicts with struct generics"),
371            );
372        }
373    }
374
375    // Keep track on fields being implicitly borrowed by being mentioned.
376    let mut implicitly_borrowed = BTreeSet::new();
377
378    let mut fields: Vec<FieldInfo> = struct_
379        .fields
380        .into_iter()
381        .enumerate()
382        .map(|(index, mut field)| {
383            let pinned = field.attrs.extract_single_attr(dcx, "pin").is_some();
384
385            assert!(
386                !field.attrs.iter().any(|a| a.path().is_ident("cfg")),
387                "cfgs should be all resolved at this point"
388            );
389            let member = match &field.ident {
390                Some(ident) => Member::Named(ident.clone()),
391                None => Member::Unnamed(Index {
392                    index: index as u32,
393                    span: field.span(),
394                }),
395            };
396
397            // Parse `#[uses]` attribute.
398            let (mut captures, wildcard_variance) = Capture::parse_list(
399                dcx,
400                &mut field.attrs,
401                &bound_lifetimes,
402                &exist_lts,
403                &field_idx_map,
404            )
405            .unwrap_or_default();
406
407            let mut generic_lt_captures = BTreeSet::new();
408            let mut generic_ty_captures = BTreeSet::new();
409
410            // Infer lifetime based on the field referenced.
411            // Bound lifetimes from struct generics take priority.
412            //
413            // For example,
414            // ```
415            // struct Foo<'a> {
416            //     bar: &'a (),
417            //     a: u32,
418            // }
419            // ```
420            // would not be inferred as self-referential because `'a` is already bound by the
421            // struct generics.
422            Lifetime::visitor(|lt| {
423                if bound_lifetimes.contains(lt) {
424                    generic_lt_captures.insert(lt.clone());
425                    return;
426                }
427
428                if captures.contains(lt) {
429                    return;
430                }
431
432                if !exist_lts.contains(lt) && !field_idx_map.contains_key(&lt.ident) {
433                    dcx.error(
434                        lt,
435                        format!("`{lt}` is neither a lifetime in generics nor a field name"),
436                    );
437                    return;
438                }
439
440                captures.insert(Capture {
441                    variance: wildcard_variance,
442                    lifetime: lt.clone(),
443                });
444            })
445            .visit_type(&field.ty);
446
447            for capture in captures.iter(){
448                if !exist_lts.contains(&capture.lifetime){
449                    implicitly_borrowed.insert(capture.lifetime.ident.clone());
450                }
451            }
452
453            GenericParam::maybe_type_params_visitor(|ident| {
454                if type_params.contains(ident) {
455                    generic_ty_captures.insert(ident.clone());
456                }
457            })
458            .visit_type(&field.ty);
459
460            let borrowed = BorrowedKind::parse(dcx, &mut field.attrs).and_then(|kind| {
461                let lifetime = Lifetime::from_ident(&member.as_ident());
462
463                if bound_lifetimes.contains(&lifetime) {
464                    dcx.error(
465                        &lifetime,
466                        format!("`{lifetime}` appear in generics and would conflict with field lifetime"),
467                    );
468                    return None;
469                }
470
471                Some(BorrowedInfo { kind, lifetime, lt_variance: Variance::default() })
472            });
473
474            FieldInfo {
475                field,
476                member,
477                pinned,
478                borrowed,
479                captures,
480                generic_lt_captures,
481                generic_ty_captures,
482            }
483        })
484        .collect();
485
486    for field_name in implicitly_borrowed.into_iter() {
487        let field = &mut fields[field_idx_map[&field_name]];
488
489        // If field is not explicit marked as borrowed, infer a shared borrow.
490        if field.borrowed.is_none() {
491            field.borrowed = Some(BorrowedInfo {
492                kind: BorrowedKind::Shared,
493                // Obtaining from `field` instead of `field_name` for the correct span.
494                lifetime: Lifetime::from_ident(&field.member.as_ident()),
495                lt_variance: Variance::Covariant,
496            });
497        }
498    }
499
500    // Check that field lifetimes do not appear in the bounds.
501    Lifetime::visitor(|lt| {
502        if bound_lifetimes.contains(&lt) {
503            return;
504        }
505
506        if field_idx_map.contains_key(&lt.ident) {
507            // Forbid the use of field lifetimes within bounds.
508            dcx.error(lt, "field lifetimes cannot be used in bounds");
509        }
510
511        // Otherwise this is completely unbound. Let Rust compiler produce that error instead.
512    })
513    .visit_generics(&struct_.generics);
514
515    // Obtain an closure of invariant fields.
516    //
517    // If a field lifetime is used invariantly, we also need to make sure that
518    // for each generic parameter `T: 'field` bound, `T` is also captured
519    // invariantly (same is true for lifetime parameters). For example, say we
520    // have a struct `SelfRef<'a>` and a field `f: &'a ()`. For wellformedness,
521    // we would have `'a: 'f`. If we have a covariant `'a`, we can observe a
522    // shortened `SelfRef<'short_a>` where `'f` outlives `'short_a`, conflicting
523    // with the wellformedness bound `'short_a: 'f`. This will enable the
524    // `&'short_a ()` to `&'f ()` coercion, which effectively shortens `'f` too,
525    // so we shortened the field lifetime despite it being invariant.
526    let mut invariant_field_idx = BTreeSet::new();
527    let mut worklist = Vec::new();
528    for field in fields.iter() {
529        for borrow in field.captures.iter() {
530            if exist_lts.contains(&borrow.lifetime) {
531                continue;
532            }
533            if let Variance::Invariant = borrow.variance {
534                let Some(borrow_idx) = fields
535                    .iter()
536                    .position(|f| f.member.as_ident() == borrow.lifetime.ident)
537                else {
538                    continue;
539                };
540                if invariant_field_idx.insert(borrow_idx) {
541                    worklist.push(&fields[borrow_idx]);
542                }
543            }
544        }
545    }
546    while let Some(field) = worklist.pop() {
547        for borrow in field.captures.iter() {
548            if exist_lts.contains(&borrow.lifetime) {
549                continue;
550            }
551            let Some(borrow_idx) = fields
552                .iter()
553                .position(|f| f.member.as_ident() == borrow.lifetime.ident)
554            else {
555                continue;
556            };
557            let borrow = &fields[borrow_idx];
558            if invariant_field_idx.insert(borrow_idx) {
559                worklist.push(borrow);
560            }
561        }
562    }
563    for idx in invariant_field_idx {
564        fields[idx].borrowed.as_mut().unwrap().lt_variance = Variance::Invariant;
565    }
566
567    // Create a lifetime parameter for each field.
568    let borrowed_fields: Vec<_> = fields.iter().filter_map(|f| f.borrowed.as_ref()).collect();
569    let borrowed_covariant_fields: Vec<_> = borrowed_fields
570        .iter()
571        .filter(|f| f.lt_variance == Variance::Covariant)
572        .collect();
573    let borrowed_invariant_fields: Vec<_> = borrowed_fields
574        .iter()
575        .filter(|f| f.lt_variance == Variance::Invariant)
576        .collect();
577
578    let mut field_lts_outlive_chain = Generics {
579        lt_token: None,
580        params: borrowed_fields
581            .iter()
582            .zip(std::iter::once(None).chain(borrowed_fields.iter().map(Some)))
583            .map(|(borrowed, prev)| {
584                GenericParam::Lifetime(LifetimeParam {
585                    attrs: Vec::new(),
586                    lifetime: borrowed.lifetime.clone(),
587                    colon_token: None,
588                    bounds: prev
589                        .iter()
590                        .map(|borrowed| borrowed.lifetime.clone())
591                        .collect(),
592                })
593            })
594            .collect(),
595        gt_token: None,
596        where_clause: None,
597    };
598
599    if let Some(last_borrowed_field) = borrowed_fields.last() {
600        let field_lt = &last_borrowed_field.lifetime;
601        for param in struct_.generics.params.iter() {
602            match param {
603                GenericParam::Lifetime(param) => {
604                    let lt = &param.lifetime;
605                    field_lts_outlive_chain
606                        .make_where_clause()
607                        .predicates
608                        .push(parse_quote!(#lt: #field_lt));
609                }
610                GenericParam::Type(param) => {
611                    let ty = &param.ident;
612                    field_lts_outlive_chain
613                        .make_where_clause()
614                        .predicates
615                        .push(parse_quote!(#ty: #field_lt));
616                }
617                GenericParam::Const(_) => (),
618            }
619        }
620    }
621
622    let exist_lt_generics = Generics {
623        lt_token: Some(Default::default()),
624        params: exist_lts
625            .iter()
626            .map(|l| {
627                GenericParam::Lifetime(LifetimeParam {
628                    attrs: Vec::new(),
629                    lifetime: l.lifetime.clone(),
630                    colon_token: Default::default(),
631                    bounds: l.bounds.iter().cloned().collect(),
632                })
633            })
634            .collect(),
635        gt_token: Some(Default::default()),
636        where_clause: None,
637    };
638
639    let mut field_lts_split_variance_outlive_chain = Generics {
640        lt_token: Some(Default::default()),
641        params: borrowed_covariant_fields
642            .iter()
643            .zip(std::iter::once(None).chain(borrowed_covariant_fields.iter().map(Some)))
644            .map(|(borrowed, prev)| {
645                GenericParam::Lifetime(LifetimeParam {
646                    attrs: Vec::new(),
647                    lifetime: borrowed.lifetime.clone(),
648                    colon_token: None,
649                    bounds: prev
650                        .iter()
651                        .map(|borrowed| borrowed.lifetime.clone())
652                        .collect(),
653                })
654            })
655            .chain(
656                borrowed_invariant_fields
657                    .iter()
658                    .zip(std::iter::once(None).chain(borrowed_invariant_fields.iter().map(Some)))
659                    .map(|(borrowed, prev)| {
660                        GenericParam::Lifetime(LifetimeParam {
661                            attrs: Vec::new(),
662                            lifetime: borrowed.lifetime.clone(),
663                            colon_token: None,
664                            bounds: prev
665                                .iter()
666                                .map(|borrowed| borrowed.lifetime.clone())
667                                .collect(),
668                        })
669                    }),
670            )
671            .collect(),
672        gt_token: Some(Default::default()),
673        where_clause: None,
674    };
675
676    // For `field_lts_split_variance_outlive_chain`, we may need to insert some additional bounds
677    // for types to be WF.
678    for field in fields.iter() {
679        let Some(borrowed) = &field.borrowed else {
680            continue;
681        };
682        let field_lt = &borrowed.lifetime;
683
684        // For each borrowed field that references a generic, we also need to insert their outlive
685        // bounds so they can refer to generics.
686        for lt in field.generic_lt_captures.iter() {
687            field_lts_split_variance_outlive_chain
688                .make_where_clause()
689                .predicates
690                .push(parse_quote!(#lt: #field_lt));
691        }
692
693        for ty in field.generic_ty_captures.iter() {
694            field_lts_split_variance_outlive_chain
695                .make_where_clause()
696                .predicates
697                .push(parse_quote!(#ty: #field_lt));
698        }
699
700        for borrow in field.captures.iter().rev() {
701            let lt = &borrow.lifetime;
702            if exist_lts.contains(lt) {
703                field_lts_split_variance_outlive_chain
704                    .make_where_clause()
705                    .predicates
706                    .push(parse_quote!(#lt: #field_lt));
707            }
708        }
709
710        // If a field is invariant, then the invariance closure rule will make all borrowed fields
711        // to be invariant, so they're already captured in `field_lts_split_variance_outlive_chain`.
712        if borrowed.lt_variance != Variance::Covariant {
713            continue;
714        }
715
716        for capture in field.captures.iter() {
717            let Some(&idx) = field_idx_map.get(&capture.lifetime.ident) else {
718                continue;
719            };
720
721            let prev_borrowed = fields[idx].borrowed.as_ref().unwrap();
722
723            // If borrowed field is covariant, it's already captured in
724            // `field_lts_split_variance_outlive_chain`.
725            if prev_borrowed.lt_variance == Variance::Invariant {
726                // Covariant field borrowing an invariant field. This is not captured in the chain
727                // so we need to add additional bound. This bound is okay, as the invariant lifetime
728                // is the longer living one, so arbitrary shortening of the covariant one does not
729                // violate their relation.
730                let param = field_lts_split_variance_outlive_chain
731                    .lifetimes_mut()
732                    .find(|l| l.lifetime == prev_borrowed.lifetime)
733                    .unwrap();
734                param.bounds.push(borrowed.lifetime.clone());
735            }
736        }
737    }
738
739    struct_.fields = Fields::Unit;
740    let info = StructInfo {
741        self_referential: fields
742            .iter()
743            .any(|f| !f.captures.is_empty() || f.borrowed.is_some()),
744        args,
745        struct_,
746        fields,
747        field_idx_map,
748        is_tuple_struct,
749        exist_lts,
750        field_lts_outlive_chain,
751        field_lts_split_variance_outlive_chain,
752        exist_lts_generics: exist_lt_generics,
753    };
754
755    for field in &info.fields {
756        if !field.pinned && is_phantom_pinned(&field.field.ty) {
757            dcx.warn(
758                &field.field,
759                format!(
760                    "The field {} of type `PhantomPinned` only has an effect \
761                    if it has the `#[pin]` attribute",
762                    field.member.display_name(),
763                ),
764            );
765        }
766    }
767
768    let struct_def = generate_struct_def(&info);
769    let unpin_impl = generate_unpin_impl(&info);
770    let drop_impl = generate_drop_impl(&info);
771    let drop_order_check = generate_drop_order_check(dcx, &info);
772    let variance_check = generate_variance_check(&info);
773    let projections = generate_projections(&info);
774    let the_pin_data = generate_the_pin_data(&info);
775
776    Ok(quote! {
777        #struct_def
778        // We put the rest into this const item, because it then will not be accessible to anything
779        // outside.
780        const _: () = {
781            #drop_order_check
782            #variance_check
783            #projections
784            #the_pin_data
785            #unpin_impl
786            #drop_impl
787        };
788    })
789}
790
791fn is_phantom_pinned(ty: &Type) -> bool {
792    match ty {
793        Type::Path(TypePath { qself: None, path }) => {
794            // Cannot possibly refer to `PhantomPinned` (except alias, but that's on the user).
795            if path.segments.len() > 3 {
796                return false;
797            }
798            // If there is a `::`, then the path needs to be `::core::marker::PhantomPinned` or
799            // `::std::marker::PhantomPinned`.
800            if path.leading_colon.is_some() && path.segments.len() != 3 {
801                return false;
802            }
803            let expected: Vec<&[&str]> = vec![&["PhantomPinned"], &["marker"], &["core", "std"]];
804            for (actual, expected) in path.segments.iter().rev().zip(expected) {
805                if !actual.arguments.is_empty() || expected.iter().all(|e| actual.ident != e) {
806                    return false;
807                }
808            }
809            true
810        }
811        _ => false,
812    }
813}
814
815struct ExistLt {
816    lifetime: Lifetime,
817    bounds: Vec<Lifetime>,
818}
819
820impl std::borrow::Borrow<Lifetime> for ExistLt {
821    fn borrow(&self) -> &Lifetime {
822        &self.lifetime
823    }
824}
825
826impl PartialEq for ExistLt {
827    fn eq(&self, other: &Self) -> bool {
828        self.lifetime == other.lifetime
829    }
830}
831
832impl Eq for ExistLt {}
833
834impl PartialOrd for ExistLt {
835    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
836        Some(self.cmp(other))
837    }
838}
839
840impl Ord for ExistLt {
841    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
842        self.lifetime.cmp(&other.lifetime)
843    }
844}
845
846impl ExistLt {
847    fn parse(dcx: &mut DiagCtxt, whr: &mut WhereClause) -> BTreeSet<ExistLt> {
848        fn parse_one(
849            dcx: &mut DiagCtxt,
850            pred: &WherePredicate,
851            result: &mut BTreeSet<ExistLt>,
852        ) -> bool {
853            let WherePredicate::Type(pred) = &pred else {
854                return false;
855            };
856            let Type::Path(path) = &pred.bounded_ty else {
857                return false;
858            };
859
860            if path.qself.is_some()
861                || path.path.leading_colon.is_some()
862                || path.path.segments.len() != 1
863            {
864                return false;
865            }
866            let path_seg = &path.path.segments[0];
867
868            if path_seg.ident != "exists" {
869                return false;
870            };
871
872            let PathArguments::AngleBracketed(p) = &path_seg.arguments else {
873                dcx.error(
874                    path_seg,
875                    "existential clauses require a single lifetime, e.g. `exists<'a>`",
876                );
877                return true;
878            };
879
880            if p.args.len() != 1 {
881                dcx.error(
882                    path_seg,
883                    "existential clauses require a single lifetime, e.g. `exists<'a>`",
884                );
885                return true;
886            }
887
888            let GenericArgument::Lifetime(lt) = &p.args[0] else {
889                dcx.error(
890                    path_seg,
891                    "existential clauses require a single lifetime, e.g. `exists<'a>`",
892                );
893                return true;
894            };
895
896            if result.contains(lt) {
897                dcx.error(
898                    lt,
899                    format!("an existential clause for `{lt}` already exists"),
900                );
901                return true;
902            }
903
904            let mut bounds = Vec::new();
905            for bound in pred.bounds.iter() {
906                let TypeParamBound::Lifetime(lt) = bound else {
907                    dcx.error(bound, "only lifetime can appear in existential clauses");
908                    return true;
909                };
910                bounds.push(lt.clone());
911            }
912            if bounds.is_empty() {
913                dcx.error(
914                    pred.colon_token,
915                    "existential clauses require at least one outlive bounds",
916                );
917                return true;
918            }
919
920            result.insert(ExistLt {
921                lifetime: lt.clone(),
922                bounds: bounds.clone(),
923            });
924
925            true
926        }
927
928        let mut result = BTreeSet::new();
929        whr.predicates = std::mem::take(&mut whr.predicates)
930            .into_pairs()
931            .filter(|p| !parse_one(dcx, p.value(), &mut result))
932            .collect();
933
934        result
935    }
936}
937
938fn generate_struct_def(info: &StructInfo) -> TokenStream {
939    let ItemStruct {
940        attrs,
941        vis,
942        struct_token,
943        ident,
944        generics,
945        fields: _,
946        semi_token,
947    } = &info.struct_;
948
949    let generated_fields = info.fields.iter().map(|field| {
950        let Field {
951            attrs,
952            vis,
953            mutability: _,
954            ident,
955            colon_token,
956            ty,
957        } = &field.field;
958
959        let mut ty = ty.to_token_stream();
960
961        // Replace lifetime for self-referential fields. For mutable fields, this uses `Erase` to
962        // block direct access.
963        if !field.captures.is_empty()
964            || matches!(
965                field.borrowed,
966                Some(BorrowedInfo {
967                    kind: BorrowedKind::Mutable,
968                    ..
969                })
970            )
971        {
972            // Build a chain `for<'a> fn(&'a ()) -> ... -> (Ty,)`. Such type will have a `EraseLt`
973            // implementation and thus may be used inside `Erase`.
974            ty = quote!((#ty,));
975
976            let mut exist_lt_phantoms = Vec::new();
977            for borrow in field.captures.iter().rev() {
978                let lt = &borrow.lifetime;
979                ty = quote!(for<#lt> fn(&#lt()) -> #ty);
980
981                if let Some(exist_lt) = info.exist_lts.get(lt) {
982                    for bound in &exist_lt.bounds {
983                        exist_lt_phantoms.push(quote!(::pin_init::__internal::ExistLt<#bound>));
984                    }
985                }
986            }
987
988            ty = quote!(::pin_init::__internal::Erase<#ty>);
989
990            if !exist_lt_phantoms.is_empty() {
991                ty = quote!(::pin_init::__internal::WithPhantom<#ty, (#(#exist_lt_phantoms,)*)>);
992            }
993        };
994
995        if let Some(borrowed) = &field.borrowed {
996            let mut invariance_capture = Vec::new();
997            if borrowed.lt_variance == Variance::Invariant {
998                for lt in &field.generic_lt_captures {
999                    invariance_capture.push(quote!(&#lt ()));
1000                }
1001
1002                for ty in &field.generic_ty_captures {
1003                    invariance_capture.push(quote!(::core::marker::PhantomData<#ty>));
1004                }
1005            }
1006            ty = quote!(::pin_init::__internal::Borrowed<#ty, (#(#invariance_capture,)*)>);
1007        }
1008
1009        quote! {
1010           #(#attrs)* #vis #ident #colon_token #ty
1011        }
1012    });
1013
1014    let whr = &generics.where_clause;
1015
1016    if info.is_tuple_struct {
1017        quote!(
1018            #(#attrs)*
1019            #vis
1020            #struct_token #ident #generics (#(#generated_fields,)*) #whr
1021            #semi_token
1022        )
1023    } else {
1024        quote!(
1025            #(#attrs)*
1026            #vis
1027            #struct_token #ident #generics #whr {
1028                #(#generated_fields,)*
1029            }
1030            #semi_token
1031        )
1032    }
1033}
1034
1035fn generate_unpin_impl(info: &StructInfo) -> TokenStream {
1036    let ItemStruct {
1037        generics, ident, ..
1038    } = &info.struct_;
1039    let (impl_generics, ty_generics, whr) = generics.split_for_impl();
1040    let predicates = whr
1041        .map(|x| &x.predicates)
1042        .unwrap_or(const { &Punctuated::new() });
1043
1044    if info.self_referential {
1045        // Self-referential structs must always be pinned.
1046        return quote! {
1047            #[doc(hidden)]
1048            impl #impl_generics ::core::marker::Unpin for #ident #ty_generics
1049            where
1050                // the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`
1051                // feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.
1052                for<'__dummy> ::core::marker::PhantomPinned: ::core::marker::Unpin,
1053                #predicates
1054            {}
1055        };
1056    }
1057
1058    let pinned_fields = info.fields.iter().filter(|f| f.pinned).map(|f| {
1059        let ident = f.member.as_ident();
1060        let ty = &f.field.ty;
1061        quote!(
1062            #ident: #ty
1063        )
1064    });
1065
1066    quote! {
1067        // This struct will be used for the unpin analysis. It is needed, because only structurally
1068        // pinned fields are relevant whether the struct should implement `Unpin`.
1069        #[allow(
1070            dead_code, // The fields below are never used.
1071            non_snake_case // The warning will be emitted on the struct definition.
1072        )]
1073        struct __Unpin #generics #whr
1074        {
1075            __phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>,
1076            #(#pinned_fields),*
1077        }
1078
1079        #[doc(hidden)]
1080        impl #impl_generics ::core::marker::Unpin for #ident #ty_generics
1081        where
1082            // the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`
1083            // feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.
1084            for<'__dummy> __Unpin #ty_generics: ::core::marker::Unpin,
1085            #predicates
1086        {}
1087    }
1088}
1089
1090fn generate_drop_impl(info: &StructInfo) -> TokenStream {
1091    let ItemStruct {
1092        generics, ident, ..
1093    } = &info.struct_;
1094    let (impl_generics, ty_generics, whr) = generics.split_for_impl();
1095    let has_pinned_drop = matches!(info.args, Args::PinnedDrop(_));
1096    // We need to disallow normal `Drop` implementation, the exact behavior depends on whether
1097    // `PinnedDrop` was specified in `args`.
1098    if has_pinned_drop {
1099        // When `PinnedDrop` was specified we just implement `Drop` and delegate.
1100        quote! {
1101            impl #impl_generics ::core::ops::Drop for #ident #ty_generics
1102                #whr
1103            {
1104                fn drop(&mut self) {
1105                    // SAFETY: Since this is a destructor, `self` will not move after this function
1106                    // terminates, since it is inaccessible.
1107                    let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };
1108                    // SAFETY: Since this is a drop function, we can create this token to call the
1109                    // pinned destructor of this type.
1110                    let token = unsafe { ::pin_init::__internal::OnlyCallFromDrop::new() };
1111                    ::pin_init::PinnedDrop::drop(pinned, token);
1112                }
1113            }
1114        }
1115    } else {
1116        // When no `PinnedDrop` was specified, then we have to prevent implementing drop.
1117        quote! {
1118            // We prevent this by creating a trait that will be implemented for all types implementing
1119            // `Drop`. Additionally we will implement this trait for the struct leading to a conflict,
1120            // if it also implements `Drop`
1121            trait MustNotImplDrop {}
1122            impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
1123            impl #impl_generics MustNotImplDrop for #ident #ty_generics
1124                #whr
1125            {}
1126            // We also take care to prevent users from writing a useless `PinnedDrop` implementation.
1127            // They might implement `PinnedDrop` correctly for the struct, but forget to give
1128            // `PinnedDrop` as the parameter to `#[pin_data]`.
1129            trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
1130            impl<T: ::pin_init::PinnedDrop + ?::core::marker::Sized>
1131                UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
1132            impl #impl_generics
1133                UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for #ident #ty_generics
1134                #whr
1135            {}
1136        }
1137    }
1138}
1139
1140fn generate_drop_order_check(dcx: &mut DiagCtxt, info: &StructInfo) -> TokenStream {
1141    let ItemStruct {
1142        ident: struct_name,
1143        generics,
1144        ..
1145    } = &info.struct_;
1146
1147    // If the struct is not self-referential then we can just skip.
1148    if !info.self_referential {
1149        return quote!();
1150    }
1151
1152    // Make sure fields are dropped earlier than the fields that they borrow.
1153    for (i, field) in info.fields.iter().enumerate() {
1154        let ident = field.member.as_ident();
1155        for capture in &field.captures {
1156            let borrowed_field = &capture.lifetime.ident;
1157
1158            if let Some(&borrowed_idx) = info.field_idx_map.get(borrowed_field) {
1159                if i == borrowed_idx {
1160                    // We need a strict outlive relationship, in case the lifetime is needed by the
1161                    // field's drop glue.
1162                    dcx.error(
1163                        borrowed_field,
1164                        format!("field `{ident}` cannot borrow from itself"),
1165                    );
1166                } else if i > borrowed_idx {
1167                    dcx.error(
1168                        borrowed_field,
1169                        format!("field `{ident}` borrows `{borrowed_field}`, but drops later"),
1170                    );
1171                }
1172            }
1173        }
1174    }
1175
1176    // The check above is necessary, but not sufficient.
1177    //
1178    // Consider this case:
1179    // ```
1180    // struct Foo {
1181    //     x: &'b &'a (),
1182    //     a: String,
1183    //     y: PrintOnDrop<&'b str>,
1184    //     b: String,
1185    // }
1186    // ```
1187    // we need to ensure that `b` will strictly outlive `a`.
1188    //
1189    // Rust needs to ensure that types are well-formed; in the above example, `&'b &'a ()` is
1190    // well-formed only if `a` outlive `b`. To avoid requiring everyone from having to express this
1191    // bound explicitly when declaring a struct, the `'b: 'a` bound is inferred by the Rust
1192    // compiler. However this causes an issue, where now `&'a str` can be coerced to `&'b str`
1193    // because compiler thinks that it shorten the lifetime. We'll be able to put a reference to `a`
1194    // into `y`; but `a` drops first, so when `y` drops, it accesses `a` and causes a
1195    // use-after-free!
1196    //
1197    // Therefore, we must ensure the types contained within the struct has their implied bound being
1198    // consistent with the actual lifetime relationship. We create a `__drop_order_check` function,
1199    // with known lifetime bounds as bounds on the function, and asks Rust to *prove* that the types
1200    // are wellformed, given the bounds that we understand.
1201
1202    let generics_with_field_lt = CombinedGenerics(vec![
1203        &info.exist_lts_generics,
1204        &info.field_lts_split_variance_outlive_chain,
1205        generics,
1206    ]);
1207
1208    let (_, ty_generics, _) = generics.split_for_impl();
1209    let (impl_generics_with_field_lt, _, whr_with_field_lt) =
1210        generics_with_field_lt.split_for_impl();
1211
1212    // Prove the wellformedness of struct fields with regarding to the bounds of
1213    // `__drop_order_check`.
1214    //
1215    // Consider this case:
1216    // ```
1217    // struct Foo {
1218    //     x: &'b &'a (),
1219    //     a: String,
1220    //     y: PrintOnDrop<&'b str>,
1221    //     b: String,
1222    // }
1223    // ```
1224    // we need to ensure that `b` will strictly outlive `a`.
1225    //
1226    // Rust needs to ensure that types are well-formed; in the above example, `&'b &'a ()` is
1227    // well-formed only if `a` outlive `b`. To avoid requiring everyone from having to express this
1228    // bound explicitly when declaring a struct, the `'b: 'a` bound is inferred by the Rust
1229    // compiler. However this causes an issue, where now `&'a str` can be coerced to `&'b str`
1230    // because compiler thinks that it shorten the lifetime. We'll be able to put a reference to `a`
1231    // into `y`; but `a` drops first, so when `y` drops, it accesses `a` and causes a
1232    // use-after-free!
1233    //
1234    // Rust needs to *prove* the wellformedness of the type below, taking into account only the
1235    // explicitly defined bounds plus the bounds implied by the lifetime-erased struct (but not
1236    // the full implied bound between the field lifetimes).
1237    let wf_proofs = info.fields.iter().rev().map(|f| {
1238        let ty = &f.field.ty;
1239        let span = ty.span().resolved_at(Span::mixed_site());
1240        let ident = f.member.as_ident();
1241        let lt = f.borrowed.as_ref().map(|b| &b.lifetime);
1242        quote_spanned!(span =>
1243            let #ident: &#lt mut #ty = loop {};
1244        )
1245    });
1246
1247    let struct_span = struct_name.span().resolved_at(Span::mixed_site());
1248    quote_spanned! {struct_span =>
1249        #[allow(non_snake_case, unused)]
1250        fn __drop_order_check #impl_generics_with_field_lt (
1251            // This must be present so the function can *assume* the implied bounds on the erased
1252            // struct. For example, if the struct has `&'a T`, Rust will infer `T: 'a`; we still
1253            // want to assume these bounds as they are not relevant to the field lifetimes.
1254            _: &#struct_name #ty_generics,
1255        ) #whr_with_field_lt {
1256            #(#wf_proofs)*
1257        }
1258    }
1259}
1260
1261/// Produce variance checks, so we can ensure that the variance of lifetimes captured by field types
1262/// actually match our expectation.
1263fn generate_variance_check(info: &StructInfo) -> TokenStream {
1264    if !info.self_referential {
1265        return quote!();
1266    }
1267
1268    let mut checks = Vec::new();
1269
1270    for f in info.fields.iter() {
1271        let covariant_captures: Vec<_> = f
1272            .captures
1273            .iter()
1274            .filter(|b| b.variance == Variance::Covariant)
1275            .map(|b| &b.lifetime)
1276            .collect();
1277        if covariant_captures.is_empty() {
1278            continue;
1279        }
1280
1281        let ident = f.member.as_ident();
1282        // Use the span of type for better error message.
1283        let span = f.field.ty.span().resolved_at(Span::mixed_site());
1284
1285        let other_field_lifetimes = Generics {
1286            lt_token: None,
1287            params: f
1288                .captures
1289                .iter()
1290                .filter(|b| b.variance != Variance::Covariant)
1291                .map(|b| GenericParam::Lifetime(LifetimeParam::new(b.lifetime.clone())))
1292                .collect(),
1293            gt_token: None,
1294            where_clause: None,
1295        };
1296
1297        let long = Lifetime::new("'__long", span);
1298        let long_ty = f
1299            .field
1300            .ty
1301            .replace_lifetimes(&covariant_captures, &vec![&long; covariant_captures.len()]);
1302
1303        let short = Lifetime::new("'__short", span);
1304        let short_ty = f
1305            .field
1306            .ty
1307            .replace_lifetimes(&covariant_captures, &vec![&short; covariant_captures.len()]);
1308
1309        let check_name = format_ident!("__{ident}_covariance", span = span);
1310
1311        // Add `<'__long: '__short, 'short>` as additional generics.
1312        let covariance_check_generics = parse_quote!(<#long: #short, #short>);
1313        let combined_generics = CombinedGenerics(vec![
1314            &covariance_check_generics,
1315            &other_field_lifetimes,
1316            &info.struct_.generics,
1317        ]);
1318        let (combined_impl_generics, _, whr) = combined_generics.split_for_impl();
1319
1320        checks.push(quote_spanned!(span =>
1321            // Emit a check to ensure the type is *really* covariant for soundness.
1322            fn #check_name #combined_impl_generics (long: #long_ty) -> #short_ty #whr {
1323                long
1324            }
1325        ));
1326    }
1327
1328    quote!(
1329        #(#checks)*
1330    )
1331}
1332
1333fn generate_projections(info: &StructInfo) -> TokenStream {
1334    let ItemStruct {
1335        vis,
1336        ident,
1337        generics,
1338        ..
1339    } = &info.struct_;
1340    let this_lt = Lifetime::new("'__this", Span::mixed_site());
1341    let this_lt_generics: Generics = parse_quote!(<#this_lt>);
1342
1343    // Wrap in `CombinedGenerics` because it's ty generics will always output `<>`, so it can be
1344    // used with `for`.
1345    let field_lts = CombinedGenerics(vec![
1346        &info.field_lts_outlive_chain,
1347        &info.exist_lts_generics,
1348    ]);
1349    let generics_with_this_lt = CombinedGenerics(vec![&this_lt_generics, generics]);
1350    let generics_with_this_field_lt = CombinedGenerics(vec![
1351        &this_lt_generics,
1352        &info.exist_lts_generics,
1353        &info.field_lts_outlive_chain,
1354        generics,
1355    ]);
1356    let generics_with_this_field_ref_lt = CombinedGenerics(vec![
1357        &this_lt_generics,
1358        &info.exist_lts_generics,
1359        &info.field_lts_split_variance_outlive_chain,
1360        generics,
1361    ]);
1362    let (_, field_lt_ty_generics, _) = field_lts.split_for_impl();
1363    let (impl_generics, ty_generics, whr) = generics.split_for_impl();
1364    let (_, ty_generics_with_this_lt, _) = generics_with_this_lt.split_for_impl();
1365    let (_, ty_generics_with_this_field_lt, _) = generics_with_this_field_lt.split_for_impl();
1366    let (_, ty_generics_with_this_field_ref_lt, _) =
1367        generics_with_this_field_ref_lt.split_for_impl();
1368
1369    let this = format_ident!("this");
1370
1371    let (fields_decl, fields_proj): (Vec<_>, Vec<_>) = info
1372        .fields
1373        .iter()
1374        .map(|f| {
1375            let vis = &f.field.vis;
1376            let ident = f.member.as_ident();
1377            let member = &f.member;
1378            // The projection of a tuple struct is a tuple struct itself, so its fields are
1379            // positional and must not be named.
1380            let name = (!info.is_tuple_struct).then(|| quote!(#ident:));
1381
1382            // if `f.ty` contains field lifetimes, which we need to replace them with shorter
1383            // `'__this` lifetime as field lifetimes are not available in this context.
1384            let all_lifetimes: Vec<_> = f.captures.iter().map(|b| &b.lifetime).collect();
1385            let ty = f
1386                .field
1387                .ty
1388                .replace_lifetimes(&all_lifetimes, &vec![&this_lt; all_lifetimes.len()]);
1389
1390            // Fields sharedly borrowed by other fields can only be shared accessed. Fields that
1391            // references other field and are covariant can also only be given shared reference
1392            // as mutable reference is invariant.
1393            let mut_token: Option<Token![mut]> = if f.borrowed.is_none() && f.captures.is_empty() {
1394                Some(Default::default())
1395            } else {
1396                None
1397            };
1398
1399            let mut accessor = quote!(&#mut_token #this.#member);
1400            if !f.captures.is_empty() || f.borrowed.is_some() {
1401                accessor = quote!(
1402                    // SAFETY: we have `Erase<..>` which we know is layout compatible with `f.ty`.
1403                    // Field lifetimes in `f.ty` can be shortened to `#ty` due to covariance.
1404                    unsafe { ::core::mem::transmute::<_, &#mut_token #ty>(#accessor) }
1405                )
1406            }
1407
1408            if !f.captures.iter().all(|b| b.variance == Variance::Covariant)
1409                || matches!(
1410                    f.borrowed,
1411                    Some(BorrowedInfo {
1412                        kind: BorrowedKind::Mutable,
1413                        ..
1414                    })
1415                )
1416            {
1417                // If the type is not covariant, it must omitted, as projection shortens the
1418                // lifetime to `'__this`.
1419                // Mutable borrow must be omitted for aliasing reason.
1420                (
1421                    quote!(
1422                        #vis #name ::pin_init::__internal::NotVisible<&'__this #mut_token #ty>,
1423                    ),
1424                    quote!(
1425                        #name ::pin_init::__internal::NotVisible::new(),
1426                    ),
1427                )
1428            } else if f.pinned {
1429                (
1430                    quote!(
1431                        #vis #name ::core::pin::Pin<&'__this #mut_token #ty>,
1432                    ),
1433                    quote!(
1434                        // SAFETY: this field is structurally pinned.
1435                        #name unsafe { ::core::pin::Pin::new_unchecked(#accessor) },
1436                    ),
1437                )
1438            } else {
1439                (
1440                    quote!(
1441                        #vis #name &'__this #mut_token #ty,
1442                    ),
1443                    quote!(
1444                        #name #accessor,
1445                    ),
1446                )
1447            }
1448        })
1449        .collect();
1450
1451    let (fields_decl_lt, fields_proj_lt): (Vec<_>, Vec<_>) = info
1452        .fields
1453        .iter()
1454        .map(|f| {
1455            let vis = &f.field.vis;
1456            let ident = f.member.as_ident();
1457            let member = &f.member;
1458            let name = (!info.is_tuple_struct).then(|| quote!(#ident:));
1459
1460            let ty = &f.field.ty;
1461
1462            // Fields shared-referenced by other fields can only be shared accessed.
1463            let mut_token: Option<Token![mut]> = if f.borrowed.is_none() {
1464                Some(Default::default())
1465            } else {
1466                None
1467            };
1468
1469            let mut accessor = quote!(&#mut_token #this.#member);
1470            if !f.captures.is_empty() || f.borrowed.is_some() {
1471                accessor = quote!(
1472                    // SAFETY: we have `Erase<..>` which we know is layout compatible with `f.ty`.
1473                    // We cannot include explicit type name here as the field lifetimes are nameable
1474                    // in this context, so `for<'field_name> ..` would fail.
1475                    unsafe { ::core::mem::transmute(#accessor) }
1476                )
1477            }
1478
1479            // In `with_project`, borrowed fields have their field lifetime available, so use it
1480            // instead of `'__this`.
1481            let lt = if f.borrowed.is_some() {
1482                Lifetime::from_ident(&ident)
1483            } else {
1484                this_lt.clone()
1485            };
1486
1487            if matches!(
1488                f.borrowed,
1489                Some(BorrowedInfo {
1490                    kind: BorrowedKind::Mutable,
1491                    ..
1492                })
1493            ) {
1494                // If the type is not covariant, it must omitted, as projection shortens the
1495                // lifetime to `'__this`.
1496                // Mutable borrow must be omitted for aliasing reason.
1497                (
1498                    quote!(
1499                        #vis #name ::pin_init::__internal::NotVisible<&#lt #mut_token #ty>,
1500                    ),
1501                    quote!(
1502                        #name ::pin_init::__internal::NotVisible::new(),
1503                    ),
1504                )
1505            } else if f.pinned {
1506                (
1507                    quote!(
1508                        #vis #name ::core::pin::Pin<&#lt #mut_token #ty>,
1509                    ),
1510                    quote!(
1511                        // SAFETY: this field is structurally pinned.
1512                        #name unsafe { ::core::pin::Pin::new_unchecked(#accessor) },
1513                    ),
1514                )
1515            } else {
1516                (
1517                    quote!(
1518                        #vis #name &#lt #mut_token #ty,
1519                    ),
1520                    quote!(
1521                        #name #accessor,
1522                    ),
1523                )
1524            }
1525        })
1526        .collect();
1527
1528    let structurally_pinned_fields_docs: Vec<_> = info
1529        .fields
1530        .iter()
1531        .filter(|f| f.pinned)
1532        .map(|f| format!(" - {}", f.member.display_name()))
1533        .collect();
1534    let not_structurally_pinned_fields_docs: Vec<_> = info
1535        .fields
1536        .iter()
1537        .filter(|f| !f.pinned)
1538        .map(|f| format!(" - {}", f.member.display_name()))
1539        .collect();
1540    let docs = format!(" Pin-projections of [`{ident}`]");
1541    let (projection_def, projection_init) = if info.is_tuple_struct {
1542        (
1543            quote! {
1544                #vis struct __Projection #generics_with_this_lt (
1545                    #(#fields_decl)*
1546                    ::core::marker::PhantomData<&'__this mut #ident #ty_generics>,
1547                ) #whr;
1548            },
1549            quote! {
1550                __Projection(
1551                    #(#fields_proj)*
1552                    ::core::marker::PhantomData,
1553                )
1554            },
1555        )
1556    } else {
1557        (
1558            quote! {
1559                #vis struct __Projection #generics_with_this_lt
1560                    #whr
1561                {
1562                    #(#fields_decl)*
1563                    __this: ::core::marker::PhantomData<&'__this mut #ident #ty_generics>,
1564                }
1565            },
1566            quote! {
1567                __Projection {
1568                    #(#fields_proj)*
1569                    __this: ::core::marker::PhantomData,
1570                }
1571            },
1572        )
1573    };
1574
1575    let projection_lt = format_ident!("__ProjectionLt");
1576    let (projection_lt_def, projection_lt_init) = if info.is_tuple_struct {
1577        (
1578            quote! {
1579                #vis struct #projection_lt #generics_with_this_field_lt (
1580                    #(#fields_decl_lt)*
1581                    ::core::marker::PhantomData<&'__this mut #ident #ty_generics>,
1582                ) #whr;
1583            },
1584            quote! {
1585                #projection_lt(
1586                    #(#fields_proj_lt)*
1587                    ::core::marker::PhantomData,
1588                )
1589            },
1590        )
1591    } else {
1592        (
1593            quote! {
1594                #vis struct #projection_lt #generics_with_this_field_lt
1595                    #whr
1596                {
1597                    #(#fields_decl_lt)*
1598                    ___pin_phantom_data:
1599                        ::core::marker::PhantomData<&'__this mut #ident #ty_generics>,
1600                }
1601            },
1602            quote! {
1603                #projection_lt {
1604                    #(#fields_proj_lt)*
1605                    ___pin_phantom_data: ::core::marker::PhantomData,
1606                }
1607            },
1608        )
1609    };
1610
1611    // For fields that references other fields, field access syntax stops working as they're wrapped
1612    // behind `Erase` because their actual lifetime is not on the struct.
1613    //
1614    // Generate an accessor method for them.
1615    let mut accessors = Vec::new();
1616    for f in info.fields.iter() {
1617        let ident = f.member.as_ident();
1618        let member = &f.member;
1619
1620        if f.captures.is_empty() {
1621            // They can be accessed normally, no accessor to be generated.
1622            continue;
1623        }
1624
1625        if matches!(
1626            f.borrowed,
1627            Some(BorrowedInfo {
1628                kind: BorrowedKind::Mutable,
1629                ..
1630            })
1631        ) {
1632            // Mutably borrowed fields cannot be accessed directly under any circumstance.
1633            continue;
1634        }
1635
1636        if f.captures.iter().all(|b| b.variance == Variance::Covariant) {
1637            let f_doc = format!("Access the `{ident}` field on a shared reference of `Self`.");
1638            let vis = &f.field.vis;
1639
1640            // Use the span of type for better error message.
1641            let span = f.field.ty.span().resolved_at(Span::mixed_site());
1642
1643            let all_lifetimes: Vec<_> = f.captures.iter().map(|b| &b.lifetime).collect();
1644            let ty = f
1645                .field
1646                .ty
1647                .replace_lifetimes(&all_lifetimes, &vec![&this_lt; all_lifetimes.len()]);
1648
1649            accessors.push(quote_spanned!(span =>
1650                #[doc = #f_doc]
1651                #[inline]
1652                #[allow(clippy::mut_from_ref)] // false positive when `&&mut` is returned.
1653                #vis fn #ident<#this_lt>(&#this_lt self) -> &#this_lt #ty {
1654                    // SAFETY: we have `Erased<..>` which we know is layout compatible with `f.ty`.
1655                    // Field lifetimes in `f.ty` can be shortened to `#ty` due to covariance.
1656                    unsafe { ::core::mem::transmute(&self.#member) }
1657                }
1658            ))
1659        } else {
1660            let f_doc = format!("Access the `{ident}` field on a shared reference of `Self`.");
1661            let vis = &f.field.vis;
1662            let with_ident = format_ident!("with_{ident}");
1663
1664            let all_lifetimes: Vec<_> = f.captures.iter().map(|b| &b.lifetime).collect();
1665            let ty = &f.field.ty;
1666
1667            accessors.push(quote!(
1668                #[doc = #f_doc]
1669                #[inline]
1670                #vis fn #with_ident<'__this, R>(
1671                    &'__this self,
1672                    f: impl for<#(#all_lifetimes,)*> ::core::ops::FnOnce(&'__this #ty) -> R,
1673                ) -> R {
1674                    // SAFETY: we have `Erase<..>` which we know is layout compatible with `f.ty`.
1675                    f(unsafe { ::core::mem::transmute(&self.#member) })
1676                }
1677            ))
1678        }
1679    }
1680
1681    let (fields_ref_decl_lt, fields_ref_proj_lt): (Vec<_>, Vec<_>) = info
1682        .fields
1683        .iter()
1684        .map(|f| {
1685            let vis = &f.field.vis;
1686            let ident = f.member.as_ident();
1687            let member = &f.member;
1688            let name = (!info.is_tuple_struct).then(|| quote!(#ident:));
1689
1690            let ty = &f.field.ty;
1691
1692            let mut accessor = quote!(&#this.#member);
1693            if !f.captures.is_empty() || f.borrowed.is_some() {
1694                accessor = quote!(
1695                    // SAFETY: we have `Erase<..>` which we know is layout compatible with `f.ty`.
1696                    // We cannot include explicit type name here as the field lifetimes are nameable
1697                    // in this context.
1698                    unsafe { ::core::mem::transmute(#accessor) }
1699                )
1700            }
1701
1702            // In `with_project`, borrowed fields have their field lifetime available, so use it
1703            // instead of `'__this`.
1704            let lt = if f.borrowed.is_some() {
1705                Lifetime::from_ident(&ident)
1706            } else {
1707                this_lt.clone()
1708            };
1709
1710            if matches!(
1711                f.borrowed,
1712                Some(BorrowedInfo {
1713                    kind: BorrowedKind::Mutable,
1714                    ..
1715                })
1716            ) {
1717                // Mutable borrow must be omitted for aliasing reason.
1718                (
1719                    quote!(
1720                        #vis #name ::pin_init::__internal::NotVisible<&#lt #ty>,
1721                    ),
1722                    quote!(
1723                        #name ::pin_init::__internal::NotVisible::new(),
1724                    ),
1725                )
1726            } else if f.pinned {
1727                (
1728                    quote!(
1729                        #vis #name ::core::pin::Pin<&#lt #ty>,
1730                    ),
1731                    quote!(
1732                        // SAFETY: this field is structurally pinned.
1733                        #name unsafe { ::core::pin::Pin::new_unchecked(#accessor) },
1734                    ),
1735                )
1736            } else {
1737                (
1738                    quote!(
1739                        #vis #name &#lt #ty,
1740                    ),
1741                    quote!(
1742                        #name #accessor,
1743                    ),
1744                )
1745            }
1746        })
1747        .collect();
1748
1749    let projection_ref_lt = format_ident!("__ProjectionRef");
1750    let (projection_ref_lt_def, projection_ref_lt_init) = if info.is_tuple_struct {
1751        (
1752            quote!(
1753                #vis struct #projection_ref_lt #generics_with_this_field_ref_lt(
1754                    #(#fields_ref_decl_lt)*
1755                    ::core::marker::PhantomData<&'__this #ident #ty_generics>,
1756                ) #whr;
1757            ),
1758            quote!(
1759                #projection_ref_lt(
1760                    #(#fields_ref_proj_lt)*
1761                    ::core::marker::PhantomData,
1762                )
1763            ),
1764        )
1765    } else {
1766        (
1767            quote! {
1768                #vis struct #projection_ref_lt #generics_with_this_field_ref_lt
1769                    #whr
1770                {
1771                    #(#fields_ref_decl_lt)*
1772                    ___pin_phantom_data: ::core::marker::PhantomData<&'__this #ident #ty_generics>,
1773                }
1774            },
1775            quote! {
1776                #projection_ref_lt {
1777                    #(#fields_ref_proj_lt)*
1778                    ___pin_phantom_data: ::core::marker::PhantomData,
1779                }
1780            },
1781        )
1782    };
1783
1784    quote! {
1785        #[doc = #docs]
1786        // Allow `non_snake_case` since the same warning will be emitted on
1787        // the struct definition.
1788        #[allow(dead_code, non_snake_case)]
1789        #[doc(hidden)]
1790        #projection_def
1791
1792        #[doc = #docs]
1793        // Allow `non_snake_case` since the same warning will be emitted on
1794        // the struct definition.
1795        #[allow(dead_code, non_snake_case, explicit_outlives_requirements)]
1796        #[doc(hidden)]
1797        #projection_lt_def
1798
1799        // Allow `non_snake_case` since the same warning will be emitted on
1800        // the struct definition.
1801        #[allow(dead_code, non_snake_case, explicit_outlives_requirements)]
1802        #[doc(hidden)]
1803        #projection_ref_lt_def
1804
1805        impl #impl_generics #ident #ty_generics
1806            #whr
1807        {
1808            /// Pin-projects all fields of `Self`.
1809            ///
1810            /// These fields are structurally pinned:
1811            #(#[doc = #structurally_pinned_fields_docs])*
1812            ///
1813            /// These fields are **not** structurally pinned:
1814            #(#[doc = #not_structurally_pinned_fields_docs])*
1815            #[inline]
1816            #vis fn project<'__this>(
1817                self: ::core::pin::Pin<&'__this mut Self>,
1818            ) -> __Projection #ty_generics_with_this_lt {
1819                // SAFETY: we only give access to `&mut` for fields not structurally pinned.
1820                let #this = unsafe { ::core::pin::Pin::get_unchecked_mut(self) };
1821                #projection_init
1822            }
1823
1824            /// Pin-projects all fields of `Self` with proper lifetime.
1825            ///
1826            /// These fields are structurally pinned:
1827            #(#[doc = #structurally_pinned_fields_docs])*
1828            ///
1829            /// These fields are **not** structurally pinned:
1830            #(#[doc = #not_structurally_pinned_fields_docs])*
1831            #[inline]
1832            #vis fn with_project<'__this, R>(
1833                self: ::core::pin::Pin<&'__this mut Self>,
1834                f: impl for #field_lt_ty_generics ::core::ops::FnOnce(
1835                    #projection_lt #ty_generics_with_this_field_lt
1836                ) -> R,
1837            ) -> R {
1838                // SAFETY: we only give access to `&mut` for fields not structurally pinned.
1839                let #this = unsafe { ::core::pin::Pin::get_unchecked_mut(self) };
1840                f(#projection_lt_init)
1841            }
1842
1843            /// Pin-projects all fields of `Self` from a shared reference with proper lifetime.
1844            ///
1845            /// These fields are structurally pinned:
1846            #(#[doc = #structurally_pinned_fields_docs])*
1847            ///
1848            /// These fields are **not** structurally pinned:
1849            #(#[doc = #not_structurally_pinned_fields_docs])*
1850            #[inline]
1851            #vis fn with_project_ref<'__this, R>(
1852                self: ::core::pin::Pin<&'__this Self>,
1853                f: impl for #field_lt_ty_generics ::core::ops::FnOnce(
1854                    #projection_ref_lt #ty_generics_with_this_field_ref_lt
1855                ) -> R,
1856            ) -> R {
1857                let #this = ::core::pin::Pin::get_ref(self);
1858                f(#projection_ref_lt_init)
1859            }
1860
1861            #(#accessors)*
1862        }
1863    }
1864}
1865
1866fn generate_the_pin_data(info: &StructInfo) -> TokenStream {
1867    let ItemStruct {
1868        vis,
1869        ident: struct_name,
1870        generics,
1871        ..
1872    } = &info.struct_;
1873
1874    // Wrap in `CombinedGenerics` because it's ty generics will always output `<>`, so it can be
1875    // used with `for`.
1876    let field_lts = CombinedGenerics(vec![&info.field_lts_outlive_chain]);
1877    let field_exist_lts = CombinedGenerics(vec![
1878        &info.field_lts_outlive_chain,
1879        &info.exist_lts_generics,
1880    ]);
1881    let generics_with_field_lt = CombinedGenerics(vec![
1882        &info.field_lts_outlive_chain,
1883        &info.exist_lts_generics,
1884        generics,
1885    ]);
1886
1887    let (impl_generics, ty_generics, whr) = generics.split_for_impl();
1888    let (_, field_lt_ty_generics, _) = field_lts.split_for_impl();
1889    let (_, field_exist_lt_ty_generics, _) = field_exist_lts.split_for_impl();
1890    let (impl_generics_with_lt, ty_generics_with_field_lt, whr_with_field_lt) =
1891        generics_with_field_lt.split_for_impl();
1892
1893    // Wrap each field in a `PhantomInvariant`. For borrowed fields, additionally
1894    // use `&#lt mut #ty` so the `lt` becomes associated with `#ty` which deduces
1895    // implied bounds.
1896    let phantom_fields = info.fields.iter().map(|f| {
1897        let ty = &f.field.ty;
1898        let ident = f.member.as_ident();
1899
1900        if let Some(borrowed) = &f.borrowed {
1901            let lt = &borrowed.lifetime;
1902            quote!(
1903                #ident: ::pin_init::__internal::PhantomInvariant<&#lt mut #ty>,
1904            )
1905        } else {
1906            quote!(
1907                #ident: ::pin_init::__internal::PhantomInvariant<#ty>,
1908            )
1909        }
1910    });
1911
1912    let field_accessors = info
1913        .fields
1914        .iter()
1915        .map(|f| {
1916            let Field { vis, ty, .. } = &f.field;
1917            let field_name = f.member.as_ident();
1918            let member = &f.member;
1919            let pin_marker = if f.pinned {
1920                quote!(Pinned)
1921            } else {
1922                quote!(Unpinned)
1923            };
1924
1925            let (slot_ty, slot_arg) = match &f.borrowed {
1926                None => (quote!(Slot), quote!()),
1927                Some(BorrowedInfo {
1928                    kind: BorrowedKind::Shared,
1929                    lifetime,
1930                    ..
1931                }) => (
1932                    // For borrowed fields, create a `SelfRefSlot`, which after initialization
1933                    // turns into a `SelfRefDropGuard` instead of `DropGuard`.
1934                    //
1935                    // They're mostly the same, except that `SelfRefDropGuard` returns `&'field T`
1936                    // instead of `&'guard T` for let bindings; this allows it to be used to be
1937                    // used to initialize other fields.
1938                    //
1939                    // The soundness of doing so relies on fact that `__make_init` requires a
1940                    // higher-ranked trait bound on the closure. Within the closure (which is the
1941                    // caller of the generated slot projection functions here), it can make no
1942                    // assumptions on the lifetime except for those implied by the struct's bounds,
1943                    // and we have validated them in `generate_drop_check`.
1944                    quote!(SelfRefSlot),
1945                    quote!(#lifetime, ::pin_init::__internal::Shared, ),
1946                ),
1947                Some(BorrowedInfo {
1948                    kind: BorrowedKind::Mutable,
1949                    lifetime,
1950                    ..
1951                }) => (
1952                    // For borrowed fields, create a `SelfRefSlot`, which after initialization
1953                    // turns into a `SelfRefDropGuard` instead of `DropGuard`.
1954                    //
1955                    // They're mostly the same, except that `SelfRefDropGuard` returns `&'field T`
1956                    // instead of `&'guard T` for let bindings; this allows it to be used to be
1957                    // used to initialize other fields.
1958                    //
1959                    // The soundness of doing so relies on fact that `__make_init` requires a
1960                    // higher-ranked trait bound on the closure. Within the closure (which is the
1961                    // caller of the generated slot projection functions here), it can make no
1962                    // assumptions on the lifetime except for those implied by the struct's bounds,
1963                    // and we have validated them in `generate_drop_check`.
1964                    quote!(SelfRefSlot),
1965                    quote!(#lifetime, ::pin_init::__internal::Mutable, ),
1966                ),
1967            };
1968
1969            quote! {
1970                /// # Safety
1971                ///
1972                /// - `slot` is valid and properly aligned.
1973                /// - `(*slot).#field_name` is properly aligned.
1974                /// - `(*slot).#field_name` points to uninitialized and exclusively accessed
1975                ///   memory.
1976                // Allow `non_snake_case` since the same warning will be emitted on
1977                // the struct definition.
1978                #[allow(non_snake_case)]
1979                #[inline(always)]
1980                #vis unsafe fn #field_name(
1981                    self,
1982                    slot: *mut #struct_name #ty_generics,
1983                ) -> ::pin_init::__internal::#slot_ty<
1984                    #slot_arg ::pin_init::__internal::#pin_marker, #ty
1985                > {
1986                    // CAST: `as _` is needed to convert types wrapped inside `SelfRef`.
1987                    // SAFETY:
1988                    // - If `#pin_marker` is `Pinned`, the corresponding field is structurally
1989                    //   pinned.
1990                    // - Other safety requirements follows the safety requirement.
1991                    // - If `#slot_ty` is `SelfRefSlot`, the lifetime `#lt` represents that of the
1992                    //   field.
1993                    unsafe { ::pin_init::__internal::#slot_ty::new(&raw mut (*slot).#member as _) }
1994                }
1995            }
1996        })
1997        .collect::<TokenStream>();
1998
1999    let exist_lt_generics_params = info.exist_lts_generics.params.iter();
2000    quote! {
2001        // We declare this struct which will host all of the projection function for our type.
2002        #[doc(hidden)]
2003        #[allow(non_snake_case, explicit_outlives_requirements)]
2004        #vis struct __PinDataLt #generics_with_field_lt
2005            #whr_with_field_lt
2006        {
2007            #(#phantom_fields)*
2008            __pin_phantom: ::core::marker::PhantomData<#struct_name #ty_generics>,
2009        }
2010
2011        impl #impl_generics_with_lt ::core::clone::Clone for __PinDataLt #ty_generics_with_field_lt
2012            #whr_with_field_lt
2013        {
2014            fn clone(&self) -> Self { *self }
2015        }
2016
2017        impl #impl_generics_with_lt ::core::marker::Copy for __PinDataLt #ty_generics_with_field_lt
2018            #whr_with_field_lt
2019        {}
2020
2021        #[allow(dead_code)] // Some functions might never be used and private.
2022        #[expect(clippy::missing_safety_doc)]
2023        impl #impl_generics_with_lt __PinDataLt #ty_generics_with_field_lt
2024            #whr_with_field_lt
2025        {
2026            #field_accessors
2027        }
2028
2029        // Declare a type that serves as the entry point of interaction with the `pin_init!` macro.
2030        // We use this type instead of defining methods directly on user's type to avoid possibility
2031        // of name conflicts.
2032        #[doc(hidden)]
2033        #vis struct __ThePinData #generics
2034            #whr
2035        {
2036            __phantom: ::pin_init::__internal::PhantomInvariant<#struct_name #ty_generics>,
2037        }
2038
2039        impl #impl_generics ::core::clone::Clone for __ThePinData #ty_generics
2040            #whr
2041        {
2042            #[inline]
2043            fn clone(&self) -> Self { *self }
2044        }
2045
2046        impl #impl_generics ::core::marker::Copy for __ThePinData #ty_generics
2047            #whr
2048        {}
2049
2050        impl #impl_generics __ThePinData #ty_generics
2051            #whr
2052        {
2053            /// Type inference helper function.
2054            #[inline(always)]
2055            #vis fn __make_closure<#(#exist_lt_generics_params,)* __F, __E>(self, f: __F) -> __F
2056            where
2057                __F: for #field_lt_ty_generics ::core::ops::FnOnce(
2058                    *mut #struct_name #ty_generics,
2059                    __PinDataLt #ty_generics_with_field_lt
2060                ) -> ::core::result::Result<::pin_init::__internal::InitOk, __E>,
2061            {
2062                f
2063            }
2064
2065            #[inline(always)]
2066            #vis fn __with_lt #field_exist_lt_ty_generics(self)
2067                -> __PinDataLt #ty_generics_with_field_lt
2068            {
2069                // Generate a zeroed to avoid naming all fields.
2070                // SAFETY: `__PinDataLt` only contains phantom fields.
2071                unsafe { ::core::mem::zeroed() }
2072            }
2073        }
2074
2075        // SAFETY: We have added the correct projection functions above to `__ThePinData` and
2076        // we also use the least restrictive generics possible.
2077        unsafe impl #impl_generics ::pin_init::__internal::HasPinData for #struct_name #ty_generics
2078            #whr
2079        {
2080            type PinData = __ThePinData #ty_generics;
2081
2082            #[inline]
2083            fn __pin_data(_: ::pin_init::__internal::InitData<Self>) -> Self::PinData {
2084                __ThePinData { __phantom: ::pin_init::__internal::PhantomInvariant::new() }
2085            }
2086        }
2087    }
2088}
2089
2090struct SelfReplacer(PathSegment);
2091
2092impl VisitMut for SelfReplacer {
2093    fn visit_path_mut(&mut self, i: &mut syn::Path) {
2094        if i.is_ident("Self") {
2095            let span = i.span();
2096            let seg = &self.0;
2097            *i = parse_quote_spanned!(span=> #seg);
2098        } else {
2099            syn::visit_mut::visit_path_mut(self, i);
2100        }
2101    }
2102
2103    fn visit_path_segment_mut(&mut self, seg: &mut PathSegment) {
2104        if seg.ident == "Self" {
2105            let span = seg.span();
2106            let this = &self.0;
2107            *seg = parse_quote_spanned!(span=> #this);
2108        } else {
2109            syn::visit_mut::visit_path_segment_mut(self, seg);
2110        }
2111    }
2112
2113    fn visit_item_mut(&mut self, _: &mut Item) {
2114        // Do not descend into items, since items reset/change what `Self` refers to.
2115    }
2116}