1use std::borrow::{Borrow, Cow};
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
27use rustc_data_structures::packed::Pu128;
28use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
29use rustc_data_structures::stack::ensure_sufficient_stack;
30use rustc_data_structures::tagged_ptr::Tag;
31use rustc_macros::{Decodable, Encodable, HashStable_Generic};
32pub use rustc_span::AttrId;
33use rustc_span::source_map::{Spanned, respan};
34use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
35use thin_vec::{ThinVec, thin_vec};
36
37pub use crate::format::*;
38use crate::ptr::P;
39use crate::token::{self, CommentKind, Delimiter};
40use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
41use crate::util::parser::{ExprPrecedence, Fixity};
42
43#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
54pub struct Label {
55 pub ident: Ident,
56}
57
58impl fmt::Debug for Label {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "label({:?})", self.ident)
61 }
62}
63
64#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)]
67pub struct Lifetime {
68 pub id: NodeId,
69 pub ident: Ident,
70}
71
72impl fmt::Debug for Lifetime {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 write!(f, "lifetime({}: {})", self.id, self)
75 }
76}
77
78impl fmt::Display for Lifetime {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(f, "{}", self.ident.name)
81 }
82}
83
84#[derive(Clone, Encodable, Decodable, Debug)]
91pub struct Path {
92 pub span: Span,
93 pub segments: ThinVec<PathSegment>,
96 pub tokens: Option<LazyAttrTokenStream>,
97}
98
99impl PartialEq<Symbol> for Path {
101 #[inline]
102 fn eq(&self, name: &Symbol) -> bool {
103 if let [segment] = self.segments.as_ref()
104 && segment == name
105 {
106 true
107 } else {
108 false
109 }
110 }
111}
112
113impl PartialEq<&[Symbol]> for Path {
115 #[inline]
116 fn eq(&self, names: &&[Symbol]) -> bool {
117 self.segments.len() == names.len()
118 && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
119 }
120}
121
122impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
123 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
124 self.segments.len().hash_stable(hcx, hasher);
125 for segment in &self.segments {
126 segment.ident.hash_stable(hcx, hasher);
127 }
128 }
129}
130
131impl Path {
132 pub fn from_ident(ident: Ident) -> Path {
135 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
136 }
137
138 pub fn is_global(&self) -> bool {
139 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
140 }
141
142 #[tracing::instrument(level = "debug", ret)]
152 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
153 allow_mgca_arg
154 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
155 }
156}
157
158pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
170 let mut iter = path.into_iter();
175 let len_hint = iter.size_hint().1.unwrap_or(1);
176 let mut s = String::with_capacity(len_hint * 8);
177
178 let first_sym = *iter.next().unwrap().borrow();
179 if first_sym != kw::PathRoot {
180 s.push_str(first_sym.as_str());
181 }
182 for sym in iter {
183 let sym = *sym.borrow();
184 debug_assert_ne!(sym, kw::PathRoot);
185 s.push_str("::");
186 s.push_str(sym.as_str());
187 }
188 s
189}
190
191pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
194 let mut iter = path.into_iter();
195 let len_hint = iter.size_hint().1.unwrap_or(1);
196 let mut s = String::with_capacity(len_hint * 8);
197
198 let first_ident = *iter.next().unwrap().borrow();
199 if first_ident.name != kw::PathRoot {
200 s.push_str(&first_ident.to_string());
201 }
202 for ident in iter {
203 let ident = *ident.borrow();
204 debug_assert_ne!(ident.name, kw::PathRoot);
205 s.push_str("::");
206 s.push_str(&ident.to_string());
207 }
208 s
209}
210
211#[derive(Clone, Encodable, Decodable, Debug)]
215pub struct PathSegment {
216 pub ident: Ident,
218
219 pub id: NodeId,
220
221 pub args: Option<P<GenericArgs>>,
228}
229
230impl PartialEq<Symbol> for PathSegment {
232 #[inline]
233 fn eq(&self, name: &Symbol) -> bool {
234 self.args.is_none() && self.ident.name == *name
235 }
236}
237
238impl PathSegment {
239 pub fn from_ident(ident: Ident) -> Self {
240 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
241 }
242
243 pub fn path_root(span: Span) -> Self {
244 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
245 }
246
247 pub fn span(&self) -> Span {
248 match &self.args {
249 Some(args) => self.ident.span.to(args.span()),
250 None => self.ident.span,
251 }
252 }
253}
254
255#[derive(Clone, Encodable, Decodable, Debug)]
259pub enum GenericArgs {
260 AngleBracketed(AngleBracketedArgs),
262 Parenthesized(ParenthesizedArgs),
264 ParenthesizedElided(Span),
266}
267
268impl GenericArgs {
269 pub fn is_angle_bracketed(&self) -> bool {
270 matches!(self, AngleBracketed(..))
271 }
272
273 pub fn span(&self) -> Span {
274 match self {
275 AngleBracketed(data) => data.span,
276 Parenthesized(data) => data.span,
277 ParenthesizedElided(span) => *span,
278 }
279 }
280}
281
282#[derive(Clone, Encodable, Decodable, Debug)]
284pub enum GenericArg {
285 Lifetime(Lifetime),
287 Type(P<Ty>),
289 Const(AnonConst),
291}
292
293impl GenericArg {
294 pub fn span(&self) -> Span {
295 match self {
296 GenericArg::Lifetime(lt) => lt.ident.span,
297 GenericArg::Type(ty) => ty.span,
298 GenericArg::Const(ct) => ct.value.span,
299 }
300 }
301}
302
303#[derive(Clone, Encodable, Decodable, Debug, Default)]
305pub struct AngleBracketedArgs {
306 pub span: Span,
308 pub args: ThinVec<AngleBracketedArg>,
310}
311
312#[derive(Clone, Encodable, Decodable, Debug)]
314pub enum AngleBracketedArg {
315 Arg(GenericArg),
317 Constraint(AssocItemConstraint),
319}
320
321impl AngleBracketedArg {
322 pub fn span(&self) -> Span {
323 match self {
324 AngleBracketedArg::Arg(arg) => arg.span(),
325 AngleBracketedArg::Constraint(constraint) => constraint.span,
326 }
327 }
328}
329
330impl From<AngleBracketedArgs> for P<GenericArgs> {
331 fn from(val: AngleBracketedArgs) -> Self {
332 P(GenericArgs::AngleBracketed(val))
333 }
334}
335
336impl From<ParenthesizedArgs> for P<GenericArgs> {
337 fn from(val: ParenthesizedArgs) -> Self {
338 P(GenericArgs::Parenthesized(val))
339 }
340}
341
342#[derive(Clone, Encodable, Decodable, Debug)]
344pub struct ParenthesizedArgs {
345 pub span: Span,
350
351 pub inputs: ThinVec<P<Ty>>,
353
354 pub inputs_span: Span,
359
360 pub output: FnRetTy,
362}
363
364impl ParenthesizedArgs {
365 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
366 let args = self
367 .inputs
368 .iter()
369 .cloned()
370 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
371 .collect();
372 AngleBracketedArgs { span: self.inputs_span, args }
373 }
374}
375
376pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
377
378#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
380pub struct TraitBoundModifiers {
381 pub constness: BoundConstness,
382 pub asyncness: BoundAsyncness,
383 pub polarity: BoundPolarity,
384}
385
386impl TraitBoundModifiers {
387 pub const NONE: Self = Self {
388 constness: BoundConstness::Never,
389 asyncness: BoundAsyncness::Normal,
390 polarity: BoundPolarity::Positive,
391 };
392}
393
394#[derive(Clone, Encodable, Decodable, Debug)]
395pub enum GenericBound {
396 Trait(PolyTraitRef),
397 Outlives(Lifetime),
398 Use(ThinVec<PreciseCapturingArg>, Span),
400}
401
402impl GenericBound {
403 pub fn span(&self) -> Span {
404 match self {
405 GenericBound::Trait(t, ..) => t.span,
406 GenericBound::Outlives(l) => l.ident.span,
407 GenericBound::Use(_, span) => *span,
408 }
409 }
410}
411
412pub type GenericBounds = Vec<GenericBound>;
413
414#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
418pub enum ParamKindOrd {
419 Lifetime,
420 TypeOrConst,
421}
422
423impl fmt::Display for ParamKindOrd {
424 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
425 match self {
426 ParamKindOrd::Lifetime => "lifetime".fmt(f),
427 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
428 }
429 }
430}
431
432#[derive(Clone, Encodable, Decodable, Debug)]
433pub enum GenericParamKind {
434 Lifetime,
436 Type {
437 default: Option<P<Ty>>,
438 },
439 Const {
440 ty: P<Ty>,
441 span: Span,
443 default: Option<AnonConst>,
445 },
446}
447
448#[derive(Clone, Encodable, Decodable, Debug)]
449pub struct GenericParam {
450 pub id: NodeId,
451 pub ident: Ident,
452 pub attrs: AttrVec,
453 pub bounds: GenericBounds,
454 pub is_placeholder: bool,
455 pub kind: GenericParamKind,
456 pub colon_span: Option<Span>,
457}
458
459impl GenericParam {
460 pub fn span(&self) -> Span {
461 match &self.kind {
462 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
463 self.ident.span
464 }
465 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
466 GenericParamKind::Const { span, .. } => *span,
467 }
468 }
469}
470
471#[derive(Clone, Encodable, Decodable, Debug, Default)]
474pub struct Generics {
475 pub params: ThinVec<GenericParam>,
476 pub where_clause: WhereClause,
477 pub span: Span,
478}
479
480#[derive(Clone, Encodable, Decodable, Debug, Default)]
482pub struct WhereClause {
483 pub has_where_token: bool,
488 pub predicates: ThinVec<WherePredicate>,
489 pub span: Span,
490}
491
492impl WhereClause {
493 pub fn is_empty(&self) -> bool {
494 !self.has_where_token && self.predicates.is_empty()
495 }
496}
497
498#[derive(Clone, Encodable, Decodable, Debug)]
500pub struct WherePredicate {
501 pub attrs: AttrVec,
502 pub kind: WherePredicateKind,
503 pub id: NodeId,
504 pub span: Span,
505 pub is_placeholder: bool,
506}
507
508#[derive(Clone, Encodable, Decodable, Debug)]
510pub enum WherePredicateKind {
511 BoundPredicate(WhereBoundPredicate),
513 RegionPredicate(WhereRegionPredicate),
515 EqPredicate(WhereEqPredicate),
517}
518
519#[derive(Clone, Encodable, Decodable, Debug)]
523pub struct WhereBoundPredicate {
524 pub bound_generic_params: ThinVec<GenericParam>,
526 pub bounded_ty: P<Ty>,
528 pub bounds: GenericBounds,
530}
531
532#[derive(Clone, Encodable, Decodable, Debug)]
536pub struct WhereRegionPredicate {
537 pub lifetime: Lifetime,
538 pub bounds: GenericBounds,
539}
540
541#[derive(Clone, Encodable, Decodable, Debug)]
545pub struct WhereEqPredicate {
546 pub lhs_ty: P<Ty>,
547 pub rhs_ty: P<Ty>,
548}
549
550#[derive(Clone, Encodable, Decodable, Debug)]
551pub struct Crate {
552 pub attrs: AttrVec,
553 pub items: ThinVec<P<Item>>,
554 pub spans: ModSpans,
555 pub id: NodeId,
558 pub is_placeholder: bool,
559}
560
561#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
568pub struct MetaItem {
569 pub unsafety: Safety,
570 pub path: Path,
571 pub kind: MetaItemKind,
572 pub span: Span,
573}
574
575#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
577pub enum MetaItemKind {
578 Word,
582
583 List(ThinVec<MetaItemInner>),
587
588 NameValue(MetaItemLit),
592}
593
594#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
598pub enum MetaItemInner {
599 MetaItem(MetaItem),
601
602 Lit(MetaItemLit),
606}
607
608#[derive(Clone, Encodable, Decodable, Debug)]
612pub struct Block {
613 pub stmts: ThinVec<Stmt>,
615 pub id: NodeId,
616 pub rules: BlockCheckMode,
618 pub span: Span,
619 pub tokens: Option<LazyAttrTokenStream>,
620}
621
622#[derive(Clone, Encodable, Decodable, Debug)]
626pub struct Pat {
627 pub id: NodeId,
628 pub kind: PatKind,
629 pub span: Span,
630 pub tokens: Option<LazyAttrTokenStream>,
631}
632
633impl Pat {
634 pub fn to_ty(&self) -> Option<P<Ty>> {
637 let kind = match &self.kind {
638 PatKind::Missing => unreachable!(),
639 PatKind::Wild => TyKind::Infer,
641 PatKind::Ident(BindingMode::NONE, ident, None) => {
643 TyKind::Path(None, Path::from_ident(*ident))
644 }
645 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
646 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
647 PatKind::Ref(pat, mutbl) => {
649 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
650 }
651 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
654 pat.to_ty().map(TyKind::Slice)?
655 }
656 PatKind::Tuple(pats) => {
659 let mut tys = ThinVec::with_capacity(pats.len());
660 for pat in pats {
662 tys.push(pat.to_ty()?);
663 }
664 TyKind::Tup(tys)
665 }
666 _ => return None,
667 };
668
669 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
670 }
671
672 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
676 if !it(self) {
677 return;
678 }
679
680 match &self.kind {
681 PatKind::Ident(_, _, Some(p)) => p.walk(it),
683
684 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
686
687 PatKind::TupleStruct(_, _, s)
689 | PatKind::Tuple(s)
690 | PatKind::Slice(s)
691 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
692
693 PatKind::Box(s)
695 | PatKind::Deref(s)
696 | PatKind::Ref(s, _)
697 | PatKind::Paren(s)
698 | PatKind::Guard(s, _) => s.walk(it),
699
700 PatKind::Missing
702 | PatKind::Wild
703 | PatKind::Rest
704 | PatKind::Never
705 | PatKind::Expr(_)
706 | PatKind::Range(..)
707 | PatKind::Ident(..)
708 | PatKind::Path(..)
709 | PatKind::MacCall(_)
710 | PatKind::Err(_) => {}
711 }
712 }
713
714 pub fn is_rest(&self) -> bool {
716 matches!(self.kind, PatKind::Rest)
717 }
718
719 pub fn could_be_never_pattern(&self) -> bool {
722 let mut could_be_never_pattern = false;
723 self.walk(&mut |pat| match &pat.kind {
724 PatKind::Never | PatKind::MacCall(_) => {
725 could_be_never_pattern = true;
726 false
727 }
728 PatKind::Or(s) => {
729 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
730 false
731 }
732 _ => true,
733 });
734 could_be_never_pattern
735 }
736
737 pub fn contains_never_pattern(&self) -> bool {
740 let mut contains_never_pattern = false;
741 self.walk(&mut |pat| {
742 if matches!(pat.kind, PatKind::Never) {
743 contains_never_pattern = true;
744 }
745 true
746 });
747 contains_never_pattern
748 }
749
750 pub fn descr(&self) -> Option<String> {
752 match &self.kind {
753 PatKind::Missing => unreachable!(),
754 PatKind::Wild => Some("_".to_string()),
755 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
756 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
757 _ => None,
758 }
759 }
760}
761
762impl From<P<Pat>> for Pat {
763 fn from(value: P<Pat>) -> Self {
764 *value
765 }
766}
767
768#[derive(Clone, Encodable, Decodable, Debug)]
774pub struct PatField {
775 pub ident: Ident,
777 pub pat: P<Pat>,
779 pub is_shorthand: bool,
780 pub attrs: AttrVec,
781 pub id: NodeId,
782 pub span: Span,
783 pub is_placeholder: bool,
784}
785
786#[derive(Clone, Copy, Debug, Eq, PartialEq)]
787#[derive(Encodable, Decodable, HashStable_Generic)]
788pub enum ByRef {
789 Yes(Mutability),
790 No,
791}
792
793impl ByRef {
794 #[must_use]
795 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
796 if let ByRef::Yes(old_mutbl) = &mut self {
797 *old_mutbl = cmp::min(*old_mutbl, mutbl);
798 }
799 self
800 }
801}
802
803#[derive(Clone, Copy, Debug, Eq, PartialEq)]
809#[derive(Encodable, Decodable, HashStable_Generic)]
810pub struct BindingMode(pub ByRef, pub Mutability);
811
812impl BindingMode {
813 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
814 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
815 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
816 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
817 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
818 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
819
820 pub fn prefix_str(self) -> &'static str {
821 match self {
822 Self::NONE => "",
823 Self::REF => "ref ",
824 Self::MUT => "mut ",
825 Self::REF_MUT => "ref mut ",
826 Self::MUT_REF => "mut ref ",
827 Self::MUT_REF_MUT => "mut ref mut ",
828 }
829 }
830}
831
832#[derive(Clone, Encodable, Decodable, Debug)]
833pub enum RangeEnd {
834 Included(RangeSyntax),
836 Excluded,
838}
839
840#[derive(Clone, Encodable, Decodable, Debug)]
841pub enum RangeSyntax {
842 DotDotDot,
844 DotDotEq,
846}
847
848#[derive(Clone, Encodable, Decodable, Debug)]
852pub enum PatKind {
853 Missing,
855
856 Wild,
858
859 Ident(BindingMode, Ident, Option<P<Pat>>),
864
865 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
867
868 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
870
871 Or(ThinVec<P<Pat>>),
874
875 Path(Option<P<QSelf>>, Path),
880
881 Tuple(ThinVec<P<Pat>>),
883
884 Box(P<Pat>),
886
887 Deref(P<Pat>),
889
890 Ref(P<Pat>, Mutability),
892
893 Expr(P<Expr>),
895
896 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
898
899 Slice(ThinVec<P<Pat>>),
901
902 Rest,
915
916 Never,
918
919 Guard(P<Pat>, P<Expr>),
921
922 Paren(P<Pat>),
924
925 MacCall(P<MacCall>),
927
928 Err(ErrorGuaranteed),
930}
931
932#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
934pub enum PatFieldsRest {
935 Rest,
937 Recovered(ErrorGuaranteed),
939 None,
941}
942
943#[derive(Clone, Copy, PartialEq, Eq, Debug)]
946#[derive(Encodable, Decodable, HashStable_Generic)]
947pub enum BorrowKind {
948 Ref,
952 Raw,
956 Pin,
960}
961
962#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
963pub enum BinOpKind {
964 Add,
966 Sub,
968 Mul,
970 Div,
972 Rem,
974 And,
976 Or,
978 BitXor,
980 BitAnd,
982 BitOr,
984 Shl,
986 Shr,
988 Eq,
990 Lt,
992 Le,
994 Ne,
996 Ge,
998 Gt,
1000}
1001
1002impl BinOpKind {
1003 pub fn as_str(&self) -> &'static str {
1004 use BinOpKind::*;
1005 match self {
1006 Add => "+",
1007 Sub => "-",
1008 Mul => "*",
1009 Div => "/",
1010 Rem => "%",
1011 And => "&&",
1012 Or => "||",
1013 BitXor => "^",
1014 BitAnd => "&",
1015 BitOr => "|",
1016 Shl => "<<",
1017 Shr => ">>",
1018 Eq => "==",
1019 Lt => "<",
1020 Le => "<=",
1021 Ne => "!=",
1022 Ge => ">=",
1023 Gt => ">",
1024 }
1025 }
1026
1027 pub fn is_lazy(&self) -> bool {
1028 matches!(self, BinOpKind::And | BinOpKind::Or)
1029 }
1030
1031 pub fn precedence(&self) -> ExprPrecedence {
1032 use BinOpKind::*;
1033 match *self {
1034 Mul | Div | Rem => ExprPrecedence::Product,
1035 Add | Sub => ExprPrecedence::Sum,
1036 Shl | Shr => ExprPrecedence::Shift,
1037 BitAnd => ExprPrecedence::BitAnd,
1038 BitXor => ExprPrecedence::BitXor,
1039 BitOr => ExprPrecedence::BitOr,
1040 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1041 And => ExprPrecedence::LAnd,
1042 Or => ExprPrecedence::LOr,
1043 }
1044 }
1045
1046 pub fn fixity(&self) -> Fixity {
1047 use BinOpKind::*;
1048 match self {
1049 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1050 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1051 Fixity::Left
1052 }
1053 }
1054 }
1055
1056 pub fn is_comparison(self) -> bool {
1057 use BinOpKind::*;
1058 match self {
1059 Eq | Ne | Lt | Le | Gt | Ge => true,
1060 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1061 }
1062 }
1063
1064 pub fn is_by_value(self) -> bool {
1066 !self.is_comparison()
1067 }
1068}
1069
1070pub type BinOp = Spanned<BinOpKind>;
1071
1072impl From<AssignOpKind> for BinOpKind {
1076 fn from(op: AssignOpKind) -> BinOpKind {
1077 match op {
1078 AssignOpKind::AddAssign => BinOpKind::Add,
1079 AssignOpKind::SubAssign => BinOpKind::Sub,
1080 AssignOpKind::MulAssign => BinOpKind::Mul,
1081 AssignOpKind::DivAssign => BinOpKind::Div,
1082 AssignOpKind::RemAssign => BinOpKind::Rem,
1083 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1084 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1085 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1086 AssignOpKind::ShlAssign => BinOpKind::Shl,
1087 AssignOpKind::ShrAssign => BinOpKind::Shr,
1088 }
1089 }
1090}
1091
1092#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1093pub enum AssignOpKind {
1094 AddAssign,
1096 SubAssign,
1098 MulAssign,
1100 DivAssign,
1102 RemAssign,
1104 BitXorAssign,
1106 BitAndAssign,
1108 BitOrAssign,
1110 ShlAssign,
1112 ShrAssign,
1114}
1115
1116impl AssignOpKind {
1117 pub fn as_str(&self) -> &'static str {
1118 use AssignOpKind::*;
1119 match self {
1120 AddAssign => "+=",
1121 SubAssign => "-=",
1122 MulAssign => "*=",
1123 DivAssign => "/=",
1124 RemAssign => "%=",
1125 BitXorAssign => "^=",
1126 BitAndAssign => "&=",
1127 BitOrAssign => "|=",
1128 ShlAssign => "<<=",
1129 ShrAssign => ">>=",
1130 }
1131 }
1132
1133 pub fn is_by_value(self) -> bool {
1135 true
1136 }
1137}
1138
1139pub type AssignOp = Spanned<AssignOpKind>;
1140
1141#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1145pub enum UnOp {
1146 Deref,
1148 Not,
1150 Neg,
1152}
1153
1154impl UnOp {
1155 pub fn as_str(&self) -> &'static str {
1156 match self {
1157 UnOp::Deref => "*",
1158 UnOp::Not => "!",
1159 UnOp::Neg => "-",
1160 }
1161 }
1162
1163 pub fn is_by_value(self) -> bool {
1165 matches!(self, Self::Neg | Self::Not)
1166 }
1167}
1168
1169#[derive(Clone, Encodable, Decodable, Debug)]
1173pub struct Stmt {
1174 pub id: NodeId,
1175 pub kind: StmtKind,
1176 pub span: Span,
1177}
1178
1179impl Stmt {
1180 pub fn has_trailing_semicolon(&self) -> bool {
1181 match &self.kind {
1182 StmtKind::Semi(_) => true,
1183 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1184 _ => false,
1185 }
1186 }
1187
1188 pub fn add_trailing_semicolon(mut self) -> Self {
1196 self.kind = match self.kind {
1197 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1198 StmtKind::MacCall(mut mac) => {
1199 mac.style = MacStmtStyle::Semicolon;
1200 StmtKind::MacCall(mac)
1201 }
1202 kind => kind,
1203 };
1204
1205 self
1206 }
1207
1208 pub fn is_item(&self) -> bool {
1209 matches!(self.kind, StmtKind::Item(_))
1210 }
1211
1212 pub fn is_expr(&self) -> bool {
1213 matches!(self.kind, StmtKind::Expr(_))
1214 }
1215}
1216
1217#[derive(Clone, Encodable, Decodable, Debug)]
1219pub enum StmtKind {
1220 Let(P<Local>),
1222 Item(P<Item>),
1224 Expr(P<Expr>),
1226 Semi(P<Expr>),
1228 Empty,
1230 MacCall(P<MacCallStmt>),
1232}
1233
1234#[derive(Clone, Encodable, Decodable, Debug)]
1235pub struct MacCallStmt {
1236 pub mac: P<MacCall>,
1237 pub style: MacStmtStyle,
1238 pub attrs: AttrVec,
1239 pub tokens: Option<LazyAttrTokenStream>,
1240}
1241
1242#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1243pub enum MacStmtStyle {
1244 Semicolon,
1247 Braces,
1249 NoBraces,
1253}
1254
1255#[derive(Clone, Encodable, Decodable, Debug)]
1257pub struct Local {
1258 pub id: NodeId,
1259 pub super_: Option<Span>,
1260 pub pat: P<Pat>,
1261 pub ty: Option<P<Ty>>,
1262 pub kind: LocalKind,
1263 pub span: Span,
1264 pub colon_sp: Option<Span>,
1265 pub attrs: AttrVec,
1266 pub tokens: Option<LazyAttrTokenStream>,
1267}
1268
1269#[derive(Clone, Encodable, Decodable, Debug)]
1270pub enum LocalKind {
1271 Decl,
1274 Init(P<Expr>),
1277 InitElse(P<Expr>, P<Block>),
1280}
1281
1282impl LocalKind {
1283 pub fn init(&self) -> Option<&Expr> {
1284 match self {
1285 Self::Decl => None,
1286 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1287 }
1288 }
1289
1290 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1291 match self {
1292 Self::Decl => None,
1293 Self::Init(init) => Some((init, None)),
1294 Self::InitElse(init, els) => Some((init, Some(els))),
1295 }
1296 }
1297}
1298
1299#[derive(Clone, Encodable, Decodable, Debug)]
1310pub struct Arm {
1311 pub attrs: AttrVec,
1312 pub pat: P<Pat>,
1314 pub guard: Option<P<Expr>>,
1316 pub body: Option<P<Expr>>,
1318 pub span: Span,
1319 pub id: NodeId,
1320 pub is_placeholder: bool,
1321}
1322
1323#[derive(Clone, Encodable, Decodable, Debug)]
1325pub struct ExprField {
1326 pub attrs: AttrVec,
1327 pub id: NodeId,
1328 pub span: Span,
1329 pub ident: Ident,
1330 pub expr: P<Expr>,
1331 pub is_shorthand: bool,
1332 pub is_placeholder: bool,
1333}
1334
1335#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1336pub enum BlockCheckMode {
1337 Default,
1338 Unsafe(UnsafeSource),
1339}
1340
1341#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1342pub enum UnsafeSource {
1343 CompilerGenerated,
1344 UserProvided,
1345}
1346
1347#[derive(Clone, Encodable, Decodable, Debug)]
1353pub struct AnonConst {
1354 pub id: NodeId,
1355 pub value: P<Expr>,
1356}
1357
1358#[derive(Clone, Encodable, Decodable, Debug)]
1360pub struct Expr {
1361 pub id: NodeId,
1362 pub kind: ExprKind,
1363 pub span: Span,
1364 pub attrs: AttrVec,
1365 pub tokens: Option<LazyAttrTokenStream>,
1366}
1367
1368impl Expr {
1369 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1383 let this = self.maybe_unwrap_block();
1384 if allow_mgca_arg {
1385 matches!(this.kind, ExprKind::Path(..))
1386 } else {
1387 if let ExprKind::Path(None, path) = &this.kind
1388 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1389 {
1390 true
1391 } else {
1392 false
1393 }
1394 }
1395 }
1396
1397 pub fn maybe_unwrap_block(&self) -> &Expr {
1399 if let ExprKind::Block(block, None) = &self.kind
1400 && let [stmt] = block.stmts.as_slice()
1401 && let StmtKind::Expr(expr) = &stmt.kind
1402 {
1403 expr
1404 } else {
1405 self
1406 }
1407 }
1408
1409 pub fn optionally_braced_mac_call(
1415 &self,
1416 already_stripped_block: bool,
1417 ) -> Option<(bool, NodeId)> {
1418 match &self.kind {
1419 ExprKind::Block(block, None)
1420 if let [stmt] = &*block.stmts
1421 && !already_stripped_block =>
1422 {
1423 match &stmt.kind {
1424 StmtKind::MacCall(_) => Some((true, stmt.id)),
1425 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1426 Some((true, expr.id))
1427 }
1428 _ => None,
1429 }
1430 }
1431 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1432 _ => None,
1433 }
1434 }
1435
1436 pub fn to_bound(&self) -> Option<GenericBound> {
1437 match &self.kind {
1438 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1439 ThinVec::new(),
1440 path.clone(),
1441 TraitBoundModifiers::NONE,
1442 self.span,
1443 Parens::No,
1444 ))),
1445 _ => None,
1446 }
1447 }
1448
1449 pub fn peel_parens(&self) -> &Expr {
1450 let mut expr = self;
1451 while let ExprKind::Paren(inner) = &expr.kind {
1452 expr = inner;
1453 }
1454 expr
1455 }
1456
1457 pub fn peel_parens_and_refs(&self) -> &Expr {
1458 let mut expr = self;
1459 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1460 {
1461 expr = inner;
1462 }
1463 expr
1464 }
1465
1466 pub fn to_ty(&self) -> Option<P<Ty>> {
1468 let kind = match &self.kind {
1469 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1471 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1472
1473 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1474
1475 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1476 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1477 }
1478
1479 ExprKind::Repeat(expr, expr_len) => {
1480 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1481 }
1482
1483 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1484 expr.to_ty().map(TyKind::Slice)?
1485 }
1486
1487 ExprKind::Tup(exprs) => {
1488 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1489 TyKind::Tup(tys)
1490 }
1491
1492 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1496 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1497 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1498 } else {
1499 return None;
1500 }
1501 }
1502
1503 ExprKind::Underscore => TyKind::Infer,
1504
1505 _ => return None,
1507 };
1508
1509 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1510 }
1511
1512 pub fn precedence(&self) -> ExprPrecedence {
1513 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1514 for attr in attrs {
1515 if let AttrStyle::Outer = attr.style {
1516 return ExprPrecedence::Prefix;
1517 }
1518 }
1519 ExprPrecedence::Unambiguous
1520 }
1521
1522 match &self.kind {
1523 ExprKind::Closure(closure) => {
1524 match closure.fn_decl.output {
1525 FnRetTy::Default(_) => ExprPrecedence::Jump,
1526 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1527 }
1528 }
1529
1530 ExprKind::Break(_ , value)
1531 | ExprKind::Ret(value)
1532 | ExprKind::Yield(YieldKind::Prefix(value))
1533 | ExprKind::Yeet(value) => match value {
1534 Some(_) => ExprPrecedence::Jump,
1535 None => prefix_attrs_precedence(&self.attrs),
1536 },
1537
1538 ExprKind::Become(_) => ExprPrecedence::Jump,
1539
1540 ExprKind::Range(..) => ExprPrecedence::Range,
1545
1546 ExprKind::Binary(op, ..) => op.node.precedence(),
1548 ExprKind::Cast(..) => ExprPrecedence::Cast,
1549
1550 ExprKind::Assign(..) |
1551 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1552
1553 ExprKind::AddrOf(..)
1555 | ExprKind::Let(..)
1560 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1561
1562 ExprKind::Array(_)
1564 | ExprKind::Await(..)
1565 | ExprKind::Use(..)
1566 | ExprKind::Block(..)
1567 | ExprKind::Call(..)
1568 | ExprKind::ConstBlock(_)
1569 | ExprKind::Continue(..)
1570 | ExprKind::Field(..)
1571 | ExprKind::ForLoop { .. }
1572 | ExprKind::FormatArgs(..)
1573 | ExprKind::Gen(..)
1574 | ExprKind::If(..)
1575 | ExprKind::IncludedBytes(..)
1576 | ExprKind::Index(..)
1577 | ExprKind::InlineAsm(..)
1578 | ExprKind::Lit(_)
1579 | ExprKind::Loop(..)
1580 | ExprKind::MacCall(..)
1581 | ExprKind::Match(..)
1582 | ExprKind::MethodCall(..)
1583 | ExprKind::OffsetOf(..)
1584 | ExprKind::Paren(..)
1585 | ExprKind::Path(..)
1586 | ExprKind::Repeat(..)
1587 | ExprKind::Struct(..)
1588 | ExprKind::Try(..)
1589 | ExprKind::TryBlock(..)
1590 | ExprKind::Tup(_)
1591 | ExprKind::Type(..)
1592 | ExprKind::Underscore
1593 | ExprKind::UnsafeBinderCast(..)
1594 | ExprKind::While(..)
1595 | ExprKind::Yield(YieldKind::Postfix(..))
1596 | ExprKind::Err(_)
1597 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1598 }
1599 }
1600
1601 pub fn is_approximately_pattern(&self) -> bool {
1603 matches!(
1604 &self.peel_parens().kind,
1605 ExprKind::Array(_)
1606 | ExprKind::Call(_, _)
1607 | ExprKind::Tup(_)
1608 | ExprKind::Lit(_)
1609 | ExprKind::Range(_, _, _)
1610 | ExprKind::Underscore
1611 | ExprKind::Path(_, _)
1612 | ExprKind::Struct(_)
1613 )
1614 }
1615
1616 pub fn dummy() -> Expr {
1620 Expr {
1621 id: DUMMY_NODE_ID,
1622 kind: ExprKind::Dummy,
1623 span: DUMMY_SP,
1624 attrs: ThinVec::new(),
1625 tokens: None,
1626 }
1627 }
1628}
1629
1630impl From<P<Expr>> for Expr {
1631 fn from(value: P<Expr>) -> Self {
1632 *value
1633 }
1634}
1635
1636#[derive(Clone, Encodable, Decodable, Debug)]
1637pub struct Closure {
1638 pub binder: ClosureBinder,
1639 pub capture_clause: CaptureBy,
1640 pub constness: Const,
1641 pub coroutine_kind: Option<CoroutineKind>,
1642 pub movability: Movability,
1643 pub fn_decl: P<FnDecl>,
1644 pub body: P<Expr>,
1645 pub fn_decl_span: Span,
1647 pub fn_arg_span: Span,
1649}
1650
1651#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1653pub enum RangeLimits {
1654 HalfOpen,
1656 Closed,
1658}
1659
1660impl RangeLimits {
1661 pub fn as_str(&self) -> &'static str {
1662 match self {
1663 RangeLimits::HalfOpen => "..",
1664 RangeLimits::Closed => "..=",
1665 }
1666 }
1667}
1668
1669#[derive(Clone, Encodable, Decodable, Debug)]
1671pub struct MethodCall {
1672 pub seg: PathSegment,
1674 pub receiver: P<Expr>,
1676 pub args: ThinVec<P<Expr>>,
1678 pub span: Span,
1681}
1682
1683#[derive(Clone, Encodable, Decodable, Debug)]
1684pub enum StructRest {
1685 Base(P<Expr>),
1687 Rest(Span),
1689 None,
1691}
1692
1693#[derive(Clone, Encodable, Decodable, Debug)]
1694pub struct StructExpr {
1695 pub qself: Option<P<QSelf>>,
1696 pub path: Path,
1697 pub fields: ThinVec<ExprField>,
1698 pub rest: StructRest,
1699}
1700
1701#[derive(Clone, Encodable, Decodable, Debug)]
1703pub enum ExprKind {
1704 Array(ThinVec<P<Expr>>),
1706 ConstBlock(AnonConst),
1708 Call(P<Expr>, ThinVec<P<Expr>>),
1715 MethodCall(Box<MethodCall>),
1717 Tup(ThinVec<P<Expr>>),
1719 Binary(BinOp, P<Expr>, P<Expr>),
1721 Unary(UnOp, P<Expr>),
1723 Lit(token::Lit),
1725 Cast(P<Expr>, P<Ty>),
1727 Type(P<Expr>, P<Ty>),
1732 Let(P<Pat>, P<Expr>, Span, Recovered),
1737 If(P<Expr>, P<Block>, Option<P<Expr>>),
1744 While(P<Expr>, P<Block>, Option<Label>),
1748 ForLoop {
1754 pat: P<Pat>,
1755 iter: P<Expr>,
1756 body: P<Block>,
1757 label: Option<Label>,
1758 kind: ForLoopKind,
1759 },
1760 Loop(P<Block>, Option<Label>, Span),
1764 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1766 Closure(Box<Closure>),
1768 Block(P<Block>, Option<Label>),
1770 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1776 Await(P<Expr>, Span),
1778 Use(P<Expr>, Span),
1780
1781 TryBlock(P<Block>),
1783
1784 Assign(P<Expr>, P<Expr>, Span),
1787 AssignOp(AssignOp, P<Expr>, P<Expr>),
1791 Field(P<Expr>, Ident),
1793 Index(P<Expr>, P<Expr>, Span),
1796 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1798 Underscore,
1800
1801 Path(Option<P<QSelf>>, Path),
1806
1807 AddrOf(BorrowKind, Mutability, P<Expr>),
1809 Break(Option<Label>, Option<P<Expr>>),
1811 Continue(Option<Label>),
1813 Ret(Option<P<Expr>>),
1815
1816 InlineAsm(P<InlineAsm>),
1818
1819 OffsetOf(P<Ty>, Vec<Ident>),
1824
1825 MacCall(P<MacCall>),
1827
1828 Struct(P<StructExpr>),
1832
1833 Repeat(P<Expr>, AnonConst),
1838
1839 Paren(P<Expr>),
1841
1842 Try(P<Expr>),
1844
1845 Yield(YieldKind),
1847
1848 Yeet(Option<P<Expr>>),
1851
1852 Become(P<Expr>),
1856
1857 IncludedBytes(ByteSymbol),
1869
1870 FormatArgs(P<FormatArgs>),
1872
1873 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1874
1875 Err(ErrorGuaranteed),
1877
1878 Dummy,
1880}
1881
1882#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1884pub enum ForLoopKind {
1885 For,
1886 ForAwait,
1887}
1888
1889#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1891pub enum GenBlockKind {
1892 Async,
1893 Gen,
1894 AsyncGen,
1895}
1896
1897impl fmt::Display for GenBlockKind {
1898 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1899 self.modifier().fmt(f)
1900 }
1901}
1902
1903impl GenBlockKind {
1904 pub fn modifier(&self) -> &'static str {
1905 match self {
1906 GenBlockKind::Async => "async",
1907 GenBlockKind::Gen => "gen",
1908 GenBlockKind::AsyncGen => "async gen",
1909 }
1910 }
1911}
1912
1913#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1915#[derive(Encodable, Decodable, HashStable_Generic)]
1916pub enum UnsafeBinderCastKind {
1917 Wrap,
1919 Unwrap,
1921}
1922
1923#[derive(Clone, Encodable, Decodable, Debug)]
1938pub struct QSelf {
1939 pub ty: P<Ty>,
1940
1941 pub path_span: Span,
1945 pub position: usize,
1946}
1947
1948#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1950pub enum CaptureBy {
1951 Value {
1953 move_kw: Span,
1955 },
1956 Ref,
1958 Use {
1964 use_kw: Span,
1966 },
1967}
1968
1969#[derive(Clone, Encodable, Decodable, Debug)]
1971pub enum ClosureBinder {
1972 NotPresent,
1974 For {
1976 span: Span,
1983
1984 generic_params: ThinVec<GenericParam>,
1991 },
1992}
1993
1994#[derive(Clone, Encodable, Decodable, Debug)]
1997pub struct MacCall {
1998 pub path: Path,
1999 pub args: P<DelimArgs>,
2000}
2001
2002impl MacCall {
2003 pub fn span(&self) -> Span {
2004 self.path.span.to(self.args.dspan.entire())
2005 }
2006}
2007
2008#[derive(Clone, Encodable, Decodable, Debug)]
2010pub enum AttrArgs {
2011 Empty,
2013 Delimited(DelimArgs),
2015 Eq {
2017 eq_span: Span,
2019 expr: P<Expr>,
2020 },
2021}
2022
2023impl AttrArgs {
2024 pub fn span(&self) -> Option<Span> {
2025 match self {
2026 AttrArgs::Empty => None,
2027 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2028 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2029 }
2030 }
2031
2032 pub fn inner_tokens(&self) -> TokenStream {
2035 match self {
2036 AttrArgs::Empty => TokenStream::default(),
2037 AttrArgs::Delimited(args) => args.tokens.clone(),
2038 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2039 }
2040 }
2041}
2042
2043#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2045pub struct DelimArgs {
2046 pub dspan: DelimSpan,
2047 pub delim: Delimiter, pub tokens: TokenStream,
2049}
2050
2051impl DelimArgs {
2052 pub fn need_semicolon(&self) -> bool {
2055 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2056 }
2057}
2058
2059#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2061pub struct MacroDef {
2062 pub body: P<DelimArgs>,
2063 pub macro_rules: bool,
2065}
2066
2067#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2068#[derive(HashStable_Generic)]
2069pub enum StrStyle {
2070 Cooked,
2072 Raw(u8),
2076}
2077
2078#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
2080pub enum MatchKind {
2081 Prefix,
2083 Postfix,
2085}
2086
2087#[derive(Clone, Encodable, Decodable, Debug)]
2089pub enum YieldKind {
2090 Prefix(Option<P<Expr>>),
2092 Postfix(P<Expr>),
2094}
2095
2096impl YieldKind {
2097 pub const fn expr(&self) -> Option<&P<Expr>> {
2101 match self {
2102 YieldKind::Prefix(expr) => expr.as_ref(),
2103 YieldKind::Postfix(expr) => Some(expr),
2104 }
2105 }
2106
2107 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2109 match self {
2110 YieldKind::Prefix(expr) => expr.as_mut(),
2111 YieldKind::Postfix(expr) => Some(expr),
2112 }
2113 }
2114
2115 pub const fn same_kind(&self, other: &Self) -> bool {
2117 match (self, other) {
2118 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2119 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2120 _ => false,
2121 }
2122 }
2123}
2124
2125#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2127pub struct MetaItemLit {
2128 pub symbol: Symbol,
2130 pub suffix: Option<Symbol>,
2132 pub kind: LitKind,
2135 pub span: Span,
2136}
2137
2138#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2140pub struct StrLit {
2141 pub symbol: Symbol,
2143 pub suffix: Option<Symbol>,
2145 pub symbol_unescaped: Symbol,
2147 pub style: StrStyle,
2148 pub span: Span,
2149}
2150
2151impl StrLit {
2152 pub fn as_token_lit(&self) -> token::Lit {
2153 let token_kind = match self.style {
2154 StrStyle::Cooked => token::Str,
2155 StrStyle::Raw(n) => token::StrRaw(n),
2156 };
2157 token::Lit::new(token_kind, self.symbol, self.suffix)
2158 }
2159}
2160
2161#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2163#[derive(HashStable_Generic)]
2164pub enum LitIntType {
2165 Signed(IntTy),
2167 Unsigned(UintTy),
2169 Unsuffixed,
2171}
2172
2173#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2175#[derive(HashStable_Generic)]
2176pub enum LitFloatType {
2177 Suffixed(FloatTy),
2179 Unsuffixed,
2181}
2182
2183#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2190pub enum LitKind {
2191 Str(Symbol, StrStyle),
2194 ByteStr(ByteSymbol, StrStyle),
2197 CStr(ByteSymbol, StrStyle),
2201 Byte(u8),
2203 Char(char),
2205 Int(Pu128, LitIntType),
2207 Float(Symbol, LitFloatType),
2211 Bool(bool),
2213 Err(ErrorGuaranteed),
2215}
2216
2217impl LitKind {
2218 pub fn str(&self) -> Option<Symbol> {
2219 match *self {
2220 LitKind::Str(s, _) => Some(s),
2221 _ => None,
2222 }
2223 }
2224
2225 pub fn is_str(&self) -> bool {
2227 matches!(self, LitKind::Str(..))
2228 }
2229
2230 pub fn is_bytestr(&self) -> bool {
2232 matches!(self, LitKind::ByteStr(..))
2233 }
2234
2235 pub fn is_numeric(&self) -> bool {
2237 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2238 }
2239
2240 pub fn is_unsuffixed(&self) -> bool {
2243 !self.is_suffixed()
2244 }
2245
2246 pub fn is_suffixed(&self) -> bool {
2248 match *self {
2249 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2251 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2252 LitKind::Str(..)
2254 | LitKind::ByteStr(..)
2255 | LitKind::CStr(..)
2256 | LitKind::Byte(..)
2257 | LitKind::Char(..)
2258 | LitKind::Int(_, LitIntType::Unsuffixed)
2259 | LitKind::Float(_, LitFloatType::Unsuffixed)
2260 | LitKind::Bool(..)
2261 | LitKind::Err(_) => false,
2262 }
2263 }
2264}
2265
2266#[derive(Clone, Encodable, Decodable, Debug)]
2269pub struct MutTy {
2270 pub ty: P<Ty>,
2271 pub mutbl: Mutability,
2272}
2273
2274#[derive(Clone, Encodable, Decodable, Debug)]
2277pub struct FnSig {
2278 pub header: FnHeader,
2279 pub decl: P<FnDecl>,
2280 pub span: Span,
2281}
2282
2283#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2284#[derive(Encodable, Decodable, HashStable_Generic)]
2285pub enum FloatTy {
2286 F16,
2287 F32,
2288 F64,
2289 F128,
2290}
2291
2292impl FloatTy {
2293 pub fn name_str(self) -> &'static str {
2294 match self {
2295 FloatTy::F16 => "f16",
2296 FloatTy::F32 => "f32",
2297 FloatTy::F64 => "f64",
2298 FloatTy::F128 => "f128",
2299 }
2300 }
2301
2302 pub fn name(self) -> Symbol {
2303 match self {
2304 FloatTy::F16 => sym::f16,
2305 FloatTy::F32 => sym::f32,
2306 FloatTy::F64 => sym::f64,
2307 FloatTy::F128 => sym::f128,
2308 }
2309 }
2310}
2311
2312#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2313#[derive(Encodable, Decodable, HashStable_Generic)]
2314pub enum IntTy {
2315 Isize,
2316 I8,
2317 I16,
2318 I32,
2319 I64,
2320 I128,
2321}
2322
2323impl IntTy {
2324 pub fn name_str(&self) -> &'static str {
2325 match *self {
2326 IntTy::Isize => "isize",
2327 IntTy::I8 => "i8",
2328 IntTy::I16 => "i16",
2329 IntTy::I32 => "i32",
2330 IntTy::I64 => "i64",
2331 IntTy::I128 => "i128",
2332 }
2333 }
2334
2335 pub fn name(&self) -> Symbol {
2336 match *self {
2337 IntTy::Isize => sym::isize,
2338 IntTy::I8 => sym::i8,
2339 IntTy::I16 => sym::i16,
2340 IntTy::I32 => sym::i32,
2341 IntTy::I64 => sym::i64,
2342 IntTy::I128 => sym::i128,
2343 }
2344 }
2345}
2346
2347#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2348#[derive(Encodable, Decodable, HashStable_Generic)]
2349pub enum UintTy {
2350 Usize,
2351 U8,
2352 U16,
2353 U32,
2354 U64,
2355 U128,
2356}
2357
2358impl UintTy {
2359 pub fn name_str(&self) -> &'static str {
2360 match *self {
2361 UintTy::Usize => "usize",
2362 UintTy::U8 => "u8",
2363 UintTy::U16 => "u16",
2364 UintTy::U32 => "u32",
2365 UintTy::U64 => "u64",
2366 UintTy::U128 => "u128",
2367 }
2368 }
2369
2370 pub fn name(&self) -> Symbol {
2371 match *self {
2372 UintTy::Usize => sym::usize,
2373 UintTy::U8 => sym::u8,
2374 UintTy::U16 => sym::u16,
2375 UintTy::U32 => sym::u32,
2376 UintTy::U64 => sym::u64,
2377 UintTy::U128 => sym::u128,
2378 }
2379 }
2380}
2381
2382#[derive(Clone, Encodable, Decodable, Debug)]
2393pub struct AssocItemConstraint {
2394 pub id: NodeId,
2395 pub ident: Ident,
2396 pub gen_args: Option<GenericArgs>,
2397 pub kind: AssocItemConstraintKind,
2398 pub span: Span,
2399}
2400
2401#[derive(Clone, Encodable, Decodable, Debug)]
2402pub enum Term {
2403 Ty(P<Ty>),
2404 Const(AnonConst),
2405}
2406
2407impl From<P<Ty>> for Term {
2408 fn from(v: P<Ty>) -> Self {
2409 Term::Ty(v)
2410 }
2411}
2412
2413impl From<AnonConst> for Term {
2414 fn from(v: AnonConst) -> Self {
2415 Term::Const(v)
2416 }
2417}
2418
2419#[derive(Clone, Encodable, Decodable, Debug)]
2421pub enum AssocItemConstraintKind {
2422 Equality { term: Term },
2429 Bound { bounds: GenericBounds },
2431}
2432
2433#[derive(Encodable, Decodable, Debug)]
2434pub struct Ty {
2435 pub id: NodeId,
2436 pub kind: TyKind,
2437 pub span: Span,
2438 pub tokens: Option<LazyAttrTokenStream>,
2439}
2440
2441impl Clone for Ty {
2442 fn clone(&self) -> Self {
2443 ensure_sufficient_stack(|| Self {
2444 id: self.id,
2445 kind: self.kind.clone(),
2446 span: self.span,
2447 tokens: self.tokens.clone(),
2448 })
2449 }
2450}
2451
2452impl From<P<Ty>> for Ty {
2453 fn from(value: P<Ty>) -> Self {
2454 *value
2455 }
2456}
2457
2458impl Ty {
2459 pub fn peel_refs(&self) -> &Self {
2460 let mut final_ty = self;
2461 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2462 {
2463 final_ty = ty;
2464 }
2465 final_ty
2466 }
2467
2468 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2469 match &self.kind {
2470 TyKind::Infer => true,
2471 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2472 _ => false,
2473 }
2474 }
2475}
2476
2477#[derive(Clone, Encodable, Decodable, Debug)]
2478pub struct FnPtrTy {
2479 pub safety: Safety,
2480 pub ext: Extern,
2481 pub generic_params: ThinVec<GenericParam>,
2482 pub decl: P<FnDecl>,
2483 pub decl_span: Span,
2486}
2487
2488#[derive(Clone, Encodable, Decodable, Debug)]
2489pub struct UnsafeBinderTy {
2490 pub generic_params: ThinVec<GenericParam>,
2491 pub inner_ty: P<Ty>,
2492}
2493
2494#[derive(Clone, Encodable, Decodable, Debug)]
2498pub enum TyKind {
2499 Slice(P<Ty>),
2501 Array(P<Ty>, AnonConst),
2503 Ptr(MutTy),
2505 Ref(Option<Lifetime>, MutTy),
2507 PinnedRef(Option<Lifetime>, MutTy),
2511 FnPtr(P<FnPtrTy>),
2513 UnsafeBinder(P<UnsafeBinderTy>),
2515 Never,
2517 Tup(ThinVec<P<Ty>>),
2519 Path(Option<P<QSelf>>, Path),
2524 TraitObject(GenericBounds, TraitObjectSyntax),
2527 ImplTrait(NodeId, GenericBounds),
2534 Paren(P<Ty>),
2536 Typeof(AnonConst),
2538 Infer,
2541 ImplicitSelf,
2543 MacCall(P<MacCall>),
2545 CVarArgs,
2547 Pat(P<Ty>, P<TyPat>),
2550 Dummy,
2552 Err(ErrorGuaranteed),
2554}
2555
2556impl TyKind {
2557 pub fn is_implicit_self(&self) -> bool {
2558 matches!(self, TyKind::ImplicitSelf)
2559 }
2560
2561 pub fn is_unit(&self) -> bool {
2562 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2563 }
2564
2565 pub fn is_simple_path(&self) -> Option<Symbol> {
2566 if let TyKind::Path(None, Path { segments, .. }) = &self
2567 && let [segment] = &segments[..]
2568 && segment.args.is_none()
2569 {
2570 Some(segment.ident.name)
2571 } else {
2572 None
2573 }
2574 }
2575
2576 pub fn maybe_scalar(&self) -> bool {
2584 let Some(ty_sym) = self.is_simple_path() else {
2585 return self.is_unit();
2587 };
2588 matches!(
2589 ty_sym,
2590 sym::i8
2591 | sym::i16
2592 | sym::i32
2593 | sym::i64
2594 | sym::i128
2595 | sym::u8
2596 | sym::u16
2597 | sym::u32
2598 | sym::u64
2599 | sym::u128
2600 | sym::f16
2601 | sym::f32
2602 | sym::f64
2603 | sym::f128
2604 | sym::char
2605 | sym::bool
2606 )
2607 }
2608}
2609
2610#[derive(Clone, Encodable, Decodable, Debug)]
2612pub struct TyPat {
2613 pub id: NodeId,
2614 pub kind: TyPatKind,
2615 pub span: Span,
2616 pub tokens: Option<LazyAttrTokenStream>,
2617}
2618
2619#[derive(Clone, Encodable, Decodable, Debug)]
2623pub enum TyPatKind {
2624 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2626
2627 Or(ThinVec<P<TyPat>>),
2628
2629 Err(ErrorGuaranteed),
2631}
2632
2633#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2635#[repr(u8)]
2636pub enum TraitObjectSyntax {
2637 Dyn = 0,
2639 None = 1,
2640}
2641
2642unsafe impl Tag for TraitObjectSyntax {
2646 const BITS: u32 = 2;
2647
2648 fn into_usize(self) -> usize {
2649 self as u8 as usize
2650 }
2651
2652 unsafe fn from_usize(tag: usize) -> Self {
2653 match tag {
2654 0 => TraitObjectSyntax::Dyn,
2655 1 => TraitObjectSyntax::None,
2656 _ => unreachable!(),
2657 }
2658 }
2659}
2660
2661#[derive(Clone, Encodable, Decodable, Debug)]
2662pub enum PreciseCapturingArg {
2663 Lifetime(Lifetime),
2665 Arg(Path, NodeId),
2667}
2668
2669#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2673pub enum InlineAsmRegOrRegClass {
2674 Reg(Symbol),
2675 RegClass(Symbol),
2676}
2677
2678#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2679pub struct InlineAsmOptions(u16);
2680bitflags::bitflags! {
2681 impl InlineAsmOptions: u16 {
2682 const PURE = 1 << 0;
2683 const NOMEM = 1 << 1;
2684 const READONLY = 1 << 2;
2685 const PRESERVES_FLAGS = 1 << 3;
2686 const NORETURN = 1 << 4;
2687 const NOSTACK = 1 << 5;
2688 const ATT_SYNTAX = 1 << 6;
2689 const RAW = 1 << 7;
2690 const MAY_UNWIND = 1 << 8;
2691 }
2692}
2693
2694impl InlineAsmOptions {
2695 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2696
2697 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2698 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2699
2700 pub fn human_readable_names(&self) -> Vec<&'static str> {
2701 let mut options = vec![];
2702
2703 if self.contains(InlineAsmOptions::PURE) {
2704 options.push("pure");
2705 }
2706 if self.contains(InlineAsmOptions::NOMEM) {
2707 options.push("nomem");
2708 }
2709 if self.contains(InlineAsmOptions::READONLY) {
2710 options.push("readonly");
2711 }
2712 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2713 options.push("preserves_flags");
2714 }
2715 if self.contains(InlineAsmOptions::NORETURN) {
2716 options.push("noreturn");
2717 }
2718 if self.contains(InlineAsmOptions::NOSTACK) {
2719 options.push("nostack");
2720 }
2721 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2722 options.push("att_syntax");
2723 }
2724 if self.contains(InlineAsmOptions::RAW) {
2725 options.push("raw");
2726 }
2727 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2728 options.push("may_unwind");
2729 }
2730
2731 options
2732 }
2733}
2734
2735impl std::fmt::Debug for InlineAsmOptions {
2736 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2737 bitflags::parser::to_writer(self, f)
2738 }
2739}
2740
2741#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2742pub enum InlineAsmTemplatePiece {
2743 String(Cow<'static, str>),
2744 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2745}
2746
2747impl fmt::Display for InlineAsmTemplatePiece {
2748 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2749 match self {
2750 Self::String(s) => {
2751 for c in s.chars() {
2752 match c {
2753 '{' => f.write_str("{{")?,
2754 '}' => f.write_str("}}")?,
2755 _ => c.fmt(f)?,
2756 }
2757 }
2758 Ok(())
2759 }
2760 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2761 write!(f, "{{{operand_idx}:{modifier}}}")
2762 }
2763 Self::Placeholder { operand_idx, modifier: None, .. } => {
2764 write!(f, "{{{operand_idx}}}")
2765 }
2766 }
2767 }
2768}
2769
2770impl InlineAsmTemplatePiece {
2771 pub fn to_string(s: &[Self]) -> String {
2773 use fmt::Write;
2774 let mut out = String::new();
2775 for p in s.iter() {
2776 let _ = write!(out, "{p}");
2777 }
2778 out
2779 }
2780}
2781
2782#[derive(Clone, Encodable, Decodable, Debug)]
2790pub struct InlineAsmSym {
2791 pub id: NodeId,
2792 pub qself: Option<P<QSelf>>,
2793 pub path: Path,
2794}
2795
2796#[derive(Clone, Encodable, Decodable, Debug)]
2800pub enum InlineAsmOperand {
2801 In {
2802 reg: InlineAsmRegOrRegClass,
2803 expr: P<Expr>,
2804 },
2805 Out {
2806 reg: InlineAsmRegOrRegClass,
2807 late: bool,
2808 expr: Option<P<Expr>>,
2809 },
2810 InOut {
2811 reg: InlineAsmRegOrRegClass,
2812 late: bool,
2813 expr: P<Expr>,
2814 },
2815 SplitInOut {
2816 reg: InlineAsmRegOrRegClass,
2817 late: bool,
2818 in_expr: P<Expr>,
2819 out_expr: Option<P<Expr>>,
2820 },
2821 Const {
2822 anon_const: AnonConst,
2823 },
2824 Sym {
2825 sym: InlineAsmSym,
2826 },
2827 Label {
2828 block: P<Block>,
2829 },
2830}
2831
2832impl InlineAsmOperand {
2833 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2834 match self {
2835 Self::In { reg, .. }
2836 | Self::Out { reg, .. }
2837 | Self::InOut { reg, .. }
2838 | Self::SplitInOut { reg, .. } => Some(reg),
2839 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2840 }
2841 }
2842}
2843
2844#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2845pub enum AsmMacro {
2846 Asm,
2848 GlobalAsm,
2850 NakedAsm,
2852}
2853
2854impl AsmMacro {
2855 pub const fn macro_name(self) -> &'static str {
2856 match self {
2857 AsmMacro::Asm => "asm",
2858 AsmMacro::GlobalAsm => "global_asm",
2859 AsmMacro::NakedAsm => "naked_asm",
2860 }
2861 }
2862
2863 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2864 match self {
2865 AsmMacro::Asm => true,
2866 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2867 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2868 }
2869 }
2870
2871 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2872 match self {
2873 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2874 AsmMacro::GlobalAsm => true,
2875 AsmMacro::NakedAsm => true,
2876 }
2877 }
2878}
2879
2880#[derive(Clone, Encodable, Decodable, Debug)]
2884pub struct InlineAsm {
2885 pub asm_macro: AsmMacro,
2886 pub template: Vec<InlineAsmTemplatePiece>,
2887 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2888 pub operands: Vec<(InlineAsmOperand, Span)>,
2889 pub clobber_abis: Vec<(Symbol, Span)>,
2890 pub options: InlineAsmOptions,
2891 pub line_spans: Vec<Span>,
2892}
2893
2894#[derive(Clone, Encodable, Decodable, Debug)]
2898pub struct Param {
2899 pub attrs: AttrVec,
2900 pub ty: P<Ty>,
2901 pub pat: P<Pat>,
2902 pub id: NodeId,
2903 pub span: Span,
2904 pub is_placeholder: bool,
2905}
2906
2907#[derive(Clone, Encodable, Decodable, Debug)]
2911pub enum SelfKind {
2912 Value(Mutability),
2914 Region(Option<Lifetime>, Mutability),
2916 Pinned(Option<Lifetime>, Mutability),
2918 Explicit(P<Ty>, Mutability),
2920}
2921
2922impl SelfKind {
2923 pub fn to_ref_suggestion(&self) -> String {
2924 match self {
2925 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2926 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2927 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2928 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2929 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2930 unreachable!("if we had an explicit self, we wouldn't be here")
2931 }
2932 }
2933 }
2934}
2935
2936pub type ExplicitSelf = Spanned<SelfKind>;
2937
2938impl Param {
2939 pub fn to_self(&self) -> Option<ExplicitSelf> {
2941 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2942 if ident.name == kw::SelfLower {
2943 return match self.ty.kind {
2944 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2945 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2946 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2947 }
2948 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2949 if ty.kind.is_implicit_self() =>
2950 {
2951 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2952 }
2953 _ => Some(respan(
2954 self.pat.span.to(self.ty.span),
2955 SelfKind::Explicit(self.ty.clone(), mutbl),
2956 )),
2957 };
2958 }
2959 }
2960 None
2961 }
2962
2963 pub fn is_self(&self) -> bool {
2965 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2966 ident.name == kw::SelfLower
2967 } else {
2968 false
2969 }
2970 }
2971
2972 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2974 let span = eself.span.to(eself_ident.span);
2975 let infer_ty = P(Ty {
2976 id: DUMMY_NODE_ID,
2977 kind: TyKind::ImplicitSelf,
2978 span: eself_ident.span,
2979 tokens: None,
2980 });
2981 let (mutbl, ty) = match eself.node {
2982 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2983 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2984 SelfKind::Region(lt, mutbl) => (
2985 Mutability::Not,
2986 P(Ty {
2987 id: DUMMY_NODE_ID,
2988 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2989 span,
2990 tokens: None,
2991 }),
2992 ),
2993 SelfKind::Pinned(lt, mutbl) => (
2994 mutbl,
2995 P(Ty {
2996 id: DUMMY_NODE_ID,
2997 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2998 span,
2999 tokens: None,
3000 }),
3001 ),
3002 };
3003 Param {
3004 attrs,
3005 pat: P(Pat {
3006 id: DUMMY_NODE_ID,
3007 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
3008 span,
3009 tokens: None,
3010 }),
3011 span,
3012 ty,
3013 id: DUMMY_NODE_ID,
3014 is_placeholder: false,
3015 }
3016 }
3017}
3018
3019#[derive(Clone, Encodable, Decodable, Debug)]
3026pub struct FnDecl {
3027 pub inputs: ThinVec<Param>,
3028 pub output: FnRetTy,
3029}
3030
3031impl FnDecl {
3032 pub fn has_self(&self) -> bool {
3033 self.inputs.get(0).is_some_and(Param::is_self)
3034 }
3035 pub fn c_variadic(&self) -> bool {
3036 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3037 }
3038}
3039
3040#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3042pub enum IsAuto {
3043 Yes,
3044 No,
3045}
3046
3047#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3049#[derive(HashStable_Generic)]
3050pub enum Safety {
3051 Unsafe(Span),
3053 Safe(Span),
3055 Default,
3058}
3059
3060#[derive(Copy, Clone, Encodable, Decodable, Debug)]
3066pub enum CoroutineKind {
3067 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3069 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3071 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3073}
3074
3075impl CoroutineKind {
3076 pub fn span(self) -> Span {
3077 match self {
3078 CoroutineKind::Async { span, .. } => span,
3079 CoroutineKind::Gen { span, .. } => span,
3080 CoroutineKind::AsyncGen { span, .. } => span,
3081 }
3082 }
3083
3084 pub fn as_str(self) -> &'static str {
3085 match self {
3086 CoroutineKind::Async { .. } => "async",
3087 CoroutineKind::Gen { .. } => "gen",
3088 CoroutineKind::AsyncGen { .. } => "async gen",
3089 }
3090 }
3091
3092 pub fn closure_id(self) -> NodeId {
3093 match self {
3094 CoroutineKind::Async { closure_id, .. }
3095 | CoroutineKind::Gen { closure_id, .. }
3096 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3097 }
3098 }
3099
3100 pub fn return_id(self) -> (NodeId, Span) {
3103 match self {
3104 CoroutineKind::Async { return_impl_trait_id, span, .. }
3105 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3106 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3107 (return_impl_trait_id, span)
3108 }
3109 }
3110 }
3111}
3112
3113#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3114#[derive(HashStable_Generic)]
3115pub enum Const {
3116 Yes(Span),
3117 No,
3118}
3119
3120#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3123pub enum Defaultness {
3124 Default(Span),
3125 Final,
3126}
3127
3128#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3129pub enum ImplPolarity {
3130 Positive,
3132 Negative(Span),
3134}
3135
3136impl fmt::Debug for ImplPolarity {
3137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3138 match *self {
3139 ImplPolarity::Positive => "positive".fmt(f),
3140 ImplPolarity::Negative(_) => "negative".fmt(f),
3141 }
3142 }
3143}
3144
3145#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3147#[derive(HashStable_Generic)]
3148pub enum BoundPolarity {
3149 Positive,
3151 Negative(Span),
3153 Maybe(Span),
3155}
3156
3157impl BoundPolarity {
3158 pub fn as_str(self) -> &'static str {
3159 match self {
3160 Self::Positive => "",
3161 Self::Negative(_) => "!",
3162 Self::Maybe(_) => "?",
3163 }
3164 }
3165}
3166
3167#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3169#[derive(HashStable_Generic)]
3170pub enum BoundConstness {
3171 Never,
3173 Always(Span),
3175 Maybe(Span),
3177}
3178
3179impl BoundConstness {
3180 pub fn as_str(self) -> &'static str {
3181 match self {
3182 Self::Never => "",
3183 Self::Always(_) => "const",
3184 Self::Maybe(_) => "[const]",
3185 }
3186 }
3187}
3188
3189#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3191#[derive(HashStable_Generic)]
3192pub enum BoundAsyncness {
3193 Normal,
3195 Async(Span),
3197}
3198
3199impl BoundAsyncness {
3200 pub fn as_str(self) -> &'static str {
3201 match self {
3202 Self::Normal => "",
3203 Self::Async(_) => "async",
3204 }
3205 }
3206}
3207
3208#[derive(Clone, Encodable, Decodable, Debug)]
3209pub enum FnRetTy {
3210 Default(Span),
3215 Ty(P<Ty>),
3217}
3218
3219impl FnRetTy {
3220 pub fn span(&self) -> Span {
3221 match self {
3222 &FnRetTy::Default(span) => span,
3223 FnRetTy::Ty(ty) => ty.span,
3224 }
3225 }
3226}
3227
3228#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3229pub enum Inline {
3230 Yes,
3231 No,
3232}
3233
3234#[derive(Clone, Encodable, Decodable, Debug)]
3236pub enum ModKind {
3237 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3242 Unloaded,
3244}
3245
3246#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3247pub struct ModSpans {
3248 pub inner_span: Span,
3251 pub inject_use_span: Span,
3252}
3253
3254#[derive(Clone, Encodable, Decodable, Debug)]
3258pub struct ForeignMod {
3259 pub extern_span: Span,
3261 pub safety: Safety,
3264 pub abi: Option<StrLit>,
3265 pub items: ThinVec<P<ForeignItem>>,
3266}
3267
3268#[derive(Clone, Encodable, Decodable, Debug)]
3269pub struct EnumDef {
3270 pub variants: ThinVec<Variant>,
3271}
3272#[derive(Clone, Encodable, Decodable, Debug)]
3274pub struct Variant {
3275 pub attrs: AttrVec,
3277 pub id: NodeId,
3279 pub span: Span,
3281 pub vis: Visibility,
3283 pub ident: Ident,
3285
3286 pub data: VariantData,
3288 pub disr_expr: Option<AnonConst>,
3290 pub is_placeholder: bool,
3292}
3293
3294#[derive(Clone, Encodable, Decodable, Debug)]
3296pub enum UseTreeKind {
3297 Simple(Option<Ident>),
3299 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3308 Glob,
3310}
3311
3312#[derive(Clone, Encodable, Decodable, Debug)]
3315pub struct UseTree {
3316 pub prefix: Path,
3317 pub kind: UseTreeKind,
3318 pub span: Span,
3319}
3320
3321impl UseTree {
3322 pub fn ident(&self) -> Ident {
3323 match self.kind {
3324 UseTreeKind::Simple(Some(rename)) => rename,
3325 UseTreeKind::Simple(None) => {
3326 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3327 }
3328 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3329 }
3330 }
3331}
3332
3333#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3337pub enum AttrStyle {
3338 Outer,
3339 Inner,
3340}
3341
3342pub type AttrVec = ThinVec<Attribute>;
3344
3345#[derive(Clone, Encodable, Decodable, Debug)]
3347pub struct Attribute {
3348 pub kind: AttrKind,
3349 pub id: AttrId,
3350 pub style: AttrStyle,
3353 pub span: Span,
3354}
3355
3356#[derive(Clone, Encodable, Decodable, Debug)]
3357pub enum AttrKind {
3358 Normal(P<NormalAttr>),
3360
3361 DocComment(CommentKind, Symbol),
3365}
3366
3367#[derive(Clone, Encodable, Decodable, Debug)]
3368pub struct NormalAttr {
3369 pub item: AttrItem,
3370 pub tokens: Option<LazyAttrTokenStream>,
3372}
3373
3374impl NormalAttr {
3375 pub fn from_ident(ident: Ident) -> Self {
3376 Self {
3377 item: AttrItem {
3378 unsafety: Safety::Default,
3379 path: Path::from_ident(ident),
3380 args: AttrArgs::Empty,
3381 tokens: None,
3382 },
3383 tokens: None,
3384 }
3385 }
3386}
3387
3388#[derive(Clone, Encodable, Decodable, Debug)]
3389pub struct AttrItem {
3390 pub unsafety: Safety,
3391 pub path: Path,
3392 pub args: AttrArgs,
3393 pub tokens: Option<LazyAttrTokenStream>,
3395}
3396
3397impl AttrItem {
3398 pub fn is_valid_for_outer_style(&self) -> bool {
3399 self.path == sym::cfg_attr
3400 || self.path == sym::cfg
3401 || self.path == sym::forbid
3402 || self.path == sym::warn
3403 || self.path == sym::allow
3404 || self.path == sym::deny
3405 }
3406}
3407
3408#[derive(Clone, Encodable, Decodable, Debug)]
3415pub struct TraitRef {
3416 pub path: Path,
3417 pub ref_id: NodeId,
3418}
3419
3420#[derive(Clone, Encodable, Decodable, Debug)]
3422pub enum Parens {
3423 Yes,
3424 No,
3425}
3426
3427#[derive(Clone, Encodable, Decodable, Debug)]
3428pub struct PolyTraitRef {
3429 pub bound_generic_params: ThinVec<GenericParam>,
3431
3432 pub modifiers: TraitBoundModifiers,
3434
3435 pub trait_ref: TraitRef,
3437
3438 pub span: Span,
3439
3440 pub parens: Parens,
3443}
3444
3445impl PolyTraitRef {
3446 pub fn new(
3447 generic_params: ThinVec<GenericParam>,
3448 path: Path,
3449 modifiers: TraitBoundModifiers,
3450 span: Span,
3451 parens: Parens,
3452 ) -> Self {
3453 PolyTraitRef {
3454 bound_generic_params: generic_params,
3455 modifiers,
3456 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3457 span,
3458 parens,
3459 }
3460 }
3461}
3462
3463#[derive(Clone, Encodable, Decodable, Debug)]
3464pub struct Visibility {
3465 pub kind: VisibilityKind,
3466 pub span: Span,
3467 pub tokens: Option<LazyAttrTokenStream>,
3468}
3469
3470#[derive(Clone, Encodable, Decodable, Debug)]
3471pub enum VisibilityKind {
3472 Public,
3473 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3474 Inherited,
3475}
3476
3477impl VisibilityKind {
3478 pub fn is_pub(&self) -> bool {
3479 matches!(self, VisibilityKind::Public)
3480 }
3481}
3482
3483#[derive(Clone, Encodable, Decodable, Debug)]
3487pub struct FieldDef {
3488 pub attrs: AttrVec,
3489 pub id: NodeId,
3490 pub span: Span,
3491 pub vis: Visibility,
3492 pub safety: Safety,
3493 pub ident: Option<Ident>,
3494
3495 pub ty: P<Ty>,
3496 pub default: Option<AnonConst>,
3497 pub is_placeholder: bool,
3498}
3499
3500#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3502pub enum Recovered {
3503 No,
3504 Yes(ErrorGuaranteed),
3505}
3506
3507#[derive(Clone, Encodable, Decodable, Debug)]
3509pub enum VariantData {
3510 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3514 Tuple(ThinVec<FieldDef>, NodeId),
3518 Unit(NodeId),
3522}
3523
3524impl VariantData {
3525 pub fn fields(&self) -> &[FieldDef] {
3527 match self {
3528 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3529 _ => &[],
3530 }
3531 }
3532
3533 pub fn ctor_node_id(&self) -> Option<NodeId> {
3535 match *self {
3536 VariantData::Struct { .. } => None,
3537 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3538 }
3539 }
3540}
3541
3542#[derive(Clone, Encodable, Decodable, Debug)]
3544pub struct Item<K = ItemKind> {
3545 pub attrs: AttrVec,
3546 pub id: NodeId,
3547 pub span: Span,
3548 pub vis: Visibility,
3549
3550 pub kind: K,
3551
3552 pub tokens: Option<LazyAttrTokenStream>,
3560}
3561
3562impl Item {
3563 pub fn span_with_attributes(&self) -> Span {
3565 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3566 }
3567
3568 pub fn opt_generics(&self) -> Option<&Generics> {
3569 match &self.kind {
3570 ItemKind::ExternCrate(..)
3571 | ItemKind::Use(_)
3572 | ItemKind::Mod(..)
3573 | ItemKind::ForeignMod(_)
3574 | ItemKind::GlobalAsm(_)
3575 | ItemKind::MacCall(_)
3576 | ItemKind::Delegation(_)
3577 | ItemKind::DelegationMac(_)
3578 | ItemKind::MacroDef(..) => None,
3579 ItemKind::Static(_) => None,
3580 ItemKind::Const(i) => Some(&i.generics),
3581 ItemKind::Fn(i) => Some(&i.generics),
3582 ItemKind::TyAlias(i) => Some(&i.generics),
3583 ItemKind::TraitAlias(_, generics, _)
3584 | ItemKind::Enum(_, generics, _)
3585 | ItemKind::Struct(_, generics, _)
3586 | ItemKind::Union(_, generics, _) => Some(&generics),
3587 ItemKind::Trait(i) => Some(&i.generics),
3588 ItemKind::Impl(i) => Some(&i.generics),
3589 }
3590 }
3591}
3592
3593#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3595pub enum Extern {
3596 None,
3600 Implicit(Span),
3606 Explicit(StrLit, Span),
3610}
3611
3612impl Extern {
3613 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3614 match abi {
3615 Some(name) => Extern::Explicit(name, span),
3616 None => Extern::Implicit(span),
3617 }
3618 }
3619}
3620
3621#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3626pub struct FnHeader {
3627 pub safety: Safety,
3629 pub coroutine_kind: Option<CoroutineKind>,
3631 pub constness: Const,
3633 pub ext: Extern,
3635}
3636
3637impl FnHeader {
3638 pub fn has_qualifiers(&self) -> bool {
3640 let Self { safety, coroutine_kind, constness, ext } = self;
3641 matches!(safety, Safety::Unsafe(_))
3642 || coroutine_kind.is_some()
3643 || matches!(constness, Const::Yes(_))
3644 || !matches!(ext, Extern::None)
3645 }
3646
3647 pub fn span(&self) -> Option<Span> {
3649 fn append(a: &mut Option<Span>, b: Span) {
3650 *a = match a {
3651 None => Some(b),
3652 Some(x) => Some(x.to(b)),
3653 }
3654 }
3655
3656 let mut full_span = None;
3657
3658 match self.safety {
3659 Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3660 Safety::Default => {}
3661 };
3662
3663 if let Some(coroutine_kind) = self.coroutine_kind {
3664 append(&mut full_span, coroutine_kind.span());
3665 }
3666
3667 if let Const::Yes(span) = self.constness {
3668 append(&mut full_span, span);
3669 }
3670
3671 match self.ext {
3672 Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3673 Extern::None => {}
3674 }
3675
3676 full_span
3677 }
3678}
3679
3680impl Default for FnHeader {
3681 fn default() -> FnHeader {
3682 FnHeader {
3683 safety: Safety::Default,
3684 coroutine_kind: None,
3685 constness: Const::No,
3686 ext: Extern::None,
3687 }
3688 }
3689}
3690
3691#[derive(Clone, Encodable, Decodable, Debug)]
3692pub struct Trait {
3693 pub constness: Const,
3694 pub safety: Safety,
3695 pub is_auto: IsAuto,
3696 pub ident: Ident,
3697 pub generics: Generics,
3698 pub bounds: GenericBounds,
3699 pub items: ThinVec<P<AssocItem>>,
3700}
3701
3702#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3721pub struct TyAliasWhereClause {
3722 pub has_where_token: bool,
3723 pub span: Span,
3724}
3725
3726#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3728pub struct TyAliasWhereClauses {
3729 pub before: TyAliasWhereClause,
3731 pub after: TyAliasWhereClause,
3733 pub split: usize,
3737}
3738
3739#[derive(Clone, Encodable, Decodable, Debug)]
3740pub struct TyAlias {
3741 pub defaultness: Defaultness,
3742 pub ident: Ident,
3743 pub generics: Generics,
3744 pub where_clauses: TyAliasWhereClauses,
3745 pub bounds: GenericBounds,
3746 pub ty: Option<P<Ty>>,
3747}
3748
3749#[derive(Clone, Encodable, Decodable, Debug)]
3750pub struct Impl {
3751 pub defaultness: Defaultness,
3752 pub safety: Safety,
3753 pub generics: Generics,
3754 pub constness: Const,
3755 pub polarity: ImplPolarity,
3756 pub of_trait: Option<TraitRef>,
3758 pub self_ty: P<Ty>,
3759 pub items: ThinVec<P<AssocItem>>,
3760}
3761
3762#[derive(Clone, Encodable, Decodable, Debug, Default)]
3763pub struct FnContract {
3764 pub requires: Option<P<Expr>>,
3765 pub ensures: Option<P<Expr>>,
3766}
3767
3768#[derive(Clone, Encodable, Decodable, Debug)]
3769pub struct Fn {
3770 pub defaultness: Defaultness,
3771 pub ident: Ident,
3772 pub generics: Generics,
3773 pub sig: FnSig,
3774 pub contract: Option<P<FnContract>>,
3775 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3776 pub body: Option<P<Block>>,
3777}
3778
3779#[derive(Clone, Encodable, Decodable, Debug)]
3780pub struct Delegation {
3781 pub id: NodeId,
3783 pub qself: Option<P<QSelf>>,
3784 pub path: Path,
3785 pub ident: Ident,
3786 pub rename: Option<Ident>,
3787 pub body: Option<P<Block>>,
3788 pub from_glob: bool,
3790}
3791
3792#[derive(Clone, Encodable, Decodable, Debug)]
3793pub struct DelegationMac {
3794 pub qself: Option<P<QSelf>>,
3795 pub prefix: Path,
3796 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3798 pub body: Option<P<Block>>,
3799}
3800
3801#[derive(Clone, Encodable, Decodable, Debug)]
3802pub struct StaticItem {
3803 pub ident: Ident,
3804 pub ty: P<Ty>,
3805 pub safety: Safety,
3806 pub mutability: Mutability,
3807 pub expr: Option<P<Expr>>,
3808 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3809}
3810
3811#[derive(Clone, Encodable, Decodable, Debug)]
3812pub struct ConstItem {
3813 pub defaultness: Defaultness,
3814 pub ident: Ident,
3815 pub generics: Generics,
3816 pub ty: P<Ty>,
3817 pub expr: Option<P<Expr>>,
3818 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3819}
3820
3821#[derive(Clone, Encodable, Decodable, Debug)]
3823pub enum ItemKind {
3824 ExternCrate(Option<Symbol>, Ident),
3828 Use(UseTree),
3832 Static(Box<StaticItem>),
3836 Const(Box<ConstItem>),
3840 Fn(Box<Fn>),
3844 Mod(Safety, Ident, ModKind),
3850 ForeignMod(ForeignMod),
3854 GlobalAsm(Box<InlineAsm>),
3856 TyAlias(Box<TyAlias>),
3860 Enum(Ident, Generics, EnumDef),
3864 Struct(Ident, Generics, VariantData),
3868 Union(Ident, Generics, VariantData),
3872 Trait(Box<Trait>),
3876 TraitAlias(Ident, Generics, GenericBounds),
3880 Impl(Box<Impl>),
3884 MacCall(P<MacCall>),
3888 MacroDef(Ident, MacroDef),
3890 Delegation(Box<Delegation>),
3894 DelegationMac(Box<DelegationMac>),
3897}
3898
3899impl ItemKind {
3900 pub fn ident(&self) -> Option<Ident> {
3901 match *self {
3902 ItemKind::ExternCrate(_, ident)
3903 | ItemKind::Static(box StaticItem { ident, .. })
3904 | ItemKind::Const(box ConstItem { ident, .. })
3905 | ItemKind::Fn(box Fn { ident, .. })
3906 | ItemKind::Mod(_, ident, _)
3907 | ItemKind::TyAlias(box TyAlias { ident, .. })
3908 | ItemKind::Enum(ident, ..)
3909 | ItemKind::Struct(ident, ..)
3910 | ItemKind::Union(ident, ..)
3911 | ItemKind::Trait(box Trait { ident, .. })
3912 | ItemKind::TraitAlias(ident, ..)
3913 | ItemKind::MacroDef(ident, _)
3914 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3915
3916 ItemKind::Use(_)
3917 | ItemKind::ForeignMod(_)
3918 | ItemKind::GlobalAsm(_)
3919 | ItemKind::Impl(_)
3920 | ItemKind::MacCall(_)
3921 | ItemKind::DelegationMac(_) => None,
3922 }
3923 }
3924
3925 pub fn article(&self) -> &'static str {
3927 use ItemKind::*;
3928 match self {
3929 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3930 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3931 | Delegation(..) | DelegationMac(..) => "a",
3932 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3933 }
3934 }
3935
3936 pub fn descr(&self) -> &'static str {
3937 match self {
3938 ItemKind::ExternCrate(..) => "extern crate",
3939 ItemKind::Use(..) => "`use` import",
3940 ItemKind::Static(..) => "static item",
3941 ItemKind::Const(..) => "constant item",
3942 ItemKind::Fn(..) => "function",
3943 ItemKind::Mod(..) => "module",
3944 ItemKind::ForeignMod(..) => "extern block",
3945 ItemKind::GlobalAsm(..) => "global asm item",
3946 ItemKind::TyAlias(..) => "type alias",
3947 ItemKind::Enum(..) => "enum",
3948 ItemKind::Struct(..) => "struct",
3949 ItemKind::Union(..) => "union",
3950 ItemKind::Trait(..) => "trait",
3951 ItemKind::TraitAlias(..) => "trait alias",
3952 ItemKind::MacCall(..) => "item macro invocation",
3953 ItemKind::MacroDef(..) => "macro definition",
3954 ItemKind::Impl { .. } => "implementation",
3955 ItemKind::Delegation(..) => "delegated function",
3956 ItemKind::DelegationMac(..) => "delegation",
3957 }
3958 }
3959
3960 pub fn generics(&self) -> Option<&Generics> {
3961 match self {
3962 Self::Fn(box Fn { generics, .. })
3963 | Self::TyAlias(box TyAlias { generics, .. })
3964 | Self::Const(box ConstItem { generics, .. })
3965 | Self::Enum(_, generics, _)
3966 | Self::Struct(_, generics, _)
3967 | Self::Union(_, generics, _)
3968 | Self::Trait(box Trait { generics, .. })
3969 | Self::TraitAlias(_, generics, _)
3970 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3971 _ => None,
3972 }
3973 }
3974}
3975
3976pub type AssocItem = Item<AssocItemKind>;
3979
3980#[derive(Clone, Encodable, Decodable, Debug)]
3988pub enum AssocItemKind {
3989 Const(Box<ConstItem>),
3992 Fn(Box<Fn>),
3994 Type(Box<TyAlias>),
3996 MacCall(P<MacCall>),
3998 Delegation(Box<Delegation>),
4000 DelegationMac(Box<DelegationMac>),
4002}
4003
4004impl AssocItemKind {
4005 pub fn ident(&self) -> Option<Ident> {
4006 match *self {
4007 AssocItemKind::Const(box ConstItem { ident, .. })
4008 | AssocItemKind::Fn(box Fn { ident, .. })
4009 | AssocItemKind::Type(box TyAlias { ident, .. })
4010 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
4011
4012 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4013 }
4014 }
4015
4016 pub fn defaultness(&self) -> Defaultness {
4017 match *self {
4018 Self::Const(box ConstItem { defaultness, .. })
4019 | Self::Fn(box Fn { defaultness, .. })
4020 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4021 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
4022 Defaultness::Final
4023 }
4024 }
4025 }
4026}
4027
4028impl From<AssocItemKind> for ItemKind {
4029 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4030 match assoc_item_kind {
4031 AssocItemKind::Const(item) => ItemKind::Const(item),
4032 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4033 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4034 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4035 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4036 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4037 }
4038 }
4039}
4040
4041impl TryFrom<ItemKind> for AssocItemKind {
4042 type Error = ItemKind;
4043
4044 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4045 Ok(match item_kind {
4046 ItemKind::Const(item) => AssocItemKind::Const(item),
4047 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4048 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4049 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4050 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4051 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4052 _ => return Err(item_kind),
4053 })
4054 }
4055}
4056
4057#[derive(Clone, Encodable, Decodable, Debug)]
4059pub enum ForeignItemKind {
4060 Static(Box<StaticItem>),
4062 Fn(Box<Fn>),
4064 TyAlias(Box<TyAlias>),
4066 MacCall(P<MacCall>),
4068}
4069
4070impl ForeignItemKind {
4071 pub fn ident(&self) -> Option<Ident> {
4072 match *self {
4073 ForeignItemKind::Static(box StaticItem { ident, .. })
4074 | ForeignItemKind::Fn(box Fn { ident, .. })
4075 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4076
4077 ForeignItemKind::MacCall(_) => None,
4078 }
4079 }
4080}
4081
4082impl From<ForeignItemKind> for ItemKind {
4083 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4084 match foreign_item_kind {
4085 ForeignItemKind::Static(box static_foreign_item) => {
4086 ItemKind::Static(Box::new(static_foreign_item))
4087 }
4088 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4089 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4090 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4091 }
4092 }
4093}
4094
4095impl TryFrom<ItemKind> for ForeignItemKind {
4096 type Error = ItemKind;
4097
4098 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4099 Ok(match item_kind {
4100 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4101 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4102 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4103 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4104 _ => return Err(item_kind),
4105 })
4106 }
4107}
4108
4109pub type ForeignItem = Item<ForeignItemKind>;
4110
4111#[cfg(target_pointer_width = "64")]
4113mod size_asserts {
4114 use rustc_data_structures::static_assert_size;
4115
4116 use super::*;
4117 static_assert_size!(AssocItem, 80);
4119 static_assert_size!(AssocItemKind, 16);
4120 static_assert_size!(Attribute, 32);
4121 static_assert_size!(Block, 32);
4122 static_assert_size!(Expr, 72);
4123 static_assert_size!(ExprKind, 40);
4124 static_assert_size!(Fn, 184);
4125 static_assert_size!(ForeignItem, 80);
4126 static_assert_size!(ForeignItemKind, 16);
4127 static_assert_size!(GenericArg, 24);
4128 static_assert_size!(GenericBound, 88);
4129 static_assert_size!(Generics, 40);
4130 static_assert_size!(Impl, 136);
4131 static_assert_size!(Item, 144);
4132 static_assert_size!(ItemKind, 80);
4133 static_assert_size!(LitKind, 24);
4134 static_assert_size!(Local, 96);
4135 static_assert_size!(MetaItemLit, 40);
4136 static_assert_size!(Param, 40);
4137 static_assert_size!(Pat, 72);
4138 static_assert_size!(PatKind, 48);
4139 static_assert_size!(Path, 24);
4140 static_assert_size!(PathSegment, 24);
4141 static_assert_size!(Stmt, 32);
4142 static_assert_size!(StmtKind, 16);
4143 static_assert_size!(Ty, 64);
4144 static_assert_size!(TyKind, 40);
4145 }