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
311pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
312
313#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
315pub struct TraitBoundModifiers {
316 pub constness: BoundConstness,
317 pub asyncness: BoundAsyncness,
318 pub polarity: BoundPolarity,
319}
320
321impl TraitBoundModifiers {
322 pub const NONE: Self = Self {
323 constness: BoundConstness::Never,
324 asyncness: BoundAsyncness::Normal,
325 polarity: BoundPolarity::Positive,
326 };
327}
328
329#[derive(Clone, Encodable, Decodable, Debug)]
330pub enum GenericBound {
331 Trait(PolyTraitRef),
332 Outlives(Lifetime),
333 Use(ThinVec<PreciseCapturingArg>, Span),
335}
336
337impl GenericBound {
338 pub fn span(&self) -> Span {
339 match self {
340 GenericBound::Trait(t, ..) => t.span,
341 GenericBound::Outlives(l) => l.ident.span,
342 GenericBound::Use(_, span) => *span,
343 }
344 }
345}
346
347pub type GenericBounds = Vec<GenericBound>;
348
349#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
353pub enum ParamKindOrd {
354 Lifetime,
355 TypeOrConst,
356}
357
358impl fmt::Display for ParamKindOrd {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 match self {
361 ParamKindOrd::Lifetime => "lifetime".fmt(f),
362 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
363 }
364 }
365}
366
367#[derive(Clone, Encodable, Decodable, Debug)]
368pub enum GenericParamKind {
369 Lifetime,
371 Type {
372 default: Option<P<Ty>>,
373 },
374 Const {
375 ty: P<Ty>,
376 kw_span: Span,
378 default: Option<AnonConst>,
380 },
381}
382
383#[derive(Clone, Encodable, Decodable, Debug)]
384pub struct GenericParam {
385 pub id: NodeId,
386 pub ident: Ident,
387 pub attrs: AttrVec,
388 pub bounds: GenericBounds,
389 pub is_placeholder: bool,
390 pub kind: GenericParamKind,
391 pub colon_span: Option<Span>,
392}
393
394impl GenericParam {
395 pub fn span(&self) -> Span {
396 match &self.kind {
397 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
398 self.ident.span
399 }
400 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
401 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
402 kw_span.to(default.value.span)
403 }
404 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
405 }
406 }
407}
408
409#[derive(Clone, Encodable, Decodable, Debug, Default)]
412pub struct Generics {
413 pub params: ThinVec<GenericParam>,
414 pub where_clause: WhereClause,
415 pub span: Span,
416}
417
418#[derive(Clone, Encodable, Decodable, Debug, Default)]
420pub struct WhereClause {
421 pub has_where_token: bool,
426 pub predicates: ThinVec<WherePredicate>,
427 pub span: Span,
428}
429
430impl WhereClause {
431 pub fn is_empty(&self) -> bool {
432 !self.has_where_token && self.predicates.is_empty()
433 }
434}
435
436#[derive(Clone, Encodable, Decodable, Debug)]
438pub struct WherePredicate {
439 pub attrs: AttrVec,
440 pub kind: WherePredicateKind,
441 pub id: NodeId,
442 pub span: Span,
443 pub is_placeholder: bool,
444}
445
446#[derive(Clone, Encodable, Decodable, Debug)]
448pub enum WherePredicateKind {
449 BoundPredicate(WhereBoundPredicate),
451 RegionPredicate(WhereRegionPredicate),
453 EqPredicate(WhereEqPredicate),
455}
456
457#[derive(Clone, Encodable, Decodable, Debug)]
461pub struct WhereBoundPredicate {
462 pub bound_generic_params: ThinVec<GenericParam>,
464 pub bounded_ty: P<Ty>,
466 pub bounds: GenericBounds,
468}
469
470#[derive(Clone, Encodable, Decodable, Debug)]
474pub struct WhereRegionPredicate {
475 pub lifetime: Lifetime,
476 pub bounds: GenericBounds,
477}
478
479#[derive(Clone, Encodable, Decodable, Debug)]
483pub struct WhereEqPredicate {
484 pub lhs_ty: P<Ty>,
485 pub rhs_ty: P<Ty>,
486}
487
488#[derive(Clone, Encodable, Decodable, Debug)]
489pub struct Crate {
490 pub attrs: AttrVec,
491 pub items: ThinVec<P<Item>>,
492 pub spans: ModSpans,
493 pub id: NodeId,
496 pub is_placeholder: bool,
497}
498
499#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
506pub struct MetaItem {
507 pub unsafety: Safety,
508 pub path: Path,
509 pub kind: MetaItemKind,
510 pub span: Span,
511}
512
513#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
515pub enum MetaItemKind {
516 Word,
520
521 List(ThinVec<MetaItemInner>),
525
526 NameValue(MetaItemLit),
530}
531
532#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
536pub enum MetaItemInner {
537 MetaItem(MetaItem),
539
540 Lit(MetaItemLit),
544}
545
546#[derive(Clone, Encodable, Decodable, Debug)]
550pub struct Block {
551 pub stmts: ThinVec<Stmt>,
553 pub id: NodeId,
554 pub rules: BlockCheckMode,
556 pub span: Span,
557 pub tokens: Option<LazyAttrTokenStream>,
558}
559
560#[derive(Clone, Encodable, Decodable, Debug)]
564pub struct Pat {
565 pub id: NodeId,
566 pub kind: PatKind,
567 pub span: Span,
568 pub tokens: Option<LazyAttrTokenStream>,
569}
570
571impl Pat {
572 pub fn to_ty(&self) -> Option<P<Ty>> {
575 let kind = match &self.kind {
576 PatKind::Missing => unreachable!(),
577 PatKind::Wild => TyKind::Infer,
579 PatKind::Ident(BindingMode::NONE, ident, None) => {
581 TyKind::Path(None, Path::from_ident(*ident))
582 }
583 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
584 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
585 PatKind::Ref(pat, mutbl) => {
587 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
588 }
589 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
592 pat.to_ty().map(TyKind::Slice)?
593 }
594 PatKind::Tuple(pats) => {
597 let mut tys = ThinVec::with_capacity(pats.len());
598 for pat in pats {
600 tys.push(pat.to_ty()?);
601 }
602 TyKind::Tup(tys)
603 }
604 _ => return None,
605 };
606
607 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
608 }
609
610 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
614 if !it(self) {
615 return;
616 }
617
618 match &self.kind {
619 PatKind::Ident(_, _, Some(p)) => p.walk(it),
621
622 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
624
625 PatKind::TupleStruct(_, _, s)
627 | PatKind::Tuple(s)
628 | PatKind::Slice(s)
629 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
630
631 PatKind::Box(s)
633 | PatKind::Deref(s)
634 | PatKind::Ref(s, _)
635 | PatKind::Paren(s)
636 | PatKind::Guard(s, _) => s.walk(it),
637
638 PatKind::Missing
640 | PatKind::Wild
641 | PatKind::Rest
642 | PatKind::Never
643 | PatKind::Expr(_)
644 | PatKind::Range(..)
645 | PatKind::Ident(..)
646 | PatKind::Path(..)
647 | PatKind::MacCall(_)
648 | PatKind::Err(_) => {}
649 }
650 }
651
652 pub fn is_rest(&self) -> bool {
654 matches!(self.kind, PatKind::Rest)
655 }
656
657 pub fn could_be_never_pattern(&self) -> bool {
660 let mut could_be_never_pattern = false;
661 self.walk(&mut |pat| match &pat.kind {
662 PatKind::Never | PatKind::MacCall(_) => {
663 could_be_never_pattern = true;
664 false
665 }
666 PatKind::Or(s) => {
667 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
668 false
669 }
670 _ => true,
671 });
672 could_be_never_pattern
673 }
674
675 pub fn contains_never_pattern(&self) -> bool {
678 let mut contains_never_pattern = false;
679 self.walk(&mut |pat| {
680 if matches!(pat.kind, PatKind::Never) {
681 contains_never_pattern = true;
682 }
683 true
684 });
685 contains_never_pattern
686 }
687
688 pub fn descr(&self) -> Option<String> {
690 match &self.kind {
691 PatKind::Missing => unreachable!(),
692 PatKind::Wild => Some("_".to_string()),
693 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
694 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
695 _ => None,
696 }
697 }
698}
699
700#[derive(Clone, Encodable, Decodable, Debug)]
706pub struct PatField {
707 pub ident: Ident,
709 pub pat: P<Pat>,
711 pub is_shorthand: bool,
712 pub attrs: AttrVec,
713 pub id: NodeId,
714 pub span: Span,
715 pub is_placeholder: bool,
716}
717
718#[derive(Clone, Copy, Debug, Eq, PartialEq)]
719#[derive(Encodable, Decodable, HashStable_Generic)]
720pub enum ByRef {
721 Yes(Mutability),
722 No,
723}
724
725impl ByRef {
726 #[must_use]
727 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
728 if let ByRef::Yes(old_mutbl) = &mut self {
729 *old_mutbl = cmp::min(*old_mutbl, mutbl);
730 }
731 self
732 }
733}
734
735#[derive(Clone, Copy, Debug, Eq, PartialEq)]
741#[derive(Encodable, Decodable, HashStable_Generic)]
742pub struct BindingMode(pub ByRef, pub Mutability);
743
744impl BindingMode {
745 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
746 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
747 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
748 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
749 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
750 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
751
752 pub fn prefix_str(self) -> &'static str {
753 match self {
754 Self::NONE => "",
755 Self::REF => "ref ",
756 Self::MUT => "mut ",
757 Self::REF_MUT => "ref mut ",
758 Self::MUT_REF => "mut ref ",
759 Self::MUT_REF_MUT => "mut ref mut ",
760 }
761 }
762}
763
764#[derive(Clone, Encodable, Decodable, Debug)]
765pub enum RangeEnd {
766 Included(RangeSyntax),
768 Excluded,
770}
771
772#[derive(Clone, Encodable, Decodable, Debug)]
773pub enum RangeSyntax {
774 DotDotDot,
776 DotDotEq,
778}
779
780#[derive(Clone, Encodable, Decodable, Debug)]
784pub enum PatKind {
785 Missing,
787
788 Wild,
790
791 Ident(BindingMode, Ident, Option<P<Pat>>),
796
797 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
799
800 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
802
803 Or(ThinVec<P<Pat>>),
806
807 Path(Option<P<QSelf>>, Path),
812
813 Tuple(ThinVec<P<Pat>>),
815
816 Box(P<Pat>),
818
819 Deref(P<Pat>),
821
822 Ref(P<Pat>, Mutability),
824
825 Expr(P<Expr>),
827
828 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
830
831 Slice(ThinVec<P<Pat>>),
833
834 Rest,
847
848 Never,
850
851 Guard(P<Pat>, P<Expr>),
853
854 Paren(P<Pat>),
856
857 MacCall(P<MacCall>),
859
860 Err(ErrorGuaranteed),
862}
863
864#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
866pub enum PatFieldsRest {
867 Rest,
869 Recovered(ErrorGuaranteed),
871 None,
873}
874
875#[derive(Clone, Copy, PartialEq, Eq, Debug)]
878#[derive(Encodable, Decodable, HashStable_Generic)]
879pub enum BorrowKind {
880 Ref,
884 Raw,
888}
889
890#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
891pub enum BinOpKind {
892 Add,
894 Sub,
896 Mul,
898 Div,
900 Rem,
902 And,
904 Or,
906 BitXor,
908 BitAnd,
910 BitOr,
912 Shl,
914 Shr,
916 Eq,
918 Lt,
920 Le,
922 Ne,
924 Ge,
926 Gt,
928}
929
930impl BinOpKind {
931 pub fn as_str(&self) -> &'static str {
932 use BinOpKind::*;
933 match self {
934 Add => "+",
935 Sub => "-",
936 Mul => "*",
937 Div => "/",
938 Rem => "%",
939 And => "&&",
940 Or => "||",
941 BitXor => "^",
942 BitAnd => "&",
943 BitOr => "|",
944 Shl => "<<",
945 Shr => ">>",
946 Eq => "==",
947 Lt => "<",
948 Le => "<=",
949 Ne => "!=",
950 Ge => ">=",
951 Gt => ">",
952 }
953 }
954
955 pub fn is_lazy(&self) -> bool {
956 matches!(self, BinOpKind::And | BinOpKind::Or)
957 }
958
959 pub fn precedence(&self) -> ExprPrecedence {
960 use BinOpKind::*;
961 match *self {
962 Mul | Div | Rem => ExprPrecedence::Product,
963 Add | Sub => ExprPrecedence::Sum,
964 Shl | Shr => ExprPrecedence::Shift,
965 BitAnd => ExprPrecedence::BitAnd,
966 BitXor => ExprPrecedence::BitXor,
967 BitOr => ExprPrecedence::BitOr,
968 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
969 And => ExprPrecedence::LAnd,
970 Or => ExprPrecedence::LOr,
971 }
972 }
973
974 pub fn fixity(&self) -> Fixity {
975 use BinOpKind::*;
976 match self {
977 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
978 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
979 Fixity::Left
980 }
981 }
982 }
983
984 pub fn is_comparison(self) -> bool {
985 use BinOpKind::*;
986 match self {
987 Eq | Ne | Lt | Le | Gt | Ge => true,
988 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
989 }
990 }
991
992 pub fn is_by_value(self) -> bool {
994 !self.is_comparison()
995 }
996}
997
998pub type BinOp = Spanned<BinOpKind>;
999
1000impl From<AssignOpKind> for BinOpKind {
1004 fn from(op: AssignOpKind) -> BinOpKind {
1005 match op {
1006 AssignOpKind::AddAssign => BinOpKind::Add,
1007 AssignOpKind::SubAssign => BinOpKind::Sub,
1008 AssignOpKind::MulAssign => BinOpKind::Mul,
1009 AssignOpKind::DivAssign => BinOpKind::Div,
1010 AssignOpKind::RemAssign => BinOpKind::Rem,
1011 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1012 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1013 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1014 AssignOpKind::ShlAssign => BinOpKind::Shl,
1015 AssignOpKind::ShrAssign => BinOpKind::Shr,
1016 }
1017 }
1018}
1019
1020#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1021pub enum AssignOpKind {
1022 AddAssign,
1024 SubAssign,
1026 MulAssign,
1028 DivAssign,
1030 RemAssign,
1032 BitXorAssign,
1034 BitAndAssign,
1036 BitOrAssign,
1038 ShlAssign,
1040 ShrAssign,
1042}
1043
1044impl AssignOpKind {
1045 pub fn as_str(&self) -> &'static str {
1046 use AssignOpKind::*;
1047 match self {
1048 AddAssign => "+=",
1049 SubAssign => "-=",
1050 MulAssign => "*=",
1051 DivAssign => "/=",
1052 RemAssign => "%=",
1053 BitXorAssign => "^=",
1054 BitAndAssign => "&=",
1055 BitOrAssign => "|=",
1056 ShlAssign => "<<=",
1057 ShrAssign => ">>=",
1058 }
1059 }
1060
1061 pub fn is_by_value(self) -> bool {
1063 true
1064 }
1065}
1066
1067pub type AssignOp = Spanned<AssignOpKind>;
1068
1069#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1073pub enum UnOp {
1074 Deref,
1076 Not,
1078 Neg,
1080}
1081
1082impl UnOp {
1083 pub fn as_str(&self) -> &'static str {
1084 match self {
1085 UnOp::Deref => "*",
1086 UnOp::Not => "!",
1087 UnOp::Neg => "-",
1088 }
1089 }
1090
1091 pub fn is_by_value(self) -> bool {
1093 matches!(self, Self::Neg | Self::Not)
1094 }
1095}
1096
1097#[derive(Clone, Encodable, Decodable, Debug)]
1101pub struct Stmt {
1102 pub id: NodeId,
1103 pub kind: StmtKind,
1104 pub span: Span,
1105}
1106
1107impl Stmt {
1108 pub fn has_trailing_semicolon(&self) -> bool {
1109 match &self.kind {
1110 StmtKind::Semi(_) => true,
1111 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1112 _ => false,
1113 }
1114 }
1115
1116 pub fn add_trailing_semicolon(mut self) -> Self {
1124 self.kind = match self.kind {
1125 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1126 StmtKind::MacCall(mac) => {
1127 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1128 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1129 }))
1130 }
1131 kind => kind,
1132 };
1133
1134 self
1135 }
1136
1137 pub fn is_item(&self) -> bool {
1138 matches!(self.kind, StmtKind::Item(_))
1139 }
1140
1141 pub fn is_expr(&self) -> bool {
1142 matches!(self.kind, StmtKind::Expr(_))
1143 }
1144}
1145
1146#[derive(Clone, Encodable, Decodable, Debug)]
1148pub enum StmtKind {
1149 Let(P<Local>),
1151 Item(P<Item>),
1153 Expr(P<Expr>),
1155 Semi(P<Expr>),
1157 Empty,
1159 MacCall(P<MacCallStmt>),
1161}
1162
1163#[derive(Clone, Encodable, Decodable, Debug)]
1164pub struct MacCallStmt {
1165 pub mac: P<MacCall>,
1166 pub style: MacStmtStyle,
1167 pub attrs: AttrVec,
1168 pub tokens: Option<LazyAttrTokenStream>,
1169}
1170
1171#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1172pub enum MacStmtStyle {
1173 Semicolon,
1176 Braces,
1178 NoBraces,
1182}
1183
1184#[derive(Clone, Encodable, Decodable, Debug)]
1186pub struct Local {
1187 pub id: NodeId,
1188 pub super_: Option<Span>,
1189 pub pat: P<Pat>,
1190 pub ty: Option<P<Ty>>,
1191 pub kind: LocalKind,
1192 pub span: Span,
1193 pub colon_sp: Option<Span>,
1194 pub attrs: AttrVec,
1195 pub tokens: Option<LazyAttrTokenStream>,
1196}
1197
1198#[derive(Clone, Encodable, Decodable, Debug)]
1199pub enum LocalKind {
1200 Decl,
1203 Init(P<Expr>),
1206 InitElse(P<Expr>, P<Block>),
1209}
1210
1211impl LocalKind {
1212 pub fn init(&self) -> Option<&Expr> {
1213 match self {
1214 Self::Decl => None,
1215 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1216 }
1217 }
1218
1219 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1220 match self {
1221 Self::Decl => None,
1222 Self::Init(init) => Some((init, None)),
1223 Self::InitElse(init, els) => Some((init, Some(els))),
1224 }
1225 }
1226}
1227
1228#[derive(Clone, Encodable, Decodable, Debug)]
1239pub struct Arm {
1240 pub attrs: AttrVec,
1241 pub pat: P<Pat>,
1243 pub guard: Option<P<Expr>>,
1245 pub body: Option<P<Expr>>,
1247 pub span: Span,
1248 pub id: NodeId,
1249 pub is_placeholder: bool,
1250}
1251
1252#[derive(Clone, Encodable, Decodable, Debug)]
1254pub struct ExprField {
1255 pub attrs: AttrVec,
1256 pub id: NodeId,
1257 pub span: Span,
1258 pub ident: Ident,
1259 pub expr: P<Expr>,
1260 pub is_shorthand: bool,
1261 pub is_placeholder: bool,
1262}
1263
1264#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1265pub enum BlockCheckMode {
1266 Default,
1267 Unsafe(UnsafeSource),
1268}
1269
1270#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1271pub enum UnsafeSource {
1272 CompilerGenerated,
1273 UserProvided,
1274}
1275
1276#[derive(Clone, Encodable, Decodable, Debug)]
1282pub struct AnonConst {
1283 pub id: NodeId,
1284 pub value: P<Expr>,
1285}
1286
1287#[derive(Clone, Encodable, Decodable, Debug)]
1289pub struct Expr {
1290 pub id: NodeId,
1291 pub kind: ExprKind,
1292 pub span: Span,
1293 pub attrs: AttrVec,
1294 pub tokens: Option<LazyAttrTokenStream>,
1295}
1296
1297impl Expr {
1298 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1312 let this = self.maybe_unwrap_block();
1313 if allow_mgca_arg {
1314 matches!(this.kind, ExprKind::Path(..))
1315 } else {
1316 if let ExprKind::Path(None, path) = &this.kind
1317 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1318 {
1319 true
1320 } else {
1321 false
1322 }
1323 }
1324 }
1325
1326 pub fn maybe_unwrap_block(&self) -> &Expr {
1328 if let ExprKind::Block(block, None) = &self.kind
1329 && let [stmt] = block.stmts.as_slice()
1330 && let StmtKind::Expr(expr) = &stmt.kind
1331 {
1332 expr
1333 } else {
1334 self
1335 }
1336 }
1337
1338 pub fn optionally_braced_mac_call(
1344 &self,
1345 already_stripped_block: bool,
1346 ) -> Option<(bool, NodeId)> {
1347 match &self.kind {
1348 ExprKind::Block(block, None)
1349 if let [stmt] = &*block.stmts
1350 && !already_stripped_block =>
1351 {
1352 match &stmt.kind {
1353 StmtKind::MacCall(_) => Some((true, stmt.id)),
1354 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1355 Some((true, expr.id))
1356 }
1357 _ => None,
1358 }
1359 }
1360 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1361 _ => None,
1362 }
1363 }
1364
1365 pub fn to_bound(&self) -> Option<GenericBound> {
1366 match &self.kind {
1367 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1368 ThinVec::new(),
1369 path.clone(),
1370 TraitBoundModifiers::NONE,
1371 self.span,
1372 ))),
1373 _ => None,
1374 }
1375 }
1376
1377 pub fn peel_parens(&self) -> &Expr {
1378 let mut expr = self;
1379 while let ExprKind::Paren(inner) = &expr.kind {
1380 expr = inner;
1381 }
1382 expr
1383 }
1384
1385 pub fn peel_parens_and_refs(&self) -> &Expr {
1386 let mut expr = self;
1387 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1388 {
1389 expr = inner;
1390 }
1391 expr
1392 }
1393
1394 pub fn to_ty(&self) -> Option<P<Ty>> {
1396 let kind = match &self.kind {
1397 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1399 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1400
1401 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1402
1403 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1404 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1405 }
1406
1407 ExprKind::Repeat(expr, expr_len) => {
1408 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1409 }
1410
1411 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1412 expr.to_ty().map(TyKind::Slice)?
1413 }
1414
1415 ExprKind::Tup(exprs) => {
1416 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1417 TyKind::Tup(tys)
1418 }
1419
1420 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1424 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1425 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1426 } else {
1427 return None;
1428 }
1429 }
1430
1431 ExprKind::Underscore => TyKind::Infer,
1432
1433 _ => return None,
1435 };
1436
1437 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1438 }
1439
1440 pub fn precedence(&self) -> ExprPrecedence {
1441 match &self.kind {
1442 ExprKind::Closure(closure) => {
1443 match closure.fn_decl.output {
1444 FnRetTy::Default(_) => ExprPrecedence::Jump,
1445 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1446 }
1447 }
1448
1449 ExprKind::Break(..)
1450 | ExprKind::Ret(..)
1451 | ExprKind::Yield(..)
1452 | ExprKind::Yeet(..)
1453 | ExprKind::Become(..) => ExprPrecedence::Jump,
1454
1455 ExprKind::Range(..) => ExprPrecedence::Range,
1460
1461 ExprKind::Binary(op, ..) => op.node.precedence(),
1463 ExprKind::Cast(..) => ExprPrecedence::Cast,
1464
1465 ExprKind::Assign(..) |
1466 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1467
1468 ExprKind::AddrOf(..)
1470 | ExprKind::Let(..)
1475 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1476
1477 ExprKind::Array(_)
1479 | ExprKind::Await(..)
1480 | ExprKind::Use(..)
1481 | ExprKind::Block(..)
1482 | ExprKind::Call(..)
1483 | ExprKind::ConstBlock(_)
1484 | ExprKind::Continue(..)
1485 | ExprKind::Field(..)
1486 | ExprKind::ForLoop { .. }
1487 | ExprKind::FormatArgs(..)
1488 | ExprKind::Gen(..)
1489 | ExprKind::If(..)
1490 | ExprKind::IncludedBytes(..)
1491 | ExprKind::Index(..)
1492 | ExprKind::InlineAsm(..)
1493 | ExprKind::Lit(_)
1494 | ExprKind::Loop(..)
1495 | ExprKind::MacCall(..)
1496 | ExprKind::Match(..)
1497 | ExprKind::MethodCall(..)
1498 | ExprKind::OffsetOf(..)
1499 | ExprKind::Paren(..)
1500 | ExprKind::Path(..)
1501 | ExprKind::Repeat(..)
1502 | ExprKind::Struct(..)
1503 | ExprKind::Try(..)
1504 | ExprKind::TryBlock(..)
1505 | ExprKind::Tup(_)
1506 | ExprKind::Type(..)
1507 | ExprKind::Underscore
1508 | ExprKind::UnsafeBinderCast(..)
1509 | ExprKind::While(..)
1510 | ExprKind::Err(_)
1511 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1512 }
1513 }
1514
1515 pub fn is_approximately_pattern(&self) -> bool {
1517 matches!(
1518 &self.peel_parens().kind,
1519 ExprKind::Array(_)
1520 | ExprKind::Call(_, _)
1521 | ExprKind::Tup(_)
1522 | ExprKind::Lit(_)
1523 | ExprKind::Range(_, _, _)
1524 | ExprKind::Underscore
1525 | ExprKind::Path(_, _)
1526 | ExprKind::Struct(_)
1527 )
1528 }
1529}
1530
1531#[derive(Clone, Encodable, Decodable, Debug)]
1532pub struct Closure {
1533 pub binder: ClosureBinder,
1534 pub capture_clause: CaptureBy,
1535 pub constness: Const,
1536 pub coroutine_kind: Option<CoroutineKind>,
1537 pub movability: Movability,
1538 pub fn_decl: P<FnDecl>,
1539 pub body: P<Expr>,
1540 pub fn_decl_span: Span,
1542 pub fn_arg_span: Span,
1544}
1545
1546#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1548pub enum RangeLimits {
1549 HalfOpen,
1551 Closed,
1553}
1554
1555impl RangeLimits {
1556 pub fn as_str(&self) -> &'static str {
1557 match self {
1558 RangeLimits::HalfOpen => "..",
1559 RangeLimits::Closed => "..=",
1560 }
1561 }
1562}
1563
1564#[derive(Clone, Encodable, Decodable, Debug)]
1566pub struct MethodCall {
1567 pub seg: PathSegment,
1569 pub receiver: P<Expr>,
1571 pub args: ThinVec<P<Expr>>,
1573 pub span: Span,
1576}
1577
1578#[derive(Clone, Encodable, Decodable, Debug)]
1579pub enum StructRest {
1580 Base(P<Expr>),
1582 Rest(Span),
1584 None,
1586}
1587
1588#[derive(Clone, Encodable, Decodable, Debug)]
1589pub struct StructExpr {
1590 pub qself: Option<P<QSelf>>,
1591 pub path: Path,
1592 pub fields: ThinVec<ExprField>,
1593 pub rest: StructRest,
1594}
1595
1596#[derive(Clone, Encodable, Decodable, Debug)]
1598pub enum ExprKind {
1599 Array(ThinVec<P<Expr>>),
1601 ConstBlock(AnonConst),
1603 Call(P<Expr>, ThinVec<P<Expr>>),
1610 MethodCall(Box<MethodCall>),
1612 Tup(ThinVec<P<Expr>>),
1614 Binary(BinOp, P<Expr>, P<Expr>),
1616 Unary(UnOp, P<Expr>),
1618 Lit(token::Lit),
1620 Cast(P<Expr>, P<Ty>),
1622 Type(P<Expr>, P<Ty>),
1627 Let(P<Pat>, P<Expr>, Span, Recovered),
1632 If(P<Expr>, P<Block>, Option<P<Expr>>),
1639 While(P<Expr>, P<Block>, Option<Label>),
1643 ForLoop {
1649 pat: P<Pat>,
1650 iter: P<Expr>,
1651 body: P<Block>,
1652 label: Option<Label>,
1653 kind: ForLoopKind,
1654 },
1655 Loop(P<Block>, Option<Label>, Span),
1659 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1661 Closure(Box<Closure>),
1663 Block(P<Block>, Option<Label>),
1665 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1671 Await(P<Expr>, Span),
1673 Use(P<Expr>, Span),
1675
1676 TryBlock(P<Block>),
1678
1679 Assign(P<Expr>, P<Expr>, Span),
1682 AssignOp(AssignOp, P<Expr>, P<Expr>),
1686 Field(P<Expr>, Ident),
1688 Index(P<Expr>, P<Expr>, Span),
1691 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1693 Underscore,
1695
1696 Path(Option<P<QSelf>>, Path),
1701
1702 AddrOf(BorrowKind, Mutability, P<Expr>),
1704 Break(Option<Label>, Option<P<Expr>>),
1706 Continue(Option<Label>),
1708 Ret(Option<P<Expr>>),
1710
1711 InlineAsm(P<InlineAsm>),
1713
1714 OffsetOf(P<Ty>, P<[Ident]>),
1719
1720 MacCall(P<MacCall>),
1722
1723 Struct(P<StructExpr>),
1727
1728 Repeat(P<Expr>, AnonConst),
1733
1734 Paren(P<Expr>),
1736
1737 Try(P<Expr>),
1739
1740 Yield(YieldKind),
1742
1743 Yeet(Option<P<Expr>>),
1746
1747 Become(P<Expr>),
1751
1752 IncludedBytes(Arc<[u8]>),
1757
1758 FormatArgs(P<FormatArgs>),
1760
1761 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1762
1763 Err(ErrorGuaranteed),
1765
1766 Dummy,
1768}
1769
1770#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1772pub enum ForLoopKind {
1773 For,
1774 ForAwait,
1775}
1776
1777#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1779pub enum GenBlockKind {
1780 Async,
1781 Gen,
1782 AsyncGen,
1783}
1784
1785impl fmt::Display for GenBlockKind {
1786 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1787 self.modifier().fmt(f)
1788 }
1789}
1790
1791impl GenBlockKind {
1792 pub fn modifier(&self) -> &'static str {
1793 match self {
1794 GenBlockKind::Async => "async",
1795 GenBlockKind::Gen => "gen",
1796 GenBlockKind::AsyncGen => "async gen",
1797 }
1798 }
1799}
1800
1801#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1803#[derive(Encodable, Decodable, HashStable_Generic)]
1804pub enum UnsafeBinderCastKind {
1805 Wrap,
1807 Unwrap,
1809}
1810
1811#[derive(Clone, Encodable, Decodable, Debug)]
1826pub struct QSelf {
1827 pub ty: P<Ty>,
1828
1829 pub path_span: Span,
1833 pub position: usize,
1834}
1835
1836#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1838pub enum CaptureBy {
1839 Value {
1841 move_kw: Span,
1843 },
1844 Ref,
1846 Use {
1852 use_kw: Span,
1854 },
1855}
1856
1857#[derive(Clone, Encodable, Decodable, Debug)]
1859pub enum ClosureBinder {
1860 NotPresent,
1862 For {
1864 span: Span,
1871
1872 generic_params: ThinVec<GenericParam>,
1879 },
1880}
1881
1882#[derive(Clone, Encodable, Decodable, Debug)]
1885pub struct MacCall {
1886 pub path: Path,
1887 pub args: P<DelimArgs>,
1888}
1889
1890impl MacCall {
1891 pub fn span(&self) -> Span {
1892 self.path.span.to(self.args.dspan.entire())
1893 }
1894}
1895
1896#[derive(Clone, Encodable, Decodable, Debug)]
1898pub enum AttrArgs {
1899 Empty,
1901 Delimited(DelimArgs),
1903 Eq {
1905 eq_span: Span,
1907 expr: P<Expr>,
1908 },
1909}
1910
1911impl AttrArgs {
1912 pub fn span(&self) -> Option<Span> {
1913 match self {
1914 AttrArgs::Empty => None,
1915 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1916 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1917 }
1918 }
1919
1920 pub fn inner_tokens(&self) -> TokenStream {
1923 match self {
1924 AttrArgs::Empty => TokenStream::default(),
1925 AttrArgs::Delimited(args) => args.tokens.clone(),
1926 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1927 }
1928 }
1929}
1930
1931#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1933pub struct DelimArgs {
1934 pub dspan: DelimSpan,
1935 pub delim: Delimiter, pub tokens: TokenStream,
1937}
1938
1939impl DelimArgs {
1940 pub fn need_semicolon(&self) -> bool {
1943 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1944 }
1945}
1946
1947#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1949pub struct MacroDef {
1950 pub body: P<DelimArgs>,
1951 pub macro_rules: bool,
1953}
1954
1955#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1956#[derive(HashStable_Generic)]
1957pub enum StrStyle {
1958 Cooked,
1960 Raw(u8),
1964}
1965
1966#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1968pub enum MatchKind {
1969 Prefix,
1971 Postfix,
1973}
1974
1975#[derive(Clone, Encodable, Decodable, Debug)]
1977pub enum YieldKind {
1978 Prefix(Option<P<Expr>>),
1980 Postfix(P<Expr>),
1982}
1983
1984impl YieldKind {
1985 pub const fn expr(&self) -> Option<&P<Expr>> {
1989 match self {
1990 YieldKind::Prefix(expr) => expr.as_ref(),
1991 YieldKind::Postfix(expr) => Some(expr),
1992 }
1993 }
1994
1995 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
1997 match self {
1998 YieldKind::Prefix(expr) => expr.as_mut(),
1999 YieldKind::Postfix(expr) => Some(expr),
2000 }
2001 }
2002
2003 pub const fn same_kind(&self, other: &Self) -> bool {
2005 match (self, other) {
2006 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2007 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2008 _ => false,
2009 }
2010 }
2011}
2012
2013#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2015pub struct MetaItemLit {
2016 pub symbol: Symbol,
2018 pub suffix: Option<Symbol>,
2020 pub kind: LitKind,
2023 pub span: Span,
2024}
2025
2026#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2028pub struct StrLit {
2029 pub symbol: Symbol,
2031 pub suffix: Option<Symbol>,
2033 pub symbol_unescaped: Symbol,
2035 pub style: StrStyle,
2036 pub span: Span,
2037}
2038
2039impl StrLit {
2040 pub fn as_token_lit(&self) -> token::Lit {
2041 let token_kind = match self.style {
2042 StrStyle::Cooked => token::Str,
2043 StrStyle::Raw(n) => token::StrRaw(n),
2044 };
2045 token::Lit::new(token_kind, self.symbol, self.suffix)
2046 }
2047}
2048
2049#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2051#[derive(HashStable_Generic)]
2052pub enum LitIntType {
2053 Signed(IntTy),
2055 Unsigned(UintTy),
2057 Unsuffixed,
2059}
2060
2061#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2063#[derive(HashStable_Generic)]
2064pub enum LitFloatType {
2065 Suffixed(FloatTy),
2067 Unsuffixed,
2069}
2070
2071#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2078pub enum LitKind {
2079 Str(Symbol, StrStyle),
2082 ByteStr(Arc<[u8]>, StrStyle),
2085 CStr(Arc<[u8]>, StrStyle),
2087 Byte(u8),
2089 Char(char),
2091 Int(Pu128, LitIntType),
2093 Float(Symbol, LitFloatType),
2097 Bool(bool),
2099 Err(ErrorGuaranteed),
2101}
2102
2103impl LitKind {
2104 pub fn str(&self) -> Option<Symbol> {
2105 match *self {
2106 LitKind::Str(s, _) => Some(s),
2107 _ => None,
2108 }
2109 }
2110
2111 pub fn is_str(&self) -> bool {
2113 matches!(self, LitKind::Str(..))
2114 }
2115
2116 pub fn is_bytestr(&self) -> bool {
2118 matches!(self, LitKind::ByteStr(..))
2119 }
2120
2121 pub fn is_numeric(&self) -> bool {
2123 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2124 }
2125
2126 pub fn is_unsuffixed(&self) -> bool {
2129 !self.is_suffixed()
2130 }
2131
2132 pub fn is_suffixed(&self) -> bool {
2134 match *self {
2135 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2137 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2138 LitKind::Str(..)
2140 | LitKind::ByteStr(..)
2141 | LitKind::CStr(..)
2142 | LitKind::Byte(..)
2143 | LitKind::Char(..)
2144 | LitKind::Int(_, LitIntType::Unsuffixed)
2145 | LitKind::Float(_, LitFloatType::Unsuffixed)
2146 | LitKind::Bool(..)
2147 | LitKind::Err(_) => false,
2148 }
2149 }
2150}
2151
2152#[derive(Clone, Encodable, Decodable, Debug)]
2155pub struct MutTy {
2156 pub ty: P<Ty>,
2157 pub mutbl: Mutability,
2158}
2159
2160#[derive(Clone, Encodable, Decodable, Debug)]
2163pub struct FnSig {
2164 pub header: FnHeader,
2165 pub decl: P<FnDecl>,
2166 pub span: Span,
2167}
2168
2169#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2170#[derive(Encodable, Decodable, HashStable_Generic)]
2171pub enum FloatTy {
2172 F16,
2173 F32,
2174 F64,
2175 F128,
2176}
2177
2178impl FloatTy {
2179 pub fn name_str(self) -> &'static str {
2180 match self {
2181 FloatTy::F16 => "f16",
2182 FloatTy::F32 => "f32",
2183 FloatTy::F64 => "f64",
2184 FloatTy::F128 => "f128",
2185 }
2186 }
2187
2188 pub fn name(self) -> Symbol {
2189 match self {
2190 FloatTy::F16 => sym::f16,
2191 FloatTy::F32 => sym::f32,
2192 FloatTy::F64 => sym::f64,
2193 FloatTy::F128 => sym::f128,
2194 }
2195 }
2196}
2197
2198#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2199#[derive(Encodable, Decodable, HashStable_Generic)]
2200pub enum IntTy {
2201 Isize,
2202 I8,
2203 I16,
2204 I32,
2205 I64,
2206 I128,
2207}
2208
2209impl IntTy {
2210 pub fn name_str(&self) -> &'static str {
2211 match *self {
2212 IntTy::Isize => "isize",
2213 IntTy::I8 => "i8",
2214 IntTy::I16 => "i16",
2215 IntTy::I32 => "i32",
2216 IntTy::I64 => "i64",
2217 IntTy::I128 => "i128",
2218 }
2219 }
2220
2221 pub fn name(&self) -> Symbol {
2222 match *self {
2223 IntTy::Isize => sym::isize,
2224 IntTy::I8 => sym::i8,
2225 IntTy::I16 => sym::i16,
2226 IntTy::I32 => sym::i32,
2227 IntTy::I64 => sym::i64,
2228 IntTy::I128 => sym::i128,
2229 }
2230 }
2231}
2232
2233#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2234#[derive(Encodable, Decodable, HashStable_Generic)]
2235pub enum UintTy {
2236 Usize,
2237 U8,
2238 U16,
2239 U32,
2240 U64,
2241 U128,
2242}
2243
2244impl UintTy {
2245 pub fn name_str(&self) -> &'static str {
2246 match *self {
2247 UintTy::Usize => "usize",
2248 UintTy::U8 => "u8",
2249 UintTy::U16 => "u16",
2250 UintTy::U32 => "u32",
2251 UintTy::U64 => "u64",
2252 UintTy::U128 => "u128",
2253 }
2254 }
2255
2256 pub fn name(&self) -> Symbol {
2257 match *self {
2258 UintTy::Usize => sym::usize,
2259 UintTy::U8 => sym::u8,
2260 UintTy::U16 => sym::u16,
2261 UintTy::U32 => sym::u32,
2262 UintTy::U64 => sym::u64,
2263 UintTy::U128 => sym::u128,
2264 }
2265 }
2266}
2267
2268#[derive(Clone, Encodable, Decodable, Debug)]
2279pub struct AssocItemConstraint {
2280 pub id: NodeId,
2281 pub ident: Ident,
2282 pub gen_args: Option<GenericArgs>,
2283 pub kind: AssocItemConstraintKind,
2284 pub span: Span,
2285}
2286
2287#[derive(Clone, Encodable, Decodable, Debug)]
2288pub enum Term {
2289 Ty(P<Ty>),
2290 Const(AnonConst),
2291}
2292
2293impl From<P<Ty>> for Term {
2294 fn from(v: P<Ty>) -> Self {
2295 Term::Ty(v)
2296 }
2297}
2298
2299impl From<AnonConst> for Term {
2300 fn from(v: AnonConst) -> Self {
2301 Term::Const(v)
2302 }
2303}
2304
2305#[derive(Clone, Encodable, Decodable, Debug)]
2307pub enum AssocItemConstraintKind {
2308 Equality { term: Term },
2315 Bound { bounds: GenericBounds },
2317}
2318
2319#[derive(Encodable, Decodable, Debug)]
2320pub struct Ty {
2321 pub id: NodeId,
2322 pub kind: TyKind,
2323 pub span: Span,
2324 pub tokens: Option<LazyAttrTokenStream>,
2325}
2326
2327impl Clone for Ty {
2328 fn clone(&self) -> Self {
2329 ensure_sufficient_stack(|| Self {
2330 id: self.id,
2331 kind: self.kind.clone(),
2332 span: self.span,
2333 tokens: self.tokens.clone(),
2334 })
2335 }
2336}
2337
2338impl Ty {
2339 pub fn peel_refs(&self) -> &Self {
2340 let mut final_ty = self;
2341 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2342 {
2343 final_ty = ty;
2344 }
2345 final_ty
2346 }
2347
2348 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2349 match &self.kind {
2350 TyKind::Infer => true,
2351 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2352 _ => false,
2353 }
2354 }
2355}
2356
2357#[derive(Clone, Encodable, Decodable, Debug)]
2358pub struct BareFnTy {
2359 pub safety: Safety,
2360 pub ext: Extern,
2361 pub generic_params: ThinVec<GenericParam>,
2362 pub decl: P<FnDecl>,
2363 pub decl_span: Span,
2366}
2367
2368#[derive(Clone, Encodable, Decodable, Debug)]
2369pub struct UnsafeBinderTy {
2370 pub generic_params: ThinVec<GenericParam>,
2371 pub inner_ty: P<Ty>,
2372}
2373
2374#[derive(Clone, Encodable, Decodable, Debug)]
2378pub enum TyKind {
2379 Slice(P<Ty>),
2381 Array(P<Ty>, AnonConst),
2383 Ptr(MutTy),
2385 Ref(Option<Lifetime>, MutTy),
2387 PinnedRef(Option<Lifetime>, MutTy),
2391 BareFn(P<BareFnTy>),
2393 UnsafeBinder(P<UnsafeBinderTy>),
2395 Never,
2397 Tup(ThinVec<P<Ty>>),
2399 Path(Option<P<QSelf>>, Path),
2404 TraitObject(GenericBounds, TraitObjectSyntax),
2407 ImplTrait(NodeId, GenericBounds),
2414 Paren(P<Ty>),
2416 Typeof(AnonConst),
2418 Infer,
2421 ImplicitSelf,
2423 MacCall(P<MacCall>),
2425 CVarArgs,
2427 Pat(P<Ty>, P<TyPat>),
2430 Dummy,
2432 Err(ErrorGuaranteed),
2434}
2435
2436impl TyKind {
2437 pub fn is_implicit_self(&self) -> bool {
2438 matches!(self, TyKind::ImplicitSelf)
2439 }
2440
2441 pub fn is_unit(&self) -> bool {
2442 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2443 }
2444
2445 pub fn is_simple_path(&self) -> Option<Symbol> {
2446 if let TyKind::Path(None, Path { segments, .. }) = &self
2447 && let [segment] = &segments[..]
2448 && segment.args.is_none()
2449 {
2450 Some(segment.ident.name)
2451 } else {
2452 None
2453 }
2454 }
2455}
2456
2457#[derive(Clone, Encodable, Decodable, Debug)]
2459pub struct TyPat {
2460 pub id: NodeId,
2461 pub kind: TyPatKind,
2462 pub span: Span,
2463 pub tokens: Option<LazyAttrTokenStream>,
2464}
2465
2466#[derive(Clone, Encodable, Decodable, Debug)]
2470pub enum TyPatKind {
2471 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2473
2474 Or(ThinVec<P<TyPat>>),
2475
2476 Err(ErrorGuaranteed),
2478}
2479
2480#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2482#[repr(u8)]
2483pub enum TraitObjectSyntax {
2484 Dyn = 0,
2486 DynStar = 1,
2487 None = 2,
2488}
2489
2490unsafe impl Tag for TraitObjectSyntax {
2494 const BITS: u32 = 2;
2495
2496 fn into_usize(self) -> usize {
2497 self as u8 as usize
2498 }
2499
2500 unsafe fn from_usize(tag: usize) -> Self {
2501 match tag {
2502 0 => TraitObjectSyntax::Dyn,
2503 1 => TraitObjectSyntax::DynStar,
2504 2 => TraitObjectSyntax::None,
2505 _ => unreachable!(),
2506 }
2507 }
2508}
2509
2510#[derive(Clone, Encodable, Decodable, Debug)]
2511pub enum PreciseCapturingArg {
2512 Lifetime(Lifetime),
2514 Arg(Path, NodeId),
2516}
2517
2518#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2522pub enum InlineAsmRegOrRegClass {
2523 Reg(Symbol),
2524 RegClass(Symbol),
2525}
2526
2527#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2528pub struct InlineAsmOptions(u16);
2529bitflags::bitflags! {
2530 impl InlineAsmOptions: u16 {
2531 const PURE = 1 << 0;
2532 const NOMEM = 1 << 1;
2533 const READONLY = 1 << 2;
2534 const PRESERVES_FLAGS = 1 << 3;
2535 const NORETURN = 1 << 4;
2536 const NOSTACK = 1 << 5;
2537 const ATT_SYNTAX = 1 << 6;
2538 const RAW = 1 << 7;
2539 const MAY_UNWIND = 1 << 8;
2540 }
2541}
2542
2543impl InlineAsmOptions {
2544 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2545
2546 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2547 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2548
2549 pub fn human_readable_names(&self) -> Vec<&'static str> {
2550 let mut options = vec![];
2551
2552 if self.contains(InlineAsmOptions::PURE) {
2553 options.push("pure");
2554 }
2555 if self.contains(InlineAsmOptions::NOMEM) {
2556 options.push("nomem");
2557 }
2558 if self.contains(InlineAsmOptions::READONLY) {
2559 options.push("readonly");
2560 }
2561 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2562 options.push("preserves_flags");
2563 }
2564 if self.contains(InlineAsmOptions::NORETURN) {
2565 options.push("noreturn");
2566 }
2567 if self.contains(InlineAsmOptions::NOSTACK) {
2568 options.push("nostack");
2569 }
2570 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2571 options.push("att_syntax");
2572 }
2573 if self.contains(InlineAsmOptions::RAW) {
2574 options.push("raw");
2575 }
2576 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2577 options.push("may_unwind");
2578 }
2579
2580 options
2581 }
2582}
2583
2584impl std::fmt::Debug for InlineAsmOptions {
2585 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2586 bitflags::parser::to_writer(self, f)
2587 }
2588}
2589
2590#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2591pub enum InlineAsmTemplatePiece {
2592 String(Cow<'static, str>),
2593 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2594}
2595
2596impl fmt::Display for InlineAsmTemplatePiece {
2597 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2598 match self {
2599 Self::String(s) => {
2600 for c in s.chars() {
2601 match c {
2602 '{' => f.write_str("{{")?,
2603 '}' => f.write_str("}}")?,
2604 _ => c.fmt(f)?,
2605 }
2606 }
2607 Ok(())
2608 }
2609 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2610 write!(f, "{{{operand_idx}:{modifier}}}")
2611 }
2612 Self::Placeholder { operand_idx, modifier: None, .. } => {
2613 write!(f, "{{{operand_idx}}}")
2614 }
2615 }
2616 }
2617}
2618
2619impl InlineAsmTemplatePiece {
2620 pub fn to_string(s: &[Self]) -> String {
2622 use fmt::Write;
2623 let mut out = String::new();
2624 for p in s.iter() {
2625 let _ = write!(out, "{p}");
2626 }
2627 out
2628 }
2629}
2630
2631#[derive(Clone, Encodable, Decodable, Debug)]
2639pub struct InlineAsmSym {
2640 pub id: NodeId,
2641 pub qself: Option<P<QSelf>>,
2642 pub path: Path,
2643}
2644
2645#[derive(Clone, Encodable, Decodable, Debug)]
2649pub enum InlineAsmOperand {
2650 In {
2651 reg: InlineAsmRegOrRegClass,
2652 expr: P<Expr>,
2653 },
2654 Out {
2655 reg: InlineAsmRegOrRegClass,
2656 late: bool,
2657 expr: Option<P<Expr>>,
2658 },
2659 InOut {
2660 reg: InlineAsmRegOrRegClass,
2661 late: bool,
2662 expr: P<Expr>,
2663 },
2664 SplitInOut {
2665 reg: InlineAsmRegOrRegClass,
2666 late: bool,
2667 in_expr: P<Expr>,
2668 out_expr: Option<P<Expr>>,
2669 },
2670 Const {
2671 anon_const: AnonConst,
2672 },
2673 Sym {
2674 sym: InlineAsmSym,
2675 },
2676 Label {
2677 block: P<Block>,
2678 },
2679}
2680
2681impl InlineAsmOperand {
2682 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2683 match self {
2684 Self::In { reg, .. }
2685 | Self::Out { reg, .. }
2686 | Self::InOut { reg, .. }
2687 | Self::SplitInOut { reg, .. } => Some(reg),
2688 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2689 }
2690 }
2691}
2692
2693#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2694pub enum AsmMacro {
2695 Asm,
2697 GlobalAsm,
2699 NakedAsm,
2701}
2702
2703impl AsmMacro {
2704 pub const fn macro_name(self) -> &'static str {
2705 match self {
2706 AsmMacro::Asm => "asm",
2707 AsmMacro::GlobalAsm => "global_asm",
2708 AsmMacro::NakedAsm => "naked_asm",
2709 }
2710 }
2711
2712 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2713 match self {
2714 AsmMacro::Asm => true,
2715 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2716 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2717 }
2718 }
2719
2720 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2721 match self {
2722 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2723 AsmMacro::GlobalAsm => true,
2724 AsmMacro::NakedAsm => true,
2725 }
2726 }
2727}
2728
2729#[derive(Clone, Encodable, Decodable, Debug)]
2733pub struct InlineAsm {
2734 pub asm_macro: AsmMacro,
2735 pub template: Vec<InlineAsmTemplatePiece>,
2736 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2737 pub operands: Vec<(InlineAsmOperand, Span)>,
2738 pub clobber_abis: Vec<(Symbol, Span)>,
2739 pub options: InlineAsmOptions,
2740 pub line_spans: Vec<Span>,
2741}
2742
2743#[derive(Clone, Encodable, Decodable, Debug)]
2747pub struct Param {
2748 pub attrs: AttrVec,
2749 pub ty: P<Ty>,
2750 pub pat: P<Pat>,
2751 pub id: NodeId,
2752 pub span: Span,
2753 pub is_placeholder: bool,
2754}
2755
2756#[derive(Clone, Encodable, Decodable, Debug)]
2760pub enum SelfKind {
2761 Value(Mutability),
2763 Region(Option<Lifetime>, Mutability),
2765 Pinned(Option<Lifetime>, Mutability),
2767 Explicit(P<Ty>, Mutability),
2769}
2770
2771impl SelfKind {
2772 pub fn to_ref_suggestion(&self) -> String {
2773 match self {
2774 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2775 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2776 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2777 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2778 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2779 unreachable!("if we had an explicit self, we wouldn't be here")
2780 }
2781 }
2782 }
2783}
2784
2785pub type ExplicitSelf = Spanned<SelfKind>;
2786
2787impl Param {
2788 pub fn to_self(&self) -> Option<ExplicitSelf> {
2790 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2791 if ident.name == kw::SelfLower {
2792 return match self.ty.kind {
2793 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2794 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2795 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2796 }
2797 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2798 if ty.kind.is_implicit_self() =>
2799 {
2800 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2801 }
2802 _ => Some(respan(
2803 self.pat.span.to(self.ty.span),
2804 SelfKind::Explicit(self.ty.clone(), mutbl),
2805 )),
2806 };
2807 }
2808 }
2809 None
2810 }
2811
2812 pub fn is_self(&self) -> bool {
2814 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2815 ident.name == kw::SelfLower
2816 } else {
2817 false
2818 }
2819 }
2820
2821 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2823 let span = eself.span.to(eself_ident.span);
2824 let infer_ty = P(Ty {
2825 id: DUMMY_NODE_ID,
2826 kind: TyKind::ImplicitSelf,
2827 span: eself_ident.span,
2828 tokens: None,
2829 });
2830 let (mutbl, ty) = match eself.node {
2831 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2832 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2833 SelfKind::Region(lt, mutbl) => (
2834 Mutability::Not,
2835 P(Ty {
2836 id: DUMMY_NODE_ID,
2837 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2838 span,
2839 tokens: None,
2840 }),
2841 ),
2842 SelfKind::Pinned(lt, mutbl) => (
2843 mutbl,
2844 P(Ty {
2845 id: DUMMY_NODE_ID,
2846 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2847 span,
2848 tokens: None,
2849 }),
2850 ),
2851 };
2852 Param {
2853 attrs,
2854 pat: P(Pat {
2855 id: DUMMY_NODE_ID,
2856 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2857 span,
2858 tokens: None,
2859 }),
2860 span,
2861 ty,
2862 id: DUMMY_NODE_ID,
2863 is_placeholder: false,
2864 }
2865 }
2866}
2867
2868#[derive(Clone, Encodable, Decodable, Debug)]
2875pub struct FnDecl {
2876 pub inputs: ThinVec<Param>,
2877 pub output: FnRetTy,
2878}
2879
2880impl FnDecl {
2881 pub fn has_self(&self) -> bool {
2882 self.inputs.get(0).is_some_and(Param::is_self)
2883 }
2884 pub fn c_variadic(&self) -> bool {
2885 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2886 }
2887}
2888
2889#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2891pub enum IsAuto {
2892 Yes,
2893 No,
2894}
2895
2896#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2898#[derive(HashStable_Generic)]
2899pub enum Safety {
2900 Unsafe(Span),
2902 Safe(Span),
2904 Default,
2907}
2908
2909#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2915pub enum CoroutineKind {
2916 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2918 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2920 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2922}
2923
2924impl CoroutineKind {
2925 pub fn span(self) -> Span {
2926 match self {
2927 CoroutineKind::Async { span, .. } => span,
2928 CoroutineKind::Gen { span, .. } => span,
2929 CoroutineKind::AsyncGen { span, .. } => span,
2930 }
2931 }
2932
2933 pub fn as_str(self) -> &'static str {
2934 match self {
2935 CoroutineKind::Async { .. } => "async",
2936 CoroutineKind::Gen { .. } => "gen",
2937 CoroutineKind::AsyncGen { .. } => "async gen",
2938 }
2939 }
2940
2941 pub fn closure_id(self) -> NodeId {
2942 match self {
2943 CoroutineKind::Async { closure_id, .. }
2944 | CoroutineKind::Gen { closure_id, .. }
2945 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2946 }
2947 }
2948
2949 pub fn return_id(self) -> (NodeId, Span) {
2952 match self {
2953 CoroutineKind::Async { return_impl_trait_id, span, .. }
2954 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2955 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2956 (return_impl_trait_id, span)
2957 }
2958 }
2959 }
2960}
2961
2962#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2963#[derive(HashStable_Generic)]
2964pub enum Const {
2965 Yes(Span),
2966 No,
2967}
2968
2969#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2972pub enum Defaultness {
2973 Default(Span),
2974 Final,
2975}
2976
2977#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2978pub enum ImplPolarity {
2979 Positive,
2981 Negative(Span),
2983}
2984
2985impl fmt::Debug for ImplPolarity {
2986 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2987 match *self {
2988 ImplPolarity::Positive => "positive".fmt(f),
2989 ImplPolarity::Negative(_) => "negative".fmt(f),
2990 }
2991 }
2992}
2993
2994#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2996#[derive(HashStable_Generic)]
2997pub enum BoundPolarity {
2998 Positive,
3000 Negative(Span),
3002 Maybe(Span),
3004}
3005
3006impl BoundPolarity {
3007 pub fn as_str(self) -> &'static str {
3008 match self {
3009 Self::Positive => "",
3010 Self::Negative(_) => "!",
3011 Self::Maybe(_) => "?",
3012 }
3013 }
3014}
3015
3016#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3018#[derive(HashStable_Generic)]
3019pub enum BoundConstness {
3020 Never,
3022 Always(Span),
3024 Maybe(Span),
3026}
3027
3028impl BoundConstness {
3029 pub fn as_str(self) -> &'static str {
3030 match self {
3031 Self::Never => "",
3032 Self::Always(_) => "const",
3033 Self::Maybe(_) => "~const",
3034 }
3035 }
3036}
3037
3038#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3040#[derive(HashStable_Generic)]
3041pub enum BoundAsyncness {
3042 Normal,
3044 Async(Span),
3046}
3047
3048impl BoundAsyncness {
3049 pub fn as_str(self) -> &'static str {
3050 match self {
3051 Self::Normal => "",
3052 Self::Async(_) => "async",
3053 }
3054 }
3055}
3056
3057#[derive(Clone, Encodable, Decodable, Debug)]
3058pub enum FnRetTy {
3059 Default(Span),
3064 Ty(P<Ty>),
3066}
3067
3068impl FnRetTy {
3069 pub fn span(&self) -> Span {
3070 match self {
3071 &FnRetTy::Default(span) => span,
3072 FnRetTy::Ty(ty) => ty.span,
3073 }
3074 }
3075}
3076
3077#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3078pub enum Inline {
3079 Yes,
3080 No,
3081}
3082
3083#[derive(Clone, Encodable, Decodable, Debug)]
3085pub enum ModKind {
3086 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3091 Unloaded,
3093}
3094
3095#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3096pub struct ModSpans {
3097 pub inner_span: Span,
3100 pub inject_use_span: Span,
3101}
3102
3103#[derive(Clone, Encodable, Decodable, Debug)]
3107pub struct ForeignMod {
3108 pub extern_span: Span,
3110 pub safety: Safety,
3113 pub abi: Option<StrLit>,
3114 pub items: ThinVec<P<ForeignItem>>,
3115}
3116
3117#[derive(Clone, Encodable, Decodable, Debug)]
3118pub struct EnumDef {
3119 pub variants: ThinVec<Variant>,
3120}
3121#[derive(Clone, Encodable, Decodable, Debug)]
3123pub struct Variant {
3124 pub attrs: AttrVec,
3126 pub id: NodeId,
3128 pub span: Span,
3130 pub vis: Visibility,
3132 pub ident: Ident,
3134
3135 pub data: VariantData,
3137 pub disr_expr: Option<AnonConst>,
3139 pub is_placeholder: bool,
3141}
3142
3143#[derive(Clone, Encodable, Decodable, Debug)]
3145pub enum UseTreeKind {
3146 Simple(Option<Ident>),
3148 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3157 Glob,
3159}
3160
3161#[derive(Clone, Encodable, Decodable, Debug)]
3164pub struct UseTree {
3165 pub prefix: Path,
3166 pub kind: UseTreeKind,
3167 pub span: Span,
3168}
3169
3170impl UseTree {
3171 pub fn ident(&self) -> Ident {
3172 match self.kind {
3173 UseTreeKind::Simple(Some(rename)) => rename,
3174 UseTreeKind::Simple(None) => {
3175 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3176 }
3177 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3178 }
3179 }
3180}
3181
3182#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3186pub enum AttrStyle {
3187 Outer,
3188 Inner,
3189}
3190
3191pub type AttrVec = ThinVec<Attribute>;
3193
3194#[derive(Clone, Encodable, Decodable, Debug)]
3196pub struct Attribute {
3197 pub kind: AttrKind,
3198 pub id: AttrId,
3199 pub style: AttrStyle,
3202 pub span: Span,
3203}
3204
3205#[derive(Clone, Encodable, Decodable, Debug)]
3206pub enum AttrKind {
3207 Normal(P<NormalAttr>),
3209
3210 DocComment(CommentKind, Symbol),
3214}
3215
3216#[derive(Clone, Encodable, Decodable, Debug)]
3217pub struct NormalAttr {
3218 pub item: AttrItem,
3219 pub tokens: Option<LazyAttrTokenStream>,
3221}
3222
3223impl NormalAttr {
3224 pub fn from_ident(ident: Ident) -> Self {
3225 Self {
3226 item: AttrItem {
3227 unsafety: Safety::Default,
3228 path: Path::from_ident(ident),
3229 args: AttrArgs::Empty,
3230 tokens: None,
3231 },
3232 tokens: None,
3233 }
3234 }
3235}
3236
3237#[derive(Clone, Encodable, Decodable, Debug)]
3238pub struct AttrItem {
3239 pub unsafety: Safety,
3240 pub path: Path,
3241 pub args: AttrArgs,
3242 pub tokens: Option<LazyAttrTokenStream>,
3244}
3245
3246impl AttrItem {
3247 pub fn is_valid_for_outer_style(&self) -> bool {
3248 self.path == sym::cfg_attr
3249 || self.path == sym::cfg
3250 || self.path == sym::forbid
3251 || self.path == sym::warn
3252 || self.path == sym::allow
3253 || self.path == sym::deny
3254 }
3255}
3256
3257#[derive(Clone, Encodable, Decodable, Debug)]
3264pub struct TraitRef {
3265 pub path: Path,
3266 pub ref_id: NodeId,
3267}
3268
3269#[derive(Clone, Encodable, Decodable, Debug)]
3270pub struct PolyTraitRef {
3271 pub bound_generic_params: ThinVec<GenericParam>,
3273
3274 pub modifiers: TraitBoundModifiers,
3276
3277 pub trait_ref: TraitRef,
3279
3280 pub span: Span,
3281}
3282
3283impl PolyTraitRef {
3284 pub fn new(
3285 generic_params: ThinVec<GenericParam>,
3286 path: Path,
3287 modifiers: TraitBoundModifiers,
3288 span: Span,
3289 ) -> Self {
3290 PolyTraitRef {
3291 bound_generic_params: generic_params,
3292 modifiers,
3293 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3294 span,
3295 }
3296 }
3297}
3298
3299#[derive(Clone, Encodable, Decodable, Debug)]
3300pub struct Visibility {
3301 pub kind: VisibilityKind,
3302 pub span: Span,
3303 pub tokens: Option<LazyAttrTokenStream>,
3304}
3305
3306#[derive(Clone, Encodable, Decodable, Debug)]
3307pub enum VisibilityKind {
3308 Public,
3309 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3310 Inherited,
3311}
3312
3313impl VisibilityKind {
3314 pub fn is_pub(&self) -> bool {
3315 matches!(self, VisibilityKind::Public)
3316 }
3317}
3318
3319#[derive(Clone, Encodable, Decodable, Debug)]
3323pub struct FieldDef {
3324 pub attrs: AttrVec,
3325 pub id: NodeId,
3326 pub span: Span,
3327 pub vis: Visibility,
3328 pub safety: Safety,
3329 pub ident: Option<Ident>,
3330
3331 pub ty: P<Ty>,
3332 pub default: Option<AnonConst>,
3333 pub is_placeholder: bool,
3334}
3335
3336#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3338pub enum Recovered {
3339 No,
3340 Yes(ErrorGuaranteed),
3341}
3342
3343#[derive(Clone, Encodable, Decodable, Debug)]
3345pub enum VariantData {
3346 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3350 Tuple(ThinVec<FieldDef>, NodeId),
3354 Unit(NodeId),
3358}
3359
3360impl VariantData {
3361 pub fn fields(&self) -> &[FieldDef] {
3363 match self {
3364 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3365 _ => &[],
3366 }
3367 }
3368
3369 pub fn ctor_node_id(&self) -> Option<NodeId> {
3371 match *self {
3372 VariantData::Struct { .. } => None,
3373 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3374 }
3375 }
3376}
3377
3378#[derive(Clone, Encodable, Decodable, Debug)]
3380pub struct Item<K = ItemKind> {
3381 pub attrs: AttrVec,
3382 pub id: NodeId,
3383 pub span: Span,
3384 pub vis: Visibility,
3385
3386 pub kind: K,
3387
3388 pub tokens: Option<LazyAttrTokenStream>,
3396}
3397
3398impl Item {
3399 pub fn span_with_attributes(&self) -> Span {
3401 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3402 }
3403
3404 pub fn opt_generics(&self) -> Option<&Generics> {
3405 match &self.kind {
3406 ItemKind::ExternCrate(..)
3407 | ItemKind::Use(_)
3408 | ItemKind::Mod(..)
3409 | ItemKind::ForeignMod(_)
3410 | ItemKind::GlobalAsm(_)
3411 | ItemKind::MacCall(_)
3412 | ItemKind::Delegation(_)
3413 | ItemKind::DelegationMac(_)
3414 | ItemKind::MacroDef(..) => None,
3415 ItemKind::Static(_) => None,
3416 ItemKind::Const(i) => Some(&i.generics),
3417 ItemKind::Fn(i) => Some(&i.generics),
3418 ItemKind::TyAlias(i) => Some(&i.generics),
3419 ItemKind::TraitAlias(_, generics, _)
3420 | ItemKind::Enum(_, _, generics)
3421 | ItemKind::Struct(_, _, generics)
3422 | ItemKind::Union(_, _, generics) => Some(&generics),
3423 ItemKind::Trait(i) => Some(&i.generics),
3424 ItemKind::Impl(i) => Some(&i.generics),
3425 }
3426 }
3427}
3428
3429#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3431pub enum Extern {
3432 None,
3436 Implicit(Span),
3442 Explicit(StrLit, Span),
3446}
3447
3448impl Extern {
3449 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3450 match abi {
3451 Some(name) => Extern::Explicit(name, span),
3452 None => Extern::Implicit(span),
3453 }
3454 }
3455}
3456
3457#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3462pub struct FnHeader {
3463 pub safety: Safety,
3465 pub coroutine_kind: Option<CoroutineKind>,
3467 pub constness: Const,
3469 pub ext: Extern,
3471}
3472
3473impl FnHeader {
3474 pub fn has_qualifiers(&self) -> bool {
3476 let Self { safety, coroutine_kind, constness, ext } = self;
3477 matches!(safety, Safety::Unsafe(_))
3478 || coroutine_kind.is_some()
3479 || matches!(constness, Const::Yes(_))
3480 || !matches!(ext, Extern::None)
3481 }
3482}
3483
3484impl Default for FnHeader {
3485 fn default() -> FnHeader {
3486 FnHeader {
3487 safety: Safety::Default,
3488 coroutine_kind: None,
3489 constness: Const::No,
3490 ext: Extern::None,
3491 }
3492 }
3493}
3494
3495#[derive(Clone, Encodable, Decodable, Debug)]
3496pub struct Trait {
3497 pub safety: Safety,
3498 pub is_auto: IsAuto,
3499 pub ident: Ident,
3500 pub generics: Generics,
3501 pub bounds: GenericBounds,
3502 pub items: ThinVec<P<AssocItem>>,
3503}
3504
3505#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3524pub struct TyAliasWhereClause {
3525 pub has_where_token: bool,
3526 pub span: Span,
3527}
3528
3529#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3531pub struct TyAliasWhereClauses {
3532 pub before: TyAliasWhereClause,
3534 pub after: TyAliasWhereClause,
3536 pub split: usize,
3540}
3541
3542#[derive(Clone, Encodable, Decodable, Debug)]
3543pub struct TyAlias {
3544 pub defaultness: Defaultness,
3545 pub ident: Ident,
3546 pub generics: Generics,
3547 pub where_clauses: TyAliasWhereClauses,
3548 pub bounds: GenericBounds,
3549 pub ty: Option<P<Ty>>,
3550}
3551
3552#[derive(Clone, Encodable, Decodable, Debug)]
3553pub struct Impl {
3554 pub defaultness: Defaultness,
3555 pub safety: Safety,
3556 pub generics: Generics,
3557 pub constness: Const,
3558 pub polarity: ImplPolarity,
3559 pub of_trait: Option<TraitRef>,
3561 pub self_ty: P<Ty>,
3562 pub items: ThinVec<P<AssocItem>>,
3563}
3564
3565#[derive(Clone, Encodable, Decodable, Debug, Default)]
3566pub struct FnContract {
3567 pub requires: Option<P<Expr>>,
3568 pub ensures: Option<P<Expr>>,
3569}
3570
3571#[derive(Clone, Encodable, Decodable, Debug)]
3572pub struct Fn {
3573 pub defaultness: Defaultness,
3574 pub ident: Ident,
3575 pub generics: Generics,
3576 pub sig: FnSig,
3577 pub contract: Option<P<FnContract>>,
3578 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3579 pub body: Option<P<Block>>,
3580}
3581
3582#[derive(Clone, Encodable, Decodable, Debug)]
3583pub struct Delegation {
3584 pub id: NodeId,
3586 pub qself: Option<P<QSelf>>,
3587 pub path: Path,
3588 pub ident: Ident,
3589 pub rename: Option<Ident>,
3590 pub body: Option<P<Block>>,
3591 pub from_glob: bool,
3593}
3594
3595#[derive(Clone, Encodable, Decodable, Debug)]
3596pub struct DelegationMac {
3597 pub qself: Option<P<QSelf>>,
3598 pub prefix: Path,
3599 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3601 pub body: Option<P<Block>>,
3602}
3603
3604#[derive(Clone, Encodable, Decodable, Debug)]
3605pub struct StaticItem {
3606 pub ident: Ident,
3607 pub ty: P<Ty>,
3608 pub safety: Safety,
3609 pub mutability: Mutability,
3610 pub expr: Option<P<Expr>>,
3611 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3612}
3613
3614#[derive(Clone, Encodable, Decodable, Debug)]
3615pub struct ConstItem {
3616 pub defaultness: Defaultness,
3617 pub ident: Ident,
3618 pub generics: Generics,
3619 pub ty: P<Ty>,
3620 pub expr: Option<P<Expr>>,
3621 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3622}
3623
3624#[derive(Clone, Encodable, Decodable, Debug)]
3626pub enum ItemKind {
3627 ExternCrate(Option<Symbol>, Ident),
3631 Use(UseTree),
3635 Static(Box<StaticItem>),
3639 Const(Box<ConstItem>),
3643 Fn(Box<Fn>),
3647 Mod(Safety, Ident, ModKind),
3653 ForeignMod(ForeignMod),
3657 GlobalAsm(Box<InlineAsm>),
3659 TyAlias(Box<TyAlias>),
3663 Enum(Ident, EnumDef, Generics),
3667 Struct(Ident, VariantData, Generics),
3671 Union(Ident, VariantData, Generics),
3675 Trait(Box<Trait>),
3679 TraitAlias(Ident, Generics, GenericBounds),
3683 Impl(Box<Impl>),
3687 MacCall(P<MacCall>),
3691
3692 MacroDef(Ident, MacroDef),
3694
3695 Delegation(Box<Delegation>),
3699 DelegationMac(Box<DelegationMac>),
3702}
3703
3704impl ItemKind {
3705 pub fn ident(&self) -> Option<Ident> {
3706 match *self {
3707 ItemKind::ExternCrate(_, ident)
3708 | ItemKind::Static(box StaticItem { ident, .. })
3709 | ItemKind::Const(box ConstItem { ident, .. })
3710 | ItemKind::Fn(box Fn { ident, .. })
3711 | ItemKind::Mod(_, ident, _)
3712 | ItemKind::TyAlias(box TyAlias { ident, .. })
3713 | ItemKind::Enum(ident, ..)
3714 | ItemKind::Struct(ident, ..)
3715 | ItemKind::Union(ident, ..)
3716 | ItemKind::Trait(box Trait { ident, .. })
3717 | ItemKind::TraitAlias(ident, ..)
3718 | ItemKind::MacroDef(ident, _)
3719 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3720
3721 ItemKind::Use(_)
3722 | ItemKind::ForeignMod(_)
3723 | ItemKind::GlobalAsm(_)
3724 | ItemKind::Impl(_)
3725 | ItemKind::MacCall(_)
3726 | ItemKind::DelegationMac(_) => None,
3727 }
3728 }
3729
3730 pub fn article(&self) -> &'static str {
3732 use ItemKind::*;
3733 match self {
3734 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3735 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3736 | Delegation(..) | DelegationMac(..) => "a",
3737 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3738 }
3739 }
3740
3741 pub fn descr(&self) -> &'static str {
3742 match self {
3743 ItemKind::ExternCrate(..) => "extern crate",
3744 ItemKind::Use(..) => "`use` import",
3745 ItemKind::Static(..) => "static item",
3746 ItemKind::Const(..) => "constant item",
3747 ItemKind::Fn(..) => "function",
3748 ItemKind::Mod(..) => "module",
3749 ItemKind::ForeignMod(..) => "extern block",
3750 ItemKind::GlobalAsm(..) => "global asm item",
3751 ItemKind::TyAlias(..) => "type alias",
3752 ItemKind::Enum(..) => "enum",
3753 ItemKind::Struct(..) => "struct",
3754 ItemKind::Union(..) => "union",
3755 ItemKind::Trait(..) => "trait",
3756 ItemKind::TraitAlias(..) => "trait alias",
3757 ItemKind::MacCall(..) => "item macro invocation",
3758 ItemKind::MacroDef(..) => "macro definition",
3759 ItemKind::Impl { .. } => "implementation",
3760 ItemKind::Delegation(..) => "delegated function",
3761 ItemKind::DelegationMac(..) => "delegation",
3762 }
3763 }
3764
3765 pub fn generics(&self) -> Option<&Generics> {
3766 match self {
3767 Self::Fn(box Fn { generics, .. })
3768 | Self::TyAlias(box TyAlias { generics, .. })
3769 | Self::Const(box ConstItem { generics, .. })
3770 | Self::Enum(_, _, generics)
3771 | Self::Struct(_, _, generics)
3772 | Self::Union(_, _, generics)
3773 | Self::Trait(box Trait { generics, .. })
3774 | Self::TraitAlias(_, generics, _)
3775 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3776 _ => None,
3777 }
3778 }
3779}
3780
3781pub type AssocItem = Item<AssocItemKind>;
3784
3785#[derive(Clone, Encodable, Decodable, Debug)]
3793pub enum AssocItemKind {
3794 Const(Box<ConstItem>),
3797 Fn(Box<Fn>),
3799 Type(Box<TyAlias>),
3801 MacCall(P<MacCall>),
3803 Delegation(Box<Delegation>),
3805 DelegationMac(Box<DelegationMac>),
3807}
3808
3809impl AssocItemKind {
3810 pub fn ident(&self) -> Option<Ident> {
3811 match *self {
3812 AssocItemKind::Const(box ConstItem { ident, .. })
3813 | AssocItemKind::Fn(box Fn { ident, .. })
3814 | AssocItemKind::Type(box TyAlias { ident, .. })
3815 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3816
3817 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3818 }
3819 }
3820
3821 pub fn defaultness(&self) -> Defaultness {
3822 match *self {
3823 Self::Const(box ConstItem { defaultness, .. })
3824 | Self::Fn(box Fn { defaultness, .. })
3825 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3826 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3827 Defaultness::Final
3828 }
3829 }
3830 }
3831}
3832
3833impl From<AssocItemKind> for ItemKind {
3834 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3835 match assoc_item_kind {
3836 AssocItemKind::Const(item) => ItemKind::Const(item),
3837 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3838 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3839 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3840 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3841 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3842 }
3843 }
3844}
3845
3846impl TryFrom<ItemKind> for AssocItemKind {
3847 type Error = ItemKind;
3848
3849 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3850 Ok(match item_kind {
3851 ItemKind::Const(item) => AssocItemKind::Const(item),
3852 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3853 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3854 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3855 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3856 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3857 _ => return Err(item_kind),
3858 })
3859 }
3860}
3861
3862#[derive(Clone, Encodable, Decodable, Debug)]
3864pub enum ForeignItemKind {
3865 Static(Box<StaticItem>),
3867 Fn(Box<Fn>),
3869 TyAlias(Box<TyAlias>),
3871 MacCall(P<MacCall>),
3873}
3874
3875impl ForeignItemKind {
3876 pub fn ident(&self) -> Option<Ident> {
3877 match *self {
3878 ForeignItemKind::Static(box StaticItem { ident, .. })
3879 | ForeignItemKind::Fn(box Fn { ident, .. })
3880 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3881
3882 ForeignItemKind::MacCall(_) => None,
3883 }
3884 }
3885}
3886
3887impl From<ForeignItemKind> for ItemKind {
3888 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3889 match foreign_item_kind {
3890 ForeignItemKind::Static(box static_foreign_item) => {
3891 ItemKind::Static(Box::new(static_foreign_item))
3892 }
3893 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3894 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3895 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3896 }
3897 }
3898}
3899
3900impl TryFrom<ItemKind> for ForeignItemKind {
3901 type Error = ItemKind;
3902
3903 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3904 Ok(match item_kind {
3905 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3906 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3907 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3908 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3909 _ => return Err(item_kind),
3910 })
3911 }
3912}
3913
3914pub type ForeignItem = Item<ForeignItemKind>;
3915
3916#[cfg(target_pointer_width = "64")]
3918mod size_asserts {
3919 use rustc_data_structures::static_assert_size;
3920
3921 use super::*;
3922 static_assert_size!(AssocItem, 80);
3924 static_assert_size!(AssocItemKind, 16);
3925 static_assert_size!(Attribute, 32);
3926 static_assert_size!(Block, 32);
3927 static_assert_size!(Expr, 72);
3928 static_assert_size!(ExprKind, 40);
3929 static_assert_size!(Fn, 184);
3930 static_assert_size!(ForeignItem, 80);
3931 static_assert_size!(ForeignItemKind, 16);
3932 static_assert_size!(GenericArg, 24);
3933 static_assert_size!(GenericBound, 88);
3934 static_assert_size!(Generics, 40);
3935 static_assert_size!(Impl, 136);
3936 static_assert_size!(Item, 144);
3937 static_assert_size!(ItemKind, 80);
3938 static_assert_size!(LitKind, 24);
3939 static_assert_size!(Local, 96);
3940 static_assert_size!(MetaItemLit, 40);
3941 static_assert_size!(Param, 40);
3942 static_assert_size!(Pat, 72);
3943 static_assert_size!(Path, 24);
3944 static_assert_size!(PathSegment, 24);
3945 static_assert_size!(PatKind, 48);
3946 static_assert_size!(Stmt, 32);
3947 static_assert_size!(StmtKind, 16);
3948 static_assert_size!(Ty, 64);
3949 static_assert_size!(TyKind, 40);
3950 }