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)]
147 pub fn is_potential_trivial_const_arg(&self) -> bool {
148 self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
149 }
150}
151
152pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
164 let mut iter = path.into_iter();
169 let len_hint = iter.size_hint().1.unwrap_or(1);
170 let mut s = String::with_capacity(len_hint * 8);
171
172 let first_sym = *iter.next().unwrap().borrow();
173 if first_sym != kw::PathRoot {
174 s.push_str(first_sym.as_str());
175 }
176 for sym in iter {
177 let sym = *sym.borrow();
178 debug_assert_ne!(sym, kw::PathRoot);
179 s.push_str("::");
180 s.push_str(sym.as_str());
181 }
182 s
183}
184
185pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
188 let mut iter = path.into_iter();
189 let len_hint = iter.size_hint().1.unwrap_or(1);
190 let mut s = String::with_capacity(len_hint * 8);
191
192 let first_ident = *iter.next().unwrap().borrow();
193 if first_ident.name != kw::PathRoot {
194 s.push_str(&first_ident.to_string());
195 }
196 for ident in iter {
197 let ident = *ident.borrow();
198 debug_assert_ne!(ident.name, kw::PathRoot);
199 s.push_str("::");
200 s.push_str(&ident.to_string());
201 }
202 s
203}
204
205#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
209pub struct PathSegment {
210 pub ident: Ident,
212
213 pub id: NodeId,
214
215 pub args: Option<Box<GenericArgs>>,
222}
223
224impl PartialEq<Symbol> for PathSegment {
226 #[inline]
227 fn eq(&self, name: &Symbol) -> bool {
228 self.args.is_none() && self.ident.name == *name
229 }
230}
231
232impl PathSegment {
233 pub fn from_ident(ident: Ident) -> Self {
234 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
235 }
236
237 pub fn path_root(span: Span) -> Self {
238 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
239 }
240
241 pub fn span(&self) -> Span {
242 match &self.args {
243 Some(args) => self.ident.span.to(args.span()),
244 None => self.ident.span,
245 }
246 }
247}
248
249#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
253pub enum GenericArgs {
254 AngleBracketed(AngleBracketedArgs),
256 Parenthesized(ParenthesizedArgs),
258 ParenthesizedElided(Span),
260}
261
262impl GenericArgs {
263 pub fn is_angle_bracketed(&self) -> bool {
264 matches!(self, AngleBracketed(..))
265 }
266
267 pub fn span(&self) -> Span {
268 match self {
269 AngleBracketed(data) => data.span,
270 Parenthesized(data) => data.span,
271 ParenthesizedElided(span) => *span,
272 }
273 }
274}
275
276#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
278pub enum GenericArg {
279 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
281 Type(Box<Ty>),
283 Const(AnonConst),
285}
286
287impl GenericArg {
288 pub fn span(&self) -> Span {
289 match self {
290 GenericArg::Lifetime(lt) => lt.ident.span,
291 GenericArg::Type(ty) => ty.span,
292 GenericArg::Const(ct) => ct.value.span,
293 }
294 }
295}
296
297#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
299pub struct AngleBracketedArgs {
300 pub span: Span,
302 pub args: ThinVec<AngleBracketedArg>,
304}
305
306#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
308pub enum AngleBracketedArg {
309 Arg(GenericArg),
311 Constraint(AssocItemConstraint),
313}
314
315impl AngleBracketedArg {
316 pub fn span(&self) -> Span {
317 match self {
318 AngleBracketedArg::Arg(arg) => arg.span(),
319 AngleBracketedArg::Constraint(constraint) => constraint.span,
320 }
321 }
322}
323
324impl From<AngleBracketedArgs> for Box<GenericArgs> {
325 fn from(val: AngleBracketedArgs) -> Self {
326 Box::new(GenericArgs::AngleBracketed(val))
327 }
328}
329
330impl From<ParenthesizedArgs> for Box<GenericArgs> {
331 fn from(val: ParenthesizedArgs) -> Self {
332 Box::new(GenericArgs::Parenthesized(val))
333 }
334}
335
336#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
338pub struct ParenthesizedArgs {
339 pub span: Span,
344
345 pub inputs: ThinVec<Box<Ty>>,
347
348 pub inputs_span: Span,
353
354 pub output: FnRetTy,
356}
357
358impl ParenthesizedArgs {
359 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
360 let args = self
361 .inputs
362 .iter()
363 .cloned()
364 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
365 .collect();
366 AngleBracketedArgs { span: self.inputs_span, args }
367 }
368}
369
370pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
371
372#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
374pub struct TraitBoundModifiers {
375 pub constness: BoundConstness,
376 pub asyncness: BoundAsyncness,
377 pub polarity: BoundPolarity,
378}
379
380impl TraitBoundModifiers {
381 pub const NONE: Self = Self {
382 constness: BoundConstness::Never,
383 asyncness: BoundAsyncness::Normal,
384 polarity: BoundPolarity::Positive,
385 };
386}
387
388#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
389pub enum GenericBound {
390 Trait(PolyTraitRef),
391 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
392 Use(ThinVec<PreciseCapturingArg>, Span),
394}
395
396impl GenericBound {
397 pub fn span(&self) -> Span {
398 match self {
399 GenericBound::Trait(t, ..) => t.span,
400 GenericBound::Outlives(l) => l.ident.span,
401 GenericBound::Use(_, span) => *span,
402 }
403 }
404}
405
406pub type GenericBounds = Vec<GenericBound>;
407
408#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
412pub enum ParamKindOrd {
413 Lifetime,
414 TypeOrConst,
415}
416
417impl fmt::Display for ParamKindOrd {
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419 match self {
420 ParamKindOrd::Lifetime => "lifetime".fmt(f),
421 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
422 }
423 }
424}
425
426#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
427pub enum GenericParamKind {
428 Lifetime,
430 Type {
431 default: Option<Box<Ty>>,
432 },
433 Const {
434 ty: Box<Ty>,
435 span: Span,
437 default: Option<AnonConst>,
439 },
440}
441
442#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
443pub struct GenericParam {
444 pub id: NodeId,
445 pub ident: Ident,
446 pub attrs: AttrVec,
447 #[visitable(extra = BoundKind::Bound)]
448 pub bounds: GenericBounds,
449 pub is_placeholder: bool,
450 pub kind: GenericParamKind,
451 pub colon_span: Option<Span>,
452}
453
454impl GenericParam {
455 pub fn span(&self) -> Span {
456 match &self.kind {
457 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
458 self.ident.span
459 }
460 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
461 GenericParamKind::Const { span, .. } => *span,
462 }
463 }
464}
465
466#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
469pub struct Generics {
470 pub params: ThinVec<GenericParam>,
471 pub where_clause: WhereClause,
472 pub span: Span,
473}
474
475#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
477pub struct WhereClause {
478 pub has_where_token: bool,
483 pub predicates: ThinVec<WherePredicate>,
484 pub span: Span,
485}
486
487impl WhereClause {
488 pub fn is_empty(&self) -> bool {
489 !self.has_where_token && self.predicates.is_empty()
490 }
491}
492
493#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
495pub struct WherePredicate {
496 pub attrs: AttrVec,
497 pub kind: WherePredicateKind,
498 pub id: NodeId,
499 pub span: Span,
500 pub is_placeholder: bool,
501}
502
503#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
505pub enum WherePredicateKind {
506 BoundPredicate(WhereBoundPredicate),
508 RegionPredicate(WhereRegionPredicate),
510 EqPredicate(WhereEqPredicate),
512}
513
514#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
518pub struct WhereBoundPredicate {
519 pub bound_generic_params: ThinVec<GenericParam>,
521 pub bounded_ty: Box<Ty>,
523 #[visitable(extra = BoundKind::Bound)]
525 pub bounds: GenericBounds,
526}
527
528#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
532pub struct WhereRegionPredicate {
533 #[visitable(extra = LifetimeCtxt::Bound)]
534 pub lifetime: Lifetime,
535 #[visitable(extra = BoundKind::Bound)]
536 pub bounds: GenericBounds,
537}
538
539#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
543pub struct WhereEqPredicate {
544 pub lhs_ty: Box<Ty>,
545 pub rhs_ty: Box<Ty>,
546}
547
548#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
549pub struct Crate {
550 pub id: NodeId,
553 pub attrs: AttrVec,
554 pub items: ThinVec<Box<Item>>,
555 pub spans: ModSpans,
556 pub is_placeholder: bool,
557}
558
559#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
566pub struct MetaItem {
567 pub unsafety: Safety,
568 pub path: Path,
569 pub kind: MetaItemKind,
570 pub span: Span,
571}
572
573#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
575pub enum MetaItemKind {
576 Word,
580
581 List(ThinVec<MetaItemInner>),
585
586 NameValue(MetaItemLit),
590}
591
592#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
596pub enum MetaItemInner {
597 MetaItem(MetaItem),
599
600 Lit(MetaItemLit),
604}
605
606#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
610pub struct Block {
611 pub stmts: ThinVec<Stmt>,
613 pub id: NodeId,
614 pub rules: BlockCheckMode,
616 pub span: Span,
617 pub tokens: Option<LazyAttrTokenStream>,
618}
619
620#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
624pub struct Pat {
625 pub id: NodeId,
626 pub kind: PatKind,
627 pub span: Span,
628 pub tokens: Option<LazyAttrTokenStream>,
629}
630
631impl Pat {
632 pub fn to_ty(&self) -> Option<Box<Ty>> {
635 let kind = match &self.kind {
636 PatKind::Missing => unreachable!(),
637 PatKind::Wild => TyKind::Infer,
639 PatKind::Ident(BindingMode::NONE, ident, None) => {
641 TyKind::Path(None, Path::from_ident(*ident))
642 }
643 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
644 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
645 PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
647 Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
648 Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }),
649 })?,
650 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
653 pat.to_ty().map(TyKind::Slice)?
654 }
655 PatKind::Tuple(pats) => {
658 let mut tys = ThinVec::with_capacity(pats.len());
659 for pat in pats {
661 tys.push(pat.to_ty()?);
662 }
663 TyKind::Tup(tys)
664 }
665 _ => return None,
666 };
667
668 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
669 }
670
671 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
675 if !it(self) {
676 return;
677 }
678
679 match &self.kind {
680 PatKind::Ident(_, _, Some(p)) => p.walk(it),
682
683 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
685
686 PatKind::TupleStruct(_, _, s)
688 | PatKind::Tuple(s)
689 | PatKind::Slice(s)
690 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
691
692 PatKind::Box(s)
694 | PatKind::Deref(s)
695 | PatKind::Ref(s, _, _)
696 | PatKind::Paren(s)
697 | PatKind::Guard(s, _) => s.walk(it),
698
699 PatKind::Missing
701 | PatKind::Wild
702 | PatKind::Rest
703 | PatKind::Never
704 | PatKind::Expr(_)
705 | PatKind::Range(..)
706 | PatKind::Ident(..)
707 | PatKind::Path(..)
708 | PatKind::MacCall(_)
709 | PatKind::Err(_) => {}
710 }
711 }
712
713 pub fn peel_refs(&self) -> &Pat {
715 let mut current = self;
716 while let PatKind::Ref(inner, _, _) = ¤t.kind {
717 current = inner;
718 }
719 current
720 }
721
722 pub fn is_rest(&self) -> bool {
724 matches!(self.kind, PatKind::Rest)
725 }
726
727 pub fn could_be_never_pattern(&self) -> bool {
730 let mut could_be_never_pattern = false;
731 self.walk(&mut |pat| match &pat.kind {
732 PatKind::Never | PatKind::MacCall(_) => {
733 could_be_never_pattern = true;
734 false
735 }
736 PatKind::Or(s) => {
737 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
738 false
739 }
740 _ => true,
741 });
742 could_be_never_pattern
743 }
744
745 pub fn contains_never_pattern(&self) -> bool {
748 let mut contains_never_pattern = false;
749 self.walk(&mut |pat| {
750 if matches!(pat.kind, PatKind::Never) {
751 contains_never_pattern = true;
752 }
753 true
754 });
755 contains_never_pattern
756 }
757
758 pub fn descr(&self) -> Option<String> {
760 match &self.kind {
761 PatKind::Missing => unreachable!(),
762 PatKind::Wild => Some("_".to_string()),
763 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
764 PatKind::Ref(pat, pinned, mutbl) => {
765 pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
766 }
767 _ => None,
768 }
769 }
770}
771
772impl From<Box<Pat>> for Pat {
773 fn from(value: Box<Pat>) -> Self {
774 *value
775 }
776}
777
778#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
784pub struct PatField {
785 pub ident: Ident,
787 pub pat: Box<Pat>,
789 pub is_shorthand: bool,
790 pub attrs: AttrVec,
791 pub id: NodeId,
792 pub span: Span,
793 pub is_placeholder: bool,
794}
795
796#[derive(Clone, Copy, Debug, Eq, PartialEq)]
797#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
798pub enum ByRef {
799 Yes(Pinnedness, Mutability),
800 No,
801}
802
803impl ByRef {
804 #[must_use]
805 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
806 if let ByRef::Yes(_, old_mutbl) = &mut self {
807 *old_mutbl = cmp::min(*old_mutbl, mutbl);
808 }
809 self
810 }
811}
812
813#[derive(Clone, Copy, Debug, Eq, PartialEq)]
819#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
820pub struct BindingMode(pub ByRef, pub Mutability);
821
822impl BindingMode {
823 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
824 pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not);
825 pub const REF_PIN: Self =
826 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not);
827 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
828 pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not);
829 pub const REF_PIN_MUT: Self =
830 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not);
831 pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut);
832 pub const MUT_REF_PIN: Self =
833 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut);
834 pub const MUT_REF_MUT: Self =
835 Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut);
836 pub const MUT_REF_PIN_MUT: Self =
837 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut);
838
839 pub fn prefix_str(self) -> &'static str {
840 match self {
841 Self::NONE => "",
842 Self::REF => "ref ",
843 Self::REF_PIN => "ref pin const ",
844 Self::MUT => "mut ",
845 Self::REF_MUT => "ref mut ",
846 Self::REF_PIN_MUT => "ref pin mut ",
847 Self::MUT_REF => "mut ref ",
848 Self::MUT_REF_PIN => "mut ref pin ",
849 Self::MUT_REF_MUT => "mut ref mut ",
850 Self::MUT_REF_PIN_MUT => "mut ref pin mut ",
851 }
852 }
853}
854
855#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
856pub enum RangeEnd {
857 Included(RangeSyntax),
859 Excluded,
861}
862
863#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
864pub enum RangeSyntax {
865 DotDotDot,
867 DotDotEq,
869}
870
871#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
875pub enum PatKind {
876 Missing,
878
879 Wild,
881
882 Ident(BindingMode, Ident, Option<Box<Pat>>),
887
888 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
890
891 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
893
894 Or(ThinVec<Pat>),
897
898 Path(Option<Box<QSelf>>, Path),
903
904 Tuple(ThinVec<Pat>),
906
907 Box(Box<Pat>),
909
910 Deref(Box<Pat>),
912
913 Ref(Box<Pat>, Pinnedness, Mutability),
915
916 Expr(Box<Expr>),
918
919 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
921
922 Slice(ThinVec<Pat>),
924
925 Rest,
938
939 Never,
941
942 Guard(Box<Pat>, Box<Expr>),
944
945 Paren(Box<Pat>),
947
948 MacCall(Box<MacCall>),
950
951 Err(ErrorGuaranteed),
953}
954
955#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
957pub enum PatFieldsRest {
958 Rest(Span),
960 Recovered(ErrorGuaranteed),
962 None,
964}
965
966#[derive(Clone, Copy, PartialEq, Eq, Debug)]
969#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
970pub enum BorrowKind {
971 Ref,
975 Raw,
979 Pin,
983}
984
985#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
986pub enum BinOpKind {
987 Add,
989 Sub,
991 Mul,
993 Div,
995 Rem,
997 And,
999 Or,
1001 BitXor,
1003 BitAnd,
1005 BitOr,
1007 Shl,
1009 Shr,
1011 Eq,
1013 Lt,
1015 Le,
1017 Ne,
1019 Ge,
1021 Gt,
1023}
1024
1025impl BinOpKind {
1026 pub fn as_str(&self) -> &'static str {
1027 use BinOpKind::*;
1028 match self {
1029 Add => "+",
1030 Sub => "-",
1031 Mul => "*",
1032 Div => "/",
1033 Rem => "%",
1034 And => "&&",
1035 Or => "||",
1036 BitXor => "^",
1037 BitAnd => "&",
1038 BitOr => "|",
1039 Shl => "<<",
1040 Shr => ">>",
1041 Eq => "==",
1042 Lt => "<",
1043 Le => "<=",
1044 Ne => "!=",
1045 Ge => ">=",
1046 Gt => ">",
1047 }
1048 }
1049
1050 pub fn is_lazy(&self) -> bool {
1051 matches!(self, BinOpKind::And | BinOpKind::Or)
1052 }
1053
1054 pub fn precedence(&self) -> ExprPrecedence {
1055 use BinOpKind::*;
1056 match *self {
1057 Mul | Div | Rem => ExprPrecedence::Product,
1058 Add | Sub => ExprPrecedence::Sum,
1059 Shl | Shr => ExprPrecedence::Shift,
1060 BitAnd => ExprPrecedence::BitAnd,
1061 BitXor => ExprPrecedence::BitXor,
1062 BitOr => ExprPrecedence::BitOr,
1063 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1064 And => ExprPrecedence::LAnd,
1065 Or => ExprPrecedence::LOr,
1066 }
1067 }
1068
1069 pub fn fixity(&self) -> Fixity {
1070 use BinOpKind::*;
1071 match self {
1072 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1073 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1074 Fixity::Left
1075 }
1076 }
1077 }
1078
1079 pub fn is_comparison(self) -> bool {
1080 use BinOpKind::*;
1081 match self {
1082 Eq | Ne | Lt | Le | Gt | Ge => true,
1083 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1084 }
1085 }
1086
1087 pub fn is_by_value(self) -> bool {
1089 !self.is_comparison()
1090 }
1091}
1092
1093pub type BinOp = Spanned<BinOpKind>;
1094
1095impl From<AssignOpKind> for BinOpKind {
1099 fn from(op: AssignOpKind) -> BinOpKind {
1100 match op {
1101 AssignOpKind::AddAssign => BinOpKind::Add,
1102 AssignOpKind::SubAssign => BinOpKind::Sub,
1103 AssignOpKind::MulAssign => BinOpKind::Mul,
1104 AssignOpKind::DivAssign => BinOpKind::Div,
1105 AssignOpKind::RemAssign => BinOpKind::Rem,
1106 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1107 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1108 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1109 AssignOpKind::ShlAssign => BinOpKind::Shl,
1110 AssignOpKind::ShrAssign => BinOpKind::Shr,
1111 }
1112 }
1113}
1114
1115#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1116pub enum AssignOpKind {
1117 AddAssign,
1119 SubAssign,
1121 MulAssign,
1123 DivAssign,
1125 RemAssign,
1127 BitXorAssign,
1129 BitAndAssign,
1131 BitOrAssign,
1133 ShlAssign,
1135 ShrAssign,
1137}
1138
1139impl AssignOpKind {
1140 pub fn as_str(&self) -> &'static str {
1141 use AssignOpKind::*;
1142 match self {
1143 AddAssign => "+=",
1144 SubAssign => "-=",
1145 MulAssign => "*=",
1146 DivAssign => "/=",
1147 RemAssign => "%=",
1148 BitXorAssign => "^=",
1149 BitAndAssign => "&=",
1150 BitOrAssign => "|=",
1151 ShlAssign => "<<=",
1152 ShrAssign => ">>=",
1153 }
1154 }
1155
1156 pub fn is_by_value(self) -> bool {
1158 true
1159 }
1160}
1161
1162pub type AssignOp = Spanned<AssignOpKind>;
1163
1164#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1168pub enum UnOp {
1169 Deref,
1171 Not,
1173 Neg,
1175}
1176
1177impl UnOp {
1178 pub fn as_str(&self) -> &'static str {
1179 match self {
1180 UnOp::Deref => "*",
1181 UnOp::Not => "!",
1182 UnOp::Neg => "-",
1183 }
1184 }
1185
1186 pub fn is_by_value(self) -> bool {
1188 matches!(self, Self::Neg | Self::Not)
1189 }
1190}
1191
1192#[derive(Clone, Encodable, Decodable, Debug)]
1196pub struct Stmt {
1197 pub id: NodeId,
1198 pub kind: StmtKind,
1199 pub span: Span,
1200}
1201
1202impl Stmt {
1203 pub fn has_trailing_semicolon(&self) -> bool {
1204 match &self.kind {
1205 StmtKind::Semi(_) => true,
1206 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1207 _ => false,
1208 }
1209 }
1210
1211 pub fn add_trailing_semicolon(mut self) -> Self {
1219 self.kind = match self.kind {
1220 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1221 StmtKind::MacCall(mut mac) => {
1222 mac.style = MacStmtStyle::Semicolon;
1223 StmtKind::MacCall(mac)
1224 }
1225 kind => kind,
1226 };
1227
1228 self
1229 }
1230
1231 pub fn is_item(&self) -> bool {
1232 matches!(self.kind, StmtKind::Item(_))
1233 }
1234
1235 pub fn is_expr(&self) -> bool {
1236 matches!(self.kind, StmtKind::Expr(_))
1237 }
1238}
1239
1240#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1242pub enum StmtKind {
1243 Let(Box<Local>),
1245 Item(Box<Item>),
1247 Expr(Box<Expr>),
1249 Semi(Box<Expr>),
1251 Empty,
1253 MacCall(Box<MacCallStmt>),
1255}
1256
1257impl StmtKind {
1258 pub fn descr(&self) -> &'static str {
1259 match self {
1260 StmtKind::Let(_) => "local",
1261 StmtKind::Item(_) => "item",
1262 StmtKind::Expr(_) => "expression",
1263 StmtKind::Semi(_) => "statement",
1264 StmtKind::Empty => "semicolon",
1265 StmtKind::MacCall(_) => "macro call",
1266 }
1267 }
1268}
1269
1270#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1271pub struct MacCallStmt {
1272 pub mac: Box<MacCall>,
1273 pub style: MacStmtStyle,
1274 pub attrs: AttrVec,
1275 pub tokens: Option<LazyAttrTokenStream>,
1276}
1277
1278#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1279pub enum MacStmtStyle {
1280 Semicolon,
1283 Braces,
1285 NoBraces,
1289}
1290
1291#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1293pub struct Local {
1294 pub id: NodeId,
1295 pub super_: Option<Span>,
1296 pub pat: Box<Pat>,
1297 pub ty: Option<Box<Ty>>,
1298 pub kind: LocalKind,
1299 pub span: Span,
1300 pub colon_sp: Option<Span>,
1301 pub attrs: AttrVec,
1302 pub tokens: Option<LazyAttrTokenStream>,
1303}
1304
1305#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1306pub enum LocalKind {
1307 Decl,
1310 Init(Box<Expr>),
1313 InitElse(Box<Expr>, Box<Block>),
1316}
1317
1318impl LocalKind {
1319 pub fn init(&self) -> Option<&Expr> {
1320 match self {
1321 Self::Decl => None,
1322 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1323 }
1324 }
1325
1326 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1327 match self {
1328 Self::Decl => None,
1329 Self::Init(init) => Some((init, None)),
1330 Self::InitElse(init, els) => Some((init, Some(els))),
1331 }
1332 }
1333}
1334
1335#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1346pub struct Arm {
1347 pub attrs: AttrVec,
1348 pub pat: Box<Pat>,
1350 pub guard: Option<Box<Expr>>,
1352 pub body: Option<Box<Expr>>,
1354 pub span: Span,
1355 pub id: NodeId,
1356 pub is_placeholder: bool,
1357}
1358
1359#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1361pub struct ExprField {
1362 pub attrs: AttrVec,
1363 pub id: NodeId,
1364 pub span: Span,
1365 pub ident: Ident,
1366 pub expr: Box<Expr>,
1367 pub is_shorthand: bool,
1368 pub is_placeholder: bool,
1369}
1370
1371#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1372pub enum BlockCheckMode {
1373 Default,
1374 Unsafe(UnsafeSource),
1375}
1376
1377#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1378pub enum UnsafeSource {
1379 CompilerGenerated,
1380 UserProvided,
1381}
1382
1383#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1387pub enum MgcaDisambiguation {
1388 AnonConst,
1389 Direct,
1390}
1391
1392#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1398pub struct AnonConst {
1399 pub id: NodeId,
1400 pub value: Box<Expr>,
1401 pub mgca_disambiguation: MgcaDisambiguation,
1402}
1403
1404#[derive(Clone, Encodable, Decodable, Debug)]
1406pub struct Expr {
1407 pub id: NodeId,
1408 pub kind: ExprKind,
1409 pub span: Span,
1410 pub attrs: AttrVec,
1411 pub tokens: Option<LazyAttrTokenStream>,
1412}
1413
1414impl Expr {
1415 pub fn is_potential_trivial_const_arg(&self) -> bool {
1427 let this = self.maybe_unwrap_block();
1428 if let ExprKind::Path(None, path) = &this.kind
1429 && path.is_potential_trivial_const_arg()
1430 {
1431 true
1432 } else {
1433 false
1434 }
1435 }
1436
1437 pub fn maybe_unwrap_block(&self) -> &Expr {
1439 if let ExprKind::Block(block, None) = &self.kind
1440 && let [stmt] = block.stmts.as_slice()
1441 && let StmtKind::Expr(expr) = &stmt.kind
1442 {
1443 expr
1444 } else {
1445 self
1446 }
1447 }
1448
1449 pub fn optionally_braced_mac_call(
1455 &self,
1456 already_stripped_block: bool,
1457 ) -> Option<(bool, NodeId)> {
1458 match &self.kind {
1459 ExprKind::Block(block, None)
1460 if let [stmt] = &*block.stmts
1461 && !already_stripped_block =>
1462 {
1463 match &stmt.kind {
1464 StmtKind::MacCall(_) => Some((true, stmt.id)),
1465 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1466 Some((true, expr.id))
1467 }
1468 _ => None,
1469 }
1470 }
1471 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1472 _ => None,
1473 }
1474 }
1475
1476 pub fn to_bound(&self) -> Option<GenericBound> {
1477 match &self.kind {
1478 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1479 ThinVec::new(),
1480 path.clone(),
1481 TraitBoundModifiers::NONE,
1482 self.span,
1483 Parens::No,
1484 ))),
1485 _ => None,
1486 }
1487 }
1488
1489 pub fn peel_parens(&self) -> &Expr {
1490 let mut expr = self;
1491 while let ExprKind::Paren(inner) = &expr.kind {
1492 expr = inner;
1493 }
1494 expr
1495 }
1496
1497 pub fn peel_parens_and_refs(&self) -> &Expr {
1498 let mut expr = self;
1499 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1500 {
1501 expr = inner;
1502 }
1503 expr
1504 }
1505
1506 pub fn to_ty(&self) -> Option<Box<Ty>> {
1508 let kind = match &self.kind {
1509 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1511 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1512
1513 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1514
1515 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1516 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1517 }
1518
1519 ExprKind::Repeat(expr, expr_len) => {
1520 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1521 }
1522
1523 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1524 expr.to_ty().map(TyKind::Slice)?
1525 }
1526
1527 ExprKind::Tup(exprs) => {
1528 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1529 TyKind::Tup(tys)
1530 }
1531
1532 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1536 let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else {
1537 return None;
1538 };
1539 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1540 }
1541
1542 ExprKind::Underscore => TyKind::Infer,
1543
1544 _ => return None,
1546 };
1547
1548 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1549 }
1550
1551 pub fn precedence(&self) -> ExprPrecedence {
1552 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1553 for attr in attrs {
1554 if let AttrStyle::Outer = attr.style {
1555 return ExprPrecedence::Prefix;
1556 }
1557 }
1558 ExprPrecedence::Unambiguous
1559 }
1560
1561 match &self.kind {
1562 ExprKind::Closure(closure) => {
1563 match closure.fn_decl.output {
1564 FnRetTy::Default(_) => ExprPrecedence::Jump,
1565 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1566 }
1567 }
1568
1569 ExprKind::Break(_ , value)
1570 | ExprKind::Ret(value)
1571 | ExprKind::Yield(YieldKind::Prefix(value))
1572 | ExprKind::Yeet(value) => match value {
1573 Some(_) => ExprPrecedence::Jump,
1574 None => prefix_attrs_precedence(&self.attrs),
1575 },
1576
1577 ExprKind::Become(_) => ExprPrecedence::Jump,
1578
1579 ExprKind::Range(..) => ExprPrecedence::Range,
1584
1585 ExprKind::Binary(op, ..) => op.node.precedence(),
1587 ExprKind::Cast(..) => ExprPrecedence::Cast,
1588
1589 ExprKind::Assign(..) |
1590 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1591
1592 ExprKind::AddrOf(..)
1594 | ExprKind::Let(..)
1599 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1600
1601 ExprKind::Array(_)
1603 | ExprKind::Await(..)
1604 | ExprKind::Use(..)
1605 | ExprKind::Block(..)
1606 | ExprKind::Call(..)
1607 | ExprKind::ConstBlock(_)
1608 | ExprKind::Continue(..)
1609 | ExprKind::Field(..)
1610 | ExprKind::ForLoop { .. }
1611 | ExprKind::FormatArgs(..)
1612 | ExprKind::Gen(..)
1613 | ExprKind::If(..)
1614 | ExprKind::IncludedBytes(..)
1615 | ExprKind::Index(..)
1616 | ExprKind::InlineAsm(..)
1617 | ExprKind::Lit(_)
1618 | ExprKind::Loop(..)
1619 | ExprKind::MacCall(..)
1620 | ExprKind::Match(..)
1621 | ExprKind::MethodCall(..)
1622 | ExprKind::OffsetOf(..)
1623 | ExprKind::Paren(..)
1624 | ExprKind::Path(..)
1625 | ExprKind::Repeat(..)
1626 | ExprKind::Struct(..)
1627 | ExprKind::Try(..)
1628 | ExprKind::TryBlock(..)
1629 | ExprKind::Tup(_)
1630 | ExprKind::Type(..)
1631 | ExprKind::Underscore
1632 | ExprKind::UnsafeBinderCast(..)
1633 | ExprKind::While(..)
1634 | ExprKind::Yield(YieldKind::Postfix(..))
1635 | ExprKind::Err(_)
1636 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1637 }
1638 }
1639
1640 pub fn is_approximately_pattern(&self) -> bool {
1642 matches!(
1643 &self.peel_parens().kind,
1644 ExprKind::Array(_)
1645 | ExprKind::Call(_, _)
1646 | ExprKind::Tup(_)
1647 | ExprKind::Lit(_)
1648 | ExprKind::Range(_, _, _)
1649 | ExprKind::Underscore
1650 | ExprKind::Path(_, _)
1651 | ExprKind::Struct(_)
1652 )
1653 }
1654
1655 pub fn dummy() -> Expr {
1659 Expr {
1660 id: DUMMY_NODE_ID,
1661 kind: ExprKind::Dummy,
1662 span: DUMMY_SP,
1663 attrs: ThinVec::new(),
1664 tokens: None,
1665 }
1666 }
1667}
1668
1669impl From<Box<Expr>> for Expr {
1670 fn from(value: Box<Expr>) -> Self {
1671 *value
1672 }
1673}
1674
1675#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1676pub struct Closure {
1677 pub binder: ClosureBinder,
1678 pub capture_clause: CaptureBy,
1679 pub constness: Const,
1680 pub coroutine_kind: Option<CoroutineKind>,
1681 pub movability: Movability,
1682 pub fn_decl: Box<FnDecl>,
1683 pub body: Box<Expr>,
1684 pub fn_decl_span: Span,
1686 pub fn_arg_span: Span,
1688}
1689
1690#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1692pub enum RangeLimits {
1693 HalfOpen,
1695 Closed,
1697}
1698
1699impl RangeLimits {
1700 pub fn as_str(&self) -> &'static str {
1701 match self {
1702 RangeLimits::HalfOpen => "..",
1703 RangeLimits::Closed => "..=",
1704 }
1705 }
1706}
1707
1708#[derive(Clone, Encodable, Decodable, Debug)]
1710pub struct MethodCall {
1711 pub seg: PathSegment,
1713 pub receiver: Box<Expr>,
1715 pub args: ThinVec<Box<Expr>>,
1717 pub span: Span,
1720}
1721
1722#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1723pub enum StructRest {
1724 Base(Box<Expr>),
1726 Rest(Span),
1728 None,
1730}
1731
1732#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1733pub struct StructExpr {
1734 pub qself: Option<Box<QSelf>>,
1735 pub path: Path,
1736 pub fields: ThinVec<ExprField>,
1737 pub rest: StructRest,
1738}
1739
1740#[derive(Clone, Encodable, Decodable, Debug)]
1742pub enum ExprKind {
1743 Array(ThinVec<Box<Expr>>),
1745 ConstBlock(AnonConst),
1747 Call(Box<Expr>, ThinVec<Box<Expr>>),
1754 MethodCall(Box<MethodCall>),
1756 Tup(ThinVec<Box<Expr>>),
1758 Binary(BinOp, Box<Expr>, Box<Expr>),
1760 Unary(UnOp, Box<Expr>),
1762 Lit(token::Lit),
1764 Cast(Box<Expr>, Box<Ty>),
1766 Type(Box<Expr>, Box<Ty>),
1771 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1776 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1783 While(Box<Expr>, Box<Block>, Option<Label>),
1787 ForLoop {
1793 pat: Box<Pat>,
1794 iter: Box<Expr>,
1795 body: Box<Block>,
1796 label: Option<Label>,
1797 kind: ForLoopKind,
1798 },
1799 Loop(Box<Block>, Option<Label>, Span),
1803 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1805 Closure(Box<Closure>),
1807 Block(Box<Block>, Option<Label>),
1809 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1815 Await(Box<Expr>, Span),
1817 Use(Box<Expr>, Span),
1819
1820 TryBlock(Box<Block>, Option<Box<Ty>>),
1828
1829 Assign(Box<Expr>, Box<Expr>, Span),
1832 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1836 Field(Box<Expr>, Ident),
1838 Index(Box<Expr>, Box<Expr>, Span),
1841 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1843 Underscore,
1845
1846 Path(Option<Box<QSelf>>, Path),
1851
1852 AddrOf(BorrowKind, Mutability, Box<Expr>),
1854 Break(Option<Label>, Option<Box<Expr>>),
1856 Continue(Option<Label>),
1858 Ret(Option<Box<Expr>>),
1860
1861 InlineAsm(Box<InlineAsm>),
1863
1864 OffsetOf(Box<Ty>, Vec<Ident>),
1869
1870 MacCall(Box<MacCall>),
1872
1873 Struct(Box<StructExpr>),
1877
1878 Repeat(Box<Expr>, AnonConst),
1883
1884 Paren(Box<Expr>),
1886
1887 Try(Box<Expr>),
1889
1890 Yield(YieldKind),
1892
1893 Yeet(Option<Box<Expr>>),
1896
1897 Become(Box<Expr>),
1901
1902 IncludedBytes(ByteSymbol),
1914
1915 FormatArgs(Box<FormatArgs>),
1917
1918 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1919
1920 Err(ErrorGuaranteed),
1922
1923 Dummy,
1925}
1926
1927#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1929pub enum ForLoopKind {
1930 For,
1931 ForAwait,
1932}
1933
1934#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1936pub enum GenBlockKind {
1937 Async,
1938 Gen,
1939 AsyncGen,
1940}
1941
1942impl fmt::Display for GenBlockKind {
1943 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1944 self.modifier().fmt(f)
1945 }
1946}
1947
1948impl GenBlockKind {
1949 pub fn modifier(&self) -> &'static str {
1950 match self {
1951 GenBlockKind::Async => "async",
1952 GenBlockKind::Gen => "gen",
1953 GenBlockKind::AsyncGen => "async gen",
1954 }
1955 }
1956}
1957
1958#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1960#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1961pub enum UnsafeBinderCastKind {
1962 Wrap,
1964 Unwrap,
1966}
1967
1968#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1983pub struct QSelf {
1984 pub ty: Box<Ty>,
1985
1986 pub path_span: Span,
1990 pub position: usize,
1991}
1992
1993#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1995pub enum CaptureBy {
1996 Value {
1998 move_kw: Span,
2000 },
2001 Ref,
2003 Use {
2009 use_kw: Span,
2011 },
2012}
2013
2014#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2016pub enum ClosureBinder {
2017 NotPresent,
2019 For {
2021 span: Span,
2028
2029 generic_params: ThinVec<GenericParam>,
2036 },
2037}
2038
2039#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2042pub struct MacCall {
2043 pub path: Path,
2044 pub args: Box<DelimArgs>,
2045}
2046
2047impl MacCall {
2048 pub fn span(&self) -> Span {
2049 self.path.span.to(self.args.dspan.entire())
2050 }
2051}
2052
2053#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2055pub enum AttrArgs {
2056 Empty,
2058 Delimited(DelimArgs),
2060 Eq {
2062 eq_span: Span,
2064 expr: Box<Expr>,
2065 },
2066}
2067
2068impl AttrArgs {
2069 pub fn span(&self) -> Option<Span> {
2070 match self {
2071 AttrArgs::Empty => None,
2072 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2073 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2074 }
2075 }
2076
2077 pub fn inner_tokens(&self) -> TokenStream {
2080 match self {
2081 AttrArgs::Empty => TokenStream::default(),
2082 AttrArgs::Delimited(args) => args.tokens.clone(),
2083 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2084 }
2085 }
2086}
2087
2088#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2090pub struct DelimArgs {
2091 pub dspan: DelimSpan,
2092 pub delim: Delimiter, pub tokens: TokenStream,
2094}
2095
2096impl DelimArgs {
2097 pub fn need_semicolon(&self) -> bool {
2100 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2101 }
2102}
2103
2104#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2106pub struct MacroDef {
2107 pub body: Box<DelimArgs>,
2108 pub macro_rules: bool,
2110
2111 pub eii_extern_target: Option<EiiExternTarget>,
2115}
2116
2117#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2118pub struct EiiExternTarget {
2119 pub extern_item_path: Path,
2121 pub impl_unsafe: bool,
2122 pub span: Span,
2123}
2124
2125#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2126#[derive(HashStable_Generic, Walkable)]
2127pub enum StrStyle {
2128 Cooked,
2130 Raw(u8),
2134}
2135
2136#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2138pub enum MatchKind {
2139 Prefix,
2141 Postfix,
2143}
2144
2145#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2147pub enum YieldKind {
2148 Prefix(Option<Box<Expr>>),
2150 Postfix(Box<Expr>),
2152}
2153
2154impl YieldKind {
2155 pub const fn expr(&self) -> Option<&Box<Expr>> {
2159 match self {
2160 YieldKind::Prefix(expr) => expr.as_ref(),
2161 YieldKind::Postfix(expr) => Some(expr),
2162 }
2163 }
2164
2165 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2167 match self {
2168 YieldKind::Prefix(expr) => expr.as_mut(),
2169 YieldKind::Postfix(expr) => Some(expr),
2170 }
2171 }
2172
2173 pub const fn same_kind(&self, other: &Self) -> bool {
2175 match (self, other) {
2176 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2177 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2178 _ => false,
2179 }
2180 }
2181}
2182
2183#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2185pub struct MetaItemLit {
2186 pub symbol: Symbol,
2188 pub suffix: Option<Symbol>,
2190 pub kind: LitKind,
2193 pub span: Span,
2194}
2195
2196#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2198pub struct StrLit {
2199 pub symbol: Symbol,
2201 pub suffix: Option<Symbol>,
2203 pub symbol_unescaped: Symbol,
2205 pub style: StrStyle,
2206 pub span: Span,
2207}
2208
2209impl StrLit {
2210 pub fn as_token_lit(&self) -> token::Lit {
2211 let token_kind = match self.style {
2212 StrStyle::Cooked => token::Str,
2213 StrStyle::Raw(n) => token::StrRaw(n),
2214 };
2215 token::Lit::new(token_kind, self.symbol, self.suffix)
2216 }
2217}
2218
2219#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2221#[derive(HashStable_Generic)]
2222pub enum LitIntType {
2223 Signed(IntTy),
2225 Unsigned(UintTy),
2227 Unsuffixed,
2229}
2230
2231#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2233#[derive(HashStable_Generic)]
2234pub enum LitFloatType {
2235 Suffixed(FloatTy),
2237 Unsuffixed,
2239}
2240
2241#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2248pub enum LitKind {
2249 Str(Symbol, StrStyle),
2252 ByteStr(ByteSymbol, StrStyle),
2255 CStr(ByteSymbol, StrStyle),
2259 Byte(u8),
2261 Char(char),
2263 Int(Pu128, LitIntType),
2265 Float(Symbol, LitFloatType),
2269 Bool(bool),
2271 Err(ErrorGuaranteed),
2273}
2274
2275impl LitKind {
2276 pub fn str(&self) -> Option<Symbol> {
2277 match *self {
2278 LitKind::Str(s, _) => Some(s),
2279 _ => None,
2280 }
2281 }
2282
2283 pub fn is_str(&self) -> bool {
2285 matches!(self, LitKind::Str(..))
2286 }
2287
2288 pub fn is_bytestr(&self) -> bool {
2290 matches!(self, LitKind::ByteStr(..))
2291 }
2292
2293 pub fn is_numeric(&self) -> bool {
2295 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2296 }
2297
2298 pub fn is_unsuffixed(&self) -> bool {
2301 !self.is_suffixed()
2302 }
2303
2304 pub fn is_suffixed(&self) -> bool {
2306 match *self {
2307 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2309 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2310 LitKind::Str(..)
2312 | LitKind::ByteStr(..)
2313 | LitKind::CStr(..)
2314 | LitKind::Byte(..)
2315 | LitKind::Char(..)
2316 | LitKind::Int(_, LitIntType::Unsuffixed)
2317 | LitKind::Float(_, LitFloatType::Unsuffixed)
2318 | LitKind::Bool(..)
2319 | LitKind::Err(_) => false,
2320 }
2321 }
2322}
2323
2324#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2327pub struct MutTy {
2328 pub ty: Box<Ty>,
2329 pub mutbl: Mutability,
2330}
2331
2332#[derive(Clone, Encodable, Decodable, Debug)]
2335pub struct FnSig {
2336 pub header: FnHeader,
2337 pub decl: Box<FnDecl>,
2338 pub span: Span,
2339}
2340
2341impl FnSig {
2342 pub fn header_span(&self) -> Span {
2344 match self.header.ext {
2345 Extern::Implicit(span) | Extern::Explicit(_, span) => {
2346 return self.span.with_hi(span.hi());
2347 }
2348 Extern::None => {}
2349 }
2350
2351 match self.header.safety {
2352 Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2353 Safety::Default => {}
2354 };
2355
2356 if let Some(coroutine_kind) = self.header.coroutine_kind {
2357 return self.span.with_hi(coroutine_kind.span().hi());
2358 }
2359
2360 if let Const::Yes(span) = self.header.constness {
2361 return self.span.with_hi(span.hi());
2362 }
2363
2364 self.span.shrink_to_lo()
2365 }
2366
2367 pub fn safety_span(&self) -> Span {
2369 match self.header.safety {
2370 Safety::Unsafe(span) | Safety::Safe(span) => span,
2371 Safety::Default => {
2372 if let Some(extern_span) = self.header.ext.span() {
2374 return extern_span.shrink_to_lo();
2375 }
2376
2377 self.header_span().shrink_to_hi()
2379 }
2380 }
2381 }
2382
2383 pub fn extern_span(&self) -> Span {
2385 self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2386 }
2387}
2388
2389#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2400pub struct AssocItemConstraint {
2401 pub id: NodeId,
2402 pub ident: Ident,
2403 pub gen_args: Option<GenericArgs>,
2404 pub kind: AssocItemConstraintKind,
2405 pub span: Span,
2406}
2407
2408#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2409pub enum Term {
2410 Ty(Box<Ty>),
2411 Const(AnonConst),
2412}
2413
2414impl From<Box<Ty>> for Term {
2415 fn from(v: Box<Ty>) -> Self {
2416 Term::Ty(v)
2417 }
2418}
2419
2420impl From<AnonConst> for Term {
2421 fn from(v: AnonConst) -> Self {
2422 Term::Const(v)
2423 }
2424}
2425
2426#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2428pub enum AssocItemConstraintKind {
2429 Equality { term: Term },
2436 Bound {
2438 #[visitable(extra = BoundKind::Bound)]
2439 bounds: GenericBounds,
2440 },
2441}
2442
2443#[derive(Encodable, Decodable, Debug, Walkable)]
2444pub struct Ty {
2445 pub id: NodeId,
2446 pub kind: TyKind,
2447 pub span: Span,
2448 pub tokens: Option<LazyAttrTokenStream>,
2449}
2450
2451impl Clone for Ty {
2452 fn clone(&self) -> Self {
2453 ensure_sufficient_stack(|| Self {
2454 id: self.id,
2455 kind: self.kind.clone(),
2456 span: self.span,
2457 tokens: self.tokens.clone(),
2458 })
2459 }
2460}
2461
2462impl From<Box<Ty>> for Ty {
2463 fn from(value: Box<Ty>) -> Self {
2464 *value
2465 }
2466}
2467
2468impl Ty {
2469 pub fn peel_refs(&self) -> &Self {
2470 let mut final_ty = self;
2471 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2472 {
2473 final_ty = ty;
2474 }
2475 final_ty
2476 }
2477
2478 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2479 match &self.kind {
2480 TyKind::Infer => true,
2481 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2482 _ => false,
2483 }
2484 }
2485}
2486
2487#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2488pub struct FnPtrTy {
2489 pub safety: Safety,
2490 pub ext: Extern,
2491 pub generic_params: ThinVec<GenericParam>,
2492 pub decl: Box<FnDecl>,
2493 pub decl_span: Span,
2496}
2497
2498#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2499pub struct UnsafeBinderTy {
2500 pub generic_params: ThinVec<GenericParam>,
2501 pub inner_ty: Box<Ty>,
2502}
2503
2504#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2508pub enum TyKind {
2509 Slice(Box<Ty>),
2511 Array(Box<Ty>, AnonConst),
2513 Ptr(MutTy),
2515 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2517 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2521 FnPtr(Box<FnPtrTy>),
2523 UnsafeBinder(Box<UnsafeBinderTy>),
2525 Never,
2527 Tup(ThinVec<Box<Ty>>),
2529 Path(Option<Box<QSelf>>, Path),
2534 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2537 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2544 Paren(Box<Ty>),
2546 Infer,
2549 ImplicitSelf,
2551 MacCall(Box<MacCall>),
2553 CVarArgs,
2555 Pat(Box<Ty>, Box<TyPat>),
2558 Dummy,
2560 Err(ErrorGuaranteed),
2562}
2563
2564impl TyKind {
2565 pub fn is_implicit_self(&self) -> bool {
2566 matches!(self, TyKind::ImplicitSelf)
2567 }
2568
2569 pub fn is_unit(&self) -> bool {
2570 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2571 }
2572
2573 pub fn is_simple_path(&self) -> Option<Symbol> {
2574 if let TyKind::Path(None, Path { segments, .. }) = &self
2575 && let [segment] = &segments[..]
2576 && segment.args.is_none()
2577 {
2578 Some(segment.ident.name)
2579 } else {
2580 None
2581 }
2582 }
2583
2584 pub fn maybe_scalar(&self) -> bool {
2592 let Some(ty_sym) = self.is_simple_path() else {
2593 return self.is_unit();
2595 };
2596 matches!(
2597 ty_sym,
2598 sym::i8
2599 | sym::i16
2600 | sym::i32
2601 | sym::i64
2602 | sym::i128
2603 | sym::u8
2604 | sym::u16
2605 | sym::u32
2606 | sym::u64
2607 | sym::u128
2608 | sym::f16
2609 | sym::f32
2610 | sym::f64
2611 | sym::f128
2612 | sym::char
2613 | sym::bool
2614 )
2615 }
2616}
2617
2618#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2620pub struct TyPat {
2621 pub id: NodeId,
2622 pub kind: TyPatKind,
2623 pub span: Span,
2624 pub tokens: Option<LazyAttrTokenStream>,
2625}
2626
2627#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2631pub enum TyPatKind {
2632 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2634
2635 NotNull,
2637
2638 Or(ThinVec<TyPat>),
2639
2640 Err(ErrorGuaranteed),
2642}
2643
2644#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2646#[repr(u8)]
2647pub enum TraitObjectSyntax {
2648 Dyn = 0,
2650 None = 1,
2651}
2652
2653unsafe impl Tag for TraitObjectSyntax {
2657 const BITS: u32 = 2;
2658
2659 fn into_usize(self) -> usize {
2660 self as u8 as usize
2661 }
2662
2663 unsafe fn from_usize(tag: usize) -> Self {
2664 match tag {
2665 0 => TraitObjectSyntax::Dyn,
2666 1 => TraitObjectSyntax::None,
2667 _ => unreachable!(),
2668 }
2669 }
2670}
2671
2672#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2673pub enum PreciseCapturingArg {
2674 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2676 Arg(Path, NodeId),
2678}
2679
2680#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2684pub enum InlineAsmRegOrRegClass {
2685 Reg(Symbol),
2686 RegClass(Symbol),
2687}
2688
2689#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2690pub struct InlineAsmOptions(u16);
2691bitflags::bitflags! {
2692 impl InlineAsmOptions: u16 {
2693 const PURE = 1 << 0;
2694 const NOMEM = 1 << 1;
2695 const READONLY = 1 << 2;
2696 const PRESERVES_FLAGS = 1 << 3;
2697 const NORETURN = 1 << 4;
2698 const NOSTACK = 1 << 5;
2699 const ATT_SYNTAX = 1 << 6;
2700 const RAW = 1 << 7;
2701 const MAY_UNWIND = 1 << 8;
2702 }
2703}
2704
2705impl InlineAsmOptions {
2706 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2707
2708 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2709 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2710
2711 pub fn human_readable_names(&self) -> Vec<&'static str> {
2712 let mut options = vec![];
2713
2714 if self.contains(InlineAsmOptions::PURE) {
2715 options.push("pure");
2716 }
2717 if self.contains(InlineAsmOptions::NOMEM) {
2718 options.push("nomem");
2719 }
2720 if self.contains(InlineAsmOptions::READONLY) {
2721 options.push("readonly");
2722 }
2723 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2724 options.push("preserves_flags");
2725 }
2726 if self.contains(InlineAsmOptions::NORETURN) {
2727 options.push("noreturn");
2728 }
2729 if self.contains(InlineAsmOptions::NOSTACK) {
2730 options.push("nostack");
2731 }
2732 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2733 options.push("att_syntax");
2734 }
2735 if self.contains(InlineAsmOptions::RAW) {
2736 options.push("raw");
2737 }
2738 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2739 options.push("may_unwind");
2740 }
2741
2742 options
2743 }
2744}
2745
2746impl std::fmt::Debug for InlineAsmOptions {
2747 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2748 bitflags::parser::to_writer(self, f)
2749 }
2750}
2751
2752#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2753pub enum InlineAsmTemplatePiece {
2754 String(Cow<'static, str>),
2755 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2756}
2757
2758impl fmt::Display for InlineAsmTemplatePiece {
2759 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2760 match self {
2761 Self::String(s) => {
2762 for c in s.chars() {
2763 match c {
2764 '{' => f.write_str("{{")?,
2765 '}' => f.write_str("}}")?,
2766 _ => c.fmt(f)?,
2767 }
2768 }
2769 Ok(())
2770 }
2771 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2772 write!(f, "{{{operand_idx}:{modifier}}}")
2773 }
2774 Self::Placeholder { operand_idx, modifier: None, .. } => {
2775 write!(f, "{{{operand_idx}}}")
2776 }
2777 }
2778 }
2779}
2780
2781impl InlineAsmTemplatePiece {
2782 pub fn to_string(s: &[Self]) -> String {
2784 use fmt::Write;
2785 let mut out = String::new();
2786 for p in s.iter() {
2787 let _ = write!(out, "{p}");
2788 }
2789 out
2790 }
2791}
2792
2793#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2801pub struct InlineAsmSym {
2802 pub id: NodeId,
2803 pub qself: Option<Box<QSelf>>,
2804 pub path: Path,
2805}
2806
2807#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2811pub enum InlineAsmOperand {
2812 In {
2813 reg: InlineAsmRegOrRegClass,
2814 expr: Box<Expr>,
2815 },
2816 Out {
2817 reg: InlineAsmRegOrRegClass,
2818 late: bool,
2819 expr: Option<Box<Expr>>,
2820 },
2821 InOut {
2822 reg: InlineAsmRegOrRegClass,
2823 late: bool,
2824 expr: Box<Expr>,
2825 },
2826 SplitInOut {
2827 reg: InlineAsmRegOrRegClass,
2828 late: bool,
2829 in_expr: Box<Expr>,
2830 out_expr: Option<Box<Expr>>,
2831 },
2832 Const {
2833 anon_const: AnonConst,
2834 },
2835 Sym {
2836 sym: InlineAsmSym,
2837 },
2838 Label {
2839 block: Box<Block>,
2840 },
2841}
2842
2843impl InlineAsmOperand {
2844 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2845 match self {
2846 Self::In { reg, .. }
2847 | Self::Out { reg, .. }
2848 | Self::InOut { reg, .. }
2849 | Self::SplitInOut { reg, .. } => Some(reg),
2850 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2851 }
2852 }
2853}
2854
2855#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2856pub enum AsmMacro {
2857 Asm,
2859 GlobalAsm,
2861 NakedAsm,
2863}
2864
2865impl AsmMacro {
2866 pub const fn macro_name(self) -> &'static str {
2867 match self {
2868 AsmMacro::Asm => "asm",
2869 AsmMacro::GlobalAsm => "global_asm",
2870 AsmMacro::NakedAsm => "naked_asm",
2871 }
2872 }
2873
2874 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2875 match self {
2876 AsmMacro::Asm => true,
2877 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2878 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2879 }
2880 }
2881
2882 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2883 match self {
2884 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2885 AsmMacro::GlobalAsm => true,
2886 AsmMacro::NakedAsm => true,
2887 }
2888 }
2889}
2890
2891#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2895pub struct InlineAsm {
2896 pub asm_macro: AsmMacro,
2897 pub template: Vec<InlineAsmTemplatePiece>,
2898 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2899 pub operands: Vec<(InlineAsmOperand, Span)>,
2900 pub clobber_abis: Vec<(Symbol, Span)>,
2901 #[visitable(ignore)]
2902 pub options: InlineAsmOptions,
2903 pub line_spans: Vec<Span>,
2904}
2905
2906#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2910pub struct Param {
2911 pub attrs: AttrVec,
2912 pub ty: Box<Ty>,
2913 pub pat: Box<Pat>,
2914 pub id: NodeId,
2915 pub span: Span,
2916 pub is_placeholder: bool,
2917}
2918
2919#[derive(Clone, Encodable, Decodable, Debug)]
2923pub enum SelfKind {
2924 Value(Mutability),
2926 Region(Option<Lifetime>, Mutability),
2928 Pinned(Option<Lifetime>, Mutability),
2930 Explicit(Box<Ty>, Mutability),
2932}
2933
2934impl SelfKind {
2935 pub fn to_ref_suggestion(&self) -> String {
2936 match self {
2937 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2938 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2939 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2940 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2941 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2942 unreachable!("if we had an explicit self, we wouldn't be here")
2943 }
2944 }
2945 }
2946}
2947
2948pub type ExplicitSelf = Spanned<SelfKind>;
2949
2950impl Param {
2951 pub fn to_self(&self) -> Option<ExplicitSelf> {
2953 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2954 if ident.name == kw::SelfLower {
2955 return match self.ty.kind {
2956 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2957 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2958 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2959 }
2960 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2961 if ty.kind.is_implicit_self() =>
2962 {
2963 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2964 }
2965 _ => Some(respan(
2966 self.pat.span.to(self.ty.span),
2967 SelfKind::Explicit(self.ty.clone(), mutbl),
2968 )),
2969 };
2970 }
2971 }
2972 None
2973 }
2974
2975 pub fn is_self(&self) -> bool {
2977 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2978 ident.name == kw::SelfLower
2979 } else {
2980 false
2981 }
2982 }
2983
2984 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2986 let span = eself.span.to(eself_ident.span);
2987 let infer_ty = Box::new(Ty {
2988 id: DUMMY_NODE_ID,
2989 kind: TyKind::ImplicitSelf,
2990 span: eself_ident.span,
2991 tokens: None,
2992 });
2993 let (mutbl, ty) = match eself.node {
2994 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2995 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2996 SelfKind::Region(lt, mutbl) => (
2997 Mutability::Not,
2998 Box::new(Ty {
2999 id: DUMMY_NODE_ID,
3000 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
3001 span,
3002 tokens: None,
3003 }),
3004 ),
3005 SelfKind::Pinned(lt, mutbl) => (
3006 mutbl,
3007 Box::new(Ty {
3008 id: DUMMY_NODE_ID,
3009 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
3010 span,
3011 tokens: None,
3012 }),
3013 ),
3014 };
3015 Param {
3016 attrs,
3017 pat: Box::new(Pat {
3018 id: DUMMY_NODE_ID,
3019 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
3020 span,
3021 tokens: None,
3022 }),
3023 span,
3024 ty,
3025 id: DUMMY_NODE_ID,
3026 is_placeholder: false,
3027 }
3028 }
3029}
3030
3031#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3038pub struct FnDecl {
3039 pub inputs: ThinVec<Param>,
3040 pub output: FnRetTy,
3041}
3042
3043impl FnDecl {
3044 pub fn has_self(&self) -> bool {
3045 self.inputs.get(0).is_some_and(Param::is_self)
3046 }
3047 pub fn c_variadic(&self) -> bool {
3048 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3049 }
3050}
3051
3052#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3054pub enum IsAuto {
3055 Yes,
3056 No,
3057}
3058
3059#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3061#[derive(HashStable_Generic, Walkable)]
3062pub enum Safety {
3063 Unsafe(Span),
3065 Safe(Span),
3067 Default,
3070}
3071
3072#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3078pub enum CoroutineKind {
3079 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3081 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3083 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3085}
3086
3087impl CoroutineKind {
3088 pub fn span(self) -> Span {
3089 match self {
3090 CoroutineKind::Async { span, .. } => span,
3091 CoroutineKind::Gen { span, .. } => span,
3092 CoroutineKind::AsyncGen { span, .. } => span,
3093 }
3094 }
3095
3096 pub fn as_str(self) -> &'static str {
3097 match self {
3098 CoroutineKind::Async { .. } => "async",
3099 CoroutineKind::Gen { .. } => "gen",
3100 CoroutineKind::AsyncGen { .. } => "async gen",
3101 }
3102 }
3103
3104 pub fn closure_id(self) -> NodeId {
3105 match self {
3106 CoroutineKind::Async { closure_id, .. }
3107 | CoroutineKind::Gen { closure_id, .. }
3108 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3109 }
3110 }
3111
3112 pub fn return_id(self) -> (NodeId, Span) {
3115 match self {
3116 CoroutineKind::Async { return_impl_trait_id, span, .. }
3117 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3118 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3119 (return_impl_trait_id, span)
3120 }
3121 }
3122 }
3123}
3124
3125#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3126#[derive(HashStable_Generic, Walkable)]
3127pub enum Const {
3128 Yes(Span),
3129 No,
3130}
3131
3132#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3135pub enum Defaultness {
3136 Default(Span),
3137 Final,
3138}
3139
3140#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3141pub enum ImplPolarity {
3142 Positive,
3144 Negative(Span),
3146}
3147
3148impl fmt::Debug for ImplPolarity {
3149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3150 match *self {
3151 ImplPolarity::Positive => "positive".fmt(f),
3152 ImplPolarity::Negative(_) => "negative".fmt(f),
3153 }
3154 }
3155}
3156
3157#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3159#[derive(HashStable_Generic, Walkable)]
3160pub enum BoundPolarity {
3161 Positive,
3163 Negative(Span),
3165 Maybe(Span),
3167}
3168
3169impl BoundPolarity {
3170 pub fn as_str(self) -> &'static str {
3171 match self {
3172 Self::Positive => "",
3173 Self::Negative(_) => "!",
3174 Self::Maybe(_) => "?",
3175 }
3176 }
3177}
3178
3179#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3181#[derive(HashStable_Generic, Walkable)]
3182pub enum BoundConstness {
3183 Never,
3185 Always(Span),
3187 Maybe(Span),
3189}
3190
3191impl BoundConstness {
3192 pub fn as_str(self) -> &'static str {
3193 match self {
3194 Self::Never => "",
3195 Self::Always(_) => "const",
3196 Self::Maybe(_) => "[const]",
3197 }
3198 }
3199}
3200
3201#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3203#[derive(HashStable_Generic, Walkable)]
3204pub enum BoundAsyncness {
3205 Normal,
3207 Async(Span),
3209}
3210
3211impl BoundAsyncness {
3212 pub fn as_str(self) -> &'static str {
3213 match self {
3214 Self::Normal => "",
3215 Self::Async(_) => "async",
3216 }
3217 }
3218}
3219
3220#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3221pub enum FnRetTy {
3222 Default(Span),
3227 Ty(Box<Ty>),
3229}
3230
3231impl FnRetTy {
3232 pub fn span(&self) -> Span {
3233 match self {
3234 &FnRetTy::Default(span) => span,
3235 FnRetTy::Ty(ty) => ty.span,
3236 }
3237 }
3238}
3239
3240#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3241pub enum Inline {
3242 Yes,
3243 No { had_parse_error: Result<(), ErrorGuaranteed> },
3244}
3245
3246#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3248pub enum ModKind {
3249 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3254 Unloaded,
3256}
3257
3258#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3259pub struct ModSpans {
3260 pub inner_span: Span,
3263 pub inject_use_span: Span,
3264}
3265
3266#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3270pub struct ForeignMod {
3271 pub extern_span: Span,
3273 pub safety: Safety,
3276 pub abi: Option<StrLit>,
3277 pub items: ThinVec<Box<ForeignItem>>,
3278}
3279
3280#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3281pub struct EnumDef {
3282 pub variants: ThinVec<Variant>,
3283}
3284
3285#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3287pub struct Variant {
3288 pub attrs: AttrVec,
3290 pub id: NodeId,
3292 pub span: Span,
3294 pub vis: Visibility,
3296 pub ident: Ident,
3298
3299 pub data: VariantData,
3301 pub disr_expr: Option<AnonConst>,
3303 pub is_placeholder: bool,
3305}
3306
3307#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3309pub enum UseTreeKind {
3310 Simple(Option<Ident>),
3312 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3321 Glob,
3323}
3324
3325#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3328pub struct UseTree {
3329 pub prefix: Path,
3330 pub kind: UseTreeKind,
3331 pub span: Span,
3332}
3333
3334impl UseTree {
3335 pub fn ident(&self) -> Ident {
3336 match self.kind {
3337 UseTreeKind::Simple(Some(rename)) => rename,
3338 UseTreeKind::Simple(None) => {
3339 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3340 }
3341 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3342 }
3343 }
3344}
3345
3346#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3350pub enum AttrStyle {
3351 Outer,
3352 Inner,
3353}
3354
3355pub type AttrVec = ThinVec<Attribute>;
3357
3358#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3360pub struct Attribute {
3361 pub kind: AttrKind,
3362 pub id: AttrId,
3363 pub style: AttrStyle,
3366 pub span: Span,
3367}
3368
3369#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3370pub enum AttrKind {
3371 Normal(Box<NormalAttr>),
3373
3374 DocComment(CommentKind, Symbol),
3378}
3379
3380#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3381pub struct NormalAttr {
3382 pub item: AttrItem,
3383 pub tokens: Option<LazyAttrTokenStream>,
3385}
3386
3387impl NormalAttr {
3388 pub fn from_ident(ident: Ident) -> Self {
3389 Self {
3390 item: AttrItem {
3391 unsafety: Safety::Default,
3392 path: Path::from_ident(ident),
3393 args: AttrArgs::Empty,
3394 tokens: None,
3395 },
3396 tokens: None,
3397 }
3398 }
3399}
3400
3401#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3402pub struct AttrItem {
3403 pub unsafety: Safety,
3404 pub path: Path,
3405 pub args: AttrArgs,
3406 pub tokens: Option<LazyAttrTokenStream>,
3408}
3409
3410impl AttrItem {
3411 pub fn is_valid_for_outer_style(&self) -> bool {
3412 self.path == sym::cfg_attr
3413 || self.path == sym::cfg
3414 || self.path == sym::forbid
3415 || self.path == sym::warn
3416 || self.path == sym::allow
3417 || self.path == sym::deny
3418 }
3419}
3420
3421#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3428pub struct TraitRef {
3429 pub path: Path,
3430 pub ref_id: NodeId,
3431}
3432
3433#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3435pub enum Parens {
3436 Yes,
3437 No,
3438}
3439
3440#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3441pub struct PolyTraitRef {
3442 pub bound_generic_params: ThinVec<GenericParam>,
3444
3445 pub modifiers: TraitBoundModifiers,
3447
3448 pub trait_ref: TraitRef,
3450
3451 pub span: Span,
3452
3453 pub parens: Parens,
3456}
3457
3458impl PolyTraitRef {
3459 pub fn new(
3460 generic_params: ThinVec<GenericParam>,
3461 path: Path,
3462 modifiers: TraitBoundModifiers,
3463 span: Span,
3464 parens: Parens,
3465 ) -> Self {
3466 PolyTraitRef {
3467 bound_generic_params: generic_params,
3468 modifiers,
3469 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3470 span,
3471 parens,
3472 }
3473 }
3474}
3475
3476#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3477pub struct Visibility {
3478 pub kind: VisibilityKind,
3479 pub span: Span,
3480 pub tokens: Option<LazyAttrTokenStream>,
3481}
3482
3483#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3484pub enum VisibilityKind {
3485 Public,
3486 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3487 Inherited,
3488}
3489
3490impl VisibilityKind {
3491 pub fn is_pub(&self) -> bool {
3492 matches!(self, VisibilityKind::Public)
3493 }
3494}
3495
3496#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3500pub struct FieldDef {
3501 pub attrs: AttrVec,
3502 pub id: NodeId,
3503 pub span: Span,
3504 pub vis: Visibility,
3505 pub safety: Safety,
3506 pub ident: Option<Ident>,
3507
3508 pub ty: Box<Ty>,
3509 pub default: Option<AnonConst>,
3510 pub is_placeholder: bool,
3511}
3512
3513#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3515pub enum Recovered {
3516 No,
3517 Yes(ErrorGuaranteed),
3518}
3519
3520#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3522pub enum VariantData {
3523 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3527 Tuple(ThinVec<FieldDef>, NodeId),
3531 Unit(NodeId),
3535}
3536
3537impl VariantData {
3538 pub fn fields(&self) -> &[FieldDef] {
3540 match self {
3541 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3542 _ => &[],
3543 }
3544 }
3545
3546 pub fn ctor_node_id(&self) -> Option<NodeId> {
3548 match *self {
3549 VariantData::Struct { .. } => None,
3550 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3551 }
3552 }
3553}
3554
3555#[derive(Clone, Encodable, Decodable, Debug)]
3557pub struct Item<K = ItemKind> {
3558 pub attrs: AttrVec,
3559 pub id: NodeId,
3560 pub span: Span,
3561 pub vis: Visibility,
3562
3563 pub kind: K,
3564
3565 pub tokens: Option<LazyAttrTokenStream>,
3573}
3574
3575impl Item {
3576 pub fn span_with_attributes(&self) -> Span {
3578 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3579 }
3580
3581 pub fn opt_generics(&self) -> Option<&Generics> {
3582 match &self.kind {
3583 ItemKind::ExternCrate(..)
3584 | ItemKind::Use(_)
3585 | ItemKind::Mod(..)
3586 | ItemKind::ForeignMod(_)
3587 | ItemKind::GlobalAsm(_)
3588 | ItemKind::MacCall(_)
3589 | ItemKind::Delegation(_)
3590 | ItemKind::DelegationMac(_)
3591 | ItemKind::MacroDef(..) => None,
3592 ItemKind::Static(_) => None,
3593 ItemKind::Const(i) => Some(&i.generics),
3594 ItemKind::Fn(i) => Some(&i.generics),
3595 ItemKind::TyAlias(i) => Some(&i.generics),
3596 ItemKind::TraitAlias(i) => Some(&i.generics),
3597
3598 ItemKind::Enum(_, generics, _)
3599 | ItemKind::Struct(_, generics, _)
3600 | ItemKind::Union(_, generics, _) => Some(&generics),
3601 ItemKind::Trait(i) => Some(&i.generics),
3602 ItemKind::Impl(i) => Some(&i.generics),
3603 }
3604 }
3605}
3606
3607#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3609pub enum Extern {
3610 None,
3614 Implicit(Span),
3620 Explicit(StrLit, Span),
3624}
3625
3626impl Extern {
3627 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3628 match abi {
3629 Some(name) => Extern::Explicit(name, span),
3630 None => Extern::Implicit(span),
3631 }
3632 }
3633
3634 pub fn span(self) -> Option<Span> {
3635 match self {
3636 Extern::None => None,
3637 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3638 }
3639 }
3640}
3641
3642#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3647pub struct FnHeader {
3648 pub constness: Const,
3650 pub coroutine_kind: Option<CoroutineKind>,
3652 pub safety: Safety,
3654 pub ext: Extern,
3656}
3657
3658impl FnHeader {
3659 pub fn has_qualifiers(&self) -> bool {
3661 let Self { safety, coroutine_kind, constness, ext } = self;
3662 matches!(safety, Safety::Unsafe(_))
3663 || coroutine_kind.is_some()
3664 || matches!(constness, Const::Yes(_))
3665 || !matches!(ext, Extern::None)
3666 }
3667}
3668
3669impl Default for FnHeader {
3670 fn default() -> FnHeader {
3671 FnHeader {
3672 safety: Safety::Default,
3673 coroutine_kind: None,
3674 constness: Const::No,
3675 ext: Extern::None,
3676 }
3677 }
3678}
3679
3680#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3681pub struct TraitAlias {
3682 pub constness: Const,
3683 pub ident: Ident,
3684 pub generics: Generics,
3685 #[visitable(extra = BoundKind::Bound)]
3686 pub bounds: GenericBounds,
3687}
3688
3689#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3690pub struct Trait {
3691 pub constness: Const,
3692 pub safety: Safety,
3693 pub is_auto: IsAuto,
3694 pub ident: Ident,
3695 pub generics: Generics,
3696 #[visitable(extra = BoundKind::SuperTraits)]
3697 pub bounds: GenericBounds,
3698 #[visitable(extra = AssocCtxt::Trait)]
3699 pub items: ThinVec<Box<AssocItem>>,
3700}
3701
3702#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3703pub struct TyAlias {
3704 pub defaultness: Defaultness,
3705 pub ident: Ident,
3706 pub generics: Generics,
3707 pub after_where_clause: WhereClause,
3722 #[visitable(extra = BoundKind::Bound)]
3723 pub bounds: GenericBounds,
3724 pub ty: Option<Box<Ty>>,
3725}
3726
3727#[derive(Clone, Encodable, Decodable, Debug)]
3728pub struct Impl {
3729 pub generics: Generics,
3730 pub constness: Const,
3731 pub of_trait: Option<Box<TraitImplHeader>>,
3732 pub self_ty: Box<Ty>,
3733 pub items: ThinVec<Box<AssocItem>>,
3734}
3735
3736#[derive(Clone, Encodable, Decodable, Debug)]
3737pub struct TraitImplHeader {
3738 pub defaultness: Defaultness,
3739 pub safety: Safety,
3740 pub polarity: ImplPolarity,
3741 pub trait_ref: TraitRef,
3742}
3743
3744#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3745pub struct FnContract {
3746 pub declarations: ThinVec<Stmt>,
3749 pub requires: Option<Box<Expr>>,
3750 pub ensures: Option<Box<Expr>>,
3751}
3752
3753#[derive(Clone, Encodable, Decodable, Debug)]
3754pub struct Fn {
3755 pub defaultness: Defaultness,
3756 pub ident: Ident,
3757 pub generics: Generics,
3758 pub sig: FnSig,
3759 pub contract: Option<Box<FnContract>>,
3760 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3761 pub body: Option<Box<Block>>,
3762
3763 pub eii_impls: ThinVec<EiiImpl>,
3767}
3768
3769#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3770pub struct EiiImpl {
3771 pub node_id: NodeId,
3772 pub eii_macro_path: Path,
3773 pub impl_safety: Safety,
3774 pub span: Span,
3775 pub inner_span: Span,
3776 pub is_default: bool,
3777}
3778
3779#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3780pub struct Delegation {
3781 pub id: NodeId,
3783 pub qself: Option<Box<QSelf>>,
3784 pub path: Path,
3785 pub ident: Ident,
3786 pub rename: Option<Ident>,
3787 pub body: Option<Box<Block>>,
3788 pub from_glob: bool,
3790}
3791
3792#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3793pub struct DelegationMac {
3794 pub qself: Option<Box<QSelf>>,
3795 pub prefix: Path,
3796 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3798 pub body: Option<Box<Block>>,
3799}
3800
3801#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3802pub struct StaticItem {
3803 pub ident: Ident,
3804 pub ty: Box<Ty>,
3805 pub safety: Safety,
3806 pub mutability: Mutability,
3807 pub expr: Option<Box<Expr>>,
3808 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3809}
3810
3811#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3812pub struct ConstItem {
3813 pub defaultness: Defaultness,
3814 pub ident: Ident,
3815 pub generics: Generics,
3816 pub ty: Box<Ty>,
3817 pub rhs: Option<ConstItemRhs>,
3818 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3819}
3820
3821#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3822pub enum ConstItemRhs {
3823 TypeConst(AnonConst),
3824 Body(Box<Expr>),
3825}
3826
3827impl ConstItemRhs {
3828 pub fn span(&self) -> Span {
3829 self.expr().span
3830 }
3831
3832 pub fn expr(&self) -> &Expr {
3833 match self {
3834 ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
3835 ConstItemRhs::Body(expr) => expr,
3836 }
3837 }
3838}
3839
3840#[derive(Clone, Encodable, Decodable, Debug)]
3842pub enum ItemKind {
3843 ExternCrate(Option<Symbol>, Ident),
3847 Use(UseTree),
3851 Static(Box<StaticItem>),
3855 Const(Box<ConstItem>),
3859 Fn(Box<Fn>),
3863 Mod(Safety, Ident, ModKind),
3869 ForeignMod(ForeignMod),
3873 GlobalAsm(Box<InlineAsm>),
3875 TyAlias(Box<TyAlias>),
3879 Enum(Ident, Generics, EnumDef),
3883 Struct(Ident, Generics, VariantData),
3887 Union(Ident, Generics, VariantData),
3891 Trait(Box<Trait>),
3895 TraitAlias(Box<TraitAlias>),
3899 Impl(Impl),
3903 MacCall(Box<MacCall>),
3907 MacroDef(Ident, MacroDef),
3909 Delegation(Box<Delegation>),
3913 DelegationMac(Box<DelegationMac>),
3916}
3917
3918impl ItemKind {
3919 pub fn ident(&self) -> Option<Ident> {
3920 match *self {
3921 ItemKind::ExternCrate(_, ident)
3922 | ItemKind::Static(box StaticItem { ident, .. })
3923 | ItemKind::Const(box ConstItem { ident, .. })
3924 | ItemKind::Fn(box Fn { ident, .. })
3925 | ItemKind::Mod(_, ident, _)
3926 | ItemKind::TyAlias(box TyAlias { ident, .. })
3927 | ItemKind::Enum(ident, ..)
3928 | ItemKind::Struct(ident, ..)
3929 | ItemKind::Union(ident, ..)
3930 | ItemKind::Trait(box Trait { ident, .. })
3931 | ItemKind::TraitAlias(box TraitAlias { ident, .. })
3932 | ItemKind::MacroDef(ident, _)
3933 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3934
3935 ItemKind::Use(_)
3936 | ItemKind::ForeignMod(_)
3937 | ItemKind::GlobalAsm(_)
3938 | ItemKind::Impl(_)
3939 | ItemKind::MacCall(_)
3940 | ItemKind::DelegationMac(_) => None,
3941 }
3942 }
3943
3944 pub fn article(&self) -> &'static str {
3946 use ItemKind::*;
3947 match self {
3948 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3949 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3950 | Delegation(..) | DelegationMac(..) => "a",
3951 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3952 }
3953 }
3954
3955 pub fn descr(&self) -> &'static str {
3956 match self {
3957 ItemKind::ExternCrate(..) => "extern crate",
3958 ItemKind::Use(..) => "`use` import",
3959 ItemKind::Static(..) => "static item",
3960 ItemKind::Const(..) => "constant item",
3961 ItemKind::Fn(..) => "function",
3962 ItemKind::Mod(..) => "module",
3963 ItemKind::ForeignMod(..) => "extern block",
3964 ItemKind::GlobalAsm(..) => "global asm item",
3965 ItemKind::TyAlias(..) => "type alias",
3966 ItemKind::Enum(..) => "enum",
3967 ItemKind::Struct(..) => "struct",
3968 ItemKind::Union(..) => "union",
3969 ItemKind::Trait(..) => "trait",
3970 ItemKind::TraitAlias(..) => "trait alias",
3971 ItemKind::MacCall(..) => "item macro invocation",
3972 ItemKind::MacroDef(..) => "macro definition",
3973 ItemKind::Impl { .. } => "implementation",
3974 ItemKind::Delegation(..) => "delegated function",
3975 ItemKind::DelegationMac(..) => "delegation",
3976 }
3977 }
3978
3979 pub fn generics(&self) -> Option<&Generics> {
3980 match self {
3981 Self::Fn(box Fn { generics, .. })
3982 | Self::TyAlias(box TyAlias { generics, .. })
3983 | Self::Const(box ConstItem { generics, .. })
3984 | Self::Enum(_, generics, _)
3985 | Self::Struct(_, generics, _)
3986 | Self::Union(_, generics, _)
3987 | Self::Trait(box Trait { generics, .. })
3988 | Self::TraitAlias(box TraitAlias { generics, .. })
3989 | Self::Impl(Impl { generics, .. }) => Some(generics),
3990 _ => None,
3991 }
3992 }
3993}
3994
3995pub type AssocItem = Item<AssocItemKind>;
3998
3999#[derive(Clone, Encodable, Decodable, Debug)]
4007pub enum AssocItemKind {
4008 Const(Box<ConstItem>),
4011 Fn(Box<Fn>),
4013 Type(Box<TyAlias>),
4015 MacCall(Box<MacCall>),
4017 Delegation(Box<Delegation>),
4019 DelegationMac(Box<DelegationMac>),
4021}
4022
4023impl AssocItemKind {
4024 pub fn ident(&self) -> Option<Ident> {
4025 match *self {
4026 AssocItemKind::Const(box ConstItem { ident, .. })
4027 | AssocItemKind::Fn(box Fn { ident, .. })
4028 | AssocItemKind::Type(box TyAlias { ident, .. })
4029 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
4030
4031 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4032 }
4033 }
4034
4035 pub fn defaultness(&self) -> Defaultness {
4036 match *self {
4037 Self::Const(box ConstItem { defaultness, .. })
4038 | Self::Fn(box Fn { defaultness, .. })
4039 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4040 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
4041 Defaultness::Final
4042 }
4043 }
4044 }
4045}
4046
4047impl From<AssocItemKind> for ItemKind {
4048 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4049 match assoc_item_kind {
4050 AssocItemKind::Const(item) => ItemKind::Const(item),
4051 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4052 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4053 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4054 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4055 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4056 }
4057 }
4058}
4059
4060impl TryFrom<ItemKind> for AssocItemKind {
4061 type Error = ItemKind;
4062
4063 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4064 Ok(match item_kind {
4065 ItemKind::Const(item) => AssocItemKind::Const(item),
4066 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4067 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4068 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4069 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4070 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4071 _ => return Err(item_kind),
4072 })
4073 }
4074}
4075
4076#[derive(Clone, Encodable, Decodable, Debug)]
4078pub enum ForeignItemKind {
4079 Static(Box<StaticItem>),
4081 Fn(Box<Fn>),
4083 TyAlias(Box<TyAlias>),
4085 MacCall(Box<MacCall>),
4087}
4088
4089impl ForeignItemKind {
4090 pub fn ident(&self) -> Option<Ident> {
4091 match *self {
4092 ForeignItemKind::Static(box StaticItem { ident, .. })
4093 | ForeignItemKind::Fn(box Fn { ident, .. })
4094 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4095
4096 ForeignItemKind::MacCall(_) => None,
4097 }
4098 }
4099}
4100
4101impl From<ForeignItemKind> for ItemKind {
4102 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4103 match foreign_item_kind {
4104 ForeignItemKind::Static(box static_foreign_item) => {
4105 ItemKind::Static(Box::new(static_foreign_item))
4106 }
4107 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4108 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4109 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4110 }
4111 }
4112}
4113
4114impl TryFrom<ItemKind> for ForeignItemKind {
4115 type Error = ItemKind;
4116
4117 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4118 Ok(match item_kind {
4119 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4120 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4121 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4122 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4123 _ => return Err(item_kind),
4124 })
4125 }
4126}
4127
4128pub type ForeignItem = Item<ForeignItemKind>;
4129
4130#[cfg(target_pointer_width = "64")]
4132mod size_asserts {
4133 use rustc_data_structures::static_assert_size;
4134
4135 use super::*;
4136 static_assert_size!(AssocItem, 80);
4138 static_assert_size!(AssocItemKind, 16);
4139 static_assert_size!(Attribute, 32);
4140 static_assert_size!(Block, 32);
4141 static_assert_size!(Expr, 72);
4142 static_assert_size!(ExprKind, 40);
4143 static_assert_size!(Fn, 192);
4144 static_assert_size!(ForeignItem, 80);
4145 static_assert_size!(ForeignItemKind, 16);
4146 static_assert_size!(GenericArg, 24);
4147 static_assert_size!(GenericBound, 88);
4148 static_assert_size!(Generics, 40);
4149 static_assert_size!(Impl, 80);
4150 static_assert_size!(Item, 152);
4151 static_assert_size!(ItemKind, 88);
4152 static_assert_size!(LitKind, 24);
4153 static_assert_size!(Local, 96);
4154 static_assert_size!(MetaItemLit, 40);
4155 static_assert_size!(Param, 40);
4156 static_assert_size!(Pat, 80);
4157 static_assert_size!(PatKind, 56);
4158 static_assert_size!(Path, 24);
4159 static_assert_size!(PathSegment, 24);
4160 static_assert_size!(Stmt, 32);
4161 static_assert_size!(StmtKind, 16);
4162 static_assert_size!(TraitImplHeader, 72);
4163 static_assert_size!(Ty, 64);
4164 static_assert_size!(TyKind, 40);
4165 }