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}
549
550#[derive(Clone, Encodable, Decodable, Debug)]
554pub struct Pat {
555 pub id: NodeId,
556 pub kind: PatKind,
557 pub span: Span,
558 pub tokens: Option<LazyAttrTokenStream>,
559}
560
561impl Pat {
562 pub fn to_ty(&self) -> Option<P<Ty>> {
565 let kind = match &self.kind {
566 PatKind::Wild => TyKind::Infer,
568 PatKind::Ident(BindingMode::NONE, ident, None) => {
570 TyKind::Path(None, Path::from_ident(*ident))
571 }
572 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
573 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
574 PatKind::Ref(pat, mutbl) => {
576 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
577 }
578 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
581 pat.to_ty().map(TyKind::Slice)?
582 }
583 PatKind::Tuple(pats) => {
586 let mut tys = ThinVec::with_capacity(pats.len());
587 for pat in pats {
589 tys.push(pat.to_ty()?);
590 }
591 TyKind::Tup(tys)
592 }
593 _ => return None,
594 };
595
596 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
597 }
598
599 pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
603 if !it(self) {
604 return;
605 }
606
607 match &self.kind {
608 PatKind::Ident(_, _, Some(p)) => p.walk(it),
610
611 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
613
614 PatKind::TupleStruct(_, _, s)
616 | PatKind::Tuple(s)
617 | PatKind::Slice(s)
618 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
619
620 PatKind::Box(s)
622 | PatKind::Deref(s)
623 | PatKind::Ref(s, _)
624 | PatKind::Paren(s)
625 | PatKind::Guard(s, _) => s.walk(it),
626
627 PatKind::Wild
629 | PatKind::Rest
630 | PatKind::Never
631 | PatKind::Expr(_)
632 | PatKind::Range(..)
633 | PatKind::Ident(..)
634 | PatKind::Path(..)
635 | PatKind::MacCall(_)
636 | PatKind::Err(_) => {}
637 }
638 }
639
640 pub fn is_rest(&self) -> bool {
642 matches!(self.kind, PatKind::Rest)
643 }
644
645 pub fn could_be_never_pattern(&self) -> bool {
648 let mut could_be_never_pattern = false;
649 self.walk(&mut |pat| match &pat.kind {
650 PatKind::Never | PatKind::MacCall(_) => {
651 could_be_never_pattern = true;
652 false
653 }
654 PatKind::Or(s) => {
655 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
656 false
657 }
658 _ => true,
659 });
660 could_be_never_pattern
661 }
662
663 pub fn contains_never_pattern(&self) -> bool {
666 let mut contains_never_pattern = false;
667 self.walk(&mut |pat| {
668 if matches!(pat.kind, PatKind::Never) {
669 contains_never_pattern = true;
670 }
671 true
672 });
673 contains_never_pattern
674 }
675
676 pub fn descr(&self) -> Option<String> {
678 match &self.kind {
679 PatKind::Wild => Some("_".to_string()),
680 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
681 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
682 _ => None,
683 }
684 }
685}
686
687#[derive(Clone, Encodable, Decodable, Debug)]
693pub struct PatField {
694 pub ident: Ident,
696 pub pat: P<Pat>,
698 pub is_shorthand: bool,
699 pub attrs: AttrVec,
700 pub id: NodeId,
701 pub span: Span,
702 pub is_placeholder: bool,
703}
704
705#[derive(Clone, Copy, Debug, Eq, PartialEq)]
706#[derive(Encodable, Decodable, HashStable_Generic)]
707pub enum ByRef {
708 Yes(Mutability),
709 No,
710}
711
712impl ByRef {
713 #[must_use]
714 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
715 if let ByRef::Yes(old_mutbl) = &mut self {
716 *old_mutbl = cmp::min(*old_mutbl, mutbl);
717 }
718 self
719 }
720}
721
722#[derive(Clone, Copy, Debug, Eq, PartialEq)]
728#[derive(Encodable, Decodable, HashStable_Generic)]
729pub struct BindingMode(pub ByRef, pub Mutability);
730
731impl BindingMode {
732 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
733 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
734 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
735 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
736 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
737 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
738
739 pub fn prefix_str(self) -> &'static str {
740 match self {
741 Self::NONE => "",
742 Self::REF => "ref ",
743 Self::MUT => "mut ",
744 Self::REF_MUT => "ref mut ",
745 Self::MUT_REF => "mut ref ",
746 Self::MUT_REF_MUT => "mut ref mut ",
747 }
748 }
749}
750
751#[derive(Clone, Encodable, Decodable, Debug)]
752pub enum RangeEnd {
753 Included(RangeSyntax),
755 Excluded,
757}
758
759#[derive(Clone, Encodable, Decodable, Debug)]
760pub enum RangeSyntax {
761 DotDotDot,
763 DotDotEq,
765}
766
767#[derive(Clone, Encodable, Decodable, Debug)]
771pub enum PatKind {
772 Wild,
774
775 Ident(BindingMode, Ident, Option<P<Pat>>),
780
781 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
783
784 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
786
787 Or(ThinVec<P<Pat>>),
790
791 Path(Option<P<QSelf>>, Path),
796
797 Tuple(ThinVec<P<Pat>>),
799
800 Box(P<Pat>),
802
803 Deref(P<Pat>),
805
806 Ref(P<Pat>, Mutability),
808
809 Expr(P<Expr>),
811
812 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
814
815 Slice(ThinVec<P<Pat>>),
817
818 Rest,
831
832 Never,
834
835 Guard(P<Pat>, P<Expr>),
837
838 Paren(P<Pat>),
840
841 MacCall(P<MacCall>),
843
844 Err(ErrorGuaranteed),
846}
847
848#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
850pub enum PatFieldsRest {
851 Rest,
853 Recovered(ErrorGuaranteed),
855 None,
857}
858
859#[derive(Clone, Copy, PartialEq, Eq, Debug)]
862#[derive(Encodable, Decodable, HashStable_Generic)]
863pub enum BorrowKind {
864 Ref,
868 Raw,
872}
873
874#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
875pub enum BinOpKind {
876 Add,
878 Sub,
880 Mul,
882 Div,
884 Rem,
886 And,
888 Or,
890 BitXor,
892 BitAnd,
894 BitOr,
896 Shl,
898 Shr,
900 Eq,
902 Lt,
904 Le,
906 Ne,
908 Ge,
910 Gt,
912}
913
914impl BinOpKind {
915 pub fn as_str(&self) -> &'static str {
916 use BinOpKind::*;
917 match self {
918 Add => "+",
919 Sub => "-",
920 Mul => "*",
921 Div => "/",
922 Rem => "%",
923 And => "&&",
924 Or => "||",
925 BitXor => "^",
926 BitAnd => "&",
927 BitOr => "|",
928 Shl => "<<",
929 Shr => ">>",
930 Eq => "==",
931 Lt => "<",
932 Le => "<=",
933 Ne => "!=",
934 Ge => ">=",
935 Gt => ">",
936 }
937 }
938
939 pub fn is_lazy(&self) -> bool {
940 matches!(self, BinOpKind::And | BinOpKind::Or)
941 }
942
943 pub fn precedence(&self) -> ExprPrecedence {
944 use BinOpKind::*;
945 match *self {
946 Mul | Div | Rem => ExprPrecedence::Product,
947 Add | Sub => ExprPrecedence::Sum,
948 Shl | Shr => ExprPrecedence::Shift,
949 BitAnd => ExprPrecedence::BitAnd,
950 BitXor => ExprPrecedence::BitXor,
951 BitOr => ExprPrecedence::BitOr,
952 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
953 And => ExprPrecedence::LAnd,
954 Or => ExprPrecedence::LOr,
955 }
956 }
957
958 pub fn fixity(&self) -> Fixity {
959 use BinOpKind::*;
960 match self {
961 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
962 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
963 Fixity::Left
964 }
965 }
966 }
967
968 pub fn is_comparison(self) -> bool {
969 use BinOpKind::*;
970 match self {
971 Eq | Ne | Lt | Le | Gt | Ge => true,
972 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
973 }
974 }
975
976 pub fn is_by_value(self) -> bool {
978 !self.is_comparison()
979 }
980}
981
982pub type BinOp = Spanned<BinOpKind>;
983
984#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
988pub enum UnOp {
989 Deref,
991 Not,
993 Neg,
995}
996
997impl UnOp {
998 pub fn as_str(&self) -> &'static str {
999 match self {
1000 UnOp::Deref => "*",
1001 UnOp::Not => "!",
1002 UnOp::Neg => "-",
1003 }
1004 }
1005
1006 pub fn is_by_value(self) -> bool {
1008 matches!(self, Self::Neg | Self::Not)
1009 }
1010}
1011
1012#[derive(Clone, Encodable, Decodable, Debug)]
1016pub struct Stmt {
1017 pub id: NodeId,
1018 pub kind: StmtKind,
1019 pub span: Span,
1020}
1021
1022impl Stmt {
1023 pub fn has_trailing_semicolon(&self) -> bool {
1024 match &self.kind {
1025 StmtKind::Semi(_) => true,
1026 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1027 _ => false,
1028 }
1029 }
1030
1031 pub fn add_trailing_semicolon(mut self) -> Self {
1039 self.kind = match self.kind {
1040 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1041 StmtKind::MacCall(mac) => {
1042 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1043 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1044 }))
1045 }
1046 kind => kind,
1047 };
1048
1049 self
1050 }
1051
1052 pub fn is_item(&self) -> bool {
1053 matches!(self.kind, StmtKind::Item(_))
1054 }
1055
1056 pub fn is_expr(&self) -> bool {
1057 matches!(self.kind, StmtKind::Expr(_))
1058 }
1059}
1060
1061#[derive(Clone, Encodable, Decodable, Debug)]
1063pub enum StmtKind {
1064 Let(P<Local>),
1066 Item(P<Item>),
1068 Expr(P<Expr>),
1070 Semi(P<Expr>),
1072 Empty,
1074 MacCall(P<MacCallStmt>),
1076}
1077
1078#[derive(Clone, Encodable, Decodable, Debug)]
1079pub struct MacCallStmt {
1080 pub mac: P<MacCall>,
1081 pub style: MacStmtStyle,
1082 pub attrs: AttrVec,
1083 pub tokens: Option<LazyAttrTokenStream>,
1084}
1085
1086#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1087pub enum MacStmtStyle {
1088 Semicolon,
1091 Braces,
1093 NoBraces,
1097}
1098
1099#[derive(Clone, Encodable, Decodable, Debug)]
1101pub struct Local {
1102 pub id: NodeId,
1103 pub pat: P<Pat>,
1104 pub ty: Option<P<Ty>>,
1105 pub kind: LocalKind,
1106 pub span: Span,
1107 pub colon_sp: Option<Span>,
1108 pub attrs: AttrVec,
1109 pub tokens: Option<LazyAttrTokenStream>,
1110}
1111
1112#[derive(Clone, Encodable, Decodable, Debug)]
1113pub enum LocalKind {
1114 Decl,
1117 Init(P<Expr>),
1120 InitElse(P<Expr>, P<Block>),
1123}
1124
1125impl LocalKind {
1126 pub fn init(&self) -> Option<&Expr> {
1127 match self {
1128 Self::Decl => None,
1129 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1130 }
1131 }
1132
1133 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1134 match self {
1135 Self::Decl => None,
1136 Self::Init(init) => Some((init, None)),
1137 Self::InitElse(init, els) => Some((init, Some(els))),
1138 }
1139 }
1140}
1141
1142#[derive(Clone, Encodable, Decodable, Debug)]
1153pub struct Arm {
1154 pub attrs: AttrVec,
1155 pub pat: P<Pat>,
1157 pub guard: Option<P<Expr>>,
1159 pub body: Option<P<Expr>>,
1161 pub span: Span,
1162 pub id: NodeId,
1163 pub is_placeholder: bool,
1164}
1165
1166#[derive(Clone, Encodable, Decodable, Debug)]
1168pub struct ExprField {
1169 pub attrs: AttrVec,
1170 pub id: NodeId,
1171 pub span: Span,
1172 pub ident: Ident,
1173 pub expr: P<Expr>,
1174 pub is_shorthand: bool,
1175 pub is_placeholder: bool,
1176}
1177
1178#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1179pub enum BlockCheckMode {
1180 Default,
1181 Unsafe(UnsafeSource),
1182}
1183
1184#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1185pub enum UnsafeSource {
1186 CompilerGenerated,
1187 UserProvided,
1188}
1189
1190#[derive(Clone, Encodable, Decodable, Debug)]
1196pub struct AnonConst {
1197 pub id: NodeId,
1198 pub value: P<Expr>,
1199}
1200
1201#[derive(Clone, Encodable, Decodable, Debug)]
1203pub struct Expr {
1204 pub id: NodeId,
1205 pub kind: ExprKind,
1206 pub span: Span,
1207 pub attrs: AttrVec,
1208 pub tokens: Option<LazyAttrTokenStream>,
1209}
1210
1211impl Expr {
1212 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1226 let this = self.maybe_unwrap_block();
1227 if allow_mgca_arg {
1228 matches!(this.kind, ExprKind::Path(..))
1229 } else {
1230 if let ExprKind::Path(None, path) = &this.kind
1231 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1232 {
1233 true
1234 } else {
1235 false
1236 }
1237 }
1238 }
1239
1240 pub fn maybe_unwrap_block(&self) -> &Expr {
1242 if let ExprKind::Block(block, None) = &self.kind
1243 && let [stmt] = block.stmts.as_slice()
1244 && let StmtKind::Expr(expr) = &stmt.kind
1245 {
1246 expr
1247 } else {
1248 self
1249 }
1250 }
1251
1252 pub fn optionally_braced_mac_call(
1258 &self,
1259 already_stripped_block: bool,
1260 ) -> Option<(bool, NodeId)> {
1261 match &self.kind {
1262 ExprKind::Block(block, None)
1263 if let [stmt] = &*block.stmts
1264 && !already_stripped_block =>
1265 {
1266 match &stmt.kind {
1267 StmtKind::MacCall(_) => Some((true, stmt.id)),
1268 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1269 Some((true, expr.id))
1270 }
1271 _ => None,
1272 }
1273 }
1274 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1275 _ => None,
1276 }
1277 }
1278
1279 pub fn to_bound(&self) -> Option<GenericBound> {
1280 match &self.kind {
1281 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1282 ThinVec::new(),
1283 path.clone(),
1284 TraitBoundModifiers::NONE,
1285 self.span,
1286 ))),
1287 _ => None,
1288 }
1289 }
1290
1291 pub fn peel_parens(&self) -> &Expr {
1292 let mut expr = self;
1293 while let ExprKind::Paren(inner) = &expr.kind {
1294 expr = inner;
1295 }
1296 expr
1297 }
1298
1299 pub fn peel_parens_and_refs(&self) -> &Expr {
1300 let mut expr = self;
1301 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1302 {
1303 expr = inner;
1304 }
1305 expr
1306 }
1307
1308 pub fn to_ty(&self) -> Option<P<Ty>> {
1310 let kind = match &self.kind {
1311 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1313 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1314
1315 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1316
1317 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1318 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1319 }
1320
1321 ExprKind::Repeat(expr, expr_len) => {
1322 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1323 }
1324
1325 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1326 expr.to_ty().map(TyKind::Slice)?
1327 }
1328
1329 ExprKind::Tup(exprs) => {
1330 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1331 TyKind::Tup(tys)
1332 }
1333
1334 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1338 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1339 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1340 } else {
1341 return None;
1342 }
1343 }
1344
1345 ExprKind::Underscore => TyKind::Infer,
1346
1347 _ => return None,
1349 };
1350
1351 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1352 }
1353
1354 pub fn precedence(&self) -> ExprPrecedence {
1355 match &self.kind {
1356 ExprKind::Closure(closure) => {
1357 match closure.fn_decl.output {
1358 FnRetTy::Default(_) => ExprPrecedence::Jump,
1359 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1360 }
1361 }
1362
1363 ExprKind::Break(..)
1364 | ExprKind::Ret(..)
1365 | ExprKind::Yield(..)
1366 | ExprKind::Yeet(..)
1367 | ExprKind::Become(..) => ExprPrecedence::Jump,
1368
1369 ExprKind::Range(..) => ExprPrecedence::Range,
1374
1375 ExprKind::Binary(op, ..) => op.node.precedence(),
1377 ExprKind::Cast(..) => ExprPrecedence::Cast,
1378
1379 ExprKind::Assign(..) |
1380 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1381
1382 ExprKind::AddrOf(..)
1384 | ExprKind::Let(..)
1389 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1390
1391 ExprKind::Array(_)
1393 | ExprKind::Await(..)
1394 | ExprKind::Use(..)
1395 | ExprKind::Block(..)
1396 | ExprKind::Call(..)
1397 | ExprKind::ConstBlock(_)
1398 | ExprKind::Continue(..)
1399 | ExprKind::Field(..)
1400 | ExprKind::ForLoop { .. }
1401 | ExprKind::FormatArgs(..)
1402 | ExprKind::Gen(..)
1403 | ExprKind::If(..)
1404 | ExprKind::IncludedBytes(..)
1405 | ExprKind::Index(..)
1406 | ExprKind::InlineAsm(..)
1407 | ExprKind::Lit(_)
1408 | ExprKind::Loop(..)
1409 | ExprKind::MacCall(..)
1410 | ExprKind::Match(..)
1411 | ExprKind::MethodCall(..)
1412 | ExprKind::OffsetOf(..)
1413 | ExprKind::Paren(..)
1414 | ExprKind::Path(..)
1415 | ExprKind::Repeat(..)
1416 | ExprKind::Struct(..)
1417 | ExprKind::Try(..)
1418 | ExprKind::TryBlock(..)
1419 | ExprKind::Tup(_)
1420 | ExprKind::Type(..)
1421 | ExprKind::Underscore
1422 | ExprKind::UnsafeBinderCast(..)
1423 | ExprKind::While(..)
1424 | ExprKind::Err(_)
1425 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1426 }
1427 }
1428
1429 pub fn is_approximately_pattern(&self) -> bool {
1431 matches!(
1432 &self.peel_parens().kind,
1433 ExprKind::Array(_)
1434 | ExprKind::Call(_, _)
1435 | ExprKind::Tup(_)
1436 | ExprKind::Lit(_)
1437 | ExprKind::Range(_, _, _)
1438 | ExprKind::Underscore
1439 | ExprKind::Path(_, _)
1440 | ExprKind::Struct(_)
1441 )
1442 }
1443}
1444
1445#[derive(Clone, Encodable, Decodable, Debug)]
1446pub struct Closure {
1447 pub binder: ClosureBinder,
1448 pub capture_clause: CaptureBy,
1449 pub constness: Const,
1450 pub coroutine_kind: Option<CoroutineKind>,
1451 pub movability: Movability,
1452 pub fn_decl: P<FnDecl>,
1453 pub body: P<Expr>,
1454 pub fn_decl_span: Span,
1456 pub fn_arg_span: Span,
1458}
1459
1460#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1462pub enum RangeLimits {
1463 HalfOpen,
1465 Closed,
1467}
1468
1469impl RangeLimits {
1470 pub fn as_str(&self) -> &'static str {
1471 match self {
1472 RangeLimits::HalfOpen => "..",
1473 RangeLimits::Closed => "..=",
1474 }
1475 }
1476}
1477
1478#[derive(Clone, Encodable, Decodable, Debug)]
1480pub struct MethodCall {
1481 pub seg: PathSegment,
1483 pub receiver: P<Expr>,
1485 pub args: ThinVec<P<Expr>>,
1487 pub span: Span,
1490}
1491
1492#[derive(Clone, Encodable, Decodable, Debug)]
1493pub enum StructRest {
1494 Base(P<Expr>),
1496 Rest(Span),
1498 None,
1500}
1501
1502#[derive(Clone, Encodable, Decodable, Debug)]
1503pub struct StructExpr {
1504 pub qself: Option<P<QSelf>>,
1505 pub path: Path,
1506 pub fields: ThinVec<ExprField>,
1507 pub rest: StructRest,
1508}
1509
1510#[derive(Clone, Encodable, Decodable, Debug)]
1512pub enum ExprKind {
1513 Array(ThinVec<P<Expr>>),
1515 ConstBlock(AnonConst),
1517 Call(P<Expr>, ThinVec<P<Expr>>),
1524 MethodCall(Box<MethodCall>),
1526 Tup(ThinVec<P<Expr>>),
1528 Binary(BinOp, P<Expr>, P<Expr>),
1530 Unary(UnOp, P<Expr>),
1532 Lit(token::Lit),
1534 Cast(P<Expr>, P<Ty>),
1536 Type(P<Expr>, P<Ty>),
1541 Let(P<Pat>, P<Expr>, Span, Recovered),
1546 If(P<Expr>, P<Block>, Option<P<Expr>>),
1550 While(P<Expr>, P<Block>, Option<Label>),
1554 ForLoop {
1560 pat: P<Pat>,
1561 iter: P<Expr>,
1562 body: P<Block>,
1563 label: Option<Label>,
1564 kind: ForLoopKind,
1565 },
1566 Loop(P<Block>, Option<Label>, Span),
1570 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1572 Closure(Box<Closure>),
1574 Block(P<Block>, Option<Label>),
1576 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1582 Await(P<Expr>, Span),
1584 Use(P<Expr>, Span),
1586
1587 TryBlock(P<Block>),
1589
1590 Assign(P<Expr>, P<Expr>, Span),
1593 AssignOp(BinOp, P<Expr>, P<Expr>),
1597 Field(P<Expr>, Ident),
1599 Index(P<Expr>, P<Expr>, Span),
1602 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1604 Underscore,
1606
1607 Path(Option<P<QSelf>>, Path),
1612
1613 AddrOf(BorrowKind, Mutability, P<Expr>),
1615 Break(Option<Label>, Option<P<Expr>>),
1617 Continue(Option<Label>),
1619 Ret(Option<P<Expr>>),
1621
1622 InlineAsm(P<InlineAsm>),
1624
1625 OffsetOf(P<Ty>, P<[Ident]>),
1630
1631 MacCall(P<MacCall>),
1633
1634 Struct(P<StructExpr>),
1638
1639 Repeat(P<Expr>, AnonConst),
1644
1645 Paren(P<Expr>),
1647
1648 Try(P<Expr>),
1650
1651 Yield(YieldKind),
1653
1654 Yeet(Option<P<Expr>>),
1657
1658 Become(P<Expr>),
1662
1663 IncludedBytes(Arc<[u8]>),
1668
1669 FormatArgs(P<FormatArgs>),
1671
1672 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1673
1674 Err(ErrorGuaranteed),
1676
1677 Dummy,
1679}
1680
1681#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1683pub enum ForLoopKind {
1684 For,
1685 ForAwait,
1686}
1687
1688#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1690pub enum GenBlockKind {
1691 Async,
1692 Gen,
1693 AsyncGen,
1694}
1695
1696impl fmt::Display for GenBlockKind {
1697 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1698 self.modifier().fmt(f)
1699 }
1700}
1701
1702impl GenBlockKind {
1703 pub fn modifier(&self) -> &'static str {
1704 match self {
1705 GenBlockKind::Async => "async",
1706 GenBlockKind::Gen => "gen",
1707 GenBlockKind::AsyncGen => "async gen",
1708 }
1709 }
1710}
1711
1712#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1714#[derive(Encodable, Decodable, HashStable_Generic)]
1715pub enum UnsafeBinderCastKind {
1716 Wrap,
1718 Unwrap,
1720}
1721
1722#[derive(Clone, Encodable, Decodable, Debug)]
1737pub struct QSelf {
1738 pub ty: P<Ty>,
1739
1740 pub path_span: Span,
1744 pub position: usize,
1745}
1746
1747#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1749pub enum CaptureBy {
1750 Value {
1752 move_kw: Span,
1754 },
1755 Ref,
1757 Use {
1763 use_kw: Span,
1765 },
1766}
1767
1768#[derive(Clone, Encodable, Decodable, Debug)]
1770pub enum ClosureBinder {
1771 NotPresent,
1773 For {
1775 span: Span,
1782
1783 generic_params: ThinVec<GenericParam>,
1790 },
1791}
1792
1793#[derive(Clone, Encodable, Decodable, Debug)]
1796pub struct MacCall {
1797 pub path: Path,
1798 pub args: P<DelimArgs>,
1799}
1800
1801impl MacCall {
1802 pub fn span(&self) -> Span {
1803 self.path.span.to(self.args.dspan.entire())
1804 }
1805}
1806
1807#[derive(Clone, Encodable, Decodable, Debug)]
1809pub enum AttrArgs {
1810 Empty,
1812 Delimited(DelimArgs),
1814 Eq {
1816 eq_span: Span,
1818 expr: P<Expr>,
1819 },
1820}
1821
1822impl AttrArgs {
1823 pub fn span(&self) -> Option<Span> {
1824 match self {
1825 AttrArgs::Empty => None,
1826 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1827 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1828 }
1829 }
1830
1831 pub fn inner_tokens(&self) -> TokenStream {
1834 match self {
1835 AttrArgs::Empty => TokenStream::default(),
1836 AttrArgs::Delimited(args) => args.tokens.clone(),
1837 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1838 }
1839 }
1840}
1841
1842#[derive(Clone, Encodable, Decodable, Debug)]
1844pub struct DelimArgs {
1845 pub dspan: DelimSpan,
1846 pub delim: Delimiter, pub tokens: TokenStream,
1848}
1849
1850impl DelimArgs {
1851 pub fn need_semicolon(&self) -> bool {
1854 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1855 }
1856}
1857
1858impl<CTX> HashStable<CTX> for DelimArgs
1859where
1860 CTX: crate::HashStableContext,
1861{
1862 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
1863 let DelimArgs { dspan, delim, tokens } = self;
1864 dspan.hash_stable(ctx, hasher);
1865 delim.hash_stable(ctx, hasher);
1866 tokens.hash_stable(ctx, hasher);
1867 }
1868}
1869
1870#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1872pub struct MacroDef {
1873 pub body: P<DelimArgs>,
1874 pub macro_rules: bool,
1876}
1877
1878#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1879#[derive(HashStable_Generic)]
1880pub enum StrStyle {
1881 Cooked,
1883 Raw(u8),
1887}
1888
1889#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1891pub enum MatchKind {
1892 Prefix,
1894 Postfix,
1896}
1897
1898#[derive(Clone, Encodable, Decodable, Debug)]
1900pub enum YieldKind {
1901 Prefix(Option<P<Expr>>),
1903 Postfix(P<Expr>),
1905}
1906
1907impl YieldKind {
1908 pub const fn expr(&self) -> Option<&P<Expr>> {
1912 match self {
1913 YieldKind::Prefix(expr) => expr.as_ref(),
1914 YieldKind::Postfix(expr) => Some(expr),
1915 }
1916 }
1917
1918 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1920 match self {
1921 YieldKind::Prefix(expr) => expr.as_mut(),
1922 YieldKind::Postfix(expr) => Some(expr),
1923 }
1924 }
1925
1926 pub const fn same_kind(&self, other: &Self) -> bool {
1928 match (self, other) {
1929 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
1930 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
1931 _ => false,
1932 }
1933 }
1934}
1935
1936#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1938pub struct MetaItemLit {
1939 pub symbol: Symbol,
1941 pub suffix: Option<Symbol>,
1943 pub kind: LitKind,
1946 pub span: Span,
1947}
1948
1949#[derive(Clone, Copy, Encodable, Decodable, Debug)]
1951pub struct StrLit {
1952 pub symbol: Symbol,
1954 pub suffix: Option<Symbol>,
1956 pub symbol_unescaped: Symbol,
1958 pub style: StrStyle,
1959 pub span: Span,
1960}
1961
1962impl StrLit {
1963 pub fn as_token_lit(&self) -> token::Lit {
1964 let token_kind = match self.style {
1965 StrStyle::Cooked => token::Str,
1966 StrStyle::Raw(n) => token::StrRaw(n),
1967 };
1968 token::Lit::new(token_kind, self.symbol, self.suffix)
1969 }
1970}
1971
1972#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1974#[derive(HashStable_Generic)]
1975pub enum LitIntType {
1976 Signed(IntTy),
1978 Unsigned(UintTy),
1980 Unsuffixed,
1982}
1983
1984#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1986#[derive(HashStable_Generic)]
1987pub enum LitFloatType {
1988 Suffixed(FloatTy),
1990 Unsuffixed,
1992}
1993
1994#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2001pub enum LitKind {
2002 Str(Symbol, StrStyle),
2005 ByteStr(Arc<[u8]>, StrStyle),
2008 CStr(Arc<[u8]>, StrStyle),
2010 Byte(u8),
2012 Char(char),
2014 Int(Pu128, LitIntType),
2016 Float(Symbol, LitFloatType),
2020 Bool(bool),
2022 Err(ErrorGuaranteed),
2024}
2025
2026impl LitKind {
2027 pub fn str(&self) -> Option<Symbol> {
2028 match *self {
2029 LitKind::Str(s, _) => Some(s),
2030 _ => None,
2031 }
2032 }
2033
2034 pub fn is_str(&self) -> bool {
2036 matches!(self, LitKind::Str(..))
2037 }
2038
2039 pub fn is_bytestr(&self) -> bool {
2041 matches!(self, LitKind::ByteStr(..))
2042 }
2043
2044 pub fn is_numeric(&self) -> bool {
2046 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2047 }
2048
2049 pub fn is_unsuffixed(&self) -> bool {
2052 !self.is_suffixed()
2053 }
2054
2055 pub fn is_suffixed(&self) -> bool {
2057 match *self {
2058 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2060 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2061 LitKind::Str(..)
2063 | LitKind::ByteStr(..)
2064 | LitKind::CStr(..)
2065 | LitKind::Byte(..)
2066 | LitKind::Char(..)
2067 | LitKind::Int(_, LitIntType::Unsuffixed)
2068 | LitKind::Float(_, LitFloatType::Unsuffixed)
2069 | LitKind::Bool(..)
2070 | LitKind::Err(_) => false,
2071 }
2072 }
2073}
2074
2075#[derive(Clone, Encodable, Decodable, Debug)]
2078pub struct MutTy {
2079 pub ty: P<Ty>,
2080 pub mutbl: Mutability,
2081}
2082
2083#[derive(Clone, Encodable, Decodable, Debug)]
2086pub struct FnSig {
2087 pub header: FnHeader,
2088 pub decl: P<FnDecl>,
2089 pub span: Span,
2090}
2091
2092#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2093#[derive(Encodable, Decodable, HashStable_Generic)]
2094pub enum FloatTy {
2095 F16,
2096 F32,
2097 F64,
2098 F128,
2099}
2100
2101impl FloatTy {
2102 pub fn name_str(self) -> &'static str {
2103 match self {
2104 FloatTy::F16 => "f16",
2105 FloatTy::F32 => "f32",
2106 FloatTy::F64 => "f64",
2107 FloatTy::F128 => "f128",
2108 }
2109 }
2110
2111 pub fn name(self) -> Symbol {
2112 match self {
2113 FloatTy::F16 => sym::f16,
2114 FloatTy::F32 => sym::f32,
2115 FloatTy::F64 => sym::f64,
2116 FloatTy::F128 => sym::f128,
2117 }
2118 }
2119}
2120
2121#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2122#[derive(Encodable, Decodable, HashStable_Generic)]
2123pub enum IntTy {
2124 Isize,
2125 I8,
2126 I16,
2127 I32,
2128 I64,
2129 I128,
2130}
2131
2132impl IntTy {
2133 pub fn name_str(&self) -> &'static str {
2134 match *self {
2135 IntTy::Isize => "isize",
2136 IntTy::I8 => "i8",
2137 IntTy::I16 => "i16",
2138 IntTy::I32 => "i32",
2139 IntTy::I64 => "i64",
2140 IntTy::I128 => "i128",
2141 }
2142 }
2143
2144 pub fn name(&self) -> Symbol {
2145 match *self {
2146 IntTy::Isize => sym::isize,
2147 IntTy::I8 => sym::i8,
2148 IntTy::I16 => sym::i16,
2149 IntTy::I32 => sym::i32,
2150 IntTy::I64 => sym::i64,
2151 IntTy::I128 => sym::i128,
2152 }
2153 }
2154}
2155
2156#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2157#[derive(Encodable, Decodable, HashStable_Generic)]
2158pub enum UintTy {
2159 Usize,
2160 U8,
2161 U16,
2162 U32,
2163 U64,
2164 U128,
2165}
2166
2167impl UintTy {
2168 pub fn name_str(&self) -> &'static str {
2169 match *self {
2170 UintTy::Usize => "usize",
2171 UintTy::U8 => "u8",
2172 UintTy::U16 => "u16",
2173 UintTy::U32 => "u32",
2174 UintTy::U64 => "u64",
2175 UintTy::U128 => "u128",
2176 }
2177 }
2178
2179 pub fn name(&self) -> Symbol {
2180 match *self {
2181 UintTy::Usize => sym::usize,
2182 UintTy::U8 => sym::u8,
2183 UintTy::U16 => sym::u16,
2184 UintTy::U32 => sym::u32,
2185 UintTy::U64 => sym::u64,
2186 UintTy::U128 => sym::u128,
2187 }
2188 }
2189}
2190
2191#[derive(Clone, Encodable, Decodable, Debug)]
2202pub struct AssocItemConstraint {
2203 pub id: NodeId,
2204 pub ident: Ident,
2205 pub gen_args: Option<GenericArgs>,
2206 pub kind: AssocItemConstraintKind,
2207 pub span: Span,
2208}
2209
2210#[derive(Clone, Encodable, Decodable, Debug)]
2211pub enum Term {
2212 Ty(P<Ty>),
2213 Const(AnonConst),
2214}
2215
2216impl From<P<Ty>> for Term {
2217 fn from(v: P<Ty>) -> Self {
2218 Term::Ty(v)
2219 }
2220}
2221
2222impl From<AnonConst> for Term {
2223 fn from(v: AnonConst) -> Self {
2224 Term::Const(v)
2225 }
2226}
2227
2228#[derive(Clone, Encodable, Decodable, Debug)]
2230pub enum AssocItemConstraintKind {
2231 Equality { term: Term },
2238 Bound { bounds: GenericBounds },
2240}
2241
2242#[derive(Encodable, Decodable, Debug)]
2243pub struct Ty {
2244 pub id: NodeId,
2245 pub kind: TyKind,
2246 pub span: Span,
2247 pub tokens: Option<LazyAttrTokenStream>,
2248}
2249
2250impl Clone for Ty {
2251 fn clone(&self) -> Self {
2252 ensure_sufficient_stack(|| Self {
2253 id: self.id,
2254 kind: self.kind.clone(),
2255 span: self.span,
2256 tokens: self.tokens.clone(),
2257 })
2258 }
2259}
2260
2261impl Ty {
2262 pub fn peel_refs(&self) -> &Self {
2263 let mut final_ty = self;
2264 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2265 {
2266 final_ty = ty;
2267 }
2268 final_ty
2269 }
2270
2271 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2272 match &self.kind {
2273 TyKind::Infer => true,
2274 TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
2275 _ => false,
2276 }
2277 }
2278}
2279
2280#[derive(Clone, Encodable, Decodable, Debug)]
2281pub struct BareFnTy {
2282 pub safety: Safety,
2283 pub ext: Extern,
2284 pub generic_params: ThinVec<GenericParam>,
2285 pub decl: P<FnDecl>,
2286 pub decl_span: Span,
2289}
2290
2291#[derive(Clone, Encodable, Decodable, Debug)]
2292pub struct UnsafeBinderTy {
2293 pub generic_params: ThinVec<GenericParam>,
2294 pub inner_ty: P<Ty>,
2295}
2296
2297#[derive(Clone, Encodable, Decodable, Debug)]
2301pub enum TyKind {
2302 Slice(P<Ty>),
2304 Array(P<Ty>, AnonConst),
2306 Ptr(MutTy),
2308 Ref(Option<Lifetime>, MutTy),
2310 PinnedRef(Option<Lifetime>, MutTy),
2314 BareFn(P<BareFnTy>),
2316 UnsafeBinder(P<UnsafeBinderTy>),
2318 Never,
2320 Tup(ThinVec<P<Ty>>),
2322 Path(Option<P<QSelf>>, Path),
2327 TraitObject(GenericBounds, TraitObjectSyntax),
2330 ImplTrait(NodeId, GenericBounds),
2337 Paren(P<Ty>),
2339 Typeof(AnonConst),
2341 Infer,
2344 ImplicitSelf,
2346 MacCall(P<MacCall>),
2348 CVarArgs,
2350 Pat(P<Ty>, P<TyPat>),
2353 Dummy,
2355 Err(ErrorGuaranteed),
2357}
2358
2359impl TyKind {
2360 pub fn is_implicit_self(&self) -> bool {
2361 matches!(self, TyKind::ImplicitSelf)
2362 }
2363
2364 pub fn is_unit(&self) -> bool {
2365 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2366 }
2367
2368 pub fn is_simple_path(&self) -> Option<Symbol> {
2369 if let TyKind::Path(None, Path { segments, .. }) = &self
2370 && let [segment] = &segments[..]
2371 && segment.args.is_none()
2372 {
2373 Some(segment.ident.name)
2374 } else {
2375 None
2376 }
2377 }
2378}
2379
2380#[derive(Clone, Encodable, Decodable, Debug)]
2382pub struct TyPat {
2383 pub id: NodeId,
2384 pub kind: TyPatKind,
2385 pub span: Span,
2386 pub tokens: Option<LazyAttrTokenStream>,
2387}
2388
2389#[derive(Clone, Encodable, Decodable, Debug)]
2393pub enum TyPatKind {
2394 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2396
2397 Err(ErrorGuaranteed),
2399}
2400
2401#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2403#[repr(u8)]
2404pub enum TraitObjectSyntax {
2405 Dyn = 0,
2407 DynStar = 1,
2408 None = 2,
2409}
2410
2411unsafe impl Tag for TraitObjectSyntax {
2415 const BITS: u32 = 2;
2416
2417 fn into_usize(self) -> usize {
2418 self as u8 as usize
2419 }
2420
2421 unsafe fn from_usize(tag: usize) -> Self {
2422 match tag {
2423 0 => TraitObjectSyntax::Dyn,
2424 1 => TraitObjectSyntax::DynStar,
2425 2 => TraitObjectSyntax::None,
2426 _ => unreachable!(),
2427 }
2428 }
2429}
2430
2431#[derive(Clone, Encodable, Decodable, Debug)]
2432pub enum PreciseCapturingArg {
2433 Lifetime(Lifetime),
2435 Arg(Path, NodeId),
2437}
2438
2439#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2443pub enum InlineAsmRegOrRegClass {
2444 Reg(Symbol),
2445 RegClass(Symbol),
2446}
2447
2448#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2449pub struct InlineAsmOptions(u16);
2450bitflags::bitflags! {
2451 impl InlineAsmOptions: u16 {
2452 const PURE = 1 << 0;
2453 const NOMEM = 1 << 1;
2454 const READONLY = 1 << 2;
2455 const PRESERVES_FLAGS = 1 << 3;
2456 const NORETURN = 1 << 4;
2457 const NOSTACK = 1 << 5;
2458 const ATT_SYNTAX = 1 << 6;
2459 const RAW = 1 << 7;
2460 const MAY_UNWIND = 1 << 8;
2461 }
2462}
2463
2464impl InlineAsmOptions {
2465 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2466
2467 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2468 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2469
2470 pub fn human_readable_names(&self) -> Vec<&'static str> {
2471 let mut options = vec![];
2472
2473 if self.contains(InlineAsmOptions::PURE) {
2474 options.push("pure");
2475 }
2476 if self.contains(InlineAsmOptions::NOMEM) {
2477 options.push("nomem");
2478 }
2479 if self.contains(InlineAsmOptions::READONLY) {
2480 options.push("readonly");
2481 }
2482 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2483 options.push("preserves_flags");
2484 }
2485 if self.contains(InlineAsmOptions::NORETURN) {
2486 options.push("noreturn");
2487 }
2488 if self.contains(InlineAsmOptions::NOSTACK) {
2489 options.push("nostack");
2490 }
2491 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2492 options.push("att_syntax");
2493 }
2494 if self.contains(InlineAsmOptions::RAW) {
2495 options.push("raw");
2496 }
2497 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2498 options.push("may_unwind");
2499 }
2500
2501 options
2502 }
2503}
2504
2505impl std::fmt::Debug for InlineAsmOptions {
2506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2507 bitflags::parser::to_writer(self, f)
2508 }
2509}
2510
2511#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2512pub enum InlineAsmTemplatePiece {
2513 String(Cow<'static, str>),
2514 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2515}
2516
2517impl fmt::Display for InlineAsmTemplatePiece {
2518 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2519 match self {
2520 Self::String(s) => {
2521 for c in s.chars() {
2522 match c {
2523 '{' => f.write_str("{{")?,
2524 '}' => f.write_str("}}")?,
2525 _ => c.fmt(f)?,
2526 }
2527 }
2528 Ok(())
2529 }
2530 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2531 write!(f, "{{{operand_idx}:{modifier}}}")
2532 }
2533 Self::Placeholder { operand_idx, modifier: None, .. } => {
2534 write!(f, "{{{operand_idx}}}")
2535 }
2536 }
2537 }
2538}
2539
2540impl InlineAsmTemplatePiece {
2541 pub fn to_string(s: &[Self]) -> String {
2543 use fmt::Write;
2544 let mut out = String::new();
2545 for p in s.iter() {
2546 let _ = write!(out, "{p}");
2547 }
2548 out
2549 }
2550}
2551
2552#[derive(Clone, Encodable, Decodable, Debug)]
2560pub struct InlineAsmSym {
2561 pub id: NodeId,
2562 pub qself: Option<P<QSelf>>,
2563 pub path: Path,
2564}
2565
2566#[derive(Clone, Encodable, Decodable, Debug)]
2570pub enum InlineAsmOperand {
2571 In {
2572 reg: InlineAsmRegOrRegClass,
2573 expr: P<Expr>,
2574 },
2575 Out {
2576 reg: InlineAsmRegOrRegClass,
2577 late: bool,
2578 expr: Option<P<Expr>>,
2579 },
2580 InOut {
2581 reg: InlineAsmRegOrRegClass,
2582 late: bool,
2583 expr: P<Expr>,
2584 },
2585 SplitInOut {
2586 reg: InlineAsmRegOrRegClass,
2587 late: bool,
2588 in_expr: P<Expr>,
2589 out_expr: Option<P<Expr>>,
2590 },
2591 Const {
2592 anon_const: AnonConst,
2593 },
2594 Sym {
2595 sym: InlineAsmSym,
2596 },
2597 Label {
2598 block: P<Block>,
2599 },
2600}
2601
2602impl InlineAsmOperand {
2603 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2604 match self {
2605 Self::In { reg, .. }
2606 | Self::Out { reg, .. }
2607 | Self::InOut { reg, .. }
2608 | Self::SplitInOut { reg, .. } => Some(reg),
2609 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2610 }
2611 }
2612}
2613
2614#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2615pub enum AsmMacro {
2616 Asm,
2618 GlobalAsm,
2620 NakedAsm,
2622}
2623
2624impl AsmMacro {
2625 pub const fn macro_name(self) -> &'static str {
2626 match self {
2627 AsmMacro::Asm => "asm",
2628 AsmMacro::GlobalAsm => "global_asm",
2629 AsmMacro::NakedAsm => "naked_asm",
2630 }
2631 }
2632
2633 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2634 match self {
2635 AsmMacro::Asm => true,
2636 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2637 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2638 }
2639 }
2640
2641 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2642 match self {
2643 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2644 AsmMacro::GlobalAsm => true,
2645 AsmMacro::NakedAsm => true,
2646 }
2647 }
2648}
2649
2650#[derive(Clone, Encodable, Decodable, Debug)]
2654pub struct InlineAsm {
2655 pub asm_macro: AsmMacro,
2656 pub template: Vec<InlineAsmTemplatePiece>,
2657 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2658 pub operands: Vec<(InlineAsmOperand, Span)>,
2659 pub clobber_abis: Vec<(Symbol, Span)>,
2660 pub options: InlineAsmOptions,
2661 pub line_spans: Vec<Span>,
2662}
2663
2664#[derive(Clone, Encodable, Decodable, Debug)]
2668pub struct Param {
2669 pub attrs: AttrVec,
2670 pub ty: P<Ty>,
2671 pub pat: P<Pat>,
2672 pub id: NodeId,
2673 pub span: Span,
2674 pub is_placeholder: bool,
2675}
2676
2677#[derive(Clone, Encodable, Decodable, Debug)]
2681pub enum SelfKind {
2682 Value(Mutability),
2684 Region(Option<Lifetime>, Mutability),
2686 Pinned(Option<Lifetime>, Mutability),
2688 Explicit(P<Ty>, Mutability),
2690}
2691
2692impl SelfKind {
2693 pub fn to_ref_suggestion(&self) -> String {
2694 match self {
2695 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2696 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2697 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2698 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2699 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2700 unreachable!("if we had an explicit self, we wouldn't be here")
2701 }
2702 }
2703 }
2704}
2705
2706pub type ExplicitSelf = Spanned<SelfKind>;
2707
2708impl Param {
2709 pub fn to_self(&self) -> Option<ExplicitSelf> {
2711 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2712 if ident.name == kw::SelfLower {
2713 return match self.ty.kind {
2714 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2715 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2716 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2717 }
2718 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2719 if ty.kind.is_implicit_self() =>
2720 {
2721 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2722 }
2723 _ => Some(respan(
2724 self.pat.span.to(self.ty.span),
2725 SelfKind::Explicit(self.ty.clone(), mutbl),
2726 )),
2727 };
2728 }
2729 }
2730 None
2731 }
2732
2733 pub fn is_self(&self) -> bool {
2735 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2736 ident.name == kw::SelfLower
2737 } else {
2738 false
2739 }
2740 }
2741
2742 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2744 let span = eself.span.to(eself_ident.span);
2745 let infer_ty = P(Ty {
2746 id: DUMMY_NODE_ID,
2747 kind: TyKind::ImplicitSelf,
2748 span: eself_ident.span,
2749 tokens: None,
2750 });
2751 let (mutbl, ty) = match eself.node {
2752 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2753 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2754 SelfKind::Region(lt, mutbl) => (
2755 Mutability::Not,
2756 P(Ty {
2757 id: DUMMY_NODE_ID,
2758 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2759 span,
2760 tokens: None,
2761 }),
2762 ),
2763 SelfKind::Pinned(lt, mutbl) => (
2764 mutbl,
2765 P(Ty {
2766 id: DUMMY_NODE_ID,
2767 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2768 span,
2769 tokens: None,
2770 }),
2771 ),
2772 };
2773 Param {
2774 attrs,
2775 pat: P(Pat {
2776 id: DUMMY_NODE_ID,
2777 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2778 span,
2779 tokens: None,
2780 }),
2781 span,
2782 ty,
2783 id: DUMMY_NODE_ID,
2784 is_placeholder: false,
2785 }
2786 }
2787}
2788
2789#[derive(Clone, Encodable, Decodable, Debug)]
2796pub struct FnDecl {
2797 pub inputs: ThinVec<Param>,
2798 pub output: FnRetTy,
2799}
2800
2801impl FnDecl {
2802 pub fn has_self(&self) -> bool {
2803 self.inputs.get(0).is_some_and(Param::is_self)
2804 }
2805 pub fn c_variadic(&self) -> bool {
2806 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2807 }
2808}
2809
2810#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2812pub enum IsAuto {
2813 Yes,
2814 No,
2815}
2816
2817#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2819#[derive(HashStable_Generic)]
2820pub enum Safety {
2821 Unsafe(Span),
2823 Safe(Span),
2825 Default,
2828}
2829
2830#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2836pub enum CoroutineKind {
2837 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2839 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2841 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2843}
2844
2845impl CoroutineKind {
2846 pub fn span(self) -> Span {
2847 match self {
2848 CoroutineKind::Async { span, .. } => span,
2849 CoroutineKind::Gen { span, .. } => span,
2850 CoroutineKind::AsyncGen { span, .. } => span,
2851 }
2852 }
2853
2854 pub fn as_str(self) -> &'static str {
2855 match self {
2856 CoroutineKind::Async { .. } => "async",
2857 CoroutineKind::Gen { .. } => "gen",
2858 CoroutineKind::AsyncGen { .. } => "async gen",
2859 }
2860 }
2861
2862 pub fn closure_id(self) -> NodeId {
2863 match self {
2864 CoroutineKind::Async { closure_id, .. }
2865 | CoroutineKind::Gen { closure_id, .. }
2866 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2867 }
2868 }
2869
2870 pub fn return_id(self) -> (NodeId, Span) {
2873 match self {
2874 CoroutineKind::Async { return_impl_trait_id, span, .. }
2875 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2876 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2877 (return_impl_trait_id, span)
2878 }
2879 }
2880 }
2881}
2882
2883#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2884#[derive(HashStable_Generic)]
2885pub enum Const {
2886 Yes(Span),
2887 No,
2888}
2889
2890#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2893pub enum Defaultness {
2894 Default(Span),
2895 Final,
2896}
2897
2898#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2899pub enum ImplPolarity {
2900 Positive,
2902 Negative(Span),
2904}
2905
2906impl fmt::Debug for ImplPolarity {
2907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2908 match *self {
2909 ImplPolarity::Positive => "positive".fmt(f),
2910 ImplPolarity::Negative(_) => "negative".fmt(f),
2911 }
2912 }
2913}
2914
2915#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2917#[derive(HashStable_Generic)]
2918pub enum BoundPolarity {
2919 Positive,
2921 Negative(Span),
2923 Maybe(Span),
2925}
2926
2927impl BoundPolarity {
2928 pub fn as_str(self) -> &'static str {
2929 match self {
2930 Self::Positive => "",
2931 Self::Negative(_) => "!",
2932 Self::Maybe(_) => "?",
2933 }
2934 }
2935}
2936
2937#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2939#[derive(HashStable_Generic)]
2940pub enum BoundConstness {
2941 Never,
2943 Always(Span),
2945 Maybe(Span),
2947}
2948
2949impl BoundConstness {
2950 pub fn as_str(self) -> &'static str {
2951 match self {
2952 Self::Never => "",
2953 Self::Always(_) => "const",
2954 Self::Maybe(_) => "~const",
2955 }
2956 }
2957}
2958
2959#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
2961#[derive(HashStable_Generic)]
2962pub enum BoundAsyncness {
2963 Normal,
2965 Async(Span),
2967}
2968
2969impl BoundAsyncness {
2970 pub fn as_str(self) -> &'static str {
2971 match self {
2972 Self::Normal => "",
2973 Self::Async(_) => "async",
2974 }
2975 }
2976}
2977
2978#[derive(Clone, Encodable, Decodable, Debug)]
2979pub enum FnRetTy {
2980 Default(Span),
2985 Ty(P<Ty>),
2987}
2988
2989impl FnRetTy {
2990 pub fn span(&self) -> Span {
2991 match self {
2992 &FnRetTy::Default(span) => span,
2993 FnRetTy::Ty(ty) => ty.span,
2994 }
2995 }
2996}
2997
2998#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
2999pub enum Inline {
3000 Yes,
3001 No,
3002}
3003
3004#[derive(Clone, Encodable, Decodable, Debug)]
3006pub enum ModKind {
3007 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3012 Unloaded,
3014}
3015
3016#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3017pub struct ModSpans {
3018 pub inner_span: Span,
3021 pub inject_use_span: Span,
3022}
3023
3024#[derive(Clone, Encodable, Decodable, Debug)]
3028pub struct ForeignMod {
3029 pub extern_span: Span,
3031 pub safety: Safety,
3034 pub abi: Option<StrLit>,
3035 pub items: ThinVec<P<ForeignItem>>,
3036}
3037
3038#[derive(Clone, Encodable, Decodable, Debug)]
3039pub struct EnumDef {
3040 pub variants: ThinVec<Variant>,
3041}
3042#[derive(Clone, Encodable, Decodable, Debug)]
3044pub struct Variant {
3045 pub attrs: AttrVec,
3047 pub id: NodeId,
3049 pub span: Span,
3051 pub vis: Visibility,
3053 pub ident: Ident,
3055
3056 pub data: VariantData,
3058 pub disr_expr: Option<AnonConst>,
3060 pub is_placeholder: bool,
3062}
3063
3064#[derive(Clone, Encodable, Decodable, Debug)]
3066pub enum UseTreeKind {
3067 Simple(Option<Ident>),
3069 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3078 Glob,
3080}
3081
3082#[derive(Clone, Encodable, Decodable, Debug)]
3085pub struct UseTree {
3086 pub prefix: Path,
3087 pub kind: UseTreeKind,
3088 pub span: Span,
3089}
3090
3091impl UseTree {
3092 pub fn ident(&self) -> Ident {
3093 match self.kind {
3094 UseTreeKind::Simple(Some(rename)) => rename,
3095 UseTreeKind::Simple(None) => {
3096 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3097 }
3098 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3099 }
3100 }
3101}
3102
3103#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3107pub enum AttrStyle {
3108 Outer,
3109 Inner,
3110}
3111
3112pub type AttrVec = ThinVec<Attribute>;
3114
3115#[derive(Clone, Encodable, Decodable, Debug)]
3117pub struct Attribute {
3118 pub kind: AttrKind,
3119 pub id: AttrId,
3120 pub style: AttrStyle,
3123 pub span: Span,
3124}
3125
3126#[derive(Clone, Encodable, Decodable, Debug)]
3127pub enum AttrKind {
3128 Normal(P<NormalAttr>),
3130
3131 DocComment(CommentKind, Symbol),
3135}
3136
3137#[derive(Clone, Encodable, Decodable, Debug)]
3138pub struct NormalAttr {
3139 pub item: AttrItem,
3140 pub tokens: Option<LazyAttrTokenStream>,
3142}
3143
3144impl NormalAttr {
3145 pub fn from_ident(ident: Ident) -> Self {
3146 Self {
3147 item: AttrItem {
3148 unsafety: Safety::Default,
3149 path: Path::from_ident(ident),
3150 args: AttrArgs::Empty,
3151 tokens: None,
3152 },
3153 tokens: None,
3154 }
3155 }
3156}
3157
3158#[derive(Clone, Encodable, Decodable, Debug)]
3159pub struct AttrItem {
3160 pub unsafety: Safety,
3161 pub path: Path,
3162 pub args: AttrArgs,
3163 pub tokens: Option<LazyAttrTokenStream>,
3165}
3166
3167impl AttrItem {
3168 pub fn is_valid_for_outer_style(&self) -> bool {
3169 self.path == sym::cfg_attr
3170 || self.path == sym::cfg
3171 || self.path == sym::forbid
3172 || self.path == sym::warn
3173 || self.path == sym::allow
3174 || self.path == sym::deny
3175 }
3176}
3177
3178#[derive(Clone, Encodable, Decodable, Debug)]
3185pub struct TraitRef {
3186 pub path: Path,
3187 pub ref_id: NodeId,
3188}
3189
3190#[derive(Clone, Encodable, Decodable, Debug)]
3191pub struct PolyTraitRef {
3192 pub bound_generic_params: ThinVec<GenericParam>,
3194
3195 pub modifiers: TraitBoundModifiers,
3197
3198 pub trait_ref: TraitRef,
3200
3201 pub span: Span,
3202}
3203
3204impl PolyTraitRef {
3205 pub fn new(
3206 generic_params: ThinVec<GenericParam>,
3207 path: Path,
3208 modifiers: TraitBoundModifiers,
3209 span: Span,
3210 ) -> Self {
3211 PolyTraitRef {
3212 bound_generic_params: generic_params,
3213 modifiers,
3214 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3215 span,
3216 }
3217 }
3218}
3219
3220#[derive(Clone, Encodable, Decodable, Debug)]
3221pub struct Visibility {
3222 pub kind: VisibilityKind,
3223 pub span: Span,
3224 pub tokens: Option<LazyAttrTokenStream>,
3225}
3226
3227#[derive(Clone, Encodable, Decodable, Debug)]
3228pub enum VisibilityKind {
3229 Public,
3230 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3231 Inherited,
3232}
3233
3234impl VisibilityKind {
3235 pub fn is_pub(&self) -> bool {
3236 matches!(self, VisibilityKind::Public)
3237 }
3238}
3239
3240#[derive(Clone, Encodable, Decodable, Debug)]
3244pub struct FieldDef {
3245 pub attrs: AttrVec,
3246 pub id: NodeId,
3247 pub span: Span,
3248 pub vis: Visibility,
3249 pub safety: Safety,
3250 pub ident: Option<Ident>,
3251
3252 pub ty: P<Ty>,
3253 pub default: Option<AnonConst>,
3254 pub is_placeholder: bool,
3255}
3256
3257#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3259pub enum Recovered {
3260 No,
3261 Yes(ErrorGuaranteed),
3262}
3263
3264#[derive(Clone, Encodable, Decodable, Debug)]
3266pub enum VariantData {
3267 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3271 Tuple(ThinVec<FieldDef>, NodeId),
3275 Unit(NodeId),
3279}
3280
3281impl VariantData {
3282 pub fn fields(&self) -> &[FieldDef] {
3284 match self {
3285 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3286 _ => &[],
3287 }
3288 }
3289
3290 pub fn ctor_node_id(&self) -> Option<NodeId> {
3292 match *self {
3293 VariantData::Struct { .. } => None,
3294 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3295 }
3296 }
3297}
3298
3299#[derive(Clone, Encodable, Decodable, Debug)]
3301pub struct Item<K = ItemKind> {
3302 pub attrs: AttrVec,
3303 pub id: NodeId,
3304 pub span: Span,
3305 pub vis: Visibility,
3306 pub ident: Ident,
3309
3310 pub kind: K,
3311
3312 pub tokens: Option<LazyAttrTokenStream>,
3320}
3321
3322impl Item {
3323 pub fn span_with_attributes(&self) -> Span {
3325 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3326 }
3327
3328 pub fn opt_generics(&self) -> Option<&Generics> {
3329 match &self.kind {
3330 ItemKind::ExternCrate(_)
3331 | ItemKind::Use(_)
3332 | ItemKind::Mod(_, _)
3333 | ItemKind::ForeignMod(_)
3334 | ItemKind::GlobalAsm(_)
3335 | ItemKind::MacCall(_)
3336 | ItemKind::Delegation(_)
3337 | ItemKind::DelegationMac(_)
3338 | ItemKind::MacroDef(_) => None,
3339 ItemKind::Static(_) => None,
3340 ItemKind::Const(i) => Some(&i.generics),
3341 ItemKind::Fn(i) => Some(&i.generics),
3342 ItemKind::TyAlias(i) => Some(&i.generics),
3343 ItemKind::TraitAlias(generics, _)
3344 | ItemKind::Enum(_, generics)
3345 | ItemKind::Struct(_, generics)
3346 | ItemKind::Union(_, generics) => Some(&generics),
3347 ItemKind::Trait(i) => Some(&i.generics),
3348 ItemKind::Impl(i) => Some(&i.generics),
3349 }
3350 }
3351}
3352
3353#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3355pub enum Extern {
3356 None,
3360 Implicit(Span),
3366 Explicit(StrLit, Span),
3370}
3371
3372impl Extern {
3373 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3374 match abi {
3375 Some(name) => Extern::Explicit(name, span),
3376 None => Extern::Implicit(span),
3377 }
3378 }
3379}
3380
3381#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3386pub struct FnHeader {
3387 pub safety: Safety,
3389 pub coroutine_kind: Option<CoroutineKind>,
3391 pub constness: Const,
3393 pub ext: Extern,
3395}
3396
3397impl FnHeader {
3398 pub fn has_qualifiers(&self) -> bool {
3400 let Self { safety, coroutine_kind, constness, ext } = self;
3401 matches!(safety, Safety::Unsafe(_))
3402 || coroutine_kind.is_some()
3403 || matches!(constness, Const::Yes(_))
3404 || !matches!(ext, Extern::None)
3405 }
3406}
3407
3408impl Default for FnHeader {
3409 fn default() -> FnHeader {
3410 FnHeader {
3411 safety: Safety::Default,
3412 coroutine_kind: None,
3413 constness: Const::No,
3414 ext: Extern::None,
3415 }
3416 }
3417}
3418
3419#[derive(Clone, Encodable, Decodable, Debug)]
3420pub struct Trait {
3421 pub safety: Safety,
3422 pub is_auto: IsAuto,
3423 pub generics: Generics,
3424 pub bounds: GenericBounds,
3425 pub items: ThinVec<P<AssocItem>>,
3426}
3427
3428#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3447pub struct TyAliasWhereClause {
3448 pub has_where_token: bool,
3449 pub span: Span,
3450}
3451
3452#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3454pub struct TyAliasWhereClauses {
3455 pub before: TyAliasWhereClause,
3457 pub after: TyAliasWhereClause,
3459 pub split: usize,
3463}
3464
3465#[derive(Clone, Encodable, Decodable, Debug)]
3466pub struct TyAlias {
3467 pub defaultness: Defaultness,
3468 pub generics: Generics,
3469 pub where_clauses: TyAliasWhereClauses,
3470 pub bounds: GenericBounds,
3471 pub ty: Option<P<Ty>>,
3472}
3473
3474#[derive(Clone, Encodable, Decodable, Debug)]
3475pub struct Impl {
3476 pub defaultness: Defaultness,
3477 pub safety: Safety,
3478 pub generics: Generics,
3479 pub constness: Const,
3480 pub polarity: ImplPolarity,
3481 pub of_trait: Option<TraitRef>,
3483 pub self_ty: P<Ty>,
3484 pub items: ThinVec<P<AssocItem>>,
3485}
3486
3487#[derive(Clone, Encodable, Decodable, Debug, Default)]
3488pub struct FnContract {
3489 pub requires: Option<P<Expr>>,
3490 pub ensures: Option<P<Expr>>,
3491}
3492
3493#[derive(Clone, Encodable, Decodable, Debug)]
3494pub struct Fn {
3495 pub defaultness: Defaultness,
3496 pub generics: Generics,
3497 pub sig: FnSig,
3498 pub contract: Option<P<FnContract>>,
3499 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3500 pub body: Option<P<Block>>,
3501}
3502
3503#[derive(Clone, Encodable, Decodable, Debug)]
3504pub struct Delegation {
3505 pub id: NodeId,
3507 pub qself: Option<P<QSelf>>,
3508 pub path: Path,
3509 pub rename: Option<Ident>,
3510 pub body: Option<P<Block>>,
3511 pub from_glob: bool,
3513}
3514
3515#[derive(Clone, Encodable, Decodable, Debug)]
3516pub struct DelegationMac {
3517 pub qself: Option<P<QSelf>>,
3518 pub prefix: Path,
3519 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3521 pub body: Option<P<Block>>,
3522}
3523
3524#[derive(Clone, Encodable, Decodable, Debug)]
3525pub struct StaticItem {
3526 pub ty: P<Ty>,
3527 pub safety: Safety,
3528 pub mutability: Mutability,
3529 pub expr: Option<P<Expr>>,
3530 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3531}
3532
3533#[derive(Clone, Encodable, Decodable, Debug)]
3534pub struct ConstItem {
3535 pub defaultness: Defaultness,
3536 pub generics: Generics,
3537 pub ty: P<Ty>,
3538 pub expr: Option<P<Expr>>,
3539 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3540}
3541
3542#[derive(Clone, Encodable, Decodable, Debug)]
3544pub enum ItemKind {
3545 ExternCrate(Option<Symbol>),
3549 Use(UseTree),
3553 Static(Box<StaticItem>),
3557 Const(Box<ConstItem>),
3561 Fn(Box<Fn>),
3565 Mod(Safety, ModKind),
3571 ForeignMod(ForeignMod),
3575 GlobalAsm(Box<InlineAsm>),
3577 TyAlias(Box<TyAlias>),
3581 Enum(EnumDef, Generics),
3585 Struct(VariantData, Generics),
3589 Union(VariantData, Generics),
3593 Trait(Box<Trait>),
3597 TraitAlias(Generics, GenericBounds),
3601 Impl(Box<Impl>),
3605 MacCall(P<MacCall>),
3609
3610 MacroDef(MacroDef),
3612
3613 Delegation(Box<Delegation>),
3617 DelegationMac(Box<DelegationMac>),
3620}
3621
3622impl ItemKind {
3623 pub fn article(&self) -> &'static str {
3625 use ItemKind::*;
3626 match self {
3627 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3628 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3629 | Delegation(..) | DelegationMac(..) => "a",
3630 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3631 }
3632 }
3633
3634 pub fn descr(&self) -> &'static str {
3635 match self {
3636 ItemKind::ExternCrate(..) => "extern crate",
3637 ItemKind::Use(..) => "`use` import",
3638 ItemKind::Static(..) => "static item",
3639 ItemKind::Const(..) => "constant item",
3640 ItemKind::Fn(..) => "function",
3641 ItemKind::Mod(..) => "module",
3642 ItemKind::ForeignMod(..) => "extern block",
3643 ItemKind::GlobalAsm(..) => "global asm item",
3644 ItemKind::TyAlias(..) => "type alias",
3645 ItemKind::Enum(..) => "enum",
3646 ItemKind::Struct(..) => "struct",
3647 ItemKind::Union(..) => "union",
3648 ItemKind::Trait(..) => "trait",
3649 ItemKind::TraitAlias(..) => "trait alias",
3650 ItemKind::MacCall(..) => "item macro invocation",
3651 ItemKind::MacroDef(..) => "macro definition",
3652 ItemKind::Impl { .. } => "implementation",
3653 ItemKind::Delegation(..) => "delegated function",
3654 ItemKind::DelegationMac(..) => "delegation",
3655 }
3656 }
3657
3658 pub fn generics(&self) -> Option<&Generics> {
3659 match self {
3660 Self::Fn(box Fn { generics, .. })
3661 | Self::TyAlias(box TyAlias { generics, .. })
3662 | Self::Const(box ConstItem { generics, .. })
3663 | Self::Enum(_, generics)
3664 | Self::Struct(_, generics)
3665 | Self::Union(_, generics)
3666 | Self::Trait(box Trait { generics, .. })
3667 | Self::TraitAlias(generics, _)
3668 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3669 _ => None,
3670 }
3671 }
3672}
3673
3674pub type AssocItem = Item<AssocItemKind>;
3677
3678#[derive(Clone, Encodable, Decodable, Debug)]
3686pub enum AssocItemKind {
3687 Const(Box<ConstItem>),
3690 Fn(Box<Fn>),
3692 Type(Box<TyAlias>),
3694 MacCall(P<MacCall>),
3696 Delegation(Box<Delegation>),
3698 DelegationMac(Box<DelegationMac>),
3700}
3701
3702impl AssocItemKind {
3703 pub fn defaultness(&self) -> Defaultness {
3704 match *self {
3705 Self::Const(box ConstItem { defaultness, .. })
3706 | Self::Fn(box Fn { defaultness, .. })
3707 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3708 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3709 Defaultness::Final
3710 }
3711 }
3712 }
3713}
3714
3715impl From<AssocItemKind> for ItemKind {
3716 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3717 match assoc_item_kind {
3718 AssocItemKind::Const(item) => ItemKind::Const(item),
3719 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3720 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3721 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3722 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3723 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3724 }
3725 }
3726}
3727
3728impl TryFrom<ItemKind> for AssocItemKind {
3729 type Error = ItemKind;
3730
3731 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3732 Ok(match item_kind {
3733 ItemKind::Const(item) => AssocItemKind::Const(item),
3734 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3735 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3736 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3737 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3738 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3739 _ => return Err(item_kind),
3740 })
3741 }
3742}
3743
3744#[derive(Clone, Encodable, Decodable, Debug)]
3746pub enum ForeignItemKind {
3747 Static(Box<StaticItem>),
3749 Fn(Box<Fn>),
3751 TyAlias(Box<TyAlias>),
3753 MacCall(P<MacCall>),
3755}
3756
3757impl From<ForeignItemKind> for ItemKind {
3758 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3759 match foreign_item_kind {
3760 ForeignItemKind::Static(box static_foreign_item) => {
3761 ItemKind::Static(Box::new(static_foreign_item))
3762 }
3763 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3764 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3765 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3766 }
3767 }
3768}
3769
3770impl TryFrom<ItemKind> for ForeignItemKind {
3771 type Error = ItemKind;
3772
3773 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3774 Ok(match item_kind {
3775 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3776 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3777 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3778 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3779 _ => return Err(item_kind),
3780 })
3781 }
3782}
3783
3784pub type ForeignItem = Item<ForeignItemKind>;
3785
3786#[cfg(target_pointer_width = "64")]
3788mod size_asserts {
3789 use rustc_data_structures::static_assert_size;
3790
3791 use super::*;
3792 static_assert_size!(AssocItem, 88);
3794 static_assert_size!(AssocItemKind, 16);
3795 static_assert_size!(Attribute, 32);
3796 static_assert_size!(Block, 32);
3797 static_assert_size!(Expr, 72);
3798 static_assert_size!(ExprKind, 40);
3799 static_assert_size!(Fn, 176);
3800 static_assert_size!(ForeignItem, 88);
3801 static_assert_size!(ForeignItemKind, 16);
3802 static_assert_size!(GenericArg, 24);
3803 static_assert_size!(GenericBound, 88);
3804 static_assert_size!(Generics, 40);
3805 static_assert_size!(Impl, 136);
3806 static_assert_size!(Item, 136);
3807 static_assert_size!(ItemKind, 64);
3808 static_assert_size!(LitKind, 24);
3809 static_assert_size!(Local, 80);
3810 static_assert_size!(MetaItemLit, 40);
3811 static_assert_size!(Param, 40);
3812 static_assert_size!(Pat, 72);
3813 static_assert_size!(Path, 24);
3814 static_assert_size!(PathSegment, 24);
3815 static_assert_size!(PatKind, 48);
3816 static_assert_size!(Stmt, 32);
3817 static_assert_size!(StmtKind, 16);
3818 static_assert_size!(Ty, 64);
3819 static_assert_size!(TyKind, 40);
3820 }