1use std::borrow::{Borrow, Cow};
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
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, Walkable};
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::token::{self, CommentKind, Delimiter};
39use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
40use crate::util::parser::{ExprPrecedence, Fixity};
41use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
42
43#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
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, Walkable)]
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, Walkable)]
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, Walkable)]
215pub struct PathSegment {
216 pub ident: Ident,
218
219 pub id: NodeId,
220
221 pub args: Option<Box<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, Walkable)]
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, Walkable)]
284pub enum GenericArg {
285 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
287 Type(Box<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, Walkable)]
305pub struct AngleBracketedArgs {
306 pub span: Span,
308 pub args: ThinVec<AngleBracketedArg>,
310}
311
312#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
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 Box<GenericArgs> {
331 fn from(val: AngleBracketedArgs) -> Self {
332 Box::new(GenericArgs::AngleBracketed(val))
333 }
334}
335
336impl From<ParenthesizedArgs> for Box<GenericArgs> {
337 fn from(val: ParenthesizedArgs) -> Self {
338 Box::new(GenericArgs::Parenthesized(val))
339 }
340}
341
342#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
344pub struct ParenthesizedArgs {
345 pub span: Span,
350
351 pub inputs: ThinVec<Box<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, Walkable)]
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, Walkable)]
395pub enum GenericBound {
396 Trait(PolyTraitRef),
397 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] 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, Walkable)]
433pub enum GenericParamKind {
434 Lifetime,
436 Type {
437 default: Option<Box<Ty>>,
438 },
439 Const {
440 ty: Box<Ty>,
441 span: Span,
443 default: Option<AnonConst>,
445 },
446}
447
448#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
449pub struct GenericParam {
450 pub id: NodeId,
451 pub ident: Ident,
452 pub attrs: AttrVec,
453 #[visitable(extra = BoundKind::Bound)]
454 pub bounds: GenericBounds,
455 pub is_placeholder: bool,
456 pub kind: GenericParamKind,
457 pub colon_span: Option<Span>,
458}
459
460impl GenericParam {
461 pub fn span(&self) -> Span {
462 match &self.kind {
463 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
464 self.ident.span
465 }
466 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
467 GenericParamKind::Const { span, .. } => *span,
468 }
469 }
470}
471
472#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
475pub struct Generics {
476 pub params: ThinVec<GenericParam>,
477 pub where_clause: WhereClause,
478 pub span: Span,
479}
480
481#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
483pub struct WhereClause {
484 pub has_where_token: bool,
489 pub predicates: ThinVec<WherePredicate>,
490 pub span: Span,
491}
492
493impl WhereClause {
494 pub fn is_empty(&self) -> bool {
495 !self.has_where_token && self.predicates.is_empty()
496 }
497}
498
499#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
501pub struct WherePredicate {
502 pub attrs: AttrVec,
503 pub kind: WherePredicateKind,
504 pub id: NodeId,
505 pub span: Span,
506 pub is_placeholder: bool,
507}
508
509#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
511pub enum WherePredicateKind {
512 BoundPredicate(WhereBoundPredicate),
514 RegionPredicate(WhereRegionPredicate),
516 EqPredicate(WhereEqPredicate),
518}
519
520#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
524pub struct WhereBoundPredicate {
525 pub bound_generic_params: ThinVec<GenericParam>,
527 pub bounded_ty: Box<Ty>,
529 #[visitable(extra = BoundKind::Bound)]
531 pub bounds: GenericBounds,
532}
533
534#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
538pub struct WhereRegionPredicate {
539 #[visitable(extra = LifetimeCtxt::Bound)]
540 pub lifetime: Lifetime,
541 #[visitable(extra = BoundKind::Bound)]
542 pub bounds: GenericBounds,
543}
544
545#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
549pub struct WhereEqPredicate {
550 pub lhs_ty: Box<Ty>,
551 pub rhs_ty: Box<Ty>,
552}
553
554#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
555pub struct Crate {
556 pub id: NodeId,
559 pub attrs: AttrVec,
560 pub items: ThinVec<Box<Item>>,
561 pub spans: ModSpans,
562 pub is_placeholder: bool,
563}
564
565#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
572pub struct MetaItem {
573 pub unsafety: Safety,
574 pub path: Path,
575 pub kind: MetaItemKind,
576 pub span: Span,
577}
578
579#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
581pub enum MetaItemKind {
582 Word,
586
587 List(ThinVec<MetaItemInner>),
591
592 NameValue(MetaItemLit),
596}
597
598#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
602pub enum MetaItemInner {
603 MetaItem(MetaItem),
605
606 Lit(MetaItemLit),
610}
611
612#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
616pub struct Block {
617 pub stmts: ThinVec<Stmt>,
619 pub id: NodeId,
620 pub rules: BlockCheckMode,
622 pub span: Span,
623 pub tokens: Option<LazyAttrTokenStream>,
624}
625
626#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
630pub struct Pat {
631 pub id: NodeId,
632 pub kind: PatKind,
633 pub span: Span,
634 pub tokens: Option<LazyAttrTokenStream>,
635}
636
637impl Pat {
638 pub fn to_ty(&self) -> Option<Box<Ty>> {
641 let kind = match &self.kind {
642 PatKind::Missing => unreachable!(),
643 PatKind::Wild => TyKind::Infer,
645 PatKind::Ident(BindingMode::NONE, ident, None) => {
647 TyKind::Path(None, Path::from_ident(*ident))
648 }
649 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
650 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
651 PatKind::Ref(pat, mutbl) => {
653 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
654 }
655 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
658 pat.to_ty().map(TyKind::Slice)?
659 }
660 PatKind::Tuple(pats) => {
663 let mut tys = ThinVec::with_capacity(pats.len());
664 for pat in pats {
666 tys.push(pat.to_ty()?);
667 }
668 TyKind::Tup(tys)
669 }
670 _ => return None,
671 };
672
673 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
674 }
675
676 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
680 if !it(self) {
681 return;
682 }
683
684 match &self.kind {
685 PatKind::Ident(_, _, Some(p)) => p.walk(it),
687
688 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
690
691 PatKind::TupleStruct(_, _, s)
693 | PatKind::Tuple(s)
694 | PatKind::Slice(s)
695 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
696
697 PatKind::Box(s)
699 | PatKind::Deref(s)
700 | PatKind::Ref(s, _)
701 | PatKind::Paren(s)
702 | PatKind::Guard(s, _) => s.walk(it),
703
704 PatKind::Missing
706 | PatKind::Wild
707 | PatKind::Rest
708 | PatKind::Never
709 | PatKind::Expr(_)
710 | PatKind::Range(..)
711 | PatKind::Ident(..)
712 | PatKind::Path(..)
713 | PatKind::MacCall(_)
714 | PatKind::Err(_) => {}
715 }
716 }
717
718 pub fn is_rest(&self) -> bool {
720 matches!(self.kind, PatKind::Rest)
721 }
722
723 pub fn could_be_never_pattern(&self) -> bool {
726 let mut could_be_never_pattern = false;
727 self.walk(&mut |pat| match &pat.kind {
728 PatKind::Never | PatKind::MacCall(_) => {
729 could_be_never_pattern = true;
730 false
731 }
732 PatKind::Or(s) => {
733 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
734 false
735 }
736 _ => true,
737 });
738 could_be_never_pattern
739 }
740
741 pub fn contains_never_pattern(&self) -> bool {
744 let mut contains_never_pattern = false;
745 self.walk(&mut |pat| {
746 if matches!(pat.kind, PatKind::Never) {
747 contains_never_pattern = true;
748 }
749 true
750 });
751 contains_never_pattern
752 }
753
754 pub fn descr(&self) -> Option<String> {
756 match &self.kind {
757 PatKind::Missing => unreachable!(),
758 PatKind::Wild => Some("_".to_string()),
759 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
760 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
761 _ => None,
762 }
763 }
764}
765
766impl From<Box<Pat>> for Pat {
767 fn from(value: Box<Pat>) -> Self {
768 *value
769 }
770}
771
772#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
778pub struct PatField {
779 pub ident: Ident,
781 pub pat: Box<Pat>,
783 pub is_shorthand: bool,
784 pub attrs: AttrVec,
785 pub id: NodeId,
786 pub span: Span,
787 pub is_placeholder: bool,
788}
789
790#[derive(Clone, Copy, Debug, Eq, PartialEq)]
791#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
792pub enum ByRef {
793 Yes(Mutability),
794 No,
795}
796
797impl ByRef {
798 #[must_use]
799 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
800 if let ByRef::Yes(old_mutbl) = &mut self {
801 *old_mutbl = cmp::min(*old_mutbl, mutbl);
802 }
803 self
804 }
805}
806
807#[derive(Clone, Copy, Debug, Eq, PartialEq)]
813#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
814pub struct BindingMode(pub ByRef, pub Mutability);
815
816impl BindingMode {
817 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
818 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
819 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
820 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
821 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
822 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
823
824 pub fn prefix_str(self) -> &'static str {
825 match self {
826 Self::NONE => "",
827 Self::REF => "ref ",
828 Self::MUT => "mut ",
829 Self::REF_MUT => "ref mut ",
830 Self::MUT_REF => "mut ref ",
831 Self::MUT_REF_MUT => "mut ref mut ",
832 }
833 }
834}
835
836#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
837pub enum RangeEnd {
838 Included(RangeSyntax),
840 Excluded,
842}
843
844#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
845pub enum RangeSyntax {
846 DotDotDot,
848 DotDotEq,
850}
851
852#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
856pub enum PatKind {
857 Missing,
859
860 Wild,
862
863 Ident(BindingMode, Ident, Option<Box<Pat>>),
868
869 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
871
872 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Box<Pat>>),
874
875 Or(ThinVec<Box<Pat>>),
878
879 Path(Option<Box<QSelf>>, Path),
884
885 Tuple(ThinVec<Box<Pat>>),
887
888 Box(Box<Pat>),
890
891 Deref(Box<Pat>),
893
894 Ref(Box<Pat>, Mutability),
896
897 Expr(Box<Expr>),
899
900 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
902
903 Slice(ThinVec<Box<Pat>>),
905
906 Rest,
919
920 Never,
922
923 Guard(Box<Pat>, Box<Expr>),
925
926 Paren(Box<Pat>),
928
929 MacCall(Box<MacCall>),
931
932 Err(ErrorGuaranteed),
934}
935
936#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
938pub enum PatFieldsRest {
939 Rest,
941 Recovered(ErrorGuaranteed),
943 None,
945}
946
947#[derive(Clone, Copy, PartialEq, Eq, Debug)]
950#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
951pub enum BorrowKind {
952 Ref,
956 Raw,
960 Pin,
964}
965
966#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
967pub enum BinOpKind {
968 Add,
970 Sub,
972 Mul,
974 Div,
976 Rem,
978 And,
980 Or,
982 BitXor,
984 BitAnd,
986 BitOr,
988 Shl,
990 Shr,
992 Eq,
994 Lt,
996 Le,
998 Ne,
1000 Ge,
1002 Gt,
1004}
1005
1006impl BinOpKind {
1007 pub fn as_str(&self) -> &'static str {
1008 use BinOpKind::*;
1009 match self {
1010 Add => "+",
1011 Sub => "-",
1012 Mul => "*",
1013 Div => "/",
1014 Rem => "%",
1015 And => "&&",
1016 Or => "||",
1017 BitXor => "^",
1018 BitAnd => "&",
1019 BitOr => "|",
1020 Shl => "<<",
1021 Shr => ">>",
1022 Eq => "==",
1023 Lt => "<",
1024 Le => "<=",
1025 Ne => "!=",
1026 Ge => ">=",
1027 Gt => ">",
1028 }
1029 }
1030
1031 pub fn is_lazy(&self) -> bool {
1032 matches!(self, BinOpKind::And | BinOpKind::Or)
1033 }
1034
1035 pub fn precedence(&self) -> ExprPrecedence {
1036 use BinOpKind::*;
1037 match *self {
1038 Mul | Div | Rem => ExprPrecedence::Product,
1039 Add | Sub => ExprPrecedence::Sum,
1040 Shl | Shr => ExprPrecedence::Shift,
1041 BitAnd => ExprPrecedence::BitAnd,
1042 BitXor => ExprPrecedence::BitXor,
1043 BitOr => ExprPrecedence::BitOr,
1044 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1045 And => ExprPrecedence::LAnd,
1046 Or => ExprPrecedence::LOr,
1047 }
1048 }
1049
1050 pub fn fixity(&self) -> Fixity {
1051 use BinOpKind::*;
1052 match self {
1053 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1054 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1055 Fixity::Left
1056 }
1057 }
1058 }
1059
1060 pub fn is_comparison(self) -> bool {
1061 use BinOpKind::*;
1062 match self {
1063 Eq | Ne | Lt | Le | Gt | Ge => true,
1064 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1065 }
1066 }
1067
1068 pub fn is_by_value(self) -> bool {
1070 !self.is_comparison()
1071 }
1072}
1073
1074pub type BinOp = Spanned<BinOpKind>;
1075
1076impl From<AssignOpKind> for BinOpKind {
1080 fn from(op: AssignOpKind) -> BinOpKind {
1081 match op {
1082 AssignOpKind::AddAssign => BinOpKind::Add,
1083 AssignOpKind::SubAssign => BinOpKind::Sub,
1084 AssignOpKind::MulAssign => BinOpKind::Mul,
1085 AssignOpKind::DivAssign => BinOpKind::Div,
1086 AssignOpKind::RemAssign => BinOpKind::Rem,
1087 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1088 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1089 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1090 AssignOpKind::ShlAssign => BinOpKind::Shl,
1091 AssignOpKind::ShrAssign => BinOpKind::Shr,
1092 }
1093 }
1094}
1095
1096#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1097pub enum AssignOpKind {
1098 AddAssign,
1100 SubAssign,
1102 MulAssign,
1104 DivAssign,
1106 RemAssign,
1108 BitXorAssign,
1110 BitAndAssign,
1112 BitOrAssign,
1114 ShlAssign,
1116 ShrAssign,
1118}
1119
1120impl AssignOpKind {
1121 pub fn as_str(&self) -> &'static str {
1122 use AssignOpKind::*;
1123 match self {
1124 AddAssign => "+=",
1125 SubAssign => "-=",
1126 MulAssign => "*=",
1127 DivAssign => "/=",
1128 RemAssign => "%=",
1129 BitXorAssign => "^=",
1130 BitAndAssign => "&=",
1131 BitOrAssign => "|=",
1132 ShlAssign => "<<=",
1133 ShrAssign => ">>=",
1134 }
1135 }
1136
1137 pub fn is_by_value(self) -> bool {
1139 true
1140 }
1141}
1142
1143pub type AssignOp = Spanned<AssignOpKind>;
1144
1145#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1149pub enum UnOp {
1150 Deref,
1152 Not,
1154 Neg,
1156}
1157
1158impl UnOp {
1159 pub fn as_str(&self) -> &'static str {
1160 match self {
1161 UnOp::Deref => "*",
1162 UnOp::Not => "!",
1163 UnOp::Neg => "-",
1164 }
1165 }
1166
1167 pub fn is_by_value(self) -> bool {
1169 matches!(self, Self::Neg | Self::Not)
1170 }
1171}
1172
1173#[derive(Clone, Encodable, Decodable, Debug)]
1177pub struct Stmt {
1178 pub id: NodeId,
1179 pub kind: StmtKind,
1180 pub span: Span,
1181}
1182
1183impl Stmt {
1184 pub fn has_trailing_semicolon(&self) -> bool {
1185 match &self.kind {
1186 StmtKind::Semi(_) => true,
1187 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1188 _ => false,
1189 }
1190 }
1191
1192 pub fn add_trailing_semicolon(mut self) -> Self {
1200 self.kind = match self.kind {
1201 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1202 StmtKind::MacCall(mut mac) => {
1203 mac.style = MacStmtStyle::Semicolon;
1204 StmtKind::MacCall(mac)
1205 }
1206 kind => kind,
1207 };
1208
1209 self
1210 }
1211
1212 pub fn is_item(&self) -> bool {
1213 matches!(self.kind, StmtKind::Item(_))
1214 }
1215
1216 pub fn is_expr(&self) -> bool {
1217 matches!(self.kind, StmtKind::Expr(_))
1218 }
1219}
1220
1221#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1223pub enum StmtKind {
1224 Let(Box<Local>),
1226 Item(Box<Item>),
1228 Expr(Box<Expr>),
1230 Semi(Box<Expr>),
1232 Empty,
1234 MacCall(Box<MacCallStmt>),
1236}
1237
1238#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1239pub struct MacCallStmt {
1240 pub mac: Box<MacCall>,
1241 pub style: MacStmtStyle,
1242 pub attrs: AttrVec,
1243 pub tokens: Option<LazyAttrTokenStream>,
1244}
1245
1246#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1247pub enum MacStmtStyle {
1248 Semicolon,
1251 Braces,
1253 NoBraces,
1257}
1258
1259#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1261pub struct Local {
1262 pub id: NodeId,
1263 pub super_: Option<Span>,
1264 pub pat: Box<Pat>,
1265 pub ty: Option<Box<Ty>>,
1266 pub kind: LocalKind,
1267 pub span: Span,
1268 pub colon_sp: Option<Span>,
1269 pub attrs: AttrVec,
1270 pub tokens: Option<LazyAttrTokenStream>,
1271}
1272
1273#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1274pub enum LocalKind {
1275 Decl,
1278 Init(Box<Expr>),
1281 InitElse(Box<Expr>, Box<Block>),
1284}
1285
1286impl LocalKind {
1287 pub fn init(&self) -> Option<&Expr> {
1288 match self {
1289 Self::Decl => None,
1290 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1291 }
1292 }
1293
1294 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1295 match self {
1296 Self::Decl => None,
1297 Self::Init(init) => Some((init, None)),
1298 Self::InitElse(init, els) => Some((init, Some(els))),
1299 }
1300 }
1301}
1302
1303#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1314pub struct Arm {
1315 pub attrs: AttrVec,
1316 pub pat: Box<Pat>,
1318 pub guard: Option<Box<Expr>>,
1320 pub body: Option<Box<Expr>>,
1322 pub span: Span,
1323 pub id: NodeId,
1324 pub is_placeholder: bool,
1325}
1326
1327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1329pub struct ExprField {
1330 pub attrs: AttrVec,
1331 pub id: NodeId,
1332 pub span: Span,
1333 pub ident: Ident,
1334 pub expr: Box<Expr>,
1335 pub is_shorthand: bool,
1336 pub is_placeholder: bool,
1337}
1338
1339#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1340pub enum BlockCheckMode {
1341 Default,
1342 Unsafe(UnsafeSource),
1343}
1344
1345#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1346pub enum UnsafeSource {
1347 CompilerGenerated,
1348 UserProvided,
1349}
1350
1351#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1357pub struct AnonConst {
1358 pub id: NodeId,
1359 pub value: Box<Expr>,
1360}
1361
1362#[derive(Clone, Encodable, Decodable, Debug)]
1364pub struct Expr {
1365 pub id: NodeId,
1366 pub kind: ExprKind,
1367 pub span: Span,
1368 pub attrs: AttrVec,
1369 pub tokens: Option<LazyAttrTokenStream>,
1370}
1371
1372impl Expr {
1373 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1387 let this = self.maybe_unwrap_block();
1388 if allow_mgca_arg {
1389 matches!(this.kind, ExprKind::Path(..))
1390 } else {
1391 if let ExprKind::Path(None, path) = &this.kind
1392 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1393 {
1394 true
1395 } else {
1396 false
1397 }
1398 }
1399 }
1400
1401 pub fn maybe_unwrap_block(&self) -> &Expr {
1403 if let ExprKind::Block(block, None) = &self.kind
1404 && let [stmt] = block.stmts.as_slice()
1405 && let StmtKind::Expr(expr) = &stmt.kind
1406 {
1407 expr
1408 } else {
1409 self
1410 }
1411 }
1412
1413 pub fn optionally_braced_mac_call(
1419 &self,
1420 already_stripped_block: bool,
1421 ) -> Option<(bool, NodeId)> {
1422 match &self.kind {
1423 ExprKind::Block(block, None)
1424 if let [stmt] = &*block.stmts
1425 && !already_stripped_block =>
1426 {
1427 match &stmt.kind {
1428 StmtKind::MacCall(_) => Some((true, stmt.id)),
1429 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1430 Some((true, expr.id))
1431 }
1432 _ => None,
1433 }
1434 }
1435 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1436 _ => None,
1437 }
1438 }
1439
1440 pub fn to_bound(&self) -> Option<GenericBound> {
1441 match &self.kind {
1442 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1443 ThinVec::new(),
1444 path.clone(),
1445 TraitBoundModifiers::NONE,
1446 self.span,
1447 Parens::No,
1448 ))),
1449 _ => None,
1450 }
1451 }
1452
1453 pub fn peel_parens(&self) -> &Expr {
1454 let mut expr = self;
1455 while let ExprKind::Paren(inner) = &expr.kind {
1456 expr = inner;
1457 }
1458 expr
1459 }
1460
1461 pub fn peel_parens_and_refs(&self) -> &Expr {
1462 let mut expr = self;
1463 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1464 {
1465 expr = inner;
1466 }
1467 expr
1468 }
1469
1470 pub fn to_ty(&self) -> Option<Box<Ty>> {
1472 let kind = match &self.kind {
1473 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1475 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1476
1477 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1478
1479 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1480 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1481 }
1482
1483 ExprKind::Repeat(expr, expr_len) => {
1484 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1485 }
1486
1487 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1488 expr.to_ty().map(TyKind::Slice)?
1489 }
1490
1491 ExprKind::Tup(exprs) => {
1492 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1493 TyKind::Tup(tys)
1494 }
1495
1496 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1500 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1501 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1502 } else {
1503 return None;
1504 }
1505 }
1506
1507 ExprKind::Underscore => TyKind::Infer,
1508
1509 _ => return None,
1511 };
1512
1513 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1514 }
1515
1516 pub fn precedence(&self) -> ExprPrecedence {
1517 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1518 for attr in attrs {
1519 if let AttrStyle::Outer = attr.style {
1520 return ExprPrecedence::Prefix;
1521 }
1522 }
1523 ExprPrecedence::Unambiguous
1524 }
1525
1526 match &self.kind {
1527 ExprKind::Closure(closure) => {
1528 match closure.fn_decl.output {
1529 FnRetTy::Default(_) => ExprPrecedence::Jump,
1530 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1531 }
1532 }
1533
1534 ExprKind::Break(_ , value)
1535 | ExprKind::Ret(value)
1536 | ExprKind::Yield(YieldKind::Prefix(value))
1537 | ExprKind::Yeet(value) => match value {
1538 Some(_) => ExprPrecedence::Jump,
1539 None => prefix_attrs_precedence(&self.attrs),
1540 },
1541
1542 ExprKind::Become(_) => ExprPrecedence::Jump,
1543
1544 ExprKind::Range(..) => ExprPrecedence::Range,
1549
1550 ExprKind::Binary(op, ..) => op.node.precedence(),
1552 ExprKind::Cast(..) => ExprPrecedence::Cast,
1553
1554 ExprKind::Assign(..) |
1555 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1556
1557 ExprKind::AddrOf(..)
1559 | ExprKind::Let(..)
1564 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1565
1566 ExprKind::Array(_)
1568 | ExprKind::Await(..)
1569 | ExprKind::Use(..)
1570 | ExprKind::Block(..)
1571 | ExprKind::Call(..)
1572 | ExprKind::ConstBlock(_)
1573 | ExprKind::Continue(..)
1574 | ExprKind::Field(..)
1575 | ExprKind::ForLoop { .. }
1576 | ExprKind::FormatArgs(..)
1577 | ExprKind::Gen(..)
1578 | ExprKind::If(..)
1579 | ExprKind::IncludedBytes(..)
1580 | ExprKind::Index(..)
1581 | ExprKind::InlineAsm(..)
1582 | ExprKind::Lit(_)
1583 | ExprKind::Loop(..)
1584 | ExprKind::MacCall(..)
1585 | ExprKind::Match(..)
1586 | ExprKind::MethodCall(..)
1587 | ExprKind::OffsetOf(..)
1588 | ExprKind::Paren(..)
1589 | ExprKind::Path(..)
1590 | ExprKind::Repeat(..)
1591 | ExprKind::Struct(..)
1592 | ExprKind::Try(..)
1593 | ExprKind::TryBlock(..)
1594 | ExprKind::Tup(_)
1595 | ExprKind::Type(..)
1596 | ExprKind::Underscore
1597 | ExprKind::UnsafeBinderCast(..)
1598 | ExprKind::While(..)
1599 | ExprKind::Yield(YieldKind::Postfix(..))
1600 | ExprKind::Err(_)
1601 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1602 }
1603 }
1604
1605 pub fn is_approximately_pattern(&self) -> bool {
1607 matches!(
1608 &self.peel_parens().kind,
1609 ExprKind::Array(_)
1610 | ExprKind::Call(_, _)
1611 | ExprKind::Tup(_)
1612 | ExprKind::Lit(_)
1613 | ExprKind::Range(_, _, _)
1614 | ExprKind::Underscore
1615 | ExprKind::Path(_, _)
1616 | ExprKind::Struct(_)
1617 )
1618 }
1619
1620 pub fn dummy() -> Expr {
1624 Expr {
1625 id: DUMMY_NODE_ID,
1626 kind: ExprKind::Dummy,
1627 span: DUMMY_SP,
1628 attrs: ThinVec::new(),
1629 tokens: None,
1630 }
1631 }
1632}
1633
1634impl From<Box<Expr>> for Expr {
1635 fn from(value: Box<Expr>) -> Self {
1636 *value
1637 }
1638}
1639
1640#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1641pub struct Closure {
1642 pub binder: ClosureBinder,
1643 pub capture_clause: CaptureBy,
1644 pub constness: Const,
1645 pub coroutine_kind: Option<CoroutineKind>,
1646 pub movability: Movability,
1647 pub fn_decl: Box<FnDecl>,
1648 pub body: Box<Expr>,
1649 pub fn_decl_span: Span,
1651 pub fn_arg_span: Span,
1653}
1654
1655#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1657pub enum RangeLimits {
1658 HalfOpen,
1660 Closed,
1662}
1663
1664impl RangeLimits {
1665 pub fn as_str(&self) -> &'static str {
1666 match self {
1667 RangeLimits::HalfOpen => "..",
1668 RangeLimits::Closed => "..=",
1669 }
1670 }
1671}
1672
1673#[derive(Clone, Encodable, Decodable, Debug)]
1675pub struct MethodCall {
1676 pub seg: PathSegment,
1678 pub receiver: Box<Expr>,
1680 pub args: ThinVec<Box<Expr>>,
1682 pub span: Span,
1685}
1686
1687#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1688pub enum StructRest {
1689 Base(Box<Expr>),
1691 Rest(Span),
1693 None,
1695}
1696
1697#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1698pub struct StructExpr {
1699 pub qself: Option<Box<QSelf>>,
1700 pub path: Path,
1701 pub fields: ThinVec<ExprField>,
1702 pub rest: StructRest,
1703}
1704
1705#[derive(Clone, Encodable, Decodable, Debug)]
1707pub enum ExprKind {
1708 Array(ThinVec<Box<Expr>>),
1710 ConstBlock(AnonConst),
1712 Call(Box<Expr>, ThinVec<Box<Expr>>),
1719 MethodCall(Box<MethodCall>),
1721 Tup(ThinVec<Box<Expr>>),
1723 Binary(BinOp, Box<Expr>, Box<Expr>),
1725 Unary(UnOp, Box<Expr>),
1727 Lit(token::Lit),
1729 Cast(Box<Expr>, Box<Ty>),
1731 Type(Box<Expr>, Box<Ty>),
1736 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1741 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1748 While(Box<Expr>, Box<Block>, Option<Label>),
1752 ForLoop {
1758 pat: Box<Pat>,
1759 iter: Box<Expr>,
1760 body: Box<Block>,
1761 label: Option<Label>,
1762 kind: ForLoopKind,
1763 },
1764 Loop(Box<Block>, Option<Label>, Span),
1768 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1770 Closure(Box<Closure>),
1772 Block(Box<Block>, Option<Label>),
1774 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1780 Await(Box<Expr>, Span),
1782 Use(Box<Expr>, Span),
1784
1785 TryBlock(Box<Block>),
1787
1788 Assign(Box<Expr>, Box<Expr>, Span),
1791 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1795 Field(Box<Expr>, Ident),
1797 Index(Box<Expr>, Box<Expr>, Span),
1800 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1802 Underscore,
1804
1805 Path(Option<Box<QSelf>>, Path),
1810
1811 AddrOf(BorrowKind, Mutability, Box<Expr>),
1813 Break(Option<Label>, Option<Box<Expr>>),
1815 Continue(Option<Label>),
1817 Ret(Option<Box<Expr>>),
1819
1820 InlineAsm(Box<InlineAsm>),
1822
1823 OffsetOf(Box<Ty>, Vec<Ident>),
1828
1829 MacCall(Box<MacCall>),
1831
1832 Struct(Box<StructExpr>),
1836
1837 Repeat(Box<Expr>, AnonConst),
1842
1843 Paren(Box<Expr>),
1845
1846 Try(Box<Expr>),
1848
1849 Yield(YieldKind),
1851
1852 Yeet(Option<Box<Expr>>),
1855
1856 Become(Box<Expr>),
1860
1861 IncludedBytes(ByteSymbol),
1873
1874 FormatArgs(Box<FormatArgs>),
1876
1877 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1878
1879 Err(ErrorGuaranteed),
1881
1882 Dummy,
1884}
1885
1886#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1888pub enum ForLoopKind {
1889 For,
1890 ForAwait,
1891}
1892
1893#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1895pub enum GenBlockKind {
1896 Async,
1897 Gen,
1898 AsyncGen,
1899}
1900
1901impl fmt::Display for GenBlockKind {
1902 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1903 self.modifier().fmt(f)
1904 }
1905}
1906
1907impl GenBlockKind {
1908 pub fn modifier(&self) -> &'static str {
1909 match self {
1910 GenBlockKind::Async => "async",
1911 GenBlockKind::Gen => "gen",
1912 GenBlockKind::AsyncGen => "async gen",
1913 }
1914 }
1915}
1916
1917#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1919#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1920pub enum UnsafeBinderCastKind {
1921 Wrap,
1923 Unwrap,
1925}
1926
1927#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1942pub struct QSelf {
1943 pub ty: Box<Ty>,
1944
1945 pub path_span: Span,
1949 pub position: usize,
1950}
1951
1952#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1954pub enum CaptureBy {
1955 Value {
1957 move_kw: Span,
1959 },
1960 Ref,
1962 Use {
1968 use_kw: Span,
1970 },
1971}
1972
1973#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1975pub enum ClosureBinder {
1976 NotPresent,
1978 For {
1980 span: Span,
1987
1988 generic_params: ThinVec<GenericParam>,
1995 },
1996}
1997
1998#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2001pub struct MacCall {
2002 pub path: Path,
2003 pub args: Box<DelimArgs>,
2004}
2005
2006impl MacCall {
2007 pub fn span(&self) -> Span {
2008 self.path.span.to(self.args.dspan.entire())
2009 }
2010}
2011
2012#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2014pub enum AttrArgs {
2015 Empty,
2017 Delimited(DelimArgs),
2019 Eq {
2021 eq_span: Span,
2023 expr: Box<Expr>,
2024 },
2025}
2026
2027impl AttrArgs {
2028 pub fn span(&self) -> Option<Span> {
2029 match self {
2030 AttrArgs::Empty => None,
2031 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2032 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2033 }
2034 }
2035
2036 pub fn inner_tokens(&self) -> TokenStream {
2039 match self {
2040 AttrArgs::Empty => TokenStream::default(),
2041 AttrArgs::Delimited(args) => args.tokens.clone(),
2042 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2043 }
2044 }
2045}
2046
2047#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2049pub struct DelimArgs {
2050 pub dspan: DelimSpan,
2051 pub delim: Delimiter, pub tokens: TokenStream,
2053}
2054
2055impl DelimArgs {
2056 pub fn need_semicolon(&self) -> bool {
2059 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2060 }
2061}
2062
2063#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2065pub struct MacroDef {
2066 pub body: Box<DelimArgs>,
2067 pub macro_rules: bool,
2069}
2070
2071#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2072#[derive(HashStable_Generic, Walkable)]
2073pub enum StrStyle {
2074 Cooked,
2076 Raw(u8),
2080}
2081
2082#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2084pub enum MatchKind {
2085 Prefix,
2087 Postfix,
2089}
2090
2091#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2093pub enum YieldKind {
2094 Prefix(Option<Box<Expr>>),
2096 Postfix(Box<Expr>),
2098}
2099
2100impl YieldKind {
2101 pub const fn expr(&self) -> Option<&Box<Expr>> {
2105 match self {
2106 YieldKind::Prefix(expr) => expr.as_ref(),
2107 YieldKind::Postfix(expr) => Some(expr),
2108 }
2109 }
2110
2111 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2113 match self {
2114 YieldKind::Prefix(expr) => expr.as_mut(),
2115 YieldKind::Postfix(expr) => Some(expr),
2116 }
2117 }
2118
2119 pub const fn same_kind(&self, other: &Self) -> bool {
2121 match (self, other) {
2122 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2123 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2124 _ => false,
2125 }
2126 }
2127}
2128
2129#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2131pub struct MetaItemLit {
2132 pub symbol: Symbol,
2134 pub suffix: Option<Symbol>,
2136 pub kind: LitKind,
2139 pub span: Span,
2140}
2141
2142#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2144pub struct StrLit {
2145 pub symbol: Symbol,
2147 pub suffix: Option<Symbol>,
2149 pub symbol_unescaped: Symbol,
2151 pub style: StrStyle,
2152 pub span: Span,
2153}
2154
2155impl StrLit {
2156 pub fn as_token_lit(&self) -> token::Lit {
2157 let token_kind = match self.style {
2158 StrStyle::Cooked => token::Str,
2159 StrStyle::Raw(n) => token::StrRaw(n),
2160 };
2161 token::Lit::new(token_kind, self.symbol, self.suffix)
2162 }
2163}
2164
2165#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2167#[derive(HashStable_Generic)]
2168pub enum LitIntType {
2169 Signed(IntTy),
2171 Unsigned(UintTy),
2173 Unsuffixed,
2175}
2176
2177#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2179#[derive(HashStable_Generic)]
2180pub enum LitFloatType {
2181 Suffixed(FloatTy),
2183 Unsuffixed,
2185}
2186
2187#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2194pub enum LitKind {
2195 Str(Symbol, StrStyle),
2198 ByteStr(ByteSymbol, StrStyle),
2201 CStr(ByteSymbol, StrStyle),
2205 Byte(u8),
2207 Char(char),
2209 Int(Pu128, LitIntType),
2211 Float(Symbol, LitFloatType),
2215 Bool(bool),
2217 Err(ErrorGuaranteed),
2219}
2220
2221impl LitKind {
2222 pub fn str(&self) -> Option<Symbol> {
2223 match *self {
2224 LitKind::Str(s, _) => Some(s),
2225 _ => None,
2226 }
2227 }
2228
2229 pub fn is_str(&self) -> bool {
2231 matches!(self, LitKind::Str(..))
2232 }
2233
2234 pub fn is_bytestr(&self) -> bool {
2236 matches!(self, LitKind::ByteStr(..))
2237 }
2238
2239 pub fn is_numeric(&self) -> bool {
2241 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2242 }
2243
2244 pub fn is_unsuffixed(&self) -> bool {
2247 !self.is_suffixed()
2248 }
2249
2250 pub fn is_suffixed(&self) -> bool {
2252 match *self {
2253 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2255 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2256 LitKind::Str(..)
2258 | LitKind::ByteStr(..)
2259 | LitKind::CStr(..)
2260 | LitKind::Byte(..)
2261 | LitKind::Char(..)
2262 | LitKind::Int(_, LitIntType::Unsuffixed)
2263 | LitKind::Float(_, LitFloatType::Unsuffixed)
2264 | LitKind::Bool(..)
2265 | LitKind::Err(_) => false,
2266 }
2267 }
2268}
2269
2270#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2273pub struct MutTy {
2274 pub ty: Box<Ty>,
2275 pub mutbl: Mutability,
2276}
2277
2278#[derive(Clone, Encodable, Decodable, Debug)]
2281pub struct FnSig {
2282 pub header: FnHeader,
2283 pub decl: Box<FnDecl>,
2284 pub span: Span,
2285}
2286
2287#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2298pub struct AssocItemConstraint {
2299 pub id: NodeId,
2300 pub ident: Ident,
2301 pub gen_args: Option<GenericArgs>,
2302 pub kind: AssocItemConstraintKind,
2303 pub span: Span,
2304}
2305
2306#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2307pub enum Term {
2308 Ty(Box<Ty>),
2309 Const(AnonConst),
2310}
2311
2312impl From<Box<Ty>> for Term {
2313 fn from(v: Box<Ty>) -> Self {
2314 Term::Ty(v)
2315 }
2316}
2317
2318impl From<AnonConst> for Term {
2319 fn from(v: AnonConst) -> Self {
2320 Term::Const(v)
2321 }
2322}
2323
2324#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2326pub enum AssocItemConstraintKind {
2327 Equality { term: Term },
2334 Bound {
2336 #[visitable(extra = BoundKind::Bound)]
2337 bounds: GenericBounds,
2338 },
2339}
2340
2341#[derive(Encodable, Decodable, Debug, Walkable)]
2342pub struct Ty {
2343 pub id: NodeId,
2344 pub kind: TyKind,
2345 pub span: Span,
2346 pub tokens: Option<LazyAttrTokenStream>,
2347}
2348
2349impl Clone for Ty {
2350 fn clone(&self) -> Self {
2351 ensure_sufficient_stack(|| Self {
2352 id: self.id,
2353 kind: self.kind.clone(),
2354 span: self.span,
2355 tokens: self.tokens.clone(),
2356 })
2357 }
2358}
2359
2360impl From<Box<Ty>> for Ty {
2361 fn from(value: Box<Ty>) -> Self {
2362 *value
2363 }
2364}
2365
2366impl Ty {
2367 pub fn peel_refs(&self) -> &Self {
2368 let mut final_ty = self;
2369 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2370 {
2371 final_ty = ty;
2372 }
2373 final_ty
2374 }
2375
2376 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2377 match &self.kind {
2378 TyKind::Infer => true,
2379 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2380 _ => false,
2381 }
2382 }
2383}
2384
2385#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2386pub struct FnPtrTy {
2387 pub safety: Safety,
2388 pub ext: Extern,
2389 pub generic_params: ThinVec<GenericParam>,
2390 pub decl: Box<FnDecl>,
2391 pub decl_span: Span,
2394}
2395
2396#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2397pub struct UnsafeBinderTy {
2398 pub generic_params: ThinVec<GenericParam>,
2399 pub inner_ty: Box<Ty>,
2400}
2401
2402#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2406pub enum TyKind {
2407 Slice(Box<Ty>),
2409 Array(Box<Ty>, AnonConst),
2411 Ptr(MutTy),
2413 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2415 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2419 FnPtr(Box<FnPtrTy>),
2421 UnsafeBinder(Box<UnsafeBinderTy>),
2423 Never,
2425 Tup(ThinVec<Box<Ty>>),
2427 Path(Option<Box<QSelf>>, Path),
2432 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2435 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2442 Paren(Box<Ty>),
2444 Typeof(AnonConst),
2446 Infer,
2449 ImplicitSelf,
2451 MacCall(Box<MacCall>),
2453 CVarArgs,
2455 Pat(Box<Ty>, Box<TyPat>),
2458 Dummy,
2460 Err(ErrorGuaranteed),
2462}
2463
2464impl TyKind {
2465 pub fn is_implicit_self(&self) -> bool {
2466 matches!(self, TyKind::ImplicitSelf)
2467 }
2468
2469 pub fn is_unit(&self) -> bool {
2470 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2471 }
2472
2473 pub fn is_simple_path(&self) -> Option<Symbol> {
2474 if let TyKind::Path(None, Path { segments, .. }) = &self
2475 && let [segment] = &segments[..]
2476 && segment.args.is_none()
2477 {
2478 Some(segment.ident.name)
2479 } else {
2480 None
2481 }
2482 }
2483
2484 pub fn maybe_scalar(&self) -> bool {
2492 let Some(ty_sym) = self.is_simple_path() else {
2493 return self.is_unit();
2495 };
2496 matches!(
2497 ty_sym,
2498 sym::i8
2499 | sym::i16
2500 | sym::i32
2501 | sym::i64
2502 | sym::i128
2503 | sym::u8
2504 | sym::u16
2505 | sym::u32
2506 | sym::u64
2507 | sym::u128
2508 | sym::f16
2509 | sym::f32
2510 | sym::f64
2511 | sym::f128
2512 | sym::char
2513 | sym::bool
2514 )
2515 }
2516}
2517
2518#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2520pub struct TyPat {
2521 pub id: NodeId,
2522 pub kind: TyPatKind,
2523 pub span: Span,
2524 pub tokens: Option<LazyAttrTokenStream>,
2525}
2526
2527#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2531pub enum TyPatKind {
2532 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2534
2535 Or(ThinVec<Box<TyPat>>),
2536
2537 Err(ErrorGuaranteed),
2539}
2540
2541#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2543#[repr(u8)]
2544pub enum TraitObjectSyntax {
2545 Dyn = 0,
2547 None = 1,
2548}
2549
2550unsafe impl Tag for TraitObjectSyntax {
2554 const BITS: u32 = 2;
2555
2556 fn into_usize(self) -> usize {
2557 self as u8 as usize
2558 }
2559
2560 unsafe fn from_usize(tag: usize) -> Self {
2561 match tag {
2562 0 => TraitObjectSyntax::Dyn,
2563 1 => TraitObjectSyntax::None,
2564 _ => unreachable!(),
2565 }
2566 }
2567}
2568
2569#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2570pub enum PreciseCapturingArg {
2571 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2573 Arg(Path, NodeId),
2575}
2576
2577#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2581pub enum InlineAsmRegOrRegClass {
2582 Reg(Symbol),
2583 RegClass(Symbol),
2584}
2585
2586#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2587pub struct InlineAsmOptions(u16);
2588bitflags::bitflags! {
2589 impl InlineAsmOptions: u16 {
2590 const PURE = 1 << 0;
2591 const NOMEM = 1 << 1;
2592 const READONLY = 1 << 2;
2593 const PRESERVES_FLAGS = 1 << 3;
2594 const NORETURN = 1 << 4;
2595 const NOSTACK = 1 << 5;
2596 const ATT_SYNTAX = 1 << 6;
2597 const RAW = 1 << 7;
2598 const MAY_UNWIND = 1 << 8;
2599 }
2600}
2601
2602impl InlineAsmOptions {
2603 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2604
2605 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2606 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2607
2608 pub fn human_readable_names(&self) -> Vec<&'static str> {
2609 let mut options = vec![];
2610
2611 if self.contains(InlineAsmOptions::PURE) {
2612 options.push("pure");
2613 }
2614 if self.contains(InlineAsmOptions::NOMEM) {
2615 options.push("nomem");
2616 }
2617 if self.contains(InlineAsmOptions::READONLY) {
2618 options.push("readonly");
2619 }
2620 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2621 options.push("preserves_flags");
2622 }
2623 if self.contains(InlineAsmOptions::NORETURN) {
2624 options.push("noreturn");
2625 }
2626 if self.contains(InlineAsmOptions::NOSTACK) {
2627 options.push("nostack");
2628 }
2629 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2630 options.push("att_syntax");
2631 }
2632 if self.contains(InlineAsmOptions::RAW) {
2633 options.push("raw");
2634 }
2635 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2636 options.push("may_unwind");
2637 }
2638
2639 options
2640 }
2641}
2642
2643impl std::fmt::Debug for InlineAsmOptions {
2644 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2645 bitflags::parser::to_writer(self, f)
2646 }
2647}
2648
2649#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2650pub enum InlineAsmTemplatePiece {
2651 String(Cow<'static, str>),
2652 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2653}
2654
2655impl fmt::Display for InlineAsmTemplatePiece {
2656 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2657 match self {
2658 Self::String(s) => {
2659 for c in s.chars() {
2660 match c {
2661 '{' => f.write_str("{{")?,
2662 '}' => f.write_str("}}")?,
2663 _ => c.fmt(f)?,
2664 }
2665 }
2666 Ok(())
2667 }
2668 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2669 write!(f, "{{{operand_idx}:{modifier}}}")
2670 }
2671 Self::Placeholder { operand_idx, modifier: None, .. } => {
2672 write!(f, "{{{operand_idx}}}")
2673 }
2674 }
2675 }
2676}
2677
2678impl InlineAsmTemplatePiece {
2679 pub fn to_string(s: &[Self]) -> String {
2681 use fmt::Write;
2682 let mut out = String::new();
2683 for p in s.iter() {
2684 let _ = write!(out, "{p}");
2685 }
2686 out
2687 }
2688}
2689
2690#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2698pub struct InlineAsmSym {
2699 pub id: NodeId,
2700 pub qself: Option<Box<QSelf>>,
2701 pub path: Path,
2702}
2703
2704#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2708pub enum InlineAsmOperand {
2709 In {
2710 reg: InlineAsmRegOrRegClass,
2711 expr: Box<Expr>,
2712 },
2713 Out {
2714 reg: InlineAsmRegOrRegClass,
2715 late: bool,
2716 expr: Option<Box<Expr>>,
2717 },
2718 InOut {
2719 reg: InlineAsmRegOrRegClass,
2720 late: bool,
2721 expr: Box<Expr>,
2722 },
2723 SplitInOut {
2724 reg: InlineAsmRegOrRegClass,
2725 late: bool,
2726 in_expr: Box<Expr>,
2727 out_expr: Option<Box<Expr>>,
2728 },
2729 Const {
2730 anon_const: AnonConst,
2731 },
2732 Sym {
2733 sym: InlineAsmSym,
2734 },
2735 Label {
2736 block: Box<Block>,
2737 },
2738}
2739
2740impl InlineAsmOperand {
2741 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2742 match self {
2743 Self::In { reg, .. }
2744 | Self::Out { reg, .. }
2745 | Self::InOut { reg, .. }
2746 | Self::SplitInOut { reg, .. } => Some(reg),
2747 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2748 }
2749 }
2750}
2751
2752#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2753pub enum AsmMacro {
2754 Asm,
2756 GlobalAsm,
2758 NakedAsm,
2760}
2761
2762impl AsmMacro {
2763 pub const fn macro_name(self) -> &'static str {
2764 match self {
2765 AsmMacro::Asm => "asm",
2766 AsmMacro::GlobalAsm => "global_asm",
2767 AsmMacro::NakedAsm => "naked_asm",
2768 }
2769 }
2770
2771 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2772 match self {
2773 AsmMacro::Asm => true,
2774 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2775 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2776 }
2777 }
2778
2779 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2780 match self {
2781 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2782 AsmMacro::GlobalAsm => true,
2783 AsmMacro::NakedAsm => true,
2784 }
2785 }
2786}
2787
2788#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2792pub struct InlineAsm {
2793 pub asm_macro: AsmMacro,
2794 pub template: Vec<InlineAsmTemplatePiece>,
2795 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2796 pub operands: Vec<(InlineAsmOperand, Span)>,
2797 pub clobber_abis: Vec<(Symbol, Span)>,
2798 #[visitable(ignore)]
2799 pub options: InlineAsmOptions,
2800 pub line_spans: Vec<Span>,
2801}
2802
2803#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2807pub struct Param {
2808 pub attrs: AttrVec,
2809 pub ty: Box<Ty>,
2810 pub pat: Box<Pat>,
2811 pub id: NodeId,
2812 pub span: Span,
2813 pub is_placeholder: bool,
2814}
2815
2816#[derive(Clone, Encodable, Decodable, Debug)]
2820pub enum SelfKind {
2821 Value(Mutability),
2823 Region(Option<Lifetime>, Mutability),
2825 Pinned(Option<Lifetime>, Mutability),
2827 Explicit(Box<Ty>, Mutability),
2829}
2830
2831impl SelfKind {
2832 pub fn to_ref_suggestion(&self) -> String {
2833 match self {
2834 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2835 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2836 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2837 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2838 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2839 unreachable!("if we had an explicit self, we wouldn't be here")
2840 }
2841 }
2842 }
2843}
2844
2845pub type ExplicitSelf = Spanned<SelfKind>;
2846
2847impl Param {
2848 pub fn to_self(&self) -> Option<ExplicitSelf> {
2850 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2851 if ident.name == kw::SelfLower {
2852 return match self.ty.kind {
2853 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2854 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2855 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2856 }
2857 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2858 if ty.kind.is_implicit_self() =>
2859 {
2860 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2861 }
2862 _ => Some(respan(
2863 self.pat.span.to(self.ty.span),
2864 SelfKind::Explicit(self.ty.clone(), mutbl),
2865 )),
2866 };
2867 }
2868 }
2869 None
2870 }
2871
2872 pub fn is_self(&self) -> bool {
2874 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2875 ident.name == kw::SelfLower
2876 } else {
2877 false
2878 }
2879 }
2880
2881 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2883 let span = eself.span.to(eself_ident.span);
2884 let infer_ty = Box::new(Ty {
2885 id: DUMMY_NODE_ID,
2886 kind: TyKind::ImplicitSelf,
2887 span: eself_ident.span,
2888 tokens: None,
2889 });
2890 let (mutbl, ty) = match eself.node {
2891 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2892 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2893 SelfKind::Region(lt, mutbl) => (
2894 Mutability::Not,
2895 Box::new(Ty {
2896 id: DUMMY_NODE_ID,
2897 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2898 span,
2899 tokens: None,
2900 }),
2901 ),
2902 SelfKind::Pinned(lt, mutbl) => (
2903 mutbl,
2904 Box::new(Ty {
2905 id: DUMMY_NODE_ID,
2906 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2907 span,
2908 tokens: None,
2909 }),
2910 ),
2911 };
2912 Param {
2913 attrs,
2914 pat: Box::new(Pat {
2915 id: DUMMY_NODE_ID,
2916 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2917 span,
2918 tokens: None,
2919 }),
2920 span,
2921 ty,
2922 id: DUMMY_NODE_ID,
2923 is_placeholder: false,
2924 }
2925 }
2926}
2927
2928#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2935pub struct FnDecl {
2936 pub inputs: ThinVec<Param>,
2937 pub output: FnRetTy,
2938}
2939
2940impl FnDecl {
2941 pub fn has_self(&self) -> bool {
2942 self.inputs.get(0).is_some_and(Param::is_self)
2943 }
2944 pub fn c_variadic(&self) -> bool {
2945 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2946 }
2947}
2948
2949#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2951pub enum IsAuto {
2952 Yes,
2953 No,
2954}
2955
2956#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2958#[derive(HashStable_Generic, Walkable)]
2959pub enum Safety {
2960 Unsafe(Span),
2962 Safe(Span),
2964 Default,
2967}
2968
2969#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
2975pub enum CoroutineKind {
2976 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2978 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2980 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2982}
2983
2984impl CoroutineKind {
2985 pub fn span(self) -> Span {
2986 match self {
2987 CoroutineKind::Async { span, .. } => span,
2988 CoroutineKind::Gen { span, .. } => span,
2989 CoroutineKind::AsyncGen { span, .. } => span,
2990 }
2991 }
2992
2993 pub fn as_str(self) -> &'static str {
2994 match self {
2995 CoroutineKind::Async { .. } => "async",
2996 CoroutineKind::Gen { .. } => "gen",
2997 CoroutineKind::AsyncGen { .. } => "async gen",
2998 }
2999 }
3000
3001 pub fn closure_id(self) -> NodeId {
3002 match self {
3003 CoroutineKind::Async { closure_id, .. }
3004 | CoroutineKind::Gen { closure_id, .. }
3005 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3006 }
3007 }
3008
3009 pub fn return_id(self) -> (NodeId, Span) {
3012 match self {
3013 CoroutineKind::Async { return_impl_trait_id, span, .. }
3014 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3015 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3016 (return_impl_trait_id, span)
3017 }
3018 }
3019 }
3020}
3021
3022#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3023#[derive(HashStable_Generic, Walkable)]
3024pub enum Const {
3025 Yes(Span),
3026 No,
3027}
3028
3029#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3032pub enum Defaultness {
3033 Default(Span),
3034 Final,
3035}
3036
3037#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3038pub enum ImplPolarity {
3039 Positive,
3041 Negative(Span),
3043}
3044
3045impl fmt::Debug for ImplPolarity {
3046 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3047 match *self {
3048 ImplPolarity::Positive => "positive".fmt(f),
3049 ImplPolarity::Negative(_) => "negative".fmt(f),
3050 }
3051 }
3052}
3053
3054#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3056#[derive(HashStable_Generic, Walkable)]
3057pub enum BoundPolarity {
3058 Positive,
3060 Negative(Span),
3062 Maybe(Span),
3064}
3065
3066impl BoundPolarity {
3067 pub fn as_str(self) -> &'static str {
3068 match self {
3069 Self::Positive => "",
3070 Self::Negative(_) => "!",
3071 Self::Maybe(_) => "?",
3072 }
3073 }
3074}
3075
3076#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3078#[derive(HashStable_Generic, Walkable)]
3079pub enum BoundConstness {
3080 Never,
3082 Always(Span),
3084 Maybe(Span),
3086}
3087
3088impl BoundConstness {
3089 pub fn as_str(self) -> &'static str {
3090 match self {
3091 Self::Never => "",
3092 Self::Always(_) => "const",
3093 Self::Maybe(_) => "[const]",
3094 }
3095 }
3096}
3097
3098#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3100#[derive(HashStable_Generic, Walkable)]
3101pub enum BoundAsyncness {
3102 Normal,
3104 Async(Span),
3106}
3107
3108impl BoundAsyncness {
3109 pub fn as_str(self) -> &'static str {
3110 match self {
3111 Self::Normal => "",
3112 Self::Async(_) => "async",
3113 }
3114 }
3115}
3116
3117#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3118pub enum FnRetTy {
3119 Default(Span),
3124 Ty(Box<Ty>),
3126}
3127
3128impl FnRetTy {
3129 pub fn span(&self) -> Span {
3130 match self {
3131 &FnRetTy::Default(span) => span,
3132 FnRetTy::Ty(ty) => ty.span,
3133 }
3134 }
3135}
3136
3137#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3138pub enum Inline {
3139 Yes,
3140 No { had_parse_error: Result<(), ErrorGuaranteed> },
3141}
3142
3143#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3145pub enum ModKind {
3146 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3151 Unloaded,
3153}
3154
3155#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3156pub struct ModSpans {
3157 pub inner_span: Span,
3160 pub inject_use_span: Span,
3161}
3162
3163#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3167pub struct ForeignMod {
3168 pub extern_span: Span,
3170 pub safety: Safety,
3173 pub abi: Option<StrLit>,
3174 pub items: ThinVec<Box<ForeignItem>>,
3175}
3176
3177#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3178pub struct EnumDef {
3179 pub variants: ThinVec<Variant>,
3180}
3181
3182#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3184pub struct Variant {
3185 pub attrs: AttrVec,
3187 pub id: NodeId,
3189 pub span: Span,
3191 pub vis: Visibility,
3193 pub ident: Ident,
3195
3196 pub data: VariantData,
3198 pub disr_expr: Option<AnonConst>,
3200 pub is_placeholder: bool,
3202}
3203
3204#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3206pub enum UseTreeKind {
3207 Simple(Option<Ident>),
3209 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3218 Glob,
3220}
3221
3222#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3225pub struct UseTree {
3226 pub prefix: Path,
3227 pub kind: UseTreeKind,
3228 pub span: Span,
3229}
3230
3231impl UseTree {
3232 pub fn ident(&self) -> Ident {
3233 match self.kind {
3234 UseTreeKind::Simple(Some(rename)) => rename,
3235 UseTreeKind::Simple(None) => {
3236 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3237 }
3238 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3239 }
3240 }
3241}
3242
3243#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3247pub enum AttrStyle {
3248 Outer,
3249 Inner,
3250}
3251
3252pub type AttrVec = ThinVec<Attribute>;
3254
3255#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3257pub struct Attribute {
3258 pub kind: AttrKind,
3259 pub id: AttrId,
3260 pub style: AttrStyle,
3263 pub span: Span,
3264}
3265
3266#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3267pub enum AttrKind {
3268 Normal(Box<NormalAttr>),
3270
3271 DocComment(CommentKind, Symbol),
3275}
3276
3277#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3278pub struct NormalAttr {
3279 pub item: AttrItem,
3280 pub tokens: Option<LazyAttrTokenStream>,
3282}
3283
3284impl NormalAttr {
3285 pub fn from_ident(ident: Ident) -> Self {
3286 Self {
3287 item: AttrItem {
3288 unsafety: Safety::Default,
3289 path: Path::from_ident(ident),
3290 args: AttrArgs::Empty,
3291 tokens: None,
3292 },
3293 tokens: None,
3294 }
3295 }
3296}
3297
3298#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3299pub struct AttrItem {
3300 pub unsafety: Safety,
3301 pub path: Path,
3302 pub args: AttrArgs,
3303 pub tokens: Option<LazyAttrTokenStream>,
3305}
3306
3307impl AttrItem {
3308 pub fn is_valid_for_outer_style(&self) -> bool {
3309 self.path == sym::cfg_attr
3310 || self.path == sym::cfg
3311 || self.path == sym::forbid
3312 || self.path == sym::warn
3313 || self.path == sym::allow
3314 || self.path == sym::deny
3315 }
3316}
3317
3318#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3325pub struct TraitRef {
3326 pub path: Path,
3327 pub ref_id: NodeId,
3328}
3329
3330#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3332pub enum Parens {
3333 Yes,
3334 No,
3335}
3336
3337#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3338pub struct PolyTraitRef {
3339 pub bound_generic_params: ThinVec<GenericParam>,
3341
3342 pub modifiers: TraitBoundModifiers,
3344
3345 pub trait_ref: TraitRef,
3347
3348 pub span: Span,
3349
3350 pub parens: Parens,
3353}
3354
3355impl PolyTraitRef {
3356 pub fn new(
3357 generic_params: ThinVec<GenericParam>,
3358 path: Path,
3359 modifiers: TraitBoundModifiers,
3360 span: Span,
3361 parens: Parens,
3362 ) -> Self {
3363 PolyTraitRef {
3364 bound_generic_params: generic_params,
3365 modifiers,
3366 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3367 span,
3368 parens,
3369 }
3370 }
3371}
3372
3373#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3374pub struct Visibility {
3375 pub kind: VisibilityKind,
3376 pub span: Span,
3377 pub tokens: Option<LazyAttrTokenStream>,
3378}
3379
3380#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3381pub enum VisibilityKind {
3382 Public,
3383 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3384 Inherited,
3385}
3386
3387impl VisibilityKind {
3388 pub fn is_pub(&self) -> bool {
3389 matches!(self, VisibilityKind::Public)
3390 }
3391}
3392
3393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3397pub struct FieldDef {
3398 pub attrs: AttrVec,
3399 pub id: NodeId,
3400 pub span: Span,
3401 pub vis: Visibility,
3402 pub safety: Safety,
3403 pub ident: Option<Ident>,
3404
3405 pub ty: Box<Ty>,
3406 pub default: Option<AnonConst>,
3407 pub is_placeholder: bool,
3408}
3409
3410#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3412pub enum Recovered {
3413 No,
3414 Yes(ErrorGuaranteed),
3415}
3416
3417#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3419pub enum VariantData {
3420 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3424 Tuple(ThinVec<FieldDef>, NodeId),
3428 Unit(NodeId),
3432}
3433
3434impl VariantData {
3435 pub fn fields(&self) -> &[FieldDef] {
3437 match self {
3438 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3439 _ => &[],
3440 }
3441 }
3442
3443 pub fn ctor_node_id(&self) -> Option<NodeId> {
3445 match *self {
3446 VariantData::Struct { .. } => None,
3447 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3448 }
3449 }
3450}
3451
3452#[derive(Clone, Encodable, Decodable, Debug)]
3454pub struct Item<K = ItemKind> {
3455 pub attrs: AttrVec,
3456 pub id: NodeId,
3457 pub span: Span,
3458 pub vis: Visibility,
3459
3460 pub kind: K,
3461
3462 pub tokens: Option<LazyAttrTokenStream>,
3470}
3471
3472impl Item {
3473 pub fn span_with_attributes(&self) -> Span {
3475 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3476 }
3477
3478 pub fn opt_generics(&self) -> Option<&Generics> {
3479 match &self.kind {
3480 ItemKind::ExternCrate(..)
3481 | ItemKind::Use(_)
3482 | ItemKind::Mod(..)
3483 | ItemKind::ForeignMod(_)
3484 | ItemKind::GlobalAsm(_)
3485 | ItemKind::MacCall(_)
3486 | ItemKind::Delegation(_)
3487 | ItemKind::DelegationMac(_)
3488 | ItemKind::MacroDef(..) => None,
3489 ItemKind::Static(_) => None,
3490 ItemKind::Const(i) => Some(&i.generics),
3491 ItemKind::Fn(i) => Some(&i.generics),
3492 ItemKind::TyAlias(i) => Some(&i.generics),
3493 ItemKind::TraitAlias(_, generics, _)
3494 | ItemKind::Enum(_, generics, _)
3495 | ItemKind::Struct(_, generics, _)
3496 | ItemKind::Union(_, generics, _) => Some(&generics),
3497 ItemKind::Trait(i) => Some(&i.generics),
3498 ItemKind::Impl(i) => Some(&i.generics),
3499 }
3500 }
3501}
3502
3503#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3505pub enum Extern {
3506 None,
3510 Implicit(Span),
3516 Explicit(StrLit, Span),
3520}
3521
3522impl Extern {
3523 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3524 match abi {
3525 Some(name) => Extern::Explicit(name, span),
3526 None => Extern::Implicit(span),
3527 }
3528 }
3529}
3530
3531#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3536pub struct FnHeader {
3537 pub safety: Safety,
3539 pub coroutine_kind: Option<CoroutineKind>,
3541 pub constness: Const,
3543 pub ext: Extern,
3545}
3546
3547impl FnHeader {
3548 pub fn has_qualifiers(&self) -> bool {
3550 let Self { safety, coroutine_kind, constness, ext } = self;
3551 matches!(safety, Safety::Unsafe(_))
3552 || coroutine_kind.is_some()
3553 || matches!(constness, Const::Yes(_))
3554 || !matches!(ext, Extern::None)
3555 }
3556
3557 pub fn span(&self) -> Option<Span> {
3559 fn append(a: &mut Option<Span>, b: Span) {
3560 *a = match a {
3561 None => Some(b),
3562 Some(x) => Some(x.to(b)),
3563 }
3564 }
3565
3566 let mut full_span = None;
3567
3568 match self.safety {
3569 Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3570 Safety::Default => {}
3571 };
3572
3573 if let Some(coroutine_kind) = self.coroutine_kind {
3574 append(&mut full_span, coroutine_kind.span());
3575 }
3576
3577 if let Const::Yes(span) = self.constness {
3578 append(&mut full_span, span);
3579 }
3580
3581 match self.ext {
3582 Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3583 Extern::None => {}
3584 }
3585
3586 full_span
3587 }
3588}
3589
3590impl Default for FnHeader {
3591 fn default() -> FnHeader {
3592 FnHeader {
3593 safety: Safety::Default,
3594 coroutine_kind: None,
3595 constness: Const::No,
3596 ext: Extern::None,
3597 }
3598 }
3599}
3600
3601#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3602pub struct Trait {
3603 pub constness: Const,
3604 pub safety: Safety,
3605 pub is_auto: IsAuto,
3606 pub ident: Ident,
3607 pub generics: Generics,
3608 #[visitable(extra = BoundKind::SuperTraits)]
3609 pub bounds: GenericBounds,
3610 #[visitable(extra = AssocCtxt::Trait)]
3611 pub items: ThinVec<Box<AssocItem>>,
3612}
3613
3614#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3633pub struct TyAliasWhereClause {
3634 pub has_where_token: bool,
3635 pub span: Span,
3636}
3637
3638#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3640pub struct TyAliasWhereClauses {
3641 pub before: TyAliasWhereClause,
3643 pub after: TyAliasWhereClause,
3645 pub split: usize,
3649}
3650
3651#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3652pub struct TyAlias {
3653 pub defaultness: Defaultness,
3654 pub ident: Ident,
3655 pub generics: Generics,
3656 pub where_clauses: TyAliasWhereClauses,
3657 #[visitable(extra = BoundKind::Bound)]
3658 pub bounds: GenericBounds,
3659 pub ty: Option<Box<Ty>>,
3660}
3661
3662#[derive(Clone, Encodable, Decodable, Debug)]
3663pub struct Impl {
3664 pub generics: Generics,
3665 pub of_trait: Option<Box<TraitImplHeader>>,
3666 pub self_ty: Box<Ty>,
3667 pub items: ThinVec<Box<AssocItem>>,
3668}
3669
3670#[derive(Clone, Encodable, Decodable, Debug)]
3671pub struct TraitImplHeader {
3672 pub defaultness: Defaultness,
3673 pub safety: Safety,
3674 pub constness: Const,
3675 pub polarity: ImplPolarity,
3676 pub trait_ref: TraitRef,
3677}
3678
3679#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3680pub struct FnContract {
3681 pub requires: Option<Box<Expr>>,
3682 pub ensures: Option<Box<Expr>>,
3683}
3684
3685#[derive(Clone, Encodable, Decodable, Debug)]
3686pub struct Fn {
3687 pub defaultness: Defaultness,
3688 pub ident: Ident,
3689 pub generics: Generics,
3690 pub sig: FnSig,
3691 pub contract: Option<Box<FnContract>>,
3692 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3693 pub body: Option<Box<Block>>,
3694}
3695
3696#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3697pub struct Delegation {
3698 pub id: NodeId,
3700 pub qself: Option<Box<QSelf>>,
3701 pub path: Path,
3702 pub ident: Ident,
3703 pub rename: Option<Ident>,
3704 pub body: Option<Box<Block>>,
3705 pub from_glob: bool,
3707}
3708
3709#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3710pub struct DelegationMac {
3711 pub qself: Option<Box<QSelf>>,
3712 pub prefix: Path,
3713 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3715 pub body: Option<Box<Block>>,
3716}
3717
3718#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3719pub struct StaticItem {
3720 pub ident: Ident,
3721 pub ty: Box<Ty>,
3722 pub safety: Safety,
3723 pub mutability: Mutability,
3724 pub expr: Option<Box<Expr>>,
3725 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3726}
3727
3728#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3729pub struct ConstItem {
3730 pub defaultness: Defaultness,
3731 pub ident: Ident,
3732 pub generics: Generics,
3733 pub ty: Box<Ty>,
3734 pub expr: Option<Box<Expr>>,
3735 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3736}
3737
3738#[derive(Clone, Encodable, Decodable, Debug)]
3740pub enum ItemKind {
3741 ExternCrate(Option<Symbol>, Ident),
3745 Use(UseTree),
3749 Static(Box<StaticItem>),
3753 Const(Box<ConstItem>),
3757 Fn(Box<Fn>),
3761 Mod(Safety, Ident, ModKind),
3767 ForeignMod(ForeignMod),
3771 GlobalAsm(Box<InlineAsm>),
3773 TyAlias(Box<TyAlias>),
3777 Enum(Ident, Generics, EnumDef),
3781 Struct(Ident, Generics, VariantData),
3785 Union(Ident, Generics, VariantData),
3789 Trait(Box<Trait>),
3793 TraitAlias(Ident, Generics, GenericBounds),
3797 Impl(Impl),
3801 MacCall(Box<MacCall>),
3805 MacroDef(Ident, MacroDef),
3807 Delegation(Box<Delegation>),
3811 DelegationMac(Box<DelegationMac>),
3814}
3815
3816impl ItemKind {
3817 pub fn ident(&self) -> Option<Ident> {
3818 match *self {
3819 ItemKind::ExternCrate(_, ident)
3820 | ItemKind::Static(box StaticItem { ident, .. })
3821 | ItemKind::Const(box ConstItem { ident, .. })
3822 | ItemKind::Fn(box Fn { ident, .. })
3823 | ItemKind::Mod(_, ident, _)
3824 | ItemKind::TyAlias(box TyAlias { ident, .. })
3825 | ItemKind::Enum(ident, ..)
3826 | ItemKind::Struct(ident, ..)
3827 | ItemKind::Union(ident, ..)
3828 | ItemKind::Trait(box Trait { ident, .. })
3829 | ItemKind::TraitAlias(ident, ..)
3830 | ItemKind::MacroDef(ident, _)
3831 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3832
3833 ItemKind::Use(_)
3834 | ItemKind::ForeignMod(_)
3835 | ItemKind::GlobalAsm(_)
3836 | ItemKind::Impl(_)
3837 | ItemKind::MacCall(_)
3838 | ItemKind::DelegationMac(_) => None,
3839 }
3840 }
3841
3842 pub fn article(&self) -> &'static str {
3844 use ItemKind::*;
3845 match self {
3846 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3847 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3848 | Delegation(..) | DelegationMac(..) => "a",
3849 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3850 }
3851 }
3852
3853 pub fn descr(&self) -> &'static str {
3854 match self {
3855 ItemKind::ExternCrate(..) => "extern crate",
3856 ItemKind::Use(..) => "`use` import",
3857 ItemKind::Static(..) => "static item",
3858 ItemKind::Const(..) => "constant item",
3859 ItemKind::Fn(..) => "function",
3860 ItemKind::Mod(..) => "module",
3861 ItemKind::ForeignMod(..) => "extern block",
3862 ItemKind::GlobalAsm(..) => "global asm item",
3863 ItemKind::TyAlias(..) => "type alias",
3864 ItemKind::Enum(..) => "enum",
3865 ItemKind::Struct(..) => "struct",
3866 ItemKind::Union(..) => "union",
3867 ItemKind::Trait(..) => "trait",
3868 ItemKind::TraitAlias(..) => "trait alias",
3869 ItemKind::MacCall(..) => "item macro invocation",
3870 ItemKind::MacroDef(..) => "macro definition",
3871 ItemKind::Impl { .. } => "implementation",
3872 ItemKind::Delegation(..) => "delegated function",
3873 ItemKind::DelegationMac(..) => "delegation",
3874 }
3875 }
3876
3877 pub fn generics(&self) -> Option<&Generics> {
3878 match self {
3879 Self::Fn(box Fn { generics, .. })
3880 | Self::TyAlias(box TyAlias { generics, .. })
3881 | Self::Const(box ConstItem { generics, .. })
3882 | Self::Enum(_, generics, _)
3883 | Self::Struct(_, generics, _)
3884 | Self::Union(_, generics, _)
3885 | Self::Trait(box Trait { generics, .. })
3886 | Self::TraitAlias(_, generics, _)
3887 | Self::Impl(Impl { generics, .. }) => Some(generics),
3888 _ => None,
3889 }
3890 }
3891}
3892
3893pub type AssocItem = Item<AssocItemKind>;
3896
3897#[derive(Clone, Encodable, Decodable, Debug)]
3905pub enum AssocItemKind {
3906 Const(Box<ConstItem>),
3909 Fn(Box<Fn>),
3911 Type(Box<TyAlias>),
3913 MacCall(Box<MacCall>),
3915 Delegation(Box<Delegation>),
3917 DelegationMac(Box<DelegationMac>),
3919}
3920
3921impl AssocItemKind {
3922 pub fn ident(&self) -> Option<Ident> {
3923 match *self {
3924 AssocItemKind::Const(box ConstItem { ident, .. })
3925 | AssocItemKind::Fn(box Fn { ident, .. })
3926 | AssocItemKind::Type(box TyAlias { ident, .. })
3927 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3928
3929 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3930 }
3931 }
3932
3933 pub fn defaultness(&self) -> Defaultness {
3934 match *self {
3935 Self::Const(box ConstItem { defaultness, .. })
3936 | Self::Fn(box Fn { defaultness, .. })
3937 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3938 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3939 Defaultness::Final
3940 }
3941 }
3942 }
3943}
3944
3945impl From<AssocItemKind> for ItemKind {
3946 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3947 match assoc_item_kind {
3948 AssocItemKind::Const(item) => ItemKind::Const(item),
3949 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3950 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3951 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3952 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3953 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3954 }
3955 }
3956}
3957
3958impl TryFrom<ItemKind> for AssocItemKind {
3959 type Error = ItemKind;
3960
3961 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3962 Ok(match item_kind {
3963 ItemKind::Const(item) => AssocItemKind::Const(item),
3964 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3965 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3966 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3967 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3968 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3969 _ => return Err(item_kind),
3970 })
3971 }
3972}
3973
3974#[derive(Clone, Encodable, Decodable, Debug)]
3976pub enum ForeignItemKind {
3977 Static(Box<StaticItem>),
3979 Fn(Box<Fn>),
3981 TyAlias(Box<TyAlias>),
3983 MacCall(Box<MacCall>),
3985}
3986
3987impl ForeignItemKind {
3988 pub fn ident(&self) -> Option<Ident> {
3989 match *self {
3990 ForeignItemKind::Static(box StaticItem { ident, .. })
3991 | ForeignItemKind::Fn(box Fn { ident, .. })
3992 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3993
3994 ForeignItemKind::MacCall(_) => None,
3995 }
3996 }
3997}
3998
3999impl From<ForeignItemKind> for ItemKind {
4000 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4001 match foreign_item_kind {
4002 ForeignItemKind::Static(box static_foreign_item) => {
4003 ItemKind::Static(Box::new(static_foreign_item))
4004 }
4005 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4006 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4007 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4008 }
4009 }
4010}
4011
4012impl TryFrom<ItemKind> for ForeignItemKind {
4013 type Error = ItemKind;
4014
4015 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4016 Ok(match item_kind {
4017 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4018 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4019 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4020 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4021 _ => return Err(item_kind),
4022 })
4023 }
4024}
4025
4026pub type ForeignItem = Item<ForeignItemKind>;
4027
4028#[cfg(target_pointer_width = "64")]
4030mod size_asserts {
4031 use rustc_data_structures::static_assert_size;
4032
4033 use super::*;
4034 static_assert_size!(AssocItem, 80);
4036 static_assert_size!(AssocItemKind, 16);
4037 static_assert_size!(Attribute, 32);
4038 static_assert_size!(Block, 32);
4039 static_assert_size!(Expr, 72);
4040 static_assert_size!(ExprKind, 40);
4041 static_assert_size!(Fn, 184);
4042 static_assert_size!(ForeignItem, 80);
4043 static_assert_size!(ForeignItemKind, 16);
4044 static_assert_size!(GenericArg, 24);
4045 static_assert_size!(GenericBound, 88);
4046 static_assert_size!(Generics, 40);
4047 static_assert_size!(Impl, 64);
4048 static_assert_size!(Item, 144);
4049 static_assert_size!(ItemKind, 80);
4050 static_assert_size!(LitKind, 24);
4051 static_assert_size!(Local, 96);
4052 static_assert_size!(MetaItemLit, 40);
4053 static_assert_size!(Param, 40);
4054 static_assert_size!(Pat, 72);
4055 static_assert_size!(PatKind, 48);
4056 static_assert_size!(Path, 24);
4057 static_assert_size!(PathSegment, 24);
4058 static_assert_size!(Stmt, 32);
4059 static_assert_size!(StmtKind, 16);
4060 static_assert_size!(TraitImplHeader, 80);
4061 static_assert_size!(Ty, 64);
4062 static_assert_size!(TyKind, 40);
4063 }