1use std::borrow::Cow;
22use std::sync::Arc;
23use std::{cmp, fmt};
24
25pub use GenericArgs::*;
26pub use UnsafeSource::*;
27pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
28use rustc_data_structures::packed::Pu128;
29use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30use rustc_data_structures::stack::ensure_sufficient_stack;
31use rustc_data_structures::tagged_ptr::Tag;
32use rustc_macros::{Decodable, Encodable, HashStable_Generic};
33pub use rustc_span::AttrId;
34use rustc_span::source_map::{Spanned, respan};
35use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
36use thin_vec::{ThinVec, thin_vec};
37
38pub use crate::format::*;
39use crate::ptr::P;
40use crate::token::{self, CommentKind, Delimiter};
41use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42use crate::util::parser::{ExprPrecedence, Fixity};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
55pub struct Label {
56 pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "label({:?})", self.ident)
62 }
63}
64
65#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
68pub struct Lifetime {
69 pub id: NodeId,
70 pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "lifetime({}: {})", self.id, self)
76 }
77}
78
79impl fmt::Display for Lifetime {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}", self.ident.name)
82 }
83}
84
85#[derive(Clone, Encodable, Decodable, Debug)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
101 #[inline]
102 fn eq(&self, symbol: &Symbol) -> bool {
103 matches!(&self.segments[..], [segment] if segment.ident.name == *symbol)
104 }
105}
106
107impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
108 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
109 self.segments.len().hash_stable(hcx, hasher);
110 for segment in &self.segments {
111 segment.ident.hash_stable(hcx, hasher);
112 }
113 }
114}
115
116impl Path {
117 pub fn from_ident(ident: Ident) -> Path {
120 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
121 }
122
123 pub fn is_ident(&self, name: Symbol) -> bool {
124 if let [segment] = self.segments.as_ref()
125 && segment.args.is_none()
126 && segment.ident.name == name
127 {
128 true
129 } else {
130 false
131 }
132 }
133
134 pub fn is_global(&self) -> bool {
135 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
136 }
137
138 #[tracing::instrument(level = "debug", ret)]
148 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
149 allow_mgca_arg
150 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
151 }
152}
153
154#[derive(Clone, Encodable, Decodable, Debug)]
158pub struct PathSegment {
159 pub ident: Ident,
161
162 pub id: NodeId,
163
164 pub args: Option<P<GenericArgs>>,
171}
172
173impl PathSegment {
174 pub fn from_ident(ident: Ident) -> Self {
175 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
176 }
177
178 pub fn path_root(span: Span) -> Self {
179 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
180 }
181
182 pub fn span(&self) -> Span {
183 match &self.args {
184 Some(args) => self.ident.span.to(args.span()),
185 None => self.ident.span,
186 }
187 }
188}
189
190#[derive(Clone, Encodable, Decodable, Debug)]
194pub enum GenericArgs {
195 AngleBracketed(AngleBracketedArgs),
197 Parenthesized(ParenthesizedArgs),
199 ParenthesizedElided(Span),
201}
202
203impl GenericArgs {
204 pub fn is_angle_bracketed(&self) -> bool {
205 matches!(self, AngleBracketed(..))
206 }
207
208 pub fn span(&self) -> Span {
209 match self {
210 AngleBracketed(data) => data.span,
211 Parenthesized(data) => data.span,
212 ParenthesizedElided(span) => *span,
213 }
214 }
215}
216
217#[derive(Clone, Encodable, Decodable, Debug)]
219pub enum GenericArg {
220 Lifetime(Lifetime),
222 Type(P<Ty>),
224 Const(AnonConst),
226}
227
228impl GenericArg {
229 pub fn span(&self) -> Span {
230 match self {
231 GenericArg::Lifetime(lt) => lt.ident.span,
232 GenericArg::Type(ty) => ty.span,
233 GenericArg::Const(ct) => ct.value.span,
234 }
235 }
236}
237
238#[derive(Clone, Encodable, Decodable, Debug, Default)]
240pub struct AngleBracketedArgs {
241 pub span: Span,
243 pub args: ThinVec<AngleBracketedArg>,
245}
246
247#[derive(Clone, Encodable, Decodable, Debug)]
249pub enum AngleBracketedArg {
250 Arg(GenericArg),
252 Constraint(AssocItemConstraint),
254}
255
256impl AngleBracketedArg {
257 pub fn span(&self) -> Span {
258 match self {
259 AngleBracketedArg::Arg(arg) => arg.span(),
260 AngleBracketedArg::Constraint(constraint) => constraint.span,
261 }
262 }
263}
264
265impl From<AngleBracketedArgs> for P<GenericArgs> {
266 fn from(val: AngleBracketedArgs) -> Self {
267 P(GenericArgs::AngleBracketed(val))
268 }
269}
270
271impl From<ParenthesizedArgs> for P<GenericArgs> {
272 fn from(val: ParenthesizedArgs) -> Self {
273 P(GenericArgs::Parenthesized(val))
274 }
275}
276
277#[derive(Clone, Encodable, Decodable, Debug)]
279pub struct ParenthesizedArgs {
280 pub span: Span,
285
286 pub inputs: ThinVec<P<Ty>>,
288
289 pub inputs_span: Span,
294
295 pub output: FnRetTy,
297}
298
299impl ParenthesizedArgs {
300 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
301 let args = self
302 .inputs
303 .iter()
304 .cloned()
305 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
306 .collect();
307 AngleBracketedArgs { span: self.inputs_span, args }
308 }
309}
310
311pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
312
313#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
315pub struct TraitBoundModifiers {
316 pub constness: BoundConstness,
317 pub asyncness: BoundAsyncness,
318 pub polarity: BoundPolarity,
319}
320
321impl TraitBoundModifiers {
322 pub const NONE: Self = Self {
323 constness: BoundConstness::Never,
324 asyncness: BoundAsyncness::Normal,
325 polarity: BoundPolarity::Positive,
326 };
327}
328
329#[derive(Clone, Encodable, Decodable, Debug)]
330pub enum GenericBound {
331 Trait(PolyTraitRef),
332 Outlives(Lifetime),
333 Use(ThinVec<PreciseCapturingArg>, Span),
335}
336
337impl GenericBound {
338 pub fn span(&self) -> Span {
339 match self {
340 GenericBound::Trait(t, ..) => t.span,
341 GenericBound::Outlives(l) => l.ident.span,
342 GenericBound::Use(_, span) => *span,
343 }
344 }
345}
346
347pub type GenericBounds = Vec<GenericBound>;
348
349#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
353pub enum ParamKindOrd {
354 Lifetime,
355 TypeOrConst,
356}
357
358impl fmt::Display for ParamKindOrd {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 match self {
361 ParamKindOrd::Lifetime => "lifetime".fmt(f),
362 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
363 }
364 }
365}
366
367#[derive(Clone, Encodable, Decodable, Debug)]
368pub enum GenericParamKind {
369 Lifetime,
371 Type {
372 default: Option<P<Ty>>,
373 },
374 Const {
375 ty: P<Ty>,
376 kw_span: Span,
378 default: Option<AnonConst>,
380 },
381}
382
383#[derive(Clone, Encodable, Decodable, Debug)]
384pub struct GenericParam {
385 pub id: NodeId,
386 pub ident: Ident,
387 pub attrs: AttrVec,
388 pub bounds: GenericBounds,
389 pub is_placeholder: bool,
390 pub kind: GenericParamKind,
391 pub colon_span: Option<Span>,
392}
393
394impl GenericParam {
395 pub fn span(&self) -> Span {
396 match &self.kind {
397 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
398 self.ident.span
399 }
400 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
401 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
402 kw_span.to(default.value.span)
403 }
404 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
405 }
406 }
407}
408
409#[derive(Clone, Encodable, Decodable, Debug, Default)]
412pub struct Generics {
413 pub params: ThinVec<GenericParam>,
414 pub where_clause: WhereClause,
415 pub span: Span,
416}
417
418#[derive(Clone, Encodable, Decodable, Debug, Default)]
420pub struct WhereClause {
421 pub has_where_token: bool,
426 pub predicates: ThinVec<WherePredicate>,
427 pub span: Span,
428}
429
430impl WhereClause {
431 pub fn is_empty(&self) -> bool {
432 !self.has_where_token && self.predicates.is_empty()
433 }
434}
435
436#[derive(Clone, Encodable, Decodable, Debug)]
438pub struct WherePredicate {
439 pub attrs: AttrVec,
440 pub kind: WherePredicateKind,
441 pub id: NodeId,
442 pub span: Span,
443 pub is_placeholder: bool,
444}
445
446#[derive(Clone, Encodable, Decodable, Debug)]
448pub enum WherePredicateKind {
449 BoundPredicate(WhereBoundPredicate),
451 RegionPredicate(WhereRegionPredicate),
453 EqPredicate(WhereEqPredicate),
455}
456
457#[derive(Clone, Encodable, Decodable, Debug)]
461pub struct WhereBoundPredicate {
462 pub bound_generic_params: ThinVec<GenericParam>,
464 pub bounded_ty: P<Ty>,
466 pub bounds: GenericBounds,
468}
469
470#[derive(Clone, Encodable, Decodable, Debug)]
474pub struct WhereRegionPredicate {
475 pub lifetime: Lifetime,
476 pub bounds: GenericBounds,
477}
478
479#[derive(Clone, Encodable, Decodable, Debug)]
483pub struct WhereEqPredicate {
484 pub lhs_ty: P<Ty>,
485 pub rhs_ty: P<Ty>,
486}
487
488#[derive(Clone, Encodable, Decodable, Debug)]
489pub struct Crate {
490 pub attrs: AttrVec,
491 pub items: ThinVec<P<Item>>,
492 pub spans: ModSpans,
493 pub id: NodeId,
496 pub is_placeholder: bool,
497}
498
499#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
506pub struct MetaItem {
507 pub unsafety: Safety,
508 pub path: Path,
509 pub kind: MetaItemKind,
510 pub span: Span,
511}
512
513#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
515pub enum MetaItemKind {
516 Word,
520
521 List(ThinVec<MetaItemInner>),
525
526 NameValue(MetaItemLit),
530}
531
532#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
536pub enum MetaItemInner {
537 MetaItem(MetaItem),
539
540 Lit(MetaItemLit),
544}
545
546#[derive(Clone, Encodable, Decodable, Debug)]
550pub struct Block {
551 pub stmts: ThinVec<Stmt>,
553 pub id: NodeId,
554 pub rules: BlockCheckMode,
556 pub span: Span,
557 pub tokens: Option<LazyAttrTokenStream>,
558}
559
560#[derive(Clone, Encodable, Decodable, Debug)]
564pub struct Pat {
565 pub id: NodeId,
566 pub kind: PatKind,
567 pub span: Span,
568 pub tokens: Option<LazyAttrTokenStream>,
569}
570
571impl Pat {
572 pub fn to_ty(&self) -> Option<P<Ty>> {
575 let kind = match &self.kind {
576 PatKind::Missing => unreachable!(),
577 PatKind::Wild => TyKind::Infer,
579 PatKind::Ident(BindingMode::NONE, ident, None) => {
581 TyKind::Path(None, Path::from_ident(*ident))
582 }
583 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
584 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
585 PatKind::Ref(pat, mutbl) => {
587 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
588 }
589 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
592 pat.to_ty().map(TyKind::Slice)?
593 }
594 PatKind::Tuple(pats) => {
597 let mut tys = ThinVec::with_capacity(pats.len());
598 for pat in pats {
600 tys.push(pat.to_ty()?);
601 }
602 TyKind::Tup(tys)
603 }
604 _ => return None,
605 };
606
607 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
608 }
609
610 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
614 if !it(self) {
615 return;
616 }
617
618 match &self.kind {
619 PatKind::Ident(_, _, Some(p)) => p.walk(it),
621
622 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
624
625 PatKind::TupleStruct(_, _, s)
627 | PatKind::Tuple(s)
628 | PatKind::Slice(s)
629 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
630
631 PatKind::Box(s)
633 | PatKind::Deref(s)
634 | PatKind::Ref(s, _)
635 | PatKind::Paren(s)
636 | PatKind::Guard(s, _) => s.walk(it),
637
638 PatKind::Missing
640 | PatKind::Wild
641 | PatKind::Rest
642 | PatKind::Never
643 | PatKind::Expr(_)
644 | PatKind::Range(..)
645 | PatKind::Ident(..)
646 | PatKind::Path(..)
647 | PatKind::MacCall(_)
648 | PatKind::Err(_) => {}
649 }
650 }
651
652 pub fn is_rest(&self) -> bool {
654 matches!(self.kind, PatKind::Rest)
655 }
656
657 pub fn could_be_never_pattern(&self) -> bool {
660 let mut could_be_never_pattern = false;
661 self.walk(&mut |pat| match &pat.kind {
662 PatKind::Never | PatKind::MacCall(_) => {
663 could_be_never_pattern = true;
664 false
665 }
666 PatKind::Or(s) => {
667 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
668 false
669 }
670 _ => true,
671 });
672 could_be_never_pattern
673 }
674
675 pub fn contains_never_pattern(&self) -> bool {
678 let mut contains_never_pattern = false;
679 self.walk(&mut |pat| {
680 if matches!(pat.kind, PatKind::Never) {
681 contains_never_pattern = true;
682 }
683 true
684 });
685 contains_never_pattern
686 }
687
688 pub fn descr(&self) -> Option<String> {
690 match &self.kind {
691 PatKind::Missing => unreachable!(),
692 PatKind::Wild => Some("_".to_string()),
693 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
694 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
695 _ => None,
696 }
697 }
698}
699
700#[derive(Clone, Encodable, Decodable, Debug)]
706pub struct PatField {
707 pub ident: Ident,
709 pub pat: P<Pat>,
711 pub is_shorthand: bool,
712 pub attrs: AttrVec,
713 pub id: NodeId,
714 pub span: Span,
715 pub is_placeholder: bool,
716}
717
718#[derive(Clone, Copy, Debug, Eq, PartialEq)]
719#[derive(Encodable, Decodable, HashStable_Generic)]
720pub enum ByRef {
721 Yes(Mutability),
722 No,
723}
724
725impl ByRef {
726 #[must_use]
727 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
728 if let ByRef::Yes(old_mutbl) = &mut self {
729 *old_mutbl = cmp::min(*old_mutbl, mutbl);
730 }
731 self
732 }
733}
734
735#[derive(Clone, Copy, Debug, Eq, PartialEq)]
741#[derive(Encodable, Decodable, HashStable_Generic)]
742pub struct BindingMode(pub ByRef, pub Mutability);
743
744impl BindingMode {
745 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
746 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
747 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
748 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
749 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
750 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
751
752 pub fn prefix_str(self) -> &'static str {
753 match self {
754 Self::NONE => "",
755 Self::REF => "ref ",
756 Self::MUT => "mut ",
757 Self::REF_MUT => "ref mut ",
758 Self::MUT_REF => "mut ref ",
759 Self::MUT_REF_MUT => "mut ref mut ",
760 }
761 }
762}
763
764#[derive(Clone, Encodable, Decodable, Debug)]
765pub enum RangeEnd {
766 Included(RangeSyntax),
768 Excluded,
770}
771
772#[derive(Clone, Encodable, Decodable, Debug)]
773pub enum RangeSyntax {
774 DotDotDot,
776 DotDotEq,
778}
779
780#[derive(Clone, Encodable, Decodable, Debug)]
784pub enum PatKind {
785 Missing,
787
788 Wild,
790
791 Ident(BindingMode, Ident, Option<P<Pat>>),
796
797 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
799
800 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
802
803 Or(ThinVec<P<Pat>>),
806
807 Path(Option<P<QSelf>>, Path),
812
813 Tuple(ThinVec<P<Pat>>),
815
816 Box(P<Pat>),
818
819 Deref(P<Pat>),
821
822 Ref(P<Pat>, Mutability),
824
825 Expr(P<Expr>),
827
828 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
830
831 Slice(ThinVec<P<Pat>>),
833
834 Rest,
847
848 Never,
850
851 Guard(P<Pat>, P<Expr>),
853
854 Paren(P<Pat>),
856
857 MacCall(P<MacCall>),
859
860 Err(ErrorGuaranteed),
862}
863
864#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
866pub enum PatFieldsRest {
867 Rest,
869 Recovered(ErrorGuaranteed),
871 None,
873}
874
875#[derive(Clone, Copy, PartialEq, Eq, Debug)]
878#[derive(Encodable, Decodable, HashStable_Generic)]
879pub enum BorrowKind {
880 Ref,
884 Raw,
888}
889
890#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
891pub enum BinOpKind {
892 Add,
894 Sub,
896 Mul,
898 Div,
900 Rem,
902 And,
904 Or,
906 BitXor,
908 BitAnd,
910 BitOr,
912 Shl,
914 Shr,
916 Eq,
918 Lt,
920 Le,
922 Ne,
924 Ge,
926 Gt,
928}
929
930impl BinOpKind {
931 pub fn as_str(&self) -> &'static str {
932 use BinOpKind::*;
933 match self {
934 Add => "+",
935 Sub => "-",
936 Mul => "*",
937 Div => "/",
938 Rem => "%",
939 And => "&&",
940 Or => "||",
941 BitXor => "^",
942 BitAnd => "&",
943 BitOr => "|",
944 Shl => "<<",
945 Shr => ">>",
946 Eq => "==",
947 Lt => "<",
948 Le => "<=",
949 Ne => "!=",
950 Ge => ">=",
951 Gt => ">",
952 }
953 }
954
955 pub fn is_lazy(&self) -> bool {
956 matches!(self, BinOpKind::And | BinOpKind::Or)
957 }
958
959 pub fn precedence(&self) -> ExprPrecedence {
960 use BinOpKind::*;
961 match *self {
962 Mul | Div | Rem => ExprPrecedence::Product,
963 Add | Sub => ExprPrecedence::Sum,
964 Shl | Shr => ExprPrecedence::Shift,
965 BitAnd => ExprPrecedence::BitAnd,
966 BitXor => ExprPrecedence::BitXor,
967 BitOr => ExprPrecedence::BitOr,
968 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
969 And => ExprPrecedence::LAnd,
970 Or => ExprPrecedence::LOr,
971 }
972 }
973
974 pub fn fixity(&self) -> Fixity {
975 use BinOpKind::*;
976 match self {
977 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
978 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
979 Fixity::Left
980 }
981 }
982 }
983
984 pub fn is_comparison(self) -> bool {
985 use BinOpKind::*;
986 match self {
987 Eq | Ne | Lt | Le | Gt | Ge => true,
988 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
989 }
990 }
991
992 pub fn is_by_value(self) -> bool {
994 !self.is_comparison()
995 }
996}
997
998pub type BinOp = Spanned<BinOpKind>;
999
1000impl From<AssignOpKind> for BinOpKind {
1004 fn from(op: AssignOpKind) -> BinOpKind {
1005 match op {
1006 AssignOpKind::AddAssign => BinOpKind::Add,
1007 AssignOpKind::SubAssign => BinOpKind::Sub,
1008 AssignOpKind::MulAssign => BinOpKind::Mul,
1009 AssignOpKind::DivAssign => BinOpKind::Div,
1010 AssignOpKind::RemAssign => BinOpKind::Rem,
1011 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1012 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1013 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1014 AssignOpKind::ShlAssign => BinOpKind::Shl,
1015 AssignOpKind::ShrAssign => BinOpKind::Shr,
1016 }
1017 }
1018}
1019
1020#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1021pub enum AssignOpKind {
1022 AddAssign,
1024 SubAssign,
1026 MulAssign,
1028 DivAssign,
1030 RemAssign,
1032 BitXorAssign,
1034 BitAndAssign,
1036 BitOrAssign,
1038 ShlAssign,
1040 ShrAssign,
1042}
1043
1044impl AssignOpKind {
1045 pub fn as_str(&self) -> &'static str {
1046 use AssignOpKind::*;
1047 match self {
1048 AddAssign => "+=",
1049 SubAssign => "-=",
1050 MulAssign => "*=",
1051 DivAssign => "/=",
1052 RemAssign => "%=",
1053 BitXorAssign => "^=",
1054 BitAndAssign => "&=",
1055 BitOrAssign => "|=",
1056 ShlAssign => "<<=",
1057 ShrAssign => ">>=",
1058 }
1059 }
1060
1061 pub fn is_by_value(self) -> bool {
1063 true
1064 }
1065}
1066
1067pub type AssignOp = Spanned<AssignOpKind>;
1068
1069#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1073pub enum UnOp {
1074 Deref,
1076 Not,
1078 Neg,
1080}
1081
1082impl UnOp {
1083 pub fn as_str(&self) -> &'static str {
1084 match self {
1085 UnOp::Deref => "*",
1086 UnOp::Not => "!",
1087 UnOp::Neg => "-",
1088 }
1089 }
1090
1091 pub fn is_by_value(self) -> bool {
1093 matches!(self, Self::Neg | Self::Not)
1094 }
1095}
1096
1097#[derive(Clone, Encodable, Decodable, Debug)]
1101pub struct Stmt {
1102 pub id: NodeId,
1103 pub kind: StmtKind,
1104 pub span: Span,
1105}
1106
1107impl Stmt {
1108 pub fn has_trailing_semicolon(&self) -> bool {
1109 match &self.kind {
1110 StmtKind::Semi(_) => true,
1111 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1112 _ => false,
1113 }
1114 }
1115
1116 pub fn add_trailing_semicolon(mut self) -> Self {
1124 self.kind = match self.kind {
1125 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1126 StmtKind::MacCall(mac) => {
1127 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1128 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1129 }))
1130 }
1131 kind => kind,
1132 };
1133
1134 self
1135 }
1136
1137 pub fn is_item(&self) -> bool {
1138 matches!(self.kind, StmtKind::Item(_))
1139 }
1140
1141 pub fn is_expr(&self) -> bool {
1142 matches!(self.kind, StmtKind::Expr(_))
1143 }
1144}
1145
1146#[derive(Clone, Encodable, Decodable, Debug)]
1148pub enum StmtKind {
1149 Let(P<Local>),
1151 Item(P<Item>),
1153 Expr(P<Expr>),
1155 Semi(P<Expr>),
1157 Empty,
1159 MacCall(P<MacCallStmt>),
1161}
1162
1163#[derive(Clone, Encodable, Decodable, Debug)]
1164pub struct MacCallStmt {
1165 pub mac: P<MacCall>,
1166 pub style: MacStmtStyle,
1167 pub attrs: AttrVec,
1168 pub tokens: Option<LazyAttrTokenStream>,
1169}
1170
1171#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1172pub enum MacStmtStyle {
1173 Semicolon,
1176 Braces,
1178 NoBraces,
1182}
1183
1184#[derive(Clone, Encodable, Decodable, Debug)]
1186pub struct Local {
1187 pub id: NodeId,
1188 pub super_: Option<Span>,
1189 pub pat: P<Pat>,
1190 pub ty: Option<P<Ty>>,
1191 pub kind: LocalKind,
1192 pub span: Span,
1193 pub colon_sp: Option<Span>,
1194 pub attrs: AttrVec,
1195 pub tokens: Option<LazyAttrTokenStream>,
1196}
1197
1198#[derive(Clone, Encodable, Decodable, Debug)]
1199pub enum LocalKind {
1200 Decl,
1203 Init(P<Expr>),
1206 InitElse(P<Expr>, P<Block>),
1209}
1210
1211impl LocalKind {
1212 pub fn init(&self) -> Option<&Expr> {
1213 match self {
1214 Self::Decl => None,
1215 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1216 }
1217 }
1218
1219 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1220 match self {
1221 Self::Decl => None,
1222 Self::Init(init) => Some((init, None)),
1223 Self::InitElse(init, els) => Some((init, Some(els))),
1224 }
1225 }
1226}
1227
1228#[derive(Clone, Encodable, Decodable, Debug)]
1239pub struct Arm {
1240 pub attrs: AttrVec,
1241 pub pat: P<Pat>,
1243 pub guard: Option<P<Expr>>,
1245 pub body: Option<P<Expr>>,
1247 pub span: Span,
1248 pub id: NodeId,
1249 pub is_placeholder: bool,
1250}
1251
1252#[derive(Clone, Encodable, Decodable, Debug)]
1254pub struct ExprField {
1255 pub attrs: AttrVec,
1256 pub id: NodeId,
1257 pub span: Span,
1258 pub ident: Ident,
1259 pub expr: P<Expr>,
1260 pub is_shorthand: bool,
1261 pub is_placeholder: bool,
1262}
1263
1264#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1265pub enum BlockCheckMode {
1266 Default,
1267 Unsafe(UnsafeSource),
1268}
1269
1270#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1271pub enum UnsafeSource {
1272 CompilerGenerated,
1273 UserProvided,
1274}
1275
1276#[derive(Clone, Encodable, Decodable, Debug)]
1282pub struct AnonConst {
1283 pub id: NodeId,
1284 pub value: P<Expr>,
1285}
1286
1287#[derive(Clone, Encodable, Decodable, Debug)]
1289pub struct Expr {
1290 pub id: NodeId,
1291 pub kind: ExprKind,
1292 pub span: Span,
1293 pub attrs: AttrVec,
1294 pub tokens: Option<LazyAttrTokenStream>,
1295}
1296
1297impl Expr {
1298 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1312 let this = self.maybe_unwrap_block();
1313 if allow_mgca_arg {
1314 matches!(this.kind, ExprKind::Path(..))
1315 } else {
1316 if let ExprKind::Path(None, path) = &this.kind
1317 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1318 {
1319 true
1320 } else {
1321 false
1322 }
1323 }
1324 }
1325
1326 pub fn maybe_unwrap_block(&self) -> &Expr {
1328 if let ExprKind::Block(block, None) = &self.kind
1329 && let [stmt] = block.stmts.as_slice()
1330 && let StmtKind::Expr(expr) = &stmt.kind
1331 {
1332 expr
1333 } else {
1334 self
1335 }
1336 }
1337
1338 pub fn optionally_braced_mac_call(
1344 &self,
1345 already_stripped_block: bool,
1346 ) -> Option<(bool, NodeId)> {
1347 match &self.kind {
1348 ExprKind::Block(block, None)
1349 if let [stmt] = &*block.stmts
1350 && !already_stripped_block =>
1351 {
1352 match &stmt.kind {
1353 StmtKind::MacCall(_) => Some((true, stmt.id)),
1354 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1355 Some((true, expr.id))
1356 }
1357 _ => None,
1358 }
1359 }
1360 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1361 _ => None,
1362 }
1363 }
1364
1365 pub fn to_bound(&self) -> Option<GenericBound> {
1366 match &self.kind {
1367 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1368 ThinVec::new(),
1369 path.clone(),
1370 TraitBoundModifiers::NONE,
1371 self.span,
1372 ))),
1373 _ => None,
1374 }
1375 }
1376
1377 pub fn peel_parens(&self) -> &Expr {
1378 let mut expr = self;
1379 while let ExprKind::Paren(inner) = &expr.kind {
1380 expr = inner;
1381 }
1382 expr
1383 }
1384
1385 pub fn peel_parens_and_refs(&self) -> &Expr {
1386 let mut expr = self;
1387 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1388 {
1389 expr = inner;
1390 }
1391 expr
1392 }
1393
1394 pub fn to_ty(&self) -> Option<P<Ty>> {
1396 let kind = match &self.kind {
1397 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1399 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1400
1401 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1402
1403 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1404 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1405 }
1406
1407 ExprKind::Repeat(expr, expr_len) => {
1408 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1409 }
1410
1411 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1412 expr.to_ty().map(TyKind::Slice)?
1413 }
1414
1415 ExprKind::Tup(exprs) => {
1416 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1417 TyKind::Tup(tys)
1418 }
1419
1420 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1424 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1425 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1426 } else {
1427 return None;
1428 }
1429 }
1430
1431 ExprKind::Underscore => TyKind::Infer,
1432
1433 _ => return None,
1435 };
1436
1437 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1438 }
1439
1440 pub fn precedence(&self) -> ExprPrecedence {
1441 match &self.kind {
1442 ExprKind::Closure(closure) => {
1443 match closure.fn_decl.output {
1444 FnRetTy::Default(_) => ExprPrecedence::Jump,
1445 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1446 }
1447 }
1448
1449 ExprKind::Break(..)
1450 | ExprKind::Ret(..)
1451 | ExprKind::Yield(..)
1452 | ExprKind::Yeet(..)
1453 | ExprKind::Become(..) => ExprPrecedence::Jump,
1454
1455 ExprKind::Range(..) => ExprPrecedence::Range,
1460
1461 ExprKind::Binary(op, ..) => op.node.precedence(),
1463 ExprKind::Cast(..) => ExprPrecedence::Cast,
1464
1465 ExprKind::Assign(..) |
1466 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1467
1468 ExprKind::AddrOf(..)
1470 | ExprKind::Let(..)
1475 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1476
1477 ExprKind::Array(_)
1479 | ExprKind::Await(..)
1480 | ExprKind::Use(..)
1481 | ExprKind::Block(..)
1482 | ExprKind::Call(..)
1483 | ExprKind::ConstBlock(_)
1484 | ExprKind::Continue(..)
1485 | ExprKind::Field(..)
1486 | ExprKind::ForLoop { .. }
1487 | ExprKind::FormatArgs(..)
1488 | ExprKind::Gen(..)
1489 | ExprKind::If(..)
1490 | ExprKind::IncludedBytes(..)
1491 | ExprKind::Index(..)
1492 | ExprKind::InlineAsm(..)
1493 | ExprKind::Lit(_)
1494 | ExprKind::Loop(..)
1495 | ExprKind::MacCall(..)
1496 | ExprKind::Match(..)
1497 | ExprKind::MethodCall(..)
1498 | ExprKind::OffsetOf(..)
1499 | ExprKind::Paren(..)
1500 | ExprKind::Path(..)
1501 | ExprKind::Repeat(..)
1502 | ExprKind::Struct(..)
1503 | ExprKind::Try(..)
1504 | ExprKind::TryBlock(..)
1505 | ExprKind::Tup(_)
1506 | ExprKind::Type(..)
1507 | ExprKind::Underscore
1508 | ExprKind::UnsafeBinderCast(..)
1509 | ExprKind::While(..)
1510 | ExprKind::Err(_)
1511 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1512 }
1513 }
1514
1515 pub fn is_approximately_pattern(&self) -> bool {
1517 matches!(
1518 &self.peel_parens().kind,
1519 ExprKind::Array(_)
1520 | ExprKind::Call(_, _)
1521 | ExprKind::Tup(_)
1522 | ExprKind::Lit(_)
1523 | ExprKind::Range(_, _, _)
1524 | ExprKind::Underscore
1525 | ExprKind::Path(_, _)
1526 | ExprKind::Struct(_)
1527 )
1528 }
1529
1530 pub fn dummy() -> P<Expr> {
1534 P(Expr {
1535 id: DUMMY_NODE_ID,
1536 kind: ExprKind::Dummy,
1537 span: DUMMY_SP,
1538 attrs: ThinVec::new(),
1539 tokens: None,
1540 })
1541 }
1542}
1543
1544#[derive(Clone, Encodable, Decodable, Debug)]
1545pub struct Closure {
1546 pub binder: ClosureBinder,
1547 pub capture_clause: CaptureBy,
1548 pub constness: Const,
1549 pub coroutine_kind: Option<CoroutineKind>,
1550 pub movability: Movability,
1551 pub fn_decl: P<FnDecl>,
1552 pub body: P<Expr>,
1553 pub fn_decl_span: Span,
1555 pub fn_arg_span: Span,
1557}
1558
1559#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1561pub enum RangeLimits {
1562 HalfOpen,
1564 Closed,
1566}
1567
1568impl RangeLimits {
1569 pub fn as_str(&self) -> &'static str {
1570 match self {
1571 RangeLimits::HalfOpen => "..",
1572 RangeLimits::Closed => "..=",
1573 }
1574 }
1575}
1576
1577#[derive(Clone, Encodable, Decodable, Debug)]
1579pub struct MethodCall {
1580 pub seg: PathSegment,
1582 pub receiver: P<Expr>,
1584 pub args: ThinVec<P<Expr>>,
1586 pub span: Span,
1589}
1590
1591#[derive(Clone, Encodable, Decodable, Debug)]
1592pub enum StructRest {
1593 Base(P<Expr>),
1595 Rest(Span),
1597 None,
1599}
1600
1601#[derive(Clone, Encodable, Decodable, Debug)]
1602pub struct StructExpr {
1603 pub qself: Option<P<QSelf>>,
1604 pub path: Path,
1605 pub fields: ThinVec<ExprField>,
1606 pub rest: StructRest,
1607}
1608
1609#[derive(Clone, Encodable, Decodable, Debug)]
1611pub enum ExprKind {
1612 Array(ThinVec<P<Expr>>),
1614 ConstBlock(AnonConst),
1616 Call(P<Expr>, ThinVec<P<Expr>>),
1623 MethodCall(Box<MethodCall>),
1625 Tup(ThinVec<P<Expr>>),
1627 Binary(BinOp, P<Expr>, P<Expr>),
1629 Unary(UnOp, P<Expr>),
1631 Lit(token::Lit),
1633 Cast(P<Expr>, P<Ty>),
1635 Type(P<Expr>, P<Ty>),
1640 Let(P<Pat>, P<Expr>, Span, Recovered),
1645 If(P<Expr>, P<Block>, Option<P<Expr>>),
1652 While(P<Expr>, P<Block>, Option<Label>),
1656 ForLoop {
1662 pat: P<Pat>,
1663 iter: P<Expr>,
1664 body: P<Block>,
1665 label: Option<Label>,
1666 kind: ForLoopKind,
1667 },
1668 Loop(P<Block>, Option<Label>, Span),
1672 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1674 Closure(Box<Closure>),
1676 Block(P<Block>, Option<Label>),
1678 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1684 Await(P<Expr>, Span),
1686 Use(P<Expr>, Span),
1688
1689 TryBlock(P<Block>),
1691
1692 Assign(P<Expr>, P<Expr>, Span),
1695 AssignOp(AssignOp, P<Expr>, P<Expr>),
1699 Field(P<Expr>, Ident),
1701 Index(P<Expr>, P<Expr>, Span),
1704 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1706 Underscore,
1708
1709 Path(Option<P<QSelf>>, Path),
1714
1715 AddrOf(BorrowKind, Mutability, P<Expr>),
1717 Break(Option<Label>, Option<P<Expr>>),
1719 Continue(Option<Label>),
1721 Ret(Option<P<Expr>>),
1723
1724 InlineAsm(P<InlineAsm>),
1726
1727 OffsetOf(P<Ty>, P<[Ident]>),
1732
1733 MacCall(P<MacCall>),
1735
1736 Struct(P<StructExpr>),
1740
1741 Repeat(P<Expr>, AnonConst),
1746
1747 Paren(P<Expr>),
1749
1750 Try(P<Expr>),
1752
1753 Yield(YieldKind),
1755
1756 Yeet(Option<P<Expr>>),
1759
1760 Become(P<Expr>),
1764
1765 IncludedBytes(Arc<[u8]>),
1770
1771 FormatArgs(P<FormatArgs>),
1773
1774 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1775
1776 Err(ErrorGuaranteed),
1778
1779 Dummy,
1781}
1782
1783#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1785pub enum ForLoopKind {
1786 For,
1787 ForAwait,
1788}
1789
1790#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1792pub enum GenBlockKind {
1793 Async,
1794 Gen,
1795 AsyncGen,
1796}
1797
1798impl fmt::Display for GenBlockKind {
1799 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1800 self.modifier().fmt(f)
1801 }
1802}
1803
1804impl GenBlockKind {
1805 pub fn modifier(&self) -> &'static str {
1806 match self {
1807 GenBlockKind::Async => "async",
1808 GenBlockKind::Gen => "gen",
1809 GenBlockKind::AsyncGen => "async gen",
1810 }
1811 }
1812}
1813
1814#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1816#[derive(Encodable, Decodable, HashStable_Generic)]
1817pub enum UnsafeBinderCastKind {
1818 Wrap,
1820 Unwrap,
1822}
1823
1824#[derive(Clone, Encodable, Decodable, Debug)]
1839pub struct QSelf {
1840 pub ty: P<Ty>,
1841
1842 pub path_span: Span,
1846 pub position: usize,
1847}
1848
1849#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1851pub enum CaptureBy {
1852 Value {
1854 move_kw: Span,
1856 },
1857 Ref,
1859 Use {
1865 use_kw: Span,
1867 },
1868}
1869
1870#[derive(Clone, Encodable, Decodable, Debug)]
1872pub enum ClosureBinder {
1873 NotPresent,
1875 For {
1877 span: Span,
1884
1885 generic_params: ThinVec<GenericParam>,
1892 },
1893}
1894
1895#[derive(Clone, Encodable, Decodable, Debug)]
1898pub struct MacCall {
1899 pub path: Path,
1900 pub args: P<DelimArgs>,
1901}
1902
1903impl MacCall {
1904 pub fn span(&self) -> Span {
1905 self.path.span.to(self.args.dspan.entire())
1906 }
1907}
1908
1909#[derive(Clone, Encodable, Decodable, Debug)]
1911pub enum AttrArgs {
1912 Empty,
1914 Delimited(DelimArgs),
1916 Eq {
1918 eq_span: Span,
1920 expr: P<Expr>,
1921 },
1922}
1923
1924impl AttrArgs {
1925 pub fn span(&self) -> Option<Span> {
1926 match self {
1927 AttrArgs::Empty => None,
1928 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1929 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1930 }
1931 }
1932
1933 pub fn inner_tokens(&self) -> TokenStream {
1936 match self {
1937 AttrArgs::Empty => TokenStream::default(),
1938 AttrArgs::Delimited(args) => args.tokens.clone(),
1939 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1940 }
1941 }
1942}
1943
1944#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1946pub struct DelimArgs {
1947 pub dspan: DelimSpan,
1948 pub delim: Delimiter, pub tokens: TokenStream,
1950}
1951
1952impl DelimArgs {
1953 pub fn need_semicolon(&self) -> bool {
1956 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1957 }
1958}
1959
1960#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1962pub struct MacroDef {
1963 pub body: P<DelimArgs>,
1964 pub macro_rules: bool,
1966}
1967
1968#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1969#[derive(HashStable_Generic)]
1970pub enum StrStyle {
1971 Cooked,
1973 Raw(u8),
1977}
1978
1979#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1981pub enum MatchKind {
1982 Prefix,
1984 Postfix,
1986}
1987
1988#[derive(Clone, Encodable, Decodable, Debug)]
1990pub enum YieldKind {
1991 Prefix(Option<P<Expr>>),
1993 Postfix(P<Expr>),
1995}
1996
1997impl YieldKind {
1998 pub const fn expr(&self) -> Option<&P<Expr>> {
2002 match self {
2003 YieldKind::Prefix(expr) => expr.as_ref(),
2004 YieldKind::Postfix(expr) => Some(expr),
2005 }
2006 }
2007
2008 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2010 match self {
2011 YieldKind::Prefix(expr) => expr.as_mut(),
2012 YieldKind::Postfix(expr) => Some(expr),
2013 }
2014 }
2015
2016 pub const fn same_kind(&self, other: &Self) -> bool {
2018 match (self, other) {
2019 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2020 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2021 _ => false,
2022 }
2023 }
2024}
2025
2026#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2028pub struct MetaItemLit {
2029 pub symbol: Symbol,
2031 pub suffix: Option<Symbol>,
2033 pub kind: LitKind,
2036 pub span: Span,
2037}
2038
2039#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2041pub struct StrLit {
2042 pub symbol: Symbol,
2044 pub suffix: Option<Symbol>,
2046 pub symbol_unescaped: Symbol,
2048 pub style: StrStyle,
2049 pub span: Span,
2050}
2051
2052impl StrLit {
2053 pub fn as_token_lit(&self) -> token::Lit {
2054 let token_kind = match self.style {
2055 StrStyle::Cooked => token::Str,
2056 StrStyle::Raw(n) => token::StrRaw(n),
2057 };
2058 token::Lit::new(token_kind, self.symbol, self.suffix)
2059 }
2060}
2061
2062#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2064#[derive(HashStable_Generic)]
2065pub enum LitIntType {
2066 Signed(IntTy),
2068 Unsigned(UintTy),
2070 Unsuffixed,
2072}
2073
2074#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2076#[derive(HashStable_Generic)]
2077pub enum LitFloatType {
2078 Suffixed(FloatTy),
2080 Unsuffixed,
2082}
2083
2084#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2091pub enum LitKind {
2092 Str(Symbol, StrStyle),
2095 ByteStr(Arc<[u8]>, StrStyle),
2098 CStr(Arc<[u8]>, StrStyle),
2100 Byte(u8),
2102 Char(char),
2104 Int(Pu128, LitIntType),
2106 Float(Symbol, LitFloatType),
2110 Bool(bool),
2112 Err(ErrorGuaranteed),
2114}
2115
2116impl LitKind {
2117 pub fn str(&self) -> Option<Symbol> {
2118 match *self {
2119 LitKind::Str(s, _) => Some(s),
2120 _ => None,
2121 }
2122 }
2123
2124 pub fn is_str(&self) -> bool {
2126 matches!(self, LitKind::Str(..))
2127 }
2128
2129 pub fn is_bytestr(&self) -> bool {
2131 matches!(self, LitKind::ByteStr(..))
2132 }
2133
2134 pub fn is_numeric(&self) -> bool {
2136 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2137 }
2138
2139 pub fn is_unsuffixed(&self) -> bool {
2142 !self.is_suffixed()
2143 }
2144
2145 pub fn is_suffixed(&self) -> bool {
2147 match *self {
2148 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2150 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2151 LitKind::Str(..)
2153 | LitKind::ByteStr(..)
2154 | LitKind::CStr(..)
2155 | LitKind::Byte(..)
2156 | LitKind::Char(..)
2157 | LitKind::Int(_, LitIntType::Unsuffixed)
2158 | LitKind::Float(_, LitFloatType::Unsuffixed)
2159 | LitKind::Bool(..)
2160 | LitKind::Err(_) => false,
2161 }
2162 }
2163}
2164
2165#[derive(Clone, Encodable, Decodable, Debug)]
2168pub struct MutTy {
2169 pub ty: P<Ty>,
2170 pub mutbl: Mutability,
2171}
2172
2173#[derive(Clone, Encodable, Decodable, Debug)]
2176pub struct FnSig {
2177 pub header: FnHeader,
2178 pub decl: P<FnDecl>,
2179 pub span: Span,
2180}
2181
2182#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2183#[derive(Encodable, Decodable, HashStable_Generic)]
2184pub enum FloatTy {
2185 F16,
2186 F32,
2187 F64,
2188 F128,
2189}
2190
2191impl FloatTy {
2192 pub fn name_str(self) -> &'static str {
2193 match self {
2194 FloatTy::F16 => "f16",
2195 FloatTy::F32 => "f32",
2196 FloatTy::F64 => "f64",
2197 FloatTy::F128 => "f128",
2198 }
2199 }
2200
2201 pub fn name(self) -> Symbol {
2202 match self {
2203 FloatTy::F16 => sym::f16,
2204 FloatTy::F32 => sym::f32,
2205 FloatTy::F64 => sym::f64,
2206 FloatTy::F128 => sym::f128,
2207 }
2208 }
2209}
2210
2211#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2212#[derive(Encodable, Decodable, HashStable_Generic)]
2213pub enum IntTy {
2214 Isize,
2215 I8,
2216 I16,
2217 I32,
2218 I64,
2219 I128,
2220}
2221
2222impl IntTy {
2223 pub fn name_str(&self) -> &'static str {
2224 match *self {
2225 IntTy::Isize => "isize",
2226 IntTy::I8 => "i8",
2227 IntTy::I16 => "i16",
2228 IntTy::I32 => "i32",
2229 IntTy::I64 => "i64",
2230 IntTy::I128 => "i128",
2231 }
2232 }
2233
2234 pub fn name(&self) -> Symbol {
2235 match *self {
2236 IntTy::Isize => sym::isize,
2237 IntTy::I8 => sym::i8,
2238 IntTy::I16 => sym::i16,
2239 IntTy::I32 => sym::i32,
2240 IntTy::I64 => sym::i64,
2241 IntTy::I128 => sym::i128,
2242 }
2243 }
2244}
2245
2246#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2247#[derive(Encodable, Decodable, HashStable_Generic)]
2248pub enum UintTy {
2249 Usize,
2250 U8,
2251 U16,
2252 U32,
2253 U64,
2254 U128,
2255}
2256
2257impl UintTy {
2258 pub fn name_str(&self) -> &'static str {
2259 match *self {
2260 UintTy::Usize => "usize",
2261 UintTy::U8 => "u8",
2262 UintTy::U16 => "u16",
2263 UintTy::U32 => "u32",
2264 UintTy::U64 => "u64",
2265 UintTy::U128 => "u128",
2266 }
2267 }
2268
2269 pub fn name(&self) -> Symbol {
2270 match *self {
2271 UintTy::Usize => sym::usize,
2272 UintTy::U8 => sym::u8,
2273 UintTy::U16 => sym::u16,
2274 UintTy::U32 => sym::u32,
2275 UintTy::U64 => sym::u64,
2276 UintTy::U128 => sym::u128,
2277 }
2278 }
2279}
2280
2281#[derive(Clone, Encodable, Decodable, Debug)]
2292pub struct AssocItemConstraint {
2293 pub id: NodeId,
2294 pub ident: Ident,
2295 pub gen_args: Option<GenericArgs>,
2296 pub kind: AssocItemConstraintKind,
2297 pub span: Span,
2298}
2299
2300#[derive(Clone, Encodable, Decodable, Debug)]
2301pub enum Term {
2302 Ty(P<Ty>),
2303 Const(AnonConst),
2304}
2305
2306impl From<P<Ty>> for Term {
2307 fn from(v: P<Ty>) -> Self {
2308 Term::Ty(v)
2309 }
2310}
2311
2312impl From<AnonConst> for Term {
2313 fn from(v: AnonConst) -> Self {
2314 Term::Const(v)
2315 }
2316}
2317
2318#[derive(Clone, Encodable, Decodable, Debug)]
2320pub enum AssocItemConstraintKind {
2321 Equality { term: Term },
2328 Bound { bounds: GenericBounds },
2330}
2331
2332#[derive(Encodable, Decodable, Debug)]
2333pub struct Ty {
2334 pub id: NodeId,
2335 pub kind: TyKind,
2336 pub span: Span,
2337 pub tokens: Option<LazyAttrTokenStream>,
2338}
2339
2340impl Clone for Ty {
2341 fn clone(&self) -> Self {
2342 ensure_sufficient_stack(|| Self {
2343 id: self.id,
2344 kind: self.kind.clone(),
2345 span: self.span,
2346 tokens: self.tokens.clone(),
2347 })
2348 }
2349}
2350
2351impl Ty {
2352 pub fn peel_refs(&self) -> &Self {
2353 let mut final_ty = self;
2354 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2355 {
2356 final_ty = ty;
2357 }
2358 final_ty
2359 }
2360
2361 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2362 match &self.kind {
2363 TyKind::Infer => true,
2364 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2365 _ => false,
2366 }
2367 }
2368}
2369
2370#[derive(Clone, Encodable, Decodable, Debug)]
2371pub struct BareFnTy {
2372 pub safety: Safety,
2373 pub ext: Extern,
2374 pub generic_params: ThinVec<GenericParam>,
2375 pub decl: P<FnDecl>,
2376 pub decl_span: Span,
2379}
2380
2381#[derive(Clone, Encodable, Decodable, Debug)]
2382pub struct UnsafeBinderTy {
2383 pub generic_params: ThinVec<GenericParam>,
2384 pub inner_ty: P<Ty>,
2385}
2386
2387#[derive(Clone, Encodable, Decodable, Debug)]
2391pub enum TyKind {
2392 Slice(P<Ty>),
2394 Array(P<Ty>, AnonConst),
2396 Ptr(MutTy),
2398 Ref(Option<Lifetime>, MutTy),
2400 PinnedRef(Option<Lifetime>, MutTy),
2404 BareFn(P<BareFnTy>),
2406 UnsafeBinder(P<UnsafeBinderTy>),
2408 Never,
2410 Tup(ThinVec<P<Ty>>),
2412 Path(Option<P<QSelf>>, Path),
2417 TraitObject(GenericBounds, TraitObjectSyntax),
2420 ImplTrait(NodeId, GenericBounds),
2427 Paren(P<Ty>),
2429 Typeof(AnonConst),
2431 Infer,
2434 ImplicitSelf,
2436 MacCall(P<MacCall>),
2438 CVarArgs,
2440 Pat(P<Ty>, P<TyPat>),
2443 Dummy,
2445 Err(ErrorGuaranteed),
2447}
2448
2449impl TyKind {
2450 pub fn is_implicit_self(&self) -> bool {
2451 matches!(self, TyKind::ImplicitSelf)
2452 }
2453
2454 pub fn is_unit(&self) -> bool {
2455 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2456 }
2457
2458 pub fn is_simple_path(&self) -> Option<Symbol> {
2459 if let TyKind::Path(None, Path { segments, .. }) = &self
2460 && let [segment] = &segments[..]
2461 && segment.args.is_none()
2462 {
2463 Some(segment.ident.name)
2464 } else {
2465 None
2466 }
2467 }
2468
2469 pub fn maybe_scalar(&self) -> bool {
2477 let Some(ty_sym) = self.is_simple_path() else {
2478 return self.is_unit();
2480 };
2481 matches!(
2482 ty_sym,
2483 sym::i8
2484 | sym::i16
2485 | sym::i32
2486 | sym::i64
2487 | sym::i128
2488 | sym::u8
2489 | sym::u16
2490 | sym::u32
2491 | sym::u64
2492 | sym::u128
2493 | sym::f16
2494 | sym::f32
2495 | sym::f64
2496 | sym::f128
2497 | sym::char
2498 | sym::bool
2499 )
2500 }
2501}
2502
2503#[derive(Clone, Encodable, Decodable, Debug)]
2505pub struct TyPat {
2506 pub id: NodeId,
2507 pub kind: TyPatKind,
2508 pub span: Span,
2509 pub tokens: Option<LazyAttrTokenStream>,
2510}
2511
2512#[derive(Clone, Encodable, Decodable, Debug)]
2516pub enum TyPatKind {
2517 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2519
2520 Or(ThinVec<P<TyPat>>),
2521
2522 Err(ErrorGuaranteed),
2524}
2525
2526#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2528#[repr(u8)]
2529pub enum TraitObjectSyntax {
2530 Dyn = 0,
2532 DynStar = 1,
2533 None = 2,
2534}
2535
2536unsafe impl Tag for TraitObjectSyntax {
2540 const BITS: u32 = 2;
2541
2542 fn into_usize(self) -> usize {
2543 self as u8 as usize
2544 }
2545
2546 unsafe fn from_usize(tag: usize) -> Self {
2547 match tag {
2548 0 => TraitObjectSyntax::Dyn,
2549 1 => TraitObjectSyntax::DynStar,
2550 2 => TraitObjectSyntax::None,
2551 _ => unreachable!(),
2552 }
2553 }
2554}
2555
2556#[derive(Clone, Encodable, Decodable, Debug)]
2557pub enum PreciseCapturingArg {
2558 Lifetime(Lifetime),
2560 Arg(Path, NodeId),
2562}
2563
2564#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2568pub enum InlineAsmRegOrRegClass {
2569 Reg(Symbol),
2570 RegClass(Symbol),
2571}
2572
2573#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2574pub struct InlineAsmOptions(u16);
2575bitflags::bitflags! {
2576 impl InlineAsmOptions: u16 {
2577 const PURE = 1 << 0;
2578 const NOMEM = 1 << 1;
2579 const READONLY = 1 << 2;
2580 const PRESERVES_FLAGS = 1 << 3;
2581 const NORETURN = 1 << 4;
2582 const NOSTACK = 1 << 5;
2583 const ATT_SYNTAX = 1 << 6;
2584 const RAW = 1 << 7;
2585 const MAY_UNWIND = 1 << 8;
2586 }
2587}
2588
2589impl InlineAsmOptions {
2590 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2591
2592 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2593 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2594
2595 pub fn human_readable_names(&self) -> Vec<&'static str> {
2596 let mut options = vec![];
2597
2598 if self.contains(InlineAsmOptions::PURE) {
2599 options.push("pure");
2600 }
2601 if self.contains(InlineAsmOptions::NOMEM) {
2602 options.push("nomem");
2603 }
2604 if self.contains(InlineAsmOptions::READONLY) {
2605 options.push("readonly");
2606 }
2607 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2608 options.push("preserves_flags");
2609 }
2610 if self.contains(InlineAsmOptions::NORETURN) {
2611 options.push("noreturn");
2612 }
2613 if self.contains(InlineAsmOptions::NOSTACK) {
2614 options.push("nostack");
2615 }
2616 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2617 options.push("att_syntax");
2618 }
2619 if self.contains(InlineAsmOptions::RAW) {
2620 options.push("raw");
2621 }
2622 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2623 options.push("may_unwind");
2624 }
2625
2626 options
2627 }
2628}
2629
2630impl std::fmt::Debug for InlineAsmOptions {
2631 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2632 bitflags::parser::to_writer(self, f)
2633 }
2634}
2635
2636#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2637pub enum InlineAsmTemplatePiece {
2638 String(Cow<'static, str>),
2639 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2640}
2641
2642impl fmt::Display for InlineAsmTemplatePiece {
2643 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2644 match self {
2645 Self::String(s) => {
2646 for c in s.chars() {
2647 match c {
2648 '{' => f.write_str("{{")?,
2649 '}' => f.write_str("}}")?,
2650 _ => c.fmt(f)?,
2651 }
2652 }
2653 Ok(())
2654 }
2655 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2656 write!(f, "{{{operand_idx}:{modifier}}}")
2657 }
2658 Self::Placeholder { operand_idx, modifier: None, .. } => {
2659 write!(f, "{{{operand_idx}}}")
2660 }
2661 }
2662 }
2663}
2664
2665impl InlineAsmTemplatePiece {
2666 pub fn to_string(s: &[Self]) -> String {
2668 use fmt::Write;
2669 let mut out = String::new();
2670 for p in s.iter() {
2671 let _ = write!(out, "{p}");
2672 }
2673 out
2674 }
2675}
2676
2677#[derive(Clone, Encodable, Decodable, Debug)]
2685pub struct InlineAsmSym {
2686 pub id: NodeId,
2687 pub qself: Option<P<QSelf>>,
2688 pub path: Path,
2689}
2690
2691#[derive(Clone, Encodable, Decodable, Debug)]
2695pub enum InlineAsmOperand {
2696 In {
2697 reg: InlineAsmRegOrRegClass,
2698 expr: P<Expr>,
2699 },
2700 Out {
2701 reg: InlineAsmRegOrRegClass,
2702 late: bool,
2703 expr: Option<P<Expr>>,
2704 },
2705 InOut {
2706 reg: InlineAsmRegOrRegClass,
2707 late: bool,
2708 expr: P<Expr>,
2709 },
2710 SplitInOut {
2711 reg: InlineAsmRegOrRegClass,
2712 late: bool,
2713 in_expr: P<Expr>,
2714 out_expr: Option<P<Expr>>,
2715 },
2716 Const {
2717 anon_const: AnonConst,
2718 },
2719 Sym {
2720 sym: InlineAsmSym,
2721 },
2722 Label {
2723 block: P<Block>,
2724 },
2725}
2726
2727impl InlineAsmOperand {
2728 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2729 match self {
2730 Self::In { reg, .. }
2731 | Self::Out { reg, .. }
2732 | Self::InOut { reg, .. }
2733 | Self::SplitInOut { reg, .. } => Some(reg),
2734 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2735 }
2736 }
2737}
2738
2739#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2740pub enum AsmMacro {
2741 Asm,
2743 GlobalAsm,
2745 NakedAsm,
2747}
2748
2749impl AsmMacro {
2750 pub const fn macro_name(self) -> &'static str {
2751 match self {
2752 AsmMacro::Asm => "asm",
2753 AsmMacro::GlobalAsm => "global_asm",
2754 AsmMacro::NakedAsm => "naked_asm",
2755 }
2756 }
2757
2758 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2759 match self {
2760 AsmMacro::Asm => true,
2761 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2762 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2763 }
2764 }
2765
2766 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2767 match self {
2768 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2769 AsmMacro::GlobalAsm => true,
2770 AsmMacro::NakedAsm => true,
2771 }
2772 }
2773}
2774
2775#[derive(Clone, Encodable, Decodable, Debug)]
2779pub struct InlineAsm {
2780 pub asm_macro: AsmMacro,
2781 pub template: Vec<InlineAsmTemplatePiece>,
2782 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2783 pub operands: Vec<(InlineAsmOperand, Span)>,
2784 pub clobber_abis: Vec<(Symbol, Span)>,
2785 pub options: InlineAsmOptions,
2786 pub line_spans: Vec<Span>,
2787}
2788
2789#[derive(Clone, Encodable, Decodable, Debug)]
2793pub struct Param {
2794 pub attrs: AttrVec,
2795 pub ty: P<Ty>,
2796 pub pat: P<Pat>,
2797 pub id: NodeId,
2798 pub span: Span,
2799 pub is_placeholder: bool,
2800}
2801
2802#[derive(Clone, Encodable, Decodable, Debug)]
2806pub enum SelfKind {
2807 Value(Mutability),
2809 Region(Option<Lifetime>, Mutability),
2811 Pinned(Option<Lifetime>, Mutability),
2813 Explicit(P<Ty>, Mutability),
2815}
2816
2817impl SelfKind {
2818 pub fn to_ref_suggestion(&self) -> String {
2819 match self {
2820 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2821 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2822 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2823 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2824 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2825 unreachable!("if we had an explicit self, we wouldn't be here")
2826 }
2827 }
2828 }
2829}
2830
2831pub type ExplicitSelf = Spanned<SelfKind>;
2832
2833impl Param {
2834 pub fn to_self(&self) -> Option<ExplicitSelf> {
2836 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2837 if ident.name == kw::SelfLower {
2838 return match self.ty.kind {
2839 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2840 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2841 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2842 }
2843 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2844 if ty.kind.is_implicit_self() =>
2845 {
2846 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2847 }
2848 _ => Some(respan(
2849 self.pat.span.to(self.ty.span),
2850 SelfKind::Explicit(self.ty.clone(), mutbl),
2851 )),
2852 };
2853 }
2854 }
2855 None
2856 }
2857
2858 pub fn is_self(&self) -> bool {
2860 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2861 ident.name == kw::SelfLower
2862 } else {
2863 false
2864 }
2865 }
2866
2867 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2869 let span = eself.span.to(eself_ident.span);
2870 let infer_ty = P(Ty {
2871 id: DUMMY_NODE_ID,
2872 kind: TyKind::ImplicitSelf,
2873 span: eself_ident.span,
2874 tokens: None,
2875 });
2876 let (mutbl, ty) = match eself.node {
2877 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2878 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2879 SelfKind::Region(lt, mutbl) => (
2880 Mutability::Not,
2881 P(Ty {
2882 id: DUMMY_NODE_ID,
2883 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2884 span,
2885 tokens: None,
2886 }),
2887 ),
2888 SelfKind::Pinned(lt, mutbl) => (
2889 mutbl,
2890 P(Ty {
2891 id: DUMMY_NODE_ID,
2892 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2893 span,
2894 tokens: None,
2895 }),
2896 ),
2897 };
2898 Param {
2899 attrs,
2900 pat: P(Pat {
2901 id: DUMMY_NODE_ID,
2902 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2903 span,
2904 tokens: None,
2905 }),
2906 span,
2907 ty,
2908 id: DUMMY_NODE_ID,
2909 is_placeholder: false,
2910 }
2911 }
2912}
2913
2914#[derive(Clone, Encodable, Decodable, Debug)]
2921pub struct FnDecl {
2922 pub inputs: ThinVec<Param>,
2923 pub output: FnRetTy,
2924}
2925
2926impl FnDecl {
2927 pub fn has_self(&self) -> bool {
2928 self.inputs.get(0).is_some_and(Param::is_self)
2929 }
2930 pub fn c_variadic(&self) -> bool {
2931 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2932 }
2933}
2934
2935#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2937pub enum IsAuto {
2938 Yes,
2939 No,
2940}
2941
2942#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2944#[derive(HashStable_Generic)]
2945pub enum Safety {
2946 Unsafe(Span),
2948 Safe(Span),
2950 Default,
2953}
2954
2955#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2961pub enum CoroutineKind {
2962 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2964 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2966 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2968}
2969
2970impl CoroutineKind {
2971 pub fn span(self) -> Span {
2972 match self {
2973 CoroutineKind::Async { span, .. } => span,
2974 CoroutineKind::Gen { span, .. } => span,
2975 CoroutineKind::AsyncGen { span, .. } => span,
2976 }
2977 }
2978
2979 pub fn as_str(self) -> &'static str {
2980 match self {
2981 CoroutineKind::Async { .. } => "async",
2982 CoroutineKind::Gen { .. } => "gen",
2983 CoroutineKind::AsyncGen { .. } => "async gen",
2984 }
2985 }
2986
2987 pub fn closure_id(self) -> NodeId {
2988 match self {
2989 CoroutineKind::Async { closure_id, .. }
2990 | CoroutineKind::Gen { closure_id, .. }
2991 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2992 }
2993 }
2994
2995 pub fn return_id(self) -> (NodeId, Span) {
2998 match self {
2999 CoroutineKind::Async { return_impl_trait_id, span, .. }
3000 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3001 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3002 (return_impl_trait_id, span)
3003 }
3004 }
3005 }
3006}
3007
3008#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3009#[derive(HashStable_Generic)]
3010pub enum Const {
3011 Yes(Span),
3012 No,
3013}
3014
3015#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3018pub enum Defaultness {
3019 Default(Span),
3020 Final,
3021}
3022
3023#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3024pub enum ImplPolarity {
3025 Positive,
3027 Negative(Span),
3029}
3030
3031impl fmt::Debug for ImplPolarity {
3032 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3033 match *self {
3034 ImplPolarity::Positive => "positive".fmt(f),
3035 ImplPolarity::Negative(_) => "negative".fmt(f),
3036 }
3037 }
3038}
3039
3040#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3042#[derive(HashStable_Generic)]
3043pub enum BoundPolarity {
3044 Positive,
3046 Negative(Span),
3048 Maybe(Span),
3050}
3051
3052impl BoundPolarity {
3053 pub fn as_str(self) -> &'static str {
3054 match self {
3055 Self::Positive => "",
3056 Self::Negative(_) => "!",
3057 Self::Maybe(_) => "?",
3058 }
3059 }
3060}
3061
3062#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3064#[derive(HashStable_Generic)]
3065pub enum BoundConstness {
3066 Never,
3068 Always(Span),
3070 Maybe(Span),
3072}
3073
3074impl BoundConstness {
3075 pub fn as_str(self) -> &'static str {
3076 match self {
3077 Self::Never => "",
3078 Self::Always(_) => "const",
3079 Self::Maybe(_) => "~const",
3080 }
3081 }
3082}
3083
3084#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3086#[derive(HashStable_Generic)]
3087pub enum BoundAsyncness {
3088 Normal,
3090 Async(Span),
3092}
3093
3094impl BoundAsyncness {
3095 pub fn as_str(self) -> &'static str {
3096 match self {
3097 Self::Normal => "",
3098 Self::Async(_) => "async",
3099 }
3100 }
3101}
3102
3103#[derive(Clone, Encodable, Decodable, Debug)]
3104pub enum FnRetTy {
3105 Default(Span),
3110 Ty(P<Ty>),
3112}
3113
3114impl FnRetTy {
3115 pub fn span(&self) -> Span {
3116 match self {
3117 &FnRetTy::Default(span) => span,
3118 FnRetTy::Ty(ty) => ty.span,
3119 }
3120 }
3121}
3122
3123#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3124pub enum Inline {
3125 Yes,
3126 No,
3127}
3128
3129#[derive(Clone, Encodable, Decodable, Debug)]
3131pub enum ModKind {
3132 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3137 Unloaded,
3139}
3140
3141#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3142pub struct ModSpans {
3143 pub inner_span: Span,
3146 pub inject_use_span: Span,
3147}
3148
3149#[derive(Clone, Encodable, Decodable, Debug)]
3153pub struct ForeignMod {
3154 pub extern_span: Span,
3156 pub safety: Safety,
3159 pub abi: Option<StrLit>,
3160 pub items: ThinVec<P<ForeignItem>>,
3161}
3162
3163#[derive(Clone, Encodable, Decodable, Debug)]
3164pub struct EnumDef {
3165 pub variants: ThinVec<Variant>,
3166}
3167#[derive(Clone, Encodable, Decodable, Debug)]
3169pub struct Variant {
3170 pub attrs: AttrVec,
3172 pub id: NodeId,
3174 pub span: Span,
3176 pub vis: Visibility,
3178 pub ident: Ident,
3180
3181 pub data: VariantData,
3183 pub disr_expr: Option<AnonConst>,
3185 pub is_placeholder: bool,
3187}
3188
3189#[derive(Clone, Encodable, Decodable, Debug)]
3191pub enum UseTreeKind {
3192 Simple(Option<Ident>),
3194 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3203 Glob,
3205}
3206
3207#[derive(Clone, Encodable, Decodable, Debug)]
3210pub struct UseTree {
3211 pub prefix: Path,
3212 pub kind: UseTreeKind,
3213 pub span: Span,
3214}
3215
3216impl UseTree {
3217 pub fn ident(&self) -> Ident {
3218 match self.kind {
3219 UseTreeKind::Simple(Some(rename)) => rename,
3220 UseTreeKind::Simple(None) => {
3221 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3222 }
3223 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3224 }
3225 }
3226}
3227
3228#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3232pub enum AttrStyle {
3233 Outer,
3234 Inner,
3235}
3236
3237pub type AttrVec = ThinVec<Attribute>;
3239
3240#[derive(Clone, Encodable, Decodable, Debug)]
3242pub struct Attribute {
3243 pub kind: AttrKind,
3244 pub id: AttrId,
3245 pub style: AttrStyle,
3248 pub span: Span,
3249}
3250
3251#[derive(Clone, Encodable, Decodable, Debug)]
3252pub enum AttrKind {
3253 Normal(P<NormalAttr>),
3255
3256 DocComment(CommentKind, Symbol),
3260}
3261
3262#[derive(Clone, Encodable, Decodable, Debug)]
3263pub struct NormalAttr {
3264 pub item: AttrItem,
3265 pub tokens: Option<LazyAttrTokenStream>,
3267}
3268
3269impl NormalAttr {
3270 pub fn from_ident(ident: Ident) -> Self {
3271 Self {
3272 item: AttrItem {
3273 unsafety: Safety::Default,
3274 path: Path::from_ident(ident),
3275 args: AttrArgs::Empty,
3276 tokens: None,
3277 },
3278 tokens: None,
3279 }
3280 }
3281}
3282
3283#[derive(Clone, Encodable, Decodable, Debug)]
3284pub struct AttrItem {
3285 pub unsafety: Safety,
3286 pub path: Path,
3287 pub args: AttrArgs,
3288 pub tokens: Option<LazyAttrTokenStream>,
3290}
3291
3292impl AttrItem {
3293 pub fn is_valid_for_outer_style(&self) -> bool {
3294 self.path == sym::cfg_attr
3295 || self.path == sym::cfg
3296 || self.path == sym::forbid
3297 || self.path == sym::warn
3298 || self.path == sym::allow
3299 || self.path == sym::deny
3300 }
3301}
3302
3303#[derive(Clone, Encodable, Decodable, Debug)]
3310pub struct TraitRef {
3311 pub path: Path,
3312 pub ref_id: NodeId,
3313}
3314
3315#[derive(Clone, Encodable, Decodable, Debug)]
3316pub struct PolyTraitRef {
3317 pub bound_generic_params: ThinVec<GenericParam>,
3319
3320 pub modifiers: TraitBoundModifiers,
3322
3323 pub trait_ref: TraitRef,
3325
3326 pub span: Span,
3327}
3328
3329impl PolyTraitRef {
3330 pub fn new(
3331 generic_params: ThinVec<GenericParam>,
3332 path: Path,
3333 modifiers: TraitBoundModifiers,
3334 span: Span,
3335 ) -> Self {
3336 PolyTraitRef {
3337 bound_generic_params: generic_params,
3338 modifiers,
3339 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3340 span,
3341 }
3342 }
3343}
3344
3345#[derive(Clone, Encodable, Decodable, Debug)]
3346pub struct Visibility {
3347 pub kind: VisibilityKind,
3348 pub span: Span,
3349 pub tokens: Option<LazyAttrTokenStream>,
3350}
3351
3352#[derive(Clone, Encodable, Decodable, Debug)]
3353pub enum VisibilityKind {
3354 Public,
3355 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3356 Inherited,
3357}
3358
3359impl VisibilityKind {
3360 pub fn is_pub(&self) -> bool {
3361 matches!(self, VisibilityKind::Public)
3362 }
3363}
3364
3365#[derive(Clone, Encodable, Decodable, Debug)]
3369pub struct FieldDef {
3370 pub attrs: AttrVec,
3371 pub id: NodeId,
3372 pub span: Span,
3373 pub vis: Visibility,
3374 pub safety: Safety,
3375 pub ident: Option<Ident>,
3376
3377 pub ty: P<Ty>,
3378 pub default: Option<AnonConst>,
3379 pub is_placeholder: bool,
3380}
3381
3382#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3384pub enum Recovered {
3385 No,
3386 Yes(ErrorGuaranteed),
3387}
3388
3389#[derive(Clone, Encodable, Decodable, Debug)]
3391pub enum VariantData {
3392 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3396 Tuple(ThinVec<FieldDef>, NodeId),
3400 Unit(NodeId),
3404}
3405
3406impl VariantData {
3407 pub fn fields(&self) -> &[FieldDef] {
3409 match self {
3410 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3411 _ => &[],
3412 }
3413 }
3414
3415 pub fn ctor_node_id(&self) -> Option<NodeId> {
3417 match *self {
3418 VariantData::Struct { .. } => None,
3419 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3420 }
3421 }
3422}
3423
3424#[derive(Clone, Encodable, Decodable, Debug)]
3426pub struct Item<K = ItemKind> {
3427 pub attrs: AttrVec,
3428 pub id: NodeId,
3429 pub span: Span,
3430 pub vis: Visibility,
3431
3432 pub kind: K,
3433
3434 pub tokens: Option<LazyAttrTokenStream>,
3442}
3443
3444impl Item {
3445 pub fn span_with_attributes(&self) -> Span {
3447 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3448 }
3449
3450 pub fn opt_generics(&self) -> Option<&Generics> {
3451 match &self.kind {
3452 ItemKind::ExternCrate(..)
3453 | ItemKind::Use(_)
3454 | ItemKind::Mod(..)
3455 | ItemKind::ForeignMod(_)
3456 | ItemKind::GlobalAsm(_)
3457 | ItemKind::MacCall(_)
3458 | ItemKind::Delegation(_)
3459 | ItemKind::DelegationMac(_)
3460 | ItemKind::MacroDef(..) => None,
3461 ItemKind::Static(_) => None,
3462 ItemKind::Const(i) => Some(&i.generics),
3463 ItemKind::Fn(i) => Some(&i.generics),
3464 ItemKind::TyAlias(i) => Some(&i.generics),
3465 ItemKind::TraitAlias(_, generics, _)
3466 | ItemKind::Enum(_, generics, _)
3467 | ItemKind::Struct(_, generics, _)
3468 | ItemKind::Union(_, generics, _) => Some(&generics),
3469 ItemKind::Trait(i) => Some(&i.generics),
3470 ItemKind::Impl(i) => Some(&i.generics),
3471 }
3472 }
3473}
3474
3475#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3477pub enum Extern {
3478 None,
3482 Implicit(Span),
3488 Explicit(StrLit, Span),
3492}
3493
3494impl Extern {
3495 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3496 match abi {
3497 Some(name) => Extern::Explicit(name, span),
3498 None => Extern::Implicit(span),
3499 }
3500 }
3501}
3502
3503#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3508pub struct FnHeader {
3509 pub safety: Safety,
3511 pub coroutine_kind: Option<CoroutineKind>,
3513 pub constness: Const,
3515 pub ext: Extern,
3517}
3518
3519impl FnHeader {
3520 pub fn has_qualifiers(&self) -> bool {
3522 let Self { safety, coroutine_kind, constness, ext } = self;
3523 matches!(safety, Safety::Unsafe(_))
3524 || coroutine_kind.is_some()
3525 || matches!(constness, Const::Yes(_))
3526 || !matches!(ext, Extern::None)
3527 }
3528}
3529
3530impl Default for FnHeader {
3531 fn default() -> FnHeader {
3532 FnHeader {
3533 safety: Safety::Default,
3534 coroutine_kind: None,
3535 constness: Const::No,
3536 ext: Extern::None,
3537 }
3538 }
3539}
3540
3541#[derive(Clone, Encodable, Decodable, Debug)]
3542pub struct Trait {
3543 pub safety: Safety,
3544 pub is_auto: IsAuto,
3545 pub ident: Ident,
3546 pub generics: Generics,
3547 pub bounds: GenericBounds,
3548 pub items: ThinVec<P<AssocItem>>,
3549}
3550
3551#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3570pub struct TyAliasWhereClause {
3571 pub has_where_token: bool,
3572 pub span: Span,
3573}
3574
3575#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3577pub struct TyAliasWhereClauses {
3578 pub before: TyAliasWhereClause,
3580 pub after: TyAliasWhereClause,
3582 pub split: usize,
3586}
3587
3588#[derive(Clone, Encodable, Decodable, Debug)]
3589pub struct TyAlias {
3590 pub defaultness: Defaultness,
3591 pub ident: Ident,
3592 pub generics: Generics,
3593 pub where_clauses: TyAliasWhereClauses,
3594 pub bounds: GenericBounds,
3595 pub ty: Option<P<Ty>>,
3596}
3597
3598#[derive(Clone, Encodable, Decodable, Debug)]
3599pub struct Impl {
3600 pub defaultness: Defaultness,
3601 pub safety: Safety,
3602 pub generics: Generics,
3603 pub constness: Const,
3604 pub polarity: ImplPolarity,
3605 pub of_trait: Option<TraitRef>,
3607 pub self_ty: P<Ty>,
3608 pub items: ThinVec<P<AssocItem>>,
3609}
3610
3611#[derive(Clone, Encodable, Decodable, Debug, Default)]
3612pub struct FnContract {
3613 pub requires: Option<P<Expr>>,
3614 pub ensures: Option<P<Expr>>,
3615}
3616
3617#[derive(Clone, Encodable, Decodable, Debug)]
3618pub struct Fn {
3619 pub defaultness: Defaultness,
3620 pub ident: Ident,
3621 pub generics: Generics,
3622 pub sig: FnSig,
3623 pub contract: Option<P<FnContract>>,
3624 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3625 pub body: Option<P<Block>>,
3626}
3627
3628#[derive(Clone, Encodable, Decodable, Debug)]
3629pub struct Delegation {
3630 pub id: NodeId,
3632 pub qself: Option<P<QSelf>>,
3633 pub path: Path,
3634 pub ident: Ident,
3635 pub rename: Option<Ident>,
3636 pub body: Option<P<Block>>,
3637 pub from_glob: bool,
3639}
3640
3641#[derive(Clone, Encodable, Decodable, Debug)]
3642pub struct DelegationMac {
3643 pub qself: Option<P<QSelf>>,
3644 pub prefix: Path,
3645 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3647 pub body: Option<P<Block>>,
3648}
3649
3650#[derive(Clone, Encodable, Decodable, Debug)]
3651pub struct StaticItem {
3652 pub ident: Ident,
3653 pub ty: P<Ty>,
3654 pub safety: Safety,
3655 pub mutability: Mutability,
3656 pub expr: Option<P<Expr>>,
3657 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3658}
3659
3660#[derive(Clone, Encodable, Decodable, Debug)]
3661pub struct ConstItem {
3662 pub defaultness: Defaultness,
3663 pub ident: Ident,
3664 pub generics: Generics,
3665 pub ty: P<Ty>,
3666 pub expr: Option<P<Expr>>,
3667 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3668}
3669
3670#[derive(Clone, Encodable, Decodable, Debug)]
3672pub enum ItemKind {
3673 ExternCrate(Option<Symbol>, Ident),
3677 Use(UseTree),
3681 Static(Box<StaticItem>),
3685 Const(Box<ConstItem>),
3689 Fn(Box<Fn>),
3693 Mod(Safety, Ident, ModKind),
3699 ForeignMod(ForeignMod),
3703 GlobalAsm(Box<InlineAsm>),
3705 TyAlias(Box<TyAlias>),
3709 Enum(Ident, Generics, EnumDef),
3713 Struct(Ident, Generics, VariantData),
3717 Union(Ident, Generics, VariantData),
3721 Trait(Box<Trait>),
3725 TraitAlias(Ident, Generics, GenericBounds),
3729 Impl(Box<Impl>),
3733 MacCall(P<MacCall>),
3737 MacroDef(Ident, MacroDef),
3739 Delegation(Box<Delegation>),
3743 DelegationMac(Box<DelegationMac>),
3746}
3747
3748impl ItemKind {
3749 pub fn ident(&self) -> Option<Ident> {
3750 match *self {
3751 ItemKind::ExternCrate(_, ident)
3752 | ItemKind::Static(box StaticItem { ident, .. })
3753 | ItemKind::Const(box ConstItem { ident, .. })
3754 | ItemKind::Fn(box Fn { ident, .. })
3755 | ItemKind::Mod(_, ident, _)
3756 | ItemKind::TyAlias(box TyAlias { ident, .. })
3757 | ItemKind::Enum(ident, ..)
3758 | ItemKind::Struct(ident, ..)
3759 | ItemKind::Union(ident, ..)
3760 | ItemKind::Trait(box Trait { ident, .. })
3761 | ItemKind::TraitAlias(ident, ..)
3762 | ItemKind::MacroDef(ident, _)
3763 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3764
3765 ItemKind::Use(_)
3766 | ItemKind::ForeignMod(_)
3767 | ItemKind::GlobalAsm(_)
3768 | ItemKind::Impl(_)
3769 | ItemKind::MacCall(_)
3770 | ItemKind::DelegationMac(_) => None,
3771 }
3772 }
3773
3774 pub fn article(&self) -> &'static str {
3776 use ItemKind::*;
3777 match self {
3778 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3779 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3780 | Delegation(..) | DelegationMac(..) => "a",
3781 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3782 }
3783 }
3784
3785 pub fn descr(&self) -> &'static str {
3786 match self {
3787 ItemKind::ExternCrate(..) => "extern crate",
3788 ItemKind::Use(..) => "`use` import",
3789 ItemKind::Static(..) => "static item",
3790 ItemKind::Const(..) => "constant item",
3791 ItemKind::Fn(..) => "function",
3792 ItemKind::Mod(..) => "module",
3793 ItemKind::ForeignMod(..) => "extern block",
3794 ItemKind::GlobalAsm(..) => "global asm item",
3795 ItemKind::TyAlias(..) => "type alias",
3796 ItemKind::Enum(..) => "enum",
3797 ItemKind::Struct(..) => "struct",
3798 ItemKind::Union(..) => "union",
3799 ItemKind::Trait(..) => "trait",
3800 ItemKind::TraitAlias(..) => "trait alias",
3801 ItemKind::MacCall(..) => "item macro invocation",
3802 ItemKind::MacroDef(..) => "macro definition",
3803 ItemKind::Impl { .. } => "implementation",
3804 ItemKind::Delegation(..) => "delegated function",
3805 ItemKind::DelegationMac(..) => "delegation",
3806 }
3807 }
3808
3809 pub fn generics(&self) -> Option<&Generics> {
3810 match self {
3811 Self::Fn(box Fn { generics, .. })
3812 | Self::TyAlias(box TyAlias { generics, .. })
3813 | Self::Const(box ConstItem { generics, .. })
3814 | Self::Enum(_, generics, _)
3815 | Self::Struct(_, generics, _)
3816 | Self::Union(_, generics, _)
3817 | Self::Trait(box Trait { generics, .. })
3818 | Self::TraitAlias(_, generics, _)
3819 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3820 _ => None,
3821 }
3822 }
3823}
3824
3825pub type AssocItem = Item<AssocItemKind>;
3828
3829#[derive(Clone, Encodable, Decodable, Debug)]
3837pub enum AssocItemKind {
3838 Const(Box<ConstItem>),
3841 Fn(Box<Fn>),
3843 Type(Box<TyAlias>),
3845 MacCall(P<MacCall>),
3847 Delegation(Box<Delegation>),
3849 DelegationMac(Box<DelegationMac>),
3851}
3852
3853impl AssocItemKind {
3854 pub fn ident(&self) -> Option<Ident> {
3855 match *self {
3856 AssocItemKind::Const(box ConstItem { ident, .. })
3857 | AssocItemKind::Fn(box Fn { ident, .. })
3858 | AssocItemKind::Type(box TyAlias { ident, .. })
3859 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3860
3861 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3862 }
3863 }
3864
3865 pub fn defaultness(&self) -> Defaultness {
3866 match *self {
3867 Self::Const(box ConstItem { defaultness, .. })
3868 | Self::Fn(box Fn { defaultness, .. })
3869 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3870 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3871 Defaultness::Final
3872 }
3873 }
3874 }
3875}
3876
3877impl From<AssocItemKind> for ItemKind {
3878 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3879 match assoc_item_kind {
3880 AssocItemKind::Const(item) => ItemKind::Const(item),
3881 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3882 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3883 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3884 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3885 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3886 }
3887 }
3888}
3889
3890impl TryFrom<ItemKind> for AssocItemKind {
3891 type Error = ItemKind;
3892
3893 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3894 Ok(match item_kind {
3895 ItemKind::Const(item) => AssocItemKind::Const(item),
3896 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3897 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3898 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3899 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3900 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3901 _ => return Err(item_kind),
3902 })
3903 }
3904}
3905
3906#[derive(Clone, Encodable, Decodable, Debug)]
3908pub enum ForeignItemKind {
3909 Static(Box<StaticItem>),
3911 Fn(Box<Fn>),
3913 TyAlias(Box<TyAlias>),
3915 MacCall(P<MacCall>),
3917}
3918
3919impl ForeignItemKind {
3920 pub fn ident(&self) -> Option<Ident> {
3921 match *self {
3922 ForeignItemKind::Static(box StaticItem { ident, .. })
3923 | ForeignItemKind::Fn(box Fn { ident, .. })
3924 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3925
3926 ForeignItemKind::MacCall(_) => None,
3927 }
3928 }
3929}
3930
3931impl From<ForeignItemKind> for ItemKind {
3932 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3933 match foreign_item_kind {
3934 ForeignItemKind::Static(box static_foreign_item) => {
3935 ItemKind::Static(Box::new(static_foreign_item))
3936 }
3937 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3938 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3939 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3940 }
3941 }
3942}
3943
3944impl TryFrom<ItemKind> for ForeignItemKind {
3945 type Error = ItemKind;
3946
3947 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3948 Ok(match item_kind {
3949 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3950 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3951 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3952 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3953 _ => return Err(item_kind),
3954 })
3955 }
3956}
3957
3958pub type ForeignItem = Item<ForeignItemKind>;
3959
3960#[cfg(target_pointer_width = "64")]
3962mod size_asserts {
3963 use rustc_data_structures::static_assert_size;
3964
3965 use super::*;
3966 static_assert_size!(AssocItem, 80);
3968 static_assert_size!(AssocItemKind, 16);
3969 static_assert_size!(Attribute, 32);
3970 static_assert_size!(Block, 32);
3971 static_assert_size!(Expr, 72);
3972 static_assert_size!(ExprKind, 40);
3973 static_assert_size!(Fn, 184);
3974 static_assert_size!(ForeignItem, 80);
3975 static_assert_size!(ForeignItemKind, 16);
3976 static_assert_size!(GenericArg, 24);
3977 static_assert_size!(GenericBound, 88);
3978 static_assert_size!(Generics, 40);
3979 static_assert_size!(Impl, 136);
3980 static_assert_size!(Item, 144);
3981 static_assert_size!(ItemKind, 80);
3982 static_assert_size!(LitKind, 24);
3983 static_assert_size!(Local, 96);
3984 static_assert_size!(MetaItemLit, 40);
3985 static_assert_size!(Param, 40);
3986 static_assert_size!(Pat, 72);
3987 static_assert_size!(Path, 24);
3988 static_assert_size!(PathSegment, 24);
3989 static_assert_size!(PatKind, 48);
3990 static_assert_size!(Stmt, 32);
3991 static_assert_size!(StmtKind, 16);
3992 static_assert_size!(Ty, 64);
3993 static_assert_size!(TyKind, 40);
3994 }