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::{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_global(&self) -> bool {
124 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
125 }
126
127 #[tracing::instrument(level = "debug", ret)]
137 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
138 allow_mgca_arg
139 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
140 }
141}
142
143#[derive(Clone, Encodable, Decodable, Debug)]
147pub struct PathSegment {
148 pub ident: Ident,
150
151 pub id: NodeId,
152
153 pub args: Option<P<GenericArgs>>,
160}
161
162impl PathSegment {
163 pub fn from_ident(ident: Ident) -> Self {
164 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
165 }
166
167 pub fn path_root(span: Span) -> Self {
168 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
169 }
170
171 pub fn span(&self) -> Span {
172 match &self.args {
173 Some(args) => self.ident.span.to(args.span()),
174 None => self.ident.span,
175 }
176 }
177}
178
179#[derive(Clone, Encodable, Decodable, Debug)]
183pub enum GenericArgs {
184 AngleBracketed(AngleBracketedArgs),
186 Parenthesized(ParenthesizedArgs),
188 ParenthesizedElided(Span),
190}
191
192impl GenericArgs {
193 pub fn is_angle_bracketed(&self) -> bool {
194 matches!(self, AngleBracketed(..))
195 }
196
197 pub fn span(&self) -> Span {
198 match self {
199 AngleBracketed(data) => data.span,
200 Parenthesized(data) => data.span,
201 ParenthesizedElided(span) => *span,
202 }
203 }
204}
205
206#[derive(Clone, Encodable, Decodable, Debug)]
208pub enum GenericArg {
209 Lifetime(Lifetime),
211 Type(P<Ty>),
213 Const(AnonConst),
215}
216
217impl GenericArg {
218 pub fn span(&self) -> Span {
219 match self {
220 GenericArg::Lifetime(lt) => lt.ident.span,
221 GenericArg::Type(ty) => ty.span,
222 GenericArg::Const(ct) => ct.value.span,
223 }
224 }
225}
226
227#[derive(Clone, Encodable, Decodable, Debug, Default)]
229pub struct AngleBracketedArgs {
230 pub span: Span,
232 pub args: ThinVec<AngleBracketedArg>,
234}
235
236#[derive(Clone, Encodable, Decodable, Debug)]
238pub enum AngleBracketedArg {
239 Arg(GenericArg),
241 Constraint(AssocItemConstraint),
243}
244
245impl AngleBracketedArg {
246 pub fn span(&self) -> Span {
247 match self {
248 AngleBracketedArg::Arg(arg) => arg.span(),
249 AngleBracketedArg::Constraint(constraint) => constraint.span,
250 }
251 }
252}
253
254impl From<AngleBracketedArgs> for P<GenericArgs> {
255 fn from(val: AngleBracketedArgs) -> Self {
256 P(GenericArgs::AngleBracketed(val))
257 }
258}
259
260impl From<ParenthesizedArgs> for P<GenericArgs> {
261 fn from(val: ParenthesizedArgs) -> Self {
262 P(GenericArgs::Parenthesized(val))
263 }
264}
265
266#[derive(Clone, Encodable, Decodable, Debug)]
268pub struct ParenthesizedArgs {
269 pub span: Span,
274
275 pub inputs: ThinVec<P<Ty>>,
277
278 pub inputs_span: Span,
283
284 pub output: FnRetTy,
286}
287
288impl ParenthesizedArgs {
289 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
290 let args = self
291 .inputs
292 .iter()
293 .cloned()
294 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
295 .collect();
296 AngleBracketedArgs { span: self.inputs_span, args }
297 }
298}
299
300use crate::AstDeref;
301pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
302
303#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
305pub struct TraitBoundModifiers {
306 pub constness: BoundConstness,
307 pub asyncness: BoundAsyncness,
308 pub polarity: BoundPolarity,
309}
310
311impl TraitBoundModifiers {
312 pub const NONE: Self = Self {
313 constness: BoundConstness::Never,
314 asyncness: BoundAsyncness::Normal,
315 polarity: BoundPolarity::Positive,
316 };
317}
318
319#[derive(Clone, Encodable, Decodable, Debug)]
320pub enum GenericBound {
321 Trait(PolyTraitRef),
322 Outlives(Lifetime),
323 Use(ThinVec<PreciseCapturingArg>, Span),
325}
326
327impl GenericBound {
328 pub fn span(&self) -> Span {
329 match self {
330 GenericBound::Trait(t, ..) => t.span,
331 GenericBound::Outlives(l) => l.ident.span,
332 GenericBound::Use(_, span) => *span,
333 }
334 }
335}
336
337pub type GenericBounds = Vec<GenericBound>;
338
339#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
343pub enum ParamKindOrd {
344 Lifetime,
345 TypeOrConst,
346}
347
348impl fmt::Display for ParamKindOrd {
349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350 match self {
351 ParamKindOrd::Lifetime => "lifetime".fmt(f),
352 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
353 }
354 }
355}
356
357#[derive(Clone, Encodable, Decodable, Debug)]
358pub enum GenericParamKind {
359 Lifetime,
361 Type {
362 default: Option<P<Ty>>,
363 },
364 Const {
365 ty: P<Ty>,
366 kw_span: Span,
368 default: Option<AnonConst>,
370 },
371}
372
373#[derive(Clone, Encodable, Decodable, Debug)]
374pub struct GenericParam {
375 pub id: NodeId,
376 pub ident: Ident,
377 pub attrs: AttrVec,
378 pub bounds: GenericBounds,
379 pub is_placeholder: bool,
380 pub kind: GenericParamKind,
381 pub colon_span: Option<Span>,
382}
383
384impl GenericParam {
385 pub fn span(&self) -> Span {
386 match &self.kind {
387 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
388 self.ident.span
389 }
390 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
391 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
392 kw_span.to(default.value.span)
393 }
394 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
395 }
396 }
397}
398
399#[derive(Clone, Encodable, Decodable, Debug, Default)]
402pub struct Generics {
403 pub params: ThinVec<GenericParam>,
404 pub where_clause: WhereClause,
405 pub span: Span,
406}
407
408#[derive(Clone, Encodable, Decodable, Debug, Default)]
410pub struct WhereClause {
411 pub has_where_token: bool,
416 pub predicates: ThinVec<WherePredicate>,
417 pub span: Span,
418}
419
420impl WhereClause {
421 pub fn is_empty(&self) -> bool {
422 !self.has_where_token && self.predicates.is_empty()
423 }
424}
425
426#[derive(Clone, Encodable, Decodable, Debug)]
428pub struct WherePredicate {
429 pub attrs: AttrVec,
430 pub kind: WherePredicateKind,
431 pub id: NodeId,
432 pub span: Span,
433 pub is_placeholder: bool,
434}
435
436#[derive(Clone, Encodable, Decodable, Debug)]
438pub enum WherePredicateKind {
439 BoundPredicate(WhereBoundPredicate),
441 RegionPredicate(WhereRegionPredicate),
443 EqPredicate(WhereEqPredicate),
445}
446
447#[derive(Clone, Encodable, Decodable, Debug)]
451pub struct WhereBoundPredicate {
452 pub bound_generic_params: ThinVec<GenericParam>,
454 pub bounded_ty: P<Ty>,
456 pub bounds: GenericBounds,
458}
459
460#[derive(Clone, Encodable, Decodable, Debug)]
464pub struct WhereRegionPredicate {
465 pub lifetime: Lifetime,
466 pub bounds: GenericBounds,
467}
468
469#[derive(Clone, Encodable, Decodable, Debug)]
473pub struct WhereEqPredicate {
474 pub lhs_ty: P<Ty>,
475 pub rhs_ty: P<Ty>,
476}
477
478#[derive(Clone, Encodable, Decodable, Debug)]
479pub struct Crate {
480 pub attrs: AttrVec,
481 pub items: ThinVec<P<Item>>,
482 pub spans: ModSpans,
483 pub id: NodeId,
486 pub is_placeholder: bool,
487}
488
489#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
496pub struct MetaItem {
497 pub unsafety: Safety,
498 pub path: Path,
499 pub kind: MetaItemKind,
500 pub span: Span,
501}
502
503#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
505pub enum MetaItemKind {
506 Word,
510
511 List(ThinVec<MetaItemInner>),
515
516 NameValue(MetaItemLit),
520}
521
522#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
526pub enum MetaItemInner {
527 MetaItem(MetaItem),
529
530 Lit(MetaItemLit),
534}
535
536#[derive(Clone, Encodable, Decodable, Debug)]
540pub struct Block {
541 pub stmts: ThinVec<Stmt>,
543 pub id: NodeId,
544 pub rules: BlockCheckMode,
546 pub span: Span,
547 pub tokens: Option<LazyAttrTokenStream>,
548 pub could_be_bare_literal: bool,
556}
557
558#[derive(Clone, Encodable, Decodable, Debug)]
562pub struct Pat {
563 pub id: NodeId,
564 pub kind: PatKind,
565 pub span: Span,
566 pub tokens: Option<LazyAttrTokenStream>,
567}
568
569impl Pat {
570 pub fn to_ty(&self) -> Option<P<Ty>> {
573 let kind = match &self.kind {
574 PatKind::Wild => TyKind::Infer,
576 PatKind::Ident(BindingMode::NONE, ident, None) => {
578 TyKind::Path(None, Path::from_ident(*ident))
579 }
580 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
581 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
582 PatKind::Ref(pat, mutbl) => {
584 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
585 }
586 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
589 pat.to_ty().map(TyKind::Slice)?
590 }
591 PatKind::Tuple(pats) => {
594 let mut tys = ThinVec::with_capacity(pats.len());
595 for pat in pats {
597 tys.push(pat.to_ty()?);
598 }
599 TyKind::Tup(tys)
600 }
601 _ => return None,
602 };
603
604 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
605 }
606
607 pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
611 if !it(self) {
612 return;
613 }
614
615 match &self.kind {
616 PatKind::Ident(_, _, Some(p)) => p.walk(it),
618
619 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
621
622 PatKind::TupleStruct(_, _, s)
624 | PatKind::Tuple(s)
625 | PatKind::Slice(s)
626 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
627
628 PatKind::Box(s)
630 | PatKind::Deref(s)
631 | PatKind::Ref(s, _)
632 | PatKind::Paren(s)
633 | PatKind::Guard(s, _) => s.walk(it),
634
635 PatKind::Wild
637 | PatKind::Rest
638 | PatKind::Never
639 | PatKind::Expr(_)
640 | PatKind::Range(..)
641 | PatKind::Ident(..)
642 | PatKind::Path(..)
643 | PatKind::MacCall(_)
644 | PatKind::Err(_) => {}
645 }
646 }
647
648 pub fn is_rest(&self) -> bool {
650 matches!(self.kind, PatKind::Rest)
651 }
652
653 pub fn could_be_never_pattern(&self) -> bool {
656 let mut could_be_never_pattern = false;
657 self.walk(&mut |pat| match &pat.kind {
658 PatKind::Never | PatKind::MacCall(_) => {
659 could_be_never_pattern = true;
660 false
661 }
662 PatKind::Or(s) => {
663 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
664 false
665 }
666 _ => true,
667 });
668 could_be_never_pattern
669 }
670
671 pub fn contains_never_pattern(&self) -> bool {
674 let mut contains_never_pattern = false;
675 self.walk(&mut |pat| {
676 if matches!(pat.kind, PatKind::Never) {
677 contains_never_pattern = true;
678 }
679 true
680 });
681 contains_never_pattern
682 }
683
684 pub fn descr(&self) -> Option<String> {
686 match &self.kind {
687 PatKind::Wild => Some("_".to_string()),
688 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
689 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
690 _ => None,
691 }
692 }
693}
694
695#[derive(Clone, Encodable, Decodable, Debug)]
701pub struct PatField {
702 pub ident: Ident,
704 pub pat: P<Pat>,
706 pub is_shorthand: bool,
707 pub attrs: AttrVec,
708 pub id: NodeId,
709 pub span: Span,
710 pub is_placeholder: bool,
711}
712
713#[derive(Clone, Copy, Debug, Eq, PartialEq)]
714#[derive(Encodable, Decodable, HashStable_Generic)]
715pub enum ByRef {
716 Yes(Mutability),
717 No,
718}
719
720impl ByRef {
721 #[must_use]
722 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
723 if let ByRef::Yes(old_mutbl) = &mut self {
724 *old_mutbl = cmp::min(*old_mutbl, mutbl);
725 }
726 self
727 }
728}
729
730#[derive(Clone, Copy, Debug, Eq, PartialEq)]
736#[derive(Encodable, Decodable, HashStable_Generic)]
737pub struct BindingMode(pub ByRef, pub Mutability);
738
739impl BindingMode {
740 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
741 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
742 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
743 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
744 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
745 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
746
747 pub fn prefix_str(self) -> &'static str {
748 match self {
749 Self::NONE => "",
750 Self::REF => "ref ",
751 Self::MUT => "mut ",
752 Self::REF_MUT => "ref mut ",
753 Self::MUT_REF => "mut ref ",
754 Self::MUT_REF_MUT => "mut ref mut ",
755 }
756 }
757}
758
759#[derive(Clone, Encodable, Decodable, Debug)]
760pub enum RangeEnd {
761 Included(RangeSyntax),
763 Excluded,
765}
766
767#[derive(Clone, Encodable, Decodable, Debug)]
768pub enum RangeSyntax {
769 DotDotDot,
771 DotDotEq,
773}
774
775#[derive(Clone, Encodable, Decodable, Debug)]
779pub enum PatKind {
780 Wild,
782
783 Ident(BindingMode, Ident, Option<P<Pat>>),
788
789 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
791
792 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
794
795 Or(ThinVec<P<Pat>>),
798
799 Path(Option<P<QSelf>>, Path),
804
805 Tuple(ThinVec<P<Pat>>),
807
808 Box(P<Pat>),
810
811 Deref(P<Pat>),
813
814 Ref(P<Pat>, Mutability),
816
817 Expr(P<Expr>),
819
820 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
822
823 Slice(ThinVec<P<Pat>>),
825
826 Rest,
839
840 Never,
842
843 Guard(P<Pat>, P<Expr>),
845
846 Paren(P<Pat>),
848
849 MacCall(P<MacCall>),
851
852 Err(ErrorGuaranteed),
854}
855
856#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
858pub enum PatFieldsRest {
859 Rest,
861 Recovered(ErrorGuaranteed),
863 None,
865}
866
867#[derive(Clone, Copy, PartialEq, Eq, Debug)]
870#[derive(Encodable, Decodable, HashStable_Generic)]
871pub enum BorrowKind {
872 Ref,
876 Raw,
880}
881
882#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
883pub enum BinOpKind {
884 Add,
886 Sub,
888 Mul,
890 Div,
892 Rem,
894 And,
896 Or,
898 BitXor,
900 BitAnd,
902 BitOr,
904 Shl,
906 Shr,
908 Eq,
910 Lt,
912 Le,
914 Ne,
916 Ge,
918 Gt,
920}
921
922impl BinOpKind {
923 pub fn as_str(&self) -> &'static str {
924 use BinOpKind::*;
925 match self {
926 Add => "+",
927 Sub => "-",
928 Mul => "*",
929 Div => "/",
930 Rem => "%",
931 And => "&&",
932 Or => "||",
933 BitXor => "^",
934 BitAnd => "&",
935 BitOr => "|",
936 Shl => "<<",
937 Shr => ">>",
938 Eq => "==",
939 Lt => "<",
940 Le => "<=",
941 Ne => "!=",
942 Ge => ">=",
943 Gt => ">",
944 }
945 }
946
947 pub fn is_lazy(&self) -> bool {
948 matches!(self, BinOpKind::And | BinOpKind::Or)
949 }
950
951 pub fn precedence(&self) -> ExprPrecedence {
952 use BinOpKind::*;
953 match *self {
954 Mul | Div | Rem => ExprPrecedence::Product,
955 Add | Sub => ExprPrecedence::Sum,
956 Shl | Shr => ExprPrecedence::Shift,
957 BitAnd => ExprPrecedence::BitAnd,
958 BitXor => ExprPrecedence::BitXor,
959 BitOr => ExprPrecedence::BitOr,
960 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
961 And => ExprPrecedence::LAnd,
962 Or => ExprPrecedence::LOr,
963 }
964 }
965
966 pub fn fixity(&self) -> Fixity {
967 use BinOpKind::*;
968 match self {
969 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
970 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
971 Fixity::Left
972 }
973 }
974 }
975
976 pub fn is_comparison(self) -> bool {
977 use BinOpKind::*;
978 match self {
979 Eq | Ne | Lt | Le | Gt | Ge => true,
980 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
981 }
982 }
983
984 pub fn is_by_value(self) -> bool {
986 !self.is_comparison()
987 }
988}
989
990pub type BinOp = Spanned<BinOpKind>;
991
992#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
996pub enum UnOp {
997 Deref,
999 Not,
1001 Neg,
1003}
1004
1005impl UnOp {
1006 pub fn as_str(&self) -> &'static str {
1007 match self {
1008 UnOp::Deref => "*",
1009 UnOp::Not => "!",
1010 UnOp::Neg => "-",
1011 }
1012 }
1013
1014 pub fn is_by_value(self) -> bool {
1016 matches!(self, Self::Neg | Self::Not)
1017 }
1018}
1019
1020#[derive(Clone, Encodable, Decodable, Debug)]
1024pub struct Stmt {
1025 pub id: NodeId,
1026 pub kind: StmtKind,
1027 pub span: Span,
1028}
1029
1030impl Stmt {
1031 pub fn has_trailing_semicolon(&self) -> bool {
1032 match &self.kind {
1033 StmtKind::Semi(_) => true,
1034 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1035 _ => false,
1036 }
1037 }
1038
1039 pub fn add_trailing_semicolon(mut self) -> Self {
1047 self.kind = match self.kind {
1048 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1049 StmtKind::MacCall(mac) => {
1050 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1051 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1052 }))
1053 }
1054 kind => kind,
1055 };
1056
1057 self
1058 }
1059
1060 pub fn is_item(&self) -> bool {
1061 matches!(self.kind, StmtKind::Item(_))
1062 }
1063
1064 pub fn is_expr(&self) -> bool {
1065 matches!(self.kind, StmtKind::Expr(_))
1066 }
1067}
1068
1069#[derive(Clone, Encodable, Decodable, Debug)]
1071pub enum StmtKind {
1072 Let(P<Local>),
1074 Item(P<Item>),
1076 Expr(P<Expr>),
1078 Semi(P<Expr>),
1080 Empty,
1082 MacCall(P<MacCallStmt>),
1084}
1085
1086#[derive(Clone, Encodable, Decodable, Debug)]
1087pub struct MacCallStmt {
1088 pub mac: P<MacCall>,
1089 pub style: MacStmtStyle,
1090 pub attrs: AttrVec,
1091 pub tokens: Option<LazyAttrTokenStream>,
1092}
1093
1094#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1095pub enum MacStmtStyle {
1096 Semicolon,
1099 Braces,
1101 NoBraces,
1105}
1106
1107#[derive(Clone, Encodable, Decodable, Debug)]
1109pub struct Local {
1110 pub id: NodeId,
1111 pub pat: P<Pat>,
1112 pub ty: Option<P<Ty>>,
1113 pub kind: LocalKind,
1114 pub span: Span,
1115 pub colon_sp: Option<Span>,
1116 pub attrs: AttrVec,
1117 pub tokens: Option<LazyAttrTokenStream>,
1118}
1119
1120#[derive(Clone, Encodable, Decodable, Debug)]
1121pub enum LocalKind {
1122 Decl,
1125 Init(P<Expr>),
1128 InitElse(P<Expr>, P<Block>),
1131}
1132
1133impl LocalKind {
1134 pub fn init(&self) -> Option<&Expr> {
1135 match self {
1136 Self::Decl => None,
1137 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1138 }
1139 }
1140
1141 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1142 match self {
1143 Self::Decl => None,
1144 Self::Init(init) => Some((init, None)),
1145 Self::InitElse(init, els) => Some((init, Some(els))),
1146 }
1147 }
1148}
1149
1150#[derive(Clone, Encodable, Decodable, Debug)]
1161pub struct Arm {
1162 pub attrs: AttrVec,
1163 pub pat: P<Pat>,
1165 pub guard: Option<P<Expr>>,
1167 pub body: Option<P<Expr>>,
1169 pub span: Span,
1170 pub id: NodeId,
1171 pub is_placeholder: bool,
1172}
1173
1174#[derive(Clone, Encodable, Decodable, Debug)]
1176pub struct ExprField {
1177 pub attrs: AttrVec,
1178 pub id: NodeId,
1179 pub span: Span,
1180 pub ident: Ident,
1181 pub expr: P<Expr>,
1182 pub is_shorthand: bool,
1183 pub is_placeholder: bool,
1184}
1185
1186#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1187pub enum BlockCheckMode {
1188 Default,
1189 Unsafe(UnsafeSource),
1190}
1191
1192#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1193pub enum UnsafeSource {
1194 CompilerGenerated,
1195 UserProvided,
1196}
1197
1198#[derive(Clone, Encodable, Decodable, Debug)]
1204pub struct AnonConst {
1205 pub id: NodeId,
1206 pub value: P<Expr>,
1207}
1208
1209#[derive(Clone, Encodable, Decodable, Debug)]
1211pub struct Expr {
1212 pub id: NodeId,
1213 pub kind: ExprKind,
1214 pub span: Span,
1215 pub attrs: AttrVec,
1216 pub tokens: Option<LazyAttrTokenStream>,
1217}
1218
1219impl Expr {
1220 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1234 let this = self.maybe_unwrap_block();
1235 if allow_mgca_arg {
1236 matches!(this.kind, ExprKind::Path(..))
1237 } else {
1238 if let ExprKind::Path(None, path) = &this.kind
1239 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1240 {
1241 true
1242 } else {
1243 false
1244 }
1245 }
1246 }
1247
1248 pub fn maybe_unwrap_block(&self) -> &Expr {
1250 if let ExprKind::Block(block, None) = &self.kind
1251 && let [stmt] = block.stmts.as_slice()
1252 && let StmtKind::Expr(expr) = &stmt.kind
1253 {
1254 expr
1255 } else {
1256 self
1257 }
1258 }
1259
1260 pub fn optionally_braced_mac_call(
1266 &self,
1267 already_stripped_block: bool,
1268 ) -> Option<(bool, NodeId)> {
1269 match &self.kind {
1270 ExprKind::Block(block, None)
1271 if let [stmt] = &*block.stmts
1272 && !already_stripped_block =>
1273 {
1274 match &stmt.kind {
1275 StmtKind::MacCall(_) => Some((true, stmt.id)),
1276 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1277 Some((true, expr.id))
1278 }
1279 _ => None,
1280 }
1281 }
1282 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1283 _ => None,
1284 }
1285 }
1286
1287 pub fn to_bound(&self) -> Option<GenericBound> {
1288 match &self.kind {
1289 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1290 ThinVec::new(),
1291 path.clone(),
1292 TraitBoundModifiers::NONE,
1293 self.span,
1294 ))),
1295 _ => None,
1296 }
1297 }
1298
1299 pub fn peel_parens(&self) -> &Expr {
1300 let mut expr = self;
1301 while let ExprKind::Paren(inner) = &expr.kind {
1302 expr = inner;
1303 }
1304 expr
1305 }
1306
1307 pub fn peel_parens_and_refs(&self) -> &Expr {
1308 let mut expr = self;
1309 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1310 {
1311 expr = inner;
1312 }
1313 expr
1314 }
1315
1316 pub fn to_ty(&self) -> Option<P<Ty>> {
1318 let kind = match &self.kind {
1319 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1321 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1322
1323 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1324
1325 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1326 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1327 }
1328
1329 ExprKind::Repeat(expr, expr_len) => {
1330 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1331 }
1332
1333 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1334 expr.to_ty().map(TyKind::Slice)?
1335 }
1336
1337 ExprKind::Tup(exprs) => {
1338 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1339 TyKind::Tup(tys)
1340 }
1341
1342 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1346 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1347 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1348 } else {
1349 return None;
1350 }
1351 }
1352
1353 ExprKind::Underscore => TyKind::Infer,
1354
1355 _ => return None,
1357 };
1358
1359 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1360 }
1361
1362 pub fn precedence(&self) -> ExprPrecedence {
1363 match &self.kind {
1364 ExprKind::Closure(closure) => {
1365 match closure.fn_decl.output {
1366 FnRetTy::Default(_) => ExprPrecedence::Jump,
1367 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1368 }
1369 }
1370
1371 ExprKind::Break(..)
1372 | ExprKind::Ret(..)
1373 | ExprKind::Yield(..)
1374 | ExprKind::Yeet(..)
1375 | ExprKind::Become(..) => ExprPrecedence::Jump,
1376
1377 ExprKind::Range(..) => ExprPrecedence::Range,
1382
1383 ExprKind::Binary(op, ..) => op.node.precedence(),
1385 ExprKind::Cast(..) => ExprPrecedence::Cast,
1386
1387 ExprKind::Assign(..) |
1388 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1389
1390 ExprKind::AddrOf(..)
1392 | ExprKind::Let(..)
1397 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1398
1399 ExprKind::Array(_)
1401 | ExprKind::Await(..)
1402 | ExprKind::Use(..)
1403 | ExprKind::Block(..)
1404 | ExprKind::Call(..)
1405 | ExprKind::ConstBlock(_)
1406 | ExprKind::Continue(..)
1407 | ExprKind::Field(..)
1408 | ExprKind::ForLoop { .. }
1409 | ExprKind::FormatArgs(..)
1410 | ExprKind::Gen(..)
1411 | ExprKind::If(..)
1412 | ExprKind::IncludedBytes(..)
1413 | ExprKind::Index(..)
1414 | ExprKind::InlineAsm(..)
1415 | ExprKind::Lit(_)
1416 | ExprKind::Loop(..)
1417 | ExprKind::MacCall(..)
1418 | ExprKind::Match(..)
1419 | ExprKind::MethodCall(..)
1420 | ExprKind::OffsetOf(..)
1421 | ExprKind::Paren(..)
1422 | ExprKind::Path(..)
1423 | ExprKind::Repeat(..)
1424 | ExprKind::Struct(..)
1425 | ExprKind::Try(..)
1426 | ExprKind::TryBlock(..)
1427 | ExprKind::Tup(_)
1428 | ExprKind::Type(..)
1429 | ExprKind::Underscore
1430 | ExprKind::UnsafeBinderCast(..)
1431 | ExprKind::While(..)
1432 | ExprKind::Err(_)
1433 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1434 }
1435 }
1436
1437 pub fn is_approximately_pattern(&self) -> bool {
1439 matches!(
1440 &self.peel_parens().kind,
1441 ExprKind::Array(_)
1442 | ExprKind::Call(_, _)
1443 | ExprKind::Tup(_)
1444 | ExprKind::Lit(_)
1445 | ExprKind::Range(_, _, _)
1446 | ExprKind::Underscore
1447 | ExprKind::Path(_, _)
1448 | ExprKind::Struct(_)
1449 )
1450 }
1451}
1452
1453#[derive(Clone, Encodable, Decodable, Debug)]
1454pub struct Closure {
1455 pub binder: ClosureBinder,
1456 pub capture_clause: CaptureBy,
1457 pub constness: Const,
1458 pub coroutine_kind: Option<CoroutineKind>,
1459 pub movability: Movability,
1460 pub fn_decl: P<FnDecl>,
1461 pub body: P<Expr>,
1462 pub fn_decl_span: Span,
1464 pub fn_arg_span: Span,
1466}
1467
1468#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1470pub enum RangeLimits {
1471 HalfOpen,
1473 Closed,
1475}
1476
1477impl RangeLimits {
1478 pub fn as_str(&self) -> &'static str {
1479 match self {
1480 RangeLimits::HalfOpen => "..",
1481 RangeLimits::Closed => "..=",
1482 }
1483 }
1484}
1485
1486#[derive(Clone, Encodable, Decodable, Debug)]
1488pub struct MethodCall {
1489 pub seg: PathSegment,
1491 pub receiver: P<Expr>,
1493 pub args: ThinVec<P<Expr>>,
1495 pub span: Span,
1498}
1499
1500#[derive(Clone, Encodable, Decodable, Debug)]
1501pub enum StructRest {
1502 Base(P<Expr>),
1504 Rest(Span),
1506 None,
1508}
1509
1510#[derive(Clone, Encodable, Decodable, Debug)]
1511pub struct StructExpr {
1512 pub qself: Option<P<QSelf>>,
1513 pub path: Path,
1514 pub fields: ThinVec<ExprField>,
1515 pub rest: StructRest,
1516}
1517
1518#[derive(Clone, Encodable, Decodable, Debug)]
1520pub enum ExprKind {
1521 Array(ThinVec<P<Expr>>),
1523 ConstBlock(AnonConst),
1525 Call(P<Expr>, ThinVec<P<Expr>>),
1532 MethodCall(Box<MethodCall>),
1534 Tup(ThinVec<P<Expr>>),
1536 Binary(BinOp, P<Expr>, P<Expr>),
1538 Unary(UnOp, P<Expr>),
1540 Lit(token::Lit),
1542 Cast(P<Expr>, P<Ty>),
1544 Type(P<Expr>, P<Ty>),
1549 Let(P<Pat>, P<Expr>, Span, Recovered),
1554 If(P<Expr>, P<Block>, Option<P<Expr>>),
1558 While(P<Expr>, P<Block>, Option<Label>),
1562 ForLoop {
1568 pat: P<Pat>,
1569 iter: P<Expr>,
1570 body: P<Block>,
1571 label: Option<Label>,
1572 kind: ForLoopKind,
1573 },
1574 Loop(P<Block>, Option<Label>, Span),
1578 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1580 Closure(Box<Closure>),
1582 Block(P<Block>, Option<Label>),
1584 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1590 Await(P<Expr>, Span),
1592 Use(P<Expr>, Span),
1594
1595 TryBlock(P<Block>),
1597
1598 Assign(P<Expr>, P<Expr>, Span),
1601 AssignOp(BinOp, P<Expr>, P<Expr>),
1605 Field(P<Expr>, Ident),
1607 Index(P<Expr>, P<Expr>, Span),
1610 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1612 Underscore,
1614
1615 Path(Option<P<QSelf>>, Path),
1620
1621 AddrOf(BorrowKind, Mutability, P<Expr>),
1623 Break(Option<Label>, Option<P<Expr>>),
1625 Continue(Option<Label>),
1627 Ret(Option<P<Expr>>),
1629
1630 InlineAsm(P<InlineAsm>),
1632
1633 OffsetOf(P<Ty>, P<[Ident]>),
1638
1639 MacCall(P<MacCall>),
1641
1642 Struct(P<StructExpr>),
1646
1647 Repeat(P<Expr>, AnonConst),
1652
1653 Paren(P<Expr>),
1655
1656 Try(P<Expr>),
1658
1659 Yield(YieldKind),
1661
1662 Yeet(Option<P<Expr>>),
1665
1666 Become(P<Expr>),
1670
1671 IncludedBytes(Arc<[u8]>),
1676
1677 FormatArgs(P<FormatArgs>),
1679
1680 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1681
1682 Err(ErrorGuaranteed),
1684
1685 Dummy,
1687}
1688
1689#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1691pub enum ForLoopKind {
1692 For,
1693 ForAwait,
1694}
1695
1696#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1698pub enum GenBlockKind {
1699 Async,
1700 Gen,
1701 AsyncGen,
1702}
1703
1704impl fmt::Display for GenBlockKind {
1705 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1706 self.modifier().fmt(f)
1707 }
1708}
1709
1710impl GenBlockKind {
1711 pub fn modifier(&self) -> &'static str {
1712 match self {
1713 GenBlockKind::Async => "async",
1714 GenBlockKind::Gen => "gen",
1715 GenBlockKind::AsyncGen => "async gen",
1716 }
1717 }
1718}
1719
1720#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1722#[derive(Encodable, Decodable, HashStable_Generic)]
1723pub enum UnsafeBinderCastKind {
1724 Wrap,
1726 Unwrap,
1728}
1729
1730#[derive(Clone, Encodable, Decodable, Debug)]
1745pub struct QSelf {
1746 pub ty: P<Ty>,
1747
1748 pub path_span: Span,
1752 pub position: usize,
1753}
1754
1755#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1757pub enum CaptureBy {
1758 Value {
1760 move_kw: Span,
1762 },
1763 Ref,
1765 Use {
1771 use_kw: Span,
1773 },
1774}
1775
1776#[derive(Clone, Encodable, Decodable, Debug)]
1778pub enum ClosureBinder {
1779 NotPresent,
1781 For {
1783 span: Span,
1790
1791 generic_params: ThinVec<GenericParam>,
1798 },
1799}
1800
1801#[derive(Clone, Encodable, Decodable, Debug)]
1804pub struct MacCall {
1805 pub path: Path,
1806 pub args: P<DelimArgs>,
1807}
1808
1809impl MacCall {
1810 pub fn span(&self) -> Span {
1811 self.path.span.to(self.args.dspan.entire())
1812 }
1813}
1814
1815#[derive(Clone, Encodable, Decodable, Debug)]
1817pub enum AttrArgs {
1818 Empty,
1820 Delimited(DelimArgs),
1822 Eq {
1824 eq_span: Span,
1826 expr: P<Expr>,
1827 },
1828}
1829
1830impl AttrArgs {
1831 pub fn span(&self) -> Option<Span> {
1832 match self {
1833 AttrArgs::Empty => None,
1834 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1835 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1836 }
1837 }
1838
1839 pub fn inner_tokens(&self) -> TokenStream {
1842 match self {
1843 AttrArgs::Empty => TokenStream::default(),
1844 AttrArgs::Delimited(args) => args.tokens.clone(),
1845 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1846 }
1847 }
1848}
1849
1850#[derive(Clone, Encodable, Decodable, Debug)]
1852pub struct DelimArgs {
1853 pub dspan: DelimSpan,
1854 pub delim: Delimiter, pub tokens: TokenStream,
1856}
1857
1858impl DelimArgs {
1859 pub fn need_semicolon(&self) -> bool {
1862 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1863 }
1864}
1865
1866impl<CTX> HashStable<CTX> for DelimArgs
1867where
1868 CTX: crate::HashStableContext,
1869{
1870 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
1871 let DelimArgs { dspan, delim, tokens } = self;
1872 dspan.hash_stable(ctx, hasher);
1873 delim.hash_stable(ctx, hasher);
1874 tokens.hash_stable(ctx, hasher);
1875 }
1876}
1877
1878#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1880pub struct MacroDef {
1881 pub body: P<DelimArgs>,
1882 pub macro_rules: bool,
1884}
1885
1886#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1887#[derive(HashStable_Generic)]
1888pub enum StrStyle {
1889 Cooked,
1891 Raw(u8),
1895}
1896
1897#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1899pub enum MatchKind {
1900 Prefix,
1902 Postfix,
1904}
1905
1906#[derive(Clone, Encodable, Decodable, Debug)]
1908pub enum YieldKind {
1909 Prefix(Option<P<Expr>>),
1911 Postfix(P<Expr>),
1913}
1914
1915impl YieldKind {
1916 pub const fn expr(&self) -> Option<&P<Expr>> {
1920 match self {
1921 YieldKind::Prefix(expr) => expr.as_ref(),
1922 YieldKind::Postfix(expr) => Some(expr),
1923 }
1924 }
1925
1926 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1928 match self {
1929 YieldKind::Prefix(expr) => expr.as_mut(),
1930 YieldKind::Postfix(expr) => Some(expr),
1931 }
1932 }
1933
1934 pub const fn same_kind(&self, other: &Self) -> bool {
1936 match (self, other) {
1937 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
1938 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
1939 _ => false,
1940 }
1941 }
1942}
1943
1944#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1946pub struct MetaItemLit {
1947 pub symbol: Symbol,
1949 pub suffix: Option<Symbol>,
1951 pub kind: LitKind,
1954 pub span: Span,
1955}
1956
1957#[derive(Clone, Copy, Encodable, Decodable, Debug)]
1959pub struct StrLit {
1960 pub symbol: Symbol,
1962 pub suffix: Option<Symbol>,
1964 pub symbol_unescaped: Symbol,
1966 pub style: StrStyle,
1967 pub span: Span,
1968}
1969
1970impl StrLit {
1971 pub fn as_token_lit(&self) -> token::Lit {
1972 let token_kind = match self.style {
1973 StrStyle::Cooked => token::Str,
1974 StrStyle::Raw(n) => token::StrRaw(n),
1975 };
1976 token::Lit::new(token_kind, self.symbol, self.suffix)
1977 }
1978}
1979
1980#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1982#[derive(HashStable_Generic)]
1983pub enum LitIntType {
1984 Signed(IntTy),
1986 Unsigned(UintTy),
1988 Unsuffixed,
1990}
1991
1992#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1994#[derive(HashStable_Generic)]
1995pub enum LitFloatType {
1996 Suffixed(FloatTy),
1998 Unsuffixed,
2000}
2001
2002#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2009pub enum LitKind {
2010 Str(Symbol, StrStyle),
2013 ByteStr(Arc<[u8]>, StrStyle),
2016 CStr(Arc<[u8]>, StrStyle),
2018 Byte(u8),
2020 Char(char),
2022 Int(Pu128, LitIntType),
2024 Float(Symbol, LitFloatType),
2028 Bool(bool),
2030 Err(ErrorGuaranteed),
2032}
2033
2034impl LitKind {
2035 pub fn str(&self) -> Option<Symbol> {
2036 match *self {
2037 LitKind::Str(s, _) => Some(s),
2038 _ => None,
2039 }
2040 }
2041
2042 pub fn is_str(&self) -> bool {
2044 matches!(self, LitKind::Str(..))
2045 }
2046
2047 pub fn is_bytestr(&self) -> bool {
2049 matches!(self, LitKind::ByteStr(..))
2050 }
2051
2052 pub fn is_numeric(&self) -> bool {
2054 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2055 }
2056
2057 pub fn is_unsuffixed(&self) -> bool {
2060 !self.is_suffixed()
2061 }
2062
2063 pub fn is_suffixed(&self) -> bool {
2065 match *self {
2066 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2068 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2069 LitKind::Str(..)
2071 | LitKind::ByteStr(..)
2072 | LitKind::CStr(..)
2073 | LitKind::Byte(..)
2074 | LitKind::Char(..)
2075 | LitKind::Int(_, LitIntType::Unsuffixed)
2076 | LitKind::Float(_, LitFloatType::Unsuffixed)
2077 | LitKind::Bool(..)
2078 | LitKind::Err(_) => false,
2079 }
2080 }
2081}
2082
2083#[derive(Clone, Encodable, Decodable, Debug)]
2086pub struct MutTy {
2087 pub ty: P<Ty>,
2088 pub mutbl: Mutability,
2089}
2090
2091#[derive(Clone, Encodable, Decodable, Debug)]
2094pub struct FnSig {
2095 pub header: FnHeader,
2096 pub decl: P<FnDecl>,
2097 pub span: Span,
2098}
2099
2100#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2101#[derive(Encodable, Decodable, HashStable_Generic)]
2102pub enum FloatTy {
2103 F16,
2104 F32,
2105 F64,
2106 F128,
2107}
2108
2109impl FloatTy {
2110 pub fn name_str(self) -> &'static str {
2111 match self {
2112 FloatTy::F16 => "f16",
2113 FloatTy::F32 => "f32",
2114 FloatTy::F64 => "f64",
2115 FloatTy::F128 => "f128",
2116 }
2117 }
2118
2119 pub fn name(self) -> Symbol {
2120 match self {
2121 FloatTy::F16 => sym::f16,
2122 FloatTy::F32 => sym::f32,
2123 FloatTy::F64 => sym::f64,
2124 FloatTy::F128 => sym::f128,
2125 }
2126 }
2127}
2128
2129#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2130#[derive(Encodable, Decodable, HashStable_Generic)]
2131pub enum IntTy {
2132 Isize,
2133 I8,
2134 I16,
2135 I32,
2136 I64,
2137 I128,
2138}
2139
2140impl IntTy {
2141 pub fn name_str(&self) -> &'static str {
2142 match *self {
2143 IntTy::Isize => "isize",
2144 IntTy::I8 => "i8",
2145 IntTy::I16 => "i16",
2146 IntTy::I32 => "i32",
2147 IntTy::I64 => "i64",
2148 IntTy::I128 => "i128",
2149 }
2150 }
2151
2152 pub fn name(&self) -> Symbol {
2153 match *self {
2154 IntTy::Isize => sym::isize,
2155 IntTy::I8 => sym::i8,
2156 IntTy::I16 => sym::i16,
2157 IntTy::I32 => sym::i32,
2158 IntTy::I64 => sym::i64,
2159 IntTy::I128 => sym::i128,
2160 }
2161 }
2162}
2163
2164#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2165#[derive(Encodable, Decodable, HashStable_Generic)]
2166pub enum UintTy {
2167 Usize,
2168 U8,
2169 U16,
2170 U32,
2171 U64,
2172 U128,
2173}
2174
2175impl UintTy {
2176 pub fn name_str(&self) -> &'static str {
2177 match *self {
2178 UintTy::Usize => "usize",
2179 UintTy::U8 => "u8",
2180 UintTy::U16 => "u16",
2181 UintTy::U32 => "u32",
2182 UintTy::U64 => "u64",
2183 UintTy::U128 => "u128",
2184 }
2185 }
2186
2187 pub fn name(&self) -> Symbol {
2188 match *self {
2189 UintTy::Usize => sym::usize,
2190 UintTy::U8 => sym::u8,
2191 UintTy::U16 => sym::u16,
2192 UintTy::U32 => sym::u32,
2193 UintTy::U64 => sym::u64,
2194 UintTy::U128 => sym::u128,
2195 }
2196 }
2197}
2198
2199#[derive(Clone, Encodable, Decodable, Debug)]
2210pub struct AssocItemConstraint {
2211 pub id: NodeId,
2212 pub ident: Ident,
2213 pub gen_args: Option<GenericArgs>,
2214 pub kind: AssocItemConstraintKind,
2215 pub span: Span,
2216}
2217
2218#[derive(Clone, Encodable, Decodable, Debug)]
2219pub enum Term {
2220 Ty(P<Ty>),
2221 Const(AnonConst),
2222}
2223
2224impl From<P<Ty>> for Term {
2225 fn from(v: P<Ty>) -> Self {
2226 Term::Ty(v)
2227 }
2228}
2229
2230impl From<AnonConst> for Term {
2231 fn from(v: AnonConst) -> Self {
2232 Term::Const(v)
2233 }
2234}
2235
2236#[derive(Clone, Encodable, Decodable, Debug)]
2238pub enum AssocItemConstraintKind {
2239 Equality { term: Term },
2246 Bound { bounds: GenericBounds },
2248}
2249
2250#[derive(Encodable, Decodable, Debug)]
2251pub struct Ty {
2252 pub id: NodeId,
2253 pub kind: TyKind,
2254 pub span: Span,
2255 pub tokens: Option<LazyAttrTokenStream>,
2256}
2257
2258impl Clone for Ty {
2259 fn clone(&self) -> Self {
2260 ensure_sufficient_stack(|| Self {
2261 id: self.id,
2262 kind: self.kind.clone(),
2263 span: self.span,
2264 tokens: self.tokens.clone(),
2265 })
2266 }
2267}
2268
2269impl Ty {
2270 pub fn peel_refs(&self) -> &Self {
2271 let mut final_ty = self;
2272 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2273 {
2274 final_ty = ty;
2275 }
2276 final_ty
2277 }
2278
2279 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2280 match &self.kind {
2281 TyKind::Infer => true,
2282 TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
2283 _ => false,
2284 }
2285 }
2286}
2287
2288#[derive(Clone, Encodable, Decodable, Debug)]
2289pub struct BareFnTy {
2290 pub safety: Safety,
2291 pub ext: Extern,
2292 pub generic_params: ThinVec<GenericParam>,
2293 pub decl: P<FnDecl>,
2294 pub decl_span: Span,
2297}
2298
2299#[derive(Clone, Encodable, Decodable, Debug)]
2300pub struct UnsafeBinderTy {
2301 pub generic_params: ThinVec<GenericParam>,
2302 pub inner_ty: P<Ty>,
2303}
2304
2305#[derive(Clone, Encodable, Decodable, Debug)]
2309pub enum TyKind {
2310 Slice(P<Ty>),
2312 Array(P<Ty>, AnonConst),
2314 Ptr(MutTy),
2316 Ref(Option<Lifetime>, MutTy),
2318 PinnedRef(Option<Lifetime>, MutTy),
2322 BareFn(P<BareFnTy>),
2324 UnsafeBinder(P<UnsafeBinderTy>),
2326 Never,
2328 Tup(ThinVec<P<Ty>>),
2330 Path(Option<P<QSelf>>, Path),
2335 TraitObject(GenericBounds, TraitObjectSyntax),
2338 ImplTrait(NodeId, GenericBounds),
2345 Paren(P<Ty>),
2347 Typeof(AnonConst),
2349 Infer,
2352 ImplicitSelf,
2354 MacCall(P<MacCall>),
2356 CVarArgs,
2358 Pat(P<Ty>, P<TyPat>),
2361 Dummy,
2363 Err(ErrorGuaranteed),
2365}
2366
2367impl TyKind {
2368 pub fn is_implicit_self(&self) -> bool {
2369 matches!(self, TyKind::ImplicitSelf)
2370 }
2371
2372 pub fn is_unit(&self) -> bool {
2373 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2374 }
2375
2376 pub fn is_simple_path(&self) -> Option<Symbol> {
2377 if let TyKind::Path(None, Path { segments, .. }) = &self
2378 && let [segment] = &segments[..]
2379 && segment.args.is_none()
2380 {
2381 Some(segment.ident.name)
2382 } else {
2383 None
2384 }
2385 }
2386}
2387
2388#[derive(Clone, Encodable, Decodable, Debug)]
2390pub struct TyPat {
2391 pub id: NodeId,
2392 pub kind: TyPatKind,
2393 pub span: Span,
2394 pub tokens: Option<LazyAttrTokenStream>,
2395}
2396
2397#[derive(Clone, Encodable, Decodable, Debug)]
2401pub enum TyPatKind {
2402 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2404
2405 Err(ErrorGuaranteed),
2407}
2408
2409#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2411#[repr(u8)]
2412pub enum TraitObjectSyntax {
2413 Dyn = 0,
2415 DynStar = 1,
2416 None = 2,
2417}
2418
2419unsafe impl Tag for TraitObjectSyntax {
2423 const BITS: u32 = 2;
2424
2425 fn into_usize(self) -> usize {
2426 self as u8 as usize
2427 }
2428
2429 unsafe fn from_usize(tag: usize) -> Self {
2430 match tag {
2431 0 => TraitObjectSyntax::Dyn,
2432 1 => TraitObjectSyntax::DynStar,
2433 2 => TraitObjectSyntax::None,
2434 _ => unreachable!(),
2435 }
2436 }
2437}
2438
2439#[derive(Clone, Encodable, Decodable, Debug)]
2440pub enum PreciseCapturingArg {
2441 Lifetime(Lifetime),
2443 Arg(Path, NodeId),
2445}
2446
2447#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2451pub enum InlineAsmRegOrRegClass {
2452 Reg(Symbol),
2453 RegClass(Symbol),
2454}
2455
2456#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2457pub struct InlineAsmOptions(u16);
2458bitflags::bitflags! {
2459 impl InlineAsmOptions: u16 {
2460 const PURE = 1 << 0;
2461 const NOMEM = 1 << 1;
2462 const READONLY = 1 << 2;
2463 const PRESERVES_FLAGS = 1 << 3;
2464 const NORETURN = 1 << 4;
2465 const NOSTACK = 1 << 5;
2466 const ATT_SYNTAX = 1 << 6;
2467 const RAW = 1 << 7;
2468 const MAY_UNWIND = 1 << 8;
2469 }
2470}
2471
2472impl InlineAsmOptions {
2473 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2474
2475 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2476 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2477
2478 pub fn human_readable_names(&self) -> Vec<&'static str> {
2479 let mut options = vec![];
2480
2481 if self.contains(InlineAsmOptions::PURE) {
2482 options.push("pure");
2483 }
2484 if self.contains(InlineAsmOptions::NOMEM) {
2485 options.push("nomem");
2486 }
2487 if self.contains(InlineAsmOptions::READONLY) {
2488 options.push("readonly");
2489 }
2490 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2491 options.push("preserves_flags");
2492 }
2493 if self.contains(InlineAsmOptions::NORETURN) {
2494 options.push("noreturn");
2495 }
2496 if self.contains(InlineAsmOptions::NOSTACK) {
2497 options.push("nostack");
2498 }
2499 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2500 options.push("att_syntax");
2501 }
2502 if self.contains(InlineAsmOptions::RAW) {
2503 options.push("raw");
2504 }
2505 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2506 options.push("may_unwind");
2507 }
2508
2509 options
2510 }
2511}
2512
2513impl std::fmt::Debug for InlineAsmOptions {
2514 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2515 bitflags::parser::to_writer(self, f)
2516 }
2517}
2518
2519#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2520pub enum InlineAsmTemplatePiece {
2521 String(Cow<'static, str>),
2522 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2523}
2524
2525impl fmt::Display for InlineAsmTemplatePiece {
2526 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2527 match self {
2528 Self::String(s) => {
2529 for c in s.chars() {
2530 match c {
2531 '{' => f.write_str("{{")?,
2532 '}' => f.write_str("}}")?,
2533 _ => c.fmt(f)?,
2534 }
2535 }
2536 Ok(())
2537 }
2538 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2539 write!(f, "{{{operand_idx}:{modifier}}}")
2540 }
2541 Self::Placeholder { operand_idx, modifier: None, .. } => {
2542 write!(f, "{{{operand_idx}}}")
2543 }
2544 }
2545 }
2546}
2547
2548impl InlineAsmTemplatePiece {
2549 pub fn to_string(s: &[Self]) -> String {
2551 use fmt::Write;
2552 let mut out = String::new();
2553 for p in s.iter() {
2554 let _ = write!(out, "{p}");
2555 }
2556 out
2557 }
2558}
2559
2560#[derive(Clone, Encodable, Decodable, Debug)]
2568pub struct InlineAsmSym {
2569 pub id: NodeId,
2570 pub qself: Option<P<QSelf>>,
2571 pub path: Path,
2572}
2573
2574#[derive(Clone, Encodable, Decodable, Debug)]
2578pub enum InlineAsmOperand {
2579 In {
2580 reg: InlineAsmRegOrRegClass,
2581 expr: P<Expr>,
2582 },
2583 Out {
2584 reg: InlineAsmRegOrRegClass,
2585 late: bool,
2586 expr: Option<P<Expr>>,
2587 },
2588 InOut {
2589 reg: InlineAsmRegOrRegClass,
2590 late: bool,
2591 expr: P<Expr>,
2592 },
2593 SplitInOut {
2594 reg: InlineAsmRegOrRegClass,
2595 late: bool,
2596 in_expr: P<Expr>,
2597 out_expr: Option<P<Expr>>,
2598 },
2599 Const {
2600 anon_const: AnonConst,
2601 },
2602 Sym {
2603 sym: InlineAsmSym,
2604 },
2605 Label {
2606 block: P<Block>,
2607 },
2608}
2609
2610impl InlineAsmOperand {
2611 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2612 match self {
2613 Self::In { reg, .. }
2614 | Self::Out { reg, .. }
2615 | Self::InOut { reg, .. }
2616 | Self::SplitInOut { reg, .. } => Some(reg),
2617 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2618 }
2619 }
2620}
2621
2622#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2623pub enum AsmMacro {
2624 Asm,
2626 GlobalAsm,
2628 NakedAsm,
2630}
2631
2632impl AsmMacro {
2633 pub const fn macro_name(self) -> &'static str {
2634 match self {
2635 AsmMacro::Asm => "asm",
2636 AsmMacro::GlobalAsm => "global_asm",
2637 AsmMacro::NakedAsm => "naked_asm",
2638 }
2639 }
2640
2641 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2642 match self {
2643 AsmMacro::Asm => true,
2644 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2645 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2646 }
2647 }
2648
2649 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2650 match self {
2651 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2652 AsmMacro::GlobalAsm => true,
2653 AsmMacro::NakedAsm => true,
2654 }
2655 }
2656}
2657
2658#[derive(Clone, Encodable, Decodable, Debug)]
2662pub struct InlineAsm {
2663 pub asm_macro: AsmMacro,
2664 pub template: Vec<InlineAsmTemplatePiece>,
2665 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2666 pub operands: Vec<(InlineAsmOperand, Span)>,
2667 pub clobber_abis: Vec<(Symbol, Span)>,
2668 pub options: InlineAsmOptions,
2669 pub line_spans: Vec<Span>,
2670}
2671
2672#[derive(Clone, Encodable, Decodable, Debug)]
2676pub struct Param {
2677 pub attrs: AttrVec,
2678 pub ty: P<Ty>,
2679 pub pat: P<Pat>,
2680 pub id: NodeId,
2681 pub span: Span,
2682 pub is_placeholder: bool,
2683}
2684
2685#[derive(Clone, Encodable, Decodable, Debug)]
2689pub enum SelfKind {
2690 Value(Mutability),
2692 Region(Option<Lifetime>, Mutability),
2694 Pinned(Option<Lifetime>, Mutability),
2696 Explicit(P<Ty>, Mutability),
2698}
2699
2700impl SelfKind {
2701 pub fn to_ref_suggestion(&self) -> String {
2702 match self {
2703 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2704 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2705 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2706 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2707 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2708 unreachable!("if we had an explicit self, we wouldn't be here")
2709 }
2710 }
2711 }
2712}
2713
2714pub type ExplicitSelf = Spanned<SelfKind>;
2715
2716impl Param {
2717 pub fn to_self(&self) -> Option<ExplicitSelf> {
2719 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2720 if ident.name == kw::SelfLower {
2721 return match self.ty.kind {
2722 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2723 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2724 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2725 }
2726 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2727 if ty.kind.is_implicit_self() =>
2728 {
2729 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2730 }
2731 _ => Some(respan(
2732 self.pat.span.to(self.ty.span),
2733 SelfKind::Explicit(self.ty.clone(), mutbl),
2734 )),
2735 };
2736 }
2737 }
2738 None
2739 }
2740
2741 pub fn is_self(&self) -> bool {
2743 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2744 ident.name == kw::SelfLower
2745 } else {
2746 false
2747 }
2748 }
2749
2750 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2752 let span = eself.span.to(eself_ident.span);
2753 let infer_ty = P(Ty {
2754 id: DUMMY_NODE_ID,
2755 kind: TyKind::ImplicitSelf,
2756 span: eself_ident.span,
2757 tokens: None,
2758 });
2759 let (mutbl, ty) = match eself.node {
2760 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2761 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2762 SelfKind::Region(lt, mutbl) => (
2763 Mutability::Not,
2764 P(Ty {
2765 id: DUMMY_NODE_ID,
2766 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2767 span,
2768 tokens: None,
2769 }),
2770 ),
2771 SelfKind::Pinned(lt, mutbl) => (
2772 mutbl,
2773 P(Ty {
2774 id: DUMMY_NODE_ID,
2775 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2776 span,
2777 tokens: None,
2778 }),
2779 ),
2780 };
2781 Param {
2782 attrs,
2783 pat: P(Pat {
2784 id: DUMMY_NODE_ID,
2785 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2786 span,
2787 tokens: None,
2788 }),
2789 span,
2790 ty,
2791 id: DUMMY_NODE_ID,
2792 is_placeholder: false,
2793 }
2794 }
2795}
2796
2797#[derive(Clone, Encodable, Decodable, Debug)]
2804pub struct FnDecl {
2805 pub inputs: ThinVec<Param>,
2806 pub output: FnRetTy,
2807}
2808
2809impl FnDecl {
2810 pub fn has_self(&self) -> bool {
2811 self.inputs.get(0).is_some_and(Param::is_self)
2812 }
2813 pub fn c_variadic(&self) -> bool {
2814 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2815 }
2816}
2817
2818#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2820pub enum IsAuto {
2821 Yes,
2822 No,
2823}
2824
2825#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2827#[derive(HashStable_Generic)]
2828pub enum Safety {
2829 Unsafe(Span),
2831 Safe(Span),
2833 Default,
2836}
2837
2838#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2844pub enum CoroutineKind {
2845 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2847 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2849 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2851}
2852
2853impl CoroutineKind {
2854 pub fn span(self) -> Span {
2855 match self {
2856 CoroutineKind::Async { span, .. } => span,
2857 CoroutineKind::Gen { span, .. } => span,
2858 CoroutineKind::AsyncGen { span, .. } => span,
2859 }
2860 }
2861
2862 pub fn as_str(self) -> &'static str {
2863 match self {
2864 CoroutineKind::Async { .. } => "async",
2865 CoroutineKind::Gen { .. } => "gen",
2866 CoroutineKind::AsyncGen { .. } => "async gen",
2867 }
2868 }
2869
2870 pub fn closure_id(self) -> NodeId {
2871 match self {
2872 CoroutineKind::Async { closure_id, .. }
2873 | CoroutineKind::Gen { closure_id, .. }
2874 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2875 }
2876 }
2877
2878 pub fn return_id(self) -> (NodeId, Span) {
2881 match self {
2882 CoroutineKind::Async { return_impl_trait_id, span, .. }
2883 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2884 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2885 (return_impl_trait_id, span)
2886 }
2887 }
2888 }
2889}
2890
2891#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2892#[derive(HashStable_Generic)]
2893pub enum Const {
2894 Yes(Span),
2895 No,
2896}
2897
2898#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2901pub enum Defaultness {
2902 Default(Span),
2903 Final,
2904}
2905
2906#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2907pub enum ImplPolarity {
2908 Positive,
2910 Negative(Span),
2912}
2913
2914impl fmt::Debug for ImplPolarity {
2915 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2916 match *self {
2917 ImplPolarity::Positive => "positive".fmt(f),
2918 ImplPolarity::Negative(_) => "negative".fmt(f),
2919 }
2920 }
2921}
2922
2923#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2925#[derive(HashStable_Generic)]
2926pub enum BoundPolarity {
2927 Positive,
2929 Negative(Span),
2931 Maybe(Span),
2933}
2934
2935impl BoundPolarity {
2936 pub fn as_str(self) -> &'static str {
2937 match self {
2938 Self::Positive => "",
2939 Self::Negative(_) => "!",
2940 Self::Maybe(_) => "?",
2941 }
2942 }
2943}
2944
2945#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2947#[derive(HashStable_Generic)]
2948pub enum BoundConstness {
2949 Never,
2951 Always(Span),
2953 Maybe(Span),
2955}
2956
2957impl BoundConstness {
2958 pub fn as_str(self) -> &'static str {
2959 match self {
2960 Self::Never => "",
2961 Self::Always(_) => "const",
2962 Self::Maybe(_) => "~const",
2963 }
2964 }
2965}
2966
2967#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
2969#[derive(HashStable_Generic)]
2970pub enum BoundAsyncness {
2971 Normal,
2973 Async(Span),
2975}
2976
2977impl BoundAsyncness {
2978 pub fn as_str(self) -> &'static str {
2979 match self {
2980 Self::Normal => "",
2981 Self::Async(_) => "async",
2982 }
2983 }
2984}
2985
2986#[derive(Clone, Encodable, Decodable, Debug)]
2987pub enum FnRetTy {
2988 Default(Span),
2993 Ty(P<Ty>),
2995}
2996
2997impl FnRetTy {
2998 pub fn span(&self) -> Span {
2999 match self {
3000 &FnRetTy::Default(span) => span,
3001 FnRetTy::Ty(ty) => ty.span,
3002 }
3003 }
3004}
3005
3006#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3007pub enum Inline {
3008 Yes,
3009 No,
3010}
3011
3012#[derive(Clone, Encodable, Decodable, Debug)]
3014pub enum ModKind {
3015 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3020 Unloaded,
3022}
3023
3024#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3025pub struct ModSpans {
3026 pub inner_span: Span,
3029 pub inject_use_span: Span,
3030}
3031
3032#[derive(Clone, Encodable, Decodable, Debug)]
3036pub struct ForeignMod {
3037 pub extern_span: Span,
3039 pub safety: Safety,
3042 pub abi: Option<StrLit>,
3043 pub items: ThinVec<P<ForeignItem>>,
3044}
3045
3046#[derive(Clone, Encodable, Decodable, Debug)]
3047pub struct EnumDef {
3048 pub variants: ThinVec<Variant>,
3049}
3050#[derive(Clone, Encodable, Decodable, Debug)]
3052pub struct Variant {
3053 pub attrs: AttrVec,
3055 pub id: NodeId,
3057 pub span: Span,
3059 pub vis: Visibility,
3061 pub ident: Ident,
3063
3064 pub data: VariantData,
3066 pub disr_expr: Option<AnonConst>,
3068 pub is_placeholder: bool,
3070}
3071
3072#[derive(Clone, Encodable, Decodable, Debug)]
3074pub enum UseTreeKind {
3075 Simple(Option<Ident>),
3077 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3086 Glob,
3088}
3089
3090#[derive(Clone, Encodable, Decodable, Debug)]
3093pub struct UseTree {
3094 pub prefix: Path,
3095 pub kind: UseTreeKind,
3096 pub span: Span,
3097}
3098
3099impl UseTree {
3100 pub fn ident(&self) -> Ident {
3101 match self.kind {
3102 UseTreeKind::Simple(Some(rename)) => rename,
3103 UseTreeKind::Simple(None) => {
3104 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3105 }
3106 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3107 }
3108 }
3109}
3110
3111#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3115pub enum AttrStyle {
3116 Outer,
3117 Inner,
3118}
3119
3120pub type AttrVec = ThinVec<Attribute>;
3122
3123#[derive(Clone, Encodable, Decodable, Debug)]
3125pub struct Attribute {
3126 pub kind: AttrKind,
3127 pub id: AttrId,
3128 pub style: AttrStyle,
3131 pub span: Span,
3132}
3133
3134#[derive(Clone, Encodable, Decodable, Debug)]
3135pub enum AttrKind {
3136 Normal(P<NormalAttr>),
3138
3139 DocComment(CommentKind, Symbol),
3143}
3144
3145#[derive(Clone, Encodable, Decodable, Debug)]
3146pub struct NormalAttr {
3147 pub item: AttrItem,
3148 pub tokens: Option<LazyAttrTokenStream>,
3150}
3151
3152impl NormalAttr {
3153 pub fn from_ident(ident: Ident) -> Self {
3154 Self {
3155 item: AttrItem {
3156 unsafety: Safety::Default,
3157 path: Path::from_ident(ident),
3158 args: AttrArgs::Empty,
3159 tokens: None,
3160 },
3161 tokens: None,
3162 }
3163 }
3164}
3165
3166#[derive(Clone, Encodable, Decodable, Debug)]
3167pub struct AttrItem {
3168 pub unsafety: Safety,
3169 pub path: Path,
3170 pub args: AttrArgs,
3171 pub tokens: Option<LazyAttrTokenStream>,
3173}
3174
3175impl AttrItem {
3176 pub fn is_valid_for_outer_style(&self) -> bool {
3177 self.path == sym::cfg_attr
3178 || self.path == sym::cfg
3179 || self.path == sym::forbid
3180 || self.path == sym::warn
3181 || self.path == sym::allow
3182 || self.path == sym::deny
3183 }
3184}
3185
3186#[derive(Clone, Encodable, Decodable, Debug)]
3193pub struct TraitRef {
3194 pub path: Path,
3195 pub ref_id: NodeId,
3196}
3197
3198#[derive(Clone, Encodable, Decodable, Debug)]
3199pub struct PolyTraitRef {
3200 pub bound_generic_params: ThinVec<GenericParam>,
3202
3203 pub modifiers: TraitBoundModifiers,
3205
3206 pub trait_ref: TraitRef,
3208
3209 pub span: Span,
3210}
3211
3212impl PolyTraitRef {
3213 pub fn new(
3214 generic_params: ThinVec<GenericParam>,
3215 path: Path,
3216 modifiers: TraitBoundModifiers,
3217 span: Span,
3218 ) -> Self {
3219 PolyTraitRef {
3220 bound_generic_params: generic_params,
3221 modifiers,
3222 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3223 span,
3224 }
3225 }
3226}
3227
3228#[derive(Clone, Encodable, Decodable, Debug)]
3229pub struct Visibility {
3230 pub kind: VisibilityKind,
3231 pub span: Span,
3232 pub tokens: Option<LazyAttrTokenStream>,
3233}
3234
3235#[derive(Clone, Encodable, Decodable, Debug)]
3236pub enum VisibilityKind {
3237 Public,
3238 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3239 Inherited,
3240}
3241
3242impl VisibilityKind {
3243 pub fn is_pub(&self) -> bool {
3244 matches!(self, VisibilityKind::Public)
3245 }
3246}
3247
3248#[derive(Clone, Encodable, Decodable, Debug)]
3252pub struct FieldDef {
3253 pub attrs: AttrVec,
3254 pub id: NodeId,
3255 pub span: Span,
3256 pub vis: Visibility,
3257 pub safety: Safety,
3258 pub ident: Option<Ident>,
3259
3260 pub ty: P<Ty>,
3261 pub default: Option<AnonConst>,
3262 pub is_placeholder: bool,
3263}
3264
3265#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3267pub enum Recovered {
3268 No,
3269 Yes(ErrorGuaranteed),
3270}
3271
3272#[derive(Clone, Encodable, Decodable, Debug)]
3274pub enum VariantData {
3275 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3279 Tuple(ThinVec<FieldDef>, NodeId),
3283 Unit(NodeId),
3287}
3288
3289impl VariantData {
3290 pub fn fields(&self) -> &[FieldDef] {
3292 match self {
3293 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3294 _ => &[],
3295 }
3296 }
3297
3298 pub fn ctor_node_id(&self) -> Option<NodeId> {
3300 match *self {
3301 VariantData::Struct { .. } => None,
3302 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3303 }
3304 }
3305}
3306
3307#[derive(Clone, Encodable, Decodable, Debug)]
3309pub struct Item<K = ItemKind> {
3310 pub attrs: AttrVec,
3311 pub id: NodeId,
3312 pub span: Span,
3313 pub vis: Visibility,
3314 pub ident: Ident,
3317
3318 pub kind: K,
3319
3320 pub tokens: Option<LazyAttrTokenStream>,
3328}
3329
3330impl Item {
3331 pub fn span_with_attributes(&self) -> Span {
3333 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3334 }
3335
3336 pub fn opt_generics(&self) -> Option<&Generics> {
3337 match &self.kind {
3338 ItemKind::ExternCrate(_)
3339 | ItemKind::Use(_)
3340 | ItemKind::Mod(_, _)
3341 | ItemKind::ForeignMod(_)
3342 | ItemKind::GlobalAsm(_)
3343 | ItemKind::MacCall(_)
3344 | ItemKind::Delegation(_)
3345 | ItemKind::DelegationMac(_)
3346 | ItemKind::MacroDef(_) => None,
3347 ItemKind::Static(_) => None,
3348 ItemKind::Const(i) => Some(&i.generics),
3349 ItemKind::Fn(i) => Some(&i.generics),
3350 ItemKind::TyAlias(i) => Some(&i.generics),
3351 ItemKind::TraitAlias(generics, _)
3352 | ItemKind::Enum(_, generics)
3353 | ItemKind::Struct(_, generics)
3354 | ItemKind::Union(_, generics) => Some(&generics),
3355 ItemKind::Trait(i) => Some(&i.generics),
3356 ItemKind::Impl(i) => Some(&i.generics),
3357 }
3358 }
3359}
3360
3361#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3363pub enum Extern {
3364 None,
3368 Implicit(Span),
3374 Explicit(StrLit, Span),
3378}
3379
3380impl Extern {
3381 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3382 match abi {
3383 Some(name) => Extern::Explicit(name, span),
3384 None => Extern::Implicit(span),
3385 }
3386 }
3387}
3388
3389#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3394pub struct FnHeader {
3395 pub safety: Safety,
3397 pub coroutine_kind: Option<CoroutineKind>,
3399 pub constness: Const,
3401 pub ext: Extern,
3403}
3404
3405impl FnHeader {
3406 pub fn has_qualifiers(&self) -> bool {
3408 let Self { safety, coroutine_kind, constness, ext } = self;
3409 matches!(safety, Safety::Unsafe(_))
3410 || coroutine_kind.is_some()
3411 || matches!(constness, Const::Yes(_))
3412 || !matches!(ext, Extern::None)
3413 }
3414}
3415
3416impl Default for FnHeader {
3417 fn default() -> FnHeader {
3418 FnHeader {
3419 safety: Safety::Default,
3420 coroutine_kind: None,
3421 constness: Const::No,
3422 ext: Extern::None,
3423 }
3424 }
3425}
3426
3427#[derive(Clone, Encodable, Decodable, Debug)]
3428pub struct Trait {
3429 pub safety: Safety,
3430 pub is_auto: IsAuto,
3431 pub generics: Generics,
3432 pub bounds: GenericBounds,
3433 pub items: ThinVec<P<AssocItem>>,
3434}
3435
3436#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3455pub struct TyAliasWhereClause {
3456 pub has_where_token: bool,
3457 pub span: Span,
3458}
3459
3460#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3462pub struct TyAliasWhereClauses {
3463 pub before: TyAliasWhereClause,
3465 pub after: TyAliasWhereClause,
3467 pub split: usize,
3471}
3472
3473#[derive(Clone, Encodable, Decodable, Debug)]
3474pub struct TyAlias {
3475 pub defaultness: Defaultness,
3476 pub generics: Generics,
3477 pub where_clauses: TyAliasWhereClauses,
3478 pub bounds: GenericBounds,
3479 pub ty: Option<P<Ty>>,
3480}
3481
3482#[derive(Clone, Encodable, Decodable, Debug)]
3483pub struct Impl {
3484 pub defaultness: Defaultness,
3485 pub safety: Safety,
3486 pub generics: Generics,
3487 pub constness: Const,
3488 pub polarity: ImplPolarity,
3489 pub of_trait: Option<TraitRef>,
3491 pub self_ty: P<Ty>,
3492 pub items: ThinVec<P<AssocItem>>,
3493}
3494
3495#[derive(Clone, Encodable, Decodable, Debug, Default)]
3496pub struct FnContract {
3497 pub requires: Option<P<Expr>>,
3498 pub ensures: Option<P<Expr>>,
3499}
3500
3501#[derive(Clone, Encodable, Decodable, Debug)]
3502pub struct Fn {
3503 pub defaultness: Defaultness,
3504 pub generics: Generics,
3505 pub sig: FnSig,
3506 pub contract: Option<P<FnContract>>,
3507 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3508 pub body: Option<P<Block>>,
3509}
3510
3511#[derive(Clone, Encodable, Decodable, Debug)]
3512pub struct Delegation {
3513 pub id: NodeId,
3515 pub qself: Option<P<QSelf>>,
3516 pub path: Path,
3517 pub rename: Option<Ident>,
3518 pub body: Option<P<Block>>,
3519 pub from_glob: bool,
3521}
3522
3523#[derive(Clone, Encodable, Decodable, Debug)]
3524pub struct DelegationMac {
3525 pub qself: Option<P<QSelf>>,
3526 pub prefix: Path,
3527 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3529 pub body: Option<P<Block>>,
3530}
3531
3532#[derive(Clone, Encodable, Decodable, Debug)]
3533pub struct StaticItem {
3534 pub ty: P<Ty>,
3535 pub safety: Safety,
3536 pub mutability: Mutability,
3537 pub expr: Option<P<Expr>>,
3538}
3539
3540#[derive(Clone, Encodable, Decodable, Debug)]
3541pub struct ConstItem {
3542 pub defaultness: Defaultness,
3543 pub generics: Generics,
3544 pub ty: P<Ty>,
3545 pub expr: Option<P<Expr>>,
3546}
3547
3548#[derive(Clone, Encodable, Decodable, Debug)]
3550pub enum ItemKind {
3551 ExternCrate(Option<Symbol>),
3555 Use(UseTree),
3559 Static(Box<StaticItem>),
3563 Const(Box<ConstItem>),
3567 Fn(Box<Fn>),
3571 Mod(Safety, ModKind),
3577 ForeignMod(ForeignMod),
3581 GlobalAsm(Box<InlineAsm>),
3583 TyAlias(Box<TyAlias>),
3587 Enum(EnumDef, Generics),
3591 Struct(VariantData, Generics),
3595 Union(VariantData, Generics),
3599 Trait(Box<Trait>),
3603 TraitAlias(Generics, GenericBounds),
3607 Impl(Box<Impl>),
3611 MacCall(P<MacCall>),
3615
3616 MacroDef(MacroDef),
3618
3619 Delegation(Box<Delegation>),
3623 DelegationMac(Box<DelegationMac>),
3626}
3627
3628impl ItemKind {
3629 pub fn article(&self) -> &'static str {
3631 use ItemKind::*;
3632 match self {
3633 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3634 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3635 | Delegation(..) | DelegationMac(..) => "a",
3636 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3637 }
3638 }
3639
3640 pub fn descr(&self) -> &'static str {
3641 match self {
3642 ItemKind::ExternCrate(..) => "extern crate",
3643 ItemKind::Use(..) => "`use` import",
3644 ItemKind::Static(..) => "static item",
3645 ItemKind::Const(..) => "constant item",
3646 ItemKind::Fn(..) => "function",
3647 ItemKind::Mod(..) => "module",
3648 ItemKind::ForeignMod(..) => "extern block",
3649 ItemKind::GlobalAsm(..) => "global asm item",
3650 ItemKind::TyAlias(..) => "type alias",
3651 ItemKind::Enum(..) => "enum",
3652 ItemKind::Struct(..) => "struct",
3653 ItemKind::Union(..) => "union",
3654 ItemKind::Trait(..) => "trait",
3655 ItemKind::TraitAlias(..) => "trait alias",
3656 ItemKind::MacCall(..) => "item macro invocation",
3657 ItemKind::MacroDef(..) => "macro definition",
3658 ItemKind::Impl { .. } => "implementation",
3659 ItemKind::Delegation(..) => "delegated function",
3660 ItemKind::DelegationMac(..) => "delegation",
3661 }
3662 }
3663
3664 pub fn generics(&self) -> Option<&Generics> {
3665 match self {
3666 Self::Fn(box Fn { generics, .. })
3667 | Self::TyAlias(box TyAlias { generics, .. })
3668 | Self::Const(box ConstItem { generics, .. })
3669 | Self::Enum(_, generics)
3670 | Self::Struct(_, generics)
3671 | Self::Union(_, generics)
3672 | Self::Trait(box Trait { generics, .. })
3673 | Self::TraitAlias(generics, _)
3674 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3675 _ => None,
3676 }
3677 }
3678}
3679
3680pub type AssocItem = Item<AssocItemKind>;
3683
3684#[derive(Clone, Encodable, Decodable, Debug)]
3692pub enum AssocItemKind {
3693 Const(Box<ConstItem>),
3696 Fn(Box<Fn>),
3698 Type(Box<TyAlias>),
3700 MacCall(P<MacCall>),
3702 Delegation(Box<Delegation>),
3704 DelegationMac(Box<DelegationMac>),
3706}
3707
3708impl AssocItemKind {
3709 pub fn defaultness(&self) -> Defaultness {
3710 match *self {
3711 Self::Const(box ConstItem { defaultness, .. })
3712 | Self::Fn(box Fn { defaultness, .. })
3713 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3714 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3715 Defaultness::Final
3716 }
3717 }
3718 }
3719}
3720
3721impl From<AssocItemKind> for ItemKind {
3722 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3723 match assoc_item_kind {
3724 AssocItemKind::Const(item) => ItemKind::Const(item),
3725 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3726 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3727 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3728 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3729 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3730 }
3731 }
3732}
3733
3734impl TryFrom<ItemKind> for AssocItemKind {
3735 type Error = ItemKind;
3736
3737 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3738 Ok(match item_kind {
3739 ItemKind::Const(item) => AssocItemKind::Const(item),
3740 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3741 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3742 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3743 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3744 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3745 _ => return Err(item_kind),
3746 })
3747 }
3748}
3749
3750#[derive(Clone, Encodable, Decodable, Debug)]
3752pub enum ForeignItemKind {
3753 Static(Box<StaticItem>),
3755 Fn(Box<Fn>),
3757 TyAlias(Box<TyAlias>),
3759 MacCall(P<MacCall>),
3761}
3762
3763impl From<ForeignItemKind> for ItemKind {
3764 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3765 match foreign_item_kind {
3766 ForeignItemKind::Static(box static_foreign_item) => {
3767 ItemKind::Static(Box::new(static_foreign_item))
3768 }
3769 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3770 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3771 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3772 }
3773 }
3774}
3775
3776impl TryFrom<ItemKind> for ForeignItemKind {
3777 type Error = ItemKind;
3778
3779 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3780 Ok(match item_kind {
3781 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3782 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3783 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3784 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3785 _ => return Err(item_kind),
3786 })
3787 }
3788}
3789
3790pub type ForeignItem = Item<ForeignItemKind>;
3791
3792#[cfg(target_pointer_width = "64")]
3794mod size_asserts {
3795 use rustc_data_structures::static_assert_size;
3796
3797 use super::*;
3798 static_assert_size!(AssocItem, 88);
3800 static_assert_size!(AssocItemKind, 16);
3801 static_assert_size!(Attribute, 32);
3802 static_assert_size!(Block, 32);
3803 static_assert_size!(Expr, 72);
3804 static_assert_size!(ExprKind, 40);
3805 static_assert_size!(Fn, 176);
3806 static_assert_size!(ForeignItem, 88);
3807 static_assert_size!(ForeignItemKind, 16);
3808 static_assert_size!(GenericArg, 24);
3809 static_assert_size!(GenericBound, 88);
3810 static_assert_size!(Generics, 40);
3811 static_assert_size!(Impl, 136);
3812 static_assert_size!(Item, 136);
3813 static_assert_size!(ItemKind, 64);
3814 static_assert_size!(LitKind, 24);
3815 static_assert_size!(Local, 80);
3816 static_assert_size!(MetaItemLit, 40);
3817 static_assert_size!(Param, 40);
3818 static_assert_size!(Pat, 72);
3819 static_assert_size!(Path, 24);
3820 static_assert_size!(PathSegment, 24);
3821 static_assert_size!(PatKind, 48);
3822 static_assert_size!(Stmt, 32);
3823 static_assert_size!(StmtKind, 16);
3824 static_assert_size!(Ty, 64);
3825 static_assert_size!(TyKind, 40);
3826 }