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