1use std::borrow::Cow;
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
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};
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::ptr::P;
39use crate::token::{self, CommentKind, Delimiter};
40use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
41use crate::util::parser::{ExprPrecedence, Fixity};
42
43#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
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)]
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)]
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.len() == names.len()
118 && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
119 }
120}
121
122impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
123 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
124 self.segments.len().hash_stable(hcx, hasher);
125 for segment in &self.segments {
126 segment.ident.hash_stable(hcx, hasher);
127 }
128 }
129}
130
131impl Path {
132 pub fn from_ident(ident: Ident) -> Path {
135 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
136 }
137
138 pub fn is_global(&self) -> bool {
139 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
140 }
141
142 #[tracing::instrument(level = "debug", ret)]
152 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
153 allow_mgca_arg
154 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
155 }
156}
157
158#[derive(Clone, Encodable, Decodable, Debug)]
162pub struct PathSegment {
163 pub ident: Ident,
165
166 pub id: NodeId,
167
168 pub args: Option<P<GenericArgs>>,
175}
176
177impl PartialEq<Symbol> for PathSegment {
179 #[inline]
180 fn eq(&self, name: &Symbol) -> bool {
181 self.args.is_none() && self.ident.name == *name
182 }
183}
184
185impl PathSegment {
186 pub fn from_ident(ident: Ident) -> Self {
187 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
188 }
189
190 pub fn path_root(span: Span) -> Self {
191 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
192 }
193
194 pub fn span(&self) -> Span {
195 match &self.args {
196 Some(args) => self.ident.span.to(args.span()),
197 None => self.ident.span,
198 }
199 }
200}
201
202#[derive(Clone, Encodable, Decodable, Debug)]
206pub enum GenericArgs {
207 AngleBracketed(AngleBracketedArgs),
209 Parenthesized(ParenthesizedArgs),
211 ParenthesizedElided(Span),
213}
214
215impl GenericArgs {
216 pub fn is_angle_bracketed(&self) -> bool {
217 matches!(self, AngleBracketed(..))
218 }
219
220 pub fn span(&self) -> Span {
221 match self {
222 AngleBracketed(data) => data.span,
223 Parenthesized(data) => data.span,
224 ParenthesizedElided(span) => *span,
225 }
226 }
227}
228
229#[derive(Clone, Encodable, Decodable, Debug)]
231pub enum GenericArg {
232 Lifetime(Lifetime),
234 Type(P<Ty>),
236 Const(AnonConst),
238}
239
240impl GenericArg {
241 pub fn span(&self) -> Span {
242 match self {
243 GenericArg::Lifetime(lt) => lt.ident.span,
244 GenericArg::Type(ty) => ty.span,
245 GenericArg::Const(ct) => ct.value.span,
246 }
247 }
248}
249
250#[derive(Clone, Encodable, Decodable, Debug, Default)]
252pub struct AngleBracketedArgs {
253 pub span: Span,
255 pub args: ThinVec<AngleBracketedArg>,
257}
258
259#[derive(Clone, Encodable, Decodable, Debug)]
261pub enum AngleBracketedArg {
262 Arg(GenericArg),
264 Constraint(AssocItemConstraint),
266}
267
268impl AngleBracketedArg {
269 pub fn span(&self) -> Span {
270 match self {
271 AngleBracketedArg::Arg(arg) => arg.span(),
272 AngleBracketedArg::Constraint(constraint) => constraint.span,
273 }
274 }
275}
276
277impl From<AngleBracketedArgs> for P<GenericArgs> {
278 fn from(val: AngleBracketedArgs) -> Self {
279 P(GenericArgs::AngleBracketed(val))
280 }
281}
282
283impl From<ParenthesizedArgs> for P<GenericArgs> {
284 fn from(val: ParenthesizedArgs) -> Self {
285 P(GenericArgs::Parenthesized(val))
286 }
287}
288
289#[derive(Clone, Encodable, Decodable, Debug)]
291pub struct ParenthesizedArgs {
292 pub span: Span,
297
298 pub inputs: ThinVec<P<Ty>>,
300
301 pub inputs_span: Span,
306
307 pub output: FnRetTy,
309}
310
311impl ParenthesizedArgs {
312 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
313 let args = self
314 .inputs
315 .iter()
316 .cloned()
317 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
318 .collect();
319 AngleBracketedArgs { span: self.inputs_span, args }
320 }
321}
322
323pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
324
325#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
327pub struct TraitBoundModifiers {
328 pub constness: BoundConstness,
329 pub asyncness: BoundAsyncness,
330 pub polarity: BoundPolarity,
331}
332
333impl TraitBoundModifiers {
334 pub const NONE: Self = Self {
335 constness: BoundConstness::Never,
336 asyncness: BoundAsyncness::Normal,
337 polarity: BoundPolarity::Positive,
338 };
339}
340
341#[derive(Clone, Encodable, Decodable, Debug)]
342pub enum GenericBound {
343 Trait(PolyTraitRef),
344 Outlives(Lifetime),
345 Use(ThinVec<PreciseCapturingArg>, Span),
347}
348
349impl GenericBound {
350 pub fn span(&self) -> Span {
351 match self {
352 GenericBound::Trait(t, ..) => t.span,
353 GenericBound::Outlives(l) => l.ident.span,
354 GenericBound::Use(_, span) => *span,
355 }
356 }
357}
358
359pub type GenericBounds = Vec<GenericBound>;
360
361#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
365pub enum ParamKindOrd {
366 Lifetime,
367 TypeOrConst,
368}
369
370impl fmt::Display for ParamKindOrd {
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372 match self {
373 ParamKindOrd::Lifetime => "lifetime".fmt(f),
374 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
375 }
376 }
377}
378
379#[derive(Clone, Encodable, Decodable, Debug)]
380pub enum GenericParamKind {
381 Lifetime,
383 Type {
384 default: Option<P<Ty>>,
385 },
386 Const {
387 ty: P<Ty>,
388 span: Span,
390 default: Option<AnonConst>,
392 },
393}
394
395#[derive(Clone, Encodable, Decodable, Debug)]
396pub struct GenericParam {
397 pub id: NodeId,
398 pub ident: Ident,
399 pub attrs: AttrVec,
400 pub bounds: GenericBounds,
401 pub is_placeholder: bool,
402 pub kind: GenericParamKind,
403 pub colon_span: Option<Span>,
404}
405
406impl GenericParam {
407 pub fn span(&self) -> Span {
408 match &self.kind {
409 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
410 self.ident.span
411 }
412 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
413 GenericParamKind::Const { span, .. } => *span,
414 }
415 }
416}
417
418#[derive(Clone, Encodable, Decodable, Debug, Default)]
421pub struct Generics {
422 pub params: ThinVec<GenericParam>,
423 pub where_clause: WhereClause,
424 pub span: Span,
425}
426
427#[derive(Clone, Encodable, Decodable, Debug, Default)]
429pub struct WhereClause {
430 pub has_where_token: bool,
435 pub predicates: ThinVec<WherePredicate>,
436 pub span: Span,
437}
438
439impl WhereClause {
440 pub fn is_empty(&self) -> bool {
441 !self.has_where_token && self.predicates.is_empty()
442 }
443}
444
445#[derive(Clone, Encodable, Decodable, Debug)]
447pub struct WherePredicate {
448 pub attrs: AttrVec,
449 pub kind: WherePredicateKind,
450 pub id: NodeId,
451 pub span: Span,
452 pub is_placeholder: bool,
453}
454
455#[derive(Clone, Encodable, Decodable, Debug)]
457pub enum WherePredicateKind {
458 BoundPredicate(WhereBoundPredicate),
460 RegionPredicate(WhereRegionPredicate),
462 EqPredicate(WhereEqPredicate),
464}
465
466#[derive(Clone, Encodable, Decodable, Debug)]
470pub struct WhereBoundPredicate {
471 pub bound_generic_params: ThinVec<GenericParam>,
473 pub bounded_ty: P<Ty>,
475 pub bounds: GenericBounds,
477}
478
479#[derive(Clone, Encodable, Decodable, Debug)]
483pub struct WhereRegionPredicate {
484 pub lifetime: Lifetime,
485 pub bounds: GenericBounds,
486}
487
488#[derive(Clone, Encodable, Decodable, Debug)]
492pub struct WhereEqPredicate {
493 pub lhs_ty: P<Ty>,
494 pub rhs_ty: P<Ty>,
495}
496
497#[derive(Clone, Encodable, Decodable, Debug)]
498pub struct Crate {
499 pub attrs: AttrVec,
500 pub items: ThinVec<P<Item>>,
501 pub spans: ModSpans,
502 pub id: NodeId,
505 pub is_placeholder: bool,
506}
507
508#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
515pub struct MetaItem {
516 pub unsafety: Safety,
517 pub path: Path,
518 pub kind: MetaItemKind,
519 pub span: Span,
520}
521
522#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
524pub enum MetaItemKind {
525 Word,
529
530 List(ThinVec<MetaItemInner>),
534
535 NameValue(MetaItemLit),
539}
540
541#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
545pub enum MetaItemInner {
546 MetaItem(MetaItem),
548
549 Lit(MetaItemLit),
553}
554
555#[derive(Clone, Encodable, Decodable, Debug)]
559pub struct Block {
560 pub stmts: ThinVec<Stmt>,
562 pub id: NodeId,
563 pub rules: BlockCheckMode,
565 pub span: Span,
566 pub tokens: Option<LazyAttrTokenStream>,
567}
568
569#[derive(Clone, Encodable, Decodable, Debug)]
573pub struct Pat {
574 pub id: NodeId,
575 pub kind: PatKind,
576 pub span: Span,
577 pub tokens: Option<LazyAttrTokenStream>,
578}
579
580impl Pat {
581 pub fn to_ty(&self) -> Option<P<Ty>> {
584 let kind = match &self.kind {
585 PatKind::Missing => unreachable!(),
586 PatKind::Wild => TyKind::Infer,
588 PatKind::Ident(BindingMode::NONE, ident, None) => {
590 TyKind::Path(None, Path::from_ident(*ident))
591 }
592 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
593 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
594 PatKind::Ref(pat, mutbl) => {
596 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
597 }
598 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
601 pat.to_ty().map(TyKind::Slice)?
602 }
603 PatKind::Tuple(pats) => {
606 let mut tys = ThinVec::with_capacity(pats.len());
607 for pat in pats {
609 tys.push(pat.to_ty()?);
610 }
611 TyKind::Tup(tys)
612 }
613 _ => return None,
614 };
615
616 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
617 }
618
619 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
623 if !it(self) {
624 return;
625 }
626
627 match &self.kind {
628 PatKind::Ident(_, _, Some(p)) => p.walk(it),
630
631 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
633
634 PatKind::TupleStruct(_, _, s)
636 | PatKind::Tuple(s)
637 | PatKind::Slice(s)
638 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
639
640 PatKind::Box(s)
642 | PatKind::Deref(s)
643 | PatKind::Ref(s, _)
644 | PatKind::Paren(s)
645 | PatKind::Guard(s, _) => s.walk(it),
646
647 PatKind::Missing
649 | PatKind::Wild
650 | PatKind::Rest
651 | PatKind::Never
652 | PatKind::Expr(_)
653 | PatKind::Range(..)
654 | PatKind::Ident(..)
655 | PatKind::Path(..)
656 | PatKind::MacCall(_)
657 | PatKind::Err(_) => {}
658 }
659 }
660
661 pub fn is_rest(&self) -> bool {
663 matches!(self.kind, PatKind::Rest)
664 }
665
666 pub fn could_be_never_pattern(&self) -> bool {
669 let mut could_be_never_pattern = false;
670 self.walk(&mut |pat| match &pat.kind {
671 PatKind::Never | PatKind::MacCall(_) => {
672 could_be_never_pattern = true;
673 false
674 }
675 PatKind::Or(s) => {
676 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
677 false
678 }
679 _ => true,
680 });
681 could_be_never_pattern
682 }
683
684 pub fn contains_never_pattern(&self) -> bool {
687 let mut contains_never_pattern = false;
688 self.walk(&mut |pat| {
689 if matches!(pat.kind, PatKind::Never) {
690 contains_never_pattern = true;
691 }
692 true
693 });
694 contains_never_pattern
695 }
696
697 pub fn descr(&self) -> Option<String> {
699 match &self.kind {
700 PatKind::Missing => unreachable!(),
701 PatKind::Wild => Some("_".to_string()),
702 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
703 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
704 _ => None,
705 }
706 }
707}
708
709impl From<P<Pat>> for Pat {
710 fn from(value: P<Pat>) -> Self {
711 *value
712 }
713}
714
715#[derive(Clone, Encodable, Decodable, Debug)]
721pub struct PatField {
722 pub ident: Ident,
724 pub pat: P<Pat>,
726 pub is_shorthand: bool,
727 pub attrs: AttrVec,
728 pub id: NodeId,
729 pub span: Span,
730 pub is_placeholder: bool,
731}
732
733#[derive(Clone, Copy, Debug, Eq, PartialEq)]
734#[derive(Encodable, Decodable, HashStable_Generic)]
735pub enum ByRef {
736 Yes(Mutability),
737 No,
738}
739
740impl ByRef {
741 #[must_use]
742 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
743 if let ByRef::Yes(old_mutbl) = &mut self {
744 *old_mutbl = cmp::min(*old_mutbl, mutbl);
745 }
746 self
747 }
748}
749
750#[derive(Clone, Copy, Debug, Eq, PartialEq)]
756#[derive(Encodable, Decodable, HashStable_Generic)]
757pub struct BindingMode(pub ByRef, pub Mutability);
758
759impl BindingMode {
760 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
761 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
762 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
763 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
764 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
765 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
766
767 pub fn prefix_str(self) -> &'static str {
768 match self {
769 Self::NONE => "",
770 Self::REF => "ref ",
771 Self::MUT => "mut ",
772 Self::REF_MUT => "ref mut ",
773 Self::MUT_REF => "mut ref ",
774 Self::MUT_REF_MUT => "mut ref mut ",
775 }
776 }
777}
778
779#[derive(Clone, Encodable, Decodable, Debug)]
780pub enum RangeEnd {
781 Included(RangeSyntax),
783 Excluded,
785}
786
787#[derive(Clone, Encodable, Decodable, Debug)]
788pub enum RangeSyntax {
789 DotDotDot,
791 DotDotEq,
793}
794
795#[derive(Clone, Encodable, Decodable, Debug)]
799pub enum PatKind {
800 Missing,
802
803 Wild,
805
806 Ident(BindingMode, Ident, Option<P<Pat>>),
811
812 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
814
815 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
817
818 Or(ThinVec<P<Pat>>),
821
822 Path(Option<P<QSelf>>, Path),
827
828 Tuple(ThinVec<P<Pat>>),
830
831 Box(P<Pat>),
833
834 Deref(P<Pat>),
836
837 Ref(P<Pat>, Mutability),
839
840 Expr(P<Expr>),
842
843 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
845
846 Slice(ThinVec<P<Pat>>),
848
849 Rest,
862
863 Never,
865
866 Guard(P<Pat>, P<Expr>),
868
869 Paren(P<Pat>),
871
872 MacCall(P<MacCall>),
874
875 Err(ErrorGuaranteed),
877}
878
879#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
881pub enum PatFieldsRest {
882 Rest,
884 Recovered(ErrorGuaranteed),
886 None,
888}
889
890#[derive(Clone, Copy, PartialEq, Eq, Debug)]
893#[derive(Encodable, Decodable, HashStable_Generic)]
894pub enum BorrowKind {
895 Ref,
899 Raw,
903 Pin,
907}
908
909#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
910pub enum BinOpKind {
911 Add,
913 Sub,
915 Mul,
917 Div,
919 Rem,
921 And,
923 Or,
925 BitXor,
927 BitAnd,
929 BitOr,
931 Shl,
933 Shr,
935 Eq,
937 Lt,
939 Le,
941 Ne,
943 Ge,
945 Gt,
947}
948
949impl BinOpKind {
950 pub fn as_str(&self) -> &'static str {
951 use BinOpKind::*;
952 match self {
953 Add => "+",
954 Sub => "-",
955 Mul => "*",
956 Div => "/",
957 Rem => "%",
958 And => "&&",
959 Or => "||",
960 BitXor => "^",
961 BitAnd => "&",
962 BitOr => "|",
963 Shl => "<<",
964 Shr => ">>",
965 Eq => "==",
966 Lt => "<",
967 Le => "<=",
968 Ne => "!=",
969 Ge => ">=",
970 Gt => ">",
971 }
972 }
973
974 pub fn is_lazy(&self) -> bool {
975 matches!(self, BinOpKind::And | BinOpKind::Or)
976 }
977
978 pub fn precedence(&self) -> ExprPrecedence {
979 use BinOpKind::*;
980 match *self {
981 Mul | Div | Rem => ExprPrecedence::Product,
982 Add | Sub => ExprPrecedence::Sum,
983 Shl | Shr => ExprPrecedence::Shift,
984 BitAnd => ExprPrecedence::BitAnd,
985 BitXor => ExprPrecedence::BitXor,
986 BitOr => ExprPrecedence::BitOr,
987 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
988 And => ExprPrecedence::LAnd,
989 Or => ExprPrecedence::LOr,
990 }
991 }
992
993 pub fn fixity(&self) -> Fixity {
994 use BinOpKind::*;
995 match self {
996 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
997 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
998 Fixity::Left
999 }
1000 }
1001 }
1002
1003 pub fn is_comparison(self) -> bool {
1004 use BinOpKind::*;
1005 match self {
1006 Eq | Ne | Lt | Le | Gt | Ge => true,
1007 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1008 }
1009 }
1010
1011 pub fn is_by_value(self) -> bool {
1013 !self.is_comparison()
1014 }
1015}
1016
1017pub type BinOp = Spanned<BinOpKind>;
1018
1019impl From<AssignOpKind> for BinOpKind {
1023 fn from(op: AssignOpKind) -> BinOpKind {
1024 match op {
1025 AssignOpKind::AddAssign => BinOpKind::Add,
1026 AssignOpKind::SubAssign => BinOpKind::Sub,
1027 AssignOpKind::MulAssign => BinOpKind::Mul,
1028 AssignOpKind::DivAssign => BinOpKind::Div,
1029 AssignOpKind::RemAssign => BinOpKind::Rem,
1030 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1031 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1032 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1033 AssignOpKind::ShlAssign => BinOpKind::Shl,
1034 AssignOpKind::ShrAssign => BinOpKind::Shr,
1035 }
1036 }
1037}
1038
1039#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1040pub enum AssignOpKind {
1041 AddAssign,
1043 SubAssign,
1045 MulAssign,
1047 DivAssign,
1049 RemAssign,
1051 BitXorAssign,
1053 BitAndAssign,
1055 BitOrAssign,
1057 ShlAssign,
1059 ShrAssign,
1061}
1062
1063impl AssignOpKind {
1064 pub fn as_str(&self) -> &'static str {
1065 use AssignOpKind::*;
1066 match self {
1067 AddAssign => "+=",
1068 SubAssign => "-=",
1069 MulAssign => "*=",
1070 DivAssign => "/=",
1071 RemAssign => "%=",
1072 BitXorAssign => "^=",
1073 BitAndAssign => "&=",
1074 BitOrAssign => "|=",
1075 ShlAssign => "<<=",
1076 ShrAssign => ">>=",
1077 }
1078 }
1079
1080 pub fn is_by_value(self) -> bool {
1082 true
1083 }
1084}
1085
1086pub type AssignOp = Spanned<AssignOpKind>;
1087
1088#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1092pub enum UnOp {
1093 Deref,
1095 Not,
1097 Neg,
1099}
1100
1101impl UnOp {
1102 pub fn as_str(&self) -> &'static str {
1103 match self {
1104 UnOp::Deref => "*",
1105 UnOp::Not => "!",
1106 UnOp::Neg => "-",
1107 }
1108 }
1109
1110 pub fn is_by_value(self) -> bool {
1112 matches!(self, Self::Neg | Self::Not)
1113 }
1114}
1115
1116#[derive(Clone, Encodable, Decodable, Debug)]
1120pub struct Stmt {
1121 pub id: NodeId,
1122 pub kind: StmtKind,
1123 pub span: Span,
1124}
1125
1126impl Stmt {
1127 pub fn has_trailing_semicolon(&self) -> bool {
1128 match &self.kind {
1129 StmtKind::Semi(_) => true,
1130 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1131 _ => false,
1132 }
1133 }
1134
1135 pub fn add_trailing_semicolon(mut self) -> Self {
1143 self.kind = match self.kind {
1144 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1145 StmtKind::MacCall(mut mac) => {
1146 mac.style = MacStmtStyle::Semicolon;
1147 StmtKind::MacCall(mac)
1148 }
1149 kind => kind,
1150 };
1151
1152 self
1153 }
1154
1155 pub fn is_item(&self) -> bool {
1156 matches!(self.kind, StmtKind::Item(_))
1157 }
1158
1159 pub fn is_expr(&self) -> bool {
1160 matches!(self.kind, StmtKind::Expr(_))
1161 }
1162}
1163
1164#[derive(Clone, Encodable, Decodable, Debug)]
1166pub enum StmtKind {
1167 Let(P<Local>),
1169 Item(P<Item>),
1171 Expr(P<Expr>),
1173 Semi(P<Expr>),
1175 Empty,
1177 MacCall(P<MacCallStmt>),
1179}
1180
1181#[derive(Clone, Encodable, Decodable, Debug)]
1182pub struct MacCallStmt {
1183 pub mac: P<MacCall>,
1184 pub style: MacStmtStyle,
1185 pub attrs: AttrVec,
1186 pub tokens: Option<LazyAttrTokenStream>,
1187}
1188
1189#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1190pub enum MacStmtStyle {
1191 Semicolon,
1194 Braces,
1196 NoBraces,
1200}
1201
1202#[derive(Clone, Encodable, Decodable, Debug)]
1204pub struct Local {
1205 pub id: NodeId,
1206 pub super_: Option<Span>,
1207 pub pat: P<Pat>,
1208 pub ty: Option<P<Ty>>,
1209 pub kind: LocalKind,
1210 pub span: Span,
1211 pub colon_sp: Option<Span>,
1212 pub attrs: AttrVec,
1213 pub tokens: Option<LazyAttrTokenStream>,
1214}
1215
1216#[derive(Clone, Encodable, Decodable, Debug)]
1217pub enum LocalKind {
1218 Decl,
1221 Init(P<Expr>),
1224 InitElse(P<Expr>, P<Block>),
1227}
1228
1229impl LocalKind {
1230 pub fn init(&self) -> Option<&Expr> {
1231 match self {
1232 Self::Decl => None,
1233 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1234 }
1235 }
1236
1237 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1238 match self {
1239 Self::Decl => None,
1240 Self::Init(init) => Some((init, None)),
1241 Self::InitElse(init, els) => Some((init, Some(els))),
1242 }
1243 }
1244}
1245
1246#[derive(Clone, Encodable, Decodable, Debug)]
1257pub struct Arm {
1258 pub attrs: AttrVec,
1259 pub pat: P<Pat>,
1261 pub guard: Option<P<Expr>>,
1263 pub body: Option<P<Expr>>,
1265 pub span: Span,
1266 pub id: NodeId,
1267 pub is_placeholder: bool,
1268}
1269
1270#[derive(Clone, Encodable, Decodable, Debug)]
1272pub struct ExprField {
1273 pub attrs: AttrVec,
1274 pub id: NodeId,
1275 pub span: Span,
1276 pub ident: Ident,
1277 pub expr: P<Expr>,
1278 pub is_shorthand: bool,
1279 pub is_placeholder: bool,
1280}
1281
1282#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1283pub enum BlockCheckMode {
1284 Default,
1285 Unsafe(UnsafeSource),
1286}
1287
1288#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1289pub enum UnsafeSource {
1290 CompilerGenerated,
1291 UserProvided,
1292}
1293
1294#[derive(Clone, Encodable, Decodable, Debug)]
1300pub struct AnonConst {
1301 pub id: NodeId,
1302 pub value: P<Expr>,
1303}
1304
1305#[derive(Clone, Encodable, Decodable, Debug)]
1307pub struct Expr {
1308 pub id: NodeId,
1309 pub kind: ExprKind,
1310 pub span: Span,
1311 pub attrs: AttrVec,
1312 pub tokens: Option<LazyAttrTokenStream>,
1313}
1314
1315impl Expr {
1316 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1330 let this = self.maybe_unwrap_block();
1331 if allow_mgca_arg {
1332 matches!(this.kind, ExprKind::Path(..))
1333 } else {
1334 if let ExprKind::Path(None, path) = &this.kind
1335 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1336 {
1337 true
1338 } else {
1339 false
1340 }
1341 }
1342 }
1343
1344 pub fn maybe_unwrap_block(&self) -> &Expr {
1346 if let ExprKind::Block(block, None) = &self.kind
1347 && let [stmt] = block.stmts.as_slice()
1348 && let StmtKind::Expr(expr) = &stmt.kind
1349 {
1350 expr
1351 } else {
1352 self
1353 }
1354 }
1355
1356 pub fn optionally_braced_mac_call(
1362 &self,
1363 already_stripped_block: bool,
1364 ) -> Option<(bool, NodeId)> {
1365 match &self.kind {
1366 ExprKind::Block(block, None)
1367 if let [stmt] = &*block.stmts
1368 && !already_stripped_block =>
1369 {
1370 match &stmt.kind {
1371 StmtKind::MacCall(_) => Some((true, stmt.id)),
1372 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1373 Some((true, expr.id))
1374 }
1375 _ => None,
1376 }
1377 }
1378 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1379 _ => None,
1380 }
1381 }
1382
1383 pub fn to_bound(&self) -> Option<GenericBound> {
1384 match &self.kind {
1385 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1386 ThinVec::new(),
1387 path.clone(),
1388 TraitBoundModifiers::NONE,
1389 self.span,
1390 Parens::No,
1391 ))),
1392 _ => None,
1393 }
1394 }
1395
1396 pub fn peel_parens(&self) -> &Expr {
1397 let mut expr = self;
1398 while let ExprKind::Paren(inner) = &expr.kind {
1399 expr = inner;
1400 }
1401 expr
1402 }
1403
1404 pub fn peel_parens_and_refs(&self) -> &Expr {
1405 let mut expr = self;
1406 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1407 {
1408 expr = inner;
1409 }
1410 expr
1411 }
1412
1413 pub fn to_ty(&self) -> Option<P<Ty>> {
1415 let kind = match &self.kind {
1416 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1418 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1419
1420 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1421
1422 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1423 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1424 }
1425
1426 ExprKind::Repeat(expr, expr_len) => {
1427 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1428 }
1429
1430 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1431 expr.to_ty().map(TyKind::Slice)?
1432 }
1433
1434 ExprKind::Tup(exprs) => {
1435 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1436 TyKind::Tup(tys)
1437 }
1438
1439 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1443 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1444 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1445 } else {
1446 return None;
1447 }
1448 }
1449
1450 ExprKind::Underscore => TyKind::Infer,
1451
1452 _ => return None,
1454 };
1455
1456 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1457 }
1458
1459 pub fn precedence(&self) -> ExprPrecedence {
1460 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1461 for attr in attrs {
1462 if let AttrStyle::Outer = attr.style {
1463 return ExprPrecedence::Prefix;
1464 }
1465 }
1466 ExprPrecedence::Unambiguous
1467 }
1468
1469 match &self.kind {
1470 ExprKind::Closure(closure) => {
1471 match closure.fn_decl.output {
1472 FnRetTy::Default(_) => ExprPrecedence::Jump,
1473 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1474 }
1475 }
1476
1477 ExprKind::Break(_ , value)
1478 | ExprKind::Ret(value)
1479 | ExprKind::Yield(YieldKind::Prefix(value))
1480 | ExprKind::Yeet(value) => match value {
1481 Some(_) => ExprPrecedence::Jump,
1482 None => prefix_attrs_precedence(&self.attrs),
1483 },
1484
1485 ExprKind::Become(_) => ExprPrecedence::Jump,
1486
1487 ExprKind::Range(..) => ExprPrecedence::Range,
1492
1493 ExprKind::Binary(op, ..) => op.node.precedence(),
1495 ExprKind::Cast(..) => ExprPrecedence::Cast,
1496
1497 ExprKind::Assign(..) |
1498 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1499
1500 ExprKind::AddrOf(..)
1502 | ExprKind::Let(..)
1507 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1508
1509 ExprKind::Array(_)
1511 | ExprKind::Await(..)
1512 | ExprKind::Use(..)
1513 | ExprKind::Block(..)
1514 | ExprKind::Call(..)
1515 | ExprKind::ConstBlock(_)
1516 | ExprKind::Continue(..)
1517 | ExprKind::Field(..)
1518 | ExprKind::ForLoop { .. }
1519 | ExprKind::FormatArgs(..)
1520 | ExprKind::Gen(..)
1521 | ExprKind::If(..)
1522 | ExprKind::IncludedBytes(..)
1523 | ExprKind::Index(..)
1524 | ExprKind::InlineAsm(..)
1525 | ExprKind::Lit(_)
1526 | ExprKind::Loop(..)
1527 | ExprKind::MacCall(..)
1528 | ExprKind::Match(..)
1529 | ExprKind::MethodCall(..)
1530 | ExprKind::OffsetOf(..)
1531 | ExprKind::Paren(..)
1532 | ExprKind::Path(..)
1533 | ExprKind::Repeat(..)
1534 | ExprKind::Struct(..)
1535 | ExprKind::Try(..)
1536 | ExprKind::TryBlock(..)
1537 | ExprKind::Tup(_)
1538 | ExprKind::Type(..)
1539 | ExprKind::Underscore
1540 | ExprKind::UnsafeBinderCast(..)
1541 | ExprKind::While(..)
1542 | ExprKind::Yield(YieldKind::Postfix(..))
1543 | ExprKind::Err(_)
1544 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1545 }
1546 }
1547
1548 pub fn is_approximately_pattern(&self) -> bool {
1550 matches!(
1551 &self.peel_parens().kind,
1552 ExprKind::Array(_)
1553 | ExprKind::Call(_, _)
1554 | ExprKind::Tup(_)
1555 | ExprKind::Lit(_)
1556 | ExprKind::Range(_, _, _)
1557 | ExprKind::Underscore
1558 | ExprKind::Path(_, _)
1559 | ExprKind::Struct(_)
1560 )
1561 }
1562
1563 pub fn dummy() -> Expr {
1567 Expr {
1568 id: DUMMY_NODE_ID,
1569 kind: ExprKind::Dummy,
1570 span: DUMMY_SP,
1571 attrs: ThinVec::new(),
1572 tokens: None,
1573 }
1574 }
1575}
1576
1577impl From<P<Expr>> for Expr {
1578 fn from(value: P<Expr>) -> Self {
1579 *value
1580 }
1581}
1582
1583#[derive(Clone, Encodable, Decodable, Debug)]
1584pub struct Closure {
1585 pub binder: ClosureBinder,
1586 pub capture_clause: CaptureBy,
1587 pub constness: Const,
1588 pub coroutine_kind: Option<CoroutineKind>,
1589 pub movability: Movability,
1590 pub fn_decl: P<FnDecl>,
1591 pub body: P<Expr>,
1592 pub fn_decl_span: Span,
1594 pub fn_arg_span: Span,
1596}
1597
1598#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1600pub enum RangeLimits {
1601 HalfOpen,
1603 Closed,
1605}
1606
1607impl RangeLimits {
1608 pub fn as_str(&self) -> &'static str {
1609 match self {
1610 RangeLimits::HalfOpen => "..",
1611 RangeLimits::Closed => "..=",
1612 }
1613 }
1614}
1615
1616#[derive(Clone, Encodable, Decodable, Debug)]
1618pub struct MethodCall {
1619 pub seg: PathSegment,
1621 pub receiver: P<Expr>,
1623 pub args: ThinVec<P<Expr>>,
1625 pub span: Span,
1628}
1629
1630#[derive(Clone, Encodable, Decodable, Debug)]
1631pub enum StructRest {
1632 Base(P<Expr>),
1634 Rest(Span),
1636 None,
1638}
1639
1640#[derive(Clone, Encodable, Decodable, Debug)]
1641pub struct StructExpr {
1642 pub qself: Option<P<QSelf>>,
1643 pub path: Path,
1644 pub fields: ThinVec<ExprField>,
1645 pub rest: StructRest,
1646}
1647
1648#[derive(Clone, Encodable, Decodable, Debug)]
1650pub enum ExprKind {
1651 Array(ThinVec<P<Expr>>),
1653 ConstBlock(AnonConst),
1655 Call(P<Expr>, ThinVec<P<Expr>>),
1662 MethodCall(Box<MethodCall>),
1664 Tup(ThinVec<P<Expr>>),
1666 Binary(BinOp, P<Expr>, P<Expr>),
1668 Unary(UnOp, P<Expr>),
1670 Lit(token::Lit),
1672 Cast(P<Expr>, P<Ty>),
1674 Type(P<Expr>, P<Ty>),
1679 Let(P<Pat>, P<Expr>, Span, Recovered),
1684 If(P<Expr>, P<Block>, Option<P<Expr>>),
1691 While(P<Expr>, P<Block>, Option<Label>),
1695 ForLoop {
1701 pat: P<Pat>,
1702 iter: P<Expr>,
1703 body: P<Block>,
1704 label: Option<Label>,
1705 kind: ForLoopKind,
1706 },
1707 Loop(P<Block>, Option<Label>, Span),
1711 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1713 Closure(Box<Closure>),
1715 Block(P<Block>, Option<Label>),
1717 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1723 Await(P<Expr>, Span),
1725 Use(P<Expr>, Span),
1727
1728 TryBlock(P<Block>),
1730
1731 Assign(P<Expr>, P<Expr>, Span),
1734 AssignOp(AssignOp, P<Expr>, P<Expr>),
1738 Field(P<Expr>, Ident),
1740 Index(P<Expr>, P<Expr>, Span),
1743 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1745 Underscore,
1747
1748 Path(Option<P<QSelf>>, Path),
1753
1754 AddrOf(BorrowKind, Mutability, P<Expr>),
1756 Break(Option<Label>, Option<P<Expr>>),
1758 Continue(Option<Label>),
1760 Ret(Option<P<Expr>>),
1762
1763 InlineAsm(P<InlineAsm>),
1765
1766 OffsetOf(P<Ty>, Vec<Ident>),
1771
1772 MacCall(P<MacCall>),
1774
1775 Struct(P<StructExpr>),
1779
1780 Repeat(P<Expr>, AnonConst),
1785
1786 Paren(P<Expr>),
1788
1789 Try(P<Expr>),
1791
1792 Yield(YieldKind),
1794
1795 Yeet(Option<P<Expr>>),
1798
1799 Become(P<Expr>),
1803
1804 IncludedBytes(ByteSymbol),
1816
1817 FormatArgs(P<FormatArgs>),
1819
1820 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1821
1822 Err(ErrorGuaranteed),
1824
1825 Dummy,
1827}
1828
1829#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1831pub enum ForLoopKind {
1832 For,
1833 ForAwait,
1834}
1835
1836#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1838pub enum GenBlockKind {
1839 Async,
1840 Gen,
1841 AsyncGen,
1842}
1843
1844impl fmt::Display for GenBlockKind {
1845 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1846 self.modifier().fmt(f)
1847 }
1848}
1849
1850impl GenBlockKind {
1851 pub fn modifier(&self) -> &'static str {
1852 match self {
1853 GenBlockKind::Async => "async",
1854 GenBlockKind::Gen => "gen",
1855 GenBlockKind::AsyncGen => "async gen",
1856 }
1857 }
1858}
1859
1860#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1862#[derive(Encodable, Decodable, HashStable_Generic)]
1863pub enum UnsafeBinderCastKind {
1864 Wrap,
1866 Unwrap,
1868}
1869
1870#[derive(Clone, Encodable, Decodable, Debug)]
1885pub struct QSelf {
1886 pub ty: P<Ty>,
1887
1888 pub path_span: Span,
1892 pub position: usize,
1893}
1894
1895#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1897pub enum CaptureBy {
1898 Value {
1900 move_kw: Span,
1902 },
1903 Ref,
1905 Use {
1911 use_kw: Span,
1913 },
1914}
1915
1916#[derive(Clone, Encodable, Decodable, Debug)]
1918pub enum ClosureBinder {
1919 NotPresent,
1921 For {
1923 span: Span,
1930
1931 generic_params: ThinVec<GenericParam>,
1938 },
1939}
1940
1941#[derive(Clone, Encodable, Decodable, Debug)]
1944pub struct MacCall {
1945 pub path: Path,
1946 pub args: P<DelimArgs>,
1947}
1948
1949impl MacCall {
1950 pub fn span(&self) -> Span {
1951 self.path.span.to(self.args.dspan.entire())
1952 }
1953}
1954
1955#[derive(Clone, Encodable, Decodable, Debug)]
1957pub enum AttrArgs {
1958 Empty,
1960 Delimited(DelimArgs),
1962 Eq {
1964 eq_span: Span,
1966 expr: P<Expr>,
1967 },
1968}
1969
1970impl AttrArgs {
1971 pub fn span(&self) -> Option<Span> {
1972 match self {
1973 AttrArgs::Empty => None,
1974 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1975 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1976 }
1977 }
1978
1979 pub fn inner_tokens(&self) -> TokenStream {
1982 match self {
1983 AttrArgs::Empty => TokenStream::default(),
1984 AttrArgs::Delimited(args) => args.tokens.clone(),
1985 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1986 }
1987 }
1988}
1989
1990#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1992pub struct DelimArgs {
1993 pub dspan: DelimSpan,
1994 pub delim: Delimiter, pub tokens: TokenStream,
1996}
1997
1998impl DelimArgs {
1999 pub fn need_semicolon(&self) -> bool {
2002 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2003 }
2004}
2005
2006#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2008pub struct MacroDef {
2009 pub body: P<DelimArgs>,
2010 pub macro_rules: bool,
2012}
2013
2014#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2015#[derive(HashStable_Generic)]
2016pub enum StrStyle {
2017 Cooked,
2019 Raw(u8),
2023}
2024
2025#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
2027pub enum MatchKind {
2028 Prefix,
2030 Postfix,
2032}
2033
2034#[derive(Clone, Encodable, Decodable, Debug)]
2036pub enum YieldKind {
2037 Prefix(Option<P<Expr>>),
2039 Postfix(P<Expr>),
2041}
2042
2043impl YieldKind {
2044 pub const fn expr(&self) -> Option<&P<Expr>> {
2048 match self {
2049 YieldKind::Prefix(expr) => expr.as_ref(),
2050 YieldKind::Postfix(expr) => Some(expr),
2051 }
2052 }
2053
2054 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2056 match self {
2057 YieldKind::Prefix(expr) => expr.as_mut(),
2058 YieldKind::Postfix(expr) => Some(expr),
2059 }
2060 }
2061
2062 pub const fn same_kind(&self, other: &Self) -> bool {
2064 match (self, other) {
2065 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2066 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2067 _ => false,
2068 }
2069 }
2070}
2071
2072#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2074pub struct MetaItemLit {
2075 pub symbol: Symbol,
2077 pub suffix: Option<Symbol>,
2079 pub kind: LitKind,
2082 pub span: Span,
2083}
2084
2085#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2087pub struct StrLit {
2088 pub symbol: Symbol,
2090 pub suffix: Option<Symbol>,
2092 pub symbol_unescaped: Symbol,
2094 pub style: StrStyle,
2095 pub span: Span,
2096}
2097
2098impl StrLit {
2099 pub fn as_token_lit(&self) -> token::Lit {
2100 let token_kind = match self.style {
2101 StrStyle::Cooked => token::Str,
2102 StrStyle::Raw(n) => token::StrRaw(n),
2103 };
2104 token::Lit::new(token_kind, self.symbol, self.suffix)
2105 }
2106}
2107
2108#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2110#[derive(HashStable_Generic)]
2111pub enum LitIntType {
2112 Signed(IntTy),
2114 Unsigned(UintTy),
2116 Unsuffixed,
2118}
2119
2120#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2122#[derive(HashStable_Generic)]
2123pub enum LitFloatType {
2124 Suffixed(FloatTy),
2126 Unsuffixed,
2128}
2129
2130#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2137pub enum LitKind {
2138 Str(Symbol, StrStyle),
2141 ByteStr(ByteSymbol, StrStyle),
2144 CStr(ByteSymbol, StrStyle),
2148 Byte(u8),
2150 Char(char),
2152 Int(Pu128, LitIntType),
2154 Float(Symbol, LitFloatType),
2158 Bool(bool),
2160 Err(ErrorGuaranteed),
2162}
2163
2164impl LitKind {
2165 pub fn str(&self) -> Option<Symbol> {
2166 match *self {
2167 LitKind::Str(s, _) => Some(s),
2168 _ => None,
2169 }
2170 }
2171
2172 pub fn is_str(&self) -> bool {
2174 matches!(self, LitKind::Str(..))
2175 }
2176
2177 pub fn is_bytestr(&self) -> bool {
2179 matches!(self, LitKind::ByteStr(..))
2180 }
2181
2182 pub fn is_numeric(&self) -> bool {
2184 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2185 }
2186
2187 pub fn is_unsuffixed(&self) -> bool {
2190 !self.is_suffixed()
2191 }
2192
2193 pub fn is_suffixed(&self) -> bool {
2195 match *self {
2196 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2198 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2199 LitKind::Str(..)
2201 | LitKind::ByteStr(..)
2202 | LitKind::CStr(..)
2203 | LitKind::Byte(..)
2204 | LitKind::Char(..)
2205 | LitKind::Int(_, LitIntType::Unsuffixed)
2206 | LitKind::Float(_, LitFloatType::Unsuffixed)
2207 | LitKind::Bool(..)
2208 | LitKind::Err(_) => false,
2209 }
2210 }
2211}
2212
2213#[derive(Clone, Encodable, Decodable, Debug)]
2216pub struct MutTy {
2217 pub ty: P<Ty>,
2218 pub mutbl: Mutability,
2219}
2220
2221#[derive(Clone, Encodable, Decodable, Debug)]
2224pub struct FnSig {
2225 pub header: FnHeader,
2226 pub decl: P<FnDecl>,
2227 pub span: Span,
2228}
2229
2230#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2231#[derive(Encodable, Decodable, HashStable_Generic)]
2232pub enum FloatTy {
2233 F16,
2234 F32,
2235 F64,
2236 F128,
2237}
2238
2239impl FloatTy {
2240 pub fn name_str(self) -> &'static str {
2241 match self {
2242 FloatTy::F16 => "f16",
2243 FloatTy::F32 => "f32",
2244 FloatTy::F64 => "f64",
2245 FloatTy::F128 => "f128",
2246 }
2247 }
2248
2249 pub fn name(self) -> Symbol {
2250 match self {
2251 FloatTy::F16 => sym::f16,
2252 FloatTy::F32 => sym::f32,
2253 FloatTy::F64 => sym::f64,
2254 FloatTy::F128 => sym::f128,
2255 }
2256 }
2257}
2258
2259#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2260#[derive(Encodable, Decodable, HashStable_Generic)]
2261pub enum IntTy {
2262 Isize,
2263 I8,
2264 I16,
2265 I32,
2266 I64,
2267 I128,
2268}
2269
2270impl IntTy {
2271 pub fn name_str(&self) -> &'static str {
2272 match *self {
2273 IntTy::Isize => "isize",
2274 IntTy::I8 => "i8",
2275 IntTy::I16 => "i16",
2276 IntTy::I32 => "i32",
2277 IntTy::I64 => "i64",
2278 IntTy::I128 => "i128",
2279 }
2280 }
2281
2282 pub fn name(&self) -> Symbol {
2283 match *self {
2284 IntTy::Isize => sym::isize,
2285 IntTy::I8 => sym::i8,
2286 IntTy::I16 => sym::i16,
2287 IntTy::I32 => sym::i32,
2288 IntTy::I64 => sym::i64,
2289 IntTy::I128 => sym::i128,
2290 }
2291 }
2292}
2293
2294#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2295#[derive(Encodable, Decodable, HashStable_Generic)]
2296pub enum UintTy {
2297 Usize,
2298 U8,
2299 U16,
2300 U32,
2301 U64,
2302 U128,
2303}
2304
2305impl UintTy {
2306 pub fn name_str(&self) -> &'static str {
2307 match *self {
2308 UintTy::Usize => "usize",
2309 UintTy::U8 => "u8",
2310 UintTy::U16 => "u16",
2311 UintTy::U32 => "u32",
2312 UintTy::U64 => "u64",
2313 UintTy::U128 => "u128",
2314 }
2315 }
2316
2317 pub fn name(&self) -> Symbol {
2318 match *self {
2319 UintTy::Usize => sym::usize,
2320 UintTy::U8 => sym::u8,
2321 UintTy::U16 => sym::u16,
2322 UintTy::U32 => sym::u32,
2323 UintTy::U64 => sym::u64,
2324 UintTy::U128 => sym::u128,
2325 }
2326 }
2327}
2328
2329#[derive(Clone, Encodable, Decodable, Debug)]
2340pub struct AssocItemConstraint {
2341 pub id: NodeId,
2342 pub ident: Ident,
2343 pub gen_args: Option<GenericArgs>,
2344 pub kind: AssocItemConstraintKind,
2345 pub span: Span,
2346}
2347
2348#[derive(Clone, Encodable, Decodable, Debug)]
2349pub enum Term {
2350 Ty(P<Ty>),
2351 Const(AnonConst),
2352}
2353
2354impl From<P<Ty>> for Term {
2355 fn from(v: P<Ty>) -> Self {
2356 Term::Ty(v)
2357 }
2358}
2359
2360impl From<AnonConst> for Term {
2361 fn from(v: AnonConst) -> Self {
2362 Term::Const(v)
2363 }
2364}
2365
2366#[derive(Clone, Encodable, Decodable, Debug)]
2368pub enum AssocItemConstraintKind {
2369 Equality { term: Term },
2376 Bound { bounds: GenericBounds },
2378}
2379
2380#[derive(Encodable, Decodable, Debug)]
2381pub struct Ty {
2382 pub id: NodeId,
2383 pub kind: TyKind,
2384 pub span: Span,
2385 pub tokens: Option<LazyAttrTokenStream>,
2386}
2387
2388impl Clone for Ty {
2389 fn clone(&self) -> Self {
2390 ensure_sufficient_stack(|| Self {
2391 id: self.id,
2392 kind: self.kind.clone(),
2393 span: self.span,
2394 tokens: self.tokens.clone(),
2395 })
2396 }
2397}
2398
2399impl From<P<Ty>> for Ty {
2400 fn from(value: P<Ty>) -> Self {
2401 *value
2402 }
2403}
2404
2405impl Ty {
2406 pub fn peel_refs(&self) -> &Self {
2407 let mut final_ty = self;
2408 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2409 {
2410 final_ty = ty;
2411 }
2412 final_ty
2413 }
2414
2415 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2416 match &self.kind {
2417 TyKind::Infer => true,
2418 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2419 _ => false,
2420 }
2421 }
2422}
2423
2424#[derive(Clone, Encodable, Decodable, Debug)]
2425pub struct FnPtrTy {
2426 pub safety: Safety,
2427 pub ext: Extern,
2428 pub generic_params: ThinVec<GenericParam>,
2429 pub decl: P<FnDecl>,
2430 pub decl_span: Span,
2433}
2434
2435#[derive(Clone, Encodable, Decodable, Debug)]
2436pub struct UnsafeBinderTy {
2437 pub generic_params: ThinVec<GenericParam>,
2438 pub inner_ty: P<Ty>,
2439}
2440
2441#[derive(Clone, Encodable, Decodable, Debug)]
2445pub enum TyKind {
2446 Slice(P<Ty>),
2448 Array(P<Ty>, AnonConst),
2450 Ptr(MutTy),
2452 Ref(Option<Lifetime>, MutTy),
2454 PinnedRef(Option<Lifetime>, MutTy),
2458 FnPtr(P<FnPtrTy>),
2460 UnsafeBinder(P<UnsafeBinderTy>),
2462 Never,
2464 Tup(ThinVec<P<Ty>>),
2466 Path(Option<P<QSelf>>, Path),
2471 TraitObject(GenericBounds, TraitObjectSyntax),
2474 ImplTrait(NodeId, GenericBounds),
2481 Paren(P<Ty>),
2483 Typeof(AnonConst),
2485 Infer,
2488 ImplicitSelf,
2490 MacCall(P<MacCall>),
2492 CVarArgs,
2494 Pat(P<Ty>, P<TyPat>),
2497 Dummy,
2499 Err(ErrorGuaranteed),
2501}
2502
2503impl TyKind {
2504 pub fn is_implicit_self(&self) -> bool {
2505 matches!(self, TyKind::ImplicitSelf)
2506 }
2507
2508 pub fn is_unit(&self) -> bool {
2509 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2510 }
2511
2512 pub fn is_simple_path(&self) -> Option<Symbol> {
2513 if let TyKind::Path(None, Path { segments, .. }) = &self
2514 && let [segment] = &segments[..]
2515 && segment.args.is_none()
2516 {
2517 Some(segment.ident.name)
2518 } else {
2519 None
2520 }
2521 }
2522
2523 pub fn maybe_scalar(&self) -> bool {
2531 let Some(ty_sym) = self.is_simple_path() else {
2532 return self.is_unit();
2534 };
2535 matches!(
2536 ty_sym,
2537 sym::i8
2538 | sym::i16
2539 | sym::i32
2540 | sym::i64
2541 | sym::i128
2542 | sym::u8
2543 | sym::u16
2544 | sym::u32
2545 | sym::u64
2546 | sym::u128
2547 | sym::f16
2548 | sym::f32
2549 | sym::f64
2550 | sym::f128
2551 | sym::char
2552 | sym::bool
2553 )
2554 }
2555}
2556
2557#[derive(Clone, Encodable, Decodable, Debug)]
2559pub struct TyPat {
2560 pub id: NodeId,
2561 pub kind: TyPatKind,
2562 pub span: Span,
2563 pub tokens: Option<LazyAttrTokenStream>,
2564}
2565
2566#[derive(Clone, Encodable, Decodable, Debug)]
2570pub enum TyPatKind {
2571 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2573
2574 Or(ThinVec<P<TyPat>>),
2575
2576 Err(ErrorGuaranteed),
2578}
2579
2580#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2582#[repr(u8)]
2583pub enum TraitObjectSyntax {
2584 Dyn = 0,
2586 None = 1,
2587}
2588
2589unsafe impl Tag for TraitObjectSyntax {
2593 const BITS: u32 = 2;
2594
2595 fn into_usize(self) -> usize {
2596 self as u8 as usize
2597 }
2598
2599 unsafe fn from_usize(tag: usize) -> Self {
2600 match tag {
2601 0 => TraitObjectSyntax::Dyn,
2602 1 => TraitObjectSyntax::None,
2603 _ => unreachable!(),
2604 }
2605 }
2606}
2607
2608#[derive(Clone, Encodable, Decodable, Debug)]
2609pub enum PreciseCapturingArg {
2610 Lifetime(Lifetime),
2612 Arg(Path, NodeId),
2614}
2615
2616#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2620pub enum InlineAsmRegOrRegClass {
2621 Reg(Symbol),
2622 RegClass(Symbol),
2623}
2624
2625#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2626pub struct InlineAsmOptions(u16);
2627bitflags::bitflags! {
2628 impl InlineAsmOptions: u16 {
2629 const PURE = 1 << 0;
2630 const NOMEM = 1 << 1;
2631 const READONLY = 1 << 2;
2632 const PRESERVES_FLAGS = 1 << 3;
2633 const NORETURN = 1 << 4;
2634 const NOSTACK = 1 << 5;
2635 const ATT_SYNTAX = 1 << 6;
2636 const RAW = 1 << 7;
2637 const MAY_UNWIND = 1 << 8;
2638 }
2639}
2640
2641impl InlineAsmOptions {
2642 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2643
2644 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2645 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2646
2647 pub fn human_readable_names(&self) -> Vec<&'static str> {
2648 let mut options = vec![];
2649
2650 if self.contains(InlineAsmOptions::PURE) {
2651 options.push("pure");
2652 }
2653 if self.contains(InlineAsmOptions::NOMEM) {
2654 options.push("nomem");
2655 }
2656 if self.contains(InlineAsmOptions::READONLY) {
2657 options.push("readonly");
2658 }
2659 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2660 options.push("preserves_flags");
2661 }
2662 if self.contains(InlineAsmOptions::NORETURN) {
2663 options.push("noreturn");
2664 }
2665 if self.contains(InlineAsmOptions::NOSTACK) {
2666 options.push("nostack");
2667 }
2668 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2669 options.push("att_syntax");
2670 }
2671 if self.contains(InlineAsmOptions::RAW) {
2672 options.push("raw");
2673 }
2674 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2675 options.push("may_unwind");
2676 }
2677
2678 options
2679 }
2680}
2681
2682impl std::fmt::Debug for InlineAsmOptions {
2683 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2684 bitflags::parser::to_writer(self, f)
2685 }
2686}
2687
2688#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2689pub enum InlineAsmTemplatePiece {
2690 String(Cow<'static, str>),
2691 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2692}
2693
2694impl fmt::Display for InlineAsmTemplatePiece {
2695 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2696 match self {
2697 Self::String(s) => {
2698 for c in s.chars() {
2699 match c {
2700 '{' => f.write_str("{{")?,
2701 '}' => f.write_str("}}")?,
2702 _ => c.fmt(f)?,
2703 }
2704 }
2705 Ok(())
2706 }
2707 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2708 write!(f, "{{{operand_idx}:{modifier}}}")
2709 }
2710 Self::Placeholder { operand_idx, modifier: None, .. } => {
2711 write!(f, "{{{operand_idx}}}")
2712 }
2713 }
2714 }
2715}
2716
2717impl InlineAsmTemplatePiece {
2718 pub fn to_string(s: &[Self]) -> String {
2720 use fmt::Write;
2721 let mut out = String::new();
2722 for p in s.iter() {
2723 let _ = write!(out, "{p}");
2724 }
2725 out
2726 }
2727}
2728
2729#[derive(Clone, Encodable, Decodable, Debug)]
2737pub struct InlineAsmSym {
2738 pub id: NodeId,
2739 pub qself: Option<P<QSelf>>,
2740 pub path: Path,
2741}
2742
2743#[derive(Clone, Encodable, Decodable, Debug)]
2747pub enum InlineAsmOperand {
2748 In {
2749 reg: InlineAsmRegOrRegClass,
2750 expr: P<Expr>,
2751 },
2752 Out {
2753 reg: InlineAsmRegOrRegClass,
2754 late: bool,
2755 expr: Option<P<Expr>>,
2756 },
2757 InOut {
2758 reg: InlineAsmRegOrRegClass,
2759 late: bool,
2760 expr: P<Expr>,
2761 },
2762 SplitInOut {
2763 reg: InlineAsmRegOrRegClass,
2764 late: bool,
2765 in_expr: P<Expr>,
2766 out_expr: Option<P<Expr>>,
2767 },
2768 Const {
2769 anon_const: AnonConst,
2770 },
2771 Sym {
2772 sym: InlineAsmSym,
2773 },
2774 Label {
2775 block: P<Block>,
2776 },
2777}
2778
2779impl InlineAsmOperand {
2780 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2781 match self {
2782 Self::In { reg, .. }
2783 | Self::Out { reg, .. }
2784 | Self::InOut { reg, .. }
2785 | Self::SplitInOut { reg, .. } => Some(reg),
2786 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2787 }
2788 }
2789}
2790
2791#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2792pub enum AsmMacro {
2793 Asm,
2795 GlobalAsm,
2797 NakedAsm,
2799}
2800
2801impl AsmMacro {
2802 pub const fn macro_name(self) -> &'static str {
2803 match self {
2804 AsmMacro::Asm => "asm",
2805 AsmMacro::GlobalAsm => "global_asm",
2806 AsmMacro::NakedAsm => "naked_asm",
2807 }
2808 }
2809
2810 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2811 match self {
2812 AsmMacro::Asm => true,
2813 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2814 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2815 }
2816 }
2817
2818 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2819 match self {
2820 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2821 AsmMacro::GlobalAsm => true,
2822 AsmMacro::NakedAsm => true,
2823 }
2824 }
2825}
2826
2827#[derive(Clone, Encodable, Decodable, Debug)]
2831pub struct InlineAsm {
2832 pub asm_macro: AsmMacro,
2833 pub template: Vec<InlineAsmTemplatePiece>,
2834 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2835 pub operands: Vec<(InlineAsmOperand, Span)>,
2836 pub clobber_abis: Vec<(Symbol, Span)>,
2837 pub options: InlineAsmOptions,
2838 pub line_spans: Vec<Span>,
2839}
2840
2841#[derive(Clone, Encodable, Decodable, Debug)]
2845pub struct Param {
2846 pub attrs: AttrVec,
2847 pub ty: P<Ty>,
2848 pub pat: P<Pat>,
2849 pub id: NodeId,
2850 pub span: Span,
2851 pub is_placeholder: bool,
2852}
2853
2854#[derive(Clone, Encodable, Decodable, Debug)]
2858pub enum SelfKind {
2859 Value(Mutability),
2861 Region(Option<Lifetime>, Mutability),
2863 Pinned(Option<Lifetime>, Mutability),
2865 Explicit(P<Ty>, Mutability),
2867}
2868
2869impl SelfKind {
2870 pub fn to_ref_suggestion(&self) -> String {
2871 match self {
2872 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2873 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2874 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2875 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2876 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2877 unreachable!("if we had an explicit self, we wouldn't be here")
2878 }
2879 }
2880 }
2881}
2882
2883pub type ExplicitSelf = Spanned<SelfKind>;
2884
2885impl Param {
2886 pub fn to_self(&self) -> Option<ExplicitSelf> {
2888 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2889 if ident.name == kw::SelfLower {
2890 return match self.ty.kind {
2891 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2892 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2893 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2894 }
2895 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2896 if ty.kind.is_implicit_self() =>
2897 {
2898 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2899 }
2900 _ => Some(respan(
2901 self.pat.span.to(self.ty.span),
2902 SelfKind::Explicit(self.ty.clone(), mutbl),
2903 )),
2904 };
2905 }
2906 }
2907 None
2908 }
2909
2910 pub fn is_self(&self) -> bool {
2912 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2913 ident.name == kw::SelfLower
2914 } else {
2915 false
2916 }
2917 }
2918
2919 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2921 let span = eself.span.to(eself_ident.span);
2922 let infer_ty = P(Ty {
2923 id: DUMMY_NODE_ID,
2924 kind: TyKind::ImplicitSelf,
2925 span: eself_ident.span,
2926 tokens: None,
2927 });
2928 let (mutbl, ty) = match eself.node {
2929 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2930 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2931 SelfKind::Region(lt, mutbl) => (
2932 Mutability::Not,
2933 P(Ty {
2934 id: DUMMY_NODE_ID,
2935 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2936 span,
2937 tokens: None,
2938 }),
2939 ),
2940 SelfKind::Pinned(lt, mutbl) => (
2941 mutbl,
2942 P(Ty {
2943 id: DUMMY_NODE_ID,
2944 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2945 span,
2946 tokens: None,
2947 }),
2948 ),
2949 };
2950 Param {
2951 attrs,
2952 pat: P(Pat {
2953 id: DUMMY_NODE_ID,
2954 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2955 span,
2956 tokens: None,
2957 }),
2958 span,
2959 ty,
2960 id: DUMMY_NODE_ID,
2961 is_placeholder: false,
2962 }
2963 }
2964}
2965
2966#[derive(Clone, Encodable, Decodable, Debug)]
2973pub struct FnDecl {
2974 pub inputs: ThinVec<Param>,
2975 pub output: FnRetTy,
2976}
2977
2978impl FnDecl {
2979 pub fn has_self(&self) -> bool {
2980 self.inputs.get(0).is_some_and(Param::is_self)
2981 }
2982 pub fn c_variadic(&self) -> bool {
2983 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2984 }
2985}
2986
2987#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2989pub enum IsAuto {
2990 Yes,
2991 No,
2992}
2993
2994#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2996#[derive(HashStable_Generic)]
2997pub enum Safety {
2998 Unsafe(Span),
3000 Safe(Span),
3002 Default,
3005}
3006
3007#[derive(Copy, Clone, Encodable, Decodable, Debug)]
3013pub enum CoroutineKind {
3014 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3016 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3018 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3020}
3021
3022impl CoroutineKind {
3023 pub fn span(self) -> Span {
3024 match self {
3025 CoroutineKind::Async { span, .. } => span,
3026 CoroutineKind::Gen { span, .. } => span,
3027 CoroutineKind::AsyncGen { span, .. } => span,
3028 }
3029 }
3030
3031 pub fn as_str(self) -> &'static str {
3032 match self {
3033 CoroutineKind::Async { .. } => "async",
3034 CoroutineKind::Gen { .. } => "gen",
3035 CoroutineKind::AsyncGen { .. } => "async gen",
3036 }
3037 }
3038
3039 pub fn closure_id(self) -> NodeId {
3040 match self {
3041 CoroutineKind::Async { closure_id, .. }
3042 | CoroutineKind::Gen { closure_id, .. }
3043 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3044 }
3045 }
3046
3047 pub fn return_id(self) -> (NodeId, Span) {
3050 match self {
3051 CoroutineKind::Async { return_impl_trait_id, span, .. }
3052 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3053 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3054 (return_impl_trait_id, span)
3055 }
3056 }
3057 }
3058}
3059
3060#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3061#[derive(HashStable_Generic)]
3062pub enum Const {
3063 Yes(Span),
3064 No,
3065}
3066
3067#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3070pub enum Defaultness {
3071 Default(Span),
3072 Final,
3073}
3074
3075#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3076pub enum ImplPolarity {
3077 Positive,
3079 Negative(Span),
3081}
3082
3083impl fmt::Debug for ImplPolarity {
3084 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3085 match *self {
3086 ImplPolarity::Positive => "positive".fmt(f),
3087 ImplPolarity::Negative(_) => "negative".fmt(f),
3088 }
3089 }
3090}
3091
3092#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3094#[derive(HashStable_Generic)]
3095pub enum BoundPolarity {
3096 Positive,
3098 Negative(Span),
3100 Maybe(Span),
3102}
3103
3104impl BoundPolarity {
3105 pub fn as_str(self) -> &'static str {
3106 match self {
3107 Self::Positive => "",
3108 Self::Negative(_) => "!",
3109 Self::Maybe(_) => "?",
3110 }
3111 }
3112}
3113
3114#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3116#[derive(HashStable_Generic)]
3117pub enum BoundConstness {
3118 Never,
3120 Always(Span),
3122 Maybe(Span),
3124}
3125
3126impl BoundConstness {
3127 pub fn as_str(self) -> &'static str {
3128 match self {
3129 Self::Never => "",
3130 Self::Always(_) => "const",
3131 Self::Maybe(_) => "[const]",
3132 }
3133 }
3134}
3135
3136#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3138#[derive(HashStable_Generic)]
3139pub enum BoundAsyncness {
3140 Normal,
3142 Async(Span),
3144}
3145
3146impl BoundAsyncness {
3147 pub fn as_str(self) -> &'static str {
3148 match self {
3149 Self::Normal => "",
3150 Self::Async(_) => "async",
3151 }
3152 }
3153}
3154
3155#[derive(Clone, Encodable, Decodable, Debug)]
3156pub enum FnRetTy {
3157 Default(Span),
3162 Ty(P<Ty>),
3164}
3165
3166impl FnRetTy {
3167 pub fn span(&self) -> Span {
3168 match self {
3169 &FnRetTy::Default(span) => span,
3170 FnRetTy::Ty(ty) => ty.span,
3171 }
3172 }
3173}
3174
3175#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3176pub enum Inline {
3177 Yes,
3178 No,
3179}
3180
3181#[derive(Clone, Encodable, Decodable, Debug)]
3183pub enum ModKind {
3184 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3189 Unloaded,
3191}
3192
3193#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3194pub struct ModSpans {
3195 pub inner_span: Span,
3198 pub inject_use_span: Span,
3199}
3200
3201#[derive(Clone, Encodable, Decodable, Debug)]
3205pub struct ForeignMod {
3206 pub extern_span: Span,
3208 pub safety: Safety,
3211 pub abi: Option<StrLit>,
3212 pub items: ThinVec<P<ForeignItem>>,
3213}
3214
3215#[derive(Clone, Encodable, Decodable, Debug)]
3216pub struct EnumDef {
3217 pub variants: ThinVec<Variant>,
3218}
3219#[derive(Clone, Encodable, Decodable, Debug)]
3221pub struct Variant {
3222 pub attrs: AttrVec,
3224 pub id: NodeId,
3226 pub span: Span,
3228 pub vis: Visibility,
3230 pub ident: Ident,
3232
3233 pub data: VariantData,
3235 pub disr_expr: Option<AnonConst>,
3237 pub is_placeholder: bool,
3239}
3240
3241#[derive(Clone, Encodable, Decodable, Debug)]
3243pub enum UseTreeKind {
3244 Simple(Option<Ident>),
3246 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3255 Glob,
3257}
3258
3259#[derive(Clone, Encodable, Decodable, Debug)]
3262pub struct UseTree {
3263 pub prefix: Path,
3264 pub kind: UseTreeKind,
3265 pub span: Span,
3266}
3267
3268impl UseTree {
3269 pub fn ident(&self) -> Ident {
3270 match self.kind {
3271 UseTreeKind::Simple(Some(rename)) => rename,
3272 UseTreeKind::Simple(None) => {
3273 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3274 }
3275 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3276 }
3277 }
3278}
3279
3280#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3284pub enum AttrStyle {
3285 Outer,
3286 Inner,
3287}
3288
3289pub type AttrVec = ThinVec<Attribute>;
3291
3292#[derive(Clone, Encodable, Decodable, Debug)]
3294pub struct Attribute {
3295 pub kind: AttrKind,
3296 pub id: AttrId,
3297 pub style: AttrStyle,
3300 pub span: Span,
3301}
3302
3303#[derive(Clone, Encodable, Decodable, Debug)]
3304pub enum AttrKind {
3305 Normal(P<NormalAttr>),
3307
3308 DocComment(CommentKind, Symbol),
3312}
3313
3314#[derive(Clone, Encodable, Decodable, Debug)]
3315pub struct NormalAttr {
3316 pub item: AttrItem,
3317 pub tokens: Option<LazyAttrTokenStream>,
3319}
3320
3321impl NormalAttr {
3322 pub fn from_ident(ident: Ident) -> Self {
3323 Self {
3324 item: AttrItem {
3325 unsafety: Safety::Default,
3326 path: Path::from_ident(ident),
3327 args: AttrArgs::Empty,
3328 tokens: None,
3329 },
3330 tokens: None,
3331 }
3332 }
3333}
3334
3335#[derive(Clone, Encodable, Decodable, Debug)]
3336pub struct AttrItem {
3337 pub unsafety: Safety,
3338 pub path: Path,
3339 pub args: AttrArgs,
3340 pub tokens: Option<LazyAttrTokenStream>,
3342}
3343
3344impl AttrItem {
3345 pub fn is_valid_for_outer_style(&self) -> bool {
3346 self.path == sym::cfg_attr
3347 || self.path == sym::cfg
3348 || self.path == sym::forbid
3349 || self.path == sym::warn
3350 || self.path == sym::allow
3351 || self.path == sym::deny
3352 }
3353}
3354
3355#[derive(Clone, Encodable, Decodable, Debug)]
3362pub struct TraitRef {
3363 pub path: Path,
3364 pub ref_id: NodeId,
3365}
3366
3367#[derive(Clone, Encodable, Decodable, Debug)]
3369pub enum Parens {
3370 Yes,
3371 No,
3372}
3373
3374#[derive(Clone, Encodable, Decodable, Debug)]
3375pub struct PolyTraitRef {
3376 pub bound_generic_params: ThinVec<GenericParam>,
3378
3379 pub modifiers: TraitBoundModifiers,
3381
3382 pub trait_ref: TraitRef,
3384
3385 pub span: Span,
3386
3387 pub parens: Parens,
3390}
3391
3392impl PolyTraitRef {
3393 pub fn new(
3394 generic_params: ThinVec<GenericParam>,
3395 path: Path,
3396 modifiers: TraitBoundModifiers,
3397 span: Span,
3398 parens: Parens,
3399 ) -> Self {
3400 PolyTraitRef {
3401 bound_generic_params: generic_params,
3402 modifiers,
3403 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3404 span,
3405 parens,
3406 }
3407 }
3408}
3409
3410#[derive(Clone, Encodable, Decodable, Debug)]
3411pub struct Visibility {
3412 pub kind: VisibilityKind,
3413 pub span: Span,
3414 pub tokens: Option<LazyAttrTokenStream>,
3415}
3416
3417#[derive(Clone, Encodable, Decodable, Debug)]
3418pub enum VisibilityKind {
3419 Public,
3420 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3421 Inherited,
3422}
3423
3424impl VisibilityKind {
3425 pub fn is_pub(&self) -> bool {
3426 matches!(self, VisibilityKind::Public)
3427 }
3428}
3429
3430#[derive(Clone, Encodable, Decodable, Debug)]
3434pub struct FieldDef {
3435 pub attrs: AttrVec,
3436 pub id: NodeId,
3437 pub span: Span,
3438 pub vis: Visibility,
3439 pub safety: Safety,
3440 pub ident: Option<Ident>,
3441
3442 pub ty: P<Ty>,
3443 pub default: Option<AnonConst>,
3444 pub is_placeholder: bool,
3445}
3446
3447#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3449pub enum Recovered {
3450 No,
3451 Yes(ErrorGuaranteed),
3452}
3453
3454#[derive(Clone, Encodable, Decodable, Debug)]
3456pub enum VariantData {
3457 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3461 Tuple(ThinVec<FieldDef>, NodeId),
3465 Unit(NodeId),
3469}
3470
3471impl VariantData {
3472 pub fn fields(&self) -> &[FieldDef] {
3474 match self {
3475 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3476 _ => &[],
3477 }
3478 }
3479
3480 pub fn ctor_node_id(&self) -> Option<NodeId> {
3482 match *self {
3483 VariantData::Struct { .. } => None,
3484 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3485 }
3486 }
3487}
3488
3489#[derive(Clone, Encodable, Decodable, Debug)]
3491pub struct Item<K = ItemKind> {
3492 pub attrs: AttrVec,
3493 pub id: NodeId,
3494 pub span: Span,
3495 pub vis: Visibility,
3496
3497 pub kind: K,
3498
3499 pub tokens: Option<LazyAttrTokenStream>,
3507}
3508
3509impl Item {
3510 pub fn span_with_attributes(&self) -> Span {
3512 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3513 }
3514
3515 pub fn opt_generics(&self) -> Option<&Generics> {
3516 match &self.kind {
3517 ItemKind::ExternCrate(..)
3518 | ItemKind::Use(_)
3519 | ItemKind::Mod(..)
3520 | ItemKind::ForeignMod(_)
3521 | ItemKind::GlobalAsm(_)
3522 | ItemKind::MacCall(_)
3523 | ItemKind::Delegation(_)
3524 | ItemKind::DelegationMac(_)
3525 | ItemKind::MacroDef(..) => None,
3526 ItemKind::Static(_) => None,
3527 ItemKind::Const(i) => Some(&i.generics),
3528 ItemKind::Fn(i) => Some(&i.generics),
3529 ItemKind::TyAlias(i) => Some(&i.generics),
3530 ItemKind::TraitAlias(_, generics, _)
3531 | ItemKind::Enum(_, generics, _)
3532 | ItemKind::Struct(_, generics, _)
3533 | ItemKind::Union(_, generics, _) => Some(&generics),
3534 ItemKind::Trait(i) => Some(&i.generics),
3535 ItemKind::Impl(i) => Some(&i.generics),
3536 }
3537 }
3538}
3539
3540#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3542pub enum Extern {
3543 None,
3547 Implicit(Span),
3553 Explicit(StrLit, Span),
3557}
3558
3559impl Extern {
3560 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3561 match abi {
3562 Some(name) => Extern::Explicit(name, span),
3563 None => Extern::Implicit(span),
3564 }
3565 }
3566}
3567
3568#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3573pub struct FnHeader {
3574 pub safety: Safety,
3576 pub coroutine_kind: Option<CoroutineKind>,
3578 pub constness: Const,
3580 pub ext: Extern,
3582}
3583
3584impl FnHeader {
3585 pub fn has_qualifiers(&self) -> bool {
3587 let Self { safety, coroutine_kind, constness, ext } = self;
3588 matches!(safety, Safety::Unsafe(_))
3589 || coroutine_kind.is_some()
3590 || matches!(constness, Const::Yes(_))
3591 || !matches!(ext, Extern::None)
3592 }
3593
3594 pub fn span(&self) -> Option<Span> {
3596 fn append(a: &mut Option<Span>, b: Span) {
3597 *a = match a {
3598 None => Some(b),
3599 Some(x) => Some(x.to(b)),
3600 }
3601 }
3602
3603 let mut full_span = None;
3604
3605 match self.safety {
3606 Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3607 Safety::Default => {}
3608 };
3609
3610 if let Some(coroutine_kind) = self.coroutine_kind {
3611 append(&mut full_span, coroutine_kind.span());
3612 }
3613
3614 if let Const::Yes(span) = self.constness {
3615 append(&mut full_span, span);
3616 }
3617
3618 match self.ext {
3619 Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3620 Extern::None => {}
3621 }
3622
3623 full_span
3624 }
3625}
3626
3627impl Default for FnHeader {
3628 fn default() -> FnHeader {
3629 FnHeader {
3630 safety: Safety::Default,
3631 coroutine_kind: None,
3632 constness: Const::No,
3633 ext: Extern::None,
3634 }
3635 }
3636}
3637
3638#[derive(Clone, Encodable, Decodable, Debug)]
3639pub struct Trait {
3640 pub safety: Safety,
3641 pub is_auto: IsAuto,
3642 pub ident: Ident,
3643 pub generics: Generics,
3644 pub bounds: GenericBounds,
3645 pub items: ThinVec<P<AssocItem>>,
3646}
3647
3648#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3667pub struct TyAliasWhereClause {
3668 pub has_where_token: bool,
3669 pub span: Span,
3670}
3671
3672#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3674pub struct TyAliasWhereClauses {
3675 pub before: TyAliasWhereClause,
3677 pub after: TyAliasWhereClause,
3679 pub split: usize,
3683}
3684
3685#[derive(Clone, Encodable, Decodable, Debug)]
3686pub struct TyAlias {
3687 pub defaultness: Defaultness,
3688 pub ident: Ident,
3689 pub generics: Generics,
3690 pub where_clauses: TyAliasWhereClauses,
3691 pub bounds: GenericBounds,
3692 pub ty: Option<P<Ty>>,
3693}
3694
3695#[derive(Clone, Encodable, Decodable, Debug)]
3696pub struct Impl {
3697 pub defaultness: Defaultness,
3698 pub safety: Safety,
3699 pub generics: Generics,
3700 pub constness: Const,
3701 pub polarity: ImplPolarity,
3702 pub of_trait: Option<TraitRef>,
3704 pub self_ty: P<Ty>,
3705 pub items: ThinVec<P<AssocItem>>,
3706}
3707
3708#[derive(Clone, Encodable, Decodable, Debug, Default)]
3709pub struct FnContract {
3710 pub requires: Option<P<Expr>>,
3711 pub ensures: Option<P<Expr>>,
3712}
3713
3714#[derive(Clone, Encodable, Decodable, Debug)]
3715pub struct Fn {
3716 pub defaultness: Defaultness,
3717 pub ident: Ident,
3718 pub generics: Generics,
3719 pub sig: FnSig,
3720 pub contract: Option<P<FnContract>>,
3721 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3722 pub body: Option<P<Block>>,
3723}
3724
3725#[derive(Clone, Encodable, Decodable, Debug)]
3726pub struct Delegation {
3727 pub id: NodeId,
3729 pub qself: Option<P<QSelf>>,
3730 pub path: Path,
3731 pub ident: Ident,
3732 pub rename: Option<Ident>,
3733 pub body: Option<P<Block>>,
3734 pub from_glob: bool,
3736}
3737
3738#[derive(Clone, Encodable, Decodable, Debug)]
3739pub struct DelegationMac {
3740 pub qself: Option<P<QSelf>>,
3741 pub prefix: Path,
3742 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3744 pub body: Option<P<Block>>,
3745}
3746
3747#[derive(Clone, Encodable, Decodable, Debug)]
3748pub struct StaticItem {
3749 pub ident: Ident,
3750 pub ty: P<Ty>,
3751 pub safety: Safety,
3752 pub mutability: Mutability,
3753 pub expr: Option<P<Expr>>,
3754 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3755}
3756
3757#[derive(Clone, Encodable, Decodable, Debug)]
3758pub struct ConstItem {
3759 pub defaultness: Defaultness,
3760 pub ident: Ident,
3761 pub generics: Generics,
3762 pub ty: P<Ty>,
3763 pub expr: Option<P<Expr>>,
3764 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3765}
3766
3767#[derive(Clone, Encodable, Decodable, Debug)]
3769pub enum ItemKind {
3770 ExternCrate(Option<Symbol>, Ident),
3774 Use(UseTree),
3778 Static(Box<StaticItem>),
3782 Const(Box<ConstItem>),
3786 Fn(Box<Fn>),
3790 Mod(Safety, Ident, ModKind),
3796 ForeignMod(ForeignMod),
3800 GlobalAsm(Box<InlineAsm>),
3802 TyAlias(Box<TyAlias>),
3806 Enum(Ident, Generics, EnumDef),
3810 Struct(Ident, Generics, VariantData),
3814 Union(Ident, Generics, VariantData),
3818 Trait(Box<Trait>),
3822 TraitAlias(Ident, Generics, GenericBounds),
3826 Impl(Box<Impl>),
3830 MacCall(P<MacCall>),
3834 MacroDef(Ident, MacroDef),
3836 Delegation(Box<Delegation>),
3840 DelegationMac(Box<DelegationMac>),
3843}
3844
3845impl ItemKind {
3846 pub fn ident(&self) -> Option<Ident> {
3847 match *self {
3848 ItemKind::ExternCrate(_, ident)
3849 | ItemKind::Static(box StaticItem { ident, .. })
3850 | ItemKind::Const(box ConstItem { ident, .. })
3851 | ItemKind::Fn(box Fn { ident, .. })
3852 | ItemKind::Mod(_, ident, _)
3853 | ItemKind::TyAlias(box TyAlias { ident, .. })
3854 | ItemKind::Enum(ident, ..)
3855 | ItemKind::Struct(ident, ..)
3856 | ItemKind::Union(ident, ..)
3857 | ItemKind::Trait(box Trait { ident, .. })
3858 | ItemKind::TraitAlias(ident, ..)
3859 | ItemKind::MacroDef(ident, _)
3860 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3861
3862 ItemKind::Use(_)
3863 | ItemKind::ForeignMod(_)
3864 | ItemKind::GlobalAsm(_)
3865 | ItemKind::Impl(_)
3866 | ItemKind::MacCall(_)
3867 | ItemKind::DelegationMac(_) => None,
3868 }
3869 }
3870
3871 pub fn article(&self) -> &'static str {
3873 use ItemKind::*;
3874 match self {
3875 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3876 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3877 | Delegation(..) | DelegationMac(..) => "a",
3878 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3879 }
3880 }
3881
3882 pub fn descr(&self) -> &'static str {
3883 match self {
3884 ItemKind::ExternCrate(..) => "extern crate",
3885 ItemKind::Use(..) => "`use` import",
3886 ItemKind::Static(..) => "static item",
3887 ItemKind::Const(..) => "constant item",
3888 ItemKind::Fn(..) => "function",
3889 ItemKind::Mod(..) => "module",
3890 ItemKind::ForeignMod(..) => "extern block",
3891 ItemKind::GlobalAsm(..) => "global asm item",
3892 ItemKind::TyAlias(..) => "type alias",
3893 ItemKind::Enum(..) => "enum",
3894 ItemKind::Struct(..) => "struct",
3895 ItemKind::Union(..) => "union",
3896 ItemKind::Trait(..) => "trait",
3897 ItemKind::TraitAlias(..) => "trait alias",
3898 ItemKind::MacCall(..) => "item macro invocation",
3899 ItemKind::MacroDef(..) => "macro definition",
3900 ItemKind::Impl { .. } => "implementation",
3901 ItemKind::Delegation(..) => "delegated function",
3902 ItemKind::DelegationMac(..) => "delegation",
3903 }
3904 }
3905
3906 pub fn generics(&self) -> Option<&Generics> {
3907 match self {
3908 Self::Fn(box Fn { generics, .. })
3909 | Self::TyAlias(box TyAlias { generics, .. })
3910 | Self::Const(box ConstItem { generics, .. })
3911 | Self::Enum(_, generics, _)
3912 | Self::Struct(_, generics, _)
3913 | Self::Union(_, generics, _)
3914 | Self::Trait(box Trait { generics, .. })
3915 | Self::TraitAlias(_, generics, _)
3916 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3917 _ => None,
3918 }
3919 }
3920}
3921
3922pub type AssocItem = Item<AssocItemKind>;
3925
3926#[derive(Clone, Encodable, Decodable, Debug)]
3934pub enum AssocItemKind {
3935 Const(Box<ConstItem>),
3938 Fn(Box<Fn>),
3940 Type(Box<TyAlias>),
3942 MacCall(P<MacCall>),
3944 Delegation(Box<Delegation>),
3946 DelegationMac(Box<DelegationMac>),
3948}
3949
3950impl AssocItemKind {
3951 pub fn ident(&self) -> Option<Ident> {
3952 match *self {
3953 AssocItemKind::Const(box ConstItem { ident, .. })
3954 | AssocItemKind::Fn(box Fn { ident, .. })
3955 | AssocItemKind::Type(box TyAlias { ident, .. })
3956 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3957
3958 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3959 }
3960 }
3961
3962 pub fn defaultness(&self) -> Defaultness {
3963 match *self {
3964 Self::Const(box ConstItem { defaultness, .. })
3965 | Self::Fn(box Fn { defaultness, .. })
3966 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3967 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3968 Defaultness::Final
3969 }
3970 }
3971 }
3972}
3973
3974impl From<AssocItemKind> for ItemKind {
3975 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3976 match assoc_item_kind {
3977 AssocItemKind::Const(item) => ItemKind::Const(item),
3978 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3979 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3980 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3981 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3982 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3983 }
3984 }
3985}
3986
3987impl TryFrom<ItemKind> for AssocItemKind {
3988 type Error = ItemKind;
3989
3990 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3991 Ok(match item_kind {
3992 ItemKind::Const(item) => AssocItemKind::Const(item),
3993 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3994 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3995 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3996 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3997 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3998 _ => return Err(item_kind),
3999 })
4000 }
4001}
4002
4003#[derive(Clone, Encodable, Decodable, Debug)]
4005pub enum ForeignItemKind {
4006 Static(Box<StaticItem>),
4008 Fn(Box<Fn>),
4010 TyAlias(Box<TyAlias>),
4012 MacCall(P<MacCall>),
4014}
4015
4016impl ForeignItemKind {
4017 pub fn ident(&self) -> Option<Ident> {
4018 match *self {
4019 ForeignItemKind::Static(box StaticItem { ident, .. })
4020 | ForeignItemKind::Fn(box Fn { ident, .. })
4021 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4022
4023 ForeignItemKind::MacCall(_) => None,
4024 }
4025 }
4026}
4027
4028impl From<ForeignItemKind> for ItemKind {
4029 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4030 match foreign_item_kind {
4031 ForeignItemKind::Static(box static_foreign_item) => {
4032 ItemKind::Static(Box::new(static_foreign_item))
4033 }
4034 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4035 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4036 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4037 }
4038 }
4039}
4040
4041impl TryFrom<ItemKind> for ForeignItemKind {
4042 type Error = ItemKind;
4043
4044 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4045 Ok(match item_kind {
4046 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4047 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4048 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4049 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4050 _ => return Err(item_kind),
4051 })
4052 }
4053}
4054
4055pub type ForeignItem = Item<ForeignItemKind>;
4056
4057#[cfg(target_pointer_width = "64")]
4059mod size_asserts {
4060 use rustc_data_structures::static_assert_size;
4061
4062 use super::*;
4063 static_assert_size!(AssocItem, 80);
4065 static_assert_size!(AssocItemKind, 16);
4066 static_assert_size!(Attribute, 32);
4067 static_assert_size!(Block, 32);
4068 static_assert_size!(Expr, 72);
4069 static_assert_size!(ExprKind, 40);
4070 static_assert_size!(Fn, 184);
4071 static_assert_size!(ForeignItem, 80);
4072 static_assert_size!(ForeignItemKind, 16);
4073 static_assert_size!(GenericArg, 24);
4074 static_assert_size!(GenericBound, 88);
4075 static_assert_size!(Generics, 40);
4076 static_assert_size!(Impl, 136);
4077 static_assert_size!(Item, 144);
4078 static_assert_size!(ItemKind, 80);
4079 static_assert_size!(LitKind, 24);
4080 static_assert_size!(Local, 96);
4081 static_assert_size!(MetaItemLit, 40);
4082 static_assert_size!(Param, 40);
4083 static_assert_size!(Pat, 72);
4084 static_assert_size!(PatKind, 48);
4085 static_assert_size!(Path, 24);
4086 static_assert_size!(PathSegment, 24);
4087 static_assert_size!(Stmt, 32);
4088 static_assert_size!(StmtKind, 16);
4089 static_assert_size!(Ty, 64);
4090 static_assert_size!(TyKind, 40);
4091 }