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(<.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(<) { 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(<.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(<) { 503 return; 504 } 505 506 if field_idx_map.contains_key(<.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 = ¶m.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 = ¶m.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