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, Encodable, Decodable, Debug, Walkable)]
861pub enum RangeEnd {
862 Included(RangeSyntax),
864 Excluded,
866}
867
868#[derive(Clone, 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, 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 Typeof(AnonConst),
2518 Infer,
2521 ImplicitSelf,
2523 MacCall(Box<MacCall>),
2525 CVarArgs,
2527 Pat(Box<Ty>, Box<TyPat>),
2530 Dummy,
2532 Err(ErrorGuaranteed),
2534}
2535
2536impl TyKind {
2537 pub fn is_implicit_self(&self) -> bool {
2538 matches!(self, TyKind::ImplicitSelf)
2539 }
2540
2541 pub fn is_unit(&self) -> bool {
2542 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2543 }
2544
2545 pub fn is_simple_path(&self) -> Option<Symbol> {
2546 if let TyKind::Path(None, Path { segments, .. }) = &self
2547 && let [segment] = &segments[..]
2548 && segment.args.is_none()
2549 {
2550 Some(segment.ident.name)
2551 } else {
2552 None
2553 }
2554 }
2555
2556 pub fn maybe_scalar(&self) -> bool {
2564 let Some(ty_sym) = self.is_simple_path() else {
2565 return self.is_unit();
2567 };
2568 matches!(
2569 ty_sym,
2570 sym::i8
2571 | sym::i16
2572 | sym::i32
2573 | sym::i64
2574 | sym::i128
2575 | sym::u8
2576 | sym::u16
2577 | sym::u32
2578 | sym::u64
2579 | sym::u128
2580 | sym::f16
2581 | sym::f32
2582 | sym::f64
2583 | sym::f128
2584 | sym::char
2585 | sym::bool
2586 )
2587 }
2588}
2589
2590#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2592pub struct TyPat {
2593 pub id: NodeId,
2594 pub kind: TyPatKind,
2595 pub span: Span,
2596 pub tokens: Option<LazyAttrTokenStream>,
2597}
2598
2599#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2603pub enum TyPatKind {
2604 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2606
2607 NotNull,
2609
2610 Or(ThinVec<TyPat>),
2611
2612 Err(ErrorGuaranteed),
2614}
2615
2616#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2618#[repr(u8)]
2619pub enum TraitObjectSyntax {
2620 Dyn = 0,
2622 None = 1,
2623}
2624
2625unsafe impl Tag for TraitObjectSyntax {
2629 const BITS: u32 = 2;
2630
2631 fn into_usize(self) -> usize {
2632 self as u8 as usize
2633 }
2634
2635 unsafe fn from_usize(tag: usize) -> Self {
2636 match tag {
2637 0 => TraitObjectSyntax::Dyn,
2638 1 => TraitObjectSyntax::None,
2639 _ => unreachable!(),
2640 }
2641 }
2642}
2643
2644#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2645pub enum PreciseCapturingArg {
2646 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2648 Arg(Path, NodeId),
2650}
2651
2652#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2656pub enum InlineAsmRegOrRegClass {
2657 Reg(Symbol),
2658 RegClass(Symbol),
2659}
2660
2661#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2662pub struct InlineAsmOptions(u16);
2663bitflags::bitflags! {
2664 impl InlineAsmOptions: u16 {
2665 const PURE = 1 << 0;
2666 const NOMEM = 1 << 1;
2667 const READONLY = 1 << 2;
2668 const PRESERVES_FLAGS = 1 << 3;
2669 const NORETURN = 1 << 4;
2670 const NOSTACK = 1 << 5;
2671 const ATT_SYNTAX = 1 << 6;
2672 const RAW = 1 << 7;
2673 const MAY_UNWIND = 1 << 8;
2674 }
2675}
2676
2677impl InlineAsmOptions {
2678 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2679
2680 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2681 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2682
2683 pub fn human_readable_names(&self) -> Vec<&'static str> {
2684 let mut options = vec![];
2685
2686 if self.contains(InlineAsmOptions::PURE) {
2687 options.push("pure");
2688 }
2689 if self.contains(InlineAsmOptions::NOMEM) {
2690 options.push("nomem");
2691 }
2692 if self.contains(InlineAsmOptions::READONLY) {
2693 options.push("readonly");
2694 }
2695 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2696 options.push("preserves_flags");
2697 }
2698 if self.contains(InlineAsmOptions::NORETURN) {
2699 options.push("noreturn");
2700 }
2701 if self.contains(InlineAsmOptions::NOSTACK) {
2702 options.push("nostack");
2703 }
2704 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2705 options.push("att_syntax");
2706 }
2707 if self.contains(InlineAsmOptions::RAW) {
2708 options.push("raw");
2709 }
2710 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2711 options.push("may_unwind");
2712 }
2713
2714 options
2715 }
2716}
2717
2718impl std::fmt::Debug for InlineAsmOptions {
2719 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2720 bitflags::parser::to_writer(self, f)
2721 }
2722}
2723
2724#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2725pub enum InlineAsmTemplatePiece {
2726 String(Cow<'static, str>),
2727 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2728}
2729
2730impl fmt::Display for InlineAsmTemplatePiece {
2731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2732 match self {
2733 Self::String(s) => {
2734 for c in s.chars() {
2735 match c {
2736 '{' => f.write_str("{{")?,
2737 '}' => f.write_str("}}")?,
2738 _ => c.fmt(f)?,
2739 }
2740 }
2741 Ok(())
2742 }
2743 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2744 write!(f, "{{{operand_idx}:{modifier}}}")
2745 }
2746 Self::Placeholder { operand_idx, modifier: None, .. } => {
2747 write!(f, "{{{operand_idx}}}")
2748 }
2749 }
2750 }
2751}
2752
2753impl InlineAsmTemplatePiece {
2754 pub fn to_string(s: &[Self]) -> String {
2756 use fmt::Write;
2757 let mut out = String::new();
2758 for p in s.iter() {
2759 let _ = write!(out, "{p}");
2760 }
2761 out
2762 }
2763}
2764
2765#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2773pub struct InlineAsmSym {
2774 pub id: NodeId,
2775 pub qself: Option<Box<QSelf>>,
2776 pub path: Path,
2777}
2778
2779#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2783pub enum InlineAsmOperand {
2784 In {
2785 reg: InlineAsmRegOrRegClass,
2786 expr: Box<Expr>,
2787 },
2788 Out {
2789 reg: InlineAsmRegOrRegClass,
2790 late: bool,
2791 expr: Option<Box<Expr>>,
2792 },
2793 InOut {
2794 reg: InlineAsmRegOrRegClass,
2795 late: bool,
2796 expr: Box<Expr>,
2797 },
2798 SplitInOut {
2799 reg: InlineAsmRegOrRegClass,
2800 late: bool,
2801 in_expr: Box<Expr>,
2802 out_expr: Option<Box<Expr>>,
2803 },
2804 Const {
2805 anon_const: AnonConst,
2806 },
2807 Sym {
2808 sym: InlineAsmSym,
2809 },
2810 Label {
2811 block: Box<Block>,
2812 },
2813}
2814
2815impl InlineAsmOperand {
2816 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2817 match self {
2818 Self::In { reg, .. }
2819 | Self::Out { reg, .. }
2820 | Self::InOut { reg, .. }
2821 | Self::SplitInOut { reg, .. } => Some(reg),
2822 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2823 }
2824 }
2825}
2826
2827#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2828pub enum AsmMacro {
2829 Asm,
2831 GlobalAsm,
2833 NakedAsm,
2835}
2836
2837impl AsmMacro {
2838 pub const fn macro_name(self) -> &'static str {
2839 match self {
2840 AsmMacro::Asm => "asm",
2841 AsmMacro::GlobalAsm => "global_asm",
2842 AsmMacro::NakedAsm => "naked_asm",
2843 }
2844 }
2845
2846 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2847 match self {
2848 AsmMacro::Asm => true,
2849 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2850 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2851 }
2852 }
2853
2854 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2855 match self {
2856 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2857 AsmMacro::GlobalAsm => true,
2858 AsmMacro::NakedAsm => true,
2859 }
2860 }
2861}
2862
2863#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2867pub struct InlineAsm {
2868 pub asm_macro: AsmMacro,
2869 pub template: Vec<InlineAsmTemplatePiece>,
2870 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2871 pub operands: Vec<(InlineAsmOperand, Span)>,
2872 pub clobber_abis: Vec<(Symbol, Span)>,
2873 #[visitable(ignore)]
2874 pub options: InlineAsmOptions,
2875 pub line_spans: Vec<Span>,
2876}
2877
2878#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2882pub struct Param {
2883 pub attrs: AttrVec,
2884 pub ty: Box<Ty>,
2885 pub pat: Box<Pat>,
2886 pub id: NodeId,
2887 pub span: Span,
2888 pub is_placeholder: bool,
2889}
2890
2891#[derive(Clone, Encodable, Decodable, Debug)]
2895pub enum SelfKind {
2896 Value(Mutability),
2898 Region(Option<Lifetime>, Mutability),
2900 Pinned(Option<Lifetime>, Mutability),
2902 Explicit(Box<Ty>, Mutability),
2904}
2905
2906impl SelfKind {
2907 pub fn to_ref_suggestion(&self) -> String {
2908 match self {
2909 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2910 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2911 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2912 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2913 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2914 unreachable!("if we had an explicit self, we wouldn't be here")
2915 }
2916 }
2917 }
2918}
2919
2920pub type ExplicitSelf = Spanned<SelfKind>;
2921
2922impl Param {
2923 pub fn to_self(&self) -> Option<ExplicitSelf> {
2925 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2926 if ident.name == kw::SelfLower {
2927 return match self.ty.kind {
2928 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2929 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2930 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2931 }
2932 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2933 if ty.kind.is_implicit_self() =>
2934 {
2935 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2936 }
2937 _ => Some(respan(
2938 self.pat.span.to(self.ty.span),
2939 SelfKind::Explicit(self.ty.clone(), mutbl),
2940 )),
2941 };
2942 }
2943 }
2944 None
2945 }
2946
2947 pub fn is_self(&self) -> bool {
2949 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2950 ident.name == kw::SelfLower
2951 } else {
2952 false
2953 }
2954 }
2955
2956 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2958 let span = eself.span.to(eself_ident.span);
2959 let infer_ty = Box::new(Ty {
2960 id: DUMMY_NODE_ID,
2961 kind: TyKind::ImplicitSelf,
2962 span: eself_ident.span,
2963 tokens: None,
2964 });
2965 let (mutbl, ty) = match eself.node {
2966 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2967 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2968 SelfKind::Region(lt, mutbl) => (
2969 Mutability::Not,
2970 Box::new(Ty {
2971 id: DUMMY_NODE_ID,
2972 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2973 span,
2974 tokens: None,
2975 }),
2976 ),
2977 SelfKind::Pinned(lt, mutbl) => (
2978 mutbl,
2979 Box::new(Ty {
2980 id: DUMMY_NODE_ID,
2981 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2982 span,
2983 tokens: None,
2984 }),
2985 ),
2986 };
2987 Param {
2988 attrs,
2989 pat: Box::new(Pat {
2990 id: DUMMY_NODE_ID,
2991 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2992 span,
2993 tokens: None,
2994 }),
2995 span,
2996 ty,
2997 id: DUMMY_NODE_ID,
2998 is_placeholder: false,
2999 }
3000 }
3001}
3002
3003#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3010pub struct FnDecl {
3011 pub inputs: ThinVec<Param>,
3012 pub output: FnRetTy,
3013}
3014
3015impl FnDecl {
3016 pub fn has_self(&self) -> bool {
3017 self.inputs.get(0).is_some_and(Param::is_self)
3018 }
3019 pub fn c_variadic(&self) -> bool {
3020 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3021 }
3022}
3023
3024#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3026pub enum IsAuto {
3027 Yes,
3028 No,
3029}
3030
3031#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3033#[derive(HashStable_Generic, Walkable)]
3034pub enum Safety {
3035 Unsafe(Span),
3037 Safe(Span),
3039 Default,
3042}
3043
3044#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3050pub enum CoroutineKind {
3051 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3053 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3055 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3057}
3058
3059impl CoroutineKind {
3060 pub fn span(self) -> Span {
3061 match self {
3062 CoroutineKind::Async { span, .. } => span,
3063 CoroutineKind::Gen { span, .. } => span,
3064 CoroutineKind::AsyncGen { span, .. } => span,
3065 }
3066 }
3067
3068 pub fn as_str(self) -> &'static str {
3069 match self {
3070 CoroutineKind::Async { .. } => "async",
3071 CoroutineKind::Gen { .. } => "gen",
3072 CoroutineKind::AsyncGen { .. } => "async gen",
3073 }
3074 }
3075
3076 pub fn closure_id(self) -> NodeId {
3077 match self {
3078 CoroutineKind::Async { closure_id, .. }
3079 | CoroutineKind::Gen { closure_id, .. }
3080 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3081 }
3082 }
3083
3084 pub fn return_id(self) -> (NodeId, Span) {
3087 match self {
3088 CoroutineKind::Async { return_impl_trait_id, span, .. }
3089 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3090 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3091 (return_impl_trait_id, span)
3092 }
3093 }
3094 }
3095}
3096
3097#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3098#[derive(HashStable_Generic, Walkable)]
3099pub enum Const {
3100 Yes(Span),
3101 No,
3102}
3103
3104#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3107pub enum Defaultness {
3108 Default(Span),
3109 Final,
3110}
3111
3112#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3113pub enum ImplPolarity {
3114 Positive,
3116 Negative(Span),
3118}
3119
3120impl fmt::Debug for ImplPolarity {
3121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3122 match *self {
3123 ImplPolarity::Positive => "positive".fmt(f),
3124 ImplPolarity::Negative(_) => "negative".fmt(f),
3125 }
3126 }
3127}
3128
3129#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3131#[derive(HashStable_Generic, Walkable)]
3132pub enum BoundPolarity {
3133 Positive,
3135 Negative(Span),
3137 Maybe(Span),
3139}
3140
3141impl BoundPolarity {
3142 pub fn as_str(self) -> &'static str {
3143 match self {
3144 Self::Positive => "",
3145 Self::Negative(_) => "!",
3146 Self::Maybe(_) => "?",
3147 }
3148 }
3149}
3150
3151#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3153#[derive(HashStable_Generic, Walkable)]
3154pub enum BoundConstness {
3155 Never,
3157 Always(Span),
3159 Maybe(Span),
3161}
3162
3163impl BoundConstness {
3164 pub fn as_str(self) -> &'static str {
3165 match self {
3166 Self::Never => "",
3167 Self::Always(_) => "const",
3168 Self::Maybe(_) => "[const]",
3169 }
3170 }
3171}
3172
3173#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3175#[derive(HashStable_Generic, Walkable)]
3176pub enum BoundAsyncness {
3177 Normal,
3179 Async(Span),
3181}
3182
3183impl BoundAsyncness {
3184 pub fn as_str(self) -> &'static str {
3185 match self {
3186 Self::Normal => "",
3187 Self::Async(_) => "async",
3188 }
3189 }
3190}
3191
3192#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3193pub enum FnRetTy {
3194 Default(Span),
3199 Ty(Box<Ty>),
3201}
3202
3203impl FnRetTy {
3204 pub fn span(&self) -> Span {
3205 match self {
3206 &FnRetTy::Default(span) => span,
3207 FnRetTy::Ty(ty) => ty.span,
3208 }
3209 }
3210}
3211
3212#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3213pub enum Inline {
3214 Yes,
3215 No { had_parse_error: Result<(), ErrorGuaranteed> },
3216}
3217
3218#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3220pub enum ModKind {
3221 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3226 Unloaded,
3228}
3229
3230#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3231pub struct ModSpans {
3232 pub inner_span: Span,
3235 pub inject_use_span: Span,
3236}
3237
3238#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3242pub struct ForeignMod {
3243 pub extern_span: Span,
3245 pub safety: Safety,
3248 pub abi: Option<StrLit>,
3249 pub items: ThinVec<Box<ForeignItem>>,
3250}
3251
3252#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3253pub struct EnumDef {
3254 pub variants: ThinVec<Variant>,
3255}
3256
3257#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3259pub struct Variant {
3260 pub attrs: AttrVec,
3262 pub id: NodeId,
3264 pub span: Span,
3266 pub vis: Visibility,
3268 pub ident: Ident,
3270
3271 pub data: VariantData,
3273 pub disr_expr: Option<AnonConst>,
3275 pub is_placeholder: bool,
3277}
3278
3279#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3281pub enum UseTreeKind {
3282 Simple(Option<Ident>),
3284 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3293 Glob,
3295}
3296
3297#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3300pub struct UseTree {
3301 pub prefix: Path,
3302 pub kind: UseTreeKind,
3303 pub span: Span,
3304}
3305
3306impl UseTree {
3307 pub fn ident(&self) -> Ident {
3308 match self.kind {
3309 UseTreeKind::Simple(Some(rename)) => rename,
3310 UseTreeKind::Simple(None) => {
3311 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3312 }
3313 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3314 }
3315 }
3316}
3317
3318#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3322pub enum AttrStyle {
3323 Outer,
3324 Inner,
3325}
3326
3327pub type AttrVec = ThinVec<Attribute>;
3329
3330#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3332pub struct Attribute {
3333 pub kind: AttrKind,
3334 pub id: AttrId,
3335 pub style: AttrStyle,
3338 pub span: Span,
3339}
3340
3341#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3342pub enum AttrKind {
3343 Normal(Box<NormalAttr>),
3345
3346 DocComment(CommentKind, Symbol),
3350}
3351
3352#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3353pub struct NormalAttr {
3354 pub item: AttrItem,
3355 pub tokens: Option<LazyAttrTokenStream>,
3357}
3358
3359impl NormalAttr {
3360 pub fn from_ident(ident: Ident) -> Self {
3361 Self {
3362 item: AttrItem {
3363 unsafety: Safety::Default,
3364 path: Path::from_ident(ident),
3365 args: AttrArgs::Empty,
3366 tokens: None,
3367 },
3368 tokens: None,
3369 }
3370 }
3371}
3372
3373#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3374pub struct AttrItem {
3375 pub unsafety: Safety,
3376 pub path: Path,
3377 pub args: AttrArgs,
3378 pub tokens: Option<LazyAttrTokenStream>,
3380}
3381
3382impl AttrItem {
3383 pub fn is_valid_for_outer_style(&self) -> bool {
3384 self.path == sym::cfg_attr
3385 || self.path == sym::cfg
3386 || self.path == sym::forbid
3387 || self.path == sym::warn
3388 || self.path == sym::allow
3389 || self.path == sym::deny
3390 }
3391}
3392
3393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3400pub struct TraitRef {
3401 pub path: Path,
3402 pub ref_id: NodeId,
3403}
3404
3405#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3407pub enum Parens {
3408 Yes,
3409 No,
3410}
3411
3412#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3413pub struct PolyTraitRef {
3414 pub bound_generic_params: ThinVec<GenericParam>,
3416
3417 pub modifiers: TraitBoundModifiers,
3419
3420 pub trait_ref: TraitRef,
3422
3423 pub span: Span,
3424
3425 pub parens: Parens,
3428}
3429
3430impl PolyTraitRef {
3431 pub fn new(
3432 generic_params: ThinVec<GenericParam>,
3433 path: Path,
3434 modifiers: TraitBoundModifiers,
3435 span: Span,
3436 parens: Parens,
3437 ) -> Self {
3438 PolyTraitRef {
3439 bound_generic_params: generic_params,
3440 modifiers,
3441 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3442 span,
3443 parens,
3444 }
3445 }
3446}
3447
3448#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3449pub struct Visibility {
3450 pub kind: VisibilityKind,
3451 pub span: Span,
3452 pub tokens: Option<LazyAttrTokenStream>,
3453}
3454
3455#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3456pub enum VisibilityKind {
3457 Public,
3458 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3459 Inherited,
3460}
3461
3462impl VisibilityKind {
3463 pub fn is_pub(&self) -> bool {
3464 matches!(self, VisibilityKind::Public)
3465 }
3466}
3467
3468#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3472pub struct FieldDef {
3473 pub attrs: AttrVec,
3474 pub id: NodeId,
3475 pub span: Span,
3476 pub vis: Visibility,
3477 pub safety: Safety,
3478 pub ident: Option<Ident>,
3479
3480 pub ty: Box<Ty>,
3481 pub default: Option<AnonConst>,
3482 pub is_placeholder: bool,
3483}
3484
3485#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3487pub enum Recovered {
3488 No,
3489 Yes(ErrorGuaranteed),
3490}
3491
3492#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3494pub enum VariantData {
3495 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3499 Tuple(ThinVec<FieldDef>, NodeId),
3503 Unit(NodeId),
3507}
3508
3509impl VariantData {
3510 pub fn fields(&self) -> &[FieldDef] {
3512 match self {
3513 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3514 _ => &[],
3515 }
3516 }
3517
3518 pub fn ctor_node_id(&self) -> Option<NodeId> {
3520 match *self {
3521 VariantData::Struct { .. } => None,
3522 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3523 }
3524 }
3525}
3526
3527#[derive(Clone, Encodable, Decodable, Debug)]
3529pub struct Item<K = ItemKind> {
3530 pub attrs: AttrVec,
3531 pub id: NodeId,
3532 pub span: Span,
3533 pub vis: Visibility,
3534
3535 pub kind: K,
3536
3537 pub tokens: Option<LazyAttrTokenStream>,
3545}
3546
3547impl Item {
3548 pub fn span_with_attributes(&self) -> Span {
3550 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3551 }
3552
3553 pub fn opt_generics(&self) -> Option<&Generics> {
3554 match &self.kind {
3555 ItemKind::ExternCrate(..)
3556 | ItemKind::Use(_)
3557 | ItemKind::Mod(..)
3558 | ItemKind::ForeignMod(_)
3559 | ItemKind::GlobalAsm(_)
3560 | ItemKind::MacCall(_)
3561 | ItemKind::Delegation(_)
3562 | ItemKind::DelegationMac(_)
3563 | ItemKind::MacroDef(..) => None,
3564 ItemKind::Static(_) => None,
3565 ItemKind::Const(i) => Some(&i.generics),
3566 ItemKind::Fn(i) => Some(&i.generics),
3567 ItemKind::TyAlias(i) => Some(&i.generics),
3568 ItemKind::TraitAlias(i) => Some(&i.generics),
3569
3570 ItemKind::Enum(_, generics, _)
3571 | ItemKind::Struct(_, generics, _)
3572 | ItemKind::Union(_, generics, _) => Some(&generics),
3573 ItemKind::Trait(i) => Some(&i.generics),
3574 ItemKind::Impl(i) => Some(&i.generics),
3575 }
3576 }
3577}
3578
3579#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3581pub enum Extern {
3582 None,
3586 Implicit(Span),
3592 Explicit(StrLit, Span),
3596}
3597
3598impl Extern {
3599 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3600 match abi {
3601 Some(name) => Extern::Explicit(name, span),
3602 None => Extern::Implicit(span),
3603 }
3604 }
3605
3606 pub fn span(self) -> Option<Span> {
3607 match self {
3608 Extern::None => None,
3609 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3610 }
3611 }
3612}
3613
3614#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3619pub struct FnHeader {
3620 pub constness: Const,
3622 pub coroutine_kind: Option<CoroutineKind>,
3624 pub safety: Safety,
3626 pub ext: Extern,
3628}
3629
3630impl FnHeader {
3631 pub fn has_qualifiers(&self) -> bool {
3633 let Self { safety, coroutine_kind, constness, ext } = self;
3634 matches!(safety, Safety::Unsafe(_))
3635 || coroutine_kind.is_some()
3636 || matches!(constness, Const::Yes(_))
3637 || !matches!(ext, Extern::None)
3638 }
3639}
3640
3641impl Default for FnHeader {
3642 fn default() -> FnHeader {
3643 FnHeader {
3644 safety: Safety::Default,
3645 coroutine_kind: None,
3646 constness: Const::No,
3647 ext: Extern::None,
3648 }
3649 }
3650}
3651
3652#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3653pub struct TraitAlias {
3654 pub constness: Const,
3655 pub ident: Ident,
3656 pub generics: Generics,
3657 #[visitable(extra = BoundKind::Bound)]
3658 pub bounds: GenericBounds,
3659}
3660
3661#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3662pub struct Trait {
3663 pub constness: Const,
3664 pub safety: Safety,
3665 pub is_auto: IsAuto,
3666 pub ident: Ident,
3667 pub generics: Generics,
3668 #[visitable(extra = BoundKind::SuperTraits)]
3669 pub bounds: GenericBounds,
3670 #[visitable(extra = AssocCtxt::Trait)]
3671 pub items: ThinVec<Box<AssocItem>>,
3672}
3673
3674#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3675pub struct TyAlias {
3676 pub defaultness: Defaultness,
3677 pub ident: Ident,
3678 pub generics: Generics,
3679 pub after_where_clause: WhereClause,
3694 #[visitable(extra = BoundKind::Bound)]
3695 pub bounds: GenericBounds,
3696 pub ty: Option<Box<Ty>>,
3697}
3698
3699#[derive(Clone, Encodable, Decodable, Debug)]
3700pub struct Impl {
3701 pub generics: Generics,
3702 pub of_trait: Option<Box<TraitImplHeader>>,
3703 pub self_ty: Box<Ty>,
3704 pub items: ThinVec<Box<AssocItem>>,
3705}
3706
3707#[derive(Clone, Encodable, Decodable, Debug)]
3708pub struct TraitImplHeader {
3709 pub defaultness: Defaultness,
3710 pub safety: Safety,
3711 pub constness: Const,
3712 pub polarity: ImplPolarity,
3713 pub trait_ref: TraitRef,
3714}
3715
3716#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3717pub struct FnContract {
3718 pub declarations: ThinVec<Stmt>,
3721 pub requires: Option<Box<Expr>>,
3722 pub ensures: Option<Box<Expr>>,
3723}
3724
3725#[derive(Clone, Encodable, Decodable, Debug)]
3726pub struct Fn {
3727 pub defaultness: Defaultness,
3728 pub ident: Ident,
3729 pub generics: Generics,
3730 pub sig: FnSig,
3731 pub contract: Option<Box<FnContract>>,
3732 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3733 pub body: Option<Box<Block>>,
3734}
3735
3736#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3737pub struct Delegation {
3738 pub id: NodeId,
3740 pub qself: Option<Box<QSelf>>,
3741 pub path: Path,
3742 pub ident: Ident,
3743 pub rename: Option<Ident>,
3744 pub body: Option<Box<Block>>,
3745 pub from_glob: bool,
3747}
3748
3749#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3750pub struct DelegationMac {
3751 pub qself: Option<Box<QSelf>>,
3752 pub prefix: Path,
3753 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3755 pub body: Option<Box<Block>>,
3756}
3757
3758#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3759pub struct StaticItem {
3760 pub ident: Ident,
3761 pub ty: Box<Ty>,
3762 pub safety: Safety,
3763 pub mutability: Mutability,
3764 pub expr: Option<Box<Expr>>,
3765 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3766}
3767
3768#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3769pub struct ConstItem {
3770 pub defaultness: Defaultness,
3771 pub ident: Ident,
3772 pub generics: Generics,
3773 pub ty: Box<Ty>,
3774 pub rhs: Option<ConstItemRhs>,
3775 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3776}
3777
3778#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3779pub enum ConstItemRhs {
3780 TypeConst(AnonConst),
3781 Body(Box<Expr>),
3782}
3783
3784impl ConstItemRhs {
3785 pub fn span(&self) -> Span {
3786 self.expr().span
3787 }
3788
3789 pub fn expr(&self) -> &Expr {
3790 match self {
3791 ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
3792 ConstItemRhs::Body(expr) => expr,
3793 }
3794 }
3795}
3796
3797#[derive(Clone, Encodable, Decodable, Debug)]
3799pub enum ItemKind {
3800 ExternCrate(Option<Symbol>, Ident),
3804 Use(UseTree),
3808 Static(Box<StaticItem>),
3812 Const(Box<ConstItem>),
3816 Fn(Box<Fn>),
3820 Mod(Safety, Ident, ModKind),
3826 ForeignMod(ForeignMod),
3830 GlobalAsm(Box<InlineAsm>),
3832 TyAlias(Box<TyAlias>),
3836 Enum(Ident, Generics, EnumDef),
3840 Struct(Ident, Generics, VariantData),
3844 Union(Ident, Generics, VariantData),
3848 Trait(Box<Trait>),
3852 TraitAlias(Box<TraitAlias>),
3856 Impl(Impl),
3860 MacCall(Box<MacCall>),
3864 MacroDef(Ident, MacroDef),
3866 Delegation(Box<Delegation>),
3870 DelegationMac(Box<DelegationMac>),
3873}
3874
3875impl ItemKind {
3876 pub fn ident(&self) -> Option<Ident> {
3877 match *self {
3878 ItemKind::ExternCrate(_, ident)
3879 | ItemKind::Static(box StaticItem { ident, .. })
3880 | ItemKind::Const(box ConstItem { ident, .. })
3881 | ItemKind::Fn(box Fn { ident, .. })
3882 | ItemKind::Mod(_, ident, _)
3883 | ItemKind::TyAlias(box TyAlias { ident, .. })
3884 | ItemKind::Enum(ident, ..)
3885 | ItemKind::Struct(ident, ..)
3886 | ItemKind::Union(ident, ..)
3887 | ItemKind::Trait(box Trait { ident, .. })
3888 | ItemKind::TraitAlias(box TraitAlias { ident, .. })
3889 | ItemKind::MacroDef(ident, _)
3890 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3891
3892 ItemKind::Use(_)
3893 | ItemKind::ForeignMod(_)
3894 | ItemKind::GlobalAsm(_)
3895 | ItemKind::Impl(_)
3896 | ItemKind::MacCall(_)
3897 | ItemKind::DelegationMac(_) => None,
3898 }
3899 }
3900
3901 pub fn article(&self) -> &'static str {
3903 use ItemKind::*;
3904 match self {
3905 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3906 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3907 | Delegation(..) | DelegationMac(..) => "a",
3908 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3909 }
3910 }
3911
3912 pub fn descr(&self) -> &'static str {
3913 match self {
3914 ItemKind::ExternCrate(..) => "extern crate",
3915 ItemKind::Use(..) => "`use` import",
3916 ItemKind::Static(..) => "static item",
3917 ItemKind::Const(..) => "constant item",
3918 ItemKind::Fn(..) => "function",
3919 ItemKind::Mod(..) => "module",
3920 ItemKind::ForeignMod(..) => "extern block",
3921 ItemKind::GlobalAsm(..) => "global asm item",
3922 ItemKind::TyAlias(..) => "type alias",
3923 ItemKind::Enum(..) => "enum",
3924 ItemKind::Struct(..) => "struct",
3925 ItemKind::Union(..) => "union",
3926 ItemKind::Trait(..) => "trait",
3927 ItemKind::TraitAlias(..) => "trait alias",
3928 ItemKind::MacCall(..) => "item macro invocation",
3929 ItemKind::MacroDef(..) => "macro definition",
3930 ItemKind::Impl { .. } => "implementation",
3931 ItemKind::Delegation(..) => "delegated function",
3932 ItemKind::DelegationMac(..) => "delegation",
3933 }
3934 }
3935
3936 pub fn generics(&self) -> Option<&Generics> {
3937 match self {
3938 Self::Fn(box Fn { generics, .. })
3939 | Self::TyAlias(box TyAlias { generics, .. })
3940 | Self::Const(box ConstItem { generics, .. })
3941 | Self::Enum(_, generics, _)
3942 | Self::Struct(_, generics, _)
3943 | Self::Union(_, generics, _)
3944 | Self::Trait(box Trait { generics, .. })
3945 | Self::TraitAlias(box TraitAlias { generics, .. })
3946 | Self::Impl(Impl { generics, .. }) => Some(generics),
3947 _ => None,
3948 }
3949 }
3950}
3951
3952pub type AssocItem = Item<AssocItemKind>;
3955
3956#[derive(Clone, Encodable, Decodable, Debug)]
3964pub enum AssocItemKind {
3965 Const(Box<ConstItem>),
3968 Fn(Box<Fn>),
3970 Type(Box<TyAlias>),
3972 MacCall(Box<MacCall>),
3974 Delegation(Box<Delegation>),
3976 DelegationMac(Box<DelegationMac>),
3978}
3979
3980impl AssocItemKind {
3981 pub fn ident(&self) -> Option<Ident> {
3982 match *self {
3983 AssocItemKind::Const(box ConstItem { ident, .. })
3984 | AssocItemKind::Fn(box Fn { ident, .. })
3985 | AssocItemKind::Type(box TyAlias { ident, .. })
3986 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3987
3988 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3989 }
3990 }
3991
3992 pub fn defaultness(&self) -> Defaultness {
3993 match *self {
3994 Self::Const(box ConstItem { defaultness, .. })
3995 | Self::Fn(box Fn { defaultness, .. })
3996 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3997 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3998 Defaultness::Final
3999 }
4000 }
4001 }
4002}
4003
4004impl From<AssocItemKind> for ItemKind {
4005 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4006 match assoc_item_kind {
4007 AssocItemKind::Const(item) => ItemKind::Const(item),
4008 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4009 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4010 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4011 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4012 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4013 }
4014 }
4015}
4016
4017impl TryFrom<ItemKind> for AssocItemKind {
4018 type Error = ItemKind;
4019
4020 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4021 Ok(match item_kind {
4022 ItemKind::Const(item) => AssocItemKind::Const(item),
4023 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4024 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4025 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4026 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4027 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4028 _ => return Err(item_kind),
4029 })
4030 }
4031}
4032
4033#[derive(Clone, Encodable, Decodable, Debug)]
4035pub enum ForeignItemKind {
4036 Static(Box<StaticItem>),
4038 Fn(Box<Fn>),
4040 TyAlias(Box<TyAlias>),
4042 MacCall(Box<MacCall>),
4044}
4045
4046impl ForeignItemKind {
4047 pub fn ident(&self) -> Option<Ident> {
4048 match *self {
4049 ForeignItemKind::Static(box StaticItem { ident, .. })
4050 | ForeignItemKind::Fn(box Fn { ident, .. })
4051 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4052
4053 ForeignItemKind::MacCall(_) => None,
4054 }
4055 }
4056}
4057
4058impl From<ForeignItemKind> for ItemKind {
4059 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4060 match foreign_item_kind {
4061 ForeignItemKind::Static(box static_foreign_item) => {
4062 ItemKind::Static(Box::new(static_foreign_item))
4063 }
4064 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4065 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4066 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4067 }
4068 }
4069}
4070
4071impl TryFrom<ItemKind> for ForeignItemKind {
4072 type Error = ItemKind;
4073
4074 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4075 Ok(match item_kind {
4076 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4077 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4078 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4079 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4080 _ => return Err(item_kind),
4081 })
4082 }
4083}
4084
4085pub type ForeignItem = Item<ForeignItemKind>;
4086
4087#[cfg(target_pointer_width = "64")]
4089mod size_asserts {
4090 use rustc_data_structures::static_assert_size;
4091
4092 use super::*;
4093 static_assert_size!(AssocItem, 80);
4095 static_assert_size!(AssocItemKind, 16);
4096 static_assert_size!(Attribute, 32);
4097 static_assert_size!(Block, 32);
4098 static_assert_size!(Expr, 72);
4099 static_assert_size!(ExprKind, 40);
4100 static_assert_size!(Fn, 184);
4101 static_assert_size!(ForeignItem, 80);
4102 static_assert_size!(ForeignItemKind, 16);
4103 static_assert_size!(GenericArg, 24);
4104 static_assert_size!(GenericBound, 88);
4105 static_assert_size!(Generics, 40);
4106 static_assert_size!(Impl, 64);
4107 static_assert_size!(Item, 136);
4108 static_assert_size!(ItemKind, 72);
4109 static_assert_size!(LitKind, 24);
4110 static_assert_size!(Local, 96);
4111 static_assert_size!(MetaItemLit, 40);
4112 static_assert_size!(Param, 40);
4113 static_assert_size!(Pat, 80);
4114 static_assert_size!(PatKind, 56);
4115 static_assert_size!(Path, 24);
4116 static_assert_size!(PathSegment, 24);
4117 static_assert_size!(Stmt, 32);
4118 static_assert_size!(StmtKind, 16);
4119 static_assert_size!(TraitImplHeader, 80);
4120 static_assert_size!(Ty, 64);
4121 static_assert_size!(TyKind, 40);
4122 }