1use std::borrow::Cow;
22use std::sync::Arc;
23use std::{cmp, fmt};
24
25pub use GenericArgs::*;
26pub use UnsafeSource::*;
27pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
28use rustc_data_structures::packed::Pu128;
29use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30use rustc_data_structures::stack::ensure_sufficient_stack;
31use rustc_data_structures::tagged_ptr::Tag;
32use rustc_macros::{Decodable, Encodable, HashStable_Generic};
33pub use rustc_span::AttrId;
34use rustc_span::source_map::{Spanned, respan};
35use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
36use thin_vec::{ThinVec, thin_vec};
37
38pub use crate::format::*;
39use crate::ptr::P;
40use crate::token::{self, CommentKind, Delimiter};
41use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42use crate::util::parser::{ExprPrecedence, Fixity};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
55pub struct Label {
56 pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "label({:?})", self.ident)
62 }
63}
64
65#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
68pub struct Lifetime {
69 pub id: NodeId,
70 pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "lifetime({}: {})", self.id, self)
76 }
77}
78
79impl fmt::Display for Lifetime {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}", self.ident.name)
82 }
83}
84
85#[derive(Clone, Encodable, Decodable, Debug)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
102 #[inline]
103 fn eq(&self, name: &Symbol) -> bool {
104 if let [segment] = self.segments.as_ref()
105 && segment == name
106 {
107 true
108 } else {
109 false
110 }
111 }
112}
113
114impl PartialEq<&[Symbol]> for Path {
116 #[inline]
117 fn eq(&self, names: &&[Symbol]) -> bool {
118 self.segments.len() == names.len()
119 && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
120 }
121}
122
123impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
124 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
125 self.segments.len().hash_stable(hcx, hasher);
126 for segment in &self.segments {
127 segment.ident.hash_stable(hcx, hasher);
128 }
129 }
130}
131
132impl Path {
133 pub fn from_ident(ident: Ident) -> Path {
136 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
137 }
138
139 pub fn is_global(&self) -> bool {
140 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
141 }
142
143 #[tracing::instrument(level = "debug", ret)]
153 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
154 allow_mgca_arg
155 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
156 }
157}
158
159#[derive(Clone, Encodable, Decodable, Debug)]
163pub struct PathSegment {
164 pub ident: Ident,
166
167 pub id: NodeId,
168
169 pub args: Option<P<GenericArgs>>,
176}
177
178impl PartialEq<Symbol> for PathSegment {
180 #[inline]
181 fn eq(&self, name: &Symbol) -> bool {
182 self.args.is_none() && self.ident.name == *name
183 }
184}
185
186impl PathSegment {
187 pub fn from_ident(ident: Ident) -> Self {
188 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
189 }
190
191 pub fn path_root(span: Span) -> Self {
192 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
193 }
194
195 pub fn span(&self) -> Span {
196 match &self.args {
197 Some(args) => self.ident.span.to(args.span()),
198 None => self.ident.span,
199 }
200 }
201}
202
203#[derive(Clone, Encodable, Decodable, Debug)]
207pub enum GenericArgs {
208 AngleBracketed(AngleBracketedArgs),
210 Parenthesized(ParenthesizedArgs),
212 ParenthesizedElided(Span),
214}
215
216impl GenericArgs {
217 pub fn is_angle_bracketed(&self) -> bool {
218 matches!(self, AngleBracketed(..))
219 }
220
221 pub fn span(&self) -> Span {
222 match self {
223 AngleBracketed(data) => data.span,
224 Parenthesized(data) => data.span,
225 ParenthesizedElided(span) => *span,
226 }
227 }
228}
229
230#[derive(Clone, Encodable, Decodable, Debug)]
232pub enum GenericArg {
233 Lifetime(Lifetime),
235 Type(P<Ty>),
237 Const(AnonConst),
239}
240
241impl GenericArg {
242 pub fn span(&self) -> Span {
243 match self {
244 GenericArg::Lifetime(lt) => lt.ident.span,
245 GenericArg::Type(ty) => ty.span,
246 GenericArg::Const(ct) => ct.value.span,
247 }
248 }
249}
250
251#[derive(Clone, Encodable, Decodable, Debug, Default)]
253pub struct AngleBracketedArgs {
254 pub span: Span,
256 pub args: ThinVec<AngleBracketedArg>,
258}
259
260#[derive(Clone, Encodable, Decodable, Debug)]
262pub enum AngleBracketedArg {
263 Arg(GenericArg),
265 Constraint(AssocItemConstraint),
267}
268
269impl AngleBracketedArg {
270 pub fn span(&self) -> Span {
271 match self {
272 AngleBracketedArg::Arg(arg) => arg.span(),
273 AngleBracketedArg::Constraint(constraint) => constraint.span,
274 }
275 }
276}
277
278impl From<AngleBracketedArgs> for P<GenericArgs> {
279 fn from(val: AngleBracketedArgs) -> Self {
280 P(GenericArgs::AngleBracketed(val))
281 }
282}
283
284impl From<ParenthesizedArgs> for P<GenericArgs> {
285 fn from(val: ParenthesizedArgs) -> Self {
286 P(GenericArgs::Parenthesized(val))
287 }
288}
289
290#[derive(Clone, Encodable, Decodable, Debug)]
292pub struct ParenthesizedArgs {
293 pub span: Span,
298
299 pub inputs: ThinVec<P<Ty>>,
301
302 pub inputs_span: Span,
307
308 pub output: FnRetTy,
310}
311
312impl ParenthesizedArgs {
313 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
314 let args = self
315 .inputs
316 .iter()
317 .cloned()
318 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
319 .collect();
320 AngleBracketedArgs { span: self.inputs_span, args }
321 }
322}
323
324pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
325
326#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
328pub struct TraitBoundModifiers {
329 pub constness: BoundConstness,
330 pub asyncness: BoundAsyncness,
331 pub polarity: BoundPolarity,
332}
333
334impl TraitBoundModifiers {
335 pub const NONE: Self = Self {
336 constness: BoundConstness::Never,
337 asyncness: BoundAsyncness::Normal,
338 polarity: BoundPolarity::Positive,
339 };
340}
341
342#[derive(Clone, Encodable, Decodable, Debug)]
343pub enum GenericBound {
344 Trait(PolyTraitRef),
345 Outlives(Lifetime),
346 Use(ThinVec<PreciseCapturingArg>, Span),
348}
349
350impl GenericBound {
351 pub fn span(&self) -> Span {
352 match self {
353 GenericBound::Trait(t, ..) => t.span,
354 GenericBound::Outlives(l) => l.ident.span,
355 GenericBound::Use(_, span) => *span,
356 }
357 }
358}
359
360pub type GenericBounds = Vec<GenericBound>;
361
362#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
366pub enum ParamKindOrd {
367 Lifetime,
368 TypeOrConst,
369}
370
371impl fmt::Display for ParamKindOrd {
372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 match self {
374 ParamKindOrd::Lifetime => "lifetime".fmt(f),
375 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
376 }
377 }
378}
379
380#[derive(Clone, Encodable, Decodable, Debug)]
381pub enum GenericParamKind {
382 Lifetime,
384 Type {
385 default: Option<P<Ty>>,
386 },
387 Const {
388 ty: P<Ty>,
389 kw_span: Span,
391 default: Option<AnonConst>,
393 },
394}
395
396#[derive(Clone, Encodable, Decodable, Debug)]
397pub struct GenericParam {
398 pub id: NodeId,
399 pub ident: Ident,
400 pub attrs: AttrVec,
401 pub bounds: GenericBounds,
402 pub is_placeholder: bool,
403 pub kind: GenericParamKind,
404 pub colon_span: Option<Span>,
405}
406
407impl GenericParam {
408 pub fn span(&self) -> Span {
409 match &self.kind {
410 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
411 self.ident.span
412 }
413 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
414 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
415 kw_span.to(default.value.span)
416 }
417 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
418 }
419 }
420}
421
422#[derive(Clone, Encodable, Decodable, Debug, Default)]
425pub struct Generics {
426 pub params: ThinVec<GenericParam>,
427 pub where_clause: WhereClause,
428 pub span: Span,
429}
430
431#[derive(Clone, Encodable, Decodable, Debug, Default)]
433pub struct WhereClause {
434 pub has_where_token: bool,
439 pub predicates: ThinVec<WherePredicate>,
440 pub span: Span,
441}
442
443impl WhereClause {
444 pub fn is_empty(&self) -> bool {
445 !self.has_where_token && self.predicates.is_empty()
446 }
447}
448
449#[derive(Clone, Encodable, Decodable, Debug)]
451pub struct WherePredicate {
452 pub attrs: AttrVec,
453 pub kind: WherePredicateKind,
454 pub id: NodeId,
455 pub span: Span,
456 pub is_placeholder: bool,
457}
458
459#[derive(Clone, Encodable, Decodable, Debug)]
461pub enum WherePredicateKind {
462 BoundPredicate(WhereBoundPredicate),
464 RegionPredicate(WhereRegionPredicate),
466 EqPredicate(WhereEqPredicate),
468}
469
470#[derive(Clone, Encodable, Decodable, Debug)]
474pub struct WhereBoundPredicate {
475 pub bound_generic_params: ThinVec<GenericParam>,
477 pub bounded_ty: P<Ty>,
479 pub bounds: GenericBounds,
481}
482
483#[derive(Clone, Encodable, Decodable, Debug)]
487pub struct WhereRegionPredicate {
488 pub lifetime: Lifetime,
489 pub bounds: GenericBounds,
490}
491
492#[derive(Clone, Encodable, Decodable, Debug)]
496pub struct WhereEqPredicate {
497 pub lhs_ty: P<Ty>,
498 pub rhs_ty: P<Ty>,
499}
500
501#[derive(Clone, Encodable, Decodable, Debug)]
502pub struct Crate {
503 pub attrs: AttrVec,
504 pub items: ThinVec<P<Item>>,
505 pub spans: ModSpans,
506 pub id: NodeId,
509 pub is_placeholder: bool,
510}
511
512#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
519pub struct MetaItem {
520 pub unsafety: Safety,
521 pub path: Path,
522 pub kind: MetaItemKind,
523 pub span: Span,
524}
525
526#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
528pub enum MetaItemKind {
529 Word,
533
534 List(ThinVec<MetaItemInner>),
538
539 NameValue(MetaItemLit),
543}
544
545#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
549pub enum MetaItemInner {
550 MetaItem(MetaItem),
552
553 Lit(MetaItemLit),
557}
558
559#[derive(Clone, Encodable, Decodable, Debug)]
563pub struct Block {
564 pub stmts: ThinVec<Stmt>,
566 pub id: NodeId,
567 pub rules: BlockCheckMode,
569 pub span: Span,
570 pub tokens: Option<LazyAttrTokenStream>,
571}
572
573#[derive(Clone, Encodable, Decodable, Debug)]
577pub struct Pat {
578 pub id: NodeId,
579 pub kind: PatKind,
580 pub span: Span,
581 pub tokens: Option<LazyAttrTokenStream>,
582}
583
584impl Pat {
585 pub fn to_ty(&self) -> Option<P<Ty>> {
588 let kind = match &self.kind {
589 PatKind::Missing => unreachable!(),
590 PatKind::Wild => TyKind::Infer,
592 PatKind::Ident(BindingMode::NONE, ident, None) => {
594 TyKind::Path(None, Path::from_ident(*ident))
595 }
596 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
597 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
598 PatKind::Ref(pat, mutbl) => {
600 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
601 }
602 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
605 pat.to_ty().map(TyKind::Slice)?
606 }
607 PatKind::Tuple(pats) => {
610 let mut tys = ThinVec::with_capacity(pats.len());
611 for pat in pats {
613 tys.push(pat.to_ty()?);
614 }
615 TyKind::Tup(tys)
616 }
617 _ => return None,
618 };
619
620 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
621 }
622
623 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
627 if !it(self) {
628 return;
629 }
630
631 match &self.kind {
632 PatKind::Ident(_, _, Some(p)) => p.walk(it),
634
635 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
637
638 PatKind::TupleStruct(_, _, s)
640 | PatKind::Tuple(s)
641 | PatKind::Slice(s)
642 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
643
644 PatKind::Box(s)
646 | PatKind::Deref(s)
647 | PatKind::Ref(s, _)
648 | PatKind::Paren(s)
649 | PatKind::Guard(s, _) => s.walk(it),
650
651 PatKind::Missing
653 | PatKind::Wild
654 | PatKind::Rest
655 | PatKind::Never
656 | PatKind::Expr(_)
657 | PatKind::Range(..)
658 | PatKind::Ident(..)
659 | PatKind::Path(..)
660 | PatKind::MacCall(_)
661 | PatKind::Err(_) => {}
662 }
663 }
664
665 pub fn is_rest(&self) -> bool {
667 matches!(self.kind, PatKind::Rest)
668 }
669
670 pub fn could_be_never_pattern(&self) -> bool {
673 let mut could_be_never_pattern = false;
674 self.walk(&mut |pat| match &pat.kind {
675 PatKind::Never | PatKind::MacCall(_) => {
676 could_be_never_pattern = true;
677 false
678 }
679 PatKind::Or(s) => {
680 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
681 false
682 }
683 _ => true,
684 });
685 could_be_never_pattern
686 }
687
688 pub fn contains_never_pattern(&self) -> bool {
691 let mut contains_never_pattern = false;
692 self.walk(&mut |pat| {
693 if matches!(pat.kind, PatKind::Never) {
694 contains_never_pattern = true;
695 }
696 true
697 });
698 contains_never_pattern
699 }
700
701 pub fn descr(&self) -> Option<String> {
703 match &self.kind {
704 PatKind::Missing => unreachable!(),
705 PatKind::Wild => Some("_".to_string()),
706 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
707 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
708 _ => None,
709 }
710 }
711}
712
713impl From<P<Pat>> for Pat {
714 fn from(value: P<Pat>) -> Self {
715 *value
716 }
717}
718
719#[derive(Clone, Encodable, Decodable, Debug)]
725pub struct PatField {
726 pub ident: Ident,
728 pub pat: P<Pat>,
730 pub is_shorthand: bool,
731 pub attrs: AttrVec,
732 pub id: NodeId,
733 pub span: Span,
734 pub is_placeholder: bool,
735}
736
737#[derive(Clone, Copy, Debug, Eq, PartialEq)]
738#[derive(Encodable, Decodable, HashStable_Generic)]
739pub enum ByRef {
740 Yes(Mutability),
741 No,
742}
743
744impl ByRef {
745 #[must_use]
746 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
747 if let ByRef::Yes(old_mutbl) = &mut self {
748 *old_mutbl = cmp::min(*old_mutbl, mutbl);
749 }
750 self
751 }
752}
753
754#[derive(Clone, Copy, Debug, Eq, PartialEq)]
760#[derive(Encodable, Decodable, HashStable_Generic)]
761pub struct BindingMode(pub ByRef, pub Mutability);
762
763impl BindingMode {
764 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
765 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
766 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
767 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
768 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
769 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
770
771 pub fn prefix_str(self) -> &'static str {
772 match self {
773 Self::NONE => "",
774 Self::REF => "ref ",
775 Self::MUT => "mut ",
776 Self::REF_MUT => "ref mut ",
777 Self::MUT_REF => "mut ref ",
778 Self::MUT_REF_MUT => "mut ref mut ",
779 }
780 }
781}
782
783#[derive(Clone, Encodable, Decodable, Debug)]
784pub enum RangeEnd {
785 Included(RangeSyntax),
787 Excluded,
789}
790
791#[derive(Clone, Encodable, Decodable, Debug)]
792pub enum RangeSyntax {
793 DotDotDot,
795 DotDotEq,
797}
798
799#[derive(Clone, Encodable, Decodable, Debug)]
803pub enum PatKind {
804 Missing,
806
807 Wild,
809
810 Ident(BindingMode, Ident, Option<P<Pat>>),
815
816 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
818
819 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
821
822 Or(ThinVec<P<Pat>>),
825
826 Path(Option<P<QSelf>>, Path),
831
832 Tuple(ThinVec<P<Pat>>),
834
835 Box(P<Pat>),
837
838 Deref(P<Pat>),
840
841 Ref(P<Pat>, Mutability),
843
844 Expr(P<Expr>),
846
847 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
849
850 Slice(ThinVec<P<Pat>>),
852
853 Rest,
866
867 Never,
869
870 Guard(P<Pat>, P<Expr>),
872
873 Paren(P<Pat>),
875
876 MacCall(P<MacCall>),
878
879 Err(ErrorGuaranteed),
881}
882
883#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
885pub enum PatFieldsRest {
886 Rest,
888 Recovered(ErrorGuaranteed),
890 None,
892}
893
894#[derive(Clone, Copy, PartialEq, Eq, Debug)]
897#[derive(Encodable, Decodable, HashStable_Generic)]
898pub enum BorrowKind {
899 Ref,
903 Raw,
907}
908
909#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
910pub enum BinOpKind {
911 Add,
913 Sub,
915 Mul,
917 Div,
919 Rem,
921 And,
923 Or,
925 BitXor,
927 BitAnd,
929 BitOr,
931 Shl,
933 Shr,
935 Eq,
937 Lt,
939 Le,
941 Ne,
943 Ge,
945 Gt,
947}
948
949impl BinOpKind {
950 pub fn as_str(&self) -> &'static str {
951 use BinOpKind::*;
952 match self {
953 Add => "+",
954 Sub => "-",
955 Mul => "*",
956 Div => "/",
957 Rem => "%",
958 And => "&&",
959 Or => "||",
960 BitXor => "^",
961 BitAnd => "&",
962 BitOr => "|",
963 Shl => "<<",
964 Shr => ">>",
965 Eq => "==",
966 Lt => "<",
967 Le => "<=",
968 Ne => "!=",
969 Ge => ">=",
970 Gt => ">",
971 }
972 }
973
974 pub fn is_lazy(&self) -> bool {
975 matches!(self, BinOpKind::And | BinOpKind::Or)
976 }
977
978 pub fn precedence(&self) -> ExprPrecedence {
979 use BinOpKind::*;
980 match *self {
981 Mul | Div | Rem => ExprPrecedence::Product,
982 Add | Sub => ExprPrecedence::Sum,
983 Shl | Shr => ExprPrecedence::Shift,
984 BitAnd => ExprPrecedence::BitAnd,
985 BitXor => ExprPrecedence::BitXor,
986 BitOr => ExprPrecedence::BitOr,
987 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
988 And => ExprPrecedence::LAnd,
989 Or => ExprPrecedence::LOr,
990 }
991 }
992
993 pub fn fixity(&self) -> Fixity {
994 use BinOpKind::*;
995 match self {
996 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
997 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
998 Fixity::Left
999 }
1000 }
1001 }
1002
1003 pub fn is_comparison(self) -> bool {
1004 use BinOpKind::*;
1005 match self {
1006 Eq | Ne | Lt | Le | Gt | Ge => true,
1007 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1008 }
1009 }
1010
1011 pub fn is_by_value(self) -> bool {
1013 !self.is_comparison()
1014 }
1015}
1016
1017pub type BinOp = Spanned<BinOpKind>;
1018
1019impl From<AssignOpKind> for BinOpKind {
1023 fn from(op: AssignOpKind) -> BinOpKind {
1024 match op {
1025 AssignOpKind::AddAssign => BinOpKind::Add,
1026 AssignOpKind::SubAssign => BinOpKind::Sub,
1027 AssignOpKind::MulAssign => BinOpKind::Mul,
1028 AssignOpKind::DivAssign => BinOpKind::Div,
1029 AssignOpKind::RemAssign => BinOpKind::Rem,
1030 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1031 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1032 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1033 AssignOpKind::ShlAssign => BinOpKind::Shl,
1034 AssignOpKind::ShrAssign => BinOpKind::Shr,
1035 }
1036 }
1037}
1038
1039#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1040pub enum AssignOpKind {
1041 AddAssign,
1043 SubAssign,
1045 MulAssign,
1047 DivAssign,
1049 RemAssign,
1051 BitXorAssign,
1053 BitAndAssign,
1055 BitOrAssign,
1057 ShlAssign,
1059 ShrAssign,
1061}
1062
1063impl AssignOpKind {
1064 pub fn as_str(&self) -> &'static str {
1065 use AssignOpKind::*;
1066 match self {
1067 AddAssign => "+=",
1068 SubAssign => "-=",
1069 MulAssign => "*=",
1070 DivAssign => "/=",
1071 RemAssign => "%=",
1072 BitXorAssign => "^=",
1073 BitAndAssign => "&=",
1074 BitOrAssign => "|=",
1075 ShlAssign => "<<=",
1076 ShrAssign => ">>=",
1077 }
1078 }
1079
1080 pub fn is_by_value(self) -> bool {
1082 true
1083 }
1084}
1085
1086pub type AssignOp = Spanned<AssignOpKind>;
1087
1088#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1092pub enum UnOp {
1093 Deref,
1095 Not,
1097 Neg,
1099}
1100
1101impl UnOp {
1102 pub fn as_str(&self) -> &'static str {
1103 match self {
1104 UnOp::Deref => "*",
1105 UnOp::Not => "!",
1106 UnOp::Neg => "-",
1107 }
1108 }
1109
1110 pub fn is_by_value(self) -> bool {
1112 matches!(self, Self::Neg | Self::Not)
1113 }
1114}
1115
1116#[derive(Clone, Encodable, Decodable, Debug)]
1120pub struct Stmt {
1121 pub id: NodeId,
1122 pub kind: StmtKind,
1123 pub span: Span,
1124}
1125
1126impl Stmt {
1127 pub fn has_trailing_semicolon(&self) -> bool {
1128 match &self.kind {
1129 StmtKind::Semi(_) => true,
1130 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1131 _ => false,
1132 }
1133 }
1134
1135 pub fn add_trailing_semicolon(mut self) -> Self {
1143 self.kind = match self.kind {
1144 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1145 StmtKind::MacCall(mut mac) => {
1146 mac.style = MacStmtStyle::Semicolon;
1147 StmtKind::MacCall(mac)
1148 }
1149 kind => kind,
1150 };
1151
1152 self
1153 }
1154
1155 pub fn is_item(&self) -> bool {
1156 matches!(self.kind, StmtKind::Item(_))
1157 }
1158
1159 pub fn is_expr(&self) -> bool {
1160 matches!(self.kind, StmtKind::Expr(_))
1161 }
1162}
1163
1164#[derive(Clone, Encodable, Decodable, Debug)]
1166pub enum StmtKind {
1167 Let(P<Local>),
1169 Item(P<Item>),
1171 Expr(P<Expr>),
1173 Semi(P<Expr>),
1175 Empty,
1177 MacCall(P<MacCallStmt>),
1179}
1180
1181#[derive(Clone, Encodable, Decodable, Debug)]
1182pub struct MacCallStmt {
1183 pub mac: P<MacCall>,
1184 pub style: MacStmtStyle,
1185 pub attrs: AttrVec,
1186 pub tokens: Option<LazyAttrTokenStream>,
1187}
1188
1189#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1190pub enum MacStmtStyle {
1191 Semicolon,
1194 Braces,
1196 NoBraces,
1200}
1201
1202#[derive(Clone, Encodable, Decodable, Debug)]
1204pub struct Local {
1205 pub id: NodeId,
1206 pub super_: Option<Span>,
1207 pub pat: P<Pat>,
1208 pub ty: Option<P<Ty>>,
1209 pub kind: LocalKind,
1210 pub span: Span,
1211 pub colon_sp: Option<Span>,
1212 pub attrs: AttrVec,
1213 pub tokens: Option<LazyAttrTokenStream>,
1214}
1215
1216#[derive(Clone, Encodable, Decodable, Debug)]
1217pub enum LocalKind {
1218 Decl,
1221 Init(P<Expr>),
1224 InitElse(P<Expr>, P<Block>),
1227}
1228
1229impl LocalKind {
1230 pub fn init(&self) -> Option<&Expr> {
1231 match self {
1232 Self::Decl => None,
1233 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1234 }
1235 }
1236
1237 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1238 match self {
1239 Self::Decl => None,
1240 Self::Init(init) => Some((init, None)),
1241 Self::InitElse(init, els) => Some((init, Some(els))),
1242 }
1243 }
1244}
1245
1246#[derive(Clone, Encodable, Decodable, Debug)]
1257pub struct Arm {
1258 pub attrs: AttrVec,
1259 pub pat: P<Pat>,
1261 pub guard: Option<P<Expr>>,
1263 pub body: Option<P<Expr>>,
1265 pub span: Span,
1266 pub id: NodeId,
1267 pub is_placeholder: bool,
1268}
1269
1270#[derive(Clone, Encodable, Decodable, Debug)]
1272pub struct ExprField {
1273 pub attrs: AttrVec,
1274 pub id: NodeId,
1275 pub span: Span,
1276 pub ident: Ident,
1277 pub expr: P<Expr>,
1278 pub is_shorthand: bool,
1279 pub is_placeholder: bool,
1280}
1281
1282#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1283pub enum BlockCheckMode {
1284 Default,
1285 Unsafe(UnsafeSource),
1286}
1287
1288#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1289pub enum UnsafeSource {
1290 CompilerGenerated,
1291 UserProvided,
1292}
1293
1294#[derive(Clone, Encodable, Decodable, Debug)]
1300pub struct AnonConst {
1301 pub id: NodeId,
1302 pub value: P<Expr>,
1303}
1304
1305#[derive(Clone, Encodable, Decodable, Debug)]
1307pub struct Expr {
1308 pub id: NodeId,
1309 pub kind: ExprKind,
1310 pub span: Span,
1311 pub attrs: AttrVec,
1312 pub tokens: Option<LazyAttrTokenStream>,
1313}
1314
1315impl Expr {
1316 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1330 let this = self.maybe_unwrap_block();
1331 if allow_mgca_arg {
1332 matches!(this.kind, ExprKind::Path(..))
1333 } else {
1334 if let ExprKind::Path(None, path) = &this.kind
1335 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1336 {
1337 true
1338 } else {
1339 false
1340 }
1341 }
1342 }
1343
1344 pub fn maybe_unwrap_block(&self) -> &Expr {
1346 if let ExprKind::Block(block, None) = &self.kind
1347 && let [stmt] = block.stmts.as_slice()
1348 && let StmtKind::Expr(expr) = &stmt.kind
1349 {
1350 expr
1351 } else {
1352 self
1353 }
1354 }
1355
1356 pub fn optionally_braced_mac_call(
1362 &self,
1363 already_stripped_block: bool,
1364 ) -> Option<(bool, NodeId)> {
1365 match &self.kind {
1366 ExprKind::Block(block, None)
1367 if let [stmt] = &*block.stmts
1368 && !already_stripped_block =>
1369 {
1370 match &stmt.kind {
1371 StmtKind::MacCall(_) => Some((true, stmt.id)),
1372 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1373 Some((true, expr.id))
1374 }
1375 _ => None,
1376 }
1377 }
1378 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1379 _ => None,
1380 }
1381 }
1382
1383 pub fn to_bound(&self) -> Option<GenericBound> {
1384 match &self.kind {
1385 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1386 ThinVec::new(),
1387 path.clone(),
1388 TraitBoundModifiers::NONE,
1389 self.span,
1390 ))),
1391 _ => None,
1392 }
1393 }
1394
1395 pub fn peel_parens(&self) -> &Expr {
1396 let mut expr = self;
1397 while let ExprKind::Paren(inner) = &expr.kind {
1398 expr = inner;
1399 }
1400 expr
1401 }
1402
1403 pub fn peel_parens_and_refs(&self) -> &Expr {
1404 let mut expr = self;
1405 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1406 {
1407 expr = inner;
1408 }
1409 expr
1410 }
1411
1412 pub fn to_ty(&self) -> Option<P<Ty>> {
1414 let kind = match &self.kind {
1415 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1417 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1418
1419 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1420
1421 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1422 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1423 }
1424
1425 ExprKind::Repeat(expr, expr_len) => {
1426 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1427 }
1428
1429 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1430 expr.to_ty().map(TyKind::Slice)?
1431 }
1432
1433 ExprKind::Tup(exprs) => {
1434 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1435 TyKind::Tup(tys)
1436 }
1437
1438 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1442 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1443 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1444 } else {
1445 return None;
1446 }
1447 }
1448
1449 ExprKind::Underscore => TyKind::Infer,
1450
1451 _ => return None,
1453 };
1454
1455 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1456 }
1457
1458 pub fn precedence(&self) -> ExprPrecedence {
1459 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1460 for attr in attrs {
1461 if let AttrStyle::Outer = attr.style {
1462 return ExprPrecedence::Prefix;
1463 }
1464 }
1465 ExprPrecedence::Unambiguous
1466 }
1467
1468 match &self.kind {
1469 ExprKind::Closure(closure) => {
1470 match closure.fn_decl.output {
1471 FnRetTy::Default(_) => ExprPrecedence::Jump,
1472 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1473 }
1474 }
1475
1476 ExprKind::Break(_ , value)
1477 | ExprKind::Ret(value)
1478 | ExprKind::Yield(YieldKind::Prefix(value))
1479 | ExprKind::Yeet(value) => match value {
1480 Some(_) => ExprPrecedence::Jump,
1481 None => prefix_attrs_precedence(&self.attrs),
1482 },
1483
1484 ExprKind::Become(_) => ExprPrecedence::Jump,
1485
1486 ExprKind::Range(..) => ExprPrecedence::Range,
1491
1492 ExprKind::Binary(op, ..) => op.node.precedence(),
1494 ExprKind::Cast(..) => ExprPrecedence::Cast,
1495
1496 ExprKind::Assign(..) |
1497 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1498
1499 ExprKind::AddrOf(..)
1501 | ExprKind::Let(..)
1506 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1507
1508 ExprKind::Array(_)
1510 | ExprKind::Await(..)
1511 | ExprKind::Use(..)
1512 | ExprKind::Block(..)
1513 | ExprKind::Call(..)
1514 | ExprKind::ConstBlock(_)
1515 | ExprKind::Continue(..)
1516 | ExprKind::Field(..)
1517 | ExprKind::ForLoop { .. }
1518 | ExprKind::FormatArgs(..)
1519 | ExprKind::Gen(..)
1520 | ExprKind::If(..)
1521 | ExprKind::IncludedBytes(..)
1522 | ExprKind::Index(..)
1523 | ExprKind::InlineAsm(..)
1524 | ExprKind::Lit(_)
1525 | ExprKind::Loop(..)
1526 | ExprKind::MacCall(..)
1527 | ExprKind::Match(..)
1528 | ExprKind::MethodCall(..)
1529 | ExprKind::OffsetOf(..)
1530 | ExprKind::Paren(..)
1531 | ExprKind::Path(..)
1532 | ExprKind::Repeat(..)
1533 | ExprKind::Struct(..)
1534 | ExprKind::Try(..)
1535 | ExprKind::TryBlock(..)
1536 | ExprKind::Tup(_)
1537 | ExprKind::Type(..)
1538 | ExprKind::Underscore
1539 | ExprKind::UnsafeBinderCast(..)
1540 | ExprKind::While(..)
1541 | ExprKind::Yield(YieldKind::Postfix(..))
1542 | ExprKind::Err(_)
1543 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1544 }
1545 }
1546
1547 pub fn is_approximately_pattern(&self) -> bool {
1549 matches!(
1550 &self.peel_parens().kind,
1551 ExprKind::Array(_)
1552 | ExprKind::Call(_, _)
1553 | ExprKind::Tup(_)
1554 | ExprKind::Lit(_)
1555 | ExprKind::Range(_, _, _)
1556 | ExprKind::Underscore
1557 | ExprKind::Path(_, _)
1558 | ExprKind::Struct(_)
1559 )
1560 }
1561
1562 pub fn dummy() -> Expr {
1566 Expr {
1567 id: DUMMY_NODE_ID,
1568 kind: ExprKind::Dummy,
1569 span: DUMMY_SP,
1570 attrs: ThinVec::new(),
1571 tokens: None,
1572 }
1573 }
1574}
1575
1576impl From<P<Expr>> for Expr {
1577 fn from(value: P<Expr>) -> Self {
1578 *value
1579 }
1580}
1581
1582#[derive(Clone, Encodable, Decodable, Debug)]
1583pub struct Closure {
1584 pub binder: ClosureBinder,
1585 pub capture_clause: CaptureBy,
1586 pub constness: Const,
1587 pub coroutine_kind: Option<CoroutineKind>,
1588 pub movability: Movability,
1589 pub fn_decl: P<FnDecl>,
1590 pub body: P<Expr>,
1591 pub fn_decl_span: Span,
1593 pub fn_arg_span: Span,
1595}
1596
1597#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1599pub enum RangeLimits {
1600 HalfOpen,
1602 Closed,
1604}
1605
1606impl RangeLimits {
1607 pub fn as_str(&self) -> &'static str {
1608 match self {
1609 RangeLimits::HalfOpen => "..",
1610 RangeLimits::Closed => "..=",
1611 }
1612 }
1613}
1614
1615#[derive(Clone, Encodable, Decodable, Debug)]
1617pub struct MethodCall {
1618 pub seg: PathSegment,
1620 pub receiver: P<Expr>,
1622 pub args: ThinVec<P<Expr>>,
1624 pub span: Span,
1627}
1628
1629#[derive(Clone, Encodable, Decodable, Debug)]
1630pub enum StructRest {
1631 Base(P<Expr>),
1633 Rest(Span),
1635 None,
1637}
1638
1639#[derive(Clone, Encodable, Decodable, Debug)]
1640pub struct StructExpr {
1641 pub qself: Option<P<QSelf>>,
1642 pub path: Path,
1643 pub fields: ThinVec<ExprField>,
1644 pub rest: StructRest,
1645}
1646
1647#[derive(Clone, Encodable, Decodable, Debug)]
1649pub enum ExprKind {
1650 Array(ThinVec<P<Expr>>),
1652 ConstBlock(AnonConst),
1654 Call(P<Expr>, ThinVec<P<Expr>>),
1661 MethodCall(Box<MethodCall>),
1663 Tup(ThinVec<P<Expr>>),
1665 Binary(BinOp, P<Expr>, P<Expr>),
1667 Unary(UnOp, P<Expr>),
1669 Lit(token::Lit),
1671 Cast(P<Expr>, P<Ty>),
1673 Type(P<Expr>, P<Ty>),
1678 Let(P<Pat>, P<Expr>, Span, Recovered),
1683 If(P<Expr>, P<Block>, Option<P<Expr>>),
1690 While(P<Expr>, P<Block>, Option<Label>),
1694 ForLoop {
1700 pat: P<Pat>,
1701 iter: P<Expr>,
1702 body: P<Block>,
1703 label: Option<Label>,
1704 kind: ForLoopKind,
1705 },
1706 Loop(P<Block>, Option<Label>, Span),
1710 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1712 Closure(Box<Closure>),
1714 Block(P<Block>, Option<Label>),
1716 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1722 Await(P<Expr>, Span),
1724 Use(P<Expr>, Span),
1726
1727 TryBlock(P<Block>),
1729
1730 Assign(P<Expr>, P<Expr>, Span),
1733 AssignOp(AssignOp, P<Expr>, P<Expr>),
1737 Field(P<Expr>, Ident),
1739 Index(P<Expr>, P<Expr>, Span),
1742 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1744 Underscore,
1746
1747 Path(Option<P<QSelf>>, Path),
1752
1753 AddrOf(BorrowKind, Mutability, P<Expr>),
1755 Break(Option<Label>, Option<P<Expr>>),
1757 Continue(Option<Label>),
1759 Ret(Option<P<Expr>>),
1761
1762 InlineAsm(P<InlineAsm>),
1764
1765 OffsetOf(P<Ty>, Vec<Ident>),
1770
1771 MacCall(P<MacCall>),
1773
1774 Struct(P<StructExpr>),
1778
1779 Repeat(P<Expr>, AnonConst),
1784
1785 Paren(P<Expr>),
1787
1788 Try(P<Expr>),
1790
1791 Yield(YieldKind),
1793
1794 Yeet(Option<P<Expr>>),
1797
1798 Become(P<Expr>),
1802
1803 IncludedBytes(Arc<[u8]>),
1808
1809 FormatArgs(P<FormatArgs>),
1811
1812 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1813
1814 Err(ErrorGuaranteed),
1816
1817 Dummy,
1819}
1820
1821#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1823pub enum ForLoopKind {
1824 For,
1825 ForAwait,
1826}
1827
1828#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1830pub enum GenBlockKind {
1831 Async,
1832 Gen,
1833 AsyncGen,
1834}
1835
1836impl fmt::Display for GenBlockKind {
1837 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1838 self.modifier().fmt(f)
1839 }
1840}
1841
1842impl GenBlockKind {
1843 pub fn modifier(&self) -> &'static str {
1844 match self {
1845 GenBlockKind::Async => "async",
1846 GenBlockKind::Gen => "gen",
1847 GenBlockKind::AsyncGen => "async gen",
1848 }
1849 }
1850}
1851
1852#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1854#[derive(Encodable, Decodable, HashStable_Generic)]
1855pub enum UnsafeBinderCastKind {
1856 Wrap,
1858 Unwrap,
1860}
1861
1862#[derive(Clone, Encodable, Decodable, Debug)]
1877pub struct QSelf {
1878 pub ty: P<Ty>,
1879
1880 pub path_span: Span,
1884 pub position: usize,
1885}
1886
1887#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1889pub enum CaptureBy {
1890 Value {
1892 move_kw: Span,
1894 },
1895 Ref,
1897 Use {
1903 use_kw: Span,
1905 },
1906}
1907
1908#[derive(Clone, Encodable, Decodable, Debug)]
1910pub enum ClosureBinder {
1911 NotPresent,
1913 For {
1915 span: Span,
1922
1923 generic_params: ThinVec<GenericParam>,
1930 },
1931}
1932
1933#[derive(Clone, Encodable, Decodable, Debug)]
1936pub struct MacCall {
1937 pub path: Path,
1938 pub args: P<DelimArgs>,
1939}
1940
1941impl MacCall {
1942 pub fn span(&self) -> Span {
1943 self.path.span.to(self.args.dspan.entire())
1944 }
1945}
1946
1947#[derive(Clone, Encodable, Decodable, Debug)]
1949pub enum AttrArgs {
1950 Empty,
1952 Delimited(DelimArgs),
1954 Eq {
1956 eq_span: Span,
1958 expr: P<Expr>,
1959 },
1960}
1961
1962impl AttrArgs {
1963 pub fn span(&self) -> Option<Span> {
1964 match self {
1965 AttrArgs::Empty => None,
1966 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1967 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1968 }
1969 }
1970
1971 pub fn inner_tokens(&self) -> TokenStream {
1974 match self {
1975 AttrArgs::Empty => TokenStream::default(),
1976 AttrArgs::Delimited(args) => args.tokens.clone(),
1977 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1978 }
1979 }
1980}
1981
1982#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1984pub struct DelimArgs {
1985 pub dspan: DelimSpan,
1986 pub delim: Delimiter, pub tokens: TokenStream,
1988}
1989
1990impl DelimArgs {
1991 pub fn need_semicolon(&self) -> bool {
1994 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1995 }
1996}
1997
1998#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2000pub struct MacroDef {
2001 pub body: P<DelimArgs>,
2002 pub macro_rules: bool,
2004}
2005
2006#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2007#[derive(HashStable_Generic)]
2008pub enum StrStyle {
2009 Cooked,
2011 Raw(u8),
2015}
2016
2017#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
2019pub enum MatchKind {
2020 Prefix,
2022 Postfix,
2024}
2025
2026#[derive(Clone, Encodable, Decodable, Debug)]
2028pub enum YieldKind {
2029 Prefix(Option<P<Expr>>),
2031 Postfix(P<Expr>),
2033}
2034
2035impl YieldKind {
2036 pub const fn expr(&self) -> Option<&P<Expr>> {
2040 match self {
2041 YieldKind::Prefix(expr) => expr.as_ref(),
2042 YieldKind::Postfix(expr) => Some(expr),
2043 }
2044 }
2045
2046 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2048 match self {
2049 YieldKind::Prefix(expr) => expr.as_mut(),
2050 YieldKind::Postfix(expr) => Some(expr),
2051 }
2052 }
2053
2054 pub const fn same_kind(&self, other: &Self) -> bool {
2056 match (self, other) {
2057 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2058 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2059 _ => false,
2060 }
2061 }
2062}
2063
2064#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2066pub struct MetaItemLit {
2067 pub symbol: Symbol,
2069 pub suffix: Option<Symbol>,
2071 pub kind: LitKind,
2074 pub span: Span,
2075}
2076
2077#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2079pub struct StrLit {
2080 pub symbol: Symbol,
2082 pub suffix: Option<Symbol>,
2084 pub symbol_unescaped: Symbol,
2086 pub style: StrStyle,
2087 pub span: Span,
2088}
2089
2090impl StrLit {
2091 pub fn as_token_lit(&self) -> token::Lit {
2092 let token_kind = match self.style {
2093 StrStyle::Cooked => token::Str,
2094 StrStyle::Raw(n) => token::StrRaw(n),
2095 };
2096 token::Lit::new(token_kind, self.symbol, self.suffix)
2097 }
2098}
2099
2100#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2102#[derive(HashStable_Generic)]
2103pub enum LitIntType {
2104 Signed(IntTy),
2106 Unsigned(UintTy),
2108 Unsuffixed,
2110}
2111
2112#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2114#[derive(HashStable_Generic)]
2115pub enum LitFloatType {
2116 Suffixed(FloatTy),
2118 Unsuffixed,
2120}
2121
2122#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2129pub enum LitKind {
2130 Str(Symbol, StrStyle),
2133 ByteStr(Arc<[u8]>, StrStyle),
2136 CStr(Arc<[u8]>, StrStyle),
2138 Byte(u8),
2140 Char(char),
2142 Int(Pu128, LitIntType),
2144 Float(Symbol, LitFloatType),
2148 Bool(bool),
2150 Err(ErrorGuaranteed),
2152}
2153
2154impl LitKind {
2155 pub fn str(&self) -> Option<Symbol> {
2156 match *self {
2157 LitKind::Str(s, _) => Some(s),
2158 _ => None,
2159 }
2160 }
2161
2162 pub fn is_str(&self) -> bool {
2164 matches!(self, LitKind::Str(..))
2165 }
2166
2167 pub fn is_bytestr(&self) -> bool {
2169 matches!(self, LitKind::ByteStr(..))
2170 }
2171
2172 pub fn is_numeric(&self) -> bool {
2174 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2175 }
2176
2177 pub fn is_unsuffixed(&self) -> bool {
2180 !self.is_suffixed()
2181 }
2182
2183 pub fn is_suffixed(&self) -> bool {
2185 match *self {
2186 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2188 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2189 LitKind::Str(..)
2191 | LitKind::ByteStr(..)
2192 | LitKind::CStr(..)
2193 | LitKind::Byte(..)
2194 | LitKind::Char(..)
2195 | LitKind::Int(_, LitIntType::Unsuffixed)
2196 | LitKind::Float(_, LitFloatType::Unsuffixed)
2197 | LitKind::Bool(..)
2198 | LitKind::Err(_) => false,
2199 }
2200 }
2201}
2202
2203#[derive(Clone, Encodable, Decodable, Debug)]
2206pub struct MutTy {
2207 pub ty: P<Ty>,
2208 pub mutbl: Mutability,
2209}
2210
2211#[derive(Clone, Encodable, Decodable, Debug)]
2214pub struct FnSig {
2215 pub header: FnHeader,
2216 pub decl: P<FnDecl>,
2217 pub span: Span,
2218}
2219
2220#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2221#[derive(Encodable, Decodable, HashStable_Generic)]
2222pub enum FloatTy {
2223 F16,
2224 F32,
2225 F64,
2226 F128,
2227}
2228
2229impl FloatTy {
2230 pub fn name_str(self) -> &'static str {
2231 match self {
2232 FloatTy::F16 => "f16",
2233 FloatTy::F32 => "f32",
2234 FloatTy::F64 => "f64",
2235 FloatTy::F128 => "f128",
2236 }
2237 }
2238
2239 pub fn name(self) -> Symbol {
2240 match self {
2241 FloatTy::F16 => sym::f16,
2242 FloatTy::F32 => sym::f32,
2243 FloatTy::F64 => sym::f64,
2244 FloatTy::F128 => sym::f128,
2245 }
2246 }
2247}
2248
2249#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2250#[derive(Encodable, Decodable, HashStable_Generic)]
2251pub enum IntTy {
2252 Isize,
2253 I8,
2254 I16,
2255 I32,
2256 I64,
2257 I128,
2258}
2259
2260impl IntTy {
2261 pub fn name_str(&self) -> &'static str {
2262 match *self {
2263 IntTy::Isize => "isize",
2264 IntTy::I8 => "i8",
2265 IntTy::I16 => "i16",
2266 IntTy::I32 => "i32",
2267 IntTy::I64 => "i64",
2268 IntTy::I128 => "i128",
2269 }
2270 }
2271
2272 pub fn name(&self) -> Symbol {
2273 match *self {
2274 IntTy::Isize => sym::isize,
2275 IntTy::I8 => sym::i8,
2276 IntTy::I16 => sym::i16,
2277 IntTy::I32 => sym::i32,
2278 IntTy::I64 => sym::i64,
2279 IntTy::I128 => sym::i128,
2280 }
2281 }
2282}
2283
2284#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2285#[derive(Encodable, Decodable, HashStable_Generic)]
2286pub enum UintTy {
2287 Usize,
2288 U8,
2289 U16,
2290 U32,
2291 U64,
2292 U128,
2293}
2294
2295impl UintTy {
2296 pub fn name_str(&self) -> &'static str {
2297 match *self {
2298 UintTy::Usize => "usize",
2299 UintTy::U8 => "u8",
2300 UintTy::U16 => "u16",
2301 UintTy::U32 => "u32",
2302 UintTy::U64 => "u64",
2303 UintTy::U128 => "u128",
2304 }
2305 }
2306
2307 pub fn name(&self) -> Symbol {
2308 match *self {
2309 UintTy::Usize => sym::usize,
2310 UintTy::U8 => sym::u8,
2311 UintTy::U16 => sym::u16,
2312 UintTy::U32 => sym::u32,
2313 UintTy::U64 => sym::u64,
2314 UintTy::U128 => sym::u128,
2315 }
2316 }
2317}
2318
2319#[derive(Clone, Encodable, Decodable, Debug)]
2330pub struct AssocItemConstraint {
2331 pub id: NodeId,
2332 pub ident: Ident,
2333 pub gen_args: Option<GenericArgs>,
2334 pub kind: AssocItemConstraintKind,
2335 pub span: Span,
2336}
2337
2338#[derive(Clone, Encodable, Decodable, Debug)]
2339pub enum Term {
2340 Ty(P<Ty>),
2341 Const(AnonConst),
2342}
2343
2344impl From<P<Ty>> for Term {
2345 fn from(v: P<Ty>) -> Self {
2346 Term::Ty(v)
2347 }
2348}
2349
2350impl From<AnonConst> for Term {
2351 fn from(v: AnonConst) -> Self {
2352 Term::Const(v)
2353 }
2354}
2355
2356#[derive(Clone, Encodable, Decodable, Debug)]
2358pub enum AssocItemConstraintKind {
2359 Equality { term: Term },
2366 Bound { bounds: GenericBounds },
2368}
2369
2370#[derive(Encodable, Decodable, Debug)]
2371pub struct Ty {
2372 pub id: NodeId,
2373 pub kind: TyKind,
2374 pub span: Span,
2375 pub tokens: Option<LazyAttrTokenStream>,
2376}
2377
2378impl Clone for Ty {
2379 fn clone(&self) -> Self {
2380 ensure_sufficient_stack(|| Self {
2381 id: self.id,
2382 kind: self.kind.clone(),
2383 span: self.span,
2384 tokens: self.tokens.clone(),
2385 })
2386 }
2387}
2388
2389impl From<P<Ty>> for Ty {
2390 fn from(value: P<Ty>) -> Self {
2391 *value
2392 }
2393}
2394
2395impl Ty {
2396 pub fn peel_refs(&self) -> &Self {
2397 let mut final_ty = self;
2398 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2399 {
2400 final_ty = ty;
2401 }
2402 final_ty
2403 }
2404
2405 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2406 match &self.kind {
2407 TyKind::Infer => true,
2408 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2409 _ => false,
2410 }
2411 }
2412}
2413
2414#[derive(Clone, Encodable, Decodable, Debug)]
2415pub struct BareFnTy {
2416 pub safety: Safety,
2417 pub ext: Extern,
2418 pub generic_params: ThinVec<GenericParam>,
2419 pub decl: P<FnDecl>,
2420 pub decl_span: Span,
2423}
2424
2425#[derive(Clone, Encodable, Decodable, Debug)]
2426pub struct UnsafeBinderTy {
2427 pub generic_params: ThinVec<GenericParam>,
2428 pub inner_ty: P<Ty>,
2429}
2430
2431#[derive(Clone, Encodable, Decodable, Debug)]
2435pub enum TyKind {
2436 Slice(P<Ty>),
2438 Array(P<Ty>, AnonConst),
2440 Ptr(MutTy),
2442 Ref(Option<Lifetime>, MutTy),
2444 PinnedRef(Option<Lifetime>, MutTy),
2448 BareFn(P<BareFnTy>),
2450 UnsafeBinder(P<UnsafeBinderTy>),
2452 Never,
2454 Tup(ThinVec<P<Ty>>),
2456 Path(Option<P<QSelf>>, Path),
2461 TraitObject(GenericBounds, TraitObjectSyntax),
2464 ImplTrait(NodeId, GenericBounds),
2471 Paren(P<Ty>),
2473 Typeof(AnonConst),
2475 Infer,
2478 ImplicitSelf,
2480 MacCall(P<MacCall>),
2482 CVarArgs,
2484 Pat(P<Ty>, P<TyPat>),
2487 Dummy,
2489 Err(ErrorGuaranteed),
2491}
2492
2493impl TyKind {
2494 pub fn is_implicit_self(&self) -> bool {
2495 matches!(self, TyKind::ImplicitSelf)
2496 }
2497
2498 pub fn is_unit(&self) -> bool {
2499 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2500 }
2501
2502 pub fn is_simple_path(&self) -> Option<Symbol> {
2503 if let TyKind::Path(None, Path { segments, .. }) = &self
2504 && let [segment] = &segments[..]
2505 && segment.args.is_none()
2506 {
2507 Some(segment.ident.name)
2508 } else {
2509 None
2510 }
2511 }
2512
2513 pub fn maybe_scalar(&self) -> bool {
2521 let Some(ty_sym) = self.is_simple_path() else {
2522 return self.is_unit();
2524 };
2525 matches!(
2526 ty_sym,
2527 sym::i8
2528 | sym::i16
2529 | sym::i32
2530 | sym::i64
2531 | sym::i128
2532 | sym::u8
2533 | sym::u16
2534 | sym::u32
2535 | sym::u64
2536 | sym::u128
2537 | sym::f16
2538 | sym::f32
2539 | sym::f64
2540 | sym::f128
2541 | sym::char
2542 | sym::bool
2543 )
2544 }
2545}
2546
2547#[derive(Clone, Encodable, Decodable, Debug)]
2549pub struct TyPat {
2550 pub id: NodeId,
2551 pub kind: TyPatKind,
2552 pub span: Span,
2553 pub tokens: Option<LazyAttrTokenStream>,
2554}
2555
2556#[derive(Clone, Encodable, Decodable, Debug)]
2560pub enum TyPatKind {
2561 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2563
2564 Or(ThinVec<P<TyPat>>),
2565
2566 Err(ErrorGuaranteed),
2568}
2569
2570#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2572#[repr(u8)]
2573pub enum TraitObjectSyntax {
2574 Dyn = 0,
2576 DynStar = 1,
2577 None = 2,
2578}
2579
2580unsafe impl Tag for TraitObjectSyntax {
2584 const BITS: u32 = 2;
2585
2586 fn into_usize(self) -> usize {
2587 self as u8 as usize
2588 }
2589
2590 unsafe fn from_usize(tag: usize) -> Self {
2591 match tag {
2592 0 => TraitObjectSyntax::Dyn,
2593 1 => TraitObjectSyntax::DynStar,
2594 2 => TraitObjectSyntax::None,
2595 _ => unreachable!(),
2596 }
2597 }
2598}
2599
2600#[derive(Clone, Encodable, Decodable, Debug)]
2601pub enum PreciseCapturingArg {
2602 Lifetime(Lifetime),
2604 Arg(Path, NodeId),
2606}
2607
2608#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2612pub enum InlineAsmRegOrRegClass {
2613 Reg(Symbol),
2614 RegClass(Symbol),
2615}
2616
2617#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2618pub struct InlineAsmOptions(u16);
2619bitflags::bitflags! {
2620 impl InlineAsmOptions: u16 {
2621 const PURE = 1 << 0;
2622 const NOMEM = 1 << 1;
2623 const READONLY = 1 << 2;
2624 const PRESERVES_FLAGS = 1 << 3;
2625 const NORETURN = 1 << 4;
2626 const NOSTACK = 1 << 5;
2627 const ATT_SYNTAX = 1 << 6;
2628 const RAW = 1 << 7;
2629 const MAY_UNWIND = 1 << 8;
2630 }
2631}
2632
2633impl InlineAsmOptions {
2634 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2635
2636 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2637 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2638
2639 pub fn human_readable_names(&self) -> Vec<&'static str> {
2640 let mut options = vec![];
2641
2642 if self.contains(InlineAsmOptions::PURE) {
2643 options.push("pure");
2644 }
2645 if self.contains(InlineAsmOptions::NOMEM) {
2646 options.push("nomem");
2647 }
2648 if self.contains(InlineAsmOptions::READONLY) {
2649 options.push("readonly");
2650 }
2651 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2652 options.push("preserves_flags");
2653 }
2654 if self.contains(InlineAsmOptions::NORETURN) {
2655 options.push("noreturn");
2656 }
2657 if self.contains(InlineAsmOptions::NOSTACK) {
2658 options.push("nostack");
2659 }
2660 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2661 options.push("att_syntax");
2662 }
2663 if self.contains(InlineAsmOptions::RAW) {
2664 options.push("raw");
2665 }
2666 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2667 options.push("may_unwind");
2668 }
2669
2670 options
2671 }
2672}
2673
2674impl std::fmt::Debug for InlineAsmOptions {
2675 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2676 bitflags::parser::to_writer(self, f)
2677 }
2678}
2679
2680#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2681pub enum InlineAsmTemplatePiece {
2682 String(Cow<'static, str>),
2683 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2684}
2685
2686impl fmt::Display for InlineAsmTemplatePiece {
2687 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2688 match self {
2689 Self::String(s) => {
2690 for c in s.chars() {
2691 match c {
2692 '{' => f.write_str("{{")?,
2693 '}' => f.write_str("}}")?,
2694 _ => c.fmt(f)?,
2695 }
2696 }
2697 Ok(())
2698 }
2699 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2700 write!(f, "{{{operand_idx}:{modifier}}}")
2701 }
2702 Self::Placeholder { operand_idx, modifier: None, .. } => {
2703 write!(f, "{{{operand_idx}}}")
2704 }
2705 }
2706 }
2707}
2708
2709impl InlineAsmTemplatePiece {
2710 pub fn to_string(s: &[Self]) -> String {
2712 use fmt::Write;
2713 let mut out = String::new();
2714 for p in s.iter() {
2715 let _ = write!(out, "{p}");
2716 }
2717 out
2718 }
2719}
2720
2721#[derive(Clone, Encodable, Decodable, Debug)]
2729pub struct InlineAsmSym {
2730 pub id: NodeId,
2731 pub qself: Option<P<QSelf>>,
2732 pub path: Path,
2733}
2734
2735#[derive(Clone, Encodable, Decodable, Debug)]
2739pub enum InlineAsmOperand {
2740 In {
2741 reg: InlineAsmRegOrRegClass,
2742 expr: P<Expr>,
2743 },
2744 Out {
2745 reg: InlineAsmRegOrRegClass,
2746 late: bool,
2747 expr: Option<P<Expr>>,
2748 },
2749 InOut {
2750 reg: InlineAsmRegOrRegClass,
2751 late: bool,
2752 expr: P<Expr>,
2753 },
2754 SplitInOut {
2755 reg: InlineAsmRegOrRegClass,
2756 late: bool,
2757 in_expr: P<Expr>,
2758 out_expr: Option<P<Expr>>,
2759 },
2760 Const {
2761 anon_const: AnonConst,
2762 },
2763 Sym {
2764 sym: InlineAsmSym,
2765 },
2766 Label {
2767 block: P<Block>,
2768 },
2769}
2770
2771impl InlineAsmOperand {
2772 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2773 match self {
2774 Self::In { reg, .. }
2775 | Self::Out { reg, .. }
2776 | Self::InOut { reg, .. }
2777 | Self::SplitInOut { reg, .. } => Some(reg),
2778 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2779 }
2780 }
2781}
2782
2783#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2784pub enum AsmMacro {
2785 Asm,
2787 GlobalAsm,
2789 NakedAsm,
2791}
2792
2793impl AsmMacro {
2794 pub const fn macro_name(self) -> &'static str {
2795 match self {
2796 AsmMacro::Asm => "asm",
2797 AsmMacro::GlobalAsm => "global_asm",
2798 AsmMacro::NakedAsm => "naked_asm",
2799 }
2800 }
2801
2802 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2803 match self {
2804 AsmMacro::Asm => true,
2805 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2806 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2807 }
2808 }
2809
2810 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2811 match self {
2812 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2813 AsmMacro::GlobalAsm => true,
2814 AsmMacro::NakedAsm => true,
2815 }
2816 }
2817}
2818
2819#[derive(Clone, Encodable, Decodable, Debug)]
2823pub struct InlineAsm {
2824 pub asm_macro: AsmMacro,
2825 pub template: Vec<InlineAsmTemplatePiece>,
2826 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2827 pub operands: Vec<(InlineAsmOperand, Span)>,
2828 pub clobber_abis: Vec<(Symbol, Span)>,
2829 pub options: InlineAsmOptions,
2830 pub line_spans: Vec<Span>,
2831}
2832
2833#[derive(Clone, Encodable, Decodable, Debug)]
2837pub struct Param {
2838 pub attrs: AttrVec,
2839 pub ty: P<Ty>,
2840 pub pat: P<Pat>,
2841 pub id: NodeId,
2842 pub span: Span,
2843 pub is_placeholder: bool,
2844}
2845
2846#[derive(Clone, Encodable, Decodable, Debug)]
2850pub enum SelfKind {
2851 Value(Mutability),
2853 Region(Option<Lifetime>, Mutability),
2855 Pinned(Option<Lifetime>, Mutability),
2857 Explicit(P<Ty>, Mutability),
2859}
2860
2861impl SelfKind {
2862 pub fn to_ref_suggestion(&self) -> String {
2863 match self {
2864 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2865 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2866 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2867 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2868 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2869 unreachable!("if we had an explicit self, we wouldn't be here")
2870 }
2871 }
2872 }
2873}
2874
2875pub type ExplicitSelf = Spanned<SelfKind>;
2876
2877impl Param {
2878 pub fn to_self(&self) -> Option<ExplicitSelf> {
2880 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2881 if ident.name == kw::SelfLower {
2882 return match self.ty.kind {
2883 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2884 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2885 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2886 }
2887 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2888 if ty.kind.is_implicit_self() =>
2889 {
2890 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2891 }
2892 _ => Some(respan(
2893 self.pat.span.to(self.ty.span),
2894 SelfKind::Explicit(self.ty.clone(), mutbl),
2895 )),
2896 };
2897 }
2898 }
2899 None
2900 }
2901
2902 pub fn is_self(&self) -> bool {
2904 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2905 ident.name == kw::SelfLower
2906 } else {
2907 false
2908 }
2909 }
2910
2911 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2913 let span = eself.span.to(eself_ident.span);
2914 let infer_ty = P(Ty {
2915 id: DUMMY_NODE_ID,
2916 kind: TyKind::ImplicitSelf,
2917 span: eself_ident.span,
2918 tokens: None,
2919 });
2920 let (mutbl, ty) = match eself.node {
2921 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2922 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2923 SelfKind::Region(lt, mutbl) => (
2924 Mutability::Not,
2925 P(Ty {
2926 id: DUMMY_NODE_ID,
2927 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2928 span,
2929 tokens: None,
2930 }),
2931 ),
2932 SelfKind::Pinned(lt, mutbl) => (
2933 mutbl,
2934 P(Ty {
2935 id: DUMMY_NODE_ID,
2936 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2937 span,
2938 tokens: None,
2939 }),
2940 ),
2941 };
2942 Param {
2943 attrs,
2944 pat: P(Pat {
2945 id: DUMMY_NODE_ID,
2946 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2947 span,
2948 tokens: None,
2949 }),
2950 span,
2951 ty,
2952 id: DUMMY_NODE_ID,
2953 is_placeholder: false,
2954 }
2955 }
2956}
2957
2958#[derive(Clone, Encodable, Decodable, Debug)]
2965pub struct FnDecl {
2966 pub inputs: ThinVec<Param>,
2967 pub output: FnRetTy,
2968}
2969
2970impl FnDecl {
2971 pub fn has_self(&self) -> bool {
2972 self.inputs.get(0).is_some_and(Param::is_self)
2973 }
2974 pub fn c_variadic(&self) -> bool {
2975 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2976 }
2977}
2978
2979#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2981pub enum IsAuto {
2982 Yes,
2983 No,
2984}
2985
2986#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2988#[derive(HashStable_Generic)]
2989pub enum Safety {
2990 Unsafe(Span),
2992 Safe(Span),
2994 Default,
2997}
2998
2999#[derive(Copy, Clone, Encodable, Decodable, Debug)]
3005pub enum CoroutineKind {
3006 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3008 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3010 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3012}
3013
3014impl CoroutineKind {
3015 pub fn span(self) -> Span {
3016 match self {
3017 CoroutineKind::Async { span, .. } => span,
3018 CoroutineKind::Gen { span, .. } => span,
3019 CoroutineKind::AsyncGen { span, .. } => span,
3020 }
3021 }
3022
3023 pub fn as_str(self) -> &'static str {
3024 match self {
3025 CoroutineKind::Async { .. } => "async",
3026 CoroutineKind::Gen { .. } => "gen",
3027 CoroutineKind::AsyncGen { .. } => "async gen",
3028 }
3029 }
3030
3031 pub fn closure_id(self) -> NodeId {
3032 match self {
3033 CoroutineKind::Async { closure_id, .. }
3034 | CoroutineKind::Gen { closure_id, .. }
3035 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3036 }
3037 }
3038
3039 pub fn return_id(self) -> (NodeId, Span) {
3042 match self {
3043 CoroutineKind::Async { return_impl_trait_id, span, .. }
3044 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3045 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3046 (return_impl_trait_id, span)
3047 }
3048 }
3049 }
3050}
3051
3052#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3053#[derive(HashStable_Generic)]
3054pub enum Const {
3055 Yes(Span),
3056 No,
3057}
3058
3059#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3062pub enum Defaultness {
3063 Default(Span),
3064 Final,
3065}
3066
3067#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3068pub enum ImplPolarity {
3069 Positive,
3071 Negative(Span),
3073}
3074
3075impl fmt::Debug for ImplPolarity {
3076 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3077 match *self {
3078 ImplPolarity::Positive => "positive".fmt(f),
3079 ImplPolarity::Negative(_) => "negative".fmt(f),
3080 }
3081 }
3082}
3083
3084#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3086#[derive(HashStable_Generic)]
3087pub enum BoundPolarity {
3088 Positive,
3090 Negative(Span),
3092 Maybe(Span),
3094}
3095
3096impl BoundPolarity {
3097 pub fn as_str(self) -> &'static str {
3098 match self {
3099 Self::Positive => "",
3100 Self::Negative(_) => "!",
3101 Self::Maybe(_) => "?",
3102 }
3103 }
3104}
3105
3106#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3108#[derive(HashStable_Generic)]
3109pub enum BoundConstness {
3110 Never,
3112 Always(Span),
3114 Maybe(Span),
3116}
3117
3118impl BoundConstness {
3119 pub fn as_str(self) -> &'static str {
3120 match self {
3121 Self::Never => "",
3122 Self::Always(_) => "const",
3123 Self::Maybe(_) => "~const",
3124 }
3125 }
3126}
3127
3128#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3130#[derive(HashStable_Generic)]
3131pub enum BoundAsyncness {
3132 Normal,
3134 Async(Span),
3136}
3137
3138impl BoundAsyncness {
3139 pub fn as_str(self) -> &'static str {
3140 match self {
3141 Self::Normal => "",
3142 Self::Async(_) => "async",
3143 }
3144 }
3145}
3146
3147#[derive(Clone, Encodable, Decodable, Debug)]
3148pub enum FnRetTy {
3149 Default(Span),
3154 Ty(P<Ty>),
3156}
3157
3158impl FnRetTy {
3159 pub fn span(&self) -> Span {
3160 match self {
3161 &FnRetTy::Default(span) => span,
3162 FnRetTy::Ty(ty) => ty.span,
3163 }
3164 }
3165}
3166
3167#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3168pub enum Inline {
3169 Yes,
3170 No,
3171}
3172
3173#[derive(Clone, Encodable, Decodable, Debug)]
3175pub enum ModKind {
3176 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3181 Unloaded,
3183}
3184
3185#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3186pub struct ModSpans {
3187 pub inner_span: Span,
3190 pub inject_use_span: Span,
3191}
3192
3193#[derive(Clone, Encodable, Decodable, Debug)]
3197pub struct ForeignMod {
3198 pub extern_span: Span,
3200 pub safety: Safety,
3203 pub abi: Option<StrLit>,
3204 pub items: ThinVec<P<ForeignItem>>,
3205}
3206
3207#[derive(Clone, Encodable, Decodable, Debug)]
3208pub struct EnumDef {
3209 pub variants: ThinVec<Variant>,
3210}
3211#[derive(Clone, Encodable, Decodable, Debug)]
3213pub struct Variant {
3214 pub attrs: AttrVec,
3216 pub id: NodeId,
3218 pub span: Span,
3220 pub vis: Visibility,
3222 pub ident: Ident,
3224
3225 pub data: VariantData,
3227 pub disr_expr: Option<AnonConst>,
3229 pub is_placeholder: bool,
3231}
3232
3233#[derive(Clone, Encodable, Decodable, Debug)]
3235pub enum UseTreeKind {
3236 Simple(Option<Ident>),
3238 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3247 Glob,
3249}
3250
3251#[derive(Clone, Encodable, Decodable, Debug)]
3254pub struct UseTree {
3255 pub prefix: Path,
3256 pub kind: UseTreeKind,
3257 pub span: Span,
3258}
3259
3260impl UseTree {
3261 pub fn ident(&self) -> Ident {
3262 match self.kind {
3263 UseTreeKind::Simple(Some(rename)) => rename,
3264 UseTreeKind::Simple(None) => {
3265 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3266 }
3267 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3268 }
3269 }
3270}
3271
3272#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3276pub enum AttrStyle {
3277 Outer,
3278 Inner,
3279}
3280
3281pub type AttrVec = ThinVec<Attribute>;
3283
3284#[derive(Clone, Encodable, Decodable, Debug)]
3286pub struct Attribute {
3287 pub kind: AttrKind,
3288 pub id: AttrId,
3289 pub style: AttrStyle,
3292 pub span: Span,
3293}
3294
3295#[derive(Clone, Encodable, Decodable, Debug)]
3296pub enum AttrKind {
3297 Normal(P<NormalAttr>),
3299
3300 DocComment(CommentKind, Symbol),
3304}
3305
3306#[derive(Clone, Encodable, Decodable, Debug)]
3307pub struct NormalAttr {
3308 pub item: AttrItem,
3309 pub tokens: Option<LazyAttrTokenStream>,
3311}
3312
3313impl NormalAttr {
3314 pub fn from_ident(ident: Ident) -> Self {
3315 Self {
3316 item: AttrItem {
3317 unsafety: Safety::Default,
3318 path: Path::from_ident(ident),
3319 args: AttrArgs::Empty,
3320 tokens: None,
3321 },
3322 tokens: None,
3323 }
3324 }
3325}
3326
3327#[derive(Clone, Encodable, Decodable, Debug)]
3328pub struct AttrItem {
3329 pub unsafety: Safety,
3330 pub path: Path,
3331 pub args: AttrArgs,
3332 pub tokens: Option<LazyAttrTokenStream>,
3334}
3335
3336impl AttrItem {
3337 pub fn is_valid_for_outer_style(&self) -> bool {
3338 self.path == sym::cfg_attr
3339 || self.path == sym::cfg
3340 || self.path == sym::forbid
3341 || self.path == sym::warn
3342 || self.path == sym::allow
3343 || self.path == sym::deny
3344 }
3345}
3346
3347#[derive(Clone, Encodable, Decodable, Debug)]
3354pub struct TraitRef {
3355 pub path: Path,
3356 pub ref_id: NodeId,
3357}
3358
3359#[derive(Clone, Encodable, Decodable, Debug)]
3360pub struct PolyTraitRef {
3361 pub bound_generic_params: ThinVec<GenericParam>,
3363
3364 pub modifiers: TraitBoundModifiers,
3366
3367 pub trait_ref: TraitRef,
3369
3370 pub span: Span,
3371}
3372
3373impl PolyTraitRef {
3374 pub fn new(
3375 generic_params: ThinVec<GenericParam>,
3376 path: Path,
3377 modifiers: TraitBoundModifiers,
3378 span: Span,
3379 ) -> Self {
3380 PolyTraitRef {
3381 bound_generic_params: generic_params,
3382 modifiers,
3383 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3384 span,
3385 }
3386 }
3387}
3388
3389#[derive(Clone, Encodable, Decodable, Debug)]
3390pub struct Visibility {
3391 pub kind: VisibilityKind,
3392 pub span: Span,
3393 pub tokens: Option<LazyAttrTokenStream>,
3394}
3395
3396#[derive(Clone, Encodable, Decodable, Debug)]
3397pub enum VisibilityKind {
3398 Public,
3399 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3400 Inherited,
3401}
3402
3403impl VisibilityKind {
3404 pub fn is_pub(&self) -> bool {
3405 matches!(self, VisibilityKind::Public)
3406 }
3407}
3408
3409#[derive(Clone, Encodable, Decodable, Debug)]
3413pub struct FieldDef {
3414 pub attrs: AttrVec,
3415 pub id: NodeId,
3416 pub span: Span,
3417 pub vis: Visibility,
3418 pub safety: Safety,
3419 pub ident: Option<Ident>,
3420
3421 pub ty: P<Ty>,
3422 pub default: Option<AnonConst>,
3423 pub is_placeholder: bool,
3424}
3425
3426#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3428pub enum Recovered {
3429 No,
3430 Yes(ErrorGuaranteed),
3431}
3432
3433#[derive(Clone, Encodable, Decodable, Debug)]
3435pub enum VariantData {
3436 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3440 Tuple(ThinVec<FieldDef>, NodeId),
3444 Unit(NodeId),
3448}
3449
3450impl VariantData {
3451 pub fn fields(&self) -> &[FieldDef] {
3453 match self {
3454 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3455 _ => &[],
3456 }
3457 }
3458
3459 pub fn ctor_node_id(&self) -> Option<NodeId> {
3461 match *self {
3462 VariantData::Struct { .. } => None,
3463 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3464 }
3465 }
3466}
3467
3468#[derive(Clone, Encodable, Decodable, Debug)]
3470pub struct Item<K = ItemKind> {
3471 pub attrs: AttrVec,
3472 pub id: NodeId,
3473 pub span: Span,
3474 pub vis: Visibility,
3475
3476 pub kind: K,
3477
3478 pub tokens: Option<LazyAttrTokenStream>,
3486}
3487
3488impl Item {
3489 pub fn span_with_attributes(&self) -> Span {
3491 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3492 }
3493
3494 pub fn opt_generics(&self) -> Option<&Generics> {
3495 match &self.kind {
3496 ItemKind::ExternCrate(..)
3497 | ItemKind::Use(_)
3498 | ItemKind::Mod(..)
3499 | ItemKind::ForeignMod(_)
3500 | ItemKind::GlobalAsm(_)
3501 | ItemKind::MacCall(_)
3502 | ItemKind::Delegation(_)
3503 | ItemKind::DelegationMac(_)
3504 | ItemKind::MacroDef(..) => None,
3505 ItemKind::Static(_) => None,
3506 ItemKind::Const(i) => Some(&i.generics),
3507 ItemKind::Fn(i) => Some(&i.generics),
3508 ItemKind::TyAlias(i) => Some(&i.generics),
3509 ItemKind::TraitAlias(_, generics, _)
3510 | ItemKind::Enum(_, generics, _)
3511 | ItemKind::Struct(_, generics, _)
3512 | ItemKind::Union(_, generics, _) => Some(&generics),
3513 ItemKind::Trait(i) => Some(&i.generics),
3514 ItemKind::Impl(i) => Some(&i.generics),
3515 }
3516 }
3517}
3518
3519#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3521pub enum Extern {
3522 None,
3526 Implicit(Span),
3532 Explicit(StrLit, Span),
3536}
3537
3538impl Extern {
3539 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3540 match abi {
3541 Some(name) => Extern::Explicit(name, span),
3542 None => Extern::Implicit(span),
3543 }
3544 }
3545}
3546
3547#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3552pub struct FnHeader {
3553 pub safety: Safety,
3555 pub coroutine_kind: Option<CoroutineKind>,
3557 pub constness: Const,
3559 pub ext: Extern,
3561}
3562
3563impl FnHeader {
3564 pub fn has_qualifiers(&self) -> bool {
3566 let Self { safety, coroutine_kind, constness, ext } = self;
3567 matches!(safety, Safety::Unsafe(_))
3568 || coroutine_kind.is_some()
3569 || matches!(constness, Const::Yes(_))
3570 || !matches!(ext, Extern::None)
3571 }
3572
3573 pub fn span(&self) -> Option<Span> {
3575 fn append(a: &mut Option<Span>, b: Span) {
3576 *a = match a {
3577 None => Some(b),
3578 Some(x) => Some(x.to(b)),
3579 }
3580 }
3581
3582 let mut full_span = None;
3583
3584 match self.safety {
3585 Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3586 Safety::Default => {}
3587 };
3588
3589 if let Some(coroutine_kind) = self.coroutine_kind {
3590 append(&mut full_span, coroutine_kind.span());
3591 }
3592
3593 if let Const::Yes(span) = self.constness {
3594 append(&mut full_span, span);
3595 }
3596
3597 match self.ext {
3598 Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3599 Extern::None => {}
3600 }
3601
3602 full_span
3603 }
3604}
3605
3606impl Default for FnHeader {
3607 fn default() -> FnHeader {
3608 FnHeader {
3609 safety: Safety::Default,
3610 coroutine_kind: None,
3611 constness: Const::No,
3612 ext: Extern::None,
3613 }
3614 }
3615}
3616
3617#[derive(Clone, Encodable, Decodable, Debug)]
3618pub struct Trait {
3619 pub safety: Safety,
3620 pub is_auto: IsAuto,
3621 pub ident: Ident,
3622 pub generics: Generics,
3623 pub bounds: GenericBounds,
3624 pub items: ThinVec<P<AssocItem>>,
3625}
3626
3627#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3646pub struct TyAliasWhereClause {
3647 pub has_where_token: bool,
3648 pub span: Span,
3649}
3650
3651#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3653pub struct TyAliasWhereClauses {
3654 pub before: TyAliasWhereClause,
3656 pub after: TyAliasWhereClause,
3658 pub split: usize,
3662}
3663
3664#[derive(Clone, Encodable, Decodable, Debug)]
3665pub struct TyAlias {
3666 pub defaultness: Defaultness,
3667 pub ident: Ident,
3668 pub generics: Generics,
3669 pub where_clauses: TyAliasWhereClauses,
3670 pub bounds: GenericBounds,
3671 pub ty: Option<P<Ty>>,
3672}
3673
3674#[derive(Clone, Encodable, Decodable, Debug)]
3675pub struct Impl {
3676 pub defaultness: Defaultness,
3677 pub safety: Safety,
3678 pub generics: Generics,
3679 pub constness: Const,
3680 pub polarity: ImplPolarity,
3681 pub of_trait: Option<TraitRef>,
3683 pub self_ty: P<Ty>,
3684 pub items: ThinVec<P<AssocItem>>,
3685}
3686
3687#[derive(Clone, Encodable, Decodable, Debug, Default)]
3688pub struct FnContract {
3689 pub requires: Option<P<Expr>>,
3690 pub ensures: Option<P<Expr>>,
3691}
3692
3693#[derive(Clone, Encodable, Decodable, Debug)]
3694pub struct Fn {
3695 pub defaultness: Defaultness,
3696 pub ident: Ident,
3697 pub generics: Generics,
3698 pub sig: FnSig,
3699 pub contract: Option<P<FnContract>>,
3700 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3701 pub body: Option<P<Block>>,
3702}
3703
3704#[derive(Clone, Encodable, Decodable, Debug)]
3705pub struct Delegation {
3706 pub id: NodeId,
3708 pub qself: Option<P<QSelf>>,
3709 pub path: Path,
3710 pub ident: Ident,
3711 pub rename: Option<Ident>,
3712 pub body: Option<P<Block>>,
3713 pub from_glob: bool,
3715}
3716
3717#[derive(Clone, Encodable, Decodable, Debug)]
3718pub struct DelegationMac {
3719 pub qself: Option<P<QSelf>>,
3720 pub prefix: Path,
3721 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3723 pub body: Option<P<Block>>,
3724}
3725
3726#[derive(Clone, Encodable, Decodable, Debug)]
3727pub struct StaticItem {
3728 pub ident: Ident,
3729 pub ty: P<Ty>,
3730 pub safety: Safety,
3731 pub mutability: Mutability,
3732 pub expr: Option<P<Expr>>,
3733 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3734}
3735
3736#[derive(Clone, Encodable, Decodable, Debug)]
3737pub struct ConstItem {
3738 pub defaultness: Defaultness,
3739 pub ident: Ident,
3740 pub generics: Generics,
3741 pub ty: P<Ty>,
3742 pub expr: Option<P<Expr>>,
3743 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3744}
3745
3746#[derive(Clone, Encodable, Decodable, Debug)]
3748pub enum ItemKind {
3749 ExternCrate(Option<Symbol>, Ident),
3753 Use(UseTree),
3757 Static(Box<StaticItem>),
3761 Const(Box<ConstItem>),
3765 Fn(Box<Fn>),
3769 Mod(Safety, Ident, ModKind),
3775 ForeignMod(ForeignMod),
3779 GlobalAsm(Box<InlineAsm>),
3781 TyAlias(Box<TyAlias>),
3785 Enum(Ident, Generics, EnumDef),
3789 Struct(Ident, Generics, VariantData),
3793 Union(Ident, Generics, VariantData),
3797 Trait(Box<Trait>),
3801 TraitAlias(Ident, Generics, GenericBounds),
3805 Impl(Box<Impl>),
3809 MacCall(P<MacCall>),
3813 MacroDef(Ident, MacroDef),
3815 Delegation(Box<Delegation>),
3819 DelegationMac(Box<DelegationMac>),
3822}
3823
3824impl ItemKind {
3825 pub fn ident(&self) -> Option<Ident> {
3826 match *self {
3827 ItemKind::ExternCrate(_, ident)
3828 | ItemKind::Static(box StaticItem { ident, .. })
3829 | ItemKind::Const(box ConstItem { ident, .. })
3830 | ItemKind::Fn(box Fn { ident, .. })
3831 | ItemKind::Mod(_, ident, _)
3832 | ItemKind::TyAlias(box TyAlias { ident, .. })
3833 | ItemKind::Enum(ident, ..)
3834 | ItemKind::Struct(ident, ..)
3835 | ItemKind::Union(ident, ..)
3836 | ItemKind::Trait(box Trait { ident, .. })
3837 | ItemKind::TraitAlias(ident, ..)
3838 | ItemKind::MacroDef(ident, _)
3839 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3840
3841 ItemKind::Use(_)
3842 | ItemKind::ForeignMod(_)
3843 | ItemKind::GlobalAsm(_)
3844 | ItemKind::Impl(_)
3845 | ItemKind::MacCall(_)
3846 | ItemKind::DelegationMac(_) => None,
3847 }
3848 }
3849
3850 pub fn article(&self) -> &'static str {
3852 use ItemKind::*;
3853 match self {
3854 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3855 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3856 | Delegation(..) | DelegationMac(..) => "a",
3857 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3858 }
3859 }
3860
3861 pub fn descr(&self) -> &'static str {
3862 match self {
3863 ItemKind::ExternCrate(..) => "extern crate",
3864 ItemKind::Use(..) => "`use` import",
3865 ItemKind::Static(..) => "static item",
3866 ItemKind::Const(..) => "constant item",
3867 ItemKind::Fn(..) => "function",
3868 ItemKind::Mod(..) => "module",
3869 ItemKind::ForeignMod(..) => "extern block",
3870 ItemKind::GlobalAsm(..) => "global asm item",
3871 ItemKind::TyAlias(..) => "type alias",
3872 ItemKind::Enum(..) => "enum",
3873 ItemKind::Struct(..) => "struct",
3874 ItemKind::Union(..) => "union",
3875 ItemKind::Trait(..) => "trait",
3876 ItemKind::TraitAlias(..) => "trait alias",
3877 ItemKind::MacCall(..) => "item macro invocation",
3878 ItemKind::MacroDef(..) => "macro definition",
3879 ItemKind::Impl { .. } => "implementation",
3880 ItemKind::Delegation(..) => "delegated function",
3881 ItemKind::DelegationMac(..) => "delegation",
3882 }
3883 }
3884
3885 pub fn generics(&self) -> Option<&Generics> {
3886 match self {
3887 Self::Fn(box Fn { generics, .. })
3888 | Self::TyAlias(box TyAlias { generics, .. })
3889 | Self::Const(box ConstItem { generics, .. })
3890 | Self::Enum(_, generics, _)
3891 | Self::Struct(_, generics, _)
3892 | Self::Union(_, generics, _)
3893 | Self::Trait(box Trait { generics, .. })
3894 | Self::TraitAlias(_, generics, _)
3895 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3896 _ => None,
3897 }
3898 }
3899}
3900
3901pub type AssocItem = Item<AssocItemKind>;
3904
3905#[derive(Clone, Encodable, Decodable, Debug)]
3913pub enum AssocItemKind {
3914 Const(Box<ConstItem>),
3917 Fn(Box<Fn>),
3919 Type(Box<TyAlias>),
3921 MacCall(P<MacCall>),
3923 Delegation(Box<Delegation>),
3925 DelegationMac(Box<DelegationMac>),
3927}
3928
3929impl AssocItemKind {
3930 pub fn ident(&self) -> Option<Ident> {
3931 match *self {
3932 AssocItemKind::Const(box ConstItem { ident, .. })
3933 | AssocItemKind::Fn(box Fn { ident, .. })
3934 | AssocItemKind::Type(box TyAlias { ident, .. })
3935 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3936
3937 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3938 }
3939 }
3940
3941 pub fn defaultness(&self) -> Defaultness {
3942 match *self {
3943 Self::Const(box ConstItem { defaultness, .. })
3944 | Self::Fn(box Fn { defaultness, .. })
3945 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3946 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3947 Defaultness::Final
3948 }
3949 }
3950 }
3951}
3952
3953impl From<AssocItemKind> for ItemKind {
3954 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3955 match assoc_item_kind {
3956 AssocItemKind::Const(item) => ItemKind::Const(item),
3957 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3958 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3959 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3960 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3961 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3962 }
3963 }
3964}
3965
3966impl TryFrom<ItemKind> for AssocItemKind {
3967 type Error = ItemKind;
3968
3969 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3970 Ok(match item_kind {
3971 ItemKind::Const(item) => AssocItemKind::Const(item),
3972 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3973 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3974 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3975 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3976 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3977 _ => return Err(item_kind),
3978 })
3979 }
3980}
3981
3982#[derive(Clone, Encodable, Decodable, Debug)]
3984pub enum ForeignItemKind {
3985 Static(Box<StaticItem>),
3987 Fn(Box<Fn>),
3989 TyAlias(Box<TyAlias>),
3991 MacCall(P<MacCall>),
3993}
3994
3995impl ForeignItemKind {
3996 pub fn ident(&self) -> Option<Ident> {
3997 match *self {
3998 ForeignItemKind::Static(box StaticItem { ident, .. })
3999 | ForeignItemKind::Fn(box Fn { ident, .. })
4000 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4001
4002 ForeignItemKind::MacCall(_) => None,
4003 }
4004 }
4005}
4006
4007impl From<ForeignItemKind> for ItemKind {
4008 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4009 match foreign_item_kind {
4010 ForeignItemKind::Static(box static_foreign_item) => {
4011 ItemKind::Static(Box::new(static_foreign_item))
4012 }
4013 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4014 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4015 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4016 }
4017 }
4018}
4019
4020impl TryFrom<ItemKind> for ForeignItemKind {
4021 type Error = ItemKind;
4022
4023 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4024 Ok(match item_kind {
4025 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4026 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4027 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4028 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4029 _ => return Err(item_kind),
4030 })
4031 }
4032}
4033
4034pub type ForeignItem = Item<ForeignItemKind>;
4035
4036#[cfg(target_pointer_width = "64")]
4038mod size_asserts {
4039 use rustc_data_structures::static_assert_size;
4040
4041 use super::*;
4042 static_assert_size!(AssocItem, 80);
4044 static_assert_size!(AssocItemKind, 16);
4045 static_assert_size!(Attribute, 32);
4046 static_assert_size!(Block, 32);
4047 static_assert_size!(Expr, 72);
4048 static_assert_size!(ExprKind, 40);
4049 static_assert_size!(Fn, 184);
4050 static_assert_size!(ForeignItem, 80);
4051 static_assert_size!(ForeignItemKind, 16);
4052 static_assert_size!(GenericArg, 24);
4053 static_assert_size!(GenericBound, 88);
4054 static_assert_size!(Generics, 40);
4055 static_assert_size!(Impl, 136);
4056 static_assert_size!(Item, 144);
4057 static_assert_size!(ItemKind, 80);
4058 static_assert_size!(LitKind, 24);
4059 static_assert_size!(Local, 96);
4060 static_assert_size!(MetaItemLit, 40);
4061 static_assert_size!(Param, 40);
4062 static_assert_size!(Pat, 72);
4063 static_assert_size!(Path, 24);
4064 static_assert_size!(PathSegment, 24);
4065 static_assert_size!(PatKind, 48);
4066 static_assert_size!(Stmt, 32);
4067 static_assert_size!(StmtKind, 16);
4068 static_assert_size!(Ty, 64);
4069 static_assert_size!(TyKind, 40);
4070 }