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.iter().eq(*names)
118 }
119}
120
121impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
122 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
123 self.segments.len().hash_stable(hcx, hasher);
124 for segment in &self.segments {
125 segment.ident.hash_stable(hcx, hasher);
126 }
127 }
128}
129
130impl Path {
131 pub fn from_ident(ident: Ident) -> Path {
134 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
135 }
136
137 pub fn is_global(&self) -> bool {
138 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
139 }
140
141 #[tracing::instrument(level = "debug", ret)]
151 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
152 allow_mgca_arg
153 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
154 }
155}
156
157pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
169 let mut iter = path.into_iter();
174 let len_hint = iter.size_hint().1.unwrap_or(1);
175 let mut s = String::with_capacity(len_hint * 8);
176
177 let first_sym = *iter.next().unwrap().borrow();
178 if first_sym != kw::PathRoot {
179 s.push_str(first_sym.as_str());
180 }
181 for sym in iter {
182 let sym = *sym.borrow();
183 debug_assert_ne!(sym, kw::PathRoot);
184 s.push_str("::");
185 s.push_str(sym.as_str());
186 }
187 s
188}
189
190pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
193 let mut iter = path.into_iter();
194 let len_hint = iter.size_hint().1.unwrap_or(1);
195 let mut s = String::with_capacity(len_hint * 8);
196
197 let first_ident = *iter.next().unwrap().borrow();
198 if first_ident.name != kw::PathRoot {
199 s.push_str(&first_ident.to_string());
200 }
201 for ident in iter {
202 let ident = *ident.borrow();
203 debug_assert_ne!(ident.name, kw::PathRoot);
204 s.push_str("::");
205 s.push_str(&ident.to_string());
206 }
207 s
208}
209
210#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
214pub struct PathSegment {
215 pub ident: Ident,
217
218 pub id: NodeId,
219
220 pub args: Option<Box<GenericArgs>>,
227}
228
229impl PartialEq<Symbol> for PathSegment {
231 #[inline]
232 fn eq(&self, name: &Symbol) -> bool {
233 self.args.is_none() && self.ident.name == *name
234 }
235}
236
237impl PathSegment {
238 pub fn from_ident(ident: Ident) -> Self {
239 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
240 }
241
242 pub fn path_root(span: Span) -> Self {
243 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
244 }
245
246 pub fn span(&self) -> Span {
247 match &self.args {
248 Some(args) => self.ident.span.to(args.span()),
249 None => self.ident.span,
250 }
251 }
252}
253
254#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
258pub enum GenericArgs {
259 AngleBracketed(AngleBracketedArgs),
261 Parenthesized(ParenthesizedArgs),
263 ParenthesizedElided(Span),
265}
266
267impl GenericArgs {
268 pub fn is_angle_bracketed(&self) -> bool {
269 matches!(self, AngleBracketed(..))
270 }
271
272 pub fn span(&self) -> Span {
273 match self {
274 AngleBracketed(data) => data.span,
275 Parenthesized(data) => data.span,
276 ParenthesizedElided(span) => *span,
277 }
278 }
279}
280
281#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
283pub enum GenericArg {
284 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
286 Type(Box<Ty>),
288 Const(AnonConst),
290}
291
292impl GenericArg {
293 pub fn span(&self) -> Span {
294 match self {
295 GenericArg::Lifetime(lt) => lt.ident.span,
296 GenericArg::Type(ty) => ty.span,
297 GenericArg::Const(ct) => ct.value.span,
298 }
299 }
300}
301
302#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
304pub struct AngleBracketedArgs {
305 pub span: Span,
307 pub args: ThinVec<AngleBracketedArg>,
309}
310
311#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
313pub enum AngleBracketedArg {
314 Arg(GenericArg),
316 Constraint(AssocItemConstraint),
318}
319
320impl AngleBracketedArg {
321 pub fn span(&self) -> Span {
322 match self {
323 AngleBracketedArg::Arg(arg) => arg.span(),
324 AngleBracketedArg::Constraint(constraint) => constraint.span,
325 }
326 }
327}
328
329impl From<AngleBracketedArgs> for Box<GenericArgs> {
330 fn from(val: AngleBracketedArgs) -> Self {
331 Box::new(GenericArgs::AngleBracketed(val))
332 }
333}
334
335impl From<ParenthesizedArgs> for Box<GenericArgs> {
336 fn from(val: ParenthesizedArgs) -> Self {
337 Box::new(GenericArgs::Parenthesized(val))
338 }
339}
340
341#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
343pub struct ParenthesizedArgs {
344 pub span: Span,
349
350 pub inputs: ThinVec<Box<Ty>>,
352
353 pub inputs_span: Span,
358
359 pub output: FnRetTy,
361}
362
363impl ParenthesizedArgs {
364 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
365 let args = self
366 .inputs
367 .iter()
368 .cloned()
369 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
370 .collect();
371 AngleBracketedArgs { span: self.inputs_span, args }
372 }
373}
374
375pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
376
377#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
379pub struct TraitBoundModifiers {
380 pub constness: BoundConstness,
381 pub asyncness: BoundAsyncness,
382 pub polarity: BoundPolarity,
383}
384
385impl TraitBoundModifiers {
386 pub const NONE: Self = Self {
387 constness: BoundConstness::Never,
388 asyncness: BoundAsyncness::Normal,
389 polarity: BoundPolarity::Positive,
390 };
391}
392
393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
394pub enum GenericBound {
395 Trait(PolyTraitRef),
396 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
397 Use(ThinVec<PreciseCapturingArg>, Span),
399}
400
401impl GenericBound {
402 pub fn span(&self) -> Span {
403 match self {
404 GenericBound::Trait(t, ..) => t.span,
405 GenericBound::Outlives(l) => l.ident.span,
406 GenericBound::Use(_, span) => *span,
407 }
408 }
409}
410
411pub type GenericBounds = Vec<GenericBound>;
412
413#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
417pub enum ParamKindOrd {
418 Lifetime,
419 TypeOrConst,
420}
421
422impl fmt::Display for ParamKindOrd {
423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424 match self {
425 ParamKindOrd::Lifetime => "lifetime".fmt(f),
426 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
427 }
428 }
429}
430
431#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
432pub enum GenericParamKind {
433 Lifetime,
435 Type {
436 default: Option<Box<Ty>>,
437 },
438 Const {
439 ty: Box<Ty>,
440 span: Span,
442 default: Option<AnonConst>,
444 },
445}
446
447#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
448pub struct GenericParam {
449 pub id: NodeId,
450 pub ident: Ident,
451 pub attrs: AttrVec,
452 #[visitable(extra = BoundKind::Bound)]
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, Walkable)]
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, Walkable)]
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, Walkable)]
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, Walkable)]
510pub enum WherePredicateKind {
511 BoundPredicate(WhereBoundPredicate),
513 RegionPredicate(WhereRegionPredicate),
515 EqPredicate(WhereEqPredicate),
517}
518
519#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
523pub struct WhereBoundPredicate {
524 pub bound_generic_params: ThinVec<GenericParam>,
526 pub bounded_ty: Box<Ty>,
528 #[visitable(extra = BoundKind::Bound)]
530 pub bounds: GenericBounds,
531}
532
533#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
537pub struct WhereRegionPredicate {
538 #[visitable(extra = LifetimeCtxt::Bound)]
539 pub lifetime: Lifetime,
540 #[visitable(extra = BoundKind::Bound)]
541 pub bounds: GenericBounds,
542}
543
544#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
548pub struct WhereEqPredicate {
549 pub lhs_ty: Box<Ty>,
550 pub rhs_ty: Box<Ty>,
551}
552
553#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
554pub struct Crate {
555 pub id: NodeId,
558 pub attrs: AttrVec,
559 pub items: ThinVec<Box<Item>>,
560 pub spans: ModSpans,
561 pub is_placeholder: bool,
562}
563
564#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
571pub struct MetaItem {
572 pub unsafety: Safety,
573 pub path: Path,
574 pub kind: MetaItemKind,
575 pub span: Span,
576}
577
578#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
580pub enum MetaItemKind {
581 Word,
585
586 List(ThinVec<MetaItemInner>),
590
591 NameValue(MetaItemLit),
595}
596
597#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
601pub enum MetaItemInner {
602 MetaItem(MetaItem),
604
605 Lit(MetaItemLit),
609}
610
611#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
615pub struct Block {
616 pub stmts: ThinVec<Stmt>,
618 pub id: NodeId,
619 pub rules: BlockCheckMode,
621 pub span: Span,
622 pub tokens: Option<LazyAttrTokenStream>,
623}
624
625#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
629pub struct Pat {
630 pub id: NodeId,
631 pub kind: PatKind,
632 pub span: Span,
633 pub tokens: Option<LazyAttrTokenStream>,
634}
635
636impl Pat {
637 pub fn to_ty(&self) -> Option<Box<Ty>> {
640 let kind = match &self.kind {
641 PatKind::Missing => unreachable!(),
642 PatKind::Wild => TyKind::Infer,
644 PatKind::Ident(BindingMode::NONE, ident, None) => {
646 TyKind::Path(None, Path::from_ident(*ident))
647 }
648 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
649 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
650 PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
652 Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
653 Pinnedness::Pinned => TyKind::PinnedRef(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 peel_refs(&self) -> &Pat {
720 let mut current = self;
721 while let PatKind::Ref(inner, _, _) = ¤t.kind {
722 current = inner;
723 }
724 current
725 }
726
727 pub fn is_rest(&self) -> bool {
729 matches!(self.kind, PatKind::Rest)
730 }
731
732 pub fn could_be_never_pattern(&self) -> bool {
735 let mut could_be_never_pattern = false;
736 self.walk(&mut |pat| match &pat.kind {
737 PatKind::Never | PatKind::MacCall(_) => {
738 could_be_never_pattern = true;
739 false
740 }
741 PatKind::Or(s) => {
742 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
743 false
744 }
745 _ => true,
746 });
747 could_be_never_pattern
748 }
749
750 pub fn contains_never_pattern(&self) -> bool {
753 let mut contains_never_pattern = false;
754 self.walk(&mut |pat| {
755 if matches!(pat.kind, PatKind::Never) {
756 contains_never_pattern = true;
757 }
758 true
759 });
760 contains_never_pattern
761 }
762
763 pub fn descr(&self) -> Option<String> {
765 match &self.kind {
766 PatKind::Missing => unreachable!(),
767 PatKind::Wild => Some("_".to_string()),
768 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
769 PatKind::Ref(pat, pinned, mutbl) => {
770 pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
771 }
772 _ => None,
773 }
774 }
775}
776
777impl From<Box<Pat>> for Pat {
778 fn from(value: Box<Pat>) -> Self {
779 *value
780 }
781}
782
783#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
789pub struct PatField {
790 pub ident: Ident,
792 pub pat: Box<Pat>,
794 pub is_shorthand: bool,
795 pub attrs: AttrVec,
796 pub id: NodeId,
797 pub span: Span,
798 pub is_placeholder: bool,
799}
800
801#[derive(Clone, Copy, Debug, Eq, PartialEq)]
802#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
803pub enum ByRef {
804 Yes(Pinnedness, Mutability),
805 No,
806}
807
808impl ByRef {
809 #[must_use]
810 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
811 if let ByRef::Yes(_, old_mutbl) = &mut self {
812 *old_mutbl = cmp::min(*old_mutbl, mutbl);
813 }
814 self
815 }
816}
817
818#[derive(Clone, Copy, Debug, Eq, PartialEq)]
824#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
825pub struct BindingMode(pub ByRef, pub Mutability);
826
827impl BindingMode {
828 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
829 pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not);
830 pub const REF_PIN: Self =
831 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not);
832 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
833 pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not);
834 pub const REF_PIN_MUT: Self =
835 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not);
836 pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut);
837 pub const MUT_REF_PIN: Self =
838 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut);
839 pub const MUT_REF_MUT: Self =
840 Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut);
841 pub const MUT_REF_PIN_MUT: Self =
842 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut);
843
844 pub fn prefix_str(self) -> &'static str {
845 match self {
846 Self::NONE => "",
847 Self::REF => "ref ",
848 Self::REF_PIN => "ref pin const ",
849 Self::MUT => "mut ",
850 Self::REF_MUT => "ref mut ",
851 Self::REF_PIN_MUT => "ref pin mut ",
852 Self::MUT_REF => "mut ref ",
853 Self::MUT_REF_PIN => "mut ref pin ",
854 Self::MUT_REF_MUT => "mut ref mut ",
855 Self::MUT_REF_PIN_MUT => "mut ref pin mut ",
856 }
857 }
858}
859
860#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
861pub enum RangeEnd {
862 Included(RangeSyntax),
864 Excluded,
866}
867
868#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
869pub enum RangeSyntax {
870 DotDotDot,
872 DotDotEq,
874}
875
876#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
880pub enum PatKind {
881 Missing,
883
884 Wild,
886
887 Ident(BindingMode, Ident, Option<Box<Pat>>),
892
893 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
895
896 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
898
899 Or(ThinVec<Pat>),
902
903 Path(Option<Box<QSelf>>, Path),
908
909 Tuple(ThinVec<Pat>),
911
912 Box(Box<Pat>),
914
915 Deref(Box<Pat>),
917
918 Ref(Box<Pat>, Pinnedness, Mutability),
920
921 Expr(Box<Expr>),
923
924 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
926
927 Slice(ThinVec<Pat>),
929
930 Rest,
943
944 Never,
946
947 Guard(Box<Pat>, Box<Expr>),
949
950 Paren(Box<Pat>),
952
953 MacCall(Box<MacCall>),
955
956 Err(ErrorGuaranteed),
958}
959
960#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
962pub enum PatFieldsRest {
963 Rest(Span),
965 Recovered(ErrorGuaranteed),
967 None,
969}
970
971#[derive(Clone, Copy, PartialEq, Eq, Debug)]
974#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
975pub enum BorrowKind {
976 Ref,
980 Raw,
984 Pin,
988}
989
990#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
991pub enum BinOpKind {
992 Add,
994 Sub,
996 Mul,
998 Div,
1000 Rem,
1002 And,
1004 Or,
1006 BitXor,
1008 BitAnd,
1010 BitOr,
1012 Shl,
1014 Shr,
1016 Eq,
1018 Lt,
1020 Le,
1022 Ne,
1024 Ge,
1026 Gt,
1028}
1029
1030impl BinOpKind {
1031 pub fn as_str(&self) -> &'static str {
1032 use BinOpKind::*;
1033 match self {
1034 Add => "+",
1035 Sub => "-",
1036 Mul => "*",
1037 Div => "/",
1038 Rem => "%",
1039 And => "&&",
1040 Or => "||",
1041 BitXor => "^",
1042 BitAnd => "&",
1043 BitOr => "|",
1044 Shl => "<<",
1045 Shr => ">>",
1046 Eq => "==",
1047 Lt => "<",
1048 Le => "<=",
1049 Ne => "!=",
1050 Ge => ">=",
1051 Gt => ">",
1052 }
1053 }
1054
1055 pub fn is_lazy(&self) -> bool {
1056 matches!(self, BinOpKind::And | BinOpKind::Or)
1057 }
1058
1059 pub fn precedence(&self) -> ExprPrecedence {
1060 use BinOpKind::*;
1061 match *self {
1062 Mul | Div | Rem => ExprPrecedence::Product,
1063 Add | Sub => ExprPrecedence::Sum,
1064 Shl | Shr => ExprPrecedence::Shift,
1065 BitAnd => ExprPrecedence::BitAnd,
1066 BitXor => ExprPrecedence::BitXor,
1067 BitOr => ExprPrecedence::BitOr,
1068 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1069 And => ExprPrecedence::LAnd,
1070 Or => ExprPrecedence::LOr,
1071 }
1072 }
1073
1074 pub fn fixity(&self) -> Fixity {
1075 use BinOpKind::*;
1076 match self {
1077 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1078 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1079 Fixity::Left
1080 }
1081 }
1082 }
1083
1084 pub fn is_comparison(self) -> bool {
1085 use BinOpKind::*;
1086 match self {
1087 Eq | Ne | Lt | Le | Gt | Ge => true,
1088 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1089 }
1090 }
1091
1092 pub fn is_by_value(self) -> bool {
1094 !self.is_comparison()
1095 }
1096}
1097
1098pub type BinOp = Spanned<BinOpKind>;
1099
1100impl From<AssignOpKind> for BinOpKind {
1104 fn from(op: AssignOpKind) -> BinOpKind {
1105 match op {
1106 AssignOpKind::AddAssign => BinOpKind::Add,
1107 AssignOpKind::SubAssign => BinOpKind::Sub,
1108 AssignOpKind::MulAssign => BinOpKind::Mul,
1109 AssignOpKind::DivAssign => BinOpKind::Div,
1110 AssignOpKind::RemAssign => BinOpKind::Rem,
1111 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1112 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1113 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1114 AssignOpKind::ShlAssign => BinOpKind::Shl,
1115 AssignOpKind::ShrAssign => BinOpKind::Shr,
1116 }
1117 }
1118}
1119
1120#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1121pub enum AssignOpKind {
1122 AddAssign,
1124 SubAssign,
1126 MulAssign,
1128 DivAssign,
1130 RemAssign,
1132 BitXorAssign,
1134 BitAndAssign,
1136 BitOrAssign,
1138 ShlAssign,
1140 ShrAssign,
1142}
1143
1144impl AssignOpKind {
1145 pub fn as_str(&self) -> &'static str {
1146 use AssignOpKind::*;
1147 match self {
1148 AddAssign => "+=",
1149 SubAssign => "-=",
1150 MulAssign => "*=",
1151 DivAssign => "/=",
1152 RemAssign => "%=",
1153 BitXorAssign => "^=",
1154 BitAndAssign => "&=",
1155 BitOrAssign => "|=",
1156 ShlAssign => "<<=",
1157 ShrAssign => ">>=",
1158 }
1159 }
1160
1161 pub fn is_by_value(self) -> bool {
1163 true
1164 }
1165}
1166
1167pub type AssignOp = Spanned<AssignOpKind>;
1168
1169#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1173pub enum UnOp {
1174 Deref,
1176 Not,
1178 Neg,
1180}
1181
1182impl UnOp {
1183 pub fn as_str(&self) -> &'static str {
1184 match self {
1185 UnOp::Deref => "*",
1186 UnOp::Not => "!",
1187 UnOp::Neg => "-",
1188 }
1189 }
1190
1191 pub fn is_by_value(self) -> bool {
1193 matches!(self, Self::Neg | Self::Not)
1194 }
1195}
1196
1197#[derive(Clone, Encodable, Decodable, Debug)]
1201pub struct Stmt {
1202 pub id: NodeId,
1203 pub kind: StmtKind,
1204 pub span: Span,
1205}
1206
1207impl Stmt {
1208 pub fn has_trailing_semicolon(&self) -> bool {
1209 match &self.kind {
1210 StmtKind::Semi(_) => true,
1211 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1212 _ => false,
1213 }
1214 }
1215
1216 pub fn add_trailing_semicolon(mut self) -> Self {
1224 self.kind = match self.kind {
1225 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1226 StmtKind::MacCall(mut mac) => {
1227 mac.style = MacStmtStyle::Semicolon;
1228 StmtKind::MacCall(mac)
1229 }
1230 kind => kind,
1231 };
1232
1233 self
1234 }
1235
1236 pub fn is_item(&self) -> bool {
1237 matches!(self.kind, StmtKind::Item(_))
1238 }
1239
1240 pub fn is_expr(&self) -> bool {
1241 matches!(self.kind, StmtKind::Expr(_))
1242 }
1243}
1244
1245#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1247pub enum StmtKind {
1248 Let(Box<Local>),
1250 Item(Box<Item>),
1252 Expr(Box<Expr>),
1254 Semi(Box<Expr>),
1256 Empty,
1258 MacCall(Box<MacCallStmt>),
1260}
1261
1262#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1263pub struct MacCallStmt {
1264 pub mac: Box<MacCall>,
1265 pub style: MacStmtStyle,
1266 pub attrs: AttrVec,
1267 pub tokens: Option<LazyAttrTokenStream>,
1268}
1269
1270#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1271pub enum MacStmtStyle {
1272 Semicolon,
1275 Braces,
1277 NoBraces,
1281}
1282
1283#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1285pub struct Local {
1286 pub id: NodeId,
1287 pub super_: Option<Span>,
1288 pub pat: Box<Pat>,
1289 pub ty: Option<Box<Ty>>,
1290 pub kind: LocalKind,
1291 pub span: Span,
1292 pub colon_sp: Option<Span>,
1293 pub attrs: AttrVec,
1294 pub tokens: Option<LazyAttrTokenStream>,
1295}
1296
1297#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1298pub enum LocalKind {
1299 Decl,
1302 Init(Box<Expr>),
1305 InitElse(Box<Expr>, Box<Block>),
1308}
1309
1310impl LocalKind {
1311 pub fn init(&self) -> Option<&Expr> {
1312 match self {
1313 Self::Decl => None,
1314 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1315 }
1316 }
1317
1318 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1319 match self {
1320 Self::Decl => None,
1321 Self::Init(init) => Some((init, None)),
1322 Self::InitElse(init, els) => Some((init, Some(els))),
1323 }
1324 }
1325}
1326
1327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1338pub struct Arm {
1339 pub attrs: AttrVec,
1340 pub pat: Box<Pat>,
1342 pub guard: Option<Box<Expr>>,
1344 pub body: Option<Box<Expr>>,
1346 pub span: Span,
1347 pub id: NodeId,
1348 pub is_placeholder: bool,
1349}
1350
1351#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1353pub struct ExprField {
1354 pub attrs: AttrVec,
1355 pub id: NodeId,
1356 pub span: Span,
1357 pub ident: Ident,
1358 pub expr: Box<Expr>,
1359 pub is_shorthand: bool,
1360 pub is_placeholder: bool,
1361}
1362
1363#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1364pub enum BlockCheckMode {
1365 Default,
1366 Unsafe(UnsafeSource),
1367}
1368
1369#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1370pub enum UnsafeSource {
1371 CompilerGenerated,
1372 UserProvided,
1373}
1374
1375#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1381pub struct AnonConst {
1382 pub id: NodeId,
1383 pub value: Box<Expr>,
1384}
1385
1386#[derive(Clone, Encodable, Decodable, Debug)]
1388pub struct Expr {
1389 pub id: NodeId,
1390 pub kind: ExprKind,
1391 pub span: Span,
1392 pub attrs: AttrVec,
1393 pub tokens: Option<LazyAttrTokenStream>,
1394}
1395
1396impl Expr {
1397 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1411 let this = self.maybe_unwrap_block();
1412 if allow_mgca_arg {
1413 matches!(this.kind, ExprKind::Path(..))
1414 } else {
1415 if let ExprKind::Path(None, path) = &this.kind
1416 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1417 {
1418 true
1419 } else {
1420 false
1421 }
1422 }
1423 }
1424
1425 pub fn maybe_unwrap_block(&self) -> &Expr {
1427 if let ExprKind::Block(block, None) = &self.kind
1428 && let [stmt] = block.stmts.as_slice()
1429 && let StmtKind::Expr(expr) = &stmt.kind
1430 {
1431 expr
1432 } else {
1433 self
1434 }
1435 }
1436
1437 pub fn optionally_braced_mac_call(
1443 &self,
1444 already_stripped_block: bool,
1445 ) -> Option<(bool, NodeId)> {
1446 match &self.kind {
1447 ExprKind::Block(block, None)
1448 if let [stmt] = &*block.stmts
1449 && !already_stripped_block =>
1450 {
1451 match &stmt.kind {
1452 StmtKind::MacCall(_) => Some((true, stmt.id)),
1453 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1454 Some((true, expr.id))
1455 }
1456 _ => None,
1457 }
1458 }
1459 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1460 _ => None,
1461 }
1462 }
1463
1464 pub fn to_bound(&self) -> Option<GenericBound> {
1465 match &self.kind {
1466 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1467 ThinVec::new(),
1468 path.clone(),
1469 TraitBoundModifiers::NONE,
1470 self.span,
1471 Parens::No,
1472 ))),
1473 _ => None,
1474 }
1475 }
1476
1477 pub fn peel_parens(&self) -> &Expr {
1478 let mut expr = self;
1479 while let ExprKind::Paren(inner) = &expr.kind {
1480 expr = inner;
1481 }
1482 expr
1483 }
1484
1485 pub fn peel_parens_and_refs(&self) -> &Expr {
1486 let mut expr = self;
1487 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1488 {
1489 expr = inner;
1490 }
1491 expr
1492 }
1493
1494 pub fn to_ty(&self) -> Option<Box<Ty>> {
1496 let kind = match &self.kind {
1497 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1499 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1500
1501 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1502
1503 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1504 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1505 }
1506
1507 ExprKind::Repeat(expr, expr_len) => {
1508 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1509 }
1510
1511 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1512 expr.to_ty().map(TyKind::Slice)?
1513 }
1514
1515 ExprKind::Tup(exprs) => {
1516 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1517 TyKind::Tup(tys)
1518 }
1519
1520 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1524 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1525 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1526 } else {
1527 return None;
1528 }
1529 }
1530
1531 ExprKind::Underscore => TyKind::Infer,
1532
1533 _ => return None,
1535 };
1536
1537 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1538 }
1539
1540 pub fn precedence(&self) -> ExprPrecedence {
1541 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1542 for attr in attrs {
1543 if let AttrStyle::Outer = attr.style {
1544 return ExprPrecedence::Prefix;
1545 }
1546 }
1547 ExprPrecedence::Unambiguous
1548 }
1549
1550 match &self.kind {
1551 ExprKind::Closure(closure) => {
1552 match closure.fn_decl.output {
1553 FnRetTy::Default(_) => ExprPrecedence::Jump,
1554 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1555 }
1556 }
1557
1558 ExprKind::Break(_ , value)
1559 | ExprKind::Ret(value)
1560 | ExprKind::Yield(YieldKind::Prefix(value))
1561 | ExprKind::Yeet(value) => match value {
1562 Some(_) => ExprPrecedence::Jump,
1563 None => prefix_attrs_precedence(&self.attrs),
1564 },
1565
1566 ExprKind::Become(_) => ExprPrecedence::Jump,
1567
1568 ExprKind::Range(..) => ExprPrecedence::Range,
1573
1574 ExprKind::Binary(op, ..) => op.node.precedence(),
1576 ExprKind::Cast(..) => ExprPrecedence::Cast,
1577
1578 ExprKind::Assign(..) |
1579 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1580
1581 ExprKind::AddrOf(..)
1583 | ExprKind::Let(..)
1588 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1589
1590 ExprKind::Array(_)
1592 | ExprKind::Await(..)
1593 | ExprKind::Use(..)
1594 | ExprKind::Block(..)
1595 | ExprKind::Call(..)
1596 | ExprKind::ConstBlock(_)
1597 | ExprKind::Continue(..)
1598 | ExprKind::Field(..)
1599 | ExprKind::ForLoop { .. }
1600 | ExprKind::FormatArgs(..)
1601 | ExprKind::Gen(..)
1602 | ExprKind::If(..)
1603 | ExprKind::IncludedBytes(..)
1604 | ExprKind::Index(..)
1605 | ExprKind::InlineAsm(..)
1606 | ExprKind::Lit(_)
1607 | ExprKind::Loop(..)
1608 | ExprKind::MacCall(..)
1609 | ExprKind::Match(..)
1610 | ExprKind::MethodCall(..)
1611 | ExprKind::OffsetOf(..)
1612 | ExprKind::Paren(..)
1613 | ExprKind::Path(..)
1614 | ExprKind::Repeat(..)
1615 | ExprKind::Struct(..)
1616 | ExprKind::Try(..)
1617 | ExprKind::TryBlock(..)
1618 | ExprKind::Tup(_)
1619 | ExprKind::Type(..)
1620 | ExprKind::Underscore
1621 | ExprKind::UnsafeBinderCast(..)
1622 | ExprKind::While(..)
1623 | ExprKind::Yield(YieldKind::Postfix(..))
1624 | ExprKind::Err(_)
1625 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1626 }
1627 }
1628
1629 pub fn is_approximately_pattern(&self) -> bool {
1631 matches!(
1632 &self.peel_parens().kind,
1633 ExprKind::Array(_)
1634 | ExprKind::Call(_, _)
1635 | ExprKind::Tup(_)
1636 | ExprKind::Lit(_)
1637 | ExprKind::Range(_, _, _)
1638 | ExprKind::Underscore
1639 | ExprKind::Path(_, _)
1640 | ExprKind::Struct(_)
1641 )
1642 }
1643
1644 pub fn dummy() -> Expr {
1648 Expr {
1649 id: DUMMY_NODE_ID,
1650 kind: ExprKind::Dummy,
1651 span: DUMMY_SP,
1652 attrs: ThinVec::new(),
1653 tokens: None,
1654 }
1655 }
1656}
1657
1658impl From<Box<Expr>> for Expr {
1659 fn from(value: Box<Expr>) -> Self {
1660 *value
1661 }
1662}
1663
1664#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1665pub struct Closure {
1666 pub binder: ClosureBinder,
1667 pub capture_clause: CaptureBy,
1668 pub constness: Const,
1669 pub coroutine_kind: Option<CoroutineKind>,
1670 pub movability: Movability,
1671 pub fn_decl: Box<FnDecl>,
1672 pub body: Box<Expr>,
1673 pub fn_decl_span: Span,
1675 pub fn_arg_span: Span,
1677}
1678
1679#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1681pub enum RangeLimits {
1682 HalfOpen,
1684 Closed,
1686}
1687
1688impl RangeLimits {
1689 pub fn as_str(&self) -> &'static str {
1690 match self {
1691 RangeLimits::HalfOpen => "..",
1692 RangeLimits::Closed => "..=",
1693 }
1694 }
1695}
1696
1697#[derive(Clone, Encodable, Decodable, Debug)]
1699pub struct MethodCall {
1700 pub seg: PathSegment,
1702 pub receiver: Box<Expr>,
1704 pub args: ThinVec<Box<Expr>>,
1706 pub span: Span,
1709}
1710
1711#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1712pub enum StructRest {
1713 Base(Box<Expr>),
1715 Rest(Span),
1717 None,
1719}
1720
1721#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1722pub struct StructExpr {
1723 pub qself: Option<Box<QSelf>>,
1724 pub path: Path,
1725 pub fields: ThinVec<ExprField>,
1726 pub rest: StructRest,
1727}
1728
1729#[derive(Clone, Encodable, Decodable, Debug)]
1731pub enum ExprKind {
1732 Array(ThinVec<Box<Expr>>),
1734 ConstBlock(AnonConst),
1736 Call(Box<Expr>, ThinVec<Box<Expr>>),
1743 MethodCall(Box<MethodCall>),
1745 Tup(ThinVec<Box<Expr>>),
1747 Binary(BinOp, Box<Expr>, Box<Expr>),
1749 Unary(UnOp, Box<Expr>),
1751 Lit(token::Lit),
1753 Cast(Box<Expr>, Box<Ty>),
1755 Type(Box<Expr>, Box<Ty>),
1760 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1765 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1772 While(Box<Expr>, Box<Block>, Option<Label>),
1776 ForLoop {
1782 pat: Box<Pat>,
1783 iter: Box<Expr>,
1784 body: Box<Block>,
1785 label: Option<Label>,
1786 kind: ForLoopKind,
1787 },
1788 Loop(Box<Block>, Option<Label>, Span),
1792 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1794 Closure(Box<Closure>),
1796 Block(Box<Block>, Option<Label>),
1798 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1804 Await(Box<Expr>, Span),
1806 Use(Box<Expr>, Span),
1808
1809 TryBlock(Box<Block>),
1811
1812 Assign(Box<Expr>, Box<Expr>, Span),
1815 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1819 Field(Box<Expr>, Ident),
1821 Index(Box<Expr>, Box<Expr>, Span),
1824 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1826 Underscore,
1828
1829 Path(Option<Box<QSelf>>, Path),
1834
1835 AddrOf(BorrowKind, Mutability, Box<Expr>),
1837 Break(Option<Label>, Option<Box<Expr>>),
1839 Continue(Option<Label>),
1841 Ret(Option<Box<Expr>>),
1843
1844 InlineAsm(Box<InlineAsm>),
1846
1847 OffsetOf(Box<Ty>, Vec<Ident>),
1852
1853 MacCall(Box<MacCall>),
1855
1856 Struct(Box<StructExpr>),
1860
1861 Repeat(Box<Expr>, AnonConst),
1866
1867 Paren(Box<Expr>),
1869
1870 Try(Box<Expr>),
1872
1873 Yield(YieldKind),
1875
1876 Yeet(Option<Box<Expr>>),
1879
1880 Become(Box<Expr>),
1884
1885 IncludedBytes(ByteSymbol),
1897
1898 FormatArgs(Box<FormatArgs>),
1900
1901 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1902
1903 Err(ErrorGuaranteed),
1905
1906 Dummy,
1908}
1909
1910#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1912pub enum ForLoopKind {
1913 For,
1914 ForAwait,
1915}
1916
1917#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1919pub enum GenBlockKind {
1920 Async,
1921 Gen,
1922 AsyncGen,
1923}
1924
1925impl fmt::Display for GenBlockKind {
1926 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1927 self.modifier().fmt(f)
1928 }
1929}
1930
1931impl GenBlockKind {
1932 pub fn modifier(&self) -> &'static str {
1933 match self {
1934 GenBlockKind::Async => "async",
1935 GenBlockKind::Gen => "gen",
1936 GenBlockKind::AsyncGen => "async gen",
1937 }
1938 }
1939}
1940
1941#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1943#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1944pub enum UnsafeBinderCastKind {
1945 Wrap,
1947 Unwrap,
1949}
1950
1951#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1966pub struct QSelf {
1967 pub ty: Box<Ty>,
1968
1969 pub path_span: Span,
1973 pub position: usize,
1974}
1975
1976#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1978pub enum CaptureBy {
1979 Value {
1981 move_kw: Span,
1983 },
1984 Ref,
1986 Use {
1992 use_kw: Span,
1994 },
1995}
1996
1997#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1999pub enum ClosureBinder {
2000 NotPresent,
2002 For {
2004 span: Span,
2011
2012 generic_params: ThinVec<GenericParam>,
2019 },
2020}
2021
2022#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2025pub struct MacCall {
2026 pub path: Path,
2027 pub args: Box<DelimArgs>,
2028}
2029
2030impl MacCall {
2031 pub fn span(&self) -> Span {
2032 self.path.span.to(self.args.dspan.entire())
2033 }
2034}
2035
2036#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2038pub enum AttrArgs {
2039 Empty,
2041 Delimited(DelimArgs),
2043 Eq {
2045 eq_span: Span,
2047 expr: Box<Expr>,
2048 },
2049}
2050
2051impl AttrArgs {
2052 pub fn span(&self) -> Option<Span> {
2053 match self {
2054 AttrArgs::Empty => None,
2055 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2056 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2057 }
2058 }
2059
2060 pub fn inner_tokens(&self) -> TokenStream {
2063 match self {
2064 AttrArgs::Empty => TokenStream::default(),
2065 AttrArgs::Delimited(args) => args.tokens.clone(),
2066 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2067 }
2068 }
2069}
2070
2071#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2073pub struct DelimArgs {
2074 pub dspan: DelimSpan,
2075 pub delim: Delimiter, pub tokens: TokenStream,
2077}
2078
2079impl DelimArgs {
2080 pub fn need_semicolon(&self) -> bool {
2083 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2084 }
2085}
2086
2087#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2089pub struct MacroDef {
2090 pub body: Box<DelimArgs>,
2091 pub macro_rules: bool,
2093}
2094
2095#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2096#[derive(HashStable_Generic, Walkable)]
2097pub enum StrStyle {
2098 Cooked,
2100 Raw(u8),
2104}
2105
2106#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2108pub enum MatchKind {
2109 Prefix,
2111 Postfix,
2113}
2114
2115#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2117pub enum YieldKind {
2118 Prefix(Option<Box<Expr>>),
2120 Postfix(Box<Expr>),
2122}
2123
2124impl YieldKind {
2125 pub const fn expr(&self) -> Option<&Box<Expr>> {
2129 match self {
2130 YieldKind::Prefix(expr) => expr.as_ref(),
2131 YieldKind::Postfix(expr) => Some(expr),
2132 }
2133 }
2134
2135 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2137 match self {
2138 YieldKind::Prefix(expr) => expr.as_mut(),
2139 YieldKind::Postfix(expr) => Some(expr),
2140 }
2141 }
2142
2143 pub const fn same_kind(&self, other: &Self) -> bool {
2145 match (self, other) {
2146 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2147 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2148 _ => false,
2149 }
2150 }
2151}
2152
2153#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2155pub struct MetaItemLit {
2156 pub symbol: Symbol,
2158 pub suffix: Option<Symbol>,
2160 pub kind: LitKind,
2163 pub span: Span,
2164}
2165
2166#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2168pub struct StrLit {
2169 pub symbol: Symbol,
2171 pub suffix: Option<Symbol>,
2173 pub symbol_unescaped: Symbol,
2175 pub style: StrStyle,
2176 pub span: Span,
2177}
2178
2179impl StrLit {
2180 pub fn as_token_lit(&self) -> token::Lit {
2181 let token_kind = match self.style {
2182 StrStyle::Cooked => token::Str,
2183 StrStyle::Raw(n) => token::StrRaw(n),
2184 };
2185 token::Lit::new(token_kind, self.symbol, self.suffix)
2186 }
2187}
2188
2189#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2191#[derive(HashStable_Generic)]
2192pub enum LitIntType {
2193 Signed(IntTy),
2195 Unsigned(UintTy),
2197 Unsuffixed,
2199}
2200
2201#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2203#[derive(HashStable_Generic)]
2204pub enum LitFloatType {
2205 Suffixed(FloatTy),
2207 Unsuffixed,
2209}
2210
2211#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2218pub enum LitKind {
2219 Str(Symbol, StrStyle),
2222 ByteStr(ByteSymbol, StrStyle),
2225 CStr(ByteSymbol, StrStyle),
2229 Byte(u8),
2231 Char(char),
2233 Int(Pu128, LitIntType),
2235 Float(Symbol, LitFloatType),
2239 Bool(bool),
2241 Err(ErrorGuaranteed),
2243}
2244
2245impl LitKind {
2246 pub fn str(&self) -> Option<Symbol> {
2247 match *self {
2248 LitKind::Str(s, _) => Some(s),
2249 _ => None,
2250 }
2251 }
2252
2253 pub fn is_str(&self) -> bool {
2255 matches!(self, LitKind::Str(..))
2256 }
2257
2258 pub fn is_bytestr(&self) -> bool {
2260 matches!(self, LitKind::ByteStr(..))
2261 }
2262
2263 pub fn is_numeric(&self) -> bool {
2265 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2266 }
2267
2268 pub fn is_unsuffixed(&self) -> bool {
2271 !self.is_suffixed()
2272 }
2273
2274 pub fn is_suffixed(&self) -> bool {
2276 match *self {
2277 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2279 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2280 LitKind::Str(..)
2282 | LitKind::ByteStr(..)
2283 | LitKind::CStr(..)
2284 | LitKind::Byte(..)
2285 | LitKind::Char(..)
2286 | LitKind::Int(_, LitIntType::Unsuffixed)
2287 | LitKind::Float(_, LitFloatType::Unsuffixed)
2288 | LitKind::Bool(..)
2289 | LitKind::Err(_) => false,
2290 }
2291 }
2292}
2293
2294#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2297pub struct MutTy {
2298 pub ty: Box<Ty>,
2299 pub mutbl: Mutability,
2300}
2301
2302#[derive(Clone, Encodable, Decodable, Debug)]
2305pub struct FnSig {
2306 pub header: FnHeader,
2307 pub decl: Box<FnDecl>,
2308 pub span: Span,
2309}
2310
2311impl FnSig {
2312 pub fn header_span(&self) -> Span {
2314 match self.header.ext {
2315 Extern::Implicit(span) | Extern::Explicit(_, span) => {
2316 return self.span.with_hi(span.hi());
2317 }
2318 Extern::None => {}
2319 }
2320
2321 match self.header.safety {
2322 Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2323 Safety::Default => {}
2324 };
2325
2326 if let Some(coroutine_kind) = self.header.coroutine_kind {
2327 return self.span.with_hi(coroutine_kind.span().hi());
2328 }
2329
2330 if let Const::Yes(span) = self.header.constness {
2331 return self.span.with_hi(span.hi());
2332 }
2333
2334 self.span.shrink_to_lo()
2335 }
2336
2337 pub fn safety_span(&self) -> Span {
2339 match self.header.safety {
2340 Safety::Unsafe(span) | Safety::Safe(span) => span,
2341 Safety::Default => {
2342 if let Some(extern_span) = self.header.ext.span() {
2344 return extern_span.shrink_to_lo();
2345 }
2346
2347 self.header_span().shrink_to_hi()
2349 }
2350 }
2351 }
2352
2353 pub fn extern_span(&self) -> Span {
2355 self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2356 }
2357}
2358
2359#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2370pub struct AssocItemConstraint {
2371 pub id: NodeId,
2372 pub ident: Ident,
2373 pub gen_args: Option<GenericArgs>,
2374 pub kind: AssocItemConstraintKind,
2375 pub span: Span,
2376}
2377
2378#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2379pub enum Term {
2380 Ty(Box<Ty>),
2381 Const(AnonConst),
2382}
2383
2384impl From<Box<Ty>> for Term {
2385 fn from(v: Box<Ty>) -> Self {
2386 Term::Ty(v)
2387 }
2388}
2389
2390impl From<AnonConst> for Term {
2391 fn from(v: AnonConst) -> Self {
2392 Term::Const(v)
2393 }
2394}
2395
2396#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2398pub enum AssocItemConstraintKind {
2399 Equality { term: Term },
2406 Bound {
2408 #[visitable(extra = BoundKind::Bound)]
2409 bounds: GenericBounds,
2410 },
2411}
2412
2413#[derive(Encodable, Decodable, Debug, Walkable)]
2414pub struct Ty {
2415 pub id: NodeId,
2416 pub kind: TyKind,
2417 pub span: Span,
2418 pub tokens: Option<LazyAttrTokenStream>,
2419}
2420
2421impl Clone for Ty {
2422 fn clone(&self) -> Self {
2423 ensure_sufficient_stack(|| Self {
2424 id: self.id,
2425 kind: self.kind.clone(),
2426 span: self.span,
2427 tokens: self.tokens.clone(),
2428 })
2429 }
2430}
2431
2432impl From<Box<Ty>> for Ty {
2433 fn from(value: Box<Ty>) -> Self {
2434 *value
2435 }
2436}
2437
2438impl Ty {
2439 pub fn peel_refs(&self) -> &Self {
2440 let mut final_ty = self;
2441 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2442 {
2443 final_ty = ty;
2444 }
2445 final_ty
2446 }
2447
2448 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2449 match &self.kind {
2450 TyKind::Infer => true,
2451 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2452 _ => false,
2453 }
2454 }
2455}
2456
2457#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2458pub struct FnPtrTy {
2459 pub safety: Safety,
2460 pub ext: Extern,
2461 pub generic_params: ThinVec<GenericParam>,
2462 pub decl: Box<FnDecl>,
2463 pub decl_span: Span,
2466}
2467
2468#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2469pub struct UnsafeBinderTy {
2470 pub generic_params: ThinVec<GenericParam>,
2471 pub inner_ty: Box<Ty>,
2472}
2473
2474#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2478pub enum TyKind {
2479 Slice(Box<Ty>),
2481 Array(Box<Ty>, AnonConst),
2483 Ptr(MutTy),
2485 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2487 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2491 FnPtr(Box<FnPtrTy>),
2493 UnsafeBinder(Box<UnsafeBinderTy>),
2495 Never,
2497 Tup(ThinVec<Box<Ty>>),
2499 Path(Option<Box<QSelf>>, Path),
2504 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2507 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2514 Paren(Box<Ty>),
2516 Infer,
2519 ImplicitSelf,
2521 MacCall(Box<MacCall>),
2523 CVarArgs,
2525 Pat(Box<Ty>, Box<TyPat>),
2528 Dummy,
2530 Err(ErrorGuaranteed),
2532}
2533
2534impl TyKind {
2535 pub fn is_implicit_self(&self) -> bool {
2536 matches!(self, TyKind::ImplicitSelf)
2537 }
2538
2539 pub fn is_unit(&self) -> bool {
2540 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2541 }
2542
2543 pub fn is_simple_path(&self) -> Option<Symbol> {
2544 if let TyKind::Path(None, Path { segments, .. }) = &self
2545 && let [segment] = &segments[..]
2546 && segment.args.is_none()
2547 {
2548 Some(segment.ident.name)
2549 } else {
2550 None
2551 }
2552 }
2553
2554 pub fn maybe_scalar(&self) -> bool {
2562 let Some(ty_sym) = self.is_simple_path() else {
2563 return self.is_unit();
2565 };
2566 matches!(
2567 ty_sym,
2568 sym::i8
2569 | sym::i16
2570 | sym::i32
2571 | sym::i64
2572 | sym::i128
2573 | sym::u8
2574 | sym::u16
2575 | sym::u32
2576 | sym::u64
2577 | sym::u128
2578 | sym::f16
2579 | sym::f32
2580 | sym::f64
2581 | sym::f128
2582 | sym::char
2583 | sym::bool
2584 )
2585 }
2586}
2587
2588#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2590pub struct TyPat {
2591 pub id: NodeId,
2592 pub kind: TyPatKind,
2593 pub span: Span,
2594 pub tokens: Option<LazyAttrTokenStream>,
2595}
2596
2597#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2601pub enum TyPatKind {
2602 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2604
2605 NotNull,
2607
2608 Or(ThinVec<TyPat>),
2609
2610 Err(ErrorGuaranteed),
2612}
2613
2614#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2616#[repr(u8)]
2617pub enum TraitObjectSyntax {
2618 Dyn = 0,
2620 None = 1,
2621}
2622
2623unsafe impl Tag for TraitObjectSyntax {
2627 const BITS: u32 = 2;
2628
2629 fn into_usize(self) -> usize {
2630 self as u8 as usize
2631 }
2632
2633 unsafe fn from_usize(tag: usize) -> Self {
2634 match tag {
2635 0 => TraitObjectSyntax::Dyn,
2636 1 => TraitObjectSyntax::None,
2637 _ => unreachable!(),
2638 }
2639 }
2640}
2641
2642#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2643pub enum PreciseCapturingArg {
2644 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2646 Arg(Path, NodeId),
2648}
2649
2650#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2654pub enum InlineAsmRegOrRegClass {
2655 Reg(Symbol),
2656 RegClass(Symbol),
2657}
2658
2659#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2660pub struct InlineAsmOptions(u16);
2661bitflags::bitflags! {
2662 impl InlineAsmOptions: u16 {
2663 const PURE = 1 << 0;
2664 const NOMEM = 1 << 1;
2665 const READONLY = 1 << 2;
2666 const PRESERVES_FLAGS = 1 << 3;
2667 const NORETURN = 1 << 4;
2668 const NOSTACK = 1 << 5;
2669 const ATT_SYNTAX = 1 << 6;
2670 const RAW = 1 << 7;
2671 const MAY_UNWIND = 1 << 8;
2672 }
2673}
2674
2675impl InlineAsmOptions {
2676 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2677
2678 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2679 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2680
2681 pub fn human_readable_names(&self) -> Vec<&'static str> {
2682 let mut options = vec![];
2683
2684 if self.contains(InlineAsmOptions::PURE) {
2685 options.push("pure");
2686 }
2687 if self.contains(InlineAsmOptions::NOMEM) {
2688 options.push("nomem");
2689 }
2690 if self.contains(InlineAsmOptions::READONLY) {
2691 options.push("readonly");
2692 }
2693 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2694 options.push("preserves_flags");
2695 }
2696 if self.contains(InlineAsmOptions::NORETURN) {
2697 options.push("noreturn");
2698 }
2699 if self.contains(InlineAsmOptions::NOSTACK) {
2700 options.push("nostack");
2701 }
2702 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2703 options.push("att_syntax");
2704 }
2705 if self.contains(InlineAsmOptions::RAW) {
2706 options.push("raw");
2707 }
2708 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2709 options.push("may_unwind");
2710 }
2711
2712 options
2713 }
2714}
2715
2716impl std::fmt::Debug for InlineAsmOptions {
2717 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2718 bitflags::parser::to_writer(self, f)
2719 }
2720}
2721
2722#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2723pub enum InlineAsmTemplatePiece {
2724 String(Cow<'static, str>),
2725 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2726}
2727
2728impl fmt::Display for InlineAsmTemplatePiece {
2729 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2730 match self {
2731 Self::String(s) => {
2732 for c in s.chars() {
2733 match c {
2734 '{' => f.write_str("{{")?,
2735 '}' => f.write_str("}}")?,
2736 _ => c.fmt(f)?,
2737 }
2738 }
2739 Ok(())
2740 }
2741 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2742 write!(f, "{{{operand_idx}:{modifier}}}")
2743 }
2744 Self::Placeholder { operand_idx, modifier: None, .. } => {
2745 write!(f, "{{{operand_idx}}}")
2746 }
2747 }
2748 }
2749}
2750
2751impl InlineAsmTemplatePiece {
2752 pub fn to_string(s: &[Self]) -> String {
2754 use fmt::Write;
2755 let mut out = String::new();
2756 for p in s.iter() {
2757 let _ = write!(out, "{p}");
2758 }
2759 out
2760 }
2761}
2762
2763#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2771pub struct InlineAsmSym {
2772 pub id: NodeId,
2773 pub qself: Option<Box<QSelf>>,
2774 pub path: Path,
2775}
2776
2777#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2781pub enum InlineAsmOperand {
2782 In {
2783 reg: InlineAsmRegOrRegClass,
2784 expr: Box<Expr>,
2785 },
2786 Out {
2787 reg: InlineAsmRegOrRegClass,
2788 late: bool,
2789 expr: Option<Box<Expr>>,
2790 },
2791 InOut {
2792 reg: InlineAsmRegOrRegClass,
2793 late: bool,
2794 expr: Box<Expr>,
2795 },
2796 SplitInOut {
2797 reg: InlineAsmRegOrRegClass,
2798 late: bool,
2799 in_expr: Box<Expr>,
2800 out_expr: Option<Box<Expr>>,
2801 },
2802 Const {
2803 anon_const: AnonConst,
2804 },
2805 Sym {
2806 sym: InlineAsmSym,
2807 },
2808 Label {
2809 block: Box<Block>,
2810 },
2811}
2812
2813impl InlineAsmOperand {
2814 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2815 match self {
2816 Self::In { reg, .. }
2817 | Self::Out { reg, .. }
2818 | Self::InOut { reg, .. }
2819 | Self::SplitInOut { reg, .. } => Some(reg),
2820 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2821 }
2822 }
2823}
2824
2825#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2826pub enum AsmMacro {
2827 Asm,
2829 GlobalAsm,
2831 NakedAsm,
2833}
2834
2835impl AsmMacro {
2836 pub const fn macro_name(self) -> &'static str {
2837 match self {
2838 AsmMacro::Asm => "asm",
2839 AsmMacro::GlobalAsm => "global_asm",
2840 AsmMacro::NakedAsm => "naked_asm",
2841 }
2842 }
2843
2844 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2845 match self {
2846 AsmMacro::Asm => true,
2847 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2848 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2849 }
2850 }
2851
2852 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2853 match self {
2854 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2855 AsmMacro::GlobalAsm => true,
2856 AsmMacro::NakedAsm => true,
2857 }
2858 }
2859}
2860
2861#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2865pub struct InlineAsm {
2866 pub asm_macro: AsmMacro,
2867 pub template: Vec<InlineAsmTemplatePiece>,
2868 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2869 pub operands: Vec<(InlineAsmOperand, Span)>,
2870 pub clobber_abis: Vec<(Symbol, Span)>,
2871 #[visitable(ignore)]
2872 pub options: InlineAsmOptions,
2873 pub line_spans: Vec<Span>,
2874}
2875
2876#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2880pub struct Param {
2881 pub attrs: AttrVec,
2882 pub ty: Box<Ty>,
2883 pub pat: Box<Pat>,
2884 pub id: NodeId,
2885 pub span: Span,
2886 pub is_placeholder: bool,
2887}
2888
2889#[derive(Clone, Encodable, Decodable, Debug)]
2893pub enum SelfKind {
2894 Value(Mutability),
2896 Region(Option<Lifetime>, Mutability),
2898 Pinned(Option<Lifetime>, Mutability),
2900 Explicit(Box<Ty>, Mutability),
2902}
2903
2904impl SelfKind {
2905 pub fn to_ref_suggestion(&self) -> String {
2906 match self {
2907 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2908 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2909 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2910 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2911 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2912 unreachable!("if we had an explicit self, we wouldn't be here")
2913 }
2914 }
2915 }
2916}
2917
2918pub type ExplicitSelf = Spanned<SelfKind>;
2919
2920impl Param {
2921 pub fn to_self(&self) -> Option<ExplicitSelf> {
2923 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2924 if ident.name == kw::SelfLower {
2925 return match self.ty.kind {
2926 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2927 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2928 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2929 }
2930 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2931 if ty.kind.is_implicit_self() =>
2932 {
2933 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2934 }
2935 _ => Some(respan(
2936 self.pat.span.to(self.ty.span),
2937 SelfKind::Explicit(self.ty.clone(), mutbl),
2938 )),
2939 };
2940 }
2941 }
2942 None
2943 }
2944
2945 pub fn is_self(&self) -> bool {
2947 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2948 ident.name == kw::SelfLower
2949 } else {
2950 false
2951 }
2952 }
2953
2954 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2956 let span = eself.span.to(eself_ident.span);
2957 let infer_ty = Box::new(Ty {
2958 id: DUMMY_NODE_ID,
2959 kind: TyKind::ImplicitSelf,
2960 span: eself_ident.span,
2961 tokens: None,
2962 });
2963 let (mutbl, ty) = match eself.node {
2964 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2965 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2966 SelfKind::Region(lt, mutbl) => (
2967 Mutability::Not,
2968 Box::new(Ty {
2969 id: DUMMY_NODE_ID,
2970 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2971 span,
2972 tokens: None,
2973 }),
2974 ),
2975 SelfKind::Pinned(lt, mutbl) => (
2976 mutbl,
2977 Box::new(Ty {
2978 id: DUMMY_NODE_ID,
2979 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2980 span,
2981 tokens: None,
2982 }),
2983 ),
2984 };
2985 Param {
2986 attrs,
2987 pat: Box::new(Pat {
2988 id: DUMMY_NODE_ID,
2989 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2990 span,
2991 tokens: None,
2992 }),
2993 span,
2994 ty,
2995 id: DUMMY_NODE_ID,
2996 is_placeholder: false,
2997 }
2998 }
2999}
3000
3001#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3008pub struct FnDecl {
3009 pub inputs: ThinVec<Param>,
3010 pub output: FnRetTy,
3011}
3012
3013impl FnDecl {
3014 pub fn has_self(&self) -> bool {
3015 self.inputs.get(0).is_some_and(Param::is_self)
3016 }
3017 pub fn c_variadic(&self) -> bool {
3018 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3019 }
3020}
3021
3022#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3024pub enum IsAuto {
3025 Yes,
3026 No,
3027}
3028
3029#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3031#[derive(HashStable_Generic, Walkable)]
3032pub enum Safety {
3033 Unsafe(Span),
3035 Safe(Span),
3037 Default,
3040}
3041
3042#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3048pub enum CoroutineKind {
3049 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3051 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3053 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3055}
3056
3057impl CoroutineKind {
3058 pub fn span(self) -> Span {
3059 match self {
3060 CoroutineKind::Async { span, .. } => span,
3061 CoroutineKind::Gen { span, .. } => span,
3062 CoroutineKind::AsyncGen { span, .. } => span,
3063 }
3064 }
3065
3066 pub fn as_str(self) -> &'static str {
3067 match self {
3068 CoroutineKind::Async { .. } => "async",
3069 CoroutineKind::Gen { .. } => "gen",
3070 CoroutineKind::AsyncGen { .. } => "async gen",
3071 }
3072 }
3073
3074 pub fn closure_id(self) -> NodeId {
3075 match self {
3076 CoroutineKind::Async { closure_id, .. }
3077 | CoroutineKind::Gen { closure_id, .. }
3078 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3079 }
3080 }
3081
3082 pub fn return_id(self) -> (NodeId, Span) {
3085 match self {
3086 CoroutineKind::Async { return_impl_trait_id, span, .. }
3087 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3088 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3089 (return_impl_trait_id, span)
3090 }
3091 }
3092 }
3093}
3094
3095#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3096#[derive(HashStable_Generic, Walkable)]
3097pub enum Const {
3098 Yes(Span),
3099 No,
3100}
3101
3102#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3105pub enum Defaultness {
3106 Default(Span),
3107 Final,
3108}
3109
3110#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3111pub enum ImplPolarity {
3112 Positive,
3114 Negative(Span),
3116}
3117
3118impl fmt::Debug for ImplPolarity {
3119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3120 match *self {
3121 ImplPolarity::Positive => "positive".fmt(f),
3122 ImplPolarity::Negative(_) => "negative".fmt(f),
3123 }
3124 }
3125}
3126
3127#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3129#[derive(HashStable_Generic, Walkable)]
3130pub enum BoundPolarity {
3131 Positive,
3133 Negative(Span),
3135 Maybe(Span),
3137}
3138
3139impl BoundPolarity {
3140 pub fn as_str(self) -> &'static str {
3141 match self {
3142 Self::Positive => "",
3143 Self::Negative(_) => "!",
3144 Self::Maybe(_) => "?",
3145 }
3146 }
3147}
3148
3149#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3151#[derive(HashStable_Generic, Walkable)]
3152pub enum BoundConstness {
3153 Never,
3155 Always(Span),
3157 Maybe(Span),
3159}
3160
3161impl BoundConstness {
3162 pub fn as_str(self) -> &'static str {
3163 match self {
3164 Self::Never => "",
3165 Self::Always(_) => "const",
3166 Self::Maybe(_) => "[const]",
3167 }
3168 }
3169}
3170
3171#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3173#[derive(HashStable_Generic, Walkable)]
3174pub enum BoundAsyncness {
3175 Normal,
3177 Async(Span),
3179}
3180
3181impl BoundAsyncness {
3182 pub fn as_str(self) -> &'static str {
3183 match self {
3184 Self::Normal => "",
3185 Self::Async(_) => "async",
3186 }
3187 }
3188}
3189
3190#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3191pub enum FnRetTy {
3192 Default(Span),
3197 Ty(Box<Ty>),
3199}
3200
3201impl FnRetTy {
3202 pub fn span(&self) -> Span {
3203 match self {
3204 &FnRetTy::Default(span) => span,
3205 FnRetTy::Ty(ty) => ty.span,
3206 }
3207 }
3208}
3209
3210#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3211pub enum Inline {
3212 Yes,
3213 No { had_parse_error: Result<(), ErrorGuaranteed> },
3214}
3215
3216#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3218pub enum ModKind {
3219 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3224 Unloaded,
3226}
3227
3228#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3229pub struct ModSpans {
3230 pub inner_span: Span,
3233 pub inject_use_span: Span,
3234}
3235
3236#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3240pub struct ForeignMod {
3241 pub extern_span: Span,
3243 pub safety: Safety,
3246 pub abi: Option<StrLit>,
3247 pub items: ThinVec<Box<ForeignItem>>,
3248}
3249
3250#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3251pub struct EnumDef {
3252 pub variants: ThinVec<Variant>,
3253}
3254
3255#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3257pub struct Variant {
3258 pub attrs: AttrVec,
3260 pub id: NodeId,
3262 pub span: Span,
3264 pub vis: Visibility,
3266 pub ident: Ident,
3268
3269 pub data: VariantData,
3271 pub disr_expr: Option<AnonConst>,
3273 pub is_placeholder: bool,
3275}
3276
3277#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3279pub enum UseTreeKind {
3280 Simple(Option<Ident>),
3282 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3291 Glob,
3293}
3294
3295#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3298pub struct UseTree {
3299 pub prefix: Path,
3300 pub kind: UseTreeKind,
3301 pub span: Span,
3302}
3303
3304impl UseTree {
3305 pub fn ident(&self) -> Ident {
3306 match self.kind {
3307 UseTreeKind::Simple(Some(rename)) => rename,
3308 UseTreeKind::Simple(None) => {
3309 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3310 }
3311 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3312 }
3313 }
3314}
3315
3316#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3320pub enum AttrStyle {
3321 Outer,
3322 Inner,
3323}
3324
3325pub type AttrVec = ThinVec<Attribute>;
3327
3328#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3330pub struct Attribute {
3331 pub kind: AttrKind,
3332 pub id: AttrId,
3333 pub style: AttrStyle,
3336 pub span: Span,
3337}
3338
3339#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3340pub enum AttrKind {
3341 Normal(Box<NormalAttr>),
3343
3344 DocComment(CommentKind, Symbol),
3348}
3349
3350#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3351pub struct NormalAttr {
3352 pub item: AttrItem,
3353 pub tokens: Option<LazyAttrTokenStream>,
3355}
3356
3357impl NormalAttr {
3358 pub fn from_ident(ident: Ident) -> Self {
3359 Self {
3360 item: AttrItem {
3361 unsafety: Safety::Default,
3362 path: Path::from_ident(ident),
3363 args: AttrArgs::Empty,
3364 tokens: None,
3365 },
3366 tokens: None,
3367 }
3368 }
3369}
3370
3371#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3372pub struct AttrItem {
3373 pub unsafety: Safety,
3374 pub path: Path,
3375 pub args: AttrArgs,
3376 pub tokens: Option<LazyAttrTokenStream>,
3378}
3379
3380impl AttrItem {
3381 pub fn is_valid_for_outer_style(&self) -> bool {
3382 self.path == sym::cfg_attr
3383 || self.path == sym::cfg
3384 || self.path == sym::forbid
3385 || self.path == sym::warn
3386 || self.path == sym::allow
3387 || self.path == sym::deny
3388 }
3389}
3390
3391#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3398pub struct TraitRef {
3399 pub path: Path,
3400 pub ref_id: NodeId,
3401}
3402
3403#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3405pub enum Parens {
3406 Yes,
3407 No,
3408}
3409
3410#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3411pub struct PolyTraitRef {
3412 pub bound_generic_params: ThinVec<GenericParam>,
3414
3415 pub modifiers: TraitBoundModifiers,
3417
3418 pub trait_ref: TraitRef,
3420
3421 pub span: Span,
3422
3423 pub parens: Parens,
3426}
3427
3428impl PolyTraitRef {
3429 pub fn new(
3430 generic_params: ThinVec<GenericParam>,
3431 path: Path,
3432 modifiers: TraitBoundModifiers,
3433 span: Span,
3434 parens: Parens,
3435 ) -> Self {
3436 PolyTraitRef {
3437 bound_generic_params: generic_params,
3438 modifiers,
3439 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3440 span,
3441 parens,
3442 }
3443 }
3444}
3445
3446#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3447pub struct Visibility {
3448 pub kind: VisibilityKind,
3449 pub span: Span,
3450 pub tokens: Option<LazyAttrTokenStream>,
3451}
3452
3453#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3454pub enum VisibilityKind {
3455 Public,
3456 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3457 Inherited,
3458}
3459
3460impl VisibilityKind {
3461 pub fn is_pub(&self) -> bool {
3462 matches!(self, VisibilityKind::Public)
3463 }
3464}
3465
3466#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3470pub struct FieldDef {
3471 pub attrs: AttrVec,
3472 pub id: NodeId,
3473 pub span: Span,
3474 pub vis: Visibility,
3475 pub safety: Safety,
3476 pub ident: Option<Ident>,
3477
3478 pub ty: Box<Ty>,
3479 pub default: Option<AnonConst>,
3480 pub is_placeholder: bool,
3481}
3482
3483#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3485pub enum Recovered {
3486 No,
3487 Yes(ErrorGuaranteed),
3488}
3489
3490#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3492pub enum VariantData {
3493 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3497 Tuple(ThinVec<FieldDef>, NodeId),
3501 Unit(NodeId),
3505}
3506
3507impl VariantData {
3508 pub fn fields(&self) -> &[FieldDef] {
3510 match self {
3511 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3512 _ => &[],
3513 }
3514 }
3515
3516 pub fn ctor_node_id(&self) -> Option<NodeId> {
3518 match *self {
3519 VariantData::Struct { .. } => None,
3520 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3521 }
3522 }
3523}
3524
3525#[derive(Clone, Encodable, Decodable, Debug)]
3527pub struct Item<K = ItemKind> {
3528 pub attrs: AttrVec,
3529 pub id: NodeId,
3530 pub span: Span,
3531 pub vis: Visibility,
3532
3533 pub kind: K,
3534
3535 pub tokens: Option<LazyAttrTokenStream>,
3543}
3544
3545impl Item {
3546 pub fn span_with_attributes(&self) -> Span {
3548 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3549 }
3550
3551 pub fn opt_generics(&self) -> Option<&Generics> {
3552 match &self.kind {
3553 ItemKind::ExternCrate(..)
3554 | ItemKind::Use(_)
3555 | ItemKind::Mod(..)
3556 | ItemKind::ForeignMod(_)
3557 | ItemKind::GlobalAsm(_)
3558 | ItemKind::MacCall(_)
3559 | ItemKind::Delegation(_)
3560 | ItemKind::DelegationMac(_)
3561 | ItemKind::MacroDef(..) => None,
3562 ItemKind::Static(_) => None,
3563 ItemKind::Const(i) => Some(&i.generics),
3564 ItemKind::Fn(i) => Some(&i.generics),
3565 ItemKind::TyAlias(i) => Some(&i.generics),
3566 ItemKind::TraitAlias(i) => Some(&i.generics),
3567
3568 ItemKind::Enum(_, generics, _)
3569 | ItemKind::Struct(_, generics, _)
3570 | ItemKind::Union(_, generics, _) => Some(&generics),
3571 ItemKind::Trait(i) => Some(&i.generics),
3572 ItemKind::Impl(i) => Some(&i.generics),
3573 }
3574 }
3575}
3576
3577#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3579pub enum Extern {
3580 None,
3584 Implicit(Span),
3590 Explicit(StrLit, Span),
3594}
3595
3596impl Extern {
3597 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3598 match abi {
3599 Some(name) => Extern::Explicit(name, span),
3600 None => Extern::Implicit(span),
3601 }
3602 }
3603
3604 pub fn span(self) -> Option<Span> {
3605 match self {
3606 Extern::None => None,
3607 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3608 }
3609 }
3610}
3611
3612#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3617pub struct FnHeader {
3618 pub constness: Const,
3620 pub coroutine_kind: Option<CoroutineKind>,
3622 pub safety: Safety,
3624 pub ext: Extern,
3626}
3627
3628impl FnHeader {
3629 pub fn has_qualifiers(&self) -> bool {
3631 let Self { safety, coroutine_kind, constness, ext } = self;
3632 matches!(safety, Safety::Unsafe(_))
3633 || coroutine_kind.is_some()
3634 || matches!(constness, Const::Yes(_))
3635 || !matches!(ext, Extern::None)
3636 }
3637}
3638
3639impl Default for FnHeader {
3640 fn default() -> FnHeader {
3641 FnHeader {
3642 safety: Safety::Default,
3643 coroutine_kind: None,
3644 constness: Const::No,
3645 ext: Extern::None,
3646 }
3647 }
3648}
3649
3650#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3651pub struct TraitAlias {
3652 pub constness: Const,
3653 pub ident: Ident,
3654 pub generics: Generics,
3655 #[visitable(extra = BoundKind::Bound)]
3656 pub bounds: GenericBounds,
3657}
3658
3659#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3660pub struct Trait {
3661 pub constness: Const,
3662 pub safety: Safety,
3663 pub is_auto: IsAuto,
3664 pub ident: Ident,
3665 pub generics: Generics,
3666 #[visitable(extra = BoundKind::SuperTraits)]
3667 pub bounds: GenericBounds,
3668 #[visitable(extra = AssocCtxt::Trait)]
3669 pub items: ThinVec<Box<AssocItem>>,
3670}
3671
3672#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3673pub struct TyAlias {
3674 pub defaultness: Defaultness,
3675 pub ident: Ident,
3676 pub generics: Generics,
3677 pub after_where_clause: WhereClause,
3692 #[visitable(extra = BoundKind::Bound)]
3693 pub bounds: GenericBounds,
3694 pub ty: Option<Box<Ty>>,
3695}
3696
3697#[derive(Clone, Encodable, Decodable, Debug)]
3698pub struct Impl {
3699 pub generics: Generics,
3700 pub constness: Const,
3701 pub of_trait: Option<Box<TraitImplHeader>>,
3702 pub self_ty: Box<Ty>,
3703 pub items: ThinVec<Box<AssocItem>>,
3704}
3705
3706#[derive(Clone, Encodable, Decodable, Debug)]
3707pub struct TraitImplHeader {
3708 pub defaultness: Defaultness,
3709 pub safety: Safety,
3710 pub polarity: ImplPolarity,
3711 pub trait_ref: TraitRef,
3712}
3713
3714#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3715pub struct FnContract {
3716 pub declarations: ThinVec<Stmt>,
3719 pub requires: Option<Box<Expr>>,
3720 pub ensures: Option<Box<Expr>>,
3721}
3722
3723#[derive(Clone, Encodable, Decodable, Debug)]
3724pub struct Fn {
3725 pub defaultness: Defaultness,
3726 pub ident: Ident,
3727 pub generics: Generics,
3728 pub sig: FnSig,
3729 pub contract: Option<Box<FnContract>>,
3730 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3731 pub body: Option<Box<Block>>,
3732}
3733
3734#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3735pub struct Delegation {
3736 pub id: NodeId,
3738 pub qself: Option<Box<QSelf>>,
3739 pub path: Path,
3740 pub ident: Ident,
3741 pub rename: Option<Ident>,
3742 pub body: Option<Box<Block>>,
3743 pub from_glob: bool,
3745}
3746
3747#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3748pub struct DelegationMac {
3749 pub qself: Option<Box<QSelf>>,
3750 pub prefix: Path,
3751 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3753 pub body: Option<Box<Block>>,
3754}
3755
3756#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3757pub struct StaticItem {
3758 pub ident: Ident,
3759 pub ty: Box<Ty>,
3760 pub safety: Safety,
3761 pub mutability: Mutability,
3762 pub expr: Option<Box<Expr>>,
3763 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3764}
3765
3766#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3767pub struct ConstItem {
3768 pub defaultness: Defaultness,
3769 pub ident: Ident,
3770 pub generics: Generics,
3771 pub ty: Box<Ty>,
3772 pub rhs: Option<ConstItemRhs>,
3773 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3774}
3775
3776#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3777pub enum ConstItemRhs {
3778 TypeConst(AnonConst),
3779 Body(Box<Expr>),
3780}
3781
3782impl ConstItemRhs {
3783 pub fn span(&self) -> Span {
3784 self.expr().span
3785 }
3786
3787 pub fn expr(&self) -> &Expr {
3788 match self {
3789 ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
3790 ConstItemRhs::Body(expr) => expr,
3791 }
3792 }
3793}
3794
3795#[derive(Clone, Encodable, Decodable, Debug)]
3797pub enum ItemKind {
3798 ExternCrate(Option<Symbol>, Ident),
3802 Use(UseTree),
3806 Static(Box<StaticItem>),
3810 Const(Box<ConstItem>),
3814 Fn(Box<Fn>),
3818 Mod(Safety, Ident, ModKind),
3824 ForeignMod(ForeignMod),
3828 GlobalAsm(Box<InlineAsm>),
3830 TyAlias(Box<TyAlias>),
3834 Enum(Ident, Generics, EnumDef),
3838 Struct(Ident, Generics, VariantData),
3842 Union(Ident, Generics, VariantData),
3846 Trait(Box<Trait>),
3850 TraitAlias(Box<TraitAlias>),
3854 Impl(Impl),
3858 MacCall(Box<MacCall>),
3862 MacroDef(Ident, MacroDef),
3864 Delegation(Box<Delegation>),
3868 DelegationMac(Box<DelegationMac>),
3871}
3872
3873impl ItemKind {
3874 pub fn ident(&self) -> Option<Ident> {
3875 match *self {
3876 ItemKind::ExternCrate(_, ident)
3877 | ItemKind::Static(box StaticItem { ident, .. })
3878 | ItemKind::Const(box ConstItem { ident, .. })
3879 | ItemKind::Fn(box Fn { ident, .. })
3880 | ItemKind::Mod(_, ident, _)
3881 | ItemKind::TyAlias(box TyAlias { ident, .. })
3882 | ItemKind::Enum(ident, ..)
3883 | ItemKind::Struct(ident, ..)
3884 | ItemKind::Union(ident, ..)
3885 | ItemKind::Trait(box Trait { ident, .. })
3886 | ItemKind::TraitAlias(box TraitAlias { ident, .. })
3887 | ItemKind::MacroDef(ident, _)
3888 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3889
3890 ItemKind::Use(_)
3891 | ItemKind::ForeignMod(_)
3892 | ItemKind::GlobalAsm(_)
3893 | ItemKind::Impl(_)
3894 | ItemKind::MacCall(_)
3895 | ItemKind::DelegationMac(_) => None,
3896 }
3897 }
3898
3899 pub fn article(&self) -> &'static str {
3901 use ItemKind::*;
3902 match self {
3903 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3904 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3905 | Delegation(..) | DelegationMac(..) => "a",
3906 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3907 }
3908 }
3909
3910 pub fn descr(&self) -> &'static str {
3911 match self {
3912 ItemKind::ExternCrate(..) => "extern crate",
3913 ItemKind::Use(..) => "`use` import",
3914 ItemKind::Static(..) => "static item",
3915 ItemKind::Const(..) => "constant item",
3916 ItemKind::Fn(..) => "function",
3917 ItemKind::Mod(..) => "module",
3918 ItemKind::ForeignMod(..) => "extern block",
3919 ItemKind::GlobalAsm(..) => "global asm item",
3920 ItemKind::TyAlias(..) => "type alias",
3921 ItemKind::Enum(..) => "enum",
3922 ItemKind::Struct(..) => "struct",
3923 ItemKind::Union(..) => "union",
3924 ItemKind::Trait(..) => "trait",
3925 ItemKind::TraitAlias(..) => "trait alias",
3926 ItemKind::MacCall(..) => "item macro invocation",
3927 ItemKind::MacroDef(..) => "macro definition",
3928 ItemKind::Impl { .. } => "implementation",
3929 ItemKind::Delegation(..) => "delegated function",
3930 ItemKind::DelegationMac(..) => "delegation",
3931 }
3932 }
3933
3934 pub fn generics(&self) -> Option<&Generics> {
3935 match self {
3936 Self::Fn(box Fn { generics, .. })
3937 | Self::TyAlias(box TyAlias { generics, .. })
3938 | Self::Const(box ConstItem { generics, .. })
3939 | Self::Enum(_, generics, _)
3940 | Self::Struct(_, generics, _)
3941 | Self::Union(_, generics, _)
3942 | Self::Trait(box Trait { generics, .. })
3943 | Self::TraitAlias(box TraitAlias { generics, .. })
3944 | Self::Impl(Impl { generics, .. }) => Some(generics),
3945 _ => None,
3946 }
3947 }
3948}
3949
3950pub type AssocItem = Item<AssocItemKind>;
3953
3954#[derive(Clone, Encodable, Decodable, Debug)]
3962pub enum AssocItemKind {
3963 Const(Box<ConstItem>),
3966 Fn(Box<Fn>),
3968 Type(Box<TyAlias>),
3970 MacCall(Box<MacCall>),
3972 Delegation(Box<Delegation>),
3974 DelegationMac(Box<DelegationMac>),
3976}
3977
3978impl AssocItemKind {
3979 pub fn ident(&self) -> Option<Ident> {
3980 match *self {
3981 AssocItemKind::Const(box ConstItem { ident, .. })
3982 | AssocItemKind::Fn(box Fn { ident, .. })
3983 | AssocItemKind::Type(box TyAlias { ident, .. })
3984 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3985
3986 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3987 }
3988 }
3989
3990 pub fn defaultness(&self) -> Defaultness {
3991 match *self {
3992 Self::Const(box ConstItem { defaultness, .. })
3993 | Self::Fn(box Fn { defaultness, .. })
3994 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3995 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3996 Defaultness::Final
3997 }
3998 }
3999 }
4000}
4001
4002impl From<AssocItemKind> for ItemKind {
4003 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4004 match assoc_item_kind {
4005 AssocItemKind::Const(item) => ItemKind::Const(item),
4006 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4007 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4008 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4009 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4010 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4011 }
4012 }
4013}
4014
4015impl TryFrom<ItemKind> for AssocItemKind {
4016 type Error = ItemKind;
4017
4018 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4019 Ok(match item_kind {
4020 ItemKind::Const(item) => AssocItemKind::Const(item),
4021 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4022 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4023 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4024 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4025 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4026 _ => return Err(item_kind),
4027 })
4028 }
4029}
4030
4031#[derive(Clone, Encodable, Decodable, Debug)]
4033pub enum ForeignItemKind {
4034 Static(Box<StaticItem>),
4036 Fn(Box<Fn>),
4038 TyAlias(Box<TyAlias>),
4040 MacCall(Box<MacCall>),
4042}
4043
4044impl ForeignItemKind {
4045 pub fn ident(&self) -> Option<Ident> {
4046 match *self {
4047 ForeignItemKind::Static(box StaticItem { ident, .. })
4048 | ForeignItemKind::Fn(box Fn { ident, .. })
4049 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4050
4051 ForeignItemKind::MacCall(_) => None,
4052 }
4053 }
4054}
4055
4056impl From<ForeignItemKind> for ItemKind {
4057 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4058 match foreign_item_kind {
4059 ForeignItemKind::Static(box static_foreign_item) => {
4060 ItemKind::Static(Box::new(static_foreign_item))
4061 }
4062 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4063 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4064 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4065 }
4066 }
4067}
4068
4069impl TryFrom<ItemKind> for ForeignItemKind {
4070 type Error = ItemKind;
4071
4072 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4073 Ok(match item_kind {
4074 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4075 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4076 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4077 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4078 _ => return Err(item_kind),
4079 })
4080 }
4081}
4082
4083pub type ForeignItem = Item<ForeignItemKind>;
4084
4085#[cfg(target_pointer_width = "64")]
4087mod size_asserts {
4088 use rustc_data_structures::static_assert_size;
4089
4090 use super::*;
4091 static_assert_size!(AssocItem, 80);
4093 static_assert_size!(AssocItemKind, 16);
4094 static_assert_size!(Attribute, 32);
4095 static_assert_size!(Block, 32);
4096 static_assert_size!(Expr, 72);
4097 static_assert_size!(ExprKind, 40);
4098 static_assert_size!(Fn, 184);
4099 static_assert_size!(ForeignItem, 80);
4100 static_assert_size!(ForeignItemKind, 16);
4101 static_assert_size!(GenericArg, 24);
4102 static_assert_size!(GenericBound, 88);
4103 static_assert_size!(Generics, 40);
4104 static_assert_size!(Impl, 80);
4105 static_assert_size!(Item, 152);
4106 static_assert_size!(ItemKind, 88);
4107 static_assert_size!(LitKind, 24);
4108 static_assert_size!(Local, 96);
4109 static_assert_size!(MetaItemLit, 40);
4110 static_assert_size!(Param, 40);
4111 static_assert_size!(Pat, 80);
4112 static_assert_size!(PatKind, 56);
4113 static_assert_size!(Path, 24);
4114 static_assert_size!(PathSegment, 24);
4115 static_assert_size!(Stmt, 32);
4116 static_assert_size!(StmtKind, 16);
4117 static_assert_size!(TraitImplHeader, 72);
4118 static_assert_size!(Ty, 64);
4119 static_assert_size!(TyKind, 40);
4120 }