1use std::borrow::{Borrow, Cow};
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
27use rustc_data_structures::packed::Pu128;
28use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
29use rustc_data_structures::stack::ensure_sufficient_stack;
30use rustc_data_structures::tagged_ptr::Tag;
31use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
32pub use rustc_span::AttrId;
33use rustc_span::source_map::{Spanned, respan};
34use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
35use thin_vec::{ThinVec, thin_vec};
36
37pub use crate::format::*;
38use crate::token::{self, CommentKind, Delimiter};
39use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
40use crate::util::parser::{ExprPrecedence, Fixity};
41use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
42
43#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
54pub struct Label {
55    pub ident: Ident,
56}
57
58impl fmt::Debug for Label {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(f, "label({:?})", self.ident)
61    }
62}
63
64#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
67pub struct Lifetime {
68    pub id: NodeId,
69    pub ident: Ident,
70}
71
72impl fmt::Debug for Lifetime {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "lifetime({}: {})", self.id, self)
75    }
76}
77
78impl fmt::Display for Lifetime {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        write!(f, "{}", self.ident.name)
81    }
82}
83
84#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
91pub struct Path {
92    pub span: Span,
93    pub segments: ThinVec<PathSegment>,
96    pub tokens: Option<LazyAttrTokenStream>,
97}
98
99impl PartialEq<Symbol> for Path {
101    #[inline]
102    fn eq(&self, name: &Symbol) -> bool {
103        if let [segment] = self.segments.as_ref()
104            && segment == name
105        {
106            true
107        } else {
108            false
109        }
110    }
111}
112
113impl PartialEq<&[Symbol]> for Path {
115    #[inline]
116    fn eq(&self, names: &&[Symbol]) -> bool {
117        self.segments.iter().eq(*names)
118    }
119}
120
121impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
122    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
123        self.segments.len().hash_stable(hcx, hasher);
124        for segment in &self.segments {
125            segment.ident.hash_stable(hcx, hasher);
126        }
127    }
128}
129
130impl Path {
131    pub fn from_ident(ident: Ident) -> Path {
134        Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
135    }
136
137    pub fn is_global(&self) -> bool {
138        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
139    }
140
141    #[tracing::instrument(level = "debug", ret)]
151    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
152        allow_mgca_arg
153            || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
154    }
155}
156
157pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
169    let mut iter = path.into_iter();
174    let len_hint = iter.size_hint().1.unwrap_or(1);
175    let mut s = String::with_capacity(len_hint * 8);
176
177    let first_sym = *iter.next().unwrap().borrow();
178    if first_sym != kw::PathRoot {
179        s.push_str(first_sym.as_str());
180    }
181    for sym in iter {
182        let sym = *sym.borrow();
183        debug_assert_ne!(sym, kw::PathRoot);
184        s.push_str("::");
185        s.push_str(sym.as_str());
186    }
187    s
188}
189
190pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
193    let mut iter = path.into_iter();
194    let len_hint = iter.size_hint().1.unwrap_or(1);
195    let mut s = String::with_capacity(len_hint * 8);
196
197    let first_ident = *iter.next().unwrap().borrow();
198    if first_ident.name != kw::PathRoot {
199        s.push_str(&first_ident.to_string());
200    }
201    for ident in iter {
202        let ident = *ident.borrow();
203        debug_assert_ne!(ident.name, kw::PathRoot);
204        s.push_str("::");
205        s.push_str(&ident.to_string());
206    }
207    s
208}
209
210#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
214pub struct PathSegment {
215    pub ident: Ident,
217
218    pub id: NodeId,
219
220    pub args: Option<Box<GenericArgs>>,
227}
228
229impl PartialEq<Symbol> for PathSegment {
231    #[inline]
232    fn eq(&self, name: &Symbol) -> bool {
233        self.args.is_none() && self.ident.name == *name
234    }
235}
236
237impl PathSegment {
238    pub fn from_ident(ident: Ident) -> Self {
239        PathSegment { ident, id: DUMMY_NODE_ID, args: None }
240    }
241
242    pub fn path_root(span: Span) -> Self {
243        PathSegment::from_ident(Ident::new(kw::PathRoot, span))
244    }
245
246    pub fn span(&self) -> Span {
247        match &self.args {
248            Some(args) => self.ident.span.to(args.span()),
249            None => self.ident.span,
250        }
251    }
252}
253
254#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
258pub enum GenericArgs {
259    AngleBracketed(AngleBracketedArgs),
261    Parenthesized(ParenthesizedArgs),
263    ParenthesizedElided(Span),
265}
266
267impl GenericArgs {
268    pub fn is_angle_bracketed(&self) -> bool {
269        matches!(self, AngleBracketed(..))
270    }
271
272    pub fn span(&self) -> Span {
273        match self {
274            AngleBracketed(data) => data.span,
275            Parenthesized(data) => data.span,
276            ParenthesizedElided(span) => *span,
277        }
278    }
279}
280
281#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
283pub enum GenericArg {
284    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
286    Type(Box<Ty>),
288    Const(AnonConst),
290}
291
292impl GenericArg {
293    pub fn span(&self) -> Span {
294        match self {
295            GenericArg::Lifetime(lt) => lt.ident.span,
296            GenericArg::Type(ty) => ty.span,
297            GenericArg::Const(ct) => ct.value.span,
298        }
299    }
300}
301
302#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
304pub struct AngleBracketedArgs {
305    pub span: Span,
307    pub args: ThinVec<AngleBracketedArg>,
309}
310
311#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
313pub enum AngleBracketedArg {
314    Arg(GenericArg),
316    Constraint(AssocItemConstraint),
318}
319
320impl AngleBracketedArg {
321    pub fn span(&self) -> Span {
322        match self {
323            AngleBracketedArg::Arg(arg) => arg.span(),
324            AngleBracketedArg::Constraint(constraint) => constraint.span,
325        }
326    }
327}
328
329impl From<AngleBracketedArgs> for Box<GenericArgs> {
330    fn from(val: AngleBracketedArgs) -> Self {
331        Box::new(GenericArgs::AngleBracketed(val))
332    }
333}
334
335impl From<ParenthesizedArgs> for Box<GenericArgs> {
336    fn from(val: ParenthesizedArgs) -> Self {
337        Box::new(GenericArgs::Parenthesized(val))
338    }
339}
340
341#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
343pub struct ParenthesizedArgs {
344    pub span: Span,
349
350    pub inputs: ThinVec<Box<Ty>>,
352
353    pub inputs_span: Span,
358
359    pub output: FnRetTy,
361}
362
363impl ParenthesizedArgs {
364    pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
365        let args = self
366            .inputs
367            .iter()
368            .cloned()
369            .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
370            .collect();
371        AngleBracketedArgs { span: self.inputs_span, args }
372    }
373}
374
375pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
376
377#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
379pub struct TraitBoundModifiers {
380    pub constness: BoundConstness,
381    pub asyncness: BoundAsyncness,
382    pub polarity: BoundPolarity,
383}
384
385impl TraitBoundModifiers {
386    pub const NONE: Self = Self {
387        constness: BoundConstness::Never,
388        asyncness: BoundAsyncness::Normal,
389        polarity: BoundPolarity::Positive,
390    };
391}
392
393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
394pub enum GenericBound {
395    Trait(PolyTraitRef),
396    Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
397    Use(ThinVec<PreciseCapturingArg>, Span),
399}
400
401impl GenericBound {
402    pub fn span(&self) -> Span {
403        match self {
404            GenericBound::Trait(t, ..) => t.span,
405            GenericBound::Outlives(l) => l.ident.span,
406            GenericBound::Use(_, span) => *span,
407        }
408    }
409}
410
411pub type GenericBounds = Vec<GenericBound>;
412
413#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
417pub enum ParamKindOrd {
418    Lifetime,
419    TypeOrConst,
420}
421
422impl fmt::Display for ParamKindOrd {
423    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424        match self {
425            ParamKindOrd::Lifetime => "lifetime".fmt(f),
426            ParamKindOrd::TypeOrConst => "type and const".fmt(f),
427        }
428    }
429}
430
431#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
432pub enum GenericParamKind {
433    Lifetime,
435    Type {
436        default: Option<Box<Ty>>,
437    },
438    Const {
439        ty: Box<Ty>,
440        span: Span,
442        default: Option<AnonConst>,
444    },
445}
446
447#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
448pub struct GenericParam {
449    pub id: NodeId,
450    pub ident: Ident,
451    pub attrs: AttrVec,
452    #[visitable(extra = BoundKind::Bound)]
453    pub bounds: GenericBounds,
454    pub is_placeholder: bool,
455    pub kind: GenericParamKind,
456    pub colon_span: Option<Span>,
457}
458
459impl GenericParam {
460    pub fn span(&self) -> Span {
461        match &self.kind {
462            GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
463                self.ident.span
464            }
465            GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
466            GenericParamKind::Const { span, .. } => *span,
467        }
468    }
469}
470
471#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
474pub struct Generics {
475    pub params: ThinVec<GenericParam>,
476    pub where_clause: WhereClause,
477    pub span: Span,
478}
479
480#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
482pub struct WhereClause {
483    pub has_where_token: bool,
488    pub predicates: ThinVec<WherePredicate>,
489    pub span: Span,
490}
491
492impl WhereClause {
493    pub fn is_empty(&self) -> bool {
494        !self.has_where_token && self.predicates.is_empty()
495    }
496}
497
498#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
500pub struct WherePredicate {
501    pub attrs: AttrVec,
502    pub kind: WherePredicateKind,
503    pub id: NodeId,
504    pub span: Span,
505    pub is_placeholder: bool,
506}
507
508#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
510pub enum WherePredicateKind {
511    BoundPredicate(WhereBoundPredicate),
513    RegionPredicate(WhereRegionPredicate),
515    EqPredicate(WhereEqPredicate),
517}
518
519#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
523pub struct WhereBoundPredicate {
524    pub bound_generic_params: ThinVec<GenericParam>,
526    pub bounded_ty: Box<Ty>,
528    #[visitable(extra = BoundKind::Bound)]
530    pub bounds: GenericBounds,
531}
532
533#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
537pub struct WhereRegionPredicate {
538    #[visitable(extra = LifetimeCtxt::Bound)]
539    pub lifetime: Lifetime,
540    #[visitable(extra = BoundKind::Bound)]
541    pub bounds: GenericBounds,
542}
543
544#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
548pub struct WhereEqPredicate {
549    pub lhs_ty: Box<Ty>,
550    pub rhs_ty: Box<Ty>,
551}
552
553#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
554pub struct Crate {
555    pub id: NodeId,
558    pub attrs: AttrVec,
559    pub items: ThinVec<Box<Item>>,
560    pub spans: ModSpans,
561    pub is_placeholder: bool,
562}
563
564#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
571pub struct MetaItem {
572    pub unsafety: Safety,
573    pub path: Path,
574    pub kind: MetaItemKind,
575    pub span: Span,
576}
577
578#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
580pub enum MetaItemKind {
581    Word,
585
586    List(ThinVec<MetaItemInner>),
590
591    NameValue(MetaItemLit),
595}
596
597#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
601pub enum MetaItemInner {
602    MetaItem(MetaItem),
604
605    Lit(MetaItemLit),
609}
610
611#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
615pub struct Block {
616    pub stmts: ThinVec<Stmt>,
618    pub id: NodeId,
619    pub rules: BlockCheckMode,
621    pub span: Span,
622    pub tokens: Option<LazyAttrTokenStream>,
623}
624
625#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
629pub struct Pat {
630    pub id: NodeId,
631    pub kind: PatKind,
632    pub span: Span,
633    pub tokens: Option<LazyAttrTokenStream>,
634}
635
636impl Pat {
637    pub fn to_ty(&self) -> Option<Box<Ty>> {
640        let kind = match &self.kind {
641            PatKind::Missing => unreachable!(),
642            PatKind::Wild => TyKind::Infer,
644            PatKind::Ident(BindingMode::NONE, ident, None) => {
646                TyKind::Path(None, Path::from_ident(*ident))
647            }
648            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
649            PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
650            PatKind::Ref(pat, mutbl) => {
652                pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
653            }
654            PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
657                pat.to_ty().map(TyKind::Slice)?
658            }
659            PatKind::Tuple(pats) => {
662                let mut tys = ThinVec::with_capacity(pats.len());
663                for pat in pats {
665                    tys.push(pat.to_ty()?);
666                }
667                TyKind::Tup(tys)
668            }
669            _ => return None,
670        };
671
672        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
673    }
674
675    pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
679        if !it(self) {
680            return;
681        }
682
683        match &self.kind {
684            PatKind::Ident(_, _, Some(p)) => p.walk(it),
686
687            PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
689
690            PatKind::TupleStruct(_, _, s)
692            | PatKind::Tuple(s)
693            | PatKind::Slice(s)
694            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
695
696            PatKind::Box(s)
698            | PatKind::Deref(s)
699            | PatKind::Ref(s, _)
700            | PatKind::Paren(s)
701            | PatKind::Guard(s, _) => s.walk(it),
702
703            PatKind::Missing
705            | PatKind::Wild
706            | PatKind::Rest
707            | PatKind::Never
708            | PatKind::Expr(_)
709            | PatKind::Range(..)
710            | PatKind::Ident(..)
711            | PatKind::Path(..)
712            | PatKind::MacCall(_)
713            | PatKind::Err(_) => {}
714        }
715    }
716
717    pub fn is_rest(&self) -> bool {
719        matches!(self.kind, PatKind::Rest)
720    }
721
722    pub fn could_be_never_pattern(&self) -> bool {
725        let mut could_be_never_pattern = false;
726        self.walk(&mut |pat| match &pat.kind {
727            PatKind::Never | PatKind::MacCall(_) => {
728                could_be_never_pattern = true;
729                false
730            }
731            PatKind::Or(s) => {
732                could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
733                false
734            }
735            _ => true,
736        });
737        could_be_never_pattern
738    }
739
740    pub fn contains_never_pattern(&self) -> bool {
743        let mut contains_never_pattern = false;
744        self.walk(&mut |pat| {
745            if matches!(pat.kind, PatKind::Never) {
746                contains_never_pattern = true;
747            }
748            true
749        });
750        contains_never_pattern
751    }
752
753    pub fn descr(&self) -> Option<String> {
755        match &self.kind {
756            PatKind::Missing => unreachable!(),
757            PatKind::Wild => Some("_".to_string()),
758            PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
759            PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
760            _ => None,
761        }
762    }
763}
764
765impl From<Box<Pat>> for Pat {
766    fn from(value: Box<Pat>) -> Self {
767        *value
768    }
769}
770
771#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
777pub struct PatField {
778    pub ident: Ident,
780    pub pat: Box<Pat>,
782    pub is_shorthand: bool,
783    pub attrs: AttrVec,
784    pub id: NodeId,
785    pub span: Span,
786    pub is_placeholder: bool,
787}
788
789#[derive(Clone, Copy, Debug, Eq, PartialEq)]
790#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
791pub enum ByRef {
792    Yes(Mutability),
793    No,
794}
795
796impl ByRef {
797    #[must_use]
798    pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
799        if let ByRef::Yes(old_mutbl) = &mut self {
800            *old_mutbl = cmp::min(*old_mutbl, mutbl);
801        }
802        self
803    }
804}
805
806#[derive(Clone, Copy, Debug, Eq, PartialEq)]
812#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
813pub struct BindingMode(pub ByRef, pub Mutability);
814
815impl BindingMode {
816    pub const NONE: Self = Self(ByRef::No, Mutability::Not);
817    pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
818    pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
819    pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
820    pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
821    pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
822
823    pub fn prefix_str(self) -> &'static str {
824        match self {
825            Self::NONE => "",
826            Self::REF => "ref ",
827            Self::MUT => "mut ",
828            Self::REF_MUT => "ref mut ",
829            Self::MUT_REF => "mut ref ",
830            Self::MUT_REF_MUT => "mut ref mut ",
831        }
832    }
833}
834
835#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
836pub enum RangeEnd {
837    Included(RangeSyntax),
839    Excluded,
841}
842
843#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
844pub enum RangeSyntax {
845    DotDotDot,
847    DotDotEq,
849}
850
851#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
855pub enum PatKind {
856    Missing,
858
859    Wild,
861
862    Ident(BindingMode, Ident, Option<Box<Pat>>),
867
868    Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
870
871    TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
873
874    Or(ThinVec<Pat>),
877
878    Path(Option<Box<QSelf>>, Path),
883
884    Tuple(ThinVec<Pat>),
886
887    Box(Box<Pat>),
889
890    Deref(Box<Pat>),
892
893    Ref(Box<Pat>, Mutability),
895
896    Expr(Box<Expr>),
898
899    Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
901
902    Slice(ThinVec<Pat>),
904
905    Rest,
918
919    Never,
921
922    Guard(Box<Pat>, Box<Expr>),
924
925    Paren(Box<Pat>),
927
928    MacCall(Box<MacCall>),
930
931    Err(ErrorGuaranteed),
933}
934
935#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
937pub enum PatFieldsRest {
938    Rest(Span),
940    Recovered(ErrorGuaranteed),
942    None,
944}
945
946#[derive(Clone, Copy, PartialEq, Eq, Debug)]
949#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
950pub enum BorrowKind {
951    Ref,
955    Raw,
959    Pin,
963}
964
965#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
966pub enum BinOpKind {
967    Add,
969    Sub,
971    Mul,
973    Div,
975    Rem,
977    And,
979    Or,
981    BitXor,
983    BitAnd,
985    BitOr,
987    Shl,
989    Shr,
991    Eq,
993    Lt,
995    Le,
997    Ne,
999    Ge,
1001    Gt,
1003}
1004
1005impl BinOpKind {
1006    pub fn as_str(&self) -> &'static str {
1007        use BinOpKind::*;
1008        match self {
1009            Add => "+",
1010            Sub => "-",
1011            Mul => "*",
1012            Div => "/",
1013            Rem => "%",
1014            And => "&&",
1015            Or => "||",
1016            BitXor => "^",
1017            BitAnd => "&",
1018            BitOr => "|",
1019            Shl => "<<",
1020            Shr => ">>",
1021            Eq => "==",
1022            Lt => "<",
1023            Le => "<=",
1024            Ne => "!=",
1025            Ge => ">=",
1026            Gt => ">",
1027        }
1028    }
1029
1030    pub fn is_lazy(&self) -> bool {
1031        matches!(self, BinOpKind::And | BinOpKind::Or)
1032    }
1033
1034    pub fn precedence(&self) -> ExprPrecedence {
1035        use BinOpKind::*;
1036        match *self {
1037            Mul | Div | Rem => ExprPrecedence::Product,
1038            Add | Sub => ExprPrecedence::Sum,
1039            Shl | Shr => ExprPrecedence::Shift,
1040            BitAnd => ExprPrecedence::BitAnd,
1041            BitXor => ExprPrecedence::BitXor,
1042            BitOr => ExprPrecedence::BitOr,
1043            Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1044            And => ExprPrecedence::LAnd,
1045            Or => ExprPrecedence::LOr,
1046        }
1047    }
1048
1049    pub fn fixity(&self) -> Fixity {
1050        use BinOpKind::*;
1051        match self {
1052            Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1053            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1054                Fixity::Left
1055            }
1056        }
1057    }
1058
1059    pub fn is_comparison(self) -> bool {
1060        use BinOpKind::*;
1061        match self {
1062            Eq | Ne | Lt | Le | Gt | Ge => true,
1063            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1064        }
1065    }
1066
1067    pub fn is_by_value(self) -> bool {
1069        !self.is_comparison()
1070    }
1071}
1072
1073pub type BinOp = Spanned<BinOpKind>;
1074
1075impl From<AssignOpKind> for BinOpKind {
1079    fn from(op: AssignOpKind) -> BinOpKind {
1080        match op {
1081            AssignOpKind::AddAssign => BinOpKind::Add,
1082            AssignOpKind::SubAssign => BinOpKind::Sub,
1083            AssignOpKind::MulAssign => BinOpKind::Mul,
1084            AssignOpKind::DivAssign => BinOpKind::Div,
1085            AssignOpKind::RemAssign => BinOpKind::Rem,
1086            AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1087            AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1088            AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1089            AssignOpKind::ShlAssign => BinOpKind::Shl,
1090            AssignOpKind::ShrAssign => BinOpKind::Shr,
1091        }
1092    }
1093}
1094
1095#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1096pub enum AssignOpKind {
1097    AddAssign,
1099    SubAssign,
1101    MulAssign,
1103    DivAssign,
1105    RemAssign,
1107    BitXorAssign,
1109    BitAndAssign,
1111    BitOrAssign,
1113    ShlAssign,
1115    ShrAssign,
1117}
1118
1119impl AssignOpKind {
1120    pub fn as_str(&self) -> &'static str {
1121        use AssignOpKind::*;
1122        match self {
1123            AddAssign => "+=",
1124            SubAssign => "-=",
1125            MulAssign => "*=",
1126            DivAssign => "/=",
1127            RemAssign => "%=",
1128            BitXorAssign => "^=",
1129            BitAndAssign => "&=",
1130            BitOrAssign => "|=",
1131            ShlAssign => "<<=",
1132            ShrAssign => ">>=",
1133        }
1134    }
1135
1136    pub fn is_by_value(self) -> bool {
1138        true
1139    }
1140}
1141
1142pub type AssignOp = Spanned<AssignOpKind>;
1143
1144#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1148pub enum UnOp {
1149    Deref,
1151    Not,
1153    Neg,
1155}
1156
1157impl UnOp {
1158    pub fn as_str(&self) -> &'static str {
1159        match self {
1160            UnOp::Deref => "*",
1161            UnOp::Not => "!",
1162            UnOp::Neg => "-",
1163        }
1164    }
1165
1166    pub fn is_by_value(self) -> bool {
1168        matches!(self, Self::Neg | Self::Not)
1169    }
1170}
1171
1172#[derive(Clone, Encodable, Decodable, Debug)]
1176pub struct Stmt {
1177    pub id: NodeId,
1178    pub kind: StmtKind,
1179    pub span: Span,
1180}
1181
1182impl Stmt {
1183    pub fn has_trailing_semicolon(&self) -> bool {
1184        match &self.kind {
1185            StmtKind::Semi(_) => true,
1186            StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1187            _ => false,
1188        }
1189    }
1190
1191    pub fn add_trailing_semicolon(mut self) -> Self {
1199        self.kind = match self.kind {
1200            StmtKind::Expr(expr) => StmtKind::Semi(expr),
1201            StmtKind::MacCall(mut mac) => {
1202                mac.style = MacStmtStyle::Semicolon;
1203                StmtKind::MacCall(mac)
1204            }
1205            kind => kind,
1206        };
1207
1208        self
1209    }
1210
1211    pub fn is_item(&self) -> bool {
1212        matches!(self.kind, StmtKind::Item(_))
1213    }
1214
1215    pub fn is_expr(&self) -> bool {
1216        matches!(self.kind, StmtKind::Expr(_))
1217    }
1218}
1219
1220#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1222pub enum StmtKind {
1223    Let(Box<Local>),
1225    Item(Box<Item>),
1227    Expr(Box<Expr>),
1229    Semi(Box<Expr>),
1231    Empty,
1233    MacCall(Box<MacCallStmt>),
1235}
1236
1237#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1238pub struct MacCallStmt {
1239    pub mac: Box<MacCall>,
1240    pub style: MacStmtStyle,
1241    pub attrs: AttrVec,
1242    pub tokens: Option<LazyAttrTokenStream>,
1243}
1244
1245#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1246pub enum MacStmtStyle {
1247    Semicolon,
1250    Braces,
1252    NoBraces,
1256}
1257
1258#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1260pub struct Local {
1261    pub id: NodeId,
1262    pub super_: Option<Span>,
1263    pub pat: Box<Pat>,
1264    pub ty: Option<Box<Ty>>,
1265    pub kind: LocalKind,
1266    pub span: Span,
1267    pub colon_sp: Option<Span>,
1268    pub attrs: AttrVec,
1269    pub tokens: Option<LazyAttrTokenStream>,
1270}
1271
1272#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1273pub enum LocalKind {
1274    Decl,
1277    Init(Box<Expr>),
1280    InitElse(Box<Expr>, Box<Block>),
1283}
1284
1285impl LocalKind {
1286    pub fn init(&self) -> Option<&Expr> {
1287        match self {
1288            Self::Decl => None,
1289            Self::Init(i) | Self::InitElse(i, _) => Some(i),
1290        }
1291    }
1292
1293    pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1294        match self {
1295            Self::Decl => None,
1296            Self::Init(init) => Some((init, None)),
1297            Self::InitElse(init, els) => Some((init, Some(els))),
1298        }
1299    }
1300}
1301
1302#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1313pub struct Arm {
1314    pub attrs: AttrVec,
1315    pub pat: Box<Pat>,
1317    pub guard: Option<Box<Expr>>,
1319    pub body: Option<Box<Expr>>,
1321    pub span: Span,
1322    pub id: NodeId,
1323    pub is_placeholder: bool,
1324}
1325
1326#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1328pub struct ExprField {
1329    pub attrs: AttrVec,
1330    pub id: NodeId,
1331    pub span: Span,
1332    pub ident: Ident,
1333    pub expr: Box<Expr>,
1334    pub is_shorthand: bool,
1335    pub is_placeholder: bool,
1336}
1337
1338#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1339pub enum BlockCheckMode {
1340    Default,
1341    Unsafe(UnsafeSource),
1342}
1343
1344#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1345pub enum UnsafeSource {
1346    CompilerGenerated,
1347    UserProvided,
1348}
1349
1350#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1356pub struct AnonConst {
1357    pub id: NodeId,
1358    pub value: Box<Expr>,
1359}
1360
1361#[derive(Clone, Encodable, Decodable, Debug)]
1363pub struct Expr {
1364    pub id: NodeId,
1365    pub kind: ExprKind,
1366    pub span: Span,
1367    pub attrs: AttrVec,
1368    pub tokens: Option<LazyAttrTokenStream>,
1369}
1370
1371impl Expr {
1372    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1386        let this = self.maybe_unwrap_block();
1387        if allow_mgca_arg {
1388            matches!(this.kind, ExprKind::Path(..))
1389        } else {
1390            if let ExprKind::Path(None, path) = &this.kind
1391                && path.is_potential_trivial_const_arg(allow_mgca_arg)
1392            {
1393                true
1394            } else {
1395                false
1396            }
1397        }
1398    }
1399
1400    pub fn maybe_unwrap_block(&self) -> &Expr {
1402        if let ExprKind::Block(block, None) = &self.kind
1403            && let [stmt] = block.stmts.as_slice()
1404            && let StmtKind::Expr(expr) = &stmt.kind
1405        {
1406            expr
1407        } else {
1408            self
1409        }
1410    }
1411
1412    pub fn optionally_braced_mac_call(
1418        &self,
1419        already_stripped_block: bool,
1420    ) -> Option<(bool, NodeId)> {
1421        match &self.kind {
1422            ExprKind::Block(block, None)
1423                if let [stmt] = &*block.stmts
1424                    && !already_stripped_block =>
1425            {
1426                match &stmt.kind {
1427                    StmtKind::MacCall(_) => Some((true, stmt.id)),
1428                    StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1429                        Some((true, expr.id))
1430                    }
1431                    _ => None,
1432                }
1433            }
1434            ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1435            _ => None,
1436        }
1437    }
1438
1439    pub fn to_bound(&self) -> Option<GenericBound> {
1440        match &self.kind {
1441            ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1442                ThinVec::new(),
1443                path.clone(),
1444                TraitBoundModifiers::NONE,
1445                self.span,
1446                Parens::No,
1447            ))),
1448            _ => None,
1449        }
1450    }
1451
1452    pub fn peel_parens(&self) -> &Expr {
1453        let mut expr = self;
1454        while let ExprKind::Paren(inner) = &expr.kind {
1455            expr = inner;
1456        }
1457        expr
1458    }
1459
1460    pub fn peel_parens_and_refs(&self) -> &Expr {
1461        let mut expr = self;
1462        while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1463        {
1464            expr = inner;
1465        }
1466        expr
1467    }
1468
1469    pub fn to_ty(&self) -> Option<Box<Ty>> {
1471        let kind = match &self.kind {
1472            ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1474            ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1475
1476            ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1477
1478            ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1479                expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1480            }
1481
1482            ExprKind::Repeat(expr, expr_len) => {
1483                expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1484            }
1485
1486            ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1487                expr.to_ty().map(TyKind::Slice)?
1488            }
1489
1490            ExprKind::Tup(exprs) => {
1491                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1492                TyKind::Tup(tys)
1493            }
1494
1495            ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1499                if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1500                    TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1501                } else {
1502                    return None;
1503                }
1504            }
1505
1506            ExprKind::Underscore => TyKind::Infer,
1507
1508            _ => return None,
1510        };
1511
1512        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1513    }
1514
1515    pub fn precedence(&self) -> ExprPrecedence {
1516        fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1517            for attr in attrs {
1518                if let AttrStyle::Outer = attr.style {
1519                    return ExprPrecedence::Prefix;
1520                }
1521            }
1522            ExprPrecedence::Unambiguous
1523        }
1524
1525        match &self.kind {
1526            ExprKind::Closure(closure) => {
1527                match closure.fn_decl.output {
1528                    FnRetTy::Default(_) => ExprPrecedence::Jump,
1529                    FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1530                }
1531            }
1532
1533            ExprKind::Break(_ , value)
1534            | ExprKind::Ret(value)
1535            | ExprKind::Yield(YieldKind::Prefix(value))
1536            | ExprKind::Yeet(value) => match value {
1537                Some(_) => ExprPrecedence::Jump,
1538                None => prefix_attrs_precedence(&self.attrs),
1539            },
1540
1541            ExprKind::Become(_) => ExprPrecedence::Jump,
1542
1543            ExprKind::Range(..) => ExprPrecedence::Range,
1548
1549            ExprKind::Binary(op, ..) => op.node.precedence(),
1551            ExprKind::Cast(..) => ExprPrecedence::Cast,
1552
1553            ExprKind::Assign(..) |
1554            ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1555
1556            ExprKind::AddrOf(..)
1558            | ExprKind::Let(..)
1563            | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1564
1565            ExprKind::Array(_)
1567            | ExprKind::Await(..)
1568            | ExprKind::Use(..)
1569            | ExprKind::Block(..)
1570            | ExprKind::Call(..)
1571            | ExprKind::ConstBlock(_)
1572            | ExprKind::Continue(..)
1573            | ExprKind::Field(..)
1574            | ExprKind::ForLoop { .. }
1575            | ExprKind::FormatArgs(..)
1576            | ExprKind::Gen(..)
1577            | ExprKind::If(..)
1578            | ExprKind::IncludedBytes(..)
1579            | ExprKind::Index(..)
1580            | ExprKind::InlineAsm(..)
1581            | ExprKind::Lit(_)
1582            | ExprKind::Loop(..)
1583            | ExprKind::MacCall(..)
1584            | ExprKind::Match(..)
1585            | ExprKind::MethodCall(..)
1586            | ExprKind::OffsetOf(..)
1587            | ExprKind::Paren(..)
1588            | ExprKind::Path(..)
1589            | ExprKind::Repeat(..)
1590            | ExprKind::Struct(..)
1591            | ExprKind::Try(..)
1592            | ExprKind::TryBlock(..)
1593            | ExprKind::Tup(_)
1594            | ExprKind::Type(..)
1595            | ExprKind::Underscore
1596            | ExprKind::UnsafeBinderCast(..)
1597            | ExprKind::While(..)
1598            | ExprKind::Yield(YieldKind::Postfix(..))
1599            | ExprKind::Err(_)
1600            | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1601        }
1602    }
1603
1604    pub fn is_approximately_pattern(&self) -> bool {
1606        matches!(
1607            &self.peel_parens().kind,
1608            ExprKind::Array(_)
1609                | ExprKind::Call(_, _)
1610                | ExprKind::Tup(_)
1611                | ExprKind::Lit(_)
1612                | ExprKind::Range(_, _, _)
1613                | ExprKind::Underscore
1614                | ExprKind::Path(_, _)
1615                | ExprKind::Struct(_)
1616        )
1617    }
1618
1619    pub fn dummy() -> Expr {
1623        Expr {
1624            id: DUMMY_NODE_ID,
1625            kind: ExprKind::Dummy,
1626            span: DUMMY_SP,
1627            attrs: ThinVec::new(),
1628            tokens: None,
1629        }
1630    }
1631}
1632
1633impl From<Box<Expr>> for Expr {
1634    fn from(value: Box<Expr>) -> Self {
1635        *value
1636    }
1637}
1638
1639#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1640pub struct Closure {
1641    pub binder: ClosureBinder,
1642    pub capture_clause: CaptureBy,
1643    pub constness: Const,
1644    pub coroutine_kind: Option<CoroutineKind>,
1645    pub movability: Movability,
1646    pub fn_decl: Box<FnDecl>,
1647    pub body: Box<Expr>,
1648    pub fn_decl_span: Span,
1650    pub fn_arg_span: Span,
1652}
1653
1654#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1656pub enum RangeLimits {
1657    HalfOpen,
1659    Closed,
1661}
1662
1663impl RangeLimits {
1664    pub fn as_str(&self) -> &'static str {
1665        match self {
1666            RangeLimits::HalfOpen => "..",
1667            RangeLimits::Closed => "..=",
1668        }
1669    }
1670}
1671
1672#[derive(Clone, Encodable, Decodable, Debug)]
1674pub struct MethodCall {
1675    pub seg: PathSegment,
1677    pub receiver: Box<Expr>,
1679    pub args: ThinVec<Box<Expr>>,
1681    pub span: Span,
1684}
1685
1686#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1687pub enum StructRest {
1688    Base(Box<Expr>),
1690    Rest(Span),
1692    None,
1694}
1695
1696#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1697pub struct StructExpr {
1698    pub qself: Option<Box<QSelf>>,
1699    pub path: Path,
1700    pub fields: ThinVec<ExprField>,
1701    pub rest: StructRest,
1702}
1703
1704#[derive(Clone, Encodable, Decodable, Debug)]
1706pub enum ExprKind {
1707    Array(ThinVec<Box<Expr>>),
1709    ConstBlock(AnonConst),
1711    Call(Box<Expr>, ThinVec<Box<Expr>>),
1718    MethodCall(Box<MethodCall>),
1720    Tup(ThinVec<Box<Expr>>),
1722    Binary(BinOp, Box<Expr>, Box<Expr>),
1724    Unary(UnOp, Box<Expr>),
1726    Lit(token::Lit),
1728    Cast(Box<Expr>, Box<Ty>),
1730    Type(Box<Expr>, Box<Ty>),
1735    Let(Box<Pat>, Box<Expr>, Span, Recovered),
1740    If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1747    While(Box<Expr>, Box<Block>, Option<Label>),
1751    ForLoop {
1757        pat: Box<Pat>,
1758        iter: Box<Expr>,
1759        body: Box<Block>,
1760        label: Option<Label>,
1761        kind: ForLoopKind,
1762    },
1763    Loop(Box<Block>, Option<Label>, Span),
1767    Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1769    Closure(Box<Closure>),
1771    Block(Box<Block>, Option<Label>),
1773    Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1779    Await(Box<Expr>, Span),
1781    Use(Box<Expr>, Span),
1783
1784    TryBlock(Box<Block>),
1786
1787    Assign(Box<Expr>, Box<Expr>, Span),
1790    AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1794    Field(Box<Expr>, Ident),
1796    Index(Box<Expr>, Box<Expr>, Span),
1799    Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1801    Underscore,
1803
1804    Path(Option<Box<QSelf>>, Path),
1809
1810    AddrOf(BorrowKind, Mutability, Box<Expr>),
1812    Break(Option<Label>, Option<Box<Expr>>),
1814    Continue(Option<Label>),
1816    Ret(Option<Box<Expr>>),
1818
1819    InlineAsm(Box<InlineAsm>),
1821
1822    OffsetOf(Box<Ty>, Vec<Ident>),
1827
1828    MacCall(Box<MacCall>),
1830
1831    Struct(Box<StructExpr>),
1835
1836    Repeat(Box<Expr>, AnonConst),
1841
1842    Paren(Box<Expr>),
1844
1845    Try(Box<Expr>),
1847
1848    Yield(YieldKind),
1850
1851    Yeet(Option<Box<Expr>>),
1854
1855    Become(Box<Expr>),
1859
1860    IncludedBytes(ByteSymbol),
1872
1873    FormatArgs(Box<FormatArgs>),
1875
1876    UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1877
1878    Err(ErrorGuaranteed),
1880
1881    Dummy,
1883}
1884
1885#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1887pub enum ForLoopKind {
1888    For,
1889    ForAwait,
1890}
1891
1892#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1894pub enum GenBlockKind {
1895    Async,
1896    Gen,
1897    AsyncGen,
1898}
1899
1900impl fmt::Display for GenBlockKind {
1901    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1902        self.modifier().fmt(f)
1903    }
1904}
1905
1906impl GenBlockKind {
1907    pub fn modifier(&self) -> &'static str {
1908        match self {
1909            GenBlockKind::Async => "async",
1910            GenBlockKind::Gen => "gen",
1911            GenBlockKind::AsyncGen => "async gen",
1912        }
1913    }
1914}
1915
1916#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1918#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1919pub enum UnsafeBinderCastKind {
1920    Wrap,
1922    Unwrap,
1924}
1925
1926#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1941pub struct QSelf {
1942    pub ty: Box<Ty>,
1943
1944    pub path_span: Span,
1948    pub position: usize,
1949}
1950
1951#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1953pub enum CaptureBy {
1954    Value {
1956        move_kw: Span,
1958    },
1959    Ref,
1961    Use {
1967        use_kw: Span,
1969    },
1970}
1971
1972#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1974pub enum ClosureBinder {
1975    NotPresent,
1977    For {
1979        span: Span,
1986
1987        generic_params: ThinVec<GenericParam>,
1994    },
1995}
1996
1997#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2000pub struct MacCall {
2001    pub path: Path,
2002    pub args: Box<DelimArgs>,
2003}
2004
2005impl MacCall {
2006    pub fn span(&self) -> Span {
2007        self.path.span.to(self.args.dspan.entire())
2008    }
2009}
2010
2011#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2013pub enum AttrArgs {
2014    Empty,
2016    Delimited(DelimArgs),
2018    Eq {
2020        eq_span: Span,
2022        expr: Box<Expr>,
2023    },
2024}
2025
2026impl AttrArgs {
2027    pub fn span(&self) -> Option<Span> {
2028        match self {
2029            AttrArgs::Empty => None,
2030            AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2031            AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2032        }
2033    }
2034
2035    pub fn inner_tokens(&self) -> TokenStream {
2038        match self {
2039            AttrArgs::Empty => TokenStream::default(),
2040            AttrArgs::Delimited(args) => args.tokens.clone(),
2041            AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2042        }
2043    }
2044}
2045
2046#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2048pub struct DelimArgs {
2049    pub dspan: DelimSpan,
2050    pub delim: Delimiter, pub tokens: TokenStream,
2052}
2053
2054impl DelimArgs {
2055    pub fn need_semicolon(&self) -> bool {
2058        !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2059    }
2060}
2061
2062#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2064pub struct MacroDef {
2065    pub body: Box<DelimArgs>,
2066    pub macro_rules: bool,
2068}
2069
2070#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2071#[derive(HashStable_Generic, Walkable)]
2072pub enum StrStyle {
2073    Cooked,
2075    Raw(u8),
2079}
2080
2081#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2083pub enum MatchKind {
2084    Prefix,
2086    Postfix,
2088}
2089
2090#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2092pub enum YieldKind {
2093    Prefix(Option<Box<Expr>>),
2095    Postfix(Box<Expr>),
2097}
2098
2099impl YieldKind {
2100    pub const fn expr(&self) -> Option<&Box<Expr>> {
2104        match self {
2105            YieldKind::Prefix(expr) => expr.as_ref(),
2106            YieldKind::Postfix(expr) => Some(expr),
2107        }
2108    }
2109
2110    pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2112        match self {
2113            YieldKind::Prefix(expr) => expr.as_mut(),
2114            YieldKind::Postfix(expr) => Some(expr),
2115        }
2116    }
2117
2118    pub const fn same_kind(&self, other: &Self) -> bool {
2120        match (self, other) {
2121            (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2122            (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2123            _ => false,
2124        }
2125    }
2126}
2127
2128#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2130pub struct MetaItemLit {
2131    pub symbol: Symbol,
2133    pub suffix: Option<Symbol>,
2135    pub kind: LitKind,
2138    pub span: Span,
2139}
2140
2141#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2143pub struct StrLit {
2144    pub symbol: Symbol,
2146    pub suffix: Option<Symbol>,
2148    pub symbol_unescaped: Symbol,
2150    pub style: StrStyle,
2151    pub span: Span,
2152}
2153
2154impl StrLit {
2155    pub fn as_token_lit(&self) -> token::Lit {
2156        let token_kind = match self.style {
2157            StrStyle::Cooked => token::Str,
2158            StrStyle::Raw(n) => token::StrRaw(n),
2159        };
2160        token::Lit::new(token_kind, self.symbol, self.suffix)
2161    }
2162}
2163
2164#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2166#[derive(HashStable_Generic)]
2167pub enum LitIntType {
2168    Signed(IntTy),
2170    Unsigned(UintTy),
2172    Unsuffixed,
2174}
2175
2176#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2178#[derive(HashStable_Generic)]
2179pub enum LitFloatType {
2180    Suffixed(FloatTy),
2182    Unsuffixed,
2184}
2185
2186#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2193pub enum LitKind {
2194    Str(Symbol, StrStyle),
2197    ByteStr(ByteSymbol, StrStyle),
2200    CStr(ByteSymbol, StrStyle),
2204    Byte(u8),
2206    Char(char),
2208    Int(Pu128, LitIntType),
2210    Float(Symbol, LitFloatType),
2214    Bool(bool),
2216    Err(ErrorGuaranteed),
2218}
2219
2220impl LitKind {
2221    pub fn str(&self) -> Option<Symbol> {
2222        match *self {
2223            LitKind::Str(s, _) => Some(s),
2224            _ => None,
2225        }
2226    }
2227
2228    pub fn is_str(&self) -> bool {
2230        matches!(self, LitKind::Str(..))
2231    }
2232
2233    pub fn is_bytestr(&self) -> bool {
2235        matches!(self, LitKind::ByteStr(..))
2236    }
2237
2238    pub fn is_numeric(&self) -> bool {
2240        matches!(self, LitKind::Int(..) | LitKind::Float(..))
2241    }
2242
2243    pub fn is_unsuffixed(&self) -> bool {
2246        !self.is_suffixed()
2247    }
2248
2249    pub fn is_suffixed(&self) -> bool {
2251        match *self {
2252            LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2254            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2255            LitKind::Str(..)
2257            | LitKind::ByteStr(..)
2258            | LitKind::CStr(..)
2259            | LitKind::Byte(..)
2260            | LitKind::Char(..)
2261            | LitKind::Int(_, LitIntType::Unsuffixed)
2262            | LitKind::Float(_, LitFloatType::Unsuffixed)
2263            | LitKind::Bool(..)
2264            | LitKind::Err(_) => false,
2265        }
2266    }
2267}
2268
2269#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2272pub struct MutTy {
2273    pub ty: Box<Ty>,
2274    pub mutbl: Mutability,
2275}
2276
2277#[derive(Clone, Encodable, Decodable, Debug)]
2280pub struct FnSig {
2281    pub header: FnHeader,
2282    pub decl: Box<FnDecl>,
2283    pub span: Span,
2284}
2285
2286impl FnSig {
2287    pub fn header_span(&self) -> Span {
2289        match self.header.ext {
2290            Extern::Implicit(span) | Extern::Explicit(_, span) => {
2291                return self.span.with_hi(span.hi());
2292            }
2293            Extern::None => {}
2294        }
2295
2296        match self.header.safety {
2297            Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2298            Safety::Default => {}
2299        };
2300
2301        if let Some(coroutine_kind) = self.header.coroutine_kind {
2302            return self.span.with_hi(coroutine_kind.span().hi());
2303        }
2304
2305        if let Const::Yes(span) = self.header.constness {
2306            return self.span.with_hi(span.hi());
2307        }
2308
2309        self.span.shrink_to_lo()
2310    }
2311
2312    pub fn safety_span(&self) -> Span {
2314        match self.header.safety {
2315            Safety::Unsafe(span) | Safety::Safe(span) => span,
2316            Safety::Default => {
2317                if let Some(extern_span) = self.header.ext.span() {
2319                    return extern_span.shrink_to_lo();
2320                }
2321
2322                self.header_span().shrink_to_hi()
2324            }
2325        }
2326    }
2327
2328    pub fn extern_span(&self) -> Span {
2330        self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2331    }
2332}
2333
2334#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2345pub struct AssocItemConstraint {
2346    pub id: NodeId,
2347    pub ident: Ident,
2348    pub gen_args: Option<GenericArgs>,
2349    pub kind: AssocItemConstraintKind,
2350    pub span: Span,
2351}
2352
2353#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2354pub enum Term {
2355    Ty(Box<Ty>),
2356    Const(AnonConst),
2357}
2358
2359impl From<Box<Ty>> for Term {
2360    fn from(v: Box<Ty>) -> Self {
2361        Term::Ty(v)
2362    }
2363}
2364
2365impl From<AnonConst> for Term {
2366    fn from(v: AnonConst) -> Self {
2367        Term::Const(v)
2368    }
2369}
2370
2371#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2373pub enum AssocItemConstraintKind {
2374    Equality { term: Term },
2381    Bound {
2383        #[visitable(extra = BoundKind::Bound)]
2384        bounds: GenericBounds,
2385    },
2386}
2387
2388#[derive(Encodable, Decodable, Debug, Walkable)]
2389pub struct Ty {
2390    pub id: NodeId,
2391    pub kind: TyKind,
2392    pub span: Span,
2393    pub tokens: Option<LazyAttrTokenStream>,
2394}
2395
2396impl Clone for Ty {
2397    fn clone(&self) -> Self {
2398        ensure_sufficient_stack(|| Self {
2399            id: self.id,
2400            kind: self.kind.clone(),
2401            span: self.span,
2402            tokens: self.tokens.clone(),
2403        })
2404    }
2405}
2406
2407impl From<Box<Ty>> for Ty {
2408    fn from(value: Box<Ty>) -> Self {
2409        *value
2410    }
2411}
2412
2413impl Ty {
2414    pub fn peel_refs(&self) -> &Self {
2415        let mut final_ty = self;
2416        while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2417        {
2418            final_ty = ty;
2419        }
2420        final_ty
2421    }
2422
2423    pub fn is_maybe_parenthesised_infer(&self) -> bool {
2424        match &self.kind {
2425            TyKind::Infer => true,
2426            TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2427            _ => false,
2428        }
2429    }
2430}
2431
2432#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2433pub struct FnPtrTy {
2434    pub safety: Safety,
2435    pub ext: Extern,
2436    pub generic_params: ThinVec<GenericParam>,
2437    pub decl: Box<FnDecl>,
2438    pub decl_span: Span,
2441}
2442
2443#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2444pub struct UnsafeBinderTy {
2445    pub generic_params: ThinVec<GenericParam>,
2446    pub inner_ty: Box<Ty>,
2447}
2448
2449#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2453pub enum TyKind {
2454    Slice(Box<Ty>),
2456    Array(Box<Ty>, AnonConst),
2458    Ptr(MutTy),
2460    Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2462    PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2466    FnPtr(Box<FnPtrTy>),
2468    UnsafeBinder(Box<UnsafeBinderTy>),
2470    Never,
2472    Tup(ThinVec<Box<Ty>>),
2474    Path(Option<Box<QSelf>>, Path),
2479    TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2482    ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2489    Paren(Box<Ty>),
2491    Typeof(AnonConst),
2493    Infer,
2496    ImplicitSelf,
2498    MacCall(Box<MacCall>),
2500    CVarArgs,
2502    Pat(Box<Ty>, Box<TyPat>),
2505    Dummy,
2507    Err(ErrorGuaranteed),
2509}
2510
2511impl TyKind {
2512    pub fn is_implicit_self(&self) -> bool {
2513        matches!(self, TyKind::ImplicitSelf)
2514    }
2515
2516    pub fn is_unit(&self) -> bool {
2517        matches!(self, TyKind::Tup(tys) if tys.is_empty())
2518    }
2519
2520    pub fn is_simple_path(&self) -> Option<Symbol> {
2521        if let TyKind::Path(None, Path { segments, .. }) = &self
2522            && let [segment] = &segments[..]
2523            && segment.args.is_none()
2524        {
2525            Some(segment.ident.name)
2526        } else {
2527            None
2528        }
2529    }
2530
2531    pub fn maybe_scalar(&self) -> bool {
2539        let Some(ty_sym) = self.is_simple_path() else {
2540            return self.is_unit();
2542        };
2543        matches!(
2544            ty_sym,
2545            sym::i8
2546                | sym::i16
2547                | sym::i32
2548                | sym::i64
2549                | sym::i128
2550                | sym::u8
2551                | sym::u16
2552                | sym::u32
2553                | sym::u64
2554                | sym::u128
2555                | sym::f16
2556                | sym::f32
2557                | sym::f64
2558                | sym::f128
2559                | sym::char
2560                | sym::bool
2561        )
2562    }
2563}
2564
2565#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2567pub struct TyPat {
2568    pub id: NodeId,
2569    pub kind: TyPatKind,
2570    pub span: Span,
2571    pub tokens: Option<LazyAttrTokenStream>,
2572}
2573
2574#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2578pub enum TyPatKind {
2579    Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2581
2582    NotNull,
2584
2585    Or(ThinVec<TyPat>),
2586
2587    Err(ErrorGuaranteed),
2589}
2590
2591#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2593#[repr(u8)]
2594pub enum TraitObjectSyntax {
2595    Dyn = 0,
2597    None = 1,
2598}
2599
2600unsafe impl Tag for TraitObjectSyntax {
2604    const BITS: u32 = 2;
2605
2606    fn into_usize(self) -> usize {
2607        self as u8 as usize
2608    }
2609
2610    unsafe fn from_usize(tag: usize) -> Self {
2611        match tag {
2612            0 => TraitObjectSyntax::Dyn,
2613            1 => TraitObjectSyntax::None,
2614            _ => unreachable!(),
2615        }
2616    }
2617}
2618
2619#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2620pub enum PreciseCapturingArg {
2621    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2623    Arg(Path, NodeId),
2625}
2626
2627#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2631pub enum InlineAsmRegOrRegClass {
2632    Reg(Symbol),
2633    RegClass(Symbol),
2634}
2635
2636#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2637pub struct InlineAsmOptions(u16);
2638bitflags::bitflags! {
2639    impl InlineAsmOptions: u16 {
2640        const PURE            = 1 << 0;
2641        const NOMEM           = 1 << 1;
2642        const READONLY        = 1 << 2;
2643        const PRESERVES_FLAGS = 1 << 3;
2644        const NORETURN        = 1 << 4;
2645        const NOSTACK         = 1 << 5;
2646        const ATT_SYNTAX      = 1 << 6;
2647        const RAW             = 1 << 7;
2648        const MAY_UNWIND      = 1 << 8;
2649    }
2650}
2651
2652impl InlineAsmOptions {
2653    pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2654
2655    pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2656    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2657
2658    pub fn human_readable_names(&self) -> Vec<&'static str> {
2659        let mut options = vec![];
2660
2661        if self.contains(InlineAsmOptions::PURE) {
2662            options.push("pure");
2663        }
2664        if self.contains(InlineAsmOptions::NOMEM) {
2665            options.push("nomem");
2666        }
2667        if self.contains(InlineAsmOptions::READONLY) {
2668            options.push("readonly");
2669        }
2670        if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2671            options.push("preserves_flags");
2672        }
2673        if self.contains(InlineAsmOptions::NORETURN) {
2674            options.push("noreturn");
2675        }
2676        if self.contains(InlineAsmOptions::NOSTACK) {
2677            options.push("nostack");
2678        }
2679        if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2680            options.push("att_syntax");
2681        }
2682        if self.contains(InlineAsmOptions::RAW) {
2683            options.push("raw");
2684        }
2685        if self.contains(InlineAsmOptions::MAY_UNWIND) {
2686            options.push("may_unwind");
2687        }
2688
2689        options
2690    }
2691}
2692
2693impl std::fmt::Debug for InlineAsmOptions {
2694    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2695        bitflags::parser::to_writer(self, f)
2696    }
2697}
2698
2699#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2700pub enum InlineAsmTemplatePiece {
2701    String(Cow<'static, str>),
2702    Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2703}
2704
2705impl fmt::Display for InlineAsmTemplatePiece {
2706    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2707        match self {
2708            Self::String(s) => {
2709                for c in s.chars() {
2710                    match c {
2711                        '{' => f.write_str("{{")?,
2712                        '}' => f.write_str("}}")?,
2713                        _ => c.fmt(f)?,
2714                    }
2715                }
2716                Ok(())
2717            }
2718            Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2719                write!(f, "{{{operand_idx}:{modifier}}}")
2720            }
2721            Self::Placeholder { operand_idx, modifier: None, .. } => {
2722                write!(f, "{{{operand_idx}}}")
2723            }
2724        }
2725    }
2726}
2727
2728impl InlineAsmTemplatePiece {
2729    pub fn to_string(s: &[Self]) -> String {
2731        use fmt::Write;
2732        let mut out = String::new();
2733        for p in s.iter() {
2734            let _ = write!(out, "{p}");
2735        }
2736        out
2737    }
2738}
2739
2740#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2748pub struct InlineAsmSym {
2749    pub id: NodeId,
2750    pub qself: Option<Box<QSelf>>,
2751    pub path: Path,
2752}
2753
2754#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2758pub enum InlineAsmOperand {
2759    In {
2760        reg: InlineAsmRegOrRegClass,
2761        expr: Box<Expr>,
2762    },
2763    Out {
2764        reg: InlineAsmRegOrRegClass,
2765        late: bool,
2766        expr: Option<Box<Expr>>,
2767    },
2768    InOut {
2769        reg: InlineAsmRegOrRegClass,
2770        late: bool,
2771        expr: Box<Expr>,
2772    },
2773    SplitInOut {
2774        reg: InlineAsmRegOrRegClass,
2775        late: bool,
2776        in_expr: Box<Expr>,
2777        out_expr: Option<Box<Expr>>,
2778    },
2779    Const {
2780        anon_const: AnonConst,
2781    },
2782    Sym {
2783        sym: InlineAsmSym,
2784    },
2785    Label {
2786        block: Box<Block>,
2787    },
2788}
2789
2790impl InlineAsmOperand {
2791    pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2792        match self {
2793            Self::In { reg, .. }
2794            | Self::Out { reg, .. }
2795            | Self::InOut { reg, .. }
2796            | Self::SplitInOut { reg, .. } => Some(reg),
2797            Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2798        }
2799    }
2800}
2801
2802#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2803pub enum AsmMacro {
2804    Asm,
2806    GlobalAsm,
2808    NakedAsm,
2810}
2811
2812impl AsmMacro {
2813    pub const fn macro_name(self) -> &'static str {
2814        match self {
2815            AsmMacro::Asm => "asm",
2816            AsmMacro::GlobalAsm => "global_asm",
2817            AsmMacro::NakedAsm => "naked_asm",
2818        }
2819    }
2820
2821    pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2822        match self {
2823            AsmMacro::Asm => true,
2824            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2825            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2826        }
2827    }
2828
2829    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2830        match self {
2831            AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2832            AsmMacro::GlobalAsm => true,
2833            AsmMacro::NakedAsm => true,
2834        }
2835    }
2836}
2837
2838#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2842pub struct InlineAsm {
2843    pub asm_macro: AsmMacro,
2844    pub template: Vec<InlineAsmTemplatePiece>,
2845    pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2846    pub operands: Vec<(InlineAsmOperand, Span)>,
2847    pub clobber_abis: Vec<(Symbol, Span)>,
2848    #[visitable(ignore)]
2849    pub options: InlineAsmOptions,
2850    pub line_spans: Vec<Span>,
2851}
2852
2853#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2857pub struct Param {
2858    pub attrs: AttrVec,
2859    pub ty: Box<Ty>,
2860    pub pat: Box<Pat>,
2861    pub id: NodeId,
2862    pub span: Span,
2863    pub is_placeholder: bool,
2864}
2865
2866#[derive(Clone, Encodable, Decodable, Debug)]
2870pub enum SelfKind {
2871    Value(Mutability),
2873    Region(Option<Lifetime>, Mutability),
2875    Pinned(Option<Lifetime>, Mutability),
2877    Explicit(Box<Ty>, Mutability),
2879}
2880
2881impl SelfKind {
2882    pub fn to_ref_suggestion(&self) -> String {
2883        match self {
2884            SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2885            SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2886            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2887            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2888            SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2889                unreachable!("if we had an explicit self, we wouldn't be here")
2890            }
2891        }
2892    }
2893}
2894
2895pub type ExplicitSelf = Spanned<SelfKind>;
2896
2897impl Param {
2898    pub fn to_self(&self) -> Option<ExplicitSelf> {
2900        if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2901            if ident.name == kw::SelfLower {
2902                return match self.ty.kind {
2903                    TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2904                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2905                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2906                    }
2907                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2908                        if ty.kind.is_implicit_self() =>
2909                    {
2910                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2911                    }
2912                    _ => Some(respan(
2913                        self.pat.span.to(self.ty.span),
2914                        SelfKind::Explicit(self.ty.clone(), mutbl),
2915                    )),
2916                };
2917            }
2918        }
2919        None
2920    }
2921
2922    pub fn is_self(&self) -> bool {
2924        if let PatKind::Ident(_, ident, _) = self.pat.kind {
2925            ident.name == kw::SelfLower
2926        } else {
2927            false
2928        }
2929    }
2930
2931    pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2933        let span = eself.span.to(eself_ident.span);
2934        let infer_ty = Box::new(Ty {
2935            id: DUMMY_NODE_ID,
2936            kind: TyKind::ImplicitSelf,
2937            span: eself_ident.span,
2938            tokens: None,
2939        });
2940        let (mutbl, ty) = match eself.node {
2941            SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2942            SelfKind::Value(mutbl) => (mutbl, infer_ty),
2943            SelfKind::Region(lt, mutbl) => (
2944                Mutability::Not,
2945                Box::new(Ty {
2946                    id: DUMMY_NODE_ID,
2947                    kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2948                    span,
2949                    tokens: None,
2950                }),
2951            ),
2952            SelfKind::Pinned(lt, mutbl) => (
2953                mutbl,
2954                Box::new(Ty {
2955                    id: DUMMY_NODE_ID,
2956                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2957                    span,
2958                    tokens: None,
2959                }),
2960            ),
2961        };
2962        Param {
2963            attrs,
2964            pat: Box::new(Pat {
2965                id: DUMMY_NODE_ID,
2966                kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2967                span,
2968                tokens: None,
2969            }),
2970            span,
2971            ty,
2972            id: DUMMY_NODE_ID,
2973            is_placeholder: false,
2974        }
2975    }
2976}
2977
2978#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2985pub struct FnDecl {
2986    pub inputs: ThinVec<Param>,
2987    pub output: FnRetTy,
2988}
2989
2990impl FnDecl {
2991    pub fn has_self(&self) -> bool {
2992        self.inputs.get(0).is_some_and(Param::is_self)
2993    }
2994    pub fn c_variadic(&self) -> bool {
2995        self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2996    }
2997}
2998
2999#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3001pub enum IsAuto {
3002    Yes,
3003    No,
3004}
3005
3006#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3008#[derive(HashStable_Generic, Walkable)]
3009pub enum Safety {
3010    Unsafe(Span),
3012    Safe(Span),
3014    Default,
3017}
3018
3019#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3025pub enum CoroutineKind {
3026    Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3028    Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3030    AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3032}
3033
3034impl CoroutineKind {
3035    pub fn span(self) -> Span {
3036        match self {
3037            CoroutineKind::Async { span, .. } => span,
3038            CoroutineKind::Gen { span, .. } => span,
3039            CoroutineKind::AsyncGen { span, .. } => span,
3040        }
3041    }
3042
3043    pub fn as_str(self) -> &'static str {
3044        match self {
3045            CoroutineKind::Async { .. } => "async",
3046            CoroutineKind::Gen { .. } => "gen",
3047            CoroutineKind::AsyncGen { .. } => "async gen",
3048        }
3049    }
3050
3051    pub fn closure_id(self) -> NodeId {
3052        match self {
3053            CoroutineKind::Async { closure_id, .. }
3054            | CoroutineKind::Gen { closure_id, .. }
3055            | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3056        }
3057    }
3058
3059    pub fn return_id(self) -> (NodeId, Span) {
3062        match self {
3063            CoroutineKind::Async { return_impl_trait_id, span, .. }
3064            | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3065            | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3066                (return_impl_trait_id, span)
3067            }
3068        }
3069    }
3070}
3071
3072#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3073#[derive(HashStable_Generic, Walkable)]
3074pub enum Const {
3075    Yes(Span),
3076    No,
3077}
3078
3079#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3082pub enum Defaultness {
3083    Default(Span),
3084    Final,
3085}
3086
3087#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3088pub enum ImplPolarity {
3089    Positive,
3091    Negative(Span),
3093}
3094
3095impl fmt::Debug for ImplPolarity {
3096    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3097        match *self {
3098            ImplPolarity::Positive => "positive".fmt(f),
3099            ImplPolarity::Negative(_) => "negative".fmt(f),
3100        }
3101    }
3102}
3103
3104#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3106#[derive(HashStable_Generic, Walkable)]
3107pub enum BoundPolarity {
3108    Positive,
3110    Negative(Span),
3112    Maybe(Span),
3114}
3115
3116impl BoundPolarity {
3117    pub fn as_str(self) -> &'static str {
3118        match self {
3119            Self::Positive => "",
3120            Self::Negative(_) => "!",
3121            Self::Maybe(_) => "?",
3122        }
3123    }
3124}
3125
3126#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3128#[derive(HashStable_Generic, Walkable)]
3129pub enum BoundConstness {
3130    Never,
3132    Always(Span),
3134    Maybe(Span),
3136}
3137
3138impl BoundConstness {
3139    pub fn as_str(self) -> &'static str {
3140        match self {
3141            Self::Never => "",
3142            Self::Always(_) => "const",
3143            Self::Maybe(_) => "[const]",
3144        }
3145    }
3146}
3147
3148#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3150#[derive(HashStable_Generic, Walkable)]
3151pub enum BoundAsyncness {
3152    Normal,
3154    Async(Span),
3156}
3157
3158impl BoundAsyncness {
3159    pub fn as_str(self) -> &'static str {
3160        match self {
3161            Self::Normal => "",
3162            Self::Async(_) => "async",
3163        }
3164    }
3165}
3166
3167#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3168pub enum FnRetTy {
3169    Default(Span),
3174    Ty(Box<Ty>),
3176}
3177
3178impl FnRetTy {
3179    pub fn span(&self) -> Span {
3180        match self {
3181            &FnRetTy::Default(span) => span,
3182            FnRetTy::Ty(ty) => ty.span,
3183        }
3184    }
3185}
3186
3187#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3188pub enum Inline {
3189    Yes,
3190    No { had_parse_error: Result<(), ErrorGuaranteed> },
3191}
3192
3193#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3195pub enum ModKind {
3196    Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3201    Unloaded,
3203}
3204
3205#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3206pub struct ModSpans {
3207    pub inner_span: Span,
3210    pub inject_use_span: Span,
3211}
3212
3213#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3217pub struct ForeignMod {
3218    pub extern_span: Span,
3220    pub safety: Safety,
3223    pub abi: Option<StrLit>,
3224    pub items: ThinVec<Box<ForeignItem>>,
3225}
3226
3227#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3228pub struct EnumDef {
3229    pub variants: ThinVec<Variant>,
3230}
3231
3232#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3234pub struct Variant {
3235    pub attrs: AttrVec,
3237    pub id: NodeId,
3239    pub span: Span,
3241    pub vis: Visibility,
3243    pub ident: Ident,
3245
3246    pub data: VariantData,
3248    pub disr_expr: Option<AnonConst>,
3250    pub is_placeholder: bool,
3252}
3253
3254#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3256pub enum UseTreeKind {
3257    Simple(Option<Ident>),
3259    Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3268    Glob,
3270}
3271
3272#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3275pub struct UseTree {
3276    pub prefix: Path,
3277    pub kind: UseTreeKind,
3278    pub span: Span,
3279}
3280
3281impl UseTree {
3282    pub fn ident(&self) -> Ident {
3283        match self.kind {
3284            UseTreeKind::Simple(Some(rename)) => rename,
3285            UseTreeKind::Simple(None) => {
3286                self.prefix.segments.last().expect("empty prefix in a simple import").ident
3287            }
3288            _ => panic!("`UseTree::ident` can only be used on a simple import"),
3289        }
3290    }
3291}
3292
3293#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3297pub enum AttrStyle {
3298    Outer,
3299    Inner,
3300}
3301
3302pub type AttrVec = ThinVec<Attribute>;
3304
3305#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3307pub struct Attribute {
3308    pub kind: AttrKind,
3309    pub id: AttrId,
3310    pub style: AttrStyle,
3313    pub span: Span,
3314}
3315
3316#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3317pub enum AttrKind {
3318    Normal(Box<NormalAttr>),
3320
3321    DocComment(CommentKind, Symbol),
3325}
3326
3327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3328pub struct NormalAttr {
3329    pub item: AttrItem,
3330    pub tokens: Option<LazyAttrTokenStream>,
3332}
3333
3334impl NormalAttr {
3335    pub fn from_ident(ident: Ident) -> Self {
3336        Self {
3337            item: AttrItem {
3338                unsafety: Safety::Default,
3339                path: Path::from_ident(ident),
3340                args: AttrArgs::Empty,
3341                tokens: None,
3342            },
3343            tokens: None,
3344        }
3345    }
3346}
3347
3348#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3349pub struct AttrItem {
3350    pub unsafety: Safety,
3351    pub path: Path,
3352    pub args: AttrArgs,
3353    pub tokens: Option<LazyAttrTokenStream>,
3355}
3356
3357impl AttrItem {
3358    pub fn is_valid_for_outer_style(&self) -> bool {
3359        self.path == sym::cfg_attr
3360            || self.path == sym::cfg
3361            || self.path == sym::forbid
3362            || self.path == sym::warn
3363            || self.path == sym::allow
3364            || self.path == sym::deny
3365    }
3366}
3367
3368#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3375pub struct TraitRef {
3376    pub path: Path,
3377    pub ref_id: NodeId,
3378}
3379
3380#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3382pub enum Parens {
3383    Yes,
3384    No,
3385}
3386
3387#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3388pub struct PolyTraitRef {
3389    pub bound_generic_params: ThinVec<GenericParam>,
3391
3392    pub modifiers: TraitBoundModifiers,
3394
3395    pub trait_ref: TraitRef,
3397
3398    pub span: Span,
3399
3400    pub parens: Parens,
3403}
3404
3405impl PolyTraitRef {
3406    pub fn new(
3407        generic_params: ThinVec<GenericParam>,
3408        path: Path,
3409        modifiers: TraitBoundModifiers,
3410        span: Span,
3411        parens: Parens,
3412    ) -> Self {
3413        PolyTraitRef {
3414            bound_generic_params: generic_params,
3415            modifiers,
3416            trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3417            span,
3418            parens,
3419        }
3420    }
3421}
3422
3423#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3424pub struct Visibility {
3425    pub kind: VisibilityKind,
3426    pub span: Span,
3427    pub tokens: Option<LazyAttrTokenStream>,
3428}
3429
3430#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3431pub enum VisibilityKind {
3432    Public,
3433    Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3434    Inherited,
3435}
3436
3437impl VisibilityKind {
3438    pub fn is_pub(&self) -> bool {
3439        matches!(self, VisibilityKind::Public)
3440    }
3441}
3442
3443#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3447pub struct FieldDef {
3448    pub attrs: AttrVec,
3449    pub id: NodeId,
3450    pub span: Span,
3451    pub vis: Visibility,
3452    pub safety: Safety,
3453    pub ident: Option<Ident>,
3454
3455    pub ty: Box<Ty>,
3456    pub default: Option<AnonConst>,
3457    pub is_placeholder: bool,
3458}
3459
3460#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3462pub enum Recovered {
3463    No,
3464    Yes(ErrorGuaranteed),
3465}
3466
3467#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3469pub enum VariantData {
3470    Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3474    Tuple(ThinVec<FieldDef>, NodeId),
3478    Unit(NodeId),
3482}
3483
3484impl VariantData {
3485    pub fn fields(&self) -> &[FieldDef] {
3487        match self {
3488            VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3489            _ => &[],
3490        }
3491    }
3492
3493    pub fn ctor_node_id(&self) -> Option<NodeId> {
3495        match *self {
3496            VariantData::Struct { .. } => None,
3497            VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3498        }
3499    }
3500}
3501
3502#[derive(Clone, Encodable, Decodable, Debug)]
3504pub struct Item<K = ItemKind> {
3505    pub attrs: AttrVec,
3506    pub id: NodeId,
3507    pub span: Span,
3508    pub vis: Visibility,
3509
3510    pub kind: K,
3511
3512    pub tokens: Option<LazyAttrTokenStream>,
3520}
3521
3522impl Item {
3523    pub fn span_with_attributes(&self) -> Span {
3525        self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3526    }
3527
3528    pub fn opt_generics(&self) -> Option<&Generics> {
3529        match &self.kind {
3530            ItemKind::ExternCrate(..)
3531            | ItemKind::Use(_)
3532            | ItemKind::Mod(..)
3533            | ItemKind::ForeignMod(_)
3534            | ItemKind::GlobalAsm(_)
3535            | ItemKind::MacCall(_)
3536            | ItemKind::Delegation(_)
3537            | ItemKind::DelegationMac(_)
3538            | ItemKind::MacroDef(..) => None,
3539            ItemKind::Static(_) => None,
3540            ItemKind::Const(i) => Some(&i.generics),
3541            ItemKind::Fn(i) => Some(&i.generics),
3542            ItemKind::TyAlias(i) => Some(&i.generics),
3543            ItemKind::TraitAlias(_, generics, _)
3544            | ItemKind::Enum(_, generics, _)
3545            | ItemKind::Struct(_, generics, _)
3546            | ItemKind::Union(_, generics, _) => Some(&generics),
3547            ItemKind::Trait(i) => Some(&i.generics),
3548            ItemKind::Impl(i) => Some(&i.generics),
3549        }
3550    }
3551}
3552
3553#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3555pub enum Extern {
3556    None,
3560    Implicit(Span),
3566    Explicit(StrLit, Span),
3570}
3571
3572impl Extern {
3573    pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3574        match abi {
3575            Some(name) => Extern::Explicit(name, span),
3576            None => Extern::Implicit(span),
3577        }
3578    }
3579
3580    pub fn span(self) -> Option<Span> {
3581        match self {
3582            Extern::None => None,
3583            Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3584        }
3585    }
3586}
3587
3588#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3593pub struct FnHeader {
3594    pub constness: Const,
3596    pub coroutine_kind: Option<CoroutineKind>,
3598    pub safety: Safety,
3600    pub ext: Extern,
3602}
3603
3604impl FnHeader {
3605    pub fn has_qualifiers(&self) -> bool {
3607        let Self { safety, coroutine_kind, constness, ext } = self;
3608        matches!(safety, Safety::Unsafe(_))
3609            || coroutine_kind.is_some()
3610            || matches!(constness, Const::Yes(_))
3611            || !matches!(ext, Extern::None)
3612    }
3613}
3614
3615impl Default for FnHeader {
3616    fn default() -> FnHeader {
3617        FnHeader {
3618            safety: Safety::Default,
3619            coroutine_kind: None,
3620            constness: Const::No,
3621            ext: Extern::None,
3622        }
3623    }
3624}
3625
3626#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3627pub struct Trait {
3628    pub constness: Const,
3629    pub safety: Safety,
3630    pub is_auto: IsAuto,
3631    pub ident: Ident,
3632    pub generics: Generics,
3633    #[visitable(extra = BoundKind::SuperTraits)]
3634    pub bounds: GenericBounds,
3635    #[visitable(extra = AssocCtxt::Trait)]
3636    pub items: ThinVec<Box<AssocItem>>,
3637}
3638
3639#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3640pub struct TyAlias {
3641    pub defaultness: Defaultness,
3642    pub ident: Ident,
3643    pub generics: Generics,
3644    pub after_where_clause: WhereClause,
3659    #[visitable(extra = BoundKind::Bound)]
3660    pub bounds: GenericBounds,
3661    pub ty: Option<Box<Ty>>,
3662}
3663
3664#[derive(Clone, Encodable, Decodable, Debug)]
3665pub struct Impl {
3666    pub generics: Generics,
3667    pub of_trait: Option<Box<TraitImplHeader>>,
3668    pub self_ty: Box<Ty>,
3669    pub items: ThinVec<Box<AssocItem>>,
3670}
3671
3672#[derive(Clone, Encodable, Decodable, Debug)]
3673pub struct TraitImplHeader {
3674    pub defaultness: Defaultness,
3675    pub safety: Safety,
3676    pub constness: Const,
3677    pub polarity: ImplPolarity,
3678    pub trait_ref: TraitRef,
3679}
3680
3681#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3682pub struct FnContract {
3683    pub requires: Option<Box<Expr>>,
3684    pub ensures: Option<Box<Expr>>,
3685}
3686
3687#[derive(Clone, Encodable, Decodable, Debug)]
3688pub struct Fn {
3689    pub defaultness: Defaultness,
3690    pub ident: Ident,
3691    pub generics: Generics,
3692    pub sig: FnSig,
3693    pub contract: Option<Box<FnContract>>,
3694    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3695    pub body: Option<Box<Block>>,
3696}
3697
3698#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3699pub struct Delegation {
3700    pub id: NodeId,
3702    pub qself: Option<Box<QSelf>>,
3703    pub path: Path,
3704    pub ident: Ident,
3705    pub rename: Option<Ident>,
3706    pub body: Option<Box<Block>>,
3707    pub from_glob: bool,
3709}
3710
3711#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3712pub struct DelegationMac {
3713    pub qself: Option<Box<QSelf>>,
3714    pub prefix: Path,
3715    pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3717    pub body: Option<Box<Block>>,
3718}
3719
3720#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3721pub struct StaticItem {
3722    pub ident: Ident,
3723    pub ty: Box<Ty>,
3724    pub safety: Safety,
3725    pub mutability: Mutability,
3726    pub expr: Option<Box<Expr>>,
3727    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3728}
3729
3730#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3731pub struct ConstItem {
3732    pub defaultness: Defaultness,
3733    pub ident: Ident,
3734    pub generics: Generics,
3735    pub ty: Box<Ty>,
3736    pub expr: Option<Box<Expr>>,
3737    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3738}
3739
3740#[derive(Clone, Encodable, Decodable, Debug)]
3742pub enum ItemKind {
3743    ExternCrate(Option<Symbol>, Ident),
3747    Use(UseTree),
3751    Static(Box<StaticItem>),
3755    Const(Box<ConstItem>),
3759    Fn(Box<Fn>),
3763    Mod(Safety, Ident, ModKind),
3769    ForeignMod(ForeignMod),
3773    GlobalAsm(Box<InlineAsm>),
3775    TyAlias(Box<TyAlias>),
3779    Enum(Ident, Generics, EnumDef),
3783    Struct(Ident, Generics, VariantData),
3787    Union(Ident, Generics, VariantData),
3791    Trait(Box<Trait>),
3795    TraitAlias(Ident, Generics, GenericBounds),
3799    Impl(Impl),
3803    MacCall(Box<MacCall>),
3807    MacroDef(Ident, MacroDef),
3809    Delegation(Box<Delegation>),
3813    DelegationMac(Box<DelegationMac>),
3816}
3817
3818impl ItemKind {
3819    pub fn ident(&self) -> Option<Ident> {
3820        match *self {
3821            ItemKind::ExternCrate(_, ident)
3822            | ItemKind::Static(box StaticItem { ident, .. })
3823            | ItemKind::Const(box ConstItem { ident, .. })
3824            | ItemKind::Fn(box Fn { ident, .. })
3825            | ItemKind::Mod(_, ident, _)
3826            | ItemKind::TyAlias(box TyAlias { ident, .. })
3827            | ItemKind::Enum(ident, ..)
3828            | ItemKind::Struct(ident, ..)
3829            | ItemKind::Union(ident, ..)
3830            | ItemKind::Trait(box Trait { ident, .. })
3831            | ItemKind::TraitAlias(ident, ..)
3832            | ItemKind::MacroDef(ident, _)
3833            | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3834
3835            ItemKind::Use(_)
3836            | ItemKind::ForeignMod(_)
3837            | ItemKind::GlobalAsm(_)
3838            | ItemKind::Impl(_)
3839            | ItemKind::MacCall(_)
3840            | ItemKind::DelegationMac(_) => None,
3841        }
3842    }
3843
3844    pub fn article(&self) -> &'static str {
3846        use ItemKind::*;
3847        match self {
3848            Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3849            | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3850            | Delegation(..) | DelegationMac(..) => "a",
3851            ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3852        }
3853    }
3854
3855    pub fn descr(&self) -> &'static str {
3856        match self {
3857            ItemKind::ExternCrate(..) => "extern crate",
3858            ItemKind::Use(..) => "`use` import",
3859            ItemKind::Static(..) => "static item",
3860            ItemKind::Const(..) => "constant item",
3861            ItemKind::Fn(..) => "function",
3862            ItemKind::Mod(..) => "module",
3863            ItemKind::ForeignMod(..) => "extern block",
3864            ItemKind::GlobalAsm(..) => "global asm item",
3865            ItemKind::TyAlias(..) => "type alias",
3866            ItemKind::Enum(..) => "enum",
3867            ItemKind::Struct(..) => "struct",
3868            ItemKind::Union(..) => "union",
3869            ItemKind::Trait(..) => "trait",
3870            ItemKind::TraitAlias(..) => "trait alias",
3871            ItemKind::MacCall(..) => "item macro invocation",
3872            ItemKind::MacroDef(..) => "macro definition",
3873            ItemKind::Impl { .. } => "implementation",
3874            ItemKind::Delegation(..) => "delegated function",
3875            ItemKind::DelegationMac(..) => "delegation",
3876        }
3877    }
3878
3879    pub fn generics(&self) -> Option<&Generics> {
3880        match self {
3881            Self::Fn(box Fn { generics, .. })
3882            | Self::TyAlias(box TyAlias { generics, .. })
3883            | Self::Const(box ConstItem { generics, .. })
3884            | Self::Enum(_, generics, _)
3885            | Self::Struct(_, generics, _)
3886            | Self::Union(_, generics, _)
3887            | Self::Trait(box Trait { generics, .. })
3888            | Self::TraitAlias(_, generics, _)
3889            | Self::Impl(Impl { generics, .. }) => Some(generics),
3890            _ => None,
3891        }
3892    }
3893}
3894
3895pub type AssocItem = Item<AssocItemKind>;
3898
3899#[derive(Clone, Encodable, Decodable, Debug)]
3907pub enum AssocItemKind {
3908    Const(Box<ConstItem>),
3911    Fn(Box<Fn>),
3913    Type(Box<TyAlias>),
3915    MacCall(Box<MacCall>),
3917    Delegation(Box<Delegation>),
3919    DelegationMac(Box<DelegationMac>),
3921}
3922
3923impl AssocItemKind {
3924    pub fn ident(&self) -> Option<Ident> {
3925        match *self {
3926            AssocItemKind::Const(box ConstItem { ident, .. })
3927            | AssocItemKind::Fn(box Fn { ident, .. })
3928            | AssocItemKind::Type(box TyAlias { ident, .. })
3929            | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3930
3931            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3932        }
3933    }
3934
3935    pub fn defaultness(&self) -> Defaultness {
3936        match *self {
3937            Self::Const(box ConstItem { defaultness, .. })
3938            | Self::Fn(box Fn { defaultness, .. })
3939            | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3940            Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3941                Defaultness::Final
3942            }
3943        }
3944    }
3945}
3946
3947impl From<AssocItemKind> for ItemKind {
3948    fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3949        match assoc_item_kind {
3950            AssocItemKind::Const(item) => ItemKind::Const(item),
3951            AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3952            AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3953            AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3954            AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3955            AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3956        }
3957    }
3958}
3959
3960impl TryFrom<ItemKind> for AssocItemKind {
3961    type Error = ItemKind;
3962
3963    fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3964        Ok(match item_kind {
3965            ItemKind::Const(item) => AssocItemKind::Const(item),
3966            ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3967            ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3968            ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3969            ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3970            ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3971            _ => return Err(item_kind),
3972        })
3973    }
3974}
3975
3976#[derive(Clone, Encodable, Decodable, Debug)]
3978pub enum ForeignItemKind {
3979    Static(Box<StaticItem>),
3981    Fn(Box<Fn>),
3983    TyAlias(Box<TyAlias>),
3985    MacCall(Box<MacCall>),
3987}
3988
3989impl ForeignItemKind {
3990    pub fn ident(&self) -> Option<Ident> {
3991        match *self {
3992            ForeignItemKind::Static(box StaticItem { ident, .. })
3993            | ForeignItemKind::Fn(box Fn { ident, .. })
3994            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3995
3996            ForeignItemKind::MacCall(_) => None,
3997        }
3998    }
3999}
4000
4001impl From<ForeignItemKind> for ItemKind {
4002    fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4003        match foreign_item_kind {
4004            ForeignItemKind::Static(box static_foreign_item) => {
4005                ItemKind::Static(Box::new(static_foreign_item))
4006            }
4007            ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4008            ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4009            ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4010        }
4011    }
4012}
4013
4014impl TryFrom<ItemKind> for ForeignItemKind {
4015    type Error = ItemKind;
4016
4017    fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4018        Ok(match item_kind {
4019            ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4020            ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4021            ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4022            ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4023            _ => return Err(item_kind),
4024        })
4025    }
4026}
4027
4028pub type ForeignItem = Item<ForeignItemKind>;
4029
4030#[cfg(target_pointer_width = "64")]
4032mod size_asserts {
4033    use rustc_data_structures::static_assert_size;
4034
4035    use super::*;
4036    static_assert_size!(AssocItem, 80);
4038    static_assert_size!(AssocItemKind, 16);
4039    static_assert_size!(Attribute, 32);
4040    static_assert_size!(Block, 32);
4041    static_assert_size!(Expr, 72);
4042    static_assert_size!(ExprKind, 40);
4043    static_assert_size!(Fn, 184);
4044    static_assert_size!(ForeignItem, 80);
4045    static_assert_size!(ForeignItemKind, 16);
4046    static_assert_size!(GenericArg, 24);
4047    static_assert_size!(GenericBound, 88);
4048    static_assert_size!(Generics, 40);
4049    static_assert_size!(Impl, 64);
4050    static_assert_size!(Item, 144);
4051    static_assert_size!(ItemKind, 80);
4052    static_assert_size!(LitKind, 24);
4053    static_assert_size!(Local, 96);
4054    static_assert_size!(MetaItemLit, 40);
4055    static_assert_size!(Param, 40);
4056    static_assert_size!(Pat, 80);
4057    static_assert_size!(PatKind, 56);
4058    static_assert_size!(Path, 24);
4059    static_assert_size!(PathSegment, 24);
4060    static_assert_size!(Stmt, 32);
4061    static_assert_size!(StmtKind, 16);
4062    static_assert_size!(TraitImplHeader, 80);
4063    static_assert_size!(Ty, 64);
4064    static_assert_size!(TyKind, 40);
4065    }