xref: /linux/rust/pin-init/internal/src/pin_data.rs (revision 12d5fc96ebbb3b948861805b32a4c3a96105ccd9)
1 // SPDX-License-Identifier: Apache-2.0 OR MIT
2 
3 use std::collections::{BTreeMap, BTreeSet};
4 
5 use proc_macro2::{Span, TokenStream};
6 use quote::{format_ident, quote, quote_spanned, ToTokens};
7 use 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 
19 use crate::{
20     diagnostics::{DiagCtxt, ErrorGuaranteed},
21     util::*,
22 };
23 
24 pub(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 
31 pub(crate) enum Args {
32     Nothing(Nothing),
33     #[allow(dead_code)]
34     PinnedDrop(kw::PinnedDrop),
35 }
36 
37 impl 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 
50 impl 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)]
61 enum BorrowedKind {
62     /// `#[borrowed]`, or implicitly inferreed.
63     #[default]
64     Shared,
65     // `#[borrowed(mut)]`.
66     Mutable,
67 }
68 
69 impl 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.
92 struct 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)]
101 enum Variance {
102     /// `covariant` annotation, or implicitly inferred.
103     #[default]
104     Covariant,
105     // `invariant` annotation.
106     Invariant,
107 }
108 
109 impl 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.
136 struct Capture {
137     variance: Variance,
138     /// Lifetime to be captured.
139     lifetime: Lifetime,
140 }
141 
142 impl std::borrow::Borrow<Lifetime> for Capture {
143     fn borrow(&self) -> &Lifetime {
144         &self.lifetime
145     }
146 }
147 
148 impl PartialEq for Capture {
149     fn eq(&self, other: &Self) -> bool {
150         self.lifetime == other.lifetime
151     }
152 }
153 
154 impl Eq for Capture {}
155 
156 impl PartialOrd for Capture {
157     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
158         Some(self.cmp(other))
159     }
160 }
161 
162 impl Ord for Capture {
163     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
164         self.lifetime.cmp(&other.lifetime)
165     }
166 }
167 
168 impl 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 
182 impl 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)]
231 struct 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 
241 struct 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 
259 pub(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 
328 fn 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 
791 fn 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 
815 struct ExistLt {
816     lifetime: Lifetime,
817     bounds: Vec<Lifetime>,
818 }
819 
820 impl std::borrow::Borrow<Lifetime> for ExistLt {
821     fn borrow(&self) -> &Lifetime {
822         &self.lifetime
823     }
824 }
825 
826 impl PartialEq for ExistLt {
827     fn eq(&self, other: &Self) -> bool {
828         self.lifetime == other.lifetime
829     }
830 }
831 
832 impl Eq for ExistLt {}
833 
834 impl PartialOrd for ExistLt {
835     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
836         Some(self.cmp(other))
837     }
838 }
839 
840 impl Ord for ExistLt {
841     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
842         self.lifetime.cmp(&other.lifetime)
843     }
844 }
845 
846 impl 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 
938 fn 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 
1035 fn 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 
1090 fn 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 
1140 fn 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.
1263 fn 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 
1333 fn 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 
1866 fn 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 
2090 struct SelfReplacer(PathSegment);
2091 
2092 impl 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 }
2117