1use std::borrow::Cow;
22use std::sync::Arc;
23use std::{cmp, fmt};
24
25pub use GenericArgs::*;
26pub use UnsafeSource::*;
27pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
28use rustc_data_structures::packed::Pu128;
29use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30use rustc_data_structures::stack::ensure_sufficient_stack;
31use rustc_data_structures::tagged_ptr::Tag;
32use rustc_macros::{Decodable, Encodable, HashStable_Generic};
33pub use rustc_span::AttrId;
34use rustc_span::source_map::{Spanned, respan};
35use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
36use thin_vec::{ThinVec, thin_vec};
37
38pub use crate::format::*;
39use crate::ptr::P;
40use crate::token::{self, CommentKind, Delimiter};
41use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42use crate::util::parser::{ExprPrecedence, Fixity};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
55pub struct Label {
56 pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "label({:?})", self.ident)
62 }
63}
64
65#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
68pub struct Lifetime {
69 pub id: NodeId,
70 pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "lifetime({}: {})", self.id, self)
76 }
77}
78
79impl fmt::Display for Lifetime {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}", self.ident.name)
82 }
83}
84
85#[derive(Clone, Encodable, Decodable, Debug)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
101 #[inline]
102 fn eq(&self, symbol: &Symbol) -> bool {
103 matches!(&self.segments[..], [segment] if segment.ident.name == *symbol)
104 }
105}
106
107impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
108 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
109 self.segments.len().hash_stable(hcx, hasher);
110 for segment in &self.segments {
111 segment.ident.hash_stable(hcx, hasher);
112 }
113 }
114}
115
116impl Path {
117 pub fn from_ident(ident: Ident) -> Path {
120 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
121 }
122
123 pub fn is_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
311use crate::AstDeref;
312pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
313
314#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
316pub struct TraitBoundModifiers {
317 pub constness: BoundConstness,
318 pub asyncness: BoundAsyncness,
319 pub polarity: BoundPolarity,
320}
321
322impl TraitBoundModifiers {
323 pub const NONE: Self = Self {
324 constness: BoundConstness::Never,
325 asyncness: BoundAsyncness::Normal,
326 polarity: BoundPolarity::Positive,
327 };
328}
329
330#[derive(Clone, Encodable, Decodable, Debug)]
331pub enum GenericBound {
332 Trait(PolyTraitRef),
333 Outlives(Lifetime),
334 Use(ThinVec<PreciseCapturingArg>, Span),
336}
337
338impl GenericBound {
339 pub fn span(&self) -> Span {
340 match self {
341 GenericBound::Trait(t, ..) => t.span,
342 GenericBound::Outlives(l) => l.ident.span,
343 GenericBound::Use(_, span) => *span,
344 }
345 }
346}
347
348pub type GenericBounds = Vec<GenericBound>;
349
350#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
354pub enum ParamKindOrd {
355 Lifetime,
356 TypeOrConst,
357}
358
359impl fmt::Display for ParamKindOrd {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 match self {
362 ParamKindOrd::Lifetime => "lifetime".fmt(f),
363 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
364 }
365 }
366}
367
368#[derive(Clone, Encodable, Decodable, Debug)]
369pub enum GenericParamKind {
370 Lifetime,
372 Type {
373 default: Option<P<Ty>>,
374 },
375 Const {
376 ty: P<Ty>,
377 kw_span: Span,
379 default: Option<AnonConst>,
381 },
382}
383
384#[derive(Clone, Encodable, Decodable, Debug)]
385pub struct GenericParam {
386 pub id: NodeId,
387 pub ident: Ident,
388 pub attrs: AttrVec,
389 pub bounds: GenericBounds,
390 pub is_placeholder: bool,
391 pub kind: GenericParamKind,
392 pub colon_span: Option<Span>,
393}
394
395impl GenericParam {
396 pub fn span(&self) -> Span {
397 match &self.kind {
398 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
399 self.ident.span
400 }
401 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
402 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
403 kw_span.to(default.value.span)
404 }
405 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
406 }
407 }
408}
409
410#[derive(Clone, Encodable, Decodable, Debug, Default)]
413pub struct Generics {
414 pub params: ThinVec<GenericParam>,
415 pub where_clause: WhereClause,
416 pub span: Span,
417}
418
419#[derive(Clone, Encodable, Decodable, Debug, Default)]
421pub struct WhereClause {
422 pub has_where_token: bool,
427 pub predicates: ThinVec<WherePredicate>,
428 pub span: Span,
429}
430
431impl WhereClause {
432 pub fn is_empty(&self) -> bool {
433 !self.has_where_token && self.predicates.is_empty()
434 }
435}
436
437#[derive(Clone, Encodable, Decodable, Debug)]
439pub struct WherePredicate {
440 pub attrs: AttrVec,
441 pub kind: WherePredicateKind,
442 pub id: NodeId,
443 pub span: Span,
444 pub is_placeholder: bool,
445}
446
447#[derive(Clone, Encodable, Decodable, Debug)]
449pub enum WherePredicateKind {
450 BoundPredicate(WhereBoundPredicate),
452 RegionPredicate(WhereRegionPredicate),
454 EqPredicate(WhereEqPredicate),
456}
457
458#[derive(Clone, Encodable, Decodable, Debug)]
462pub struct WhereBoundPredicate {
463 pub bound_generic_params: ThinVec<GenericParam>,
465 pub bounded_ty: P<Ty>,
467 pub bounds: GenericBounds,
469}
470
471#[derive(Clone, Encodable, Decodable, Debug)]
475pub struct WhereRegionPredicate {
476 pub lifetime: Lifetime,
477 pub bounds: GenericBounds,
478}
479
480#[derive(Clone, Encodable, Decodable, Debug)]
484pub struct WhereEqPredicate {
485 pub lhs_ty: P<Ty>,
486 pub rhs_ty: P<Ty>,
487}
488
489#[derive(Clone, Encodable, Decodable, Debug)]
490pub struct Crate {
491 pub attrs: AttrVec,
492 pub items: ThinVec<P<Item>>,
493 pub spans: ModSpans,
494 pub id: NodeId,
497 pub is_placeholder: bool,
498}
499
500#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
507pub struct MetaItem {
508 pub unsafety: Safety,
509 pub path: Path,
510 pub kind: MetaItemKind,
511 pub span: Span,
512}
513
514#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
516pub enum MetaItemKind {
517 Word,
521
522 List(ThinVec<MetaItemInner>),
526
527 NameValue(MetaItemLit),
531}
532
533#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
537pub enum MetaItemInner {
538 MetaItem(MetaItem),
540
541 Lit(MetaItemLit),
545}
546
547#[derive(Clone, Encodable, Decodable, Debug)]
551pub struct Block {
552 pub stmts: ThinVec<Stmt>,
554 pub id: NodeId,
555 pub rules: BlockCheckMode,
557 pub span: Span,
558 pub tokens: Option<LazyAttrTokenStream>,
559}
560
561#[derive(Clone, Encodable, Decodable, Debug)]
565pub struct Pat {
566 pub id: NodeId,
567 pub kind: PatKind,
568 pub span: Span,
569 pub tokens: Option<LazyAttrTokenStream>,
570}
571
572impl Pat {
573 pub fn to_ty(&self) -> Option<P<Ty>> {
576 let kind = match &self.kind {
577 PatKind::Missing => unreachable!(),
578 PatKind::Wild => TyKind::Infer,
580 PatKind::Ident(BindingMode::NONE, ident, None) => {
582 TyKind::Path(None, Path::from_ident(*ident))
583 }
584 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
585 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
586 PatKind::Ref(pat, mutbl) => {
588 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
589 }
590 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
593 pat.to_ty().map(TyKind::Slice)?
594 }
595 PatKind::Tuple(pats) => {
598 let mut tys = ThinVec::with_capacity(pats.len());
599 for pat in pats {
601 tys.push(pat.to_ty()?);
602 }
603 TyKind::Tup(tys)
604 }
605 _ => return None,
606 };
607
608 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
609 }
610
611 pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
615 if !it(self) {
616 return;
617 }
618
619 match &self.kind {
620 PatKind::Ident(_, _, Some(p)) => p.walk(it),
622
623 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
625
626 PatKind::TupleStruct(_, _, s)
628 | PatKind::Tuple(s)
629 | PatKind::Slice(s)
630 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
631
632 PatKind::Box(s)
634 | PatKind::Deref(s)
635 | PatKind::Ref(s, _)
636 | PatKind::Paren(s)
637 | PatKind::Guard(s, _) => s.walk(it),
638
639 PatKind::Missing
641 | PatKind::Wild
642 | PatKind::Rest
643 | PatKind::Never
644 | PatKind::Expr(_)
645 | PatKind::Range(..)
646 | PatKind::Ident(..)
647 | PatKind::Path(..)
648 | PatKind::MacCall(_)
649 | PatKind::Err(_) => {}
650 }
651 }
652
653 pub fn is_rest(&self) -> bool {
655 matches!(self.kind, PatKind::Rest)
656 }
657
658 pub fn could_be_never_pattern(&self) -> bool {
661 let mut could_be_never_pattern = false;
662 self.walk(&mut |pat| match &pat.kind {
663 PatKind::Never | PatKind::MacCall(_) => {
664 could_be_never_pattern = true;
665 false
666 }
667 PatKind::Or(s) => {
668 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
669 false
670 }
671 _ => true,
672 });
673 could_be_never_pattern
674 }
675
676 pub fn contains_never_pattern(&self) -> bool {
679 let mut contains_never_pattern = false;
680 self.walk(&mut |pat| {
681 if matches!(pat.kind, PatKind::Never) {
682 contains_never_pattern = true;
683 }
684 true
685 });
686 contains_never_pattern
687 }
688
689 pub fn descr(&self) -> Option<String> {
691 match &self.kind {
692 PatKind::Missing => unreachable!(),
693 PatKind::Wild => Some("_".to_string()),
694 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
695 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
696 _ => None,
697 }
698 }
699}
700
701#[derive(Clone, Encodable, Decodable, Debug)]
707pub struct PatField {
708 pub ident: Ident,
710 pub pat: P<Pat>,
712 pub is_shorthand: bool,
713 pub attrs: AttrVec,
714 pub id: NodeId,
715 pub span: Span,
716 pub is_placeholder: bool,
717}
718
719#[derive(Clone, Copy, Debug, Eq, PartialEq)]
720#[derive(Encodable, Decodable, HashStable_Generic)]
721pub enum ByRef {
722 Yes(Mutability),
723 No,
724}
725
726impl ByRef {
727 #[must_use]
728 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
729 if let ByRef::Yes(old_mutbl) = &mut self {
730 *old_mutbl = cmp::min(*old_mutbl, mutbl);
731 }
732 self
733 }
734}
735
736#[derive(Clone, Copy, Debug, Eq, PartialEq)]
742#[derive(Encodable, Decodable, HashStable_Generic)]
743pub struct BindingMode(pub ByRef, pub Mutability);
744
745impl BindingMode {
746 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
747 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
748 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
749 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
750 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
751 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
752
753 pub fn prefix_str(self) -> &'static str {
754 match self {
755 Self::NONE => "",
756 Self::REF => "ref ",
757 Self::MUT => "mut ",
758 Self::REF_MUT => "ref mut ",
759 Self::MUT_REF => "mut ref ",
760 Self::MUT_REF_MUT => "mut ref mut ",
761 }
762 }
763}
764
765#[derive(Clone, Encodable, Decodable, Debug)]
766pub enum RangeEnd {
767 Included(RangeSyntax),
769 Excluded,
771}
772
773#[derive(Clone, Encodable, Decodable, Debug)]
774pub enum RangeSyntax {
775 DotDotDot,
777 DotDotEq,
779}
780
781#[derive(Clone, Encodable, Decodable, Debug)]
785pub enum PatKind {
786 Missing,
788
789 Wild,
791
792 Ident(BindingMode, Ident, Option<P<Pat>>),
797
798 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
800
801 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
803
804 Or(ThinVec<P<Pat>>),
807
808 Path(Option<P<QSelf>>, Path),
813
814 Tuple(ThinVec<P<Pat>>),
816
817 Box(P<Pat>),
819
820 Deref(P<Pat>),
822
823 Ref(P<Pat>, Mutability),
825
826 Expr(P<Expr>),
828
829 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
831
832 Slice(ThinVec<P<Pat>>),
834
835 Rest,
848
849 Never,
851
852 Guard(P<Pat>, P<Expr>),
854
855 Paren(P<Pat>),
857
858 MacCall(P<MacCall>),
860
861 Err(ErrorGuaranteed),
863}
864
865#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
867pub enum PatFieldsRest {
868 Rest,
870 Recovered(ErrorGuaranteed),
872 None,
874}
875
876#[derive(Clone, Copy, PartialEq, Eq, Debug)]
879#[derive(Encodable, Decodable, HashStable_Generic)]
880pub enum BorrowKind {
881 Ref,
885 Raw,
889}
890
891#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
892pub enum BinOpKind {
893 Add,
895 Sub,
897 Mul,
899 Div,
901 Rem,
903 And,
905 Or,
907 BitXor,
909 BitAnd,
911 BitOr,
913 Shl,
915 Shr,
917 Eq,
919 Lt,
921 Le,
923 Ne,
925 Ge,
927 Gt,
929}
930
931impl BinOpKind {
932 pub fn as_str(&self) -> &'static str {
933 use BinOpKind::*;
934 match self {
935 Add => "+",
936 Sub => "-",
937 Mul => "*",
938 Div => "/",
939 Rem => "%",
940 And => "&&",
941 Or => "||",
942 BitXor => "^",
943 BitAnd => "&",
944 BitOr => "|",
945 Shl => "<<",
946 Shr => ">>",
947 Eq => "==",
948 Lt => "<",
949 Le => "<=",
950 Ne => "!=",
951 Ge => ">=",
952 Gt => ">",
953 }
954 }
955
956 pub fn is_lazy(&self) -> bool {
957 matches!(self, BinOpKind::And | BinOpKind::Or)
958 }
959
960 pub fn precedence(&self) -> ExprPrecedence {
961 use BinOpKind::*;
962 match *self {
963 Mul | Div | Rem => ExprPrecedence::Product,
964 Add | Sub => ExprPrecedence::Sum,
965 Shl | Shr => ExprPrecedence::Shift,
966 BitAnd => ExprPrecedence::BitAnd,
967 BitXor => ExprPrecedence::BitXor,
968 BitOr => ExprPrecedence::BitOr,
969 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
970 And => ExprPrecedence::LAnd,
971 Or => ExprPrecedence::LOr,
972 }
973 }
974
975 pub fn fixity(&self) -> Fixity {
976 use BinOpKind::*;
977 match self {
978 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
979 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
980 Fixity::Left
981 }
982 }
983 }
984
985 pub fn is_comparison(self) -> bool {
986 use BinOpKind::*;
987 match self {
988 Eq | Ne | Lt | Le | Gt | Ge => true,
989 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
990 }
991 }
992
993 pub fn is_by_value(self) -> bool {
995 !self.is_comparison()
996 }
997}
998
999pub type BinOp = Spanned<BinOpKind>;
1000
1001impl From<AssignOpKind> for BinOpKind {
1005 fn from(op: AssignOpKind) -> BinOpKind {
1006 match op {
1007 AssignOpKind::AddAssign => BinOpKind::Add,
1008 AssignOpKind::SubAssign => BinOpKind::Sub,
1009 AssignOpKind::MulAssign => BinOpKind::Mul,
1010 AssignOpKind::DivAssign => BinOpKind::Div,
1011 AssignOpKind::RemAssign => BinOpKind::Rem,
1012 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1013 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1014 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1015 AssignOpKind::ShlAssign => BinOpKind::Shl,
1016 AssignOpKind::ShrAssign => BinOpKind::Shr,
1017 }
1018 }
1019}
1020
1021#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1022pub enum AssignOpKind {
1023 AddAssign,
1025 SubAssign,
1027 MulAssign,
1029 DivAssign,
1031 RemAssign,
1033 BitXorAssign,
1035 BitAndAssign,
1037 BitOrAssign,
1039 ShlAssign,
1041 ShrAssign,
1043}
1044
1045impl AssignOpKind {
1046 pub fn as_str(&self) -> &'static str {
1047 use AssignOpKind::*;
1048 match self {
1049 AddAssign => "+=",
1050 SubAssign => "-=",
1051 MulAssign => "*=",
1052 DivAssign => "/=",
1053 RemAssign => "%=",
1054 BitXorAssign => "^=",
1055 BitAndAssign => "&=",
1056 BitOrAssign => "|=",
1057 ShlAssign => "<<=",
1058 ShrAssign => ">>=",
1059 }
1060 }
1061
1062 pub fn is_by_value(self) -> bool {
1064 true
1065 }
1066}
1067
1068pub type AssignOp = Spanned<AssignOpKind>;
1069
1070#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1074pub enum UnOp {
1075 Deref,
1077 Not,
1079 Neg,
1081}
1082
1083impl UnOp {
1084 pub fn as_str(&self) -> &'static str {
1085 match self {
1086 UnOp::Deref => "*",
1087 UnOp::Not => "!",
1088 UnOp::Neg => "-",
1089 }
1090 }
1091
1092 pub fn is_by_value(self) -> bool {
1094 matches!(self, Self::Neg | Self::Not)
1095 }
1096}
1097
1098#[derive(Clone, Encodable, Decodable, Debug)]
1102pub struct Stmt {
1103 pub id: NodeId,
1104 pub kind: StmtKind,
1105 pub span: Span,
1106}
1107
1108impl Stmt {
1109 pub fn has_trailing_semicolon(&self) -> bool {
1110 match &self.kind {
1111 StmtKind::Semi(_) => true,
1112 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1113 _ => false,
1114 }
1115 }
1116
1117 pub fn add_trailing_semicolon(mut self) -> Self {
1125 self.kind = match self.kind {
1126 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1127 StmtKind::MacCall(mac) => {
1128 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1129 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1130 }))
1131 }
1132 kind => kind,
1133 };
1134
1135 self
1136 }
1137
1138 pub fn is_item(&self) -> bool {
1139 matches!(self.kind, StmtKind::Item(_))
1140 }
1141
1142 pub fn is_expr(&self) -> bool {
1143 matches!(self.kind, StmtKind::Expr(_))
1144 }
1145}
1146
1147#[derive(Clone, Encodable, Decodable, Debug)]
1149pub enum StmtKind {
1150 Let(P<Local>),
1152 Item(P<Item>),
1154 Expr(P<Expr>),
1156 Semi(P<Expr>),
1158 Empty,
1160 MacCall(P<MacCallStmt>),
1162}
1163
1164#[derive(Clone, Encodable, Decodable, Debug)]
1165pub struct MacCallStmt {
1166 pub mac: P<MacCall>,
1167 pub style: MacStmtStyle,
1168 pub attrs: AttrVec,
1169 pub tokens: Option<LazyAttrTokenStream>,
1170}
1171
1172#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1173pub enum MacStmtStyle {
1174 Semicolon,
1177 Braces,
1179 NoBraces,
1183}
1184
1185#[derive(Clone, Encodable, Decodable, Debug)]
1187pub struct Local {
1188 pub id: NodeId,
1189 pub super_: Option<Span>,
1190 pub pat: P<Pat>,
1191 pub ty: Option<P<Ty>>,
1192 pub kind: LocalKind,
1193 pub span: Span,
1194 pub colon_sp: Option<Span>,
1195 pub attrs: AttrVec,
1196 pub tokens: Option<LazyAttrTokenStream>,
1197}
1198
1199#[derive(Clone, Encodable, Decodable, Debug)]
1200pub enum LocalKind {
1201 Decl,
1204 Init(P<Expr>),
1207 InitElse(P<Expr>, P<Block>),
1210}
1211
1212impl LocalKind {
1213 pub fn init(&self) -> Option<&Expr> {
1214 match self {
1215 Self::Decl => None,
1216 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1217 }
1218 }
1219
1220 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1221 match self {
1222 Self::Decl => None,
1223 Self::Init(init) => Some((init, None)),
1224 Self::InitElse(init, els) => Some((init, Some(els))),
1225 }
1226 }
1227}
1228
1229#[derive(Clone, Encodable, Decodable, Debug)]
1240pub struct Arm {
1241 pub attrs: AttrVec,
1242 pub pat: P<Pat>,
1244 pub guard: Option<P<Expr>>,
1246 pub body: Option<P<Expr>>,
1248 pub span: Span,
1249 pub id: NodeId,
1250 pub is_placeholder: bool,
1251}
1252
1253#[derive(Clone, Encodable, Decodable, Debug)]
1255pub struct ExprField {
1256 pub attrs: AttrVec,
1257 pub id: NodeId,
1258 pub span: Span,
1259 pub ident: Ident,
1260 pub expr: P<Expr>,
1261 pub is_shorthand: bool,
1262 pub is_placeholder: bool,
1263}
1264
1265#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1266pub enum BlockCheckMode {
1267 Default,
1268 Unsafe(UnsafeSource),
1269}
1270
1271#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1272pub enum UnsafeSource {
1273 CompilerGenerated,
1274 UserProvided,
1275}
1276
1277#[derive(Clone, Encodable, Decodable, Debug)]
1283pub struct AnonConst {
1284 pub id: NodeId,
1285 pub value: P<Expr>,
1286}
1287
1288#[derive(Clone, Encodable, Decodable, Debug)]
1290pub struct Expr {
1291 pub id: NodeId,
1292 pub kind: ExprKind,
1293 pub span: Span,
1294 pub attrs: AttrVec,
1295 pub tokens: Option<LazyAttrTokenStream>,
1296}
1297
1298impl Expr {
1299 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1313 let this = self.maybe_unwrap_block();
1314 if allow_mgca_arg {
1315 matches!(this.kind, ExprKind::Path(..))
1316 } else {
1317 if let ExprKind::Path(None, path) = &this.kind
1318 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1319 {
1320 true
1321 } else {
1322 false
1323 }
1324 }
1325 }
1326
1327 pub fn maybe_unwrap_block(&self) -> &Expr {
1329 if let ExprKind::Block(block, None) = &self.kind
1330 && let [stmt] = block.stmts.as_slice()
1331 && let StmtKind::Expr(expr) = &stmt.kind
1332 {
1333 expr
1334 } else {
1335 self
1336 }
1337 }
1338
1339 pub fn optionally_braced_mac_call(
1345 &self,
1346 already_stripped_block: bool,
1347 ) -> Option<(bool, NodeId)> {
1348 match &self.kind {
1349 ExprKind::Block(block, None)
1350 if let [stmt] = &*block.stmts
1351 && !already_stripped_block =>
1352 {
1353 match &stmt.kind {
1354 StmtKind::MacCall(_) => Some((true, stmt.id)),
1355 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1356 Some((true, expr.id))
1357 }
1358 _ => None,
1359 }
1360 }
1361 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1362 _ => None,
1363 }
1364 }
1365
1366 pub fn to_bound(&self) -> Option<GenericBound> {
1367 match &self.kind {
1368 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1369 ThinVec::new(),
1370 path.clone(),
1371 TraitBoundModifiers::NONE,
1372 self.span,
1373 ))),
1374 _ => None,
1375 }
1376 }
1377
1378 pub fn peel_parens(&self) -> &Expr {
1379 let mut expr = self;
1380 while let ExprKind::Paren(inner) = &expr.kind {
1381 expr = inner;
1382 }
1383 expr
1384 }
1385
1386 pub fn peel_parens_and_refs(&self) -> &Expr {
1387 let mut expr = self;
1388 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1389 {
1390 expr = inner;
1391 }
1392 expr
1393 }
1394
1395 pub fn to_ty(&self) -> Option<P<Ty>> {
1397 let kind = match &self.kind {
1398 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1400 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1401
1402 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1403
1404 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1405 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1406 }
1407
1408 ExprKind::Repeat(expr, expr_len) => {
1409 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1410 }
1411
1412 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1413 expr.to_ty().map(TyKind::Slice)?
1414 }
1415
1416 ExprKind::Tup(exprs) => {
1417 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1418 TyKind::Tup(tys)
1419 }
1420
1421 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1425 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1426 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1427 } else {
1428 return None;
1429 }
1430 }
1431
1432 ExprKind::Underscore => TyKind::Infer,
1433
1434 _ => return None,
1436 };
1437
1438 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1439 }
1440
1441 pub fn precedence(&self) -> ExprPrecedence {
1442 match &self.kind {
1443 ExprKind::Closure(closure) => {
1444 match closure.fn_decl.output {
1445 FnRetTy::Default(_) => ExprPrecedence::Jump,
1446 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1447 }
1448 }
1449
1450 ExprKind::Break(..)
1451 | ExprKind::Ret(..)
1452 | ExprKind::Yield(..)
1453 | ExprKind::Yeet(..)
1454 | ExprKind::Become(..) => ExprPrecedence::Jump,
1455
1456 ExprKind::Range(..) => ExprPrecedence::Range,
1461
1462 ExprKind::Binary(op, ..) => op.node.precedence(),
1464 ExprKind::Cast(..) => ExprPrecedence::Cast,
1465
1466 ExprKind::Assign(..) |
1467 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1468
1469 ExprKind::AddrOf(..)
1471 | ExprKind::Let(..)
1476 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1477
1478 ExprKind::Array(_)
1480 | ExprKind::Await(..)
1481 | ExprKind::Use(..)
1482 | ExprKind::Block(..)
1483 | ExprKind::Call(..)
1484 | ExprKind::ConstBlock(_)
1485 | ExprKind::Continue(..)
1486 | ExprKind::Field(..)
1487 | ExprKind::ForLoop { .. }
1488 | ExprKind::FormatArgs(..)
1489 | ExprKind::Gen(..)
1490 | ExprKind::If(..)
1491 | ExprKind::IncludedBytes(..)
1492 | ExprKind::Index(..)
1493 | ExprKind::InlineAsm(..)
1494 | ExprKind::Lit(_)
1495 | ExprKind::Loop(..)
1496 | ExprKind::MacCall(..)
1497 | ExprKind::Match(..)
1498 | ExprKind::MethodCall(..)
1499 | ExprKind::OffsetOf(..)
1500 | ExprKind::Paren(..)
1501 | ExprKind::Path(..)
1502 | ExprKind::Repeat(..)
1503 | ExprKind::Struct(..)
1504 | ExprKind::Try(..)
1505 | ExprKind::TryBlock(..)
1506 | ExprKind::Tup(_)
1507 | ExprKind::Type(..)
1508 | ExprKind::Underscore
1509 | ExprKind::UnsafeBinderCast(..)
1510 | ExprKind::While(..)
1511 | ExprKind::Err(_)
1512 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1513 }
1514 }
1515
1516 pub fn is_approximately_pattern(&self) -> bool {
1518 matches!(
1519 &self.peel_parens().kind,
1520 ExprKind::Array(_)
1521 | ExprKind::Call(_, _)
1522 | ExprKind::Tup(_)
1523 | ExprKind::Lit(_)
1524 | ExprKind::Range(_, _, _)
1525 | ExprKind::Underscore
1526 | ExprKind::Path(_, _)
1527 | ExprKind::Struct(_)
1528 )
1529 }
1530}
1531
1532#[derive(Clone, Encodable, Decodable, Debug)]
1533pub struct Closure {
1534 pub binder: ClosureBinder,
1535 pub capture_clause: CaptureBy,
1536 pub constness: Const,
1537 pub coroutine_kind: Option<CoroutineKind>,
1538 pub movability: Movability,
1539 pub fn_decl: P<FnDecl>,
1540 pub body: P<Expr>,
1541 pub fn_decl_span: Span,
1543 pub fn_arg_span: Span,
1545}
1546
1547#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1549pub enum RangeLimits {
1550 HalfOpen,
1552 Closed,
1554}
1555
1556impl RangeLimits {
1557 pub fn as_str(&self) -> &'static str {
1558 match self {
1559 RangeLimits::HalfOpen => "..",
1560 RangeLimits::Closed => "..=",
1561 }
1562 }
1563}
1564
1565#[derive(Clone, Encodable, Decodable, Debug)]
1567pub struct MethodCall {
1568 pub seg: PathSegment,
1570 pub receiver: P<Expr>,
1572 pub args: ThinVec<P<Expr>>,
1574 pub span: Span,
1577}
1578
1579#[derive(Clone, Encodable, Decodable, Debug)]
1580pub enum StructRest {
1581 Base(P<Expr>),
1583 Rest(Span),
1585 None,
1587}
1588
1589#[derive(Clone, Encodable, Decodable, Debug)]
1590pub struct StructExpr {
1591 pub qself: Option<P<QSelf>>,
1592 pub path: Path,
1593 pub fields: ThinVec<ExprField>,
1594 pub rest: StructRest,
1595}
1596
1597#[derive(Clone, Encodable, Decodable, Debug)]
1599pub enum ExprKind {
1600 Array(ThinVec<P<Expr>>),
1602 ConstBlock(AnonConst),
1604 Call(P<Expr>, ThinVec<P<Expr>>),
1611 MethodCall(Box<MethodCall>),
1613 Tup(ThinVec<P<Expr>>),
1615 Binary(BinOp, P<Expr>, P<Expr>),
1617 Unary(UnOp, P<Expr>),
1619 Lit(token::Lit),
1621 Cast(P<Expr>, P<Ty>),
1623 Type(P<Expr>, P<Ty>),
1628 Let(P<Pat>, P<Expr>, Span, Recovered),
1633 If(P<Expr>, P<Block>, Option<P<Expr>>),
1640 While(P<Expr>, P<Block>, Option<Label>),
1644 ForLoop {
1650 pat: P<Pat>,
1651 iter: P<Expr>,
1652 body: P<Block>,
1653 label: Option<Label>,
1654 kind: ForLoopKind,
1655 },
1656 Loop(P<Block>, Option<Label>, Span),
1660 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1662 Closure(Box<Closure>),
1664 Block(P<Block>, Option<Label>),
1666 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1672 Await(P<Expr>, Span),
1674 Use(P<Expr>, Span),
1676
1677 TryBlock(P<Block>),
1679
1680 Assign(P<Expr>, P<Expr>, Span),
1683 AssignOp(AssignOp, P<Expr>, P<Expr>),
1687 Field(P<Expr>, Ident),
1689 Index(P<Expr>, P<Expr>, Span),
1692 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1694 Underscore,
1696
1697 Path(Option<P<QSelf>>, Path),
1702
1703 AddrOf(BorrowKind, Mutability, P<Expr>),
1705 Break(Option<Label>, Option<P<Expr>>),
1707 Continue(Option<Label>),
1709 Ret(Option<P<Expr>>),
1711
1712 InlineAsm(P<InlineAsm>),
1714
1715 OffsetOf(P<Ty>, P<[Ident]>),
1720
1721 MacCall(P<MacCall>),
1723
1724 Struct(P<StructExpr>),
1728
1729 Repeat(P<Expr>, AnonConst),
1734
1735 Paren(P<Expr>),
1737
1738 Try(P<Expr>),
1740
1741 Yield(YieldKind),
1743
1744 Yeet(Option<P<Expr>>),
1747
1748 Become(P<Expr>),
1752
1753 IncludedBytes(Arc<[u8]>),
1758
1759 FormatArgs(P<FormatArgs>),
1761
1762 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1763
1764 Err(ErrorGuaranteed),
1766
1767 Dummy,
1769}
1770
1771#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1773pub enum ForLoopKind {
1774 For,
1775 ForAwait,
1776}
1777
1778#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1780pub enum GenBlockKind {
1781 Async,
1782 Gen,
1783 AsyncGen,
1784}
1785
1786impl fmt::Display for GenBlockKind {
1787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1788 self.modifier().fmt(f)
1789 }
1790}
1791
1792impl GenBlockKind {
1793 pub fn modifier(&self) -> &'static str {
1794 match self {
1795 GenBlockKind::Async => "async",
1796 GenBlockKind::Gen => "gen",
1797 GenBlockKind::AsyncGen => "async gen",
1798 }
1799 }
1800}
1801
1802#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1804#[derive(Encodable, Decodable, HashStable_Generic)]
1805pub enum UnsafeBinderCastKind {
1806 Wrap,
1808 Unwrap,
1810}
1811
1812#[derive(Clone, Encodable, Decodable, Debug)]
1827pub struct QSelf {
1828 pub ty: P<Ty>,
1829
1830 pub path_span: Span,
1834 pub position: usize,
1835}
1836
1837#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1839pub enum CaptureBy {
1840 Value {
1842 move_kw: Span,
1844 },
1845 Ref,
1847 Use {
1853 use_kw: Span,
1855 },
1856}
1857
1858#[derive(Clone, Encodable, Decodable, Debug)]
1860pub enum ClosureBinder {
1861 NotPresent,
1863 For {
1865 span: Span,
1872
1873 generic_params: ThinVec<GenericParam>,
1880 },
1881}
1882
1883#[derive(Clone, Encodable, Decodable, Debug)]
1886pub struct MacCall {
1887 pub path: Path,
1888 pub args: P<DelimArgs>,
1889}
1890
1891impl MacCall {
1892 pub fn span(&self) -> Span {
1893 self.path.span.to(self.args.dspan.entire())
1894 }
1895}
1896
1897#[derive(Clone, Encodable, Decodable, Debug)]
1899pub enum AttrArgs {
1900 Empty,
1902 Delimited(DelimArgs),
1904 Eq {
1906 eq_span: Span,
1908 expr: P<Expr>,
1909 },
1910}
1911
1912impl AttrArgs {
1913 pub fn span(&self) -> Option<Span> {
1914 match self {
1915 AttrArgs::Empty => None,
1916 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1917 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1918 }
1919 }
1920
1921 pub fn inner_tokens(&self) -> TokenStream {
1924 match self {
1925 AttrArgs::Empty => TokenStream::default(),
1926 AttrArgs::Delimited(args) => args.tokens.clone(),
1927 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1928 }
1929 }
1930}
1931
1932#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1934pub struct DelimArgs {
1935 pub dspan: DelimSpan,
1936 pub delim: Delimiter, pub tokens: TokenStream,
1938}
1939
1940impl DelimArgs {
1941 pub fn need_semicolon(&self) -> bool {
1944 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1945 }
1946}
1947
1948#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1950pub struct MacroDef {
1951 pub body: P<DelimArgs>,
1952 pub macro_rules: bool,
1954}
1955
1956#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1957#[derive(HashStable_Generic)]
1958pub enum StrStyle {
1959 Cooked,
1961 Raw(u8),
1965}
1966
1967#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1969pub enum MatchKind {
1970 Prefix,
1972 Postfix,
1974}
1975
1976#[derive(Clone, Encodable, Decodable, Debug)]
1978pub enum YieldKind {
1979 Prefix(Option<P<Expr>>),
1981 Postfix(P<Expr>),
1983}
1984
1985impl YieldKind {
1986 pub const fn expr(&self) -> Option<&P<Expr>> {
1990 match self {
1991 YieldKind::Prefix(expr) => expr.as_ref(),
1992 YieldKind::Postfix(expr) => Some(expr),
1993 }
1994 }
1995
1996 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1998 match self {
1999 YieldKind::Prefix(expr) => expr.as_mut(),
2000 YieldKind::Postfix(expr) => Some(expr),
2001 }
2002 }
2003
2004 pub const fn same_kind(&self, other: &Self) -> bool {
2006 match (self, other) {
2007 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2008 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2009 _ => false,
2010 }
2011 }
2012}
2013
2014#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2016pub struct MetaItemLit {
2017 pub symbol: Symbol,
2019 pub suffix: Option<Symbol>,
2021 pub kind: LitKind,
2024 pub span: Span,
2025}
2026
2027#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2029pub struct StrLit {
2030 pub symbol: Symbol,
2032 pub suffix: Option<Symbol>,
2034 pub symbol_unescaped: Symbol,
2036 pub style: StrStyle,
2037 pub span: Span,
2038}
2039
2040impl StrLit {
2041 pub fn as_token_lit(&self) -> token::Lit {
2042 let token_kind = match self.style {
2043 StrStyle::Cooked => token::Str,
2044 StrStyle::Raw(n) => token::StrRaw(n),
2045 };
2046 token::Lit::new(token_kind, self.symbol, self.suffix)
2047 }
2048}
2049
2050#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2052#[derive(HashStable_Generic)]
2053pub enum LitIntType {
2054 Signed(IntTy),
2056 Unsigned(UintTy),
2058 Unsuffixed,
2060}
2061
2062#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2064#[derive(HashStable_Generic)]
2065pub enum LitFloatType {
2066 Suffixed(FloatTy),
2068 Unsuffixed,
2070}
2071
2072#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2079pub enum LitKind {
2080 Str(Symbol, StrStyle),
2083 ByteStr(Arc<[u8]>, StrStyle),
2086 CStr(Arc<[u8]>, StrStyle),
2088 Byte(u8),
2090 Char(char),
2092 Int(Pu128, LitIntType),
2094 Float(Symbol, LitFloatType),
2098 Bool(bool),
2100 Err(ErrorGuaranteed),
2102}
2103
2104impl LitKind {
2105 pub fn str(&self) -> Option<Symbol> {
2106 match *self {
2107 LitKind::Str(s, _) => Some(s),
2108 _ => None,
2109 }
2110 }
2111
2112 pub fn is_str(&self) -> bool {
2114 matches!(self, LitKind::Str(..))
2115 }
2116
2117 pub fn is_bytestr(&self) -> bool {
2119 matches!(self, LitKind::ByteStr(..))
2120 }
2121
2122 pub fn is_numeric(&self) -> bool {
2124 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2125 }
2126
2127 pub fn is_unsuffixed(&self) -> bool {
2130 !self.is_suffixed()
2131 }
2132
2133 pub fn is_suffixed(&self) -> bool {
2135 match *self {
2136 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2138 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2139 LitKind::Str(..)
2141 | LitKind::ByteStr(..)
2142 | LitKind::CStr(..)
2143 | LitKind::Byte(..)
2144 | LitKind::Char(..)
2145 | LitKind::Int(_, LitIntType::Unsuffixed)
2146 | LitKind::Float(_, LitFloatType::Unsuffixed)
2147 | LitKind::Bool(..)
2148 | LitKind::Err(_) => false,
2149 }
2150 }
2151}
2152
2153#[derive(Clone, Encodable, Decodable, Debug)]
2156pub struct MutTy {
2157 pub ty: P<Ty>,
2158 pub mutbl: Mutability,
2159}
2160
2161#[derive(Clone, Encodable, Decodable, Debug)]
2164pub struct FnSig {
2165 pub header: FnHeader,
2166 pub decl: P<FnDecl>,
2167 pub span: Span,
2168}
2169
2170#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2171#[derive(Encodable, Decodable, HashStable_Generic)]
2172pub enum FloatTy {
2173 F16,
2174 F32,
2175 F64,
2176 F128,
2177}
2178
2179impl FloatTy {
2180 pub fn name_str(self) -> &'static str {
2181 match self {
2182 FloatTy::F16 => "f16",
2183 FloatTy::F32 => "f32",
2184 FloatTy::F64 => "f64",
2185 FloatTy::F128 => "f128",
2186 }
2187 }
2188
2189 pub fn name(self) -> Symbol {
2190 match self {
2191 FloatTy::F16 => sym::f16,
2192 FloatTy::F32 => sym::f32,
2193 FloatTy::F64 => sym::f64,
2194 FloatTy::F128 => sym::f128,
2195 }
2196 }
2197}
2198
2199#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2200#[derive(Encodable, Decodable, HashStable_Generic)]
2201pub enum IntTy {
2202 Isize,
2203 I8,
2204 I16,
2205 I32,
2206 I64,
2207 I128,
2208}
2209
2210impl IntTy {
2211 pub fn name_str(&self) -> &'static str {
2212 match *self {
2213 IntTy::Isize => "isize",
2214 IntTy::I8 => "i8",
2215 IntTy::I16 => "i16",
2216 IntTy::I32 => "i32",
2217 IntTy::I64 => "i64",
2218 IntTy::I128 => "i128",
2219 }
2220 }
2221
2222 pub fn name(&self) -> Symbol {
2223 match *self {
2224 IntTy::Isize => sym::isize,
2225 IntTy::I8 => sym::i8,
2226 IntTy::I16 => sym::i16,
2227 IntTy::I32 => sym::i32,
2228 IntTy::I64 => sym::i64,
2229 IntTy::I128 => sym::i128,
2230 }
2231 }
2232}
2233
2234#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2235#[derive(Encodable, Decodable, HashStable_Generic)]
2236pub enum UintTy {
2237 Usize,
2238 U8,
2239 U16,
2240 U32,
2241 U64,
2242 U128,
2243}
2244
2245impl UintTy {
2246 pub fn name_str(&self) -> &'static str {
2247 match *self {
2248 UintTy::Usize => "usize",
2249 UintTy::U8 => "u8",
2250 UintTy::U16 => "u16",
2251 UintTy::U32 => "u32",
2252 UintTy::U64 => "u64",
2253 UintTy::U128 => "u128",
2254 }
2255 }
2256
2257 pub fn name(&self) -> Symbol {
2258 match *self {
2259 UintTy::Usize => sym::usize,
2260 UintTy::U8 => sym::u8,
2261 UintTy::U16 => sym::u16,
2262 UintTy::U32 => sym::u32,
2263 UintTy::U64 => sym::u64,
2264 UintTy::U128 => sym::u128,
2265 }
2266 }
2267}
2268
2269#[derive(Clone, Encodable, Decodable, Debug)]
2280pub struct AssocItemConstraint {
2281 pub id: NodeId,
2282 pub ident: Ident,
2283 pub gen_args: Option<GenericArgs>,
2284 pub kind: AssocItemConstraintKind,
2285 pub span: Span,
2286}
2287
2288#[derive(Clone, Encodable, Decodable, Debug)]
2289pub enum Term {
2290 Ty(P<Ty>),
2291 Const(AnonConst),
2292}
2293
2294impl From<P<Ty>> for Term {
2295 fn from(v: P<Ty>) -> Self {
2296 Term::Ty(v)
2297 }
2298}
2299
2300impl From<AnonConst> for Term {
2301 fn from(v: AnonConst) -> Self {
2302 Term::Const(v)
2303 }
2304}
2305
2306#[derive(Clone, Encodable, Decodable, Debug)]
2308pub enum AssocItemConstraintKind {
2309 Equality { term: Term },
2316 Bound { bounds: GenericBounds },
2318}
2319
2320#[derive(Encodable, Decodable, Debug)]
2321pub struct Ty {
2322 pub id: NodeId,
2323 pub kind: TyKind,
2324 pub span: Span,
2325 pub tokens: Option<LazyAttrTokenStream>,
2326}
2327
2328impl Clone for Ty {
2329 fn clone(&self) -> Self {
2330 ensure_sufficient_stack(|| Self {
2331 id: self.id,
2332 kind: self.kind.clone(),
2333 span: self.span,
2334 tokens: self.tokens.clone(),
2335 })
2336 }
2337}
2338
2339impl Ty {
2340 pub fn peel_refs(&self) -> &Self {
2341 let mut final_ty = self;
2342 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2343 {
2344 final_ty = ty;
2345 }
2346 final_ty
2347 }
2348
2349 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2350 match &self.kind {
2351 TyKind::Infer => true,
2352 TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
2353 _ => false,
2354 }
2355 }
2356}
2357
2358#[derive(Clone, Encodable, Decodable, Debug)]
2359pub struct BareFnTy {
2360 pub safety: Safety,
2361 pub ext: Extern,
2362 pub generic_params: ThinVec<GenericParam>,
2363 pub decl: P<FnDecl>,
2364 pub decl_span: Span,
2367}
2368
2369#[derive(Clone, Encodable, Decodable, Debug)]
2370pub struct UnsafeBinderTy {
2371 pub generic_params: ThinVec<GenericParam>,
2372 pub inner_ty: P<Ty>,
2373}
2374
2375#[derive(Clone, Encodable, Decodable, Debug)]
2379pub enum TyKind {
2380 Slice(P<Ty>),
2382 Array(P<Ty>, AnonConst),
2384 Ptr(MutTy),
2386 Ref(Option<Lifetime>, MutTy),
2388 PinnedRef(Option<Lifetime>, MutTy),
2392 BareFn(P<BareFnTy>),
2394 UnsafeBinder(P<UnsafeBinderTy>),
2396 Never,
2398 Tup(ThinVec<P<Ty>>),
2400 Path(Option<P<QSelf>>, Path),
2405 TraitObject(GenericBounds, TraitObjectSyntax),
2408 ImplTrait(NodeId, GenericBounds),
2415 Paren(P<Ty>),
2417 Typeof(AnonConst),
2419 Infer,
2422 ImplicitSelf,
2424 MacCall(P<MacCall>),
2426 CVarArgs,
2428 Pat(P<Ty>, P<TyPat>),
2431 Dummy,
2433 Err(ErrorGuaranteed),
2435}
2436
2437impl TyKind {
2438 pub fn is_implicit_self(&self) -> bool {
2439 matches!(self, TyKind::ImplicitSelf)
2440 }
2441
2442 pub fn is_unit(&self) -> bool {
2443 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2444 }
2445
2446 pub fn is_simple_path(&self) -> Option<Symbol> {
2447 if let TyKind::Path(None, Path { segments, .. }) = &self
2448 && let [segment] = &segments[..]
2449 && segment.args.is_none()
2450 {
2451 Some(segment.ident.name)
2452 } else {
2453 None
2454 }
2455 }
2456}
2457
2458#[derive(Clone, Encodable, Decodable, Debug)]
2460pub struct TyPat {
2461 pub id: NodeId,
2462 pub kind: TyPatKind,
2463 pub span: Span,
2464 pub tokens: Option<LazyAttrTokenStream>,
2465}
2466
2467#[derive(Clone, Encodable, Decodable, Debug)]
2471pub enum TyPatKind {
2472 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2474
2475 Or(ThinVec<P<TyPat>>),
2476
2477 Err(ErrorGuaranteed),
2479}
2480
2481#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2483#[repr(u8)]
2484pub enum TraitObjectSyntax {
2485 Dyn = 0,
2487 DynStar = 1,
2488 None = 2,
2489}
2490
2491unsafe impl Tag for TraitObjectSyntax {
2495 const BITS: u32 = 2;
2496
2497 fn into_usize(self) -> usize {
2498 self as u8 as usize
2499 }
2500
2501 unsafe fn from_usize(tag: usize) -> Self {
2502 match tag {
2503 0 => TraitObjectSyntax::Dyn,
2504 1 => TraitObjectSyntax::DynStar,
2505 2 => TraitObjectSyntax::None,
2506 _ => unreachable!(),
2507 }
2508 }
2509}
2510
2511#[derive(Clone, Encodable, Decodable, Debug)]
2512pub enum PreciseCapturingArg {
2513 Lifetime(Lifetime),
2515 Arg(Path, NodeId),
2517}
2518
2519#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2523pub enum InlineAsmRegOrRegClass {
2524 Reg(Symbol),
2525 RegClass(Symbol),
2526}
2527
2528#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2529pub struct InlineAsmOptions(u16);
2530bitflags::bitflags! {
2531 impl InlineAsmOptions: u16 {
2532 const PURE = 1 << 0;
2533 const NOMEM = 1 << 1;
2534 const READONLY = 1 << 2;
2535 const PRESERVES_FLAGS = 1 << 3;
2536 const NORETURN = 1 << 4;
2537 const NOSTACK = 1 << 5;
2538 const ATT_SYNTAX = 1 << 6;
2539 const RAW = 1 << 7;
2540 const MAY_UNWIND = 1 << 8;
2541 }
2542}
2543
2544impl InlineAsmOptions {
2545 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2546
2547 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2548 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2549
2550 pub fn human_readable_names(&self) -> Vec<&'static str> {
2551 let mut options = vec![];
2552
2553 if self.contains(InlineAsmOptions::PURE) {
2554 options.push("pure");
2555 }
2556 if self.contains(InlineAsmOptions::NOMEM) {
2557 options.push("nomem");
2558 }
2559 if self.contains(InlineAsmOptions::READONLY) {
2560 options.push("readonly");
2561 }
2562 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2563 options.push("preserves_flags");
2564 }
2565 if self.contains(InlineAsmOptions::NORETURN) {
2566 options.push("noreturn");
2567 }
2568 if self.contains(InlineAsmOptions::NOSTACK) {
2569 options.push("nostack");
2570 }
2571 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2572 options.push("att_syntax");
2573 }
2574 if self.contains(InlineAsmOptions::RAW) {
2575 options.push("raw");
2576 }
2577 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2578 options.push("may_unwind");
2579 }
2580
2581 options
2582 }
2583}
2584
2585impl std::fmt::Debug for InlineAsmOptions {
2586 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2587 bitflags::parser::to_writer(self, f)
2588 }
2589}
2590
2591#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2592pub enum InlineAsmTemplatePiece {
2593 String(Cow<'static, str>),
2594 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2595}
2596
2597impl fmt::Display for InlineAsmTemplatePiece {
2598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2599 match self {
2600 Self::String(s) => {
2601 for c in s.chars() {
2602 match c {
2603 '{' => f.write_str("{{")?,
2604 '}' => f.write_str("}}")?,
2605 _ => c.fmt(f)?,
2606 }
2607 }
2608 Ok(())
2609 }
2610 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2611 write!(f, "{{{operand_idx}:{modifier}}}")
2612 }
2613 Self::Placeholder { operand_idx, modifier: None, .. } => {
2614 write!(f, "{{{operand_idx}}}")
2615 }
2616 }
2617 }
2618}
2619
2620impl InlineAsmTemplatePiece {
2621 pub fn to_string(s: &[Self]) -> String {
2623 use fmt::Write;
2624 let mut out = String::new();
2625 for p in s.iter() {
2626 let _ = write!(out, "{p}");
2627 }
2628 out
2629 }
2630}
2631
2632#[derive(Clone, Encodable, Decodable, Debug)]
2640pub struct InlineAsmSym {
2641 pub id: NodeId,
2642 pub qself: Option<P<QSelf>>,
2643 pub path: Path,
2644}
2645
2646#[derive(Clone, Encodable, Decodable, Debug)]
2650pub enum InlineAsmOperand {
2651 In {
2652 reg: InlineAsmRegOrRegClass,
2653 expr: P<Expr>,
2654 },
2655 Out {
2656 reg: InlineAsmRegOrRegClass,
2657 late: bool,
2658 expr: Option<P<Expr>>,
2659 },
2660 InOut {
2661 reg: InlineAsmRegOrRegClass,
2662 late: bool,
2663 expr: P<Expr>,
2664 },
2665 SplitInOut {
2666 reg: InlineAsmRegOrRegClass,
2667 late: bool,
2668 in_expr: P<Expr>,
2669 out_expr: Option<P<Expr>>,
2670 },
2671 Const {
2672 anon_const: AnonConst,
2673 },
2674 Sym {
2675 sym: InlineAsmSym,
2676 },
2677 Label {
2678 block: P<Block>,
2679 },
2680}
2681
2682impl InlineAsmOperand {
2683 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2684 match self {
2685 Self::In { reg, .. }
2686 | Self::Out { reg, .. }
2687 | Self::InOut { reg, .. }
2688 | Self::SplitInOut { reg, .. } => Some(reg),
2689 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2690 }
2691 }
2692}
2693
2694#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2695pub enum AsmMacro {
2696 Asm,
2698 GlobalAsm,
2700 NakedAsm,
2702}
2703
2704impl AsmMacro {
2705 pub const fn macro_name(self) -> &'static str {
2706 match self {
2707 AsmMacro::Asm => "asm",
2708 AsmMacro::GlobalAsm => "global_asm",
2709 AsmMacro::NakedAsm => "naked_asm",
2710 }
2711 }
2712
2713 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2714 match self {
2715 AsmMacro::Asm => true,
2716 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2717 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2718 }
2719 }
2720
2721 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2722 match self {
2723 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2724 AsmMacro::GlobalAsm => true,
2725 AsmMacro::NakedAsm => true,
2726 }
2727 }
2728}
2729
2730#[derive(Clone, Encodable, Decodable, Debug)]
2734pub struct InlineAsm {
2735 pub asm_macro: AsmMacro,
2736 pub template: Vec<InlineAsmTemplatePiece>,
2737 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2738 pub operands: Vec<(InlineAsmOperand, Span)>,
2739 pub clobber_abis: Vec<(Symbol, Span)>,
2740 pub options: InlineAsmOptions,
2741 pub line_spans: Vec<Span>,
2742}
2743
2744#[derive(Clone, Encodable, Decodable, Debug)]
2748pub struct Param {
2749 pub attrs: AttrVec,
2750 pub ty: P<Ty>,
2751 pub pat: P<Pat>,
2752 pub id: NodeId,
2753 pub span: Span,
2754 pub is_placeholder: bool,
2755}
2756
2757#[derive(Clone, Encodable, Decodable, Debug)]
2761pub enum SelfKind {
2762 Value(Mutability),
2764 Region(Option<Lifetime>, Mutability),
2766 Pinned(Option<Lifetime>, Mutability),
2768 Explicit(P<Ty>, Mutability),
2770}
2771
2772impl SelfKind {
2773 pub fn to_ref_suggestion(&self) -> String {
2774 match self {
2775 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2776 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2777 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2778 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2779 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2780 unreachable!("if we had an explicit self, we wouldn't be here")
2781 }
2782 }
2783 }
2784}
2785
2786pub type ExplicitSelf = Spanned<SelfKind>;
2787
2788impl Param {
2789 pub fn to_self(&self) -> Option<ExplicitSelf> {
2791 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2792 if ident.name == kw::SelfLower {
2793 return match self.ty.kind {
2794 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2795 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2796 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2797 }
2798 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2799 if ty.kind.is_implicit_self() =>
2800 {
2801 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2802 }
2803 _ => Some(respan(
2804 self.pat.span.to(self.ty.span),
2805 SelfKind::Explicit(self.ty.clone(), mutbl),
2806 )),
2807 };
2808 }
2809 }
2810 None
2811 }
2812
2813 pub fn is_self(&self) -> bool {
2815 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2816 ident.name == kw::SelfLower
2817 } else {
2818 false
2819 }
2820 }
2821
2822 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2824 let span = eself.span.to(eself_ident.span);
2825 let infer_ty = P(Ty {
2826 id: DUMMY_NODE_ID,
2827 kind: TyKind::ImplicitSelf,
2828 span: eself_ident.span,
2829 tokens: None,
2830 });
2831 let (mutbl, ty) = match eself.node {
2832 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2833 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2834 SelfKind::Region(lt, mutbl) => (
2835 Mutability::Not,
2836 P(Ty {
2837 id: DUMMY_NODE_ID,
2838 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2839 span,
2840 tokens: None,
2841 }),
2842 ),
2843 SelfKind::Pinned(lt, mutbl) => (
2844 mutbl,
2845 P(Ty {
2846 id: DUMMY_NODE_ID,
2847 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2848 span,
2849 tokens: None,
2850 }),
2851 ),
2852 };
2853 Param {
2854 attrs,
2855 pat: P(Pat {
2856 id: DUMMY_NODE_ID,
2857 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2858 span,
2859 tokens: None,
2860 }),
2861 span,
2862 ty,
2863 id: DUMMY_NODE_ID,
2864 is_placeholder: false,
2865 }
2866 }
2867}
2868
2869#[derive(Clone, Encodable, Decodable, Debug)]
2876pub struct FnDecl {
2877 pub inputs: ThinVec<Param>,
2878 pub output: FnRetTy,
2879}
2880
2881impl FnDecl {
2882 pub fn has_self(&self) -> bool {
2883 self.inputs.get(0).is_some_and(Param::is_self)
2884 }
2885 pub fn c_variadic(&self) -> bool {
2886 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2887 }
2888}
2889
2890#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2892pub enum IsAuto {
2893 Yes,
2894 No,
2895}
2896
2897#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2899#[derive(HashStable_Generic)]
2900pub enum Safety {
2901 Unsafe(Span),
2903 Safe(Span),
2905 Default,
2908}
2909
2910#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2916pub enum CoroutineKind {
2917 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2919 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2921 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2923}
2924
2925impl CoroutineKind {
2926 pub fn span(self) -> Span {
2927 match self {
2928 CoroutineKind::Async { span, .. } => span,
2929 CoroutineKind::Gen { span, .. } => span,
2930 CoroutineKind::AsyncGen { span, .. } => span,
2931 }
2932 }
2933
2934 pub fn as_str(self) -> &'static str {
2935 match self {
2936 CoroutineKind::Async { .. } => "async",
2937 CoroutineKind::Gen { .. } => "gen",
2938 CoroutineKind::AsyncGen { .. } => "async gen",
2939 }
2940 }
2941
2942 pub fn closure_id(self) -> NodeId {
2943 match self {
2944 CoroutineKind::Async { closure_id, .. }
2945 | CoroutineKind::Gen { closure_id, .. }
2946 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2947 }
2948 }
2949
2950 pub fn return_id(self) -> (NodeId, Span) {
2953 match self {
2954 CoroutineKind::Async { return_impl_trait_id, span, .. }
2955 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2956 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2957 (return_impl_trait_id, span)
2958 }
2959 }
2960 }
2961}
2962
2963#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2964#[derive(HashStable_Generic)]
2965pub enum Const {
2966 Yes(Span),
2967 No,
2968}
2969
2970#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2973pub enum Defaultness {
2974 Default(Span),
2975 Final,
2976}
2977
2978#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2979pub enum ImplPolarity {
2980 Positive,
2982 Negative(Span),
2984}
2985
2986impl fmt::Debug for ImplPolarity {
2987 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2988 match *self {
2989 ImplPolarity::Positive => "positive".fmt(f),
2990 ImplPolarity::Negative(_) => "negative".fmt(f),
2991 }
2992 }
2993}
2994
2995#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2997#[derive(HashStable_Generic)]
2998pub enum BoundPolarity {
2999 Positive,
3001 Negative(Span),
3003 Maybe(Span),
3005}
3006
3007impl BoundPolarity {
3008 pub fn as_str(self) -> &'static str {
3009 match self {
3010 Self::Positive => "",
3011 Self::Negative(_) => "!",
3012 Self::Maybe(_) => "?",
3013 }
3014 }
3015}
3016
3017#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3019#[derive(HashStable_Generic)]
3020pub enum BoundConstness {
3021 Never,
3023 Always(Span),
3025 Maybe(Span),
3027}
3028
3029impl BoundConstness {
3030 pub fn as_str(self) -> &'static str {
3031 match self {
3032 Self::Never => "",
3033 Self::Always(_) => "const",
3034 Self::Maybe(_) => "~const",
3035 }
3036 }
3037}
3038
3039#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3041#[derive(HashStable_Generic)]
3042pub enum BoundAsyncness {
3043 Normal,
3045 Async(Span),
3047}
3048
3049impl BoundAsyncness {
3050 pub fn as_str(self) -> &'static str {
3051 match self {
3052 Self::Normal => "",
3053 Self::Async(_) => "async",
3054 }
3055 }
3056}
3057
3058#[derive(Clone, Encodable, Decodable, Debug)]
3059pub enum FnRetTy {
3060 Default(Span),
3065 Ty(P<Ty>),
3067}
3068
3069impl FnRetTy {
3070 pub fn span(&self) -> Span {
3071 match self {
3072 &FnRetTy::Default(span) => span,
3073 FnRetTy::Ty(ty) => ty.span,
3074 }
3075 }
3076}
3077
3078#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3079pub enum Inline {
3080 Yes,
3081 No,
3082}
3083
3084#[derive(Clone, Encodable, Decodable, Debug)]
3086pub enum ModKind {
3087 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3092 Unloaded,
3094}
3095
3096#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3097pub struct ModSpans {
3098 pub inner_span: Span,
3101 pub inject_use_span: Span,
3102}
3103
3104#[derive(Clone, Encodable, Decodable, Debug)]
3108pub struct ForeignMod {
3109 pub extern_span: Span,
3111 pub safety: Safety,
3114 pub abi: Option<StrLit>,
3115 pub items: ThinVec<P<ForeignItem>>,
3116}
3117
3118#[derive(Clone, Encodable, Decodable, Debug)]
3119pub struct EnumDef {
3120 pub variants: ThinVec<Variant>,
3121}
3122#[derive(Clone, Encodable, Decodable, Debug)]
3124pub struct Variant {
3125 pub attrs: AttrVec,
3127 pub id: NodeId,
3129 pub span: Span,
3131 pub vis: Visibility,
3133 pub ident: Ident,
3135
3136 pub data: VariantData,
3138 pub disr_expr: Option<AnonConst>,
3140 pub is_placeholder: bool,
3142}
3143
3144#[derive(Clone, Encodable, Decodable, Debug)]
3146pub enum UseTreeKind {
3147 Simple(Option<Ident>),
3149 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3158 Glob,
3160}
3161
3162#[derive(Clone, Encodable, Decodable, Debug)]
3165pub struct UseTree {
3166 pub prefix: Path,
3167 pub kind: UseTreeKind,
3168 pub span: Span,
3169}
3170
3171impl UseTree {
3172 pub fn ident(&self) -> Ident {
3173 match self.kind {
3174 UseTreeKind::Simple(Some(rename)) => rename,
3175 UseTreeKind::Simple(None) => {
3176 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3177 }
3178 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3179 }
3180 }
3181}
3182
3183#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3187pub enum AttrStyle {
3188 Outer,
3189 Inner,
3190}
3191
3192pub type AttrVec = ThinVec<Attribute>;
3194
3195#[derive(Clone, Encodable, Decodable, Debug)]
3197pub struct Attribute {
3198 pub kind: AttrKind,
3199 pub id: AttrId,
3200 pub style: AttrStyle,
3203 pub span: Span,
3204}
3205
3206#[derive(Clone, Encodable, Decodable, Debug)]
3207pub enum AttrKind {
3208 Normal(P<NormalAttr>),
3210
3211 DocComment(CommentKind, Symbol),
3215}
3216
3217#[derive(Clone, Encodable, Decodable, Debug)]
3218pub struct NormalAttr {
3219 pub item: AttrItem,
3220 pub tokens: Option<LazyAttrTokenStream>,
3222}
3223
3224impl NormalAttr {
3225 pub fn from_ident(ident: Ident) -> Self {
3226 Self {
3227 item: AttrItem {
3228 unsafety: Safety::Default,
3229 path: Path::from_ident(ident),
3230 args: AttrArgs::Empty,
3231 tokens: None,
3232 },
3233 tokens: None,
3234 }
3235 }
3236}
3237
3238#[derive(Clone, Encodable, Decodable, Debug)]
3239pub struct AttrItem {
3240 pub unsafety: Safety,
3241 pub path: Path,
3242 pub args: AttrArgs,
3243 pub tokens: Option<LazyAttrTokenStream>,
3245}
3246
3247impl AttrItem {
3248 pub fn is_valid_for_outer_style(&self) -> bool {
3249 self.path == sym::cfg_attr
3250 || self.path == sym::cfg
3251 || self.path == sym::forbid
3252 || self.path == sym::warn
3253 || self.path == sym::allow
3254 || self.path == sym::deny
3255 }
3256}
3257
3258#[derive(Clone, Encodable, Decodable, Debug)]
3265pub struct TraitRef {
3266 pub path: Path,
3267 pub ref_id: NodeId,
3268}
3269
3270#[derive(Clone, Encodable, Decodable, Debug)]
3271pub struct PolyTraitRef {
3272 pub bound_generic_params: ThinVec<GenericParam>,
3274
3275 pub modifiers: TraitBoundModifiers,
3277
3278 pub trait_ref: TraitRef,
3280
3281 pub span: Span,
3282}
3283
3284impl PolyTraitRef {
3285 pub fn new(
3286 generic_params: ThinVec<GenericParam>,
3287 path: Path,
3288 modifiers: TraitBoundModifiers,
3289 span: Span,
3290 ) -> Self {
3291 PolyTraitRef {
3292 bound_generic_params: generic_params,
3293 modifiers,
3294 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3295 span,
3296 }
3297 }
3298}
3299
3300#[derive(Clone, Encodable, Decodable, Debug)]
3301pub struct Visibility {
3302 pub kind: VisibilityKind,
3303 pub span: Span,
3304 pub tokens: Option<LazyAttrTokenStream>,
3305}
3306
3307#[derive(Clone, Encodable, Decodable, Debug)]
3308pub enum VisibilityKind {
3309 Public,
3310 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3311 Inherited,
3312}
3313
3314impl VisibilityKind {
3315 pub fn is_pub(&self) -> bool {
3316 matches!(self, VisibilityKind::Public)
3317 }
3318}
3319
3320#[derive(Clone, Encodable, Decodable, Debug)]
3324pub struct FieldDef {
3325 pub attrs: AttrVec,
3326 pub id: NodeId,
3327 pub span: Span,
3328 pub vis: Visibility,
3329 pub safety: Safety,
3330 pub ident: Option<Ident>,
3331
3332 pub ty: P<Ty>,
3333 pub default: Option<AnonConst>,
3334 pub is_placeholder: bool,
3335}
3336
3337#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3339pub enum Recovered {
3340 No,
3341 Yes(ErrorGuaranteed),
3342}
3343
3344#[derive(Clone, Encodable, Decodable, Debug)]
3346pub enum VariantData {
3347 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3351 Tuple(ThinVec<FieldDef>, NodeId),
3355 Unit(NodeId),
3359}
3360
3361impl VariantData {
3362 pub fn fields(&self) -> &[FieldDef] {
3364 match self {
3365 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3366 _ => &[],
3367 }
3368 }
3369
3370 pub fn ctor_node_id(&self) -> Option<NodeId> {
3372 match *self {
3373 VariantData::Struct { .. } => None,
3374 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3375 }
3376 }
3377}
3378
3379#[derive(Clone, Encodable, Decodable, Debug)]
3381pub struct Item<K = ItemKind> {
3382 pub attrs: AttrVec,
3383 pub id: NodeId,
3384 pub span: Span,
3385 pub vis: Visibility,
3386
3387 pub kind: K,
3388
3389 pub tokens: Option<LazyAttrTokenStream>,
3397}
3398
3399impl Item {
3400 pub fn span_with_attributes(&self) -> Span {
3402 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3403 }
3404
3405 pub fn opt_generics(&self) -> Option<&Generics> {
3406 match &self.kind {
3407 ItemKind::ExternCrate(..)
3408 | ItemKind::Use(_)
3409 | ItemKind::Mod(..)
3410 | ItemKind::ForeignMod(_)
3411 | ItemKind::GlobalAsm(_)
3412 | ItemKind::MacCall(_)
3413 | ItemKind::Delegation(_)
3414 | ItemKind::DelegationMac(_)
3415 | ItemKind::MacroDef(..) => None,
3416 ItemKind::Static(_) => None,
3417 ItemKind::Const(i) => Some(&i.generics),
3418 ItemKind::Fn(i) => Some(&i.generics),
3419 ItemKind::TyAlias(i) => Some(&i.generics),
3420 ItemKind::TraitAlias(_, generics, _)
3421 | ItemKind::Enum(_, _, generics)
3422 | ItemKind::Struct(_, _, generics)
3423 | ItemKind::Union(_, _, generics) => Some(&generics),
3424 ItemKind::Trait(i) => Some(&i.generics),
3425 ItemKind::Impl(i) => Some(&i.generics),
3426 }
3427 }
3428}
3429
3430#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3432pub enum Extern {
3433 None,
3437 Implicit(Span),
3443 Explicit(StrLit, Span),
3447}
3448
3449impl Extern {
3450 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3451 match abi {
3452 Some(name) => Extern::Explicit(name, span),
3453 None => Extern::Implicit(span),
3454 }
3455 }
3456}
3457
3458#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3463pub struct FnHeader {
3464 pub safety: Safety,
3466 pub coroutine_kind: Option<CoroutineKind>,
3468 pub constness: Const,
3470 pub ext: Extern,
3472}
3473
3474impl FnHeader {
3475 pub fn has_qualifiers(&self) -> bool {
3477 let Self { safety, coroutine_kind, constness, ext } = self;
3478 matches!(safety, Safety::Unsafe(_))
3479 || coroutine_kind.is_some()
3480 || matches!(constness, Const::Yes(_))
3481 || !matches!(ext, Extern::None)
3482 }
3483}
3484
3485impl Default for FnHeader {
3486 fn default() -> FnHeader {
3487 FnHeader {
3488 safety: Safety::Default,
3489 coroutine_kind: None,
3490 constness: Const::No,
3491 ext: Extern::None,
3492 }
3493 }
3494}
3495
3496#[derive(Clone, Encodable, Decodable, Debug)]
3497pub struct Trait {
3498 pub safety: Safety,
3499 pub is_auto: IsAuto,
3500 pub ident: Ident,
3501 pub generics: Generics,
3502 pub bounds: GenericBounds,
3503 pub items: ThinVec<P<AssocItem>>,
3504}
3505
3506#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3525pub struct TyAliasWhereClause {
3526 pub has_where_token: bool,
3527 pub span: Span,
3528}
3529
3530#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3532pub struct TyAliasWhereClauses {
3533 pub before: TyAliasWhereClause,
3535 pub after: TyAliasWhereClause,
3537 pub split: usize,
3541}
3542
3543#[derive(Clone, Encodable, Decodable, Debug)]
3544pub struct TyAlias {
3545 pub defaultness: Defaultness,
3546 pub ident: Ident,
3547 pub generics: Generics,
3548 pub where_clauses: TyAliasWhereClauses,
3549 pub bounds: GenericBounds,
3550 pub ty: Option<P<Ty>>,
3551}
3552
3553#[derive(Clone, Encodable, Decodable, Debug)]
3554pub struct Impl {
3555 pub defaultness: Defaultness,
3556 pub safety: Safety,
3557 pub generics: Generics,
3558 pub constness: Const,
3559 pub polarity: ImplPolarity,
3560 pub of_trait: Option<TraitRef>,
3562 pub self_ty: P<Ty>,
3563 pub items: ThinVec<P<AssocItem>>,
3564}
3565
3566#[derive(Clone, Encodable, Decodable, Debug, Default)]
3567pub struct FnContract {
3568 pub requires: Option<P<Expr>>,
3569 pub ensures: Option<P<Expr>>,
3570}
3571
3572#[derive(Clone, Encodable, Decodable, Debug)]
3573pub struct Fn {
3574 pub defaultness: Defaultness,
3575 pub ident: Ident,
3576 pub generics: Generics,
3577 pub sig: FnSig,
3578 pub contract: Option<P<FnContract>>,
3579 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3580 pub body: Option<P<Block>>,
3581}
3582
3583#[derive(Clone, Encodable, Decodable, Debug)]
3584pub struct Delegation {
3585 pub id: NodeId,
3587 pub qself: Option<P<QSelf>>,
3588 pub path: Path,
3589 pub ident: Ident,
3590 pub rename: Option<Ident>,
3591 pub body: Option<P<Block>>,
3592 pub from_glob: bool,
3594}
3595
3596#[derive(Clone, Encodable, Decodable, Debug)]
3597pub struct DelegationMac {
3598 pub qself: Option<P<QSelf>>,
3599 pub prefix: Path,
3600 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3602 pub body: Option<P<Block>>,
3603}
3604
3605#[derive(Clone, Encodable, Decodable, Debug)]
3606pub struct StaticItem {
3607 pub ident: Ident,
3608 pub ty: P<Ty>,
3609 pub safety: Safety,
3610 pub mutability: Mutability,
3611 pub expr: Option<P<Expr>>,
3612 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3613}
3614
3615#[derive(Clone, Encodable, Decodable, Debug)]
3616pub struct ConstItem {
3617 pub defaultness: Defaultness,
3618 pub ident: Ident,
3619 pub generics: Generics,
3620 pub ty: P<Ty>,
3621 pub expr: Option<P<Expr>>,
3622 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3623}
3624
3625#[derive(Clone, Encodable, Decodable, Debug)]
3627pub enum ItemKind {
3628 ExternCrate(Option<Symbol>, Ident),
3632 Use(UseTree),
3636 Static(Box<StaticItem>),
3640 Const(Box<ConstItem>),
3644 Fn(Box<Fn>),
3648 Mod(Safety, Ident, ModKind),
3654 ForeignMod(ForeignMod),
3658 GlobalAsm(Box<InlineAsm>),
3660 TyAlias(Box<TyAlias>),
3664 Enum(Ident, EnumDef, Generics),
3668 Struct(Ident, VariantData, Generics),
3672 Union(Ident, VariantData, Generics),
3676 Trait(Box<Trait>),
3680 TraitAlias(Ident, Generics, GenericBounds),
3684 Impl(Box<Impl>),
3688 MacCall(P<MacCall>),
3692
3693 MacroDef(Ident, MacroDef),
3695
3696 Delegation(Box<Delegation>),
3700 DelegationMac(Box<DelegationMac>),
3703}
3704
3705impl ItemKind {
3706 pub fn ident(&self) -> Option<Ident> {
3707 match *self {
3708 ItemKind::ExternCrate(_, ident)
3709 | ItemKind::Static(box StaticItem { ident, .. })
3710 | ItemKind::Const(box ConstItem { ident, .. })
3711 | ItemKind::Fn(box Fn { ident, .. })
3712 | ItemKind::Mod(_, ident, _)
3713 | ItemKind::TyAlias(box TyAlias { ident, .. })
3714 | ItemKind::Enum(ident, ..)
3715 | ItemKind::Struct(ident, ..)
3716 | ItemKind::Union(ident, ..)
3717 | ItemKind::Trait(box Trait { ident, .. })
3718 | ItemKind::TraitAlias(ident, ..)
3719 | ItemKind::MacroDef(ident, _)
3720 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3721
3722 ItemKind::Use(_)
3723 | ItemKind::ForeignMod(_)
3724 | ItemKind::GlobalAsm(_)
3725 | ItemKind::Impl(_)
3726 | ItemKind::MacCall(_)
3727 | ItemKind::DelegationMac(_) => None,
3728 }
3729 }
3730
3731 pub fn article(&self) -> &'static str {
3733 use ItemKind::*;
3734 match self {
3735 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3736 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3737 | Delegation(..) | DelegationMac(..) => "a",
3738 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3739 }
3740 }
3741
3742 pub fn descr(&self) -> &'static str {
3743 match self {
3744 ItemKind::ExternCrate(..) => "extern crate",
3745 ItemKind::Use(..) => "`use` import",
3746 ItemKind::Static(..) => "static item",
3747 ItemKind::Const(..) => "constant item",
3748 ItemKind::Fn(..) => "function",
3749 ItemKind::Mod(..) => "module",
3750 ItemKind::ForeignMod(..) => "extern block",
3751 ItemKind::GlobalAsm(..) => "global asm item",
3752 ItemKind::TyAlias(..) => "type alias",
3753 ItemKind::Enum(..) => "enum",
3754 ItemKind::Struct(..) => "struct",
3755 ItemKind::Union(..) => "union",
3756 ItemKind::Trait(..) => "trait",
3757 ItemKind::TraitAlias(..) => "trait alias",
3758 ItemKind::MacCall(..) => "item macro invocation",
3759 ItemKind::MacroDef(..) => "macro definition",
3760 ItemKind::Impl { .. } => "implementation",
3761 ItemKind::Delegation(..) => "delegated function",
3762 ItemKind::DelegationMac(..) => "delegation",
3763 }
3764 }
3765
3766 pub fn generics(&self) -> Option<&Generics> {
3767 match self {
3768 Self::Fn(box Fn { generics, .. })
3769 | Self::TyAlias(box TyAlias { generics, .. })
3770 | Self::Const(box ConstItem { generics, .. })
3771 | Self::Enum(_, _, generics)
3772 | Self::Struct(_, _, generics)
3773 | Self::Union(_, _, generics)
3774 | Self::Trait(box Trait { generics, .. })
3775 | Self::TraitAlias(_, generics, _)
3776 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3777 _ => None,
3778 }
3779 }
3780}
3781
3782pub type AssocItem = Item<AssocItemKind>;
3785
3786#[derive(Clone, Encodable, Decodable, Debug)]
3794pub enum AssocItemKind {
3795 Const(Box<ConstItem>),
3798 Fn(Box<Fn>),
3800 Type(Box<TyAlias>),
3802 MacCall(P<MacCall>),
3804 Delegation(Box<Delegation>),
3806 DelegationMac(Box<DelegationMac>),
3808}
3809
3810impl AssocItemKind {
3811 pub fn ident(&self) -> Option<Ident> {
3812 match *self {
3813 AssocItemKind::Const(box ConstItem { ident, .. })
3814 | AssocItemKind::Fn(box Fn { ident, .. })
3815 | AssocItemKind::Type(box TyAlias { ident, .. })
3816 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3817
3818 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3819 }
3820 }
3821
3822 pub fn defaultness(&self) -> Defaultness {
3823 match *self {
3824 Self::Const(box ConstItem { defaultness, .. })
3825 | Self::Fn(box Fn { defaultness, .. })
3826 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3827 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3828 Defaultness::Final
3829 }
3830 }
3831 }
3832}
3833
3834impl From<AssocItemKind> for ItemKind {
3835 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3836 match assoc_item_kind {
3837 AssocItemKind::Const(item) => ItemKind::Const(item),
3838 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3839 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3840 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3841 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3842 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3843 }
3844 }
3845}
3846
3847impl TryFrom<ItemKind> for AssocItemKind {
3848 type Error = ItemKind;
3849
3850 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3851 Ok(match item_kind {
3852 ItemKind::Const(item) => AssocItemKind::Const(item),
3853 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3854 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3855 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3856 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3857 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3858 _ => return Err(item_kind),
3859 })
3860 }
3861}
3862
3863#[derive(Clone, Encodable, Decodable, Debug)]
3865pub enum ForeignItemKind {
3866 Static(Box<StaticItem>),
3868 Fn(Box<Fn>),
3870 TyAlias(Box<TyAlias>),
3872 MacCall(P<MacCall>),
3874}
3875
3876impl ForeignItemKind {
3877 pub fn ident(&self) -> Option<Ident> {
3878 match *self {
3879 ForeignItemKind::Static(box StaticItem { ident, .. })
3880 | ForeignItemKind::Fn(box Fn { ident, .. })
3881 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3882
3883 ForeignItemKind::MacCall(_) => None,
3884 }
3885 }
3886}
3887
3888impl From<ForeignItemKind> for ItemKind {
3889 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3890 match foreign_item_kind {
3891 ForeignItemKind::Static(box static_foreign_item) => {
3892 ItemKind::Static(Box::new(static_foreign_item))
3893 }
3894 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3895 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3896 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3897 }
3898 }
3899}
3900
3901impl TryFrom<ItemKind> for ForeignItemKind {
3902 type Error = ItemKind;
3903
3904 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3905 Ok(match item_kind {
3906 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3907 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3908 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3909 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3910 _ => return Err(item_kind),
3911 })
3912 }
3913}
3914
3915pub type ForeignItem = Item<ForeignItemKind>;
3916
3917#[cfg(target_pointer_width = "64")]
3919mod size_asserts {
3920 use rustc_data_structures::static_assert_size;
3921
3922 use super::*;
3923 static_assert_size!(AssocItem, 80);
3925 static_assert_size!(AssocItemKind, 16);
3926 static_assert_size!(Attribute, 32);
3927 static_assert_size!(Block, 32);
3928 static_assert_size!(Expr, 72);
3929 static_assert_size!(ExprKind, 40);
3930 static_assert_size!(Fn, 184);
3931 static_assert_size!(ForeignItem, 80);
3932 static_assert_size!(ForeignItemKind, 16);
3933 static_assert_size!(GenericArg, 24);
3934 static_assert_size!(GenericBound, 88);
3935 static_assert_size!(Generics, 40);
3936 static_assert_size!(Impl, 136);
3937 static_assert_size!(Item, 144);
3938 static_assert_size!(ItemKind, 80);
3939 static_assert_size!(LitKind, 24);
3940 static_assert_size!(Local, 96);
3941 static_assert_size!(MetaItemLit, 40);
3942 static_assert_size!(Param, 40);
3943 static_assert_size!(Pat, 72);
3944 static_assert_size!(Path, 24);
3945 static_assert_size!(PathSegment, 24);
3946 static_assert_size!(PatKind, 48);
3947 static_assert_size!(Stmt, 32);
3948 static_assert_size!(StmtKind, 16);
3949 static_assert_size!(Ty, 64);
3950 static_assert_size!(TyKind, 40);
3951 }