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>>),
1637 While(P<Expr>, P<Block>, Option<Label>),
1641 ForLoop {
1647 pat: P<Pat>,
1648 iter: P<Expr>,
1649 body: P<Block>,
1650 label: Option<Label>,
1651 kind: ForLoopKind,
1652 },
1653 Loop(P<Block>, Option<Label>, Span),
1657 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1659 Closure(Box<Closure>),
1661 Block(P<Block>, Option<Label>),
1663 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1669 Await(P<Expr>, Span),
1671 Use(P<Expr>, Span),
1673
1674 TryBlock(P<Block>),
1676
1677 Assign(P<Expr>, P<Expr>, Span),
1680 AssignOp(AssignOp, P<Expr>, P<Expr>),
1684 Field(P<Expr>, Ident),
1686 Index(P<Expr>, P<Expr>, Span),
1689 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1691 Underscore,
1693
1694 Path(Option<P<QSelf>>, Path),
1699
1700 AddrOf(BorrowKind, Mutability, P<Expr>),
1702 Break(Option<Label>, Option<P<Expr>>),
1704 Continue(Option<Label>),
1706 Ret(Option<P<Expr>>),
1708
1709 InlineAsm(P<InlineAsm>),
1711
1712 OffsetOf(P<Ty>, P<[Ident]>),
1717
1718 MacCall(P<MacCall>),
1720
1721 Struct(P<StructExpr>),
1725
1726 Repeat(P<Expr>, AnonConst),
1731
1732 Paren(P<Expr>),
1734
1735 Try(P<Expr>),
1737
1738 Yield(YieldKind),
1740
1741 Yeet(Option<P<Expr>>),
1744
1745 Become(P<Expr>),
1749
1750 IncludedBytes(Arc<[u8]>),
1755
1756 FormatArgs(P<FormatArgs>),
1758
1759 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1760
1761 Err(ErrorGuaranteed),
1763
1764 Dummy,
1766}
1767
1768#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1770pub enum ForLoopKind {
1771 For,
1772 ForAwait,
1773}
1774
1775#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1777pub enum GenBlockKind {
1778 Async,
1779 Gen,
1780 AsyncGen,
1781}
1782
1783impl fmt::Display for GenBlockKind {
1784 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1785 self.modifier().fmt(f)
1786 }
1787}
1788
1789impl GenBlockKind {
1790 pub fn modifier(&self) -> &'static str {
1791 match self {
1792 GenBlockKind::Async => "async",
1793 GenBlockKind::Gen => "gen",
1794 GenBlockKind::AsyncGen => "async gen",
1795 }
1796 }
1797}
1798
1799#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1801#[derive(Encodable, Decodable, HashStable_Generic)]
1802pub enum UnsafeBinderCastKind {
1803 Wrap,
1805 Unwrap,
1807}
1808
1809#[derive(Clone, Encodable, Decodable, Debug)]
1824pub struct QSelf {
1825 pub ty: P<Ty>,
1826
1827 pub path_span: Span,
1831 pub position: usize,
1832}
1833
1834#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1836pub enum CaptureBy {
1837 Value {
1839 move_kw: Span,
1841 },
1842 Ref,
1844 Use {
1850 use_kw: Span,
1852 },
1853}
1854
1855#[derive(Clone, Encodable, Decodable, Debug)]
1857pub enum ClosureBinder {
1858 NotPresent,
1860 For {
1862 span: Span,
1869
1870 generic_params: ThinVec<GenericParam>,
1877 },
1878}
1879
1880#[derive(Clone, Encodable, Decodable, Debug)]
1883pub struct MacCall {
1884 pub path: Path,
1885 pub args: P<DelimArgs>,
1886}
1887
1888impl MacCall {
1889 pub fn span(&self) -> Span {
1890 self.path.span.to(self.args.dspan.entire())
1891 }
1892}
1893
1894#[derive(Clone, Encodable, Decodable, Debug)]
1896pub enum AttrArgs {
1897 Empty,
1899 Delimited(DelimArgs),
1901 Eq {
1903 eq_span: Span,
1905 expr: P<Expr>,
1906 },
1907}
1908
1909impl AttrArgs {
1910 pub fn span(&self) -> Option<Span> {
1911 match self {
1912 AttrArgs::Empty => None,
1913 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1914 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1915 }
1916 }
1917
1918 pub fn inner_tokens(&self) -> TokenStream {
1921 match self {
1922 AttrArgs::Empty => TokenStream::default(),
1923 AttrArgs::Delimited(args) => args.tokens.clone(),
1924 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1925 }
1926 }
1927}
1928
1929#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1931pub struct DelimArgs {
1932 pub dspan: DelimSpan,
1933 pub delim: Delimiter, pub tokens: TokenStream,
1935}
1936
1937impl DelimArgs {
1938 pub fn need_semicolon(&self) -> bool {
1941 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1942 }
1943}
1944
1945#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1947pub struct MacroDef {
1948 pub body: P<DelimArgs>,
1949 pub macro_rules: bool,
1951}
1952
1953#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1954#[derive(HashStable_Generic)]
1955pub enum StrStyle {
1956 Cooked,
1958 Raw(u8),
1962}
1963
1964#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1966pub enum MatchKind {
1967 Prefix,
1969 Postfix,
1971}
1972
1973#[derive(Clone, Encodable, Decodable, Debug)]
1975pub enum YieldKind {
1976 Prefix(Option<P<Expr>>),
1978 Postfix(P<Expr>),
1980}
1981
1982impl YieldKind {
1983 pub const fn expr(&self) -> Option<&P<Expr>> {
1987 match self {
1988 YieldKind::Prefix(expr) => expr.as_ref(),
1989 YieldKind::Postfix(expr) => Some(expr),
1990 }
1991 }
1992
1993 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1995 match self {
1996 YieldKind::Prefix(expr) => expr.as_mut(),
1997 YieldKind::Postfix(expr) => Some(expr),
1998 }
1999 }
2000
2001 pub const fn same_kind(&self, other: &Self) -> bool {
2003 match (self, other) {
2004 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2005 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2006 _ => false,
2007 }
2008 }
2009}
2010
2011#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2013pub struct MetaItemLit {
2014 pub symbol: Symbol,
2016 pub suffix: Option<Symbol>,
2018 pub kind: LitKind,
2021 pub span: Span,
2022}
2023
2024#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2026pub struct StrLit {
2027 pub symbol: Symbol,
2029 pub suffix: Option<Symbol>,
2031 pub symbol_unescaped: Symbol,
2033 pub style: StrStyle,
2034 pub span: Span,
2035}
2036
2037impl StrLit {
2038 pub fn as_token_lit(&self) -> token::Lit {
2039 let token_kind = match self.style {
2040 StrStyle::Cooked => token::Str,
2041 StrStyle::Raw(n) => token::StrRaw(n),
2042 };
2043 token::Lit::new(token_kind, self.symbol, self.suffix)
2044 }
2045}
2046
2047#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2049#[derive(HashStable_Generic)]
2050pub enum LitIntType {
2051 Signed(IntTy),
2053 Unsigned(UintTy),
2055 Unsuffixed,
2057}
2058
2059#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2061#[derive(HashStable_Generic)]
2062pub enum LitFloatType {
2063 Suffixed(FloatTy),
2065 Unsuffixed,
2067}
2068
2069#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2076pub enum LitKind {
2077 Str(Symbol, StrStyle),
2080 ByteStr(Arc<[u8]>, StrStyle),
2083 CStr(Arc<[u8]>, StrStyle),
2085 Byte(u8),
2087 Char(char),
2089 Int(Pu128, LitIntType),
2091 Float(Symbol, LitFloatType),
2095 Bool(bool),
2097 Err(ErrorGuaranteed),
2099}
2100
2101impl LitKind {
2102 pub fn str(&self) -> Option<Symbol> {
2103 match *self {
2104 LitKind::Str(s, _) => Some(s),
2105 _ => None,
2106 }
2107 }
2108
2109 pub fn is_str(&self) -> bool {
2111 matches!(self, LitKind::Str(..))
2112 }
2113
2114 pub fn is_bytestr(&self) -> bool {
2116 matches!(self, LitKind::ByteStr(..))
2117 }
2118
2119 pub fn is_numeric(&self) -> bool {
2121 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2122 }
2123
2124 pub fn is_unsuffixed(&self) -> bool {
2127 !self.is_suffixed()
2128 }
2129
2130 pub fn is_suffixed(&self) -> bool {
2132 match *self {
2133 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2135 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2136 LitKind::Str(..)
2138 | LitKind::ByteStr(..)
2139 | LitKind::CStr(..)
2140 | LitKind::Byte(..)
2141 | LitKind::Char(..)
2142 | LitKind::Int(_, LitIntType::Unsuffixed)
2143 | LitKind::Float(_, LitFloatType::Unsuffixed)
2144 | LitKind::Bool(..)
2145 | LitKind::Err(_) => false,
2146 }
2147 }
2148}
2149
2150#[derive(Clone, Encodable, Decodable, Debug)]
2153pub struct MutTy {
2154 pub ty: P<Ty>,
2155 pub mutbl: Mutability,
2156}
2157
2158#[derive(Clone, Encodable, Decodable, Debug)]
2161pub struct FnSig {
2162 pub header: FnHeader,
2163 pub decl: P<FnDecl>,
2164 pub span: Span,
2165}
2166
2167#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2168#[derive(Encodable, Decodable, HashStable_Generic)]
2169pub enum FloatTy {
2170 F16,
2171 F32,
2172 F64,
2173 F128,
2174}
2175
2176impl FloatTy {
2177 pub fn name_str(self) -> &'static str {
2178 match self {
2179 FloatTy::F16 => "f16",
2180 FloatTy::F32 => "f32",
2181 FloatTy::F64 => "f64",
2182 FloatTy::F128 => "f128",
2183 }
2184 }
2185
2186 pub fn name(self) -> Symbol {
2187 match self {
2188 FloatTy::F16 => sym::f16,
2189 FloatTy::F32 => sym::f32,
2190 FloatTy::F64 => sym::f64,
2191 FloatTy::F128 => sym::f128,
2192 }
2193 }
2194}
2195
2196#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2197#[derive(Encodable, Decodable, HashStable_Generic)]
2198pub enum IntTy {
2199 Isize,
2200 I8,
2201 I16,
2202 I32,
2203 I64,
2204 I128,
2205}
2206
2207impl IntTy {
2208 pub fn name_str(&self) -> &'static str {
2209 match *self {
2210 IntTy::Isize => "isize",
2211 IntTy::I8 => "i8",
2212 IntTy::I16 => "i16",
2213 IntTy::I32 => "i32",
2214 IntTy::I64 => "i64",
2215 IntTy::I128 => "i128",
2216 }
2217 }
2218
2219 pub fn name(&self) -> Symbol {
2220 match *self {
2221 IntTy::Isize => sym::isize,
2222 IntTy::I8 => sym::i8,
2223 IntTy::I16 => sym::i16,
2224 IntTy::I32 => sym::i32,
2225 IntTy::I64 => sym::i64,
2226 IntTy::I128 => sym::i128,
2227 }
2228 }
2229}
2230
2231#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2232#[derive(Encodable, Decodable, HashStable_Generic)]
2233pub enum UintTy {
2234 Usize,
2235 U8,
2236 U16,
2237 U32,
2238 U64,
2239 U128,
2240}
2241
2242impl UintTy {
2243 pub fn name_str(&self) -> &'static str {
2244 match *self {
2245 UintTy::Usize => "usize",
2246 UintTy::U8 => "u8",
2247 UintTy::U16 => "u16",
2248 UintTy::U32 => "u32",
2249 UintTy::U64 => "u64",
2250 UintTy::U128 => "u128",
2251 }
2252 }
2253
2254 pub fn name(&self) -> Symbol {
2255 match *self {
2256 UintTy::Usize => sym::usize,
2257 UintTy::U8 => sym::u8,
2258 UintTy::U16 => sym::u16,
2259 UintTy::U32 => sym::u32,
2260 UintTy::U64 => sym::u64,
2261 UintTy::U128 => sym::u128,
2262 }
2263 }
2264}
2265
2266#[derive(Clone, Encodable, Decodable, Debug)]
2277pub struct AssocItemConstraint {
2278 pub id: NodeId,
2279 pub ident: Ident,
2280 pub gen_args: Option<GenericArgs>,
2281 pub kind: AssocItemConstraintKind,
2282 pub span: Span,
2283}
2284
2285#[derive(Clone, Encodable, Decodable, Debug)]
2286pub enum Term {
2287 Ty(P<Ty>),
2288 Const(AnonConst),
2289}
2290
2291impl From<P<Ty>> for Term {
2292 fn from(v: P<Ty>) -> Self {
2293 Term::Ty(v)
2294 }
2295}
2296
2297impl From<AnonConst> for Term {
2298 fn from(v: AnonConst) -> Self {
2299 Term::Const(v)
2300 }
2301}
2302
2303#[derive(Clone, Encodable, Decodable, Debug)]
2305pub enum AssocItemConstraintKind {
2306 Equality { term: Term },
2313 Bound { bounds: GenericBounds },
2315}
2316
2317#[derive(Encodable, Decodable, Debug)]
2318pub struct Ty {
2319 pub id: NodeId,
2320 pub kind: TyKind,
2321 pub span: Span,
2322 pub tokens: Option<LazyAttrTokenStream>,
2323}
2324
2325impl Clone for Ty {
2326 fn clone(&self) -> Self {
2327 ensure_sufficient_stack(|| Self {
2328 id: self.id,
2329 kind: self.kind.clone(),
2330 span: self.span,
2331 tokens: self.tokens.clone(),
2332 })
2333 }
2334}
2335
2336impl Ty {
2337 pub fn peel_refs(&self) -> &Self {
2338 let mut final_ty = self;
2339 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2340 {
2341 final_ty = ty;
2342 }
2343 final_ty
2344 }
2345
2346 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2347 match &self.kind {
2348 TyKind::Infer => true,
2349 TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
2350 _ => false,
2351 }
2352 }
2353}
2354
2355#[derive(Clone, Encodable, Decodable, Debug)]
2356pub struct BareFnTy {
2357 pub safety: Safety,
2358 pub ext: Extern,
2359 pub generic_params: ThinVec<GenericParam>,
2360 pub decl: P<FnDecl>,
2361 pub decl_span: Span,
2364}
2365
2366#[derive(Clone, Encodable, Decodable, Debug)]
2367pub struct UnsafeBinderTy {
2368 pub generic_params: ThinVec<GenericParam>,
2369 pub inner_ty: P<Ty>,
2370}
2371
2372#[derive(Clone, Encodable, Decodable, Debug)]
2376pub enum TyKind {
2377 Slice(P<Ty>),
2379 Array(P<Ty>, AnonConst),
2381 Ptr(MutTy),
2383 Ref(Option<Lifetime>, MutTy),
2385 PinnedRef(Option<Lifetime>, MutTy),
2389 BareFn(P<BareFnTy>),
2391 UnsafeBinder(P<UnsafeBinderTy>),
2393 Never,
2395 Tup(ThinVec<P<Ty>>),
2397 Path(Option<P<QSelf>>, Path),
2402 TraitObject(GenericBounds, TraitObjectSyntax),
2405 ImplTrait(NodeId, GenericBounds),
2412 Paren(P<Ty>),
2414 Typeof(AnonConst),
2416 Infer,
2419 ImplicitSelf,
2421 MacCall(P<MacCall>),
2423 CVarArgs,
2425 Pat(P<Ty>, P<TyPat>),
2428 Dummy,
2430 Err(ErrorGuaranteed),
2432}
2433
2434impl TyKind {
2435 pub fn is_implicit_self(&self) -> bool {
2436 matches!(self, TyKind::ImplicitSelf)
2437 }
2438
2439 pub fn is_unit(&self) -> bool {
2440 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2441 }
2442
2443 pub fn is_simple_path(&self) -> Option<Symbol> {
2444 if let TyKind::Path(None, Path { segments, .. }) = &self
2445 && let [segment] = &segments[..]
2446 && segment.args.is_none()
2447 {
2448 Some(segment.ident.name)
2449 } else {
2450 None
2451 }
2452 }
2453}
2454
2455#[derive(Clone, Encodable, Decodable, Debug)]
2457pub struct TyPat {
2458 pub id: NodeId,
2459 pub kind: TyPatKind,
2460 pub span: Span,
2461 pub tokens: Option<LazyAttrTokenStream>,
2462}
2463
2464#[derive(Clone, Encodable, Decodable, Debug)]
2468pub enum TyPatKind {
2469 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2471
2472 Err(ErrorGuaranteed),
2474}
2475
2476#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2478#[repr(u8)]
2479pub enum TraitObjectSyntax {
2480 Dyn = 0,
2482 DynStar = 1,
2483 None = 2,
2484}
2485
2486unsafe impl Tag for TraitObjectSyntax {
2490 const BITS: u32 = 2;
2491
2492 fn into_usize(self) -> usize {
2493 self as u8 as usize
2494 }
2495
2496 unsafe fn from_usize(tag: usize) -> Self {
2497 match tag {
2498 0 => TraitObjectSyntax::Dyn,
2499 1 => TraitObjectSyntax::DynStar,
2500 2 => TraitObjectSyntax::None,
2501 _ => unreachable!(),
2502 }
2503 }
2504}
2505
2506#[derive(Clone, Encodable, Decodable, Debug)]
2507pub enum PreciseCapturingArg {
2508 Lifetime(Lifetime),
2510 Arg(Path, NodeId),
2512}
2513
2514#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2518pub enum InlineAsmRegOrRegClass {
2519 Reg(Symbol),
2520 RegClass(Symbol),
2521}
2522
2523#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2524pub struct InlineAsmOptions(u16);
2525bitflags::bitflags! {
2526 impl InlineAsmOptions: u16 {
2527 const PURE = 1 << 0;
2528 const NOMEM = 1 << 1;
2529 const READONLY = 1 << 2;
2530 const PRESERVES_FLAGS = 1 << 3;
2531 const NORETURN = 1 << 4;
2532 const NOSTACK = 1 << 5;
2533 const ATT_SYNTAX = 1 << 6;
2534 const RAW = 1 << 7;
2535 const MAY_UNWIND = 1 << 8;
2536 }
2537}
2538
2539impl InlineAsmOptions {
2540 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2541
2542 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2543 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2544
2545 pub fn human_readable_names(&self) -> Vec<&'static str> {
2546 let mut options = vec![];
2547
2548 if self.contains(InlineAsmOptions::PURE) {
2549 options.push("pure");
2550 }
2551 if self.contains(InlineAsmOptions::NOMEM) {
2552 options.push("nomem");
2553 }
2554 if self.contains(InlineAsmOptions::READONLY) {
2555 options.push("readonly");
2556 }
2557 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2558 options.push("preserves_flags");
2559 }
2560 if self.contains(InlineAsmOptions::NORETURN) {
2561 options.push("noreturn");
2562 }
2563 if self.contains(InlineAsmOptions::NOSTACK) {
2564 options.push("nostack");
2565 }
2566 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2567 options.push("att_syntax");
2568 }
2569 if self.contains(InlineAsmOptions::RAW) {
2570 options.push("raw");
2571 }
2572 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2573 options.push("may_unwind");
2574 }
2575
2576 options
2577 }
2578}
2579
2580impl std::fmt::Debug for InlineAsmOptions {
2581 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2582 bitflags::parser::to_writer(self, f)
2583 }
2584}
2585
2586#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2587pub enum InlineAsmTemplatePiece {
2588 String(Cow<'static, str>),
2589 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2590}
2591
2592impl fmt::Display for InlineAsmTemplatePiece {
2593 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2594 match self {
2595 Self::String(s) => {
2596 for c in s.chars() {
2597 match c {
2598 '{' => f.write_str("{{")?,
2599 '}' => f.write_str("}}")?,
2600 _ => c.fmt(f)?,
2601 }
2602 }
2603 Ok(())
2604 }
2605 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2606 write!(f, "{{{operand_idx}:{modifier}}}")
2607 }
2608 Self::Placeholder { operand_idx, modifier: None, .. } => {
2609 write!(f, "{{{operand_idx}}}")
2610 }
2611 }
2612 }
2613}
2614
2615impl InlineAsmTemplatePiece {
2616 pub fn to_string(s: &[Self]) -> String {
2618 use fmt::Write;
2619 let mut out = String::new();
2620 for p in s.iter() {
2621 let _ = write!(out, "{p}");
2622 }
2623 out
2624 }
2625}
2626
2627#[derive(Clone, Encodable, Decodable, Debug)]
2635pub struct InlineAsmSym {
2636 pub id: NodeId,
2637 pub qself: Option<P<QSelf>>,
2638 pub path: Path,
2639}
2640
2641#[derive(Clone, Encodable, Decodable, Debug)]
2645pub enum InlineAsmOperand {
2646 In {
2647 reg: InlineAsmRegOrRegClass,
2648 expr: P<Expr>,
2649 },
2650 Out {
2651 reg: InlineAsmRegOrRegClass,
2652 late: bool,
2653 expr: Option<P<Expr>>,
2654 },
2655 InOut {
2656 reg: InlineAsmRegOrRegClass,
2657 late: bool,
2658 expr: P<Expr>,
2659 },
2660 SplitInOut {
2661 reg: InlineAsmRegOrRegClass,
2662 late: bool,
2663 in_expr: P<Expr>,
2664 out_expr: Option<P<Expr>>,
2665 },
2666 Const {
2667 anon_const: AnonConst,
2668 },
2669 Sym {
2670 sym: InlineAsmSym,
2671 },
2672 Label {
2673 block: P<Block>,
2674 },
2675}
2676
2677impl InlineAsmOperand {
2678 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2679 match self {
2680 Self::In { reg, .. }
2681 | Self::Out { reg, .. }
2682 | Self::InOut { reg, .. }
2683 | Self::SplitInOut { reg, .. } => Some(reg),
2684 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2685 }
2686 }
2687}
2688
2689#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2690pub enum AsmMacro {
2691 Asm,
2693 GlobalAsm,
2695 NakedAsm,
2697}
2698
2699impl AsmMacro {
2700 pub const fn macro_name(self) -> &'static str {
2701 match self {
2702 AsmMacro::Asm => "asm",
2703 AsmMacro::GlobalAsm => "global_asm",
2704 AsmMacro::NakedAsm => "naked_asm",
2705 }
2706 }
2707
2708 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2709 match self {
2710 AsmMacro::Asm => true,
2711 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2712 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2713 }
2714 }
2715
2716 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2717 match self {
2718 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2719 AsmMacro::GlobalAsm => true,
2720 AsmMacro::NakedAsm => true,
2721 }
2722 }
2723}
2724
2725#[derive(Clone, Encodable, Decodable, Debug)]
2729pub struct InlineAsm {
2730 pub asm_macro: AsmMacro,
2731 pub template: Vec<InlineAsmTemplatePiece>,
2732 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2733 pub operands: Vec<(InlineAsmOperand, Span)>,
2734 pub clobber_abis: Vec<(Symbol, Span)>,
2735 pub options: InlineAsmOptions,
2736 pub line_spans: Vec<Span>,
2737}
2738
2739#[derive(Clone, Encodable, Decodable, Debug)]
2743pub struct Param {
2744 pub attrs: AttrVec,
2745 pub ty: P<Ty>,
2746 pub pat: P<Pat>,
2747 pub id: NodeId,
2748 pub span: Span,
2749 pub is_placeholder: bool,
2750}
2751
2752#[derive(Clone, Encodable, Decodable, Debug)]
2756pub enum SelfKind {
2757 Value(Mutability),
2759 Region(Option<Lifetime>, Mutability),
2761 Pinned(Option<Lifetime>, Mutability),
2763 Explicit(P<Ty>, Mutability),
2765}
2766
2767impl SelfKind {
2768 pub fn to_ref_suggestion(&self) -> String {
2769 match self {
2770 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2771 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2772 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2773 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2774 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2775 unreachable!("if we had an explicit self, we wouldn't be here")
2776 }
2777 }
2778 }
2779}
2780
2781pub type ExplicitSelf = Spanned<SelfKind>;
2782
2783impl Param {
2784 pub fn to_self(&self) -> Option<ExplicitSelf> {
2786 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2787 if ident.name == kw::SelfLower {
2788 return match self.ty.kind {
2789 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2790 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2791 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2792 }
2793 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2794 if ty.kind.is_implicit_self() =>
2795 {
2796 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2797 }
2798 _ => Some(respan(
2799 self.pat.span.to(self.ty.span),
2800 SelfKind::Explicit(self.ty.clone(), mutbl),
2801 )),
2802 };
2803 }
2804 }
2805 None
2806 }
2807
2808 pub fn is_self(&self) -> bool {
2810 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2811 ident.name == kw::SelfLower
2812 } else {
2813 false
2814 }
2815 }
2816
2817 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2819 let span = eself.span.to(eself_ident.span);
2820 let infer_ty = P(Ty {
2821 id: DUMMY_NODE_ID,
2822 kind: TyKind::ImplicitSelf,
2823 span: eself_ident.span,
2824 tokens: None,
2825 });
2826 let (mutbl, ty) = match eself.node {
2827 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2828 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2829 SelfKind::Region(lt, mutbl) => (
2830 Mutability::Not,
2831 P(Ty {
2832 id: DUMMY_NODE_ID,
2833 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2834 span,
2835 tokens: None,
2836 }),
2837 ),
2838 SelfKind::Pinned(lt, mutbl) => (
2839 mutbl,
2840 P(Ty {
2841 id: DUMMY_NODE_ID,
2842 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2843 span,
2844 tokens: None,
2845 }),
2846 ),
2847 };
2848 Param {
2849 attrs,
2850 pat: P(Pat {
2851 id: DUMMY_NODE_ID,
2852 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2853 span,
2854 tokens: None,
2855 }),
2856 span,
2857 ty,
2858 id: DUMMY_NODE_ID,
2859 is_placeholder: false,
2860 }
2861 }
2862}
2863
2864#[derive(Clone, Encodable, Decodable, Debug)]
2871pub struct FnDecl {
2872 pub inputs: ThinVec<Param>,
2873 pub output: FnRetTy,
2874}
2875
2876impl FnDecl {
2877 pub fn has_self(&self) -> bool {
2878 self.inputs.get(0).is_some_and(Param::is_self)
2879 }
2880 pub fn c_variadic(&self) -> bool {
2881 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2882 }
2883}
2884
2885#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2887pub enum IsAuto {
2888 Yes,
2889 No,
2890}
2891
2892#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2894#[derive(HashStable_Generic)]
2895pub enum Safety {
2896 Unsafe(Span),
2898 Safe(Span),
2900 Default,
2903}
2904
2905#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2911pub enum CoroutineKind {
2912 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2914 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2916 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2918}
2919
2920impl CoroutineKind {
2921 pub fn span(self) -> Span {
2922 match self {
2923 CoroutineKind::Async { span, .. } => span,
2924 CoroutineKind::Gen { span, .. } => span,
2925 CoroutineKind::AsyncGen { span, .. } => span,
2926 }
2927 }
2928
2929 pub fn as_str(self) -> &'static str {
2930 match self {
2931 CoroutineKind::Async { .. } => "async",
2932 CoroutineKind::Gen { .. } => "gen",
2933 CoroutineKind::AsyncGen { .. } => "async gen",
2934 }
2935 }
2936
2937 pub fn closure_id(self) -> NodeId {
2938 match self {
2939 CoroutineKind::Async { closure_id, .. }
2940 | CoroutineKind::Gen { closure_id, .. }
2941 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2942 }
2943 }
2944
2945 pub fn return_id(self) -> (NodeId, Span) {
2948 match self {
2949 CoroutineKind::Async { return_impl_trait_id, span, .. }
2950 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2951 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2952 (return_impl_trait_id, span)
2953 }
2954 }
2955 }
2956}
2957
2958#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2959#[derive(HashStable_Generic)]
2960pub enum Const {
2961 Yes(Span),
2962 No,
2963}
2964
2965#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2968pub enum Defaultness {
2969 Default(Span),
2970 Final,
2971}
2972
2973#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2974pub enum ImplPolarity {
2975 Positive,
2977 Negative(Span),
2979}
2980
2981impl fmt::Debug for ImplPolarity {
2982 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2983 match *self {
2984 ImplPolarity::Positive => "positive".fmt(f),
2985 ImplPolarity::Negative(_) => "negative".fmt(f),
2986 }
2987 }
2988}
2989
2990#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2992#[derive(HashStable_Generic)]
2993pub enum BoundPolarity {
2994 Positive,
2996 Negative(Span),
2998 Maybe(Span),
3000}
3001
3002impl BoundPolarity {
3003 pub fn as_str(self) -> &'static str {
3004 match self {
3005 Self::Positive => "",
3006 Self::Negative(_) => "!",
3007 Self::Maybe(_) => "?",
3008 }
3009 }
3010}
3011
3012#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3014#[derive(HashStable_Generic)]
3015pub enum BoundConstness {
3016 Never,
3018 Always(Span),
3020 Maybe(Span),
3022}
3023
3024impl BoundConstness {
3025 pub fn as_str(self) -> &'static str {
3026 match self {
3027 Self::Never => "",
3028 Self::Always(_) => "const",
3029 Self::Maybe(_) => "~const",
3030 }
3031 }
3032}
3033
3034#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3036#[derive(HashStable_Generic)]
3037pub enum BoundAsyncness {
3038 Normal,
3040 Async(Span),
3042}
3043
3044impl BoundAsyncness {
3045 pub fn as_str(self) -> &'static str {
3046 match self {
3047 Self::Normal => "",
3048 Self::Async(_) => "async",
3049 }
3050 }
3051}
3052
3053#[derive(Clone, Encodable, Decodable, Debug)]
3054pub enum FnRetTy {
3055 Default(Span),
3060 Ty(P<Ty>),
3062}
3063
3064impl FnRetTy {
3065 pub fn span(&self) -> Span {
3066 match self {
3067 &FnRetTy::Default(span) => span,
3068 FnRetTy::Ty(ty) => ty.span,
3069 }
3070 }
3071}
3072
3073#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3074pub enum Inline {
3075 Yes,
3076 No,
3077}
3078
3079#[derive(Clone, Encodable, Decodable, Debug)]
3081pub enum ModKind {
3082 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3087 Unloaded,
3089}
3090
3091#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3092pub struct ModSpans {
3093 pub inner_span: Span,
3096 pub inject_use_span: Span,
3097}
3098
3099#[derive(Clone, Encodable, Decodable, Debug)]
3103pub struct ForeignMod {
3104 pub extern_span: Span,
3106 pub safety: Safety,
3109 pub abi: Option<StrLit>,
3110 pub items: ThinVec<P<ForeignItem>>,
3111}
3112
3113#[derive(Clone, Encodable, Decodable, Debug)]
3114pub struct EnumDef {
3115 pub variants: ThinVec<Variant>,
3116}
3117#[derive(Clone, Encodable, Decodable, Debug)]
3119pub struct Variant {
3120 pub attrs: AttrVec,
3122 pub id: NodeId,
3124 pub span: Span,
3126 pub vis: Visibility,
3128 pub ident: Ident,
3130
3131 pub data: VariantData,
3133 pub disr_expr: Option<AnonConst>,
3135 pub is_placeholder: bool,
3137}
3138
3139#[derive(Clone, Encodable, Decodable, Debug)]
3141pub enum UseTreeKind {
3142 Simple(Option<Ident>),
3144 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3153 Glob,
3155}
3156
3157#[derive(Clone, Encodable, Decodable, Debug)]
3160pub struct UseTree {
3161 pub prefix: Path,
3162 pub kind: UseTreeKind,
3163 pub span: Span,
3164}
3165
3166impl UseTree {
3167 pub fn ident(&self) -> Ident {
3168 match self.kind {
3169 UseTreeKind::Simple(Some(rename)) => rename,
3170 UseTreeKind::Simple(None) => {
3171 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3172 }
3173 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3174 }
3175 }
3176}
3177
3178#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3182pub enum AttrStyle {
3183 Outer,
3184 Inner,
3185}
3186
3187pub type AttrVec = ThinVec<Attribute>;
3189
3190#[derive(Clone, Encodable, Decodable, Debug)]
3192pub struct Attribute {
3193 pub kind: AttrKind,
3194 pub id: AttrId,
3195 pub style: AttrStyle,
3198 pub span: Span,
3199}
3200
3201#[derive(Clone, Encodable, Decodable, Debug)]
3202pub enum AttrKind {
3203 Normal(P<NormalAttr>),
3205
3206 DocComment(CommentKind, Symbol),
3210}
3211
3212#[derive(Clone, Encodable, Decodable, Debug)]
3213pub struct NormalAttr {
3214 pub item: AttrItem,
3215 pub tokens: Option<LazyAttrTokenStream>,
3217}
3218
3219impl NormalAttr {
3220 pub fn from_ident(ident: Ident) -> Self {
3221 Self {
3222 item: AttrItem {
3223 unsafety: Safety::Default,
3224 path: Path::from_ident(ident),
3225 args: AttrArgs::Empty,
3226 tokens: None,
3227 },
3228 tokens: None,
3229 }
3230 }
3231}
3232
3233#[derive(Clone, Encodable, Decodable, Debug)]
3234pub struct AttrItem {
3235 pub unsafety: Safety,
3236 pub path: Path,
3237 pub args: AttrArgs,
3238 pub tokens: Option<LazyAttrTokenStream>,
3240}
3241
3242impl AttrItem {
3243 pub fn is_valid_for_outer_style(&self) -> bool {
3244 self.path == sym::cfg_attr
3245 || self.path == sym::cfg
3246 || self.path == sym::forbid
3247 || self.path == sym::warn
3248 || self.path == sym::allow
3249 || self.path == sym::deny
3250 }
3251}
3252
3253#[derive(Clone, Encodable, Decodable, Debug)]
3260pub struct TraitRef {
3261 pub path: Path,
3262 pub ref_id: NodeId,
3263}
3264
3265#[derive(Clone, Encodable, Decodable, Debug)]
3266pub struct PolyTraitRef {
3267 pub bound_generic_params: ThinVec<GenericParam>,
3269
3270 pub modifiers: TraitBoundModifiers,
3272
3273 pub trait_ref: TraitRef,
3275
3276 pub span: Span,
3277}
3278
3279impl PolyTraitRef {
3280 pub fn new(
3281 generic_params: ThinVec<GenericParam>,
3282 path: Path,
3283 modifiers: TraitBoundModifiers,
3284 span: Span,
3285 ) -> Self {
3286 PolyTraitRef {
3287 bound_generic_params: generic_params,
3288 modifiers,
3289 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3290 span,
3291 }
3292 }
3293}
3294
3295#[derive(Clone, Encodable, Decodable, Debug)]
3296pub struct Visibility {
3297 pub kind: VisibilityKind,
3298 pub span: Span,
3299 pub tokens: Option<LazyAttrTokenStream>,
3300}
3301
3302#[derive(Clone, Encodable, Decodable, Debug)]
3303pub enum VisibilityKind {
3304 Public,
3305 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3306 Inherited,
3307}
3308
3309impl VisibilityKind {
3310 pub fn is_pub(&self) -> bool {
3311 matches!(self, VisibilityKind::Public)
3312 }
3313}
3314
3315#[derive(Clone, Encodable, Decodable, Debug)]
3319pub struct FieldDef {
3320 pub attrs: AttrVec,
3321 pub id: NodeId,
3322 pub span: Span,
3323 pub vis: Visibility,
3324 pub safety: Safety,
3325 pub ident: Option<Ident>,
3326
3327 pub ty: P<Ty>,
3328 pub default: Option<AnonConst>,
3329 pub is_placeholder: bool,
3330}
3331
3332#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3334pub enum Recovered {
3335 No,
3336 Yes(ErrorGuaranteed),
3337}
3338
3339#[derive(Clone, Encodable, Decodable, Debug)]
3341pub enum VariantData {
3342 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3346 Tuple(ThinVec<FieldDef>, NodeId),
3350 Unit(NodeId),
3354}
3355
3356impl VariantData {
3357 pub fn fields(&self) -> &[FieldDef] {
3359 match self {
3360 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3361 _ => &[],
3362 }
3363 }
3364
3365 pub fn ctor_node_id(&self) -> Option<NodeId> {
3367 match *self {
3368 VariantData::Struct { .. } => None,
3369 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3370 }
3371 }
3372}
3373
3374#[derive(Clone, Encodable, Decodable, Debug)]
3376pub struct Item<K = ItemKind> {
3377 pub attrs: AttrVec,
3378 pub id: NodeId,
3379 pub span: Span,
3380 pub vis: Visibility,
3381
3382 pub kind: K,
3383
3384 pub tokens: Option<LazyAttrTokenStream>,
3392}
3393
3394impl Item {
3395 pub fn span_with_attributes(&self) -> Span {
3397 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3398 }
3399
3400 pub fn opt_generics(&self) -> Option<&Generics> {
3401 match &self.kind {
3402 ItemKind::ExternCrate(..)
3403 | ItemKind::Use(_)
3404 | ItemKind::Mod(..)
3405 | ItemKind::ForeignMod(_)
3406 | ItemKind::GlobalAsm(_)
3407 | ItemKind::MacCall(_)
3408 | ItemKind::Delegation(_)
3409 | ItemKind::DelegationMac(_)
3410 | ItemKind::MacroDef(..) => None,
3411 ItemKind::Static(_) => None,
3412 ItemKind::Const(i) => Some(&i.generics),
3413 ItemKind::Fn(i) => Some(&i.generics),
3414 ItemKind::TyAlias(i) => Some(&i.generics),
3415 ItemKind::TraitAlias(_, generics, _)
3416 | ItemKind::Enum(_, _, generics)
3417 | ItemKind::Struct(_, _, generics)
3418 | ItemKind::Union(_, _, generics) => Some(&generics),
3419 ItemKind::Trait(i) => Some(&i.generics),
3420 ItemKind::Impl(i) => Some(&i.generics),
3421 }
3422 }
3423}
3424
3425#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3427pub enum Extern {
3428 None,
3432 Implicit(Span),
3438 Explicit(StrLit, Span),
3442}
3443
3444impl Extern {
3445 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3446 match abi {
3447 Some(name) => Extern::Explicit(name, span),
3448 None => Extern::Implicit(span),
3449 }
3450 }
3451}
3452
3453#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3458pub struct FnHeader {
3459 pub safety: Safety,
3461 pub coroutine_kind: Option<CoroutineKind>,
3463 pub constness: Const,
3465 pub ext: Extern,
3467}
3468
3469impl FnHeader {
3470 pub fn has_qualifiers(&self) -> bool {
3472 let Self { safety, coroutine_kind, constness, ext } = self;
3473 matches!(safety, Safety::Unsafe(_))
3474 || coroutine_kind.is_some()
3475 || matches!(constness, Const::Yes(_))
3476 || !matches!(ext, Extern::None)
3477 }
3478}
3479
3480impl Default for FnHeader {
3481 fn default() -> FnHeader {
3482 FnHeader {
3483 safety: Safety::Default,
3484 coroutine_kind: None,
3485 constness: Const::No,
3486 ext: Extern::None,
3487 }
3488 }
3489}
3490
3491#[derive(Clone, Encodable, Decodable, Debug)]
3492pub struct Trait {
3493 pub safety: Safety,
3494 pub is_auto: IsAuto,
3495 pub ident: Ident,
3496 pub generics: Generics,
3497 pub bounds: GenericBounds,
3498 pub items: ThinVec<P<AssocItem>>,
3499}
3500
3501#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3520pub struct TyAliasWhereClause {
3521 pub has_where_token: bool,
3522 pub span: Span,
3523}
3524
3525#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3527pub struct TyAliasWhereClauses {
3528 pub before: TyAliasWhereClause,
3530 pub after: TyAliasWhereClause,
3532 pub split: usize,
3536}
3537
3538#[derive(Clone, Encodable, Decodable, Debug)]
3539pub struct TyAlias {
3540 pub defaultness: Defaultness,
3541 pub ident: Ident,
3542 pub generics: Generics,
3543 pub where_clauses: TyAliasWhereClauses,
3544 pub bounds: GenericBounds,
3545 pub ty: Option<P<Ty>>,
3546}
3547
3548#[derive(Clone, Encodable, Decodable, Debug)]
3549pub struct Impl {
3550 pub defaultness: Defaultness,
3551 pub safety: Safety,
3552 pub generics: Generics,
3553 pub constness: Const,
3554 pub polarity: ImplPolarity,
3555 pub of_trait: Option<TraitRef>,
3557 pub self_ty: P<Ty>,
3558 pub items: ThinVec<P<AssocItem>>,
3559}
3560
3561#[derive(Clone, Encodable, Decodable, Debug, Default)]
3562pub struct FnContract {
3563 pub requires: Option<P<Expr>>,
3564 pub ensures: Option<P<Expr>>,
3565}
3566
3567#[derive(Clone, Encodable, Decodable, Debug)]
3568pub struct Fn {
3569 pub defaultness: Defaultness,
3570 pub ident: Ident,
3571 pub generics: Generics,
3572 pub sig: FnSig,
3573 pub contract: Option<P<FnContract>>,
3574 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3575 pub body: Option<P<Block>>,
3576}
3577
3578#[derive(Clone, Encodable, Decodable, Debug)]
3579pub struct Delegation {
3580 pub id: NodeId,
3582 pub qself: Option<P<QSelf>>,
3583 pub path: Path,
3584 pub ident: Ident,
3585 pub rename: Option<Ident>,
3586 pub body: Option<P<Block>>,
3587 pub from_glob: bool,
3589}
3590
3591#[derive(Clone, Encodable, Decodable, Debug)]
3592pub struct DelegationMac {
3593 pub qself: Option<P<QSelf>>,
3594 pub prefix: Path,
3595 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3597 pub body: Option<P<Block>>,
3598}
3599
3600#[derive(Clone, Encodable, Decodable, Debug)]
3601pub struct StaticItem {
3602 pub ident: Ident,
3603 pub ty: P<Ty>,
3604 pub safety: Safety,
3605 pub mutability: Mutability,
3606 pub expr: Option<P<Expr>>,
3607 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3608}
3609
3610#[derive(Clone, Encodable, Decodable, Debug)]
3611pub struct ConstItem {
3612 pub defaultness: Defaultness,
3613 pub ident: Ident,
3614 pub generics: Generics,
3615 pub ty: P<Ty>,
3616 pub expr: Option<P<Expr>>,
3617 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3618}
3619
3620#[derive(Clone, Encodable, Decodable, Debug)]
3622pub enum ItemKind {
3623 ExternCrate(Option<Symbol>, Ident),
3627 Use(UseTree),
3631 Static(Box<StaticItem>),
3635 Const(Box<ConstItem>),
3639 Fn(Box<Fn>),
3643 Mod(Safety, Ident, ModKind),
3649 ForeignMod(ForeignMod),
3653 GlobalAsm(Box<InlineAsm>),
3655 TyAlias(Box<TyAlias>),
3659 Enum(Ident, EnumDef, Generics),
3663 Struct(Ident, VariantData, Generics),
3667 Union(Ident, VariantData, Generics),
3671 Trait(Box<Trait>),
3675 TraitAlias(Ident, Generics, GenericBounds),
3679 Impl(Box<Impl>),
3683 MacCall(P<MacCall>),
3687
3688 MacroDef(Ident, MacroDef),
3690
3691 Delegation(Box<Delegation>),
3695 DelegationMac(Box<DelegationMac>),
3698}
3699
3700impl ItemKind {
3701 pub fn ident(&self) -> Option<Ident> {
3702 match *self {
3703 ItemKind::ExternCrate(_, ident)
3704 | ItemKind::Static(box StaticItem { ident, .. })
3705 | ItemKind::Const(box ConstItem { ident, .. })
3706 | ItemKind::Fn(box Fn { ident, .. })
3707 | ItemKind::Mod(_, ident, _)
3708 | ItemKind::TyAlias(box TyAlias { ident, .. })
3709 | ItemKind::Enum(ident, ..)
3710 | ItemKind::Struct(ident, ..)
3711 | ItemKind::Union(ident, ..)
3712 | ItemKind::Trait(box Trait { ident, .. })
3713 | ItemKind::TraitAlias(ident, ..)
3714 | ItemKind::MacroDef(ident, _)
3715 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3716
3717 ItemKind::Use(_)
3718 | ItemKind::ForeignMod(_)
3719 | ItemKind::GlobalAsm(_)
3720 | ItemKind::Impl(_)
3721 | ItemKind::MacCall(_)
3722 | ItemKind::DelegationMac(_) => None,
3723 }
3724 }
3725
3726 pub fn article(&self) -> &'static str {
3728 use ItemKind::*;
3729 match self {
3730 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3731 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3732 | Delegation(..) | DelegationMac(..) => "a",
3733 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3734 }
3735 }
3736
3737 pub fn descr(&self) -> &'static str {
3738 match self {
3739 ItemKind::ExternCrate(..) => "extern crate",
3740 ItemKind::Use(..) => "`use` import",
3741 ItemKind::Static(..) => "static item",
3742 ItemKind::Const(..) => "constant item",
3743 ItemKind::Fn(..) => "function",
3744 ItemKind::Mod(..) => "module",
3745 ItemKind::ForeignMod(..) => "extern block",
3746 ItemKind::GlobalAsm(..) => "global asm item",
3747 ItemKind::TyAlias(..) => "type alias",
3748 ItemKind::Enum(..) => "enum",
3749 ItemKind::Struct(..) => "struct",
3750 ItemKind::Union(..) => "union",
3751 ItemKind::Trait(..) => "trait",
3752 ItemKind::TraitAlias(..) => "trait alias",
3753 ItemKind::MacCall(..) => "item macro invocation",
3754 ItemKind::MacroDef(..) => "macro definition",
3755 ItemKind::Impl { .. } => "implementation",
3756 ItemKind::Delegation(..) => "delegated function",
3757 ItemKind::DelegationMac(..) => "delegation",
3758 }
3759 }
3760
3761 pub fn generics(&self) -> Option<&Generics> {
3762 match self {
3763 Self::Fn(box Fn { generics, .. })
3764 | Self::TyAlias(box TyAlias { generics, .. })
3765 | Self::Const(box ConstItem { generics, .. })
3766 | Self::Enum(_, _, generics)
3767 | Self::Struct(_, _, generics)
3768 | Self::Union(_, _, generics)
3769 | Self::Trait(box Trait { generics, .. })
3770 | Self::TraitAlias(_, generics, _)
3771 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3772 _ => None,
3773 }
3774 }
3775}
3776
3777pub type AssocItem = Item<AssocItemKind>;
3780
3781#[derive(Clone, Encodable, Decodable, Debug)]
3789pub enum AssocItemKind {
3790 Const(Box<ConstItem>),
3793 Fn(Box<Fn>),
3795 Type(Box<TyAlias>),
3797 MacCall(P<MacCall>),
3799 Delegation(Box<Delegation>),
3801 DelegationMac(Box<DelegationMac>),
3803}
3804
3805impl AssocItemKind {
3806 pub fn ident(&self) -> Option<Ident> {
3807 match *self {
3808 AssocItemKind::Const(box ConstItem { ident, .. })
3809 | AssocItemKind::Fn(box Fn { ident, .. })
3810 | AssocItemKind::Type(box TyAlias { ident, .. })
3811 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3812
3813 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3814 }
3815 }
3816
3817 pub fn defaultness(&self) -> Defaultness {
3818 match *self {
3819 Self::Const(box ConstItem { defaultness, .. })
3820 | Self::Fn(box Fn { defaultness, .. })
3821 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3822 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3823 Defaultness::Final
3824 }
3825 }
3826 }
3827}
3828
3829impl From<AssocItemKind> for ItemKind {
3830 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3831 match assoc_item_kind {
3832 AssocItemKind::Const(item) => ItemKind::Const(item),
3833 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3834 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3835 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3836 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3837 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3838 }
3839 }
3840}
3841
3842impl TryFrom<ItemKind> for AssocItemKind {
3843 type Error = ItemKind;
3844
3845 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3846 Ok(match item_kind {
3847 ItemKind::Const(item) => AssocItemKind::Const(item),
3848 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3849 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3850 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3851 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3852 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3853 _ => return Err(item_kind),
3854 })
3855 }
3856}
3857
3858#[derive(Clone, Encodable, Decodable, Debug)]
3860pub enum ForeignItemKind {
3861 Static(Box<StaticItem>),
3863 Fn(Box<Fn>),
3865 TyAlias(Box<TyAlias>),
3867 MacCall(P<MacCall>),
3869}
3870
3871impl ForeignItemKind {
3872 pub fn ident(&self) -> Option<Ident> {
3873 match *self {
3874 ForeignItemKind::Static(box StaticItem { ident, .. })
3875 | ForeignItemKind::Fn(box Fn { ident, .. })
3876 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3877
3878 ForeignItemKind::MacCall(_) => None,
3879 }
3880 }
3881}
3882
3883impl From<ForeignItemKind> for ItemKind {
3884 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3885 match foreign_item_kind {
3886 ForeignItemKind::Static(box static_foreign_item) => {
3887 ItemKind::Static(Box::new(static_foreign_item))
3888 }
3889 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3890 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3891 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3892 }
3893 }
3894}
3895
3896impl TryFrom<ItemKind> for ForeignItemKind {
3897 type Error = ItemKind;
3898
3899 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3900 Ok(match item_kind {
3901 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3902 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3903 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3904 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3905 _ => return Err(item_kind),
3906 })
3907 }
3908}
3909
3910pub type ForeignItem = Item<ForeignItemKind>;
3911
3912#[cfg(target_pointer_width = "64")]
3914mod size_asserts {
3915 use rustc_data_structures::static_assert_size;
3916
3917 use super::*;
3918 static_assert_size!(AssocItem, 80);
3920 static_assert_size!(AssocItemKind, 16);
3921 static_assert_size!(Attribute, 32);
3922 static_assert_size!(Block, 32);
3923 static_assert_size!(Expr, 72);
3924 static_assert_size!(ExprKind, 40);
3925 static_assert_size!(Fn, 184);
3926 static_assert_size!(ForeignItem, 80);
3927 static_assert_size!(ForeignItemKind, 16);
3928 static_assert_size!(GenericArg, 24);
3929 static_assert_size!(GenericBound, 88);
3930 static_assert_size!(Generics, 40);
3931 static_assert_size!(Impl, 136);
3932 static_assert_size!(Item, 144);
3933 static_assert_size!(ItemKind, 80);
3934 static_assert_size!(LitKind, 24);
3935 static_assert_size!(Local, 96);
3936 static_assert_size!(MetaItemLit, 40);
3937 static_assert_size!(Param, 40);
3938 static_assert_size!(Pat, 72);
3939 static_assert_size!(Path, 24);
3940 static_assert_size!(PathSegment, 24);
3941 static_assert_size!(PatKind, 48);
3942 static_assert_size!(Stmt, 32);
3943 static_assert_size!(StmtKind, 16);
3944 static_assert_size!(Ty, 64);
3945 static_assert_size!(TyKind, 40);
3946 }