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
37use crate::attr::data_structures::CfgEntry;
38pub use crate::format::*;
39use crate::token::{self, CommentKind, Delimiter};
40use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
41use crate::util::parser::{ExprPrecedence, Fixity};
42use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
55pub struct Label {
56 pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "label({:?})", self.ident)
62 }
63}
64
65#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
68pub struct Lifetime {
69 pub id: NodeId,
70 pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "lifetime({}: {})", self.id, self)
76 }
77}
78
79impl fmt::Display for Lifetime {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}", self.ident.name)
82 }
83}
84
85#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
102 #[inline]
103 fn eq(&self, name: &Symbol) -> bool {
104 if let [segment] = self.segments.as_ref()
105 && segment == name
106 {
107 true
108 } else {
109 false
110 }
111 }
112}
113
114impl PartialEq<&[Symbol]> for Path {
116 #[inline]
117 fn eq(&self, names: &&[Symbol]) -> bool {
118 self.segments.iter().eq(*names)
119 }
120}
121
122impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
123 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
124 self.segments.len().hash_stable(hcx, hasher);
125 for segment in &self.segments {
126 segment.ident.hash_stable(hcx, hasher);
127 }
128 }
129}
130
131impl Path {
132 pub fn from_ident(ident: Ident) -> Path {
135 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
136 }
137
138 pub fn is_global(&self) -> bool {
139 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
140 }
141
142 #[tracing::instrument(level = "debug", ret)]
148 pub fn is_potential_trivial_const_arg(&self) -> bool {
149 self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
150 }
151}
152
153pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
165 let mut iter = path.into_iter();
170 let len_hint = iter.size_hint().1.unwrap_or(1);
171 let mut s = String::with_capacity(len_hint * 8);
172
173 let first_sym = *iter.next().unwrap().borrow();
174 if first_sym != kw::PathRoot {
175 s.push_str(first_sym.as_str());
176 }
177 for sym in iter {
178 let sym = *sym.borrow();
179 debug_assert_ne!(sym, kw::PathRoot);
180 s.push_str("::");
181 s.push_str(sym.as_str());
182 }
183 s
184}
185
186pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
189 let mut iter = path.into_iter();
190 let len_hint = iter.size_hint().1.unwrap_or(1);
191 let mut s = String::with_capacity(len_hint * 8);
192
193 let first_ident = *iter.next().unwrap().borrow();
194 if first_ident.name != kw::PathRoot {
195 s.push_str(&first_ident.to_string());
196 }
197 for ident in iter {
198 let ident = *ident.borrow();
199 debug_assert_ne!(ident.name, kw::PathRoot);
200 s.push_str("::");
201 s.push_str(&ident.to_string());
202 }
203 s
204}
205
206#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
210pub struct PathSegment {
211 pub ident: Ident,
213
214 pub id: NodeId,
215
216 pub args: Option<Box<GenericArgs>>,
223}
224
225impl PartialEq<Symbol> for PathSegment {
227 #[inline]
228 fn eq(&self, name: &Symbol) -> bool {
229 self.args.is_none() && self.ident.name == *name
230 }
231}
232
233impl PathSegment {
234 pub fn from_ident(ident: Ident) -> Self {
235 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
236 }
237
238 pub fn path_root(span: Span) -> Self {
239 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
240 }
241
242 pub fn span(&self) -> Span {
243 match &self.args {
244 Some(args) => self.ident.span.to(args.span()),
245 None => self.ident.span,
246 }
247 }
248}
249
250#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
254pub enum GenericArgs {
255 AngleBracketed(AngleBracketedArgs),
257 Parenthesized(ParenthesizedArgs),
259 ParenthesizedElided(Span),
261}
262
263impl GenericArgs {
264 pub fn is_angle_bracketed(&self) -> bool {
265 matches!(self, AngleBracketed(..))
266 }
267
268 pub fn span(&self) -> Span {
269 match self {
270 AngleBracketed(data) => data.span,
271 Parenthesized(data) => data.span,
272 ParenthesizedElided(span) => *span,
273 }
274 }
275}
276
277#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
279pub enum GenericArg {
280 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
282 Type(Box<Ty>),
284 Const(AnonConst),
286}
287
288impl GenericArg {
289 pub fn span(&self) -> Span {
290 match self {
291 GenericArg::Lifetime(lt) => lt.ident.span,
292 GenericArg::Type(ty) => ty.span,
293 GenericArg::Const(ct) => ct.value.span,
294 }
295 }
296}
297
298#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
300pub struct AngleBracketedArgs {
301 pub span: Span,
303 pub args: ThinVec<AngleBracketedArg>,
305}
306
307#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
309pub enum AngleBracketedArg {
310 Arg(GenericArg),
312 Constraint(AssocItemConstraint),
314}
315
316impl AngleBracketedArg {
317 pub fn span(&self) -> Span {
318 match self {
319 AngleBracketedArg::Arg(arg) => arg.span(),
320 AngleBracketedArg::Constraint(constraint) => constraint.span,
321 }
322 }
323}
324
325impl From<AngleBracketedArgs> for Box<GenericArgs> {
326 fn from(val: AngleBracketedArgs) -> Self {
327 Box::new(GenericArgs::AngleBracketed(val))
328 }
329}
330
331impl From<ParenthesizedArgs> for Box<GenericArgs> {
332 fn from(val: ParenthesizedArgs) -> Self {
333 Box::new(GenericArgs::Parenthesized(val))
334 }
335}
336
337#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
339pub struct ParenthesizedArgs {
340 pub span: Span,
345
346 pub inputs: ThinVec<Box<Ty>>,
348
349 pub inputs_span: Span,
354
355 pub output: FnRetTy,
357}
358
359impl ParenthesizedArgs {
360 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
361 let args = self
362 .inputs
363 .iter()
364 .cloned()
365 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
366 .collect();
367 AngleBracketedArgs { span: self.inputs_span, args }
368 }
369}
370
371pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
372
373#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
375pub struct TraitBoundModifiers {
376 pub constness: BoundConstness,
377 pub asyncness: BoundAsyncness,
378 pub polarity: BoundPolarity,
379}
380
381impl TraitBoundModifiers {
382 pub const NONE: Self = Self {
383 constness: BoundConstness::Never,
384 asyncness: BoundAsyncness::Normal,
385 polarity: BoundPolarity::Positive,
386 };
387}
388
389#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
390pub enum GenericBound {
391 Trait(PolyTraitRef),
392 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
393 Use(ThinVec<PreciseCapturingArg>, Span),
395}
396
397impl GenericBound {
398 pub fn span(&self) -> Span {
399 match self {
400 GenericBound::Trait(t, ..) => t.span,
401 GenericBound::Outlives(l) => l.ident.span,
402 GenericBound::Use(_, span) => *span,
403 }
404 }
405}
406
407pub type GenericBounds = Vec<GenericBound>;
408
409#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
413pub enum ParamKindOrd {
414 Lifetime,
415 TypeOrConst,
416}
417
418impl fmt::Display for ParamKindOrd {
419 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420 match self {
421 ParamKindOrd::Lifetime => "lifetime".fmt(f),
422 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
423 }
424 }
425}
426
427#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
428pub enum GenericParamKind {
429 Lifetime,
431 Type {
432 default: Option<Box<Ty>>,
433 },
434 Const {
435 ty: Box<Ty>,
436 span: Span,
438 default: Option<AnonConst>,
440 },
441}
442
443#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
444pub struct GenericParam {
445 pub id: NodeId,
446 pub ident: Ident,
447 pub attrs: AttrVec,
448 #[visitable(extra = BoundKind::Bound)]
449 pub bounds: GenericBounds,
450 pub is_placeholder: bool,
451 pub kind: GenericParamKind,
452 pub colon_span: Option<Span>,
453}
454
455impl GenericParam {
456 pub fn span(&self) -> Span {
457 match &self.kind {
458 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
459 self.ident.span
460 }
461 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
462 GenericParamKind::Const { span, .. } => *span,
463 }
464 }
465}
466
467#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
470pub struct Generics {
471 pub params: ThinVec<GenericParam>,
472 pub where_clause: WhereClause,
473 pub span: Span,
474}
475
476#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
478pub struct WhereClause {
479 pub has_where_token: bool,
484 pub predicates: ThinVec<WherePredicate>,
485 pub span: Span,
486}
487
488impl WhereClause {
489 pub fn is_empty(&self) -> bool {
490 !self.has_where_token && self.predicates.is_empty()
491 }
492}
493
494#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
496pub struct WherePredicate {
497 pub attrs: AttrVec,
498 pub kind: WherePredicateKind,
499 pub id: NodeId,
500 pub span: Span,
501 pub is_placeholder: bool,
502}
503
504#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
506pub enum WherePredicateKind {
507 BoundPredicate(WhereBoundPredicate),
509 RegionPredicate(WhereRegionPredicate),
511 EqPredicate(WhereEqPredicate),
513}
514
515#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
519pub struct WhereBoundPredicate {
520 pub bound_generic_params: ThinVec<GenericParam>,
522 pub bounded_ty: Box<Ty>,
524 #[visitable(extra = BoundKind::Bound)]
526 pub bounds: GenericBounds,
527}
528
529#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
533pub struct WhereRegionPredicate {
534 #[visitable(extra = LifetimeCtxt::Bound)]
535 pub lifetime: Lifetime,
536 #[visitable(extra = BoundKind::Bound)]
537 pub bounds: GenericBounds,
538}
539
540#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
544pub struct WhereEqPredicate {
545 pub lhs_ty: Box<Ty>,
546 pub rhs_ty: Box<Ty>,
547}
548
549#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
550pub struct Crate {
551 pub id: NodeId,
554 pub attrs: AttrVec,
555 pub items: ThinVec<Box<Item>>,
556 pub spans: ModSpans,
557 pub is_placeholder: bool,
558}
559
560#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
567pub struct MetaItem {
568 pub unsafety: Safety,
569 pub path: Path,
570 pub kind: MetaItemKind,
571 pub span: Span,
572}
573
574#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
576pub enum MetaItemKind {
577 Word,
581
582 List(ThinVec<MetaItemInner>),
586
587 NameValue(MetaItemLit),
591}
592
593#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
597pub enum MetaItemInner {
598 MetaItem(MetaItem),
600
601 Lit(MetaItemLit),
605}
606
607#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
611pub struct Block {
612 pub stmts: ThinVec<Stmt>,
614 pub id: NodeId,
615 pub rules: BlockCheckMode,
617 pub span: Span,
618 pub tokens: Option<LazyAttrTokenStream>,
619}
620
621#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
625pub struct Pat {
626 pub id: NodeId,
627 pub kind: PatKind,
628 pub span: Span,
629 pub tokens: Option<LazyAttrTokenStream>,
630}
631
632impl Pat {
633 pub fn to_ty(&self) -> Option<Box<Ty>> {
636 let kind = match &self.kind {
637 PatKind::Missing => unreachable!(),
638 PatKind::Wild => TyKind::Infer,
640 PatKind::Ident(BindingMode::NONE, ident, None) => {
642 TyKind::Path(None, Path::from_ident(*ident))
643 }
644 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
645 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
646 PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
648 Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
649 Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }),
650 })?,
651 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
654 pat.to_ty().map(TyKind::Slice)?
655 }
656 PatKind::Tuple(pats) => {
659 let mut tys = ThinVec::with_capacity(pats.len());
660 for pat in pats {
662 tys.push(pat.to_ty()?);
663 }
664 TyKind::Tup(tys)
665 }
666 _ => return None,
667 };
668
669 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
670 }
671
672 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
676 if !it(self) {
677 return;
678 }
679
680 match &self.kind {
681 PatKind::Ident(_, _, Some(p)) => p.walk(it),
683
684 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
686
687 PatKind::TupleStruct(_, _, s)
689 | PatKind::Tuple(s)
690 | PatKind::Slice(s)
691 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
692
693 PatKind::Box(s)
695 | PatKind::Deref(s)
696 | PatKind::Ref(s, _, _)
697 | PatKind::Paren(s)
698 | PatKind::Guard(s, _) => s.walk(it),
699
700 PatKind::Missing
702 | PatKind::Wild
703 | PatKind::Rest
704 | PatKind::Never
705 | PatKind::Expr(_)
706 | PatKind::Range(..)
707 | PatKind::Ident(..)
708 | PatKind::Path(..)
709 | PatKind::MacCall(_)
710 | PatKind::Err(_) => {}
711 }
712 }
713
714 pub fn peel_refs(&self) -> &Pat {
716 let mut current = self;
717 while let PatKind::Ref(inner, _, _) = ¤t.kind {
718 current = inner;
719 }
720 current
721 }
722
723 pub fn is_rest(&self) -> bool {
725 matches!(self.kind, PatKind::Rest)
726 }
727
728 pub fn could_be_never_pattern(&self) -> bool {
731 let mut could_be_never_pattern = false;
732 self.walk(&mut |pat| match &pat.kind {
733 PatKind::Never | PatKind::MacCall(_) => {
734 could_be_never_pattern = true;
735 false
736 }
737 PatKind::Or(s) => {
738 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
739 false
740 }
741 _ => true,
742 });
743 could_be_never_pattern
744 }
745
746 pub fn contains_never_pattern(&self) -> bool {
749 let mut contains_never_pattern = false;
750 self.walk(&mut |pat| {
751 if matches!(pat.kind, PatKind::Never) {
752 contains_never_pattern = true;
753 }
754 true
755 });
756 contains_never_pattern
757 }
758
759 pub fn descr(&self) -> Option<String> {
761 match &self.kind {
762 PatKind::Missing => unreachable!(),
763 PatKind::Wild => Some("_".to_string()),
764 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
765 PatKind::Ref(pat, pinned, mutbl) => {
766 pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
767 }
768 _ => None,
769 }
770 }
771}
772
773impl From<Box<Pat>> for Pat {
774 fn from(value: Box<Pat>) -> Self {
775 *value
776 }
777}
778
779#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
785pub struct PatField {
786 pub ident: Ident,
788 pub pat: Box<Pat>,
790 pub is_shorthand: bool,
791 pub attrs: AttrVec,
792 pub id: NodeId,
793 pub span: Span,
794 pub is_placeholder: bool,
795}
796
797#[derive(Clone, Copy, Debug, Eq, PartialEq)]
798#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
799pub enum ByRef {
800 Yes(Pinnedness, Mutability),
801 No,
802}
803
804impl ByRef {
805 #[must_use]
806 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
807 if let ByRef::Yes(_, old_mutbl) = &mut self {
808 *old_mutbl = cmp::min(*old_mutbl, mutbl);
809 }
810 self
811 }
812}
813
814#[derive(Clone, Copy, Debug, Eq, PartialEq)]
820#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
821pub struct BindingMode(pub ByRef, pub Mutability);
822
823impl BindingMode {
824 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
825 pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not);
826 pub const REF_PIN: Self =
827 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not);
828 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
829 pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not);
830 pub const REF_PIN_MUT: Self =
831 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not);
832 pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut);
833 pub const MUT_REF_PIN: Self =
834 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut);
835 pub const MUT_REF_MUT: Self =
836 Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut);
837 pub const MUT_REF_PIN_MUT: Self =
838 Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut);
839
840 pub fn prefix_str(self) -> &'static str {
841 match self {
842 Self::NONE => "",
843 Self::REF => "ref ",
844 Self::REF_PIN => "ref pin const ",
845 Self::MUT => "mut ",
846 Self::REF_MUT => "ref mut ",
847 Self::REF_PIN_MUT => "ref pin mut ",
848 Self::MUT_REF => "mut ref ",
849 Self::MUT_REF_PIN => "mut ref pin ",
850 Self::MUT_REF_MUT => "mut ref mut ",
851 Self::MUT_REF_PIN_MUT => "mut ref pin mut ",
852 }
853 }
854}
855
856#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
857pub enum RangeEnd {
858 Included(RangeSyntax),
860 Excluded,
862}
863
864#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
865pub enum RangeSyntax {
866 DotDotDot,
868 DotDotEq,
870}
871
872#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
876pub enum PatKind {
877 Missing,
879
880 Wild,
882
883 Ident(BindingMode, Ident, Option<Box<Pat>>),
888
889 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
891
892 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
894
895 Or(ThinVec<Pat>),
898
899 Path(Option<Box<QSelf>>, Path),
904
905 Tuple(ThinVec<Pat>),
907
908 Box(Box<Pat>),
910
911 Deref(Box<Pat>),
913
914 Ref(Box<Pat>, Pinnedness, Mutability),
916
917 Expr(Box<Expr>),
919
920 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
922
923 Slice(ThinVec<Pat>),
925
926 Rest,
939
940 Never,
942
943 Guard(Box<Pat>, Box<Expr>),
945
946 Paren(Box<Pat>),
948
949 MacCall(Box<MacCall>),
951
952 Err(ErrorGuaranteed),
954}
955
956#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
958pub enum PatFieldsRest {
959 Rest(Span),
961 Recovered(ErrorGuaranteed),
963 None,
965}
966
967#[derive(Clone, Copy, PartialEq, Eq, Debug)]
970#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
971pub enum BorrowKind {
972 Ref,
976 Raw,
980 Pin,
984}
985
986#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
987pub enum BinOpKind {
988 Add,
990 Sub,
992 Mul,
994 Div,
996 Rem,
998 And,
1000 Or,
1002 BitXor,
1004 BitAnd,
1006 BitOr,
1008 Shl,
1010 Shr,
1012 Eq,
1014 Lt,
1016 Le,
1018 Ne,
1020 Ge,
1022 Gt,
1024}
1025
1026impl BinOpKind {
1027 pub fn as_str(&self) -> &'static str {
1028 use BinOpKind::*;
1029 match self {
1030 Add => "+",
1031 Sub => "-",
1032 Mul => "*",
1033 Div => "/",
1034 Rem => "%",
1035 And => "&&",
1036 Or => "||",
1037 BitXor => "^",
1038 BitAnd => "&",
1039 BitOr => "|",
1040 Shl => "<<",
1041 Shr => ">>",
1042 Eq => "==",
1043 Lt => "<",
1044 Le => "<=",
1045 Ne => "!=",
1046 Ge => ">=",
1047 Gt => ">",
1048 }
1049 }
1050
1051 pub fn is_lazy(&self) -> bool {
1052 matches!(self, BinOpKind::And | BinOpKind::Or)
1053 }
1054
1055 pub fn precedence(&self) -> ExprPrecedence {
1056 use BinOpKind::*;
1057 match *self {
1058 Mul | Div | Rem => ExprPrecedence::Product,
1059 Add | Sub => ExprPrecedence::Sum,
1060 Shl | Shr => ExprPrecedence::Shift,
1061 BitAnd => ExprPrecedence::BitAnd,
1062 BitXor => ExprPrecedence::BitXor,
1063 BitOr => ExprPrecedence::BitOr,
1064 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1065 And => ExprPrecedence::LAnd,
1066 Or => ExprPrecedence::LOr,
1067 }
1068 }
1069
1070 pub fn fixity(&self) -> Fixity {
1071 use BinOpKind::*;
1072 match self {
1073 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1074 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1075 Fixity::Left
1076 }
1077 }
1078 }
1079
1080 pub fn is_comparison(self) -> bool {
1081 use BinOpKind::*;
1082 match self {
1083 Eq | Ne | Lt | Le | Gt | Ge => true,
1084 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1085 }
1086 }
1087
1088 pub fn is_by_value(self) -> bool {
1090 !self.is_comparison()
1091 }
1092}
1093
1094pub type BinOp = Spanned<BinOpKind>;
1095
1096impl From<AssignOpKind> for BinOpKind {
1100 fn from(op: AssignOpKind) -> BinOpKind {
1101 match op {
1102 AssignOpKind::AddAssign => BinOpKind::Add,
1103 AssignOpKind::SubAssign => BinOpKind::Sub,
1104 AssignOpKind::MulAssign => BinOpKind::Mul,
1105 AssignOpKind::DivAssign => BinOpKind::Div,
1106 AssignOpKind::RemAssign => BinOpKind::Rem,
1107 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1108 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1109 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1110 AssignOpKind::ShlAssign => BinOpKind::Shl,
1111 AssignOpKind::ShrAssign => BinOpKind::Shr,
1112 }
1113 }
1114}
1115
1116#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1117pub enum AssignOpKind {
1118 AddAssign,
1120 SubAssign,
1122 MulAssign,
1124 DivAssign,
1126 RemAssign,
1128 BitXorAssign,
1130 BitAndAssign,
1132 BitOrAssign,
1134 ShlAssign,
1136 ShrAssign,
1138}
1139
1140impl AssignOpKind {
1141 pub fn as_str(&self) -> &'static str {
1142 use AssignOpKind::*;
1143 match self {
1144 AddAssign => "+=",
1145 SubAssign => "-=",
1146 MulAssign => "*=",
1147 DivAssign => "/=",
1148 RemAssign => "%=",
1149 BitXorAssign => "^=",
1150 BitAndAssign => "&=",
1151 BitOrAssign => "|=",
1152 ShlAssign => "<<=",
1153 ShrAssign => ">>=",
1154 }
1155 }
1156
1157 pub fn is_by_value(self) -> bool {
1159 true
1160 }
1161}
1162
1163pub type AssignOp = Spanned<AssignOpKind>;
1164
1165#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1169pub enum UnOp {
1170 Deref,
1172 Not,
1174 Neg,
1176}
1177
1178impl UnOp {
1179 pub fn as_str(&self) -> &'static str {
1180 match self {
1181 UnOp::Deref => "*",
1182 UnOp::Not => "!",
1183 UnOp::Neg => "-",
1184 }
1185 }
1186
1187 pub fn is_by_value(self) -> bool {
1189 matches!(self, Self::Neg | Self::Not)
1190 }
1191}
1192
1193#[derive(Clone, Encodable, Decodable, Debug)]
1197pub struct Stmt {
1198 pub id: NodeId,
1199 pub kind: StmtKind,
1200 pub span: Span,
1201}
1202
1203impl Stmt {
1204 pub fn has_trailing_semicolon(&self) -> bool {
1205 match &self.kind {
1206 StmtKind::Semi(_) => true,
1207 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1208 _ => false,
1209 }
1210 }
1211
1212 pub fn add_trailing_semicolon(mut self) -> Self {
1220 self.kind = match self.kind {
1221 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1222 StmtKind::MacCall(mut mac) => {
1223 mac.style = MacStmtStyle::Semicolon;
1224 StmtKind::MacCall(mac)
1225 }
1226 kind => kind,
1227 };
1228
1229 self
1230 }
1231
1232 pub fn is_item(&self) -> bool {
1233 matches!(self.kind, StmtKind::Item(_))
1234 }
1235
1236 pub fn is_expr(&self) -> bool {
1237 matches!(self.kind, StmtKind::Expr(_))
1238 }
1239}
1240
1241#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1243pub enum StmtKind {
1244 Let(Box<Local>),
1246 Item(Box<Item>),
1248 Expr(Box<Expr>),
1250 Semi(Box<Expr>),
1252 Empty,
1254 MacCall(Box<MacCallStmt>),
1256}
1257
1258impl StmtKind {
1259 pub fn descr(&self) -> &'static str {
1260 match self {
1261 StmtKind::Let(_) => "local",
1262 StmtKind::Item(_) => "item",
1263 StmtKind::Expr(_) => "expression",
1264 StmtKind::Semi(_) => "statement",
1265 StmtKind::Empty => "semicolon",
1266 StmtKind::MacCall(_) => "macro call",
1267 }
1268 }
1269}
1270
1271#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1272pub struct MacCallStmt {
1273 pub mac: Box<MacCall>,
1274 pub style: MacStmtStyle,
1275 pub attrs: AttrVec,
1276 pub tokens: Option<LazyAttrTokenStream>,
1277}
1278
1279#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1280pub enum MacStmtStyle {
1281 Semicolon,
1284 Braces,
1286 NoBraces,
1290}
1291
1292#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1294pub struct Local {
1295 pub id: NodeId,
1296 pub super_: Option<Span>,
1297 pub pat: Box<Pat>,
1298 pub ty: Option<Box<Ty>>,
1299 pub kind: LocalKind,
1300 pub span: Span,
1301 pub colon_sp: Option<Span>,
1302 pub attrs: AttrVec,
1303 pub tokens: Option<LazyAttrTokenStream>,
1304}
1305
1306#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1307pub enum LocalKind {
1308 Decl,
1311 Init(Box<Expr>),
1314 InitElse(Box<Expr>, Box<Block>),
1317}
1318
1319impl LocalKind {
1320 pub fn init(&self) -> Option<&Expr> {
1321 match self {
1322 Self::Decl => None,
1323 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1324 }
1325 }
1326
1327 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1328 match self {
1329 Self::Decl => None,
1330 Self::Init(init) => Some((init, None)),
1331 Self::InitElse(init, els) => Some((init, Some(els))),
1332 }
1333 }
1334}
1335
1336#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1347pub struct Arm {
1348 pub attrs: AttrVec,
1349 pub pat: Box<Pat>,
1351 pub guard: Option<Box<Expr>>,
1353 pub body: Option<Box<Expr>>,
1355 pub span: Span,
1356 pub id: NodeId,
1357 pub is_placeholder: bool,
1358}
1359
1360#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1362pub struct ExprField {
1363 pub attrs: AttrVec,
1364 pub id: NodeId,
1365 pub span: Span,
1366 pub ident: Ident,
1367 pub expr: Box<Expr>,
1368 pub is_shorthand: bool,
1369 pub is_placeholder: bool,
1370}
1371
1372#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1373pub enum BlockCheckMode {
1374 Default,
1375 Unsafe(UnsafeSource),
1376}
1377
1378#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1379pub enum UnsafeSource {
1380 CompilerGenerated,
1381 UserProvided,
1382}
1383
1384#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1388pub enum MgcaDisambiguation {
1389 AnonConst,
1390 Direct,
1391}
1392
1393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1399pub struct AnonConst {
1400 pub id: NodeId,
1401 pub value: Box<Expr>,
1402 pub mgca_disambiguation: MgcaDisambiguation,
1403}
1404
1405#[derive(Clone, Encodable, Decodable, Debug)]
1407pub struct Expr {
1408 pub id: NodeId,
1409 pub kind: ExprKind,
1410 pub span: Span,
1411 pub attrs: AttrVec,
1412 pub tokens: Option<LazyAttrTokenStream>,
1413}
1414
1415impl Expr {
1416 pub fn is_potential_trivial_const_arg(&self) -> bool {
1428 let this = self.maybe_unwrap_block();
1429 if let ExprKind::Path(None, path) = &this.kind
1430 && path.is_potential_trivial_const_arg()
1431 {
1432 true
1433 } else {
1434 false
1435 }
1436 }
1437
1438 pub fn maybe_unwrap_block(&self) -> &Expr {
1440 if let ExprKind::Block(block, None) = &self.kind
1441 && let [stmt] = block.stmts.as_slice()
1442 && let StmtKind::Expr(expr) = &stmt.kind
1443 {
1444 expr
1445 } else {
1446 self
1447 }
1448 }
1449
1450 pub fn optionally_braced_mac_call(
1456 &self,
1457 already_stripped_block: bool,
1458 ) -> Option<(bool, NodeId)> {
1459 match &self.kind {
1460 ExprKind::Block(block, None)
1461 if let [stmt] = &*block.stmts
1462 && !already_stripped_block =>
1463 {
1464 match &stmt.kind {
1465 StmtKind::MacCall(_) => Some((true, stmt.id)),
1466 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1467 Some((true, expr.id))
1468 }
1469 _ => None,
1470 }
1471 }
1472 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1473 _ => None,
1474 }
1475 }
1476
1477 pub fn to_bound(&self) -> Option<GenericBound> {
1478 match &self.kind {
1479 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1480 ThinVec::new(),
1481 path.clone(),
1482 TraitBoundModifiers::NONE,
1483 self.span,
1484 Parens::No,
1485 ))),
1486 _ => None,
1487 }
1488 }
1489
1490 pub fn peel_parens(&self) -> &Expr {
1491 let mut expr = self;
1492 while let ExprKind::Paren(inner) = &expr.kind {
1493 expr = inner;
1494 }
1495 expr
1496 }
1497
1498 pub fn peel_parens_and_refs(&self) -> &Expr {
1499 let mut expr = self;
1500 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1501 {
1502 expr = inner;
1503 }
1504 expr
1505 }
1506
1507 pub fn to_ty(&self) -> Option<Box<Ty>> {
1509 let kind = match &self.kind {
1510 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1512 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1513
1514 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1515
1516 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1517 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1518 }
1519
1520 ExprKind::Repeat(expr, expr_len) => {
1521 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1522 }
1523
1524 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1525 expr.to_ty().map(TyKind::Slice)?
1526 }
1527
1528 ExprKind::Tup(exprs) => {
1529 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1530 TyKind::Tup(tys)
1531 }
1532
1533 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1537 let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else {
1538 return None;
1539 };
1540 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1541 }
1542
1543 ExprKind::Underscore => TyKind::Infer,
1544
1545 _ => return None,
1547 };
1548
1549 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1550 }
1551
1552 pub fn precedence(&self) -> ExprPrecedence {
1553 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1554 for attr in attrs {
1555 if let AttrStyle::Outer = attr.style {
1556 return ExprPrecedence::Prefix;
1557 }
1558 }
1559 ExprPrecedence::Unambiguous
1560 }
1561
1562 match &self.kind {
1563 ExprKind::Closure(closure) => {
1564 match closure.fn_decl.output {
1565 FnRetTy::Default(_) => ExprPrecedence::Jump,
1566 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1567 }
1568 }
1569
1570 ExprKind::Break(_ , value)
1571 | ExprKind::Ret(value)
1572 | ExprKind::Yield(YieldKind::Prefix(value))
1573 | ExprKind::Yeet(value) => match value {
1574 Some(_) => ExprPrecedence::Jump,
1575 None => prefix_attrs_precedence(&self.attrs),
1576 },
1577
1578 ExprKind::Become(_) => ExprPrecedence::Jump,
1579
1580 ExprKind::Range(..) => ExprPrecedence::Range,
1585
1586 ExprKind::Binary(op, ..) => op.node.precedence(),
1588 ExprKind::Cast(..) => ExprPrecedence::Cast,
1589
1590 ExprKind::Assign(..) |
1591 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1592
1593 ExprKind::AddrOf(..)
1595 | ExprKind::Let(..)
1600 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1601
1602 ExprKind::Array(_)
1604 | ExprKind::Await(..)
1605 | ExprKind::Use(..)
1606 | ExprKind::Block(..)
1607 | ExprKind::Call(..)
1608 | ExprKind::ConstBlock(_)
1609 | ExprKind::Continue(..)
1610 | ExprKind::Field(..)
1611 | ExprKind::ForLoop { .. }
1612 | ExprKind::FormatArgs(..)
1613 | ExprKind::Gen(..)
1614 | ExprKind::If(..)
1615 | ExprKind::IncludedBytes(..)
1616 | ExprKind::Index(..)
1617 | ExprKind::InlineAsm(..)
1618 | ExprKind::Lit(_)
1619 | ExprKind::Loop(..)
1620 | ExprKind::MacCall(..)
1621 | ExprKind::Match(..)
1622 | ExprKind::MethodCall(..)
1623 | ExprKind::OffsetOf(..)
1624 | ExprKind::Paren(..)
1625 | ExprKind::Path(..)
1626 | ExprKind::Repeat(..)
1627 | ExprKind::Struct(..)
1628 | ExprKind::Try(..)
1629 | ExprKind::TryBlock(..)
1630 | ExprKind::Tup(_)
1631 | ExprKind::Type(..)
1632 | ExprKind::Underscore
1633 | ExprKind::UnsafeBinderCast(..)
1634 | ExprKind::While(..)
1635 | ExprKind::Yield(YieldKind::Postfix(..))
1636 | ExprKind::Err(_)
1637 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1638 }
1639 }
1640
1641 pub fn is_approximately_pattern(&self) -> bool {
1643 matches!(
1644 &self.peel_parens().kind,
1645 ExprKind::Array(_)
1646 | ExprKind::Call(_, _)
1647 | ExprKind::Tup(_)
1648 | ExprKind::Lit(_)
1649 | ExprKind::Range(_, _, _)
1650 | ExprKind::Underscore
1651 | ExprKind::Path(_, _)
1652 | ExprKind::Struct(_)
1653 )
1654 }
1655
1656 pub fn dummy() -> Expr {
1660 Expr {
1661 id: DUMMY_NODE_ID,
1662 kind: ExprKind::Dummy,
1663 span: DUMMY_SP,
1664 attrs: ThinVec::new(),
1665 tokens: None,
1666 }
1667 }
1668}
1669
1670impl From<Box<Expr>> for Expr {
1671 fn from(value: Box<Expr>) -> Self {
1672 *value
1673 }
1674}
1675
1676#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1677pub struct Closure {
1678 pub binder: ClosureBinder,
1679 pub capture_clause: CaptureBy,
1680 pub constness: Const,
1681 pub coroutine_kind: Option<CoroutineKind>,
1682 pub movability: Movability,
1683 pub fn_decl: Box<FnDecl>,
1684 pub body: Box<Expr>,
1685 pub fn_decl_span: Span,
1687 pub fn_arg_span: Span,
1689}
1690
1691#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1693pub enum RangeLimits {
1694 HalfOpen,
1696 Closed,
1698}
1699
1700impl RangeLimits {
1701 pub fn as_str(&self) -> &'static str {
1702 match self {
1703 RangeLimits::HalfOpen => "..",
1704 RangeLimits::Closed => "..=",
1705 }
1706 }
1707}
1708
1709#[derive(Clone, Encodable, Decodable, Debug)]
1711pub struct MethodCall {
1712 pub seg: PathSegment,
1714 pub receiver: Box<Expr>,
1716 pub args: ThinVec<Box<Expr>>,
1718 pub span: Span,
1721}
1722
1723#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1724pub enum StructRest {
1725 Base(Box<Expr>),
1727 Rest(Span),
1729 None,
1731}
1732
1733#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1734pub struct StructExpr {
1735 pub qself: Option<Box<QSelf>>,
1736 pub path: Path,
1737 pub fields: ThinVec<ExprField>,
1738 pub rest: StructRest,
1739}
1740
1741#[derive(Clone, Encodable, Decodable, Debug)]
1743pub enum ExprKind {
1744 Array(ThinVec<Box<Expr>>),
1746 ConstBlock(AnonConst),
1748 Call(Box<Expr>, ThinVec<Box<Expr>>),
1755 MethodCall(Box<MethodCall>),
1757 Tup(ThinVec<Box<Expr>>),
1759 Binary(BinOp, Box<Expr>, Box<Expr>),
1761 Unary(UnOp, Box<Expr>),
1763 Lit(token::Lit),
1765 Cast(Box<Expr>, Box<Ty>),
1767 Type(Box<Expr>, Box<Ty>),
1772 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1777 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1784 While(Box<Expr>, Box<Block>, Option<Label>),
1788 ForLoop {
1794 pat: Box<Pat>,
1795 iter: Box<Expr>,
1796 body: Box<Block>,
1797 label: Option<Label>,
1798 kind: ForLoopKind,
1799 },
1800 Loop(Box<Block>, Option<Label>, Span),
1804 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1806 Closure(Box<Closure>),
1808 Block(Box<Block>, Option<Label>),
1810 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1816 Await(Box<Expr>, Span),
1818 Use(Box<Expr>, Span),
1820
1821 TryBlock(Box<Block>, Option<Box<Ty>>),
1829
1830 Assign(Box<Expr>, Box<Expr>, Span),
1833 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1837 Field(Box<Expr>, Ident),
1839 Index(Box<Expr>, Box<Expr>, Span),
1842 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1844 Underscore,
1846
1847 Path(Option<Box<QSelf>>, Path),
1852
1853 AddrOf(BorrowKind, Mutability, Box<Expr>),
1855 Break(Option<Label>, Option<Box<Expr>>),
1857 Continue(Option<Label>),
1859 Ret(Option<Box<Expr>>),
1861
1862 InlineAsm(Box<InlineAsm>),
1864
1865 OffsetOf(Box<Ty>, Vec<Ident>),
1870
1871 MacCall(Box<MacCall>),
1873
1874 Struct(Box<StructExpr>),
1878
1879 Repeat(Box<Expr>, AnonConst),
1884
1885 Paren(Box<Expr>),
1887
1888 Try(Box<Expr>),
1890
1891 Yield(YieldKind),
1893
1894 Yeet(Option<Box<Expr>>),
1897
1898 Become(Box<Expr>),
1902
1903 IncludedBytes(ByteSymbol),
1915
1916 FormatArgs(Box<FormatArgs>),
1918
1919 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1920
1921 Err(ErrorGuaranteed),
1923
1924 Dummy,
1926}
1927
1928#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1930pub enum ForLoopKind {
1931 For,
1932 ForAwait,
1933}
1934
1935#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1937pub enum GenBlockKind {
1938 Async,
1939 Gen,
1940 AsyncGen,
1941}
1942
1943impl fmt::Display for GenBlockKind {
1944 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1945 self.modifier().fmt(f)
1946 }
1947}
1948
1949impl GenBlockKind {
1950 pub fn modifier(&self) -> &'static str {
1951 match self {
1952 GenBlockKind::Async => "async",
1953 GenBlockKind::Gen => "gen",
1954 GenBlockKind::AsyncGen => "async gen",
1955 }
1956 }
1957}
1958
1959#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1961#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1962pub enum UnsafeBinderCastKind {
1963 Wrap,
1965 Unwrap,
1967}
1968
1969#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1984pub struct QSelf {
1985 pub ty: Box<Ty>,
1986
1987 pub path_span: Span,
1991 pub position: usize,
1992}
1993
1994#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1996pub enum CaptureBy {
1997 Value {
1999 move_kw: Span,
2001 },
2002 Ref,
2004 Use {
2010 use_kw: Span,
2012 },
2013}
2014
2015#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2017pub enum ClosureBinder {
2018 NotPresent,
2020 For {
2022 span: Span,
2029
2030 generic_params: ThinVec<GenericParam>,
2037 },
2038}
2039
2040#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2043pub struct MacCall {
2044 pub path: Path,
2045 pub args: Box<DelimArgs>,
2046}
2047
2048impl MacCall {
2049 pub fn span(&self) -> Span {
2050 self.path.span.to(self.args.dspan.entire())
2051 }
2052}
2053
2054#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2056pub enum AttrArgs {
2057 Empty,
2059 Delimited(DelimArgs),
2061 Eq {
2063 eq_span: Span,
2065 expr: Box<Expr>,
2066 },
2067}
2068
2069impl AttrArgs {
2070 pub fn span(&self) -> Option<Span> {
2071 match self {
2072 AttrArgs::Empty => None,
2073 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2074 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2075 }
2076 }
2077
2078 pub fn inner_tokens(&self) -> TokenStream {
2081 match self {
2082 AttrArgs::Empty => TokenStream::default(),
2083 AttrArgs::Delimited(args) => args.tokens.clone(),
2084 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2085 }
2086 }
2087}
2088
2089#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2091pub struct DelimArgs {
2092 pub dspan: DelimSpan,
2093 pub delim: Delimiter, pub tokens: TokenStream,
2095}
2096
2097impl DelimArgs {
2098 pub fn need_semicolon(&self) -> bool {
2101 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2102 }
2103}
2104
2105#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2107pub struct MacroDef {
2108 pub body: Box<DelimArgs>,
2109 pub macro_rules: bool,
2111
2112 pub eii_declaration: Option<EiiDecl>,
2118}
2119
2120#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2121pub struct EiiDecl {
2122 pub foreign_item: Path,
2124 pub impl_unsafe: bool,
2125}
2126
2127#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2128#[derive(HashStable_Generic, Walkable)]
2129pub enum StrStyle {
2130 Cooked,
2132 Raw(u8),
2136}
2137
2138#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2140pub enum MatchKind {
2141 Prefix,
2143 Postfix,
2145}
2146
2147#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2149pub enum YieldKind {
2150 Prefix(Option<Box<Expr>>),
2152 Postfix(Box<Expr>),
2154}
2155
2156impl YieldKind {
2157 pub const fn expr(&self) -> Option<&Box<Expr>> {
2161 match self {
2162 YieldKind::Prefix(expr) => expr.as_ref(),
2163 YieldKind::Postfix(expr) => Some(expr),
2164 }
2165 }
2166
2167 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2169 match self {
2170 YieldKind::Prefix(expr) => expr.as_mut(),
2171 YieldKind::Postfix(expr) => Some(expr),
2172 }
2173 }
2174
2175 pub const fn same_kind(&self, other: &Self) -> bool {
2177 match (self, other) {
2178 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2179 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2180 _ => false,
2181 }
2182 }
2183}
2184
2185#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2187pub struct MetaItemLit {
2188 pub symbol: Symbol,
2190 pub suffix: Option<Symbol>,
2192 pub kind: LitKind,
2195 pub span: Span,
2196}
2197
2198#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2200pub struct StrLit {
2201 pub symbol: Symbol,
2203 pub suffix: Option<Symbol>,
2205 pub symbol_unescaped: Symbol,
2207 pub style: StrStyle,
2208 pub span: Span,
2209}
2210
2211impl StrLit {
2212 pub fn as_token_lit(&self) -> token::Lit {
2213 let token_kind = match self.style {
2214 StrStyle::Cooked => token::Str,
2215 StrStyle::Raw(n) => token::StrRaw(n),
2216 };
2217 token::Lit::new(token_kind, self.symbol, self.suffix)
2218 }
2219}
2220
2221#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2223#[derive(HashStable_Generic)]
2224pub enum LitIntType {
2225 Signed(IntTy),
2227 Unsigned(UintTy),
2229 Unsuffixed,
2231}
2232
2233#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2235#[derive(HashStable_Generic)]
2236pub enum LitFloatType {
2237 Suffixed(FloatTy),
2239 Unsuffixed,
2241}
2242
2243#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2250pub enum LitKind {
2251 Str(Symbol, StrStyle),
2254 ByteStr(ByteSymbol, StrStyle),
2257 CStr(ByteSymbol, StrStyle),
2261 Byte(u8),
2263 Char(char),
2265 Int(Pu128, LitIntType),
2267 Float(Symbol, LitFloatType),
2271 Bool(bool),
2273 Err(ErrorGuaranteed),
2275}
2276
2277impl LitKind {
2278 pub fn str(&self) -> Option<Symbol> {
2279 match *self {
2280 LitKind::Str(s, _) => Some(s),
2281 _ => None,
2282 }
2283 }
2284
2285 pub fn is_str(&self) -> bool {
2287 matches!(self, LitKind::Str(..))
2288 }
2289
2290 pub fn is_bytestr(&self) -> bool {
2292 matches!(self, LitKind::ByteStr(..))
2293 }
2294
2295 pub fn is_numeric(&self) -> bool {
2297 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2298 }
2299
2300 pub fn is_unsuffixed(&self) -> bool {
2303 !self.is_suffixed()
2304 }
2305
2306 pub fn is_suffixed(&self) -> bool {
2308 match *self {
2309 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2311 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2312 LitKind::Str(..)
2314 | LitKind::ByteStr(..)
2315 | LitKind::CStr(..)
2316 | LitKind::Byte(..)
2317 | LitKind::Char(..)
2318 | LitKind::Int(_, LitIntType::Unsuffixed)
2319 | LitKind::Float(_, LitFloatType::Unsuffixed)
2320 | LitKind::Bool(..)
2321 | LitKind::Err(_) => false,
2322 }
2323 }
2324}
2325
2326#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2329pub struct MutTy {
2330 pub ty: Box<Ty>,
2331 pub mutbl: Mutability,
2332}
2333
2334#[derive(Clone, Encodable, Decodable, Debug)]
2337pub struct FnSig {
2338 pub header: FnHeader,
2339 pub decl: Box<FnDecl>,
2340 pub span: Span,
2341}
2342
2343impl FnSig {
2344 pub fn header_span(&self) -> Span {
2346 match self.header.ext {
2347 Extern::Implicit(span) | Extern::Explicit(_, span) => {
2348 return self.span.with_hi(span.hi());
2349 }
2350 Extern::None => {}
2351 }
2352
2353 match self.header.safety {
2354 Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2355 Safety::Default => {}
2356 };
2357
2358 if let Some(coroutine_kind) = self.header.coroutine_kind {
2359 return self.span.with_hi(coroutine_kind.span().hi());
2360 }
2361
2362 if let Const::Yes(span) = self.header.constness {
2363 return self.span.with_hi(span.hi());
2364 }
2365
2366 self.span.shrink_to_lo()
2367 }
2368
2369 pub fn safety_span(&self) -> Span {
2371 match self.header.safety {
2372 Safety::Unsafe(span) | Safety::Safe(span) => span,
2373 Safety::Default => {
2374 if let Some(extern_span) = self.header.ext.span() {
2376 return extern_span.shrink_to_lo();
2377 }
2378
2379 self.header_span().shrink_to_hi()
2381 }
2382 }
2383 }
2384
2385 pub fn extern_span(&self) -> Span {
2387 self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2388 }
2389}
2390
2391#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2402pub struct AssocItemConstraint {
2403 pub id: NodeId,
2404 pub ident: Ident,
2405 pub gen_args: Option<GenericArgs>,
2406 pub kind: AssocItemConstraintKind,
2407 pub span: Span,
2408}
2409
2410#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2411pub enum Term {
2412 Ty(Box<Ty>),
2413 Const(AnonConst),
2414}
2415
2416impl From<Box<Ty>> for Term {
2417 fn from(v: Box<Ty>) -> Self {
2418 Term::Ty(v)
2419 }
2420}
2421
2422impl From<AnonConst> for Term {
2423 fn from(v: AnonConst) -> Self {
2424 Term::Const(v)
2425 }
2426}
2427
2428#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2430pub enum AssocItemConstraintKind {
2431 Equality { term: Term },
2438 Bound {
2440 #[visitable(extra = BoundKind::Bound)]
2441 bounds: GenericBounds,
2442 },
2443}
2444
2445#[derive(Encodable, Decodable, Debug, Walkable)]
2446pub struct Ty {
2447 pub id: NodeId,
2448 pub kind: TyKind,
2449 pub span: Span,
2450 pub tokens: Option<LazyAttrTokenStream>,
2451}
2452
2453impl Clone for Ty {
2454 fn clone(&self) -> Self {
2455 ensure_sufficient_stack(|| Self {
2456 id: self.id,
2457 kind: self.kind.clone(),
2458 span: self.span,
2459 tokens: self.tokens.clone(),
2460 })
2461 }
2462}
2463
2464impl From<Box<Ty>> for Ty {
2465 fn from(value: Box<Ty>) -> Self {
2466 *value
2467 }
2468}
2469
2470impl Ty {
2471 pub fn peel_refs(&self) -> &Self {
2472 let mut final_ty = self;
2473 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2474 {
2475 final_ty = ty;
2476 }
2477 final_ty
2478 }
2479
2480 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2481 match &self.kind {
2482 TyKind::Infer => true,
2483 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2484 _ => false,
2485 }
2486 }
2487}
2488
2489#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2490pub struct FnPtrTy {
2491 pub safety: Safety,
2492 pub ext: Extern,
2493 pub generic_params: ThinVec<GenericParam>,
2494 pub decl: Box<FnDecl>,
2495 pub decl_span: Span,
2498}
2499
2500#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2501pub struct UnsafeBinderTy {
2502 pub generic_params: ThinVec<GenericParam>,
2503 pub inner_ty: Box<Ty>,
2504}
2505
2506#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2510pub enum TyKind {
2511 Slice(Box<Ty>),
2513 Array(Box<Ty>, AnonConst),
2515 Ptr(MutTy),
2517 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2519 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2523 FnPtr(Box<FnPtrTy>),
2525 UnsafeBinder(Box<UnsafeBinderTy>),
2527 Never,
2529 Tup(ThinVec<Box<Ty>>),
2531 Path(Option<Box<QSelf>>, Path),
2536 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2539 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2546 Paren(Box<Ty>),
2548 Infer,
2551 ImplicitSelf,
2553 MacCall(Box<MacCall>),
2555 CVarArgs,
2557 Pat(Box<Ty>, Box<TyPat>),
2560 Dummy,
2562 Err(ErrorGuaranteed),
2564}
2565
2566impl TyKind {
2567 pub fn is_implicit_self(&self) -> bool {
2568 matches!(self, TyKind::ImplicitSelf)
2569 }
2570
2571 pub fn is_unit(&self) -> bool {
2572 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2573 }
2574
2575 pub fn is_simple_path(&self) -> Option<Symbol> {
2576 if let TyKind::Path(None, Path { segments, .. }) = &self
2577 && let [segment] = &segments[..]
2578 && segment.args.is_none()
2579 {
2580 Some(segment.ident.name)
2581 } else {
2582 None
2583 }
2584 }
2585
2586 pub fn maybe_scalar(&self) -> bool {
2594 let Some(ty_sym) = self.is_simple_path() else {
2595 return self.is_unit();
2597 };
2598 matches!(
2599 ty_sym,
2600 sym::i8
2601 | sym::i16
2602 | sym::i32
2603 | sym::i64
2604 | sym::i128
2605 | sym::u8
2606 | sym::u16
2607 | sym::u32
2608 | sym::u64
2609 | sym::u128
2610 | sym::f16
2611 | sym::f32
2612 | sym::f64
2613 | sym::f128
2614 | sym::char
2615 | sym::bool
2616 )
2617 }
2618}
2619
2620#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2622pub struct TyPat {
2623 pub id: NodeId,
2624 pub kind: TyPatKind,
2625 pub span: Span,
2626 pub tokens: Option<LazyAttrTokenStream>,
2627}
2628
2629#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2633pub enum TyPatKind {
2634 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2636
2637 NotNull,
2639
2640 Or(ThinVec<TyPat>),
2641
2642 Err(ErrorGuaranteed),
2644}
2645
2646#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2648#[repr(u8)]
2649pub enum TraitObjectSyntax {
2650 Dyn = 0,
2652 None = 1,
2653}
2654
2655unsafe impl Tag for TraitObjectSyntax {
2659 const BITS: u32 = 2;
2660
2661 fn into_usize(self) -> usize {
2662 self as u8 as usize
2663 }
2664
2665 unsafe fn from_usize(tag: usize) -> Self {
2666 match tag {
2667 0 => TraitObjectSyntax::Dyn,
2668 1 => TraitObjectSyntax::None,
2669 _ => unreachable!(),
2670 }
2671 }
2672}
2673
2674#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2675pub enum PreciseCapturingArg {
2676 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2678 Arg(Path, NodeId),
2680}
2681
2682#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2686pub enum InlineAsmRegOrRegClass {
2687 Reg(Symbol),
2688 RegClass(Symbol),
2689}
2690
2691#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2692pub struct InlineAsmOptions(u16);
2693bitflags::bitflags! {
2694 impl InlineAsmOptions: u16 {
2695 const PURE = 1 << 0;
2696 const NOMEM = 1 << 1;
2697 const READONLY = 1 << 2;
2698 const PRESERVES_FLAGS = 1 << 3;
2699 const NORETURN = 1 << 4;
2700 const NOSTACK = 1 << 5;
2701 const ATT_SYNTAX = 1 << 6;
2702 const RAW = 1 << 7;
2703 const MAY_UNWIND = 1 << 8;
2704 }
2705}
2706
2707impl InlineAsmOptions {
2708 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2709
2710 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2711 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2712
2713 pub fn human_readable_names(&self) -> Vec<&'static str> {
2714 let mut options = vec![];
2715
2716 if self.contains(InlineAsmOptions::PURE) {
2717 options.push("pure");
2718 }
2719 if self.contains(InlineAsmOptions::NOMEM) {
2720 options.push("nomem");
2721 }
2722 if self.contains(InlineAsmOptions::READONLY) {
2723 options.push("readonly");
2724 }
2725 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2726 options.push("preserves_flags");
2727 }
2728 if self.contains(InlineAsmOptions::NORETURN) {
2729 options.push("noreturn");
2730 }
2731 if self.contains(InlineAsmOptions::NOSTACK) {
2732 options.push("nostack");
2733 }
2734 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2735 options.push("att_syntax");
2736 }
2737 if self.contains(InlineAsmOptions::RAW) {
2738 options.push("raw");
2739 }
2740 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2741 options.push("may_unwind");
2742 }
2743
2744 options
2745 }
2746}
2747
2748impl std::fmt::Debug for InlineAsmOptions {
2749 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2750 bitflags::parser::to_writer(self, f)
2751 }
2752}
2753
2754#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2755pub enum InlineAsmTemplatePiece {
2756 String(Cow<'static, str>),
2757 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2758}
2759
2760impl fmt::Display for InlineAsmTemplatePiece {
2761 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2762 match self {
2763 Self::String(s) => {
2764 for c in s.chars() {
2765 match c {
2766 '{' => f.write_str("{{")?,
2767 '}' => f.write_str("}}")?,
2768 _ => c.fmt(f)?,
2769 }
2770 }
2771 Ok(())
2772 }
2773 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2774 write!(f, "{{{operand_idx}:{modifier}}}")
2775 }
2776 Self::Placeholder { operand_idx, modifier: None, .. } => {
2777 write!(f, "{{{operand_idx}}}")
2778 }
2779 }
2780 }
2781}
2782
2783impl InlineAsmTemplatePiece {
2784 pub fn to_string(s: &[Self]) -> String {
2786 use fmt::Write;
2787 let mut out = String::new();
2788 for p in s.iter() {
2789 let _ = write!(out, "{p}");
2790 }
2791 out
2792 }
2793}
2794
2795#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2803pub struct InlineAsmSym {
2804 pub id: NodeId,
2805 pub qself: Option<Box<QSelf>>,
2806 pub path: Path,
2807}
2808
2809#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2813pub enum InlineAsmOperand {
2814 In {
2815 reg: InlineAsmRegOrRegClass,
2816 expr: Box<Expr>,
2817 },
2818 Out {
2819 reg: InlineAsmRegOrRegClass,
2820 late: bool,
2821 expr: Option<Box<Expr>>,
2822 },
2823 InOut {
2824 reg: InlineAsmRegOrRegClass,
2825 late: bool,
2826 expr: Box<Expr>,
2827 },
2828 SplitInOut {
2829 reg: InlineAsmRegOrRegClass,
2830 late: bool,
2831 in_expr: Box<Expr>,
2832 out_expr: Option<Box<Expr>>,
2833 },
2834 Const {
2835 anon_const: AnonConst,
2836 },
2837 Sym {
2838 sym: InlineAsmSym,
2839 },
2840 Label {
2841 block: Box<Block>,
2842 },
2843}
2844
2845impl InlineAsmOperand {
2846 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2847 match self {
2848 Self::In { reg, .. }
2849 | Self::Out { reg, .. }
2850 | Self::InOut { reg, .. }
2851 | Self::SplitInOut { reg, .. } => Some(reg),
2852 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2853 }
2854 }
2855}
2856
2857#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2858pub enum AsmMacro {
2859 Asm,
2861 GlobalAsm,
2863 NakedAsm,
2865}
2866
2867impl AsmMacro {
2868 pub const fn macro_name(self) -> &'static str {
2869 match self {
2870 AsmMacro::Asm => "asm",
2871 AsmMacro::GlobalAsm => "global_asm",
2872 AsmMacro::NakedAsm => "naked_asm",
2873 }
2874 }
2875
2876 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2877 match self {
2878 AsmMacro::Asm => true,
2879 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2880 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2881 }
2882 }
2883
2884 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2885 match self {
2886 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2887 AsmMacro::GlobalAsm => true,
2888 AsmMacro::NakedAsm => true,
2889 }
2890 }
2891}
2892
2893#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2897pub struct InlineAsm {
2898 pub asm_macro: AsmMacro,
2899 pub template: Vec<InlineAsmTemplatePiece>,
2900 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2901 pub operands: Vec<(InlineAsmOperand, Span)>,
2902 pub clobber_abis: Vec<(Symbol, Span)>,
2903 #[visitable(ignore)]
2904 pub options: InlineAsmOptions,
2905 pub line_spans: Vec<Span>,
2906}
2907
2908#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2912pub struct Param {
2913 pub attrs: AttrVec,
2914 pub ty: Box<Ty>,
2915 pub pat: Box<Pat>,
2916 pub id: NodeId,
2917 pub span: Span,
2918 pub is_placeholder: bool,
2919}
2920
2921#[derive(Clone, Encodable, Decodable, Debug)]
2925pub enum SelfKind {
2926 Value(Mutability),
2928 Region(Option<Lifetime>, Mutability),
2930 Pinned(Option<Lifetime>, Mutability),
2932 Explicit(Box<Ty>, Mutability),
2934}
2935
2936impl SelfKind {
2937 pub fn to_ref_suggestion(&self) -> String {
2938 match self {
2939 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2940 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2941 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2942 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2943 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2944 unreachable!("if we had an explicit self, we wouldn't be here")
2945 }
2946 }
2947 }
2948}
2949
2950pub type ExplicitSelf = Spanned<SelfKind>;
2951
2952impl Param {
2953 pub fn to_self(&self) -> Option<ExplicitSelf> {
2955 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2956 if ident.name == kw::SelfLower {
2957 return match self.ty.kind {
2958 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2959 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2960 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2961 }
2962 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2963 if ty.kind.is_implicit_self() =>
2964 {
2965 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2966 }
2967 _ => Some(respan(
2968 self.pat.span.to(self.ty.span),
2969 SelfKind::Explicit(self.ty.clone(), mutbl),
2970 )),
2971 };
2972 }
2973 }
2974 None
2975 }
2976
2977 pub fn is_self(&self) -> bool {
2979 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2980 ident.name == kw::SelfLower
2981 } else {
2982 false
2983 }
2984 }
2985
2986 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2988 let span = eself.span.to(eself_ident.span);
2989 let infer_ty = Box::new(Ty {
2990 id: DUMMY_NODE_ID,
2991 kind: TyKind::ImplicitSelf,
2992 span: eself_ident.span,
2993 tokens: None,
2994 });
2995 let (mutbl, ty) = match eself.node {
2996 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2997 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2998 SelfKind::Region(lt, mutbl) => (
2999 Mutability::Not,
3000 Box::new(Ty {
3001 id: DUMMY_NODE_ID,
3002 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
3003 span,
3004 tokens: None,
3005 }),
3006 ),
3007 SelfKind::Pinned(lt, mutbl) => (
3008 mutbl,
3009 Box::new(Ty {
3010 id: DUMMY_NODE_ID,
3011 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
3012 span,
3013 tokens: None,
3014 }),
3015 ),
3016 };
3017 Param {
3018 attrs,
3019 pat: Box::new(Pat {
3020 id: DUMMY_NODE_ID,
3021 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
3022 span,
3023 tokens: None,
3024 }),
3025 span,
3026 ty,
3027 id: DUMMY_NODE_ID,
3028 is_placeholder: false,
3029 }
3030 }
3031}
3032
3033#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3040pub struct FnDecl {
3041 pub inputs: ThinVec<Param>,
3042 pub output: FnRetTy,
3043}
3044
3045impl FnDecl {
3046 pub fn has_self(&self) -> bool {
3047 self.inputs.get(0).is_some_and(Param::is_self)
3048 }
3049 pub fn c_variadic(&self) -> bool {
3050 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3051 }
3052}
3053
3054#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3056pub enum IsAuto {
3057 Yes,
3058 No,
3059}
3060
3061#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3063#[derive(HashStable_Generic, Walkable)]
3064pub enum Safety {
3065 Unsafe(Span),
3067 Safe(Span),
3069 Default,
3072}
3073
3074#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3080pub enum CoroutineKind {
3081 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3083 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3085 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3087}
3088
3089impl CoroutineKind {
3090 pub fn span(self) -> Span {
3091 match self {
3092 CoroutineKind::Async { span, .. } => span,
3093 CoroutineKind::Gen { span, .. } => span,
3094 CoroutineKind::AsyncGen { span, .. } => span,
3095 }
3096 }
3097
3098 pub fn as_str(self) -> &'static str {
3099 match self {
3100 CoroutineKind::Async { .. } => "async",
3101 CoroutineKind::Gen { .. } => "gen",
3102 CoroutineKind::AsyncGen { .. } => "async gen",
3103 }
3104 }
3105
3106 pub fn closure_id(self) -> NodeId {
3107 match self {
3108 CoroutineKind::Async { closure_id, .. }
3109 | CoroutineKind::Gen { closure_id, .. }
3110 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3111 }
3112 }
3113
3114 pub fn return_id(self) -> (NodeId, Span) {
3117 match self {
3118 CoroutineKind::Async { return_impl_trait_id, span, .. }
3119 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3120 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3121 (return_impl_trait_id, span)
3122 }
3123 }
3124 }
3125}
3126
3127#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3128#[derive(HashStable_Generic, Walkable)]
3129pub enum Const {
3130 Yes(Span),
3131 No,
3132}
3133
3134#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3137pub enum Defaultness {
3138 Default(Span),
3139 Final,
3140}
3141
3142#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3143pub enum ImplPolarity {
3144 Positive,
3146 Negative(Span),
3148}
3149
3150impl fmt::Debug for ImplPolarity {
3151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3152 match *self {
3153 ImplPolarity::Positive => "positive".fmt(f),
3154 ImplPolarity::Negative(_) => "negative".fmt(f),
3155 }
3156 }
3157}
3158
3159#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3161#[derive(HashStable_Generic, Walkable)]
3162pub enum BoundPolarity {
3163 Positive,
3165 Negative(Span),
3167 Maybe(Span),
3169}
3170
3171impl BoundPolarity {
3172 pub fn as_str(self) -> &'static str {
3173 match self {
3174 Self::Positive => "",
3175 Self::Negative(_) => "!",
3176 Self::Maybe(_) => "?",
3177 }
3178 }
3179}
3180
3181#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3183#[derive(HashStable_Generic, Walkable)]
3184pub enum BoundConstness {
3185 Never,
3187 Always(Span),
3189 Maybe(Span),
3191}
3192
3193impl BoundConstness {
3194 pub fn as_str(self) -> &'static str {
3195 match self {
3196 Self::Never => "",
3197 Self::Always(_) => "const",
3198 Self::Maybe(_) => "[const]",
3199 }
3200 }
3201}
3202
3203#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3205#[derive(HashStable_Generic, Walkable)]
3206pub enum BoundAsyncness {
3207 Normal,
3209 Async(Span),
3211}
3212
3213impl BoundAsyncness {
3214 pub fn as_str(self) -> &'static str {
3215 match self {
3216 Self::Normal => "",
3217 Self::Async(_) => "async",
3218 }
3219 }
3220}
3221
3222#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3223pub enum FnRetTy {
3224 Default(Span),
3229 Ty(Box<Ty>),
3231}
3232
3233impl FnRetTy {
3234 pub fn span(&self) -> Span {
3235 match self {
3236 &FnRetTy::Default(span) => span,
3237 FnRetTy::Ty(ty) => ty.span,
3238 }
3239 }
3240}
3241
3242#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3243pub enum Inline {
3244 Yes,
3245 No { had_parse_error: Result<(), ErrorGuaranteed> },
3246}
3247
3248#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3250pub enum ModKind {
3251 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3256 Unloaded,
3258}
3259
3260#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3261pub struct ModSpans {
3262 pub inner_span: Span,
3265 pub inject_use_span: Span,
3266}
3267
3268#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3272pub struct ForeignMod {
3273 pub extern_span: Span,
3275 pub safety: Safety,
3278 pub abi: Option<StrLit>,
3279 pub items: ThinVec<Box<ForeignItem>>,
3280}
3281
3282#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3283pub struct EnumDef {
3284 pub variants: ThinVec<Variant>,
3285}
3286
3287#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3289pub struct Variant {
3290 pub attrs: AttrVec,
3292 pub id: NodeId,
3294 pub span: Span,
3296 pub vis: Visibility,
3298 pub ident: Ident,
3300
3301 pub data: VariantData,
3303 pub disr_expr: Option<AnonConst>,
3305 pub is_placeholder: bool,
3307}
3308
3309#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3311pub enum UseTreeKind {
3312 Simple(Option<Ident>),
3314 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3323 Glob,
3325}
3326
3327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3330pub struct UseTree {
3331 pub prefix: Path,
3332 pub kind: UseTreeKind,
3333 pub span: Span,
3334}
3335
3336impl UseTree {
3337 pub fn ident(&self) -> Ident {
3338 match self.kind {
3339 UseTreeKind::Simple(Some(rename)) => rename,
3340 UseTreeKind::Simple(None) => {
3341 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3342 }
3343 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3344 }
3345 }
3346}
3347
3348#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3352pub enum AttrStyle {
3353 Outer,
3354 Inner,
3355}
3356
3357pub type AttrVec = ThinVec<Attribute>;
3359
3360#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3362pub struct Attribute {
3363 pub kind: AttrKind,
3364 pub id: AttrId,
3365 pub style: AttrStyle,
3368 pub span: Span,
3369}
3370
3371#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3372pub enum AttrKind {
3373 Normal(Box<NormalAttr>),
3375
3376 DocComment(CommentKind, Symbol),
3380}
3381
3382#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3383pub struct NormalAttr {
3384 pub item: AttrItem,
3385 pub tokens: Option<LazyAttrTokenStream>,
3387}
3388
3389impl NormalAttr {
3390 pub fn from_ident(ident: Ident) -> Self {
3391 Self {
3392 item: AttrItem {
3393 unsafety: Safety::Default,
3394 path: Path::from_ident(ident),
3395 args: AttrItemKind::Unparsed(AttrArgs::Empty),
3396 tokens: None,
3397 },
3398 tokens: None,
3399 }
3400 }
3401}
3402
3403#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3404pub struct AttrItem {
3405 pub unsafety: Safety,
3406 pub path: Path,
3407 pub args: AttrItemKind,
3408 pub tokens: Option<LazyAttrTokenStream>,
3410}
3411
3412#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3415pub enum AttrItemKind {
3416 Parsed(EarlyParsedAttribute),
3417 Unparsed(AttrArgs),
3418}
3419
3420impl AttrItemKind {
3421 pub fn unparsed(self) -> Option<AttrArgs> {
3422 match self {
3423 AttrItemKind::Unparsed(args) => Some(args),
3424 AttrItemKind::Parsed(_) => None,
3425 }
3426 }
3427
3428 pub fn unparsed_ref(&self) -> Option<&AttrArgs> {
3429 match self {
3430 AttrItemKind::Unparsed(args) => Some(args),
3431 AttrItemKind::Parsed(_) => None,
3432 }
3433 }
3434
3435 pub fn span(&self) -> Option<Span> {
3436 match self {
3437 AttrItemKind::Unparsed(args) => args.span(),
3438 AttrItemKind::Parsed(_) => None,
3439 }
3440 }
3441}
3442
3443#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
3449pub enum EarlyParsedAttribute {
3450 CfgTrace(CfgEntry),
3451 CfgAttrTrace,
3452}
3453
3454impl AttrItem {
3455 pub fn is_valid_for_outer_style(&self) -> bool {
3456 self.path == sym::cfg_attr
3457 || self.path == sym::cfg
3458 || self.path == sym::forbid
3459 || self.path == sym::warn
3460 || self.path == sym::allow
3461 || self.path == sym::deny
3462 }
3463}
3464
3465#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3472pub struct TraitRef {
3473 pub path: Path,
3474 pub ref_id: NodeId,
3475}
3476
3477#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3479pub enum Parens {
3480 Yes,
3481 No,
3482}
3483
3484#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3485pub struct PolyTraitRef {
3486 pub bound_generic_params: ThinVec<GenericParam>,
3488
3489 pub modifiers: TraitBoundModifiers,
3491
3492 pub trait_ref: TraitRef,
3494
3495 pub span: Span,
3496
3497 pub parens: Parens,
3500}
3501
3502impl PolyTraitRef {
3503 pub fn new(
3504 generic_params: ThinVec<GenericParam>,
3505 path: Path,
3506 modifiers: TraitBoundModifiers,
3507 span: Span,
3508 parens: Parens,
3509 ) -> Self {
3510 PolyTraitRef {
3511 bound_generic_params: generic_params,
3512 modifiers,
3513 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3514 span,
3515 parens,
3516 }
3517 }
3518}
3519
3520#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3521pub struct Visibility {
3522 pub kind: VisibilityKind,
3523 pub span: Span,
3524 pub tokens: Option<LazyAttrTokenStream>,
3525}
3526
3527#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3528pub enum VisibilityKind {
3529 Public,
3530 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3531 Inherited,
3532}
3533
3534impl VisibilityKind {
3535 pub fn is_pub(&self) -> bool {
3536 matches!(self, VisibilityKind::Public)
3537 }
3538}
3539
3540#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3544pub struct FieldDef {
3545 pub attrs: AttrVec,
3546 pub id: NodeId,
3547 pub span: Span,
3548 pub vis: Visibility,
3549 pub safety: Safety,
3550 pub ident: Option<Ident>,
3551
3552 pub ty: Box<Ty>,
3553 pub default: Option<AnonConst>,
3554 pub is_placeholder: bool,
3555}
3556
3557#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3559pub enum Recovered {
3560 No,
3561 Yes(ErrorGuaranteed),
3562}
3563
3564#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3566pub enum VariantData {
3567 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3571 Tuple(ThinVec<FieldDef>, NodeId),
3575 Unit(NodeId),
3579}
3580
3581impl VariantData {
3582 pub fn fields(&self) -> &[FieldDef] {
3584 match self {
3585 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3586 _ => &[],
3587 }
3588 }
3589
3590 pub fn ctor_node_id(&self) -> Option<NodeId> {
3592 match *self {
3593 VariantData::Struct { .. } => None,
3594 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3595 }
3596 }
3597}
3598
3599#[derive(Clone, Encodable, Decodable, Debug)]
3601pub struct Item<K = ItemKind> {
3602 pub attrs: AttrVec,
3603 pub id: NodeId,
3604 pub span: Span,
3605 pub vis: Visibility,
3606
3607 pub kind: K,
3608
3609 pub tokens: Option<LazyAttrTokenStream>,
3617}
3618
3619impl Item {
3620 pub fn span_with_attributes(&self) -> Span {
3622 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3623 }
3624
3625 pub fn opt_generics(&self) -> Option<&Generics> {
3626 match &self.kind {
3627 ItemKind::ExternCrate(..)
3628 | ItemKind::Use(_)
3629 | ItemKind::Mod(..)
3630 | ItemKind::ForeignMod(_)
3631 | ItemKind::GlobalAsm(_)
3632 | ItemKind::MacCall(_)
3633 | ItemKind::Delegation(_)
3634 | ItemKind::DelegationMac(_)
3635 | ItemKind::MacroDef(..) => None,
3636 ItemKind::Static(_) => None,
3637 ItemKind::Const(i) => Some(&i.generics),
3638 ItemKind::Fn(i) => Some(&i.generics),
3639 ItemKind::TyAlias(i) => Some(&i.generics),
3640 ItemKind::TraitAlias(i) => Some(&i.generics),
3641
3642 ItemKind::Enum(_, generics, _)
3643 | ItemKind::Struct(_, generics, _)
3644 | ItemKind::Union(_, generics, _) => Some(&generics),
3645 ItemKind::Trait(i) => Some(&i.generics),
3646 ItemKind::Impl(i) => Some(&i.generics),
3647 }
3648 }
3649}
3650
3651#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3653pub enum Extern {
3654 None,
3658 Implicit(Span),
3664 Explicit(StrLit, Span),
3668}
3669
3670impl Extern {
3671 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3672 match abi {
3673 Some(name) => Extern::Explicit(name, span),
3674 None => Extern::Implicit(span),
3675 }
3676 }
3677
3678 pub fn span(self) -> Option<Span> {
3679 match self {
3680 Extern::None => None,
3681 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3682 }
3683 }
3684}
3685
3686#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3691pub struct FnHeader {
3692 pub constness: Const,
3694 pub coroutine_kind: Option<CoroutineKind>,
3696 pub safety: Safety,
3698 pub ext: Extern,
3700}
3701
3702impl FnHeader {
3703 pub fn has_qualifiers(&self) -> bool {
3705 let Self { safety, coroutine_kind, constness, ext } = self;
3706 matches!(safety, Safety::Unsafe(_))
3707 || coroutine_kind.is_some()
3708 || matches!(constness, Const::Yes(_))
3709 || !matches!(ext, Extern::None)
3710 }
3711}
3712
3713impl Default for FnHeader {
3714 fn default() -> FnHeader {
3715 FnHeader {
3716 safety: Safety::Default,
3717 coroutine_kind: None,
3718 constness: Const::No,
3719 ext: Extern::None,
3720 }
3721 }
3722}
3723
3724#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3725pub struct TraitAlias {
3726 pub constness: Const,
3727 pub ident: Ident,
3728 pub generics: Generics,
3729 #[visitable(extra = BoundKind::Bound)]
3730 pub bounds: GenericBounds,
3731}
3732
3733#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3734pub struct Trait {
3735 pub constness: Const,
3736 pub safety: Safety,
3737 pub is_auto: IsAuto,
3738 pub ident: Ident,
3739 pub generics: Generics,
3740 #[visitable(extra = BoundKind::SuperTraits)]
3741 pub bounds: GenericBounds,
3742 #[visitable(extra = AssocCtxt::Trait)]
3743 pub items: ThinVec<Box<AssocItem>>,
3744}
3745
3746#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3747pub struct TyAlias {
3748 pub defaultness: Defaultness,
3749 pub ident: Ident,
3750 pub generics: Generics,
3751 pub after_where_clause: WhereClause,
3766 #[visitable(extra = BoundKind::Bound)]
3767 pub bounds: GenericBounds,
3768 pub ty: Option<Box<Ty>>,
3769}
3770
3771#[derive(Clone, Encodable, Decodable, Debug)]
3772pub struct Impl {
3773 pub generics: Generics,
3774 pub constness: Const,
3775 pub of_trait: Option<Box<TraitImplHeader>>,
3776 pub self_ty: Box<Ty>,
3777 pub items: ThinVec<Box<AssocItem>>,
3778}
3779
3780#[derive(Clone, Encodable, Decodable, Debug)]
3781pub struct TraitImplHeader {
3782 pub defaultness: Defaultness,
3783 pub safety: Safety,
3784 pub polarity: ImplPolarity,
3785 pub trait_ref: TraitRef,
3786}
3787
3788#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3789pub struct FnContract {
3790 pub declarations: ThinVec<Stmt>,
3793 pub requires: Option<Box<Expr>>,
3794 pub ensures: Option<Box<Expr>>,
3795}
3796
3797#[derive(Clone, Encodable, Decodable, Debug)]
3798pub struct Fn {
3799 pub defaultness: Defaultness,
3800 pub ident: Ident,
3801 pub generics: Generics,
3802 pub sig: FnSig,
3803 pub contract: Option<Box<FnContract>>,
3804 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3805 pub body: Option<Box<Block>>,
3806
3807 pub eii_impls: ThinVec<EiiImpl>,
3811}
3812
3813#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3814pub struct EiiImpl {
3815 pub node_id: NodeId,
3816 pub eii_macro_path: Path,
3817 pub known_eii_macro_resolution: Option<EiiDecl>,
3830 pub impl_safety: Safety,
3831 pub span: Span,
3832 pub inner_span: Span,
3833 pub is_default: bool,
3834}
3835
3836#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3837pub struct Delegation {
3838 pub id: NodeId,
3840 pub qself: Option<Box<QSelf>>,
3841 pub path: Path,
3842 pub ident: Ident,
3843 pub rename: Option<Ident>,
3844 pub body: Option<Box<Block>>,
3845 pub from_glob: bool,
3847}
3848
3849#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3850pub struct DelegationMac {
3851 pub qself: Option<Box<QSelf>>,
3852 pub prefix: Path,
3853 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3855 pub body: Option<Box<Block>>,
3856}
3857
3858#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3859pub struct StaticItem {
3860 pub ident: Ident,
3861 pub ty: Box<Ty>,
3862 pub safety: Safety,
3863 pub mutability: Mutability,
3864 pub expr: Option<Box<Expr>>,
3865 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3866}
3867
3868#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3869pub struct ConstItem {
3870 pub defaultness: Defaultness,
3871 pub ident: Ident,
3872 pub generics: Generics,
3873 pub ty: Box<Ty>,
3874 pub rhs: Option<ConstItemRhs>,
3875 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3876}
3877
3878#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3879pub enum ConstItemRhs {
3880 TypeConst(AnonConst),
3881 Body(Box<Expr>),
3882}
3883
3884impl ConstItemRhs {
3885 pub fn span(&self) -> Span {
3886 self.expr().span
3887 }
3888
3889 pub fn expr(&self) -> &Expr {
3890 match self {
3891 ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
3892 ConstItemRhs::Body(expr) => expr,
3893 }
3894 }
3895}
3896
3897#[derive(Clone, Encodable, Decodable, Debug)]
3899pub enum ItemKind {
3900 ExternCrate(Option<Symbol>, Ident),
3904 Use(UseTree),
3908 Static(Box<StaticItem>),
3912 Const(Box<ConstItem>),
3916 Fn(Box<Fn>),
3920 Mod(Safety, Ident, ModKind),
3926 ForeignMod(ForeignMod),
3930 GlobalAsm(Box<InlineAsm>),
3932 TyAlias(Box<TyAlias>),
3936 Enum(Ident, Generics, EnumDef),
3940 Struct(Ident, Generics, VariantData),
3944 Union(Ident, Generics, VariantData),
3948 Trait(Box<Trait>),
3952 TraitAlias(Box<TraitAlias>),
3956 Impl(Impl),
3960 MacCall(Box<MacCall>),
3964 MacroDef(Ident, MacroDef),
3966 Delegation(Box<Delegation>),
3970 DelegationMac(Box<DelegationMac>),
3973}
3974
3975impl ItemKind {
3976 pub fn ident(&self) -> Option<Ident> {
3977 match *self {
3978 ItemKind::ExternCrate(_, ident)
3979 | ItemKind::Static(box StaticItem { ident, .. })
3980 | ItemKind::Const(box ConstItem { ident, .. })
3981 | ItemKind::Fn(box Fn { ident, .. })
3982 | ItemKind::Mod(_, ident, _)
3983 | ItemKind::TyAlias(box TyAlias { ident, .. })
3984 | ItemKind::Enum(ident, ..)
3985 | ItemKind::Struct(ident, ..)
3986 | ItemKind::Union(ident, ..)
3987 | ItemKind::Trait(box Trait { ident, .. })
3988 | ItemKind::TraitAlias(box TraitAlias { ident, .. })
3989 | ItemKind::MacroDef(ident, _)
3990 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3991
3992 ItemKind::Use(_)
3993 | ItemKind::ForeignMod(_)
3994 | ItemKind::GlobalAsm(_)
3995 | ItemKind::Impl(_)
3996 | ItemKind::MacCall(_)
3997 | ItemKind::DelegationMac(_) => None,
3998 }
3999 }
4000
4001 pub fn article(&self) -> &'static str {
4003 use ItemKind::*;
4004 match self {
4005 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
4006 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
4007 | Delegation(..) | DelegationMac(..) => "a",
4008 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
4009 }
4010 }
4011
4012 pub fn descr(&self) -> &'static str {
4013 match self {
4014 ItemKind::ExternCrate(..) => "extern crate",
4015 ItemKind::Use(..) => "`use` import",
4016 ItemKind::Static(..) => "static item",
4017 ItemKind::Const(..) => "constant item",
4018 ItemKind::Fn(..) => "function",
4019 ItemKind::Mod(..) => "module",
4020 ItemKind::ForeignMod(..) => "extern block",
4021 ItemKind::GlobalAsm(..) => "global asm item",
4022 ItemKind::TyAlias(..) => "type alias",
4023 ItemKind::Enum(..) => "enum",
4024 ItemKind::Struct(..) => "struct",
4025 ItemKind::Union(..) => "union",
4026 ItemKind::Trait(..) => "trait",
4027 ItemKind::TraitAlias(..) => "trait alias",
4028 ItemKind::MacCall(..) => "item macro invocation",
4029 ItemKind::MacroDef(..) => "macro definition",
4030 ItemKind::Impl { .. } => "implementation",
4031 ItemKind::Delegation(..) => "delegated function",
4032 ItemKind::DelegationMac(..) => "delegation",
4033 }
4034 }
4035
4036 pub fn generics(&self) -> Option<&Generics> {
4037 match self {
4038 Self::Fn(box Fn { generics, .. })
4039 | Self::TyAlias(box TyAlias { generics, .. })
4040 | Self::Const(box ConstItem { generics, .. })
4041 | Self::Enum(_, generics, _)
4042 | Self::Struct(_, generics, _)
4043 | Self::Union(_, generics, _)
4044 | Self::Trait(box Trait { generics, .. })
4045 | Self::TraitAlias(box TraitAlias { generics, .. })
4046 | Self::Impl(Impl { generics, .. }) => Some(generics),
4047 _ => None,
4048 }
4049 }
4050}
4051
4052pub type AssocItem = Item<AssocItemKind>;
4055
4056#[derive(Clone, Encodable, Decodable, Debug)]
4064pub enum AssocItemKind {
4065 Const(Box<ConstItem>),
4068 Fn(Box<Fn>),
4070 Type(Box<TyAlias>),
4072 MacCall(Box<MacCall>),
4074 Delegation(Box<Delegation>),
4076 DelegationMac(Box<DelegationMac>),
4078}
4079
4080impl AssocItemKind {
4081 pub fn ident(&self) -> Option<Ident> {
4082 match *self {
4083 AssocItemKind::Const(box ConstItem { ident, .. })
4084 | AssocItemKind::Fn(box Fn { ident, .. })
4085 | AssocItemKind::Type(box TyAlias { ident, .. })
4086 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
4087
4088 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
4089 }
4090 }
4091
4092 pub fn defaultness(&self) -> Defaultness {
4093 match *self {
4094 Self::Const(box ConstItem { defaultness, .. })
4095 | Self::Fn(box Fn { defaultness, .. })
4096 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
4097 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
4098 Defaultness::Final
4099 }
4100 }
4101 }
4102}
4103
4104impl From<AssocItemKind> for ItemKind {
4105 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4106 match assoc_item_kind {
4107 AssocItemKind::Const(item) => ItemKind::Const(item),
4108 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4109 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4110 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4111 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4112 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4113 }
4114 }
4115}
4116
4117impl TryFrom<ItemKind> for AssocItemKind {
4118 type Error = ItemKind;
4119
4120 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4121 Ok(match item_kind {
4122 ItemKind::Const(item) => AssocItemKind::Const(item),
4123 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4124 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4125 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4126 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4127 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4128 _ => return Err(item_kind),
4129 })
4130 }
4131}
4132
4133#[derive(Clone, Encodable, Decodable, Debug)]
4135pub enum ForeignItemKind {
4136 Static(Box<StaticItem>),
4138 Fn(Box<Fn>),
4140 TyAlias(Box<TyAlias>),
4142 MacCall(Box<MacCall>),
4144}
4145
4146impl ForeignItemKind {
4147 pub fn ident(&self) -> Option<Ident> {
4148 match *self {
4149 ForeignItemKind::Static(box StaticItem { ident, .. })
4150 | ForeignItemKind::Fn(box Fn { ident, .. })
4151 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4152
4153 ForeignItemKind::MacCall(_) => None,
4154 }
4155 }
4156}
4157
4158impl From<ForeignItemKind> for ItemKind {
4159 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4160 match foreign_item_kind {
4161 ForeignItemKind::Static(box static_foreign_item) => {
4162 ItemKind::Static(Box::new(static_foreign_item))
4163 }
4164 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4165 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4166 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4167 }
4168 }
4169}
4170
4171impl TryFrom<ItemKind> for ForeignItemKind {
4172 type Error = ItemKind;
4173
4174 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4175 Ok(match item_kind {
4176 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4177 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4178 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4179 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4180 _ => return Err(item_kind),
4181 })
4182 }
4183}
4184
4185pub type ForeignItem = Item<ForeignItemKind>;
4186
4187#[cfg(target_pointer_width = "64")]
4189mod size_asserts {
4190 use rustc_data_structures::static_assert_size;
4191
4192 use super::*;
4193 static_assert_size!(AssocItem, 80);
4195 static_assert_size!(AssocItemKind, 16);
4196 static_assert_size!(Attribute, 32);
4197 static_assert_size!(Block, 32);
4198 static_assert_size!(Expr, 72);
4199 static_assert_size!(ExprKind, 40);
4200 static_assert_size!(Fn, 192);
4201 static_assert_size!(ForeignItem, 80);
4202 static_assert_size!(ForeignItemKind, 16);
4203 static_assert_size!(GenericArg, 24);
4204 static_assert_size!(GenericBound, 88);
4205 static_assert_size!(Generics, 40);
4206 static_assert_size!(Impl, 80);
4207 static_assert_size!(Item, 152);
4208 static_assert_size!(ItemKind, 88);
4209 static_assert_size!(LitKind, 24);
4210 static_assert_size!(Local, 96);
4211 static_assert_size!(MetaItemLit, 40);
4212 static_assert_size!(Param, 40);
4213 static_assert_size!(Pat, 80);
4214 static_assert_size!(PatKind, 56);
4215 static_assert_size!(Path, 24);
4216 static_assert_size!(PathSegment, 24);
4217 static_assert_size!(Stmt, 32);
4218 static_assert_size!(StmtKind, 16);
4219 static_assert_size!(TraitImplHeader, 72);
4220 static_assert_size!(Ty, 64);
4221 static_assert_size!(TyKind, 40);
4222 }