1use std::borrow::{Borrow, Cow};
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
27use rustc_data_structures::packed::Pu128;
28use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
29use rustc_data_structures::stack::ensure_sufficient_stack;
30use rustc_data_structures::tagged_ptr::Tag;
31use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
32pub use rustc_span::AttrId;
33use rustc_span::source_map::{Spanned, respan};
34use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
35use thin_vec::{ThinVec, thin_vec};
36
37pub use crate::format::*;
38use crate::token::{self, CommentKind, Delimiter};
39use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
40use crate::util::parser::{ExprPrecedence, Fixity};
41use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
42
43#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
54pub struct Label {
55 pub ident: Ident,
56}
57
58impl fmt::Debug for Label {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "label({:?})", self.ident)
61 }
62}
63
64#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
67pub struct Lifetime {
68 pub id: NodeId,
69 pub ident: Ident,
70}
71
72impl fmt::Debug for Lifetime {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 write!(f, "lifetime({}: {})", self.id, self)
75 }
76}
77
78impl fmt::Display for Lifetime {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(f, "{}", self.ident.name)
81 }
82}
83
84#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
91pub struct Path {
92 pub span: Span,
93 pub segments: ThinVec<PathSegment>,
96 pub tokens: Option<LazyAttrTokenStream>,
97}
98
99impl PartialEq<Symbol> for Path {
101 #[inline]
102 fn eq(&self, name: &Symbol) -> bool {
103 if let [segment] = self.segments.as_ref()
104 && segment == name
105 {
106 true
107 } else {
108 false
109 }
110 }
111}
112
113impl PartialEq<&[Symbol]> for Path {
115 #[inline]
116 fn eq(&self, names: &&[Symbol]) -> bool {
117 self.segments.iter().eq(*names)
118 }
119}
120
121impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
122 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
123 self.segments.len().hash_stable(hcx, hasher);
124 for segment in &self.segments {
125 segment.ident.hash_stable(hcx, hasher);
126 }
127 }
128}
129
130impl Path {
131 pub fn from_ident(ident: Ident) -> Path {
134 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
135 }
136
137 pub fn is_global(&self) -> bool {
138 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
139 }
140
141 #[tracing::instrument(level = "debug", ret)]
151 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
152 allow_mgca_arg
153 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
154 }
155}
156
157pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
169 let mut iter = path.into_iter();
174 let len_hint = iter.size_hint().1.unwrap_or(1);
175 let mut s = String::with_capacity(len_hint * 8);
176
177 let first_sym = *iter.next().unwrap().borrow();
178 if first_sym != kw::PathRoot {
179 s.push_str(first_sym.as_str());
180 }
181 for sym in iter {
182 let sym = *sym.borrow();
183 debug_assert_ne!(sym, kw::PathRoot);
184 s.push_str("::");
185 s.push_str(sym.as_str());
186 }
187 s
188}
189
190pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
193 let mut iter = path.into_iter();
194 let len_hint = iter.size_hint().1.unwrap_or(1);
195 let mut s = String::with_capacity(len_hint * 8);
196
197 let first_ident = *iter.next().unwrap().borrow();
198 if first_ident.name != kw::PathRoot {
199 s.push_str(&first_ident.to_string());
200 }
201 for ident in iter {
202 let ident = *ident.borrow();
203 debug_assert_ne!(ident.name, kw::PathRoot);
204 s.push_str("::");
205 s.push_str(&ident.to_string());
206 }
207 s
208}
209
210#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
214pub struct PathSegment {
215 pub ident: Ident,
217
218 pub id: NodeId,
219
220 pub args: Option<Box<GenericArgs>>,
227}
228
229impl PartialEq<Symbol> for PathSegment {
231 #[inline]
232 fn eq(&self, name: &Symbol) -> bool {
233 self.args.is_none() && self.ident.name == *name
234 }
235}
236
237impl PathSegment {
238 pub fn from_ident(ident: Ident) -> Self {
239 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
240 }
241
242 pub fn path_root(span: Span) -> Self {
243 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
244 }
245
246 pub fn span(&self) -> Span {
247 match &self.args {
248 Some(args) => self.ident.span.to(args.span()),
249 None => self.ident.span,
250 }
251 }
252}
253
254#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
258pub enum GenericArgs {
259 AngleBracketed(AngleBracketedArgs),
261 Parenthesized(ParenthesizedArgs),
263 ParenthesizedElided(Span),
265}
266
267impl GenericArgs {
268 pub fn is_angle_bracketed(&self) -> bool {
269 matches!(self, AngleBracketed(..))
270 }
271
272 pub fn span(&self) -> Span {
273 match self {
274 AngleBracketed(data) => data.span,
275 Parenthesized(data) => data.span,
276 ParenthesizedElided(span) => *span,
277 }
278 }
279}
280
281#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
283pub enum GenericArg {
284 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
286 Type(Box<Ty>),
288 Const(AnonConst),
290}
291
292impl GenericArg {
293 pub fn span(&self) -> Span {
294 match self {
295 GenericArg::Lifetime(lt) => lt.ident.span,
296 GenericArg::Type(ty) => ty.span,
297 GenericArg::Const(ct) => ct.value.span,
298 }
299 }
300}
301
302#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
304pub struct AngleBracketedArgs {
305 pub span: Span,
307 pub args: ThinVec<AngleBracketedArg>,
309}
310
311#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
313pub enum AngleBracketedArg {
314 Arg(GenericArg),
316 Constraint(AssocItemConstraint),
318}
319
320impl AngleBracketedArg {
321 pub fn span(&self) -> Span {
322 match self {
323 AngleBracketedArg::Arg(arg) => arg.span(),
324 AngleBracketedArg::Constraint(constraint) => constraint.span,
325 }
326 }
327}
328
329impl From<AngleBracketedArgs> for Box<GenericArgs> {
330 fn from(val: AngleBracketedArgs) -> Self {
331 Box::new(GenericArgs::AngleBracketed(val))
332 }
333}
334
335impl From<ParenthesizedArgs> for Box<GenericArgs> {
336 fn from(val: ParenthesizedArgs) -> Self {
337 Box::new(GenericArgs::Parenthesized(val))
338 }
339}
340
341#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
343pub struct ParenthesizedArgs {
344 pub span: Span,
349
350 pub inputs: ThinVec<Box<Ty>>,
352
353 pub inputs_span: Span,
358
359 pub output: FnRetTy,
361}
362
363impl ParenthesizedArgs {
364 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
365 let args = self
366 .inputs
367 .iter()
368 .cloned()
369 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
370 .collect();
371 AngleBracketedArgs { span: self.inputs_span, args }
372 }
373}
374
375pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
376
377#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
379pub struct TraitBoundModifiers {
380 pub constness: BoundConstness,
381 pub asyncness: BoundAsyncness,
382 pub polarity: BoundPolarity,
383}
384
385impl TraitBoundModifiers {
386 pub const NONE: Self = Self {
387 constness: BoundConstness::Never,
388 asyncness: BoundAsyncness::Normal,
389 polarity: BoundPolarity::Positive,
390 };
391}
392
393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
394pub enum GenericBound {
395 Trait(PolyTraitRef),
396 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
397 Use(ThinVec<PreciseCapturingArg>, Span),
399}
400
401impl GenericBound {
402 pub fn span(&self) -> Span {
403 match self {
404 GenericBound::Trait(t, ..) => t.span,
405 GenericBound::Outlives(l) => l.ident.span,
406 GenericBound::Use(_, span) => *span,
407 }
408 }
409}
410
411pub type GenericBounds = Vec<GenericBound>;
412
413#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
417pub enum ParamKindOrd {
418 Lifetime,
419 TypeOrConst,
420}
421
422impl fmt::Display for ParamKindOrd {
423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424 match self {
425 ParamKindOrd::Lifetime => "lifetime".fmt(f),
426 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
427 }
428 }
429}
430
431#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
432pub enum GenericParamKind {
433 Lifetime,
435 Type {
436 default: Option<Box<Ty>>,
437 },
438 Const {
439 ty: Box<Ty>,
440 span: Span,
442 default: Option<AnonConst>,
444 },
445}
446
447#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
448pub struct GenericParam {
449 pub id: NodeId,
450 pub ident: Ident,
451 pub attrs: AttrVec,
452 #[visitable(extra = BoundKind::Bound)]
453 pub bounds: GenericBounds,
454 pub is_placeholder: bool,
455 pub kind: GenericParamKind,
456 pub colon_span: Option<Span>,
457}
458
459impl GenericParam {
460 pub fn span(&self) -> Span {
461 match &self.kind {
462 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
463 self.ident.span
464 }
465 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
466 GenericParamKind::Const { span, .. } => *span,
467 }
468 }
469}
470
471#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
474pub struct Generics {
475 pub params: ThinVec<GenericParam>,
476 pub where_clause: WhereClause,
477 pub span: Span,
478}
479
480#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
482pub struct WhereClause {
483 pub has_where_token: bool,
488 pub predicates: ThinVec<WherePredicate>,
489 pub span: Span,
490}
491
492impl WhereClause {
493 pub fn is_empty(&self) -> bool {
494 !self.has_where_token && self.predicates.is_empty()
495 }
496}
497
498#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
500pub struct WherePredicate {
501 pub attrs: AttrVec,
502 pub kind: WherePredicateKind,
503 pub id: NodeId,
504 pub span: Span,
505 pub is_placeholder: bool,
506}
507
508#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
510pub enum WherePredicateKind {
511 BoundPredicate(WhereBoundPredicate),
513 RegionPredicate(WhereRegionPredicate),
515 EqPredicate(WhereEqPredicate),
517}
518
519#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
523pub struct WhereBoundPredicate {
524 pub bound_generic_params: ThinVec<GenericParam>,
526 pub bounded_ty: Box<Ty>,
528 #[visitable(extra = BoundKind::Bound)]
530 pub bounds: GenericBounds,
531}
532
533#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
537pub struct WhereRegionPredicate {
538 #[visitable(extra = LifetimeCtxt::Bound)]
539 pub lifetime: Lifetime,
540 #[visitable(extra = BoundKind::Bound)]
541 pub bounds: GenericBounds,
542}
543
544#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
548pub struct WhereEqPredicate {
549 pub lhs_ty: Box<Ty>,
550 pub rhs_ty: Box<Ty>,
551}
552
553#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
554pub struct Crate {
555 pub id: NodeId,
558 pub attrs: AttrVec,
559 pub items: ThinVec<Box<Item>>,
560 pub spans: ModSpans,
561 pub is_placeholder: bool,
562}
563
564#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
571pub struct MetaItem {
572 pub unsafety: Safety,
573 pub path: Path,
574 pub kind: MetaItemKind,
575 pub span: Span,
576}
577
578#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
580pub enum MetaItemKind {
581 Word,
585
586 List(ThinVec<MetaItemInner>),
590
591 NameValue(MetaItemLit),
595}
596
597#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
601pub enum MetaItemInner {
602 MetaItem(MetaItem),
604
605 Lit(MetaItemLit),
609}
610
611#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
615pub struct Block {
616 pub stmts: ThinVec<Stmt>,
618 pub id: NodeId,
619 pub rules: BlockCheckMode,
621 pub span: Span,
622 pub tokens: Option<LazyAttrTokenStream>,
623}
624
625#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
629pub struct Pat {
630 pub id: NodeId,
631 pub kind: PatKind,
632 pub span: Span,
633 pub tokens: Option<LazyAttrTokenStream>,
634}
635
636impl Pat {
637 pub fn to_ty(&self) -> Option<Box<Ty>> {
640 let kind = match &self.kind {
641 PatKind::Missing => unreachable!(),
642 PatKind::Wild => TyKind::Infer,
644 PatKind::Ident(BindingMode::NONE, ident, None) => {
646 TyKind::Path(None, Path::from_ident(*ident))
647 }
648 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
649 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
650 PatKind::Ref(pat, mutbl) => {
652 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
653 }
654 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
657 pat.to_ty().map(TyKind::Slice)?
658 }
659 PatKind::Tuple(pats) => {
662 let mut tys = ThinVec::with_capacity(pats.len());
663 for pat in pats {
665 tys.push(pat.to_ty()?);
666 }
667 TyKind::Tup(tys)
668 }
669 _ => return None,
670 };
671
672 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
673 }
674
675 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
679 if !it(self) {
680 return;
681 }
682
683 match &self.kind {
684 PatKind::Ident(_, _, Some(p)) => p.walk(it),
686
687 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
689
690 PatKind::TupleStruct(_, _, s)
692 | PatKind::Tuple(s)
693 | PatKind::Slice(s)
694 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
695
696 PatKind::Box(s)
698 | PatKind::Deref(s)
699 | PatKind::Ref(s, _)
700 | PatKind::Paren(s)
701 | PatKind::Guard(s, _) => s.walk(it),
702
703 PatKind::Missing
705 | PatKind::Wild
706 | PatKind::Rest
707 | PatKind::Never
708 | PatKind::Expr(_)
709 | PatKind::Range(..)
710 | PatKind::Ident(..)
711 | PatKind::Path(..)
712 | PatKind::MacCall(_)
713 | PatKind::Err(_) => {}
714 }
715 }
716
717 pub fn is_rest(&self) -> bool {
719 matches!(self.kind, PatKind::Rest)
720 }
721
722 pub fn could_be_never_pattern(&self) -> bool {
725 let mut could_be_never_pattern = false;
726 self.walk(&mut |pat| match &pat.kind {
727 PatKind::Never | PatKind::MacCall(_) => {
728 could_be_never_pattern = true;
729 false
730 }
731 PatKind::Or(s) => {
732 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
733 false
734 }
735 _ => true,
736 });
737 could_be_never_pattern
738 }
739
740 pub fn contains_never_pattern(&self) -> bool {
743 let mut contains_never_pattern = false;
744 self.walk(&mut |pat| {
745 if matches!(pat.kind, PatKind::Never) {
746 contains_never_pattern = true;
747 }
748 true
749 });
750 contains_never_pattern
751 }
752
753 pub fn descr(&self) -> Option<String> {
755 match &self.kind {
756 PatKind::Missing => unreachable!(),
757 PatKind::Wild => Some("_".to_string()),
758 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
759 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
760 _ => None,
761 }
762 }
763}
764
765impl From<Box<Pat>> for Pat {
766 fn from(value: Box<Pat>) -> Self {
767 *value
768 }
769}
770
771#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
777pub struct PatField {
778 pub ident: Ident,
780 pub pat: Box<Pat>,
782 pub is_shorthand: bool,
783 pub attrs: AttrVec,
784 pub id: NodeId,
785 pub span: Span,
786 pub is_placeholder: bool,
787}
788
789#[derive(Clone, Copy, Debug, Eq, PartialEq)]
790#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
791pub enum ByRef {
792 Yes(Mutability),
793 No,
794}
795
796impl ByRef {
797 #[must_use]
798 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
799 if let ByRef::Yes(old_mutbl) = &mut self {
800 *old_mutbl = cmp::min(*old_mutbl, mutbl);
801 }
802 self
803 }
804}
805
806#[derive(Clone, Copy, Debug, Eq, PartialEq)]
812#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
813pub struct BindingMode(pub ByRef, pub Mutability);
814
815impl BindingMode {
816 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
817 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
818 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
819 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
820 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
821 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
822
823 pub fn prefix_str(self) -> &'static str {
824 match self {
825 Self::NONE => "",
826 Self::REF => "ref ",
827 Self::MUT => "mut ",
828 Self::REF_MUT => "ref mut ",
829 Self::MUT_REF => "mut ref ",
830 Self::MUT_REF_MUT => "mut ref mut ",
831 }
832 }
833}
834
835#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
836pub enum RangeEnd {
837 Included(RangeSyntax),
839 Excluded,
841}
842
843#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
844pub enum RangeSyntax {
845 DotDotDot,
847 DotDotEq,
849}
850
851#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
855pub enum PatKind {
856 Missing,
858
859 Wild,
861
862 Ident(BindingMode, Ident, Option<Box<Pat>>),
867
868 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
870
871 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
873
874 Or(ThinVec<Pat>),
877
878 Path(Option<Box<QSelf>>, Path),
883
884 Tuple(ThinVec<Pat>),
886
887 Box(Box<Pat>),
889
890 Deref(Box<Pat>),
892
893 Ref(Box<Pat>, Mutability),
895
896 Expr(Box<Expr>),
898
899 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
901
902 Slice(ThinVec<Pat>),
904
905 Rest,
918
919 Never,
921
922 Guard(Box<Pat>, Box<Expr>),
924
925 Paren(Box<Pat>),
927
928 MacCall(Box<MacCall>),
930
931 Err(ErrorGuaranteed),
933}
934
935#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
937pub enum PatFieldsRest {
938 Rest(Span),
940 Recovered(ErrorGuaranteed),
942 None,
944}
945
946#[derive(Clone, Copy, PartialEq, Eq, Debug)]
949#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
950pub enum BorrowKind {
951 Ref,
955 Raw,
959 Pin,
963}
964
965#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
966pub enum BinOpKind {
967 Add,
969 Sub,
971 Mul,
973 Div,
975 Rem,
977 And,
979 Or,
981 BitXor,
983 BitAnd,
985 BitOr,
987 Shl,
989 Shr,
991 Eq,
993 Lt,
995 Le,
997 Ne,
999 Ge,
1001 Gt,
1003}
1004
1005impl BinOpKind {
1006 pub fn as_str(&self) -> &'static str {
1007 use BinOpKind::*;
1008 match self {
1009 Add => "+",
1010 Sub => "-",
1011 Mul => "*",
1012 Div => "/",
1013 Rem => "%",
1014 And => "&&",
1015 Or => "||",
1016 BitXor => "^",
1017 BitAnd => "&",
1018 BitOr => "|",
1019 Shl => "<<",
1020 Shr => ">>",
1021 Eq => "==",
1022 Lt => "<",
1023 Le => "<=",
1024 Ne => "!=",
1025 Ge => ">=",
1026 Gt => ">",
1027 }
1028 }
1029
1030 pub fn is_lazy(&self) -> bool {
1031 matches!(self, BinOpKind::And | BinOpKind::Or)
1032 }
1033
1034 pub fn precedence(&self) -> ExprPrecedence {
1035 use BinOpKind::*;
1036 match *self {
1037 Mul | Div | Rem => ExprPrecedence::Product,
1038 Add | Sub => ExprPrecedence::Sum,
1039 Shl | Shr => ExprPrecedence::Shift,
1040 BitAnd => ExprPrecedence::BitAnd,
1041 BitXor => ExprPrecedence::BitXor,
1042 BitOr => ExprPrecedence::BitOr,
1043 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1044 And => ExprPrecedence::LAnd,
1045 Or => ExprPrecedence::LOr,
1046 }
1047 }
1048
1049 pub fn fixity(&self) -> Fixity {
1050 use BinOpKind::*;
1051 match self {
1052 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1053 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1054 Fixity::Left
1055 }
1056 }
1057 }
1058
1059 pub fn is_comparison(self) -> bool {
1060 use BinOpKind::*;
1061 match self {
1062 Eq | Ne | Lt | Le | Gt | Ge => true,
1063 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1064 }
1065 }
1066
1067 pub fn is_by_value(self) -> bool {
1069 !self.is_comparison()
1070 }
1071}
1072
1073pub type BinOp = Spanned<BinOpKind>;
1074
1075impl From<AssignOpKind> for BinOpKind {
1079 fn from(op: AssignOpKind) -> BinOpKind {
1080 match op {
1081 AssignOpKind::AddAssign => BinOpKind::Add,
1082 AssignOpKind::SubAssign => BinOpKind::Sub,
1083 AssignOpKind::MulAssign => BinOpKind::Mul,
1084 AssignOpKind::DivAssign => BinOpKind::Div,
1085 AssignOpKind::RemAssign => BinOpKind::Rem,
1086 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1087 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1088 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1089 AssignOpKind::ShlAssign => BinOpKind::Shl,
1090 AssignOpKind::ShrAssign => BinOpKind::Shr,
1091 }
1092 }
1093}
1094
1095#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1096pub enum AssignOpKind {
1097 AddAssign,
1099 SubAssign,
1101 MulAssign,
1103 DivAssign,
1105 RemAssign,
1107 BitXorAssign,
1109 BitAndAssign,
1111 BitOrAssign,
1113 ShlAssign,
1115 ShrAssign,
1117}
1118
1119impl AssignOpKind {
1120 pub fn as_str(&self) -> &'static str {
1121 use AssignOpKind::*;
1122 match self {
1123 AddAssign => "+=",
1124 SubAssign => "-=",
1125 MulAssign => "*=",
1126 DivAssign => "/=",
1127 RemAssign => "%=",
1128 BitXorAssign => "^=",
1129 BitAndAssign => "&=",
1130 BitOrAssign => "|=",
1131 ShlAssign => "<<=",
1132 ShrAssign => ">>=",
1133 }
1134 }
1135
1136 pub fn is_by_value(self) -> bool {
1138 true
1139 }
1140}
1141
1142pub type AssignOp = Spanned<AssignOpKind>;
1143
1144#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1148pub enum UnOp {
1149 Deref,
1151 Not,
1153 Neg,
1155}
1156
1157impl UnOp {
1158 pub fn as_str(&self) -> &'static str {
1159 match self {
1160 UnOp::Deref => "*",
1161 UnOp::Not => "!",
1162 UnOp::Neg => "-",
1163 }
1164 }
1165
1166 pub fn is_by_value(self) -> bool {
1168 matches!(self, Self::Neg | Self::Not)
1169 }
1170}
1171
1172#[derive(Clone, Encodable, Decodable, Debug)]
1176pub struct Stmt {
1177 pub id: NodeId,
1178 pub kind: StmtKind,
1179 pub span: Span,
1180}
1181
1182impl Stmt {
1183 pub fn has_trailing_semicolon(&self) -> bool {
1184 match &self.kind {
1185 StmtKind::Semi(_) => true,
1186 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1187 _ => false,
1188 }
1189 }
1190
1191 pub fn add_trailing_semicolon(mut self) -> Self {
1199 self.kind = match self.kind {
1200 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1201 StmtKind::MacCall(mut mac) => {
1202 mac.style = MacStmtStyle::Semicolon;
1203 StmtKind::MacCall(mac)
1204 }
1205 kind => kind,
1206 };
1207
1208 self
1209 }
1210
1211 pub fn is_item(&self) -> bool {
1212 matches!(self.kind, StmtKind::Item(_))
1213 }
1214
1215 pub fn is_expr(&self) -> bool {
1216 matches!(self.kind, StmtKind::Expr(_))
1217 }
1218}
1219
1220#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1222pub enum StmtKind {
1223 Let(Box<Local>),
1225 Item(Box<Item>),
1227 Expr(Box<Expr>),
1229 Semi(Box<Expr>),
1231 Empty,
1233 MacCall(Box<MacCallStmt>),
1235}
1236
1237#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1238pub struct MacCallStmt {
1239 pub mac: Box<MacCall>,
1240 pub style: MacStmtStyle,
1241 pub attrs: AttrVec,
1242 pub tokens: Option<LazyAttrTokenStream>,
1243}
1244
1245#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1246pub enum MacStmtStyle {
1247 Semicolon,
1250 Braces,
1252 NoBraces,
1256}
1257
1258#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1260pub struct Local {
1261 pub id: NodeId,
1262 pub super_: Option<Span>,
1263 pub pat: Box<Pat>,
1264 pub ty: Option<Box<Ty>>,
1265 pub kind: LocalKind,
1266 pub span: Span,
1267 pub colon_sp: Option<Span>,
1268 pub attrs: AttrVec,
1269 pub tokens: Option<LazyAttrTokenStream>,
1270}
1271
1272#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1273pub enum LocalKind {
1274 Decl,
1277 Init(Box<Expr>),
1280 InitElse(Box<Expr>, Box<Block>),
1283}
1284
1285impl LocalKind {
1286 pub fn init(&self) -> Option<&Expr> {
1287 match self {
1288 Self::Decl => None,
1289 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1290 }
1291 }
1292
1293 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1294 match self {
1295 Self::Decl => None,
1296 Self::Init(init) => Some((init, None)),
1297 Self::InitElse(init, els) => Some((init, Some(els))),
1298 }
1299 }
1300}
1301
1302#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1313pub struct Arm {
1314 pub attrs: AttrVec,
1315 pub pat: Box<Pat>,
1317 pub guard: Option<Box<Expr>>,
1319 pub body: Option<Box<Expr>>,
1321 pub span: Span,
1322 pub id: NodeId,
1323 pub is_placeholder: bool,
1324}
1325
1326#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1328pub struct ExprField {
1329 pub attrs: AttrVec,
1330 pub id: NodeId,
1331 pub span: Span,
1332 pub ident: Ident,
1333 pub expr: Box<Expr>,
1334 pub is_shorthand: bool,
1335 pub is_placeholder: bool,
1336}
1337
1338#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1339pub enum BlockCheckMode {
1340 Default,
1341 Unsafe(UnsafeSource),
1342}
1343
1344#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1345pub enum UnsafeSource {
1346 CompilerGenerated,
1347 UserProvided,
1348}
1349
1350#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1356pub struct AnonConst {
1357 pub id: NodeId,
1358 pub value: Box<Expr>,
1359}
1360
1361#[derive(Clone, Encodable, Decodable, Debug)]
1363pub struct Expr {
1364 pub id: NodeId,
1365 pub kind: ExprKind,
1366 pub span: Span,
1367 pub attrs: AttrVec,
1368 pub tokens: Option<LazyAttrTokenStream>,
1369}
1370
1371impl Expr {
1372 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1386 let this = self.maybe_unwrap_block();
1387 if allow_mgca_arg {
1388 matches!(this.kind, ExprKind::Path(..))
1389 } else {
1390 if let ExprKind::Path(None, path) = &this.kind
1391 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1392 {
1393 true
1394 } else {
1395 false
1396 }
1397 }
1398 }
1399
1400 pub fn maybe_unwrap_block(&self) -> &Expr {
1402 if let ExprKind::Block(block, None) = &self.kind
1403 && let [stmt] = block.stmts.as_slice()
1404 && let StmtKind::Expr(expr) = &stmt.kind
1405 {
1406 expr
1407 } else {
1408 self
1409 }
1410 }
1411
1412 pub fn optionally_braced_mac_call(
1418 &self,
1419 already_stripped_block: bool,
1420 ) -> Option<(bool, NodeId)> {
1421 match &self.kind {
1422 ExprKind::Block(block, None)
1423 if let [stmt] = &*block.stmts
1424 && !already_stripped_block =>
1425 {
1426 match &stmt.kind {
1427 StmtKind::MacCall(_) => Some((true, stmt.id)),
1428 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1429 Some((true, expr.id))
1430 }
1431 _ => None,
1432 }
1433 }
1434 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1435 _ => None,
1436 }
1437 }
1438
1439 pub fn to_bound(&self) -> Option<GenericBound> {
1440 match &self.kind {
1441 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1442 ThinVec::new(),
1443 path.clone(),
1444 TraitBoundModifiers::NONE,
1445 self.span,
1446 Parens::No,
1447 ))),
1448 _ => None,
1449 }
1450 }
1451
1452 pub fn peel_parens(&self) -> &Expr {
1453 let mut expr = self;
1454 while let ExprKind::Paren(inner) = &expr.kind {
1455 expr = inner;
1456 }
1457 expr
1458 }
1459
1460 pub fn peel_parens_and_refs(&self) -> &Expr {
1461 let mut expr = self;
1462 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1463 {
1464 expr = inner;
1465 }
1466 expr
1467 }
1468
1469 pub fn to_ty(&self) -> Option<Box<Ty>> {
1471 let kind = match &self.kind {
1472 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1474 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1475
1476 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1477
1478 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1479 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1480 }
1481
1482 ExprKind::Repeat(expr, expr_len) => {
1483 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1484 }
1485
1486 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1487 expr.to_ty().map(TyKind::Slice)?
1488 }
1489
1490 ExprKind::Tup(exprs) => {
1491 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1492 TyKind::Tup(tys)
1493 }
1494
1495 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1499 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1500 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1501 } else {
1502 return None;
1503 }
1504 }
1505
1506 ExprKind::Underscore => TyKind::Infer,
1507
1508 _ => return None,
1510 };
1511
1512 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1513 }
1514
1515 pub fn precedence(&self) -> ExprPrecedence {
1516 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1517 for attr in attrs {
1518 if let AttrStyle::Outer = attr.style {
1519 return ExprPrecedence::Prefix;
1520 }
1521 }
1522 ExprPrecedence::Unambiguous
1523 }
1524
1525 match &self.kind {
1526 ExprKind::Closure(closure) => {
1527 match closure.fn_decl.output {
1528 FnRetTy::Default(_) => ExprPrecedence::Jump,
1529 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1530 }
1531 }
1532
1533 ExprKind::Break(_ , value)
1534 | ExprKind::Ret(value)
1535 | ExprKind::Yield(YieldKind::Prefix(value))
1536 | ExprKind::Yeet(value) => match value {
1537 Some(_) => ExprPrecedence::Jump,
1538 None => prefix_attrs_precedence(&self.attrs),
1539 },
1540
1541 ExprKind::Become(_) => ExprPrecedence::Jump,
1542
1543 ExprKind::Range(..) => ExprPrecedence::Range,
1548
1549 ExprKind::Binary(op, ..) => op.node.precedence(),
1551 ExprKind::Cast(..) => ExprPrecedence::Cast,
1552
1553 ExprKind::Assign(..) |
1554 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1555
1556 ExprKind::AddrOf(..)
1558 | ExprKind::Let(..)
1563 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1564
1565 ExprKind::Array(_)
1567 | ExprKind::Await(..)
1568 | ExprKind::Use(..)
1569 | ExprKind::Block(..)
1570 | ExprKind::Call(..)
1571 | ExprKind::ConstBlock(_)
1572 | ExprKind::Continue(..)
1573 | ExprKind::Field(..)
1574 | ExprKind::ForLoop { .. }
1575 | ExprKind::FormatArgs(..)
1576 | ExprKind::Gen(..)
1577 | ExprKind::If(..)
1578 | ExprKind::IncludedBytes(..)
1579 | ExprKind::Index(..)
1580 | ExprKind::InlineAsm(..)
1581 | ExprKind::Lit(_)
1582 | ExprKind::Loop(..)
1583 | ExprKind::MacCall(..)
1584 | ExprKind::Match(..)
1585 | ExprKind::MethodCall(..)
1586 | ExprKind::OffsetOf(..)
1587 | ExprKind::Paren(..)
1588 | ExprKind::Path(..)
1589 | ExprKind::Repeat(..)
1590 | ExprKind::Struct(..)
1591 | ExprKind::Try(..)
1592 | ExprKind::TryBlock(..)
1593 | ExprKind::Tup(_)
1594 | ExprKind::Type(..)
1595 | ExprKind::Underscore
1596 | ExprKind::UnsafeBinderCast(..)
1597 | ExprKind::While(..)
1598 | ExprKind::Yield(YieldKind::Postfix(..))
1599 | ExprKind::Err(_)
1600 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1601 }
1602 }
1603
1604 pub fn is_approximately_pattern(&self) -> bool {
1606 matches!(
1607 &self.peel_parens().kind,
1608 ExprKind::Array(_)
1609 | ExprKind::Call(_, _)
1610 | ExprKind::Tup(_)
1611 | ExprKind::Lit(_)
1612 | ExprKind::Range(_, _, _)
1613 | ExprKind::Underscore
1614 | ExprKind::Path(_, _)
1615 | ExprKind::Struct(_)
1616 )
1617 }
1618
1619 pub fn dummy() -> Expr {
1623 Expr {
1624 id: DUMMY_NODE_ID,
1625 kind: ExprKind::Dummy,
1626 span: DUMMY_SP,
1627 attrs: ThinVec::new(),
1628 tokens: None,
1629 }
1630 }
1631}
1632
1633impl From<Box<Expr>> for Expr {
1634 fn from(value: Box<Expr>) -> Self {
1635 *value
1636 }
1637}
1638
1639#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1640pub struct Closure {
1641 pub binder: ClosureBinder,
1642 pub capture_clause: CaptureBy,
1643 pub constness: Const,
1644 pub coroutine_kind: Option<CoroutineKind>,
1645 pub movability: Movability,
1646 pub fn_decl: Box<FnDecl>,
1647 pub body: Box<Expr>,
1648 pub fn_decl_span: Span,
1650 pub fn_arg_span: Span,
1652}
1653
1654#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1656pub enum RangeLimits {
1657 HalfOpen,
1659 Closed,
1661}
1662
1663impl RangeLimits {
1664 pub fn as_str(&self) -> &'static str {
1665 match self {
1666 RangeLimits::HalfOpen => "..",
1667 RangeLimits::Closed => "..=",
1668 }
1669 }
1670}
1671
1672#[derive(Clone, Encodable, Decodable, Debug)]
1674pub struct MethodCall {
1675 pub seg: PathSegment,
1677 pub receiver: Box<Expr>,
1679 pub args: ThinVec<Box<Expr>>,
1681 pub span: Span,
1684}
1685
1686#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1687pub enum StructRest {
1688 Base(Box<Expr>),
1690 Rest(Span),
1692 None,
1694}
1695
1696#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1697pub struct StructExpr {
1698 pub qself: Option<Box<QSelf>>,
1699 pub path: Path,
1700 pub fields: ThinVec<ExprField>,
1701 pub rest: StructRest,
1702}
1703
1704#[derive(Clone, Encodable, Decodable, Debug)]
1706pub enum ExprKind {
1707 Array(ThinVec<Box<Expr>>),
1709 ConstBlock(AnonConst),
1711 Call(Box<Expr>, ThinVec<Box<Expr>>),
1718 MethodCall(Box<MethodCall>),
1720 Tup(ThinVec<Box<Expr>>),
1722 Binary(BinOp, Box<Expr>, Box<Expr>),
1724 Unary(UnOp, Box<Expr>),
1726 Lit(token::Lit),
1728 Cast(Box<Expr>, Box<Ty>),
1730 Type(Box<Expr>, Box<Ty>),
1735 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1740 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1747 While(Box<Expr>, Box<Block>, Option<Label>),
1751 ForLoop {
1757 pat: Box<Pat>,
1758 iter: Box<Expr>,
1759 body: Box<Block>,
1760 label: Option<Label>,
1761 kind: ForLoopKind,
1762 },
1763 Loop(Box<Block>, Option<Label>, Span),
1767 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1769 Closure(Box<Closure>),
1771 Block(Box<Block>, Option<Label>),
1773 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1779 Await(Box<Expr>, Span),
1781 Use(Box<Expr>, Span),
1783
1784 TryBlock(Box<Block>),
1786
1787 Assign(Box<Expr>, Box<Expr>, Span),
1790 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1794 Field(Box<Expr>, Ident),
1796 Index(Box<Expr>, Box<Expr>, Span),
1799 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1801 Underscore,
1803
1804 Path(Option<Box<QSelf>>, Path),
1809
1810 AddrOf(BorrowKind, Mutability, Box<Expr>),
1812 Break(Option<Label>, Option<Box<Expr>>),
1814 Continue(Option<Label>),
1816 Ret(Option<Box<Expr>>),
1818
1819 InlineAsm(Box<InlineAsm>),
1821
1822 OffsetOf(Box<Ty>, Vec<Ident>),
1827
1828 MacCall(Box<MacCall>),
1830
1831 Struct(Box<StructExpr>),
1835
1836 Repeat(Box<Expr>, AnonConst),
1841
1842 Paren(Box<Expr>),
1844
1845 Try(Box<Expr>),
1847
1848 Yield(YieldKind),
1850
1851 Yeet(Option<Box<Expr>>),
1854
1855 Become(Box<Expr>),
1859
1860 IncludedBytes(ByteSymbol),
1872
1873 FormatArgs(Box<FormatArgs>),
1875
1876 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1877
1878 Err(ErrorGuaranteed),
1880
1881 Dummy,
1883}
1884
1885#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1887pub enum ForLoopKind {
1888 For,
1889 ForAwait,
1890}
1891
1892#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1894pub enum GenBlockKind {
1895 Async,
1896 Gen,
1897 AsyncGen,
1898}
1899
1900impl fmt::Display for GenBlockKind {
1901 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1902 self.modifier().fmt(f)
1903 }
1904}
1905
1906impl GenBlockKind {
1907 pub fn modifier(&self) -> &'static str {
1908 match self {
1909 GenBlockKind::Async => "async",
1910 GenBlockKind::Gen => "gen",
1911 GenBlockKind::AsyncGen => "async gen",
1912 }
1913 }
1914}
1915
1916#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1918#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1919pub enum UnsafeBinderCastKind {
1920 Wrap,
1922 Unwrap,
1924}
1925
1926#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1941pub struct QSelf {
1942 pub ty: Box<Ty>,
1943
1944 pub path_span: Span,
1948 pub position: usize,
1949}
1950
1951#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1953pub enum CaptureBy {
1954 Value {
1956 move_kw: Span,
1958 },
1959 Ref,
1961 Use {
1967 use_kw: Span,
1969 },
1970}
1971
1972#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1974pub enum ClosureBinder {
1975 NotPresent,
1977 For {
1979 span: Span,
1986
1987 generic_params: ThinVec<GenericParam>,
1994 },
1995}
1996
1997#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2000pub struct MacCall {
2001 pub path: Path,
2002 pub args: Box<DelimArgs>,
2003}
2004
2005impl MacCall {
2006 pub fn span(&self) -> Span {
2007 self.path.span.to(self.args.dspan.entire())
2008 }
2009}
2010
2011#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2013pub enum AttrArgs {
2014 Empty,
2016 Delimited(DelimArgs),
2018 Eq {
2020 eq_span: Span,
2022 expr: Box<Expr>,
2023 },
2024}
2025
2026impl AttrArgs {
2027 pub fn span(&self) -> Option<Span> {
2028 match self {
2029 AttrArgs::Empty => None,
2030 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2031 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2032 }
2033 }
2034
2035 pub fn inner_tokens(&self) -> TokenStream {
2038 match self {
2039 AttrArgs::Empty => TokenStream::default(),
2040 AttrArgs::Delimited(args) => args.tokens.clone(),
2041 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2042 }
2043 }
2044}
2045
2046#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2048pub struct DelimArgs {
2049 pub dspan: DelimSpan,
2050 pub delim: Delimiter, pub tokens: TokenStream,
2052}
2053
2054impl DelimArgs {
2055 pub fn need_semicolon(&self) -> bool {
2058 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2059 }
2060}
2061
2062#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2064pub struct MacroDef {
2065 pub body: Box<DelimArgs>,
2066 pub macro_rules: bool,
2068}
2069
2070#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2071#[derive(HashStable_Generic, Walkable)]
2072pub enum StrStyle {
2073 Cooked,
2075 Raw(u8),
2079}
2080
2081#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2083pub enum MatchKind {
2084 Prefix,
2086 Postfix,
2088}
2089
2090#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2092pub enum YieldKind {
2093 Prefix(Option<Box<Expr>>),
2095 Postfix(Box<Expr>),
2097}
2098
2099impl YieldKind {
2100 pub const fn expr(&self) -> Option<&Box<Expr>> {
2104 match self {
2105 YieldKind::Prefix(expr) => expr.as_ref(),
2106 YieldKind::Postfix(expr) => Some(expr),
2107 }
2108 }
2109
2110 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2112 match self {
2113 YieldKind::Prefix(expr) => expr.as_mut(),
2114 YieldKind::Postfix(expr) => Some(expr),
2115 }
2116 }
2117
2118 pub const fn same_kind(&self, other: &Self) -> bool {
2120 match (self, other) {
2121 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2122 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2123 _ => false,
2124 }
2125 }
2126}
2127
2128#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2130pub struct MetaItemLit {
2131 pub symbol: Symbol,
2133 pub suffix: Option<Symbol>,
2135 pub kind: LitKind,
2138 pub span: Span,
2139}
2140
2141#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2143pub struct StrLit {
2144 pub symbol: Symbol,
2146 pub suffix: Option<Symbol>,
2148 pub symbol_unescaped: Symbol,
2150 pub style: StrStyle,
2151 pub span: Span,
2152}
2153
2154impl StrLit {
2155 pub fn as_token_lit(&self) -> token::Lit {
2156 let token_kind = match self.style {
2157 StrStyle::Cooked => token::Str,
2158 StrStyle::Raw(n) => token::StrRaw(n),
2159 };
2160 token::Lit::new(token_kind, self.symbol, self.suffix)
2161 }
2162}
2163
2164#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2166#[derive(HashStable_Generic)]
2167pub enum LitIntType {
2168 Signed(IntTy),
2170 Unsigned(UintTy),
2172 Unsuffixed,
2174}
2175
2176#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2178#[derive(HashStable_Generic)]
2179pub enum LitFloatType {
2180 Suffixed(FloatTy),
2182 Unsuffixed,
2184}
2185
2186#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2193pub enum LitKind {
2194 Str(Symbol, StrStyle),
2197 ByteStr(ByteSymbol, StrStyle),
2200 CStr(ByteSymbol, StrStyle),
2204 Byte(u8),
2206 Char(char),
2208 Int(Pu128, LitIntType),
2210 Float(Symbol, LitFloatType),
2214 Bool(bool),
2216 Err(ErrorGuaranteed),
2218}
2219
2220impl LitKind {
2221 pub fn str(&self) -> Option<Symbol> {
2222 match *self {
2223 LitKind::Str(s, _) => Some(s),
2224 _ => None,
2225 }
2226 }
2227
2228 pub fn is_str(&self) -> bool {
2230 matches!(self, LitKind::Str(..))
2231 }
2232
2233 pub fn is_bytestr(&self) -> bool {
2235 matches!(self, LitKind::ByteStr(..))
2236 }
2237
2238 pub fn is_numeric(&self) -> bool {
2240 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2241 }
2242
2243 pub fn is_unsuffixed(&self) -> bool {
2246 !self.is_suffixed()
2247 }
2248
2249 pub fn is_suffixed(&self) -> bool {
2251 match *self {
2252 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2254 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2255 LitKind::Str(..)
2257 | LitKind::ByteStr(..)
2258 | LitKind::CStr(..)
2259 | LitKind::Byte(..)
2260 | LitKind::Char(..)
2261 | LitKind::Int(_, LitIntType::Unsuffixed)
2262 | LitKind::Float(_, LitFloatType::Unsuffixed)
2263 | LitKind::Bool(..)
2264 | LitKind::Err(_) => false,
2265 }
2266 }
2267}
2268
2269#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2272pub struct MutTy {
2273 pub ty: Box<Ty>,
2274 pub mutbl: Mutability,
2275}
2276
2277#[derive(Clone, Encodable, Decodable, Debug)]
2280pub struct FnSig {
2281 pub header: FnHeader,
2282 pub decl: Box<FnDecl>,
2283 pub span: Span,
2284}
2285
2286impl FnSig {
2287 pub fn header_span(&self) -> Span {
2289 match self.header.ext {
2290 Extern::Implicit(span) | Extern::Explicit(_, span) => {
2291 return self.span.with_hi(span.hi());
2292 }
2293 Extern::None => {}
2294 }
2295
2296 match self.header.safety {
2297 Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2298 Safety::Default => {}
2299 };
2300
2301 if let Some(coroutine_kind) = self.header.coroutine_kind {
2302 return self.span.with_hi(coroutine_kind.span().hi());
2303 }
2304
2305 if let Const::Yes(span) = self.header.constness {
2306 return self.span.with_hi(span.hi());
2307 }
2308
2309 self.span.shrink_to_lo()
2310 }
2311
2312 pub fn safety_span(&self) -> Span {
2314 match self.header.safety {
2315 Safety::Unsafe(span) | Safety::Safe(span) => span,
2316 Safety::Default => {
2317 if let Some(extern_span) = self.header.ext.span() {
2319 return extern_span.shrink_to_lo();
2320 }
2321
2322 self.header_span().shrink_to_hi()
2324 }
2325 }
2326 }
2327
2328 pub fn extern_span(&self) -> Span {
2330 self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2331 }
2332}
2333
2334#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2345pub struct AssocItemConstraint {
2346 pub id: NodeId,
2347 pub ident: Ident,
2348 pub gen_args: Option<GenericArgs>,
2349 pub kind: AssocItemConstraintKind,
2350 pub span: Span,
2351}
2352
2353#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2354pub enum Term {
2355 Ty(Box<Ty>),
2356 Const(AnonConst),
2357}
2358
2359impl From<Box<Ty>> for Term {
2360 fn from(v: Box<Ty>) -> Self {
2361 Term::Ty(v)
2362 }
2363}
2364
2365impl From<AnonConst> for Term {
2366 fn from(v: AnonConst) -> Self {
2367 Term::Const(v)
2368 }
2369}
2370
2371#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2373pub enum AssocItemConstraintKind {
2374 Equality { term: Term },
2381 Bound {
2383 #[visitable(extra = BoundKind::Bound)]
2384 bounds: GenericBounds,
2385 },
2386}
2387
2388#[derive(Encodable, Decodable, Debug, Walkable)]
2389pub struct Ty {
2390 pub id: NodeId,
2391 pub kind: TyKind,
2392 pub span: Span,
2393 pub tokens: Option<LazyAttrTokenStream>,
2394}
2395
2396impl Clone for Ty {
2397 fn clone(&self) -> Self {
2398 ensure_sufficient_stack(|| Self {
2399 id: self.id,
2400 kind: self.kind.clone(),
2401 span: self.span,
2402 tokens: self.tokens.clone(),
2403 })
2404 }
2405}
2406
2407impl From<Box<Ty>> for Ty {
2408 fn from(value: Box<Ty>) -> Self {
2409 *value
2410 }
2411}
2412
2413impl Ty {
2414 pub fn peel_refs(&self) -> &Self {
2415 let mut final_ty = self;
2416 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2417 {
2418 final_ty = ty;
2419 }
2420 final_ty
2421 }
2422
2423 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2424 match &self.kind {
2425 TyKind::Infer => true,
2426 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2427 _ => false,
2428 }
2429 }
2430}
2431
2432#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2433pub struct FnPtrTy {
2434 pub safety: Safety,
2435 pub ext: Extern,
2436 pub generic_params: ThinVec<GenericParam>,
2437 pub decl: Box<FnDecl>,
2438 pub decl_span: Span,
2441}
2442
2443#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2444pub struct UnsafeBinderTy {
2445 pub generic_params: ThinVec<GenericParam>,
2446 pub inner_ty: Box<Ty>,
2447}
2448
2449#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2453pub enum TyKind {
2454 Slice(Box<Ty>),
2456 Array(Box<Ty>, AnonConst),
2458 Ptr(MutTy),
2460 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2462 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2466 FnPtr(Box<FnPtrTy>),
2468 UnsafeBinder(Box<UnsafeBinderTy>),
2470 Never,
2472 Tup(ThinVec<Box<Ty>>),
2474 Path(Option<Box<QSelf>>, Path),
2479 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2482 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2489 Paren(Box<Ty>),
2491 Typeof(AnonConst),
2493 Infer,
2496 ImplicitSelf,
2498 MacCall(Box<MacCall>),
2500 CVarArgs,
2502 Pat(Box<Ty>, Box<TyPat>),
2505 Dummy,
2507 Err(ErrorGuaranteed),
2509}
2510
2511impl TyKind {
2512 pub fn is_implicit_self(&self) -> bool {
2513 matches!(self, TyKind::ImplicitSelf)
2514 }
2515
2516 pub fn is_unit(&self) -> bool {
2517 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2518 }
2519
2520 pub fn is_simple_path(&self) -> Option<Symbol> {
2521 if let TyKind::Path(None, Path { segments, .. }) = &self
2522 && let [segment] = &segments[..]
2523 && segment.args.is_none()
2524 {
2525 Some(segment.ident.name)
2526 } else {
2527 None
2528 }
2529 }
2530
2531 pub fn maybe_scalar(&self) -> bool {
2539 let Some(ty_sym) = self.is_simple_path() else {
2540 return self.is_unit();
2542 };
2543 matches!(
2544 ty_sym,
2545 sym::i8
2546 | sym::i16
2547 | sym::i32
2548 | sym::i64
2549 | sym::i128
2550 | sym::u8
2551 | sym::u16
2552 | sym::u32
2553 | sym::u64
2554 | sym::u128
2555 | sym::f16
2556 | sym::f32
2557 | sym::f64
2558 | sym::f128
2559 | sym::char
2560 | sym::bool
2561 )
2562 }
2563}
2564
2565#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2567pub struct TyPat {
2568 pub id: NodeId,
2569 pub kind: TyPatKind,
2570 pub span: Span,
2571 pub tokens: Option<LazyAttrTokenStream>,
2572}
2573
2574#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2578pub enum TyPatKind {
2579 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2581
2582 NotNull,
2584
2585 Or(ThinVec<TyPat>),
2586
2587 Err(ErrorGuaranteed),
2589}
2590
2591#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2593#[repr(u8)]
2594pub enum TraitObjectSyntax {
2595 Dyn = 0,
2597 None = 1,
2598}
2599
2600unsafe impl Tag for TraitObjectSyntax {
2604 const BITS: u32 = 2;
2605
2606 fn into_usize(self) -> usize {
2607 self as u8 as usize
2608 }
2609
2610 unsafe fn from_usize(tag: usize) -> Self {
2611 match tag {
2612 0 => TraitObjectSyntax::Dyn,
2613 1 => TraitObjectSyntax::None,
2614 _ => unreachable!(),
2615 }
2616 }
2617}
2618
2619#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2620pub enum PreciseCapturingArg {
2621 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2623 Arg(Path, NodeId),
2625}
2626
2627#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2631pub enum InlineAsmRegOrRegClass {
2632 Reg(Symbol),
2633 RegClass(Symbol),
2634}
2635
2636#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2637pub struct InlineAsmOptions(u16);
2638bitflags::bitflags! {
2639 impl InlineAsmOptions: u16 {
2640 const PURE = 1 << 0;
2641 const NOMEM = 1 << 1;
2642 const READONLY = 1 << 2;
2643 const PRESERVES_FLAGS = 1 << 3;
2644 const NORETURN = 1 << 4;
2645 const NOSTACK = 1 << 5;
2646 const ATT_SYNTAX = 1 << 6;
2647 const RAW = 1 << 7;
2648 const MAY_UNWIND = 1 << 8;
2649 }
2650}
2651
2652impl InlineAsmOptions {
2653 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2654
2655 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2656 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2657
2658 pub fn human_readable_names(&self) -> Vec<&'static str> {
2659 let mut options = vec![];
2660
2661 if self.contains(InlineAsmOptions::PURE) {
2662 options.push("pure");
2663 }
2664 if self.contains(InlineAsmOptions::NOMEM) {
2665 options.push("nomem");
2666 }
2667 if self.contains(InlineAsmOptions::READONLY) {
2668 options.push("readonly");
2669 }
2670 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2671 options.push("preserves_flags");
2672 }
2673 if self.contains(InlineAsmOptions::NORETURN) {
2674 options.push("noreturn");
2675 }
2676 if self.contains(InlineAsmOptions::NOSTACK) {
2677 options.push("nostack");
2678 }
2679 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2680 options.push("att_syntax");
2681 }
2682 if self.contains(InlineAsmOptions::RAW) {
2683 options.push("raw");
2684 }
2685 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2686 options.push("may_unwind");
2687 }
2688
2689 options
2690 }
2691}
2692
2693impl std::fmt::Debug for InlineAsmOptions {
2694 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2695 bitflags::parser::to_writer(self, f)
2696 }
2697}
2698
2699#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2700pub enum InlineAsmTemplatePiece {
2701 String(Cow<'static, str>),
2702 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2703}
2704
2705impl fmt::Display for InlineAsmTemplatePiece {
2706 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2707 match self {
2708 Self::String(s) => {
2709 for c in s.chars() {
2710 match c {
2711 '{' => f.write_str("{{")?,
2712 '}' => f.write_str("}}")?,
2713 _ => c.fmt(f)?,
2714 }
2715 }
2716 Ok(())
2717 }
2718 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2719 write!(f, "{{{operand_idx}:{modifier}}}")
2720 }
2721 Self::Placeholder { operand_idx, modifier: None, .. } => {
2722 write!(f, "{{{operand_idx}}}")
2723 }
2724 }
2725 }
2726}
2727
2728impl InlineAsmTemplatePiece {
2729 pub fn to_string(s: &[Self]) -> String {
2731 use fmt::Write;
2732 let mut out = String::new();
2733 for p in s.iter() {
2734 let _ = write!(out, "{p}");
2735 }
2736 out
2737 }
2738}
2739
2740#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2748pub struct InlineAsmSym {
2749 pub id: NodeId,
2750 pub qself: Option<Box<QSelf>>,
2751 pub path: Path,
2752}
2753
2754#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2758pub enum InlineAsmOperand {
2759 In {
2760 reg: InlineAsmRegOrRegClass,
2761 expr: Box<Expr>,
2762 },
2763 Out {
2764 reg: InlineAsmRegOrRegClass,
2765 late: bool,
2766 expr: Option<Box<Expr>>,
2767 },
2768 InOut {
2769 reg: InlineAsmRegOrRegClass,
2770 late: bool,
2771 expr: Box<Expr>,
2772 },
2773 SplitInOut {
2774 reg: InlineAsmRegOrRegClass,
2775 late: bool,
2776 in_expr: Box<Expr>,
2777 out_expr: Option<Box<Expr>>,
2778 },
2779 Const {
2780 anon_const: AnonConst,
2781 },
2782 Sym {
2783 sym: InlineAsmSym,
2784 },
2785 Label {
2786 block: Box<Block>,
2787 },
2788}
2789
2790impl InlineAsmOperand {
2791 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2792 match self {
2793 Self::In { reg, .. }
2794 | Self::Out { reg, .. }
2795 | Self::InOut { reg, .. }
2796 | Self::SplitInOut { reg, .. } => Some(reg),
2797 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2798 }
2799 }
2800}
2801
2802#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2803pub enum AsmMacro {
2804 Asm,
2806 GlobalAsm,
2808 NakedAsm,
2810}
2811
2812impl AsmMacro {
2813 pub const fn macro_name(self) -> &'static str {
2814 match self {
2815 AsmMacro::Asm => "asm",
2816 AsmMacro::GlobalAsm => "global_asm",
2817 AsmMacro::NakedAsm => "naked_asm",
2818 }
2819 }
2820
2821 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2822 match self {
2823 AsmMacro::Asm => true,
2824 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2825 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2826 }
2827 }
2828
2829 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2830 match self {
2831 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2832 AsmMacro::GlobalAsm => true,
2833 AsmMacro::NakedAsm => true,
2834 }
2835 }
2836}
2837
2838#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2842pub struct InlineAsm {
2843 pub asm_macro: AsmMacro,
2844 pub template: Vec<InlineAsmTemplatePiece>,
2845 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2846 pub operands: Vec<(InlineAsmOperand, Span)>,
2847 pub clobber_abis: Vec<(Symbol, Span)>,
2848 #[visitable(ignore)]
2849 pub options: InlineAsmOptions,
2850 pub line_spans: Vec<Span>,
2851}
2852
2853#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2857pub struct Param {
2858 pub attrs: AttrVec,
2859 pub ty: Box<Ty>,
2860 pub pat: Box<Pat>,
2861 pub id: NodeId,
2862 pub span: Span,
2863 pub is_placeholder: bool,
2864}
2865
2866#[derive(Clone, Encodable, Decodable, Debug)]
2870pub enum SelfKind {
2871 Value(Mutability),
2873 Region(Option<Lifetime>, Mutability),
2875 Pinned(Option<Lifetime>, Mutability),
2877 Explicit(Box<Ty>, Mutability),
2879}
2880
2881impl SelfKind {
2882 pub fn to_ref_suggestion(&self) -> String {
2883 match self {
2884 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2885 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2886 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2887 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2888 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2889 unreachable!("if we had an explicit self, we wouldn't be here")
2890 }
2891 }
2892 }
2893}
2894
2895pub type ExplicitSelf = Spanned<SelfKind>;
2896
2897impl Param {
2898 pub fn to_self(&self) -> Option<ExplicitSelf> {
2900 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2901 if ident.name == kw::SelfLower {
2902 return match self.ty.kind {
2903 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2904 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2905 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2906 }
2907 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2908 if ty.kind.is_implicit_self() =>
2909 {
2910 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2911 }
2912 _ => Some(respan(
2913 self.pat.span.to(self.ty.span),
2914 SelfKind::Explicit(self.ty.clone(), mutbl),
2915 )),
2916 };
2917 }
2918 }
2919 None
2920 }
2921
2922 pub fn is_self(&self) -> bool {
2924 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2925 ident.name == kw::SelfLower
2926 } else {
2927 false
2928 }
2929 }
2930
2931 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2933 let span = eself.span.to(eself_ident.span);
2934 let infer_ty = Box::new(Ty {
2935 id: DUMMY_NODE_ID,
2936 kind: TyKind::ImplicitSelf,
2937 span: eself_ident.span,
2938 tokens: None,
2939 });
2940 let (mutbl, ty) = match eself.node {
2941 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2942 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2943 SelfKind::Region(lt, mutbl) => (
2944 Mutability::Not,
2945 Box::new(Ty {
2946 id: DUMMY_NODE_ID,
2947 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2948 span,
2949 tokens: None,
2950 }),
2951 ),
2952 SelfKind::Pinned(lt, mutbl) => (
2953 mutbl,
2954 Box::new(Ty {
2955 id: DUMMY_NODE_ID,
2956 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2957 span,
2958 tokens: None,
2959 }),
2960 ),
2961 };
2962 Param {
2963 attrs,
2964 pat: Box::new(Pat {
2965 id: DUMMY_NODE_ID,
2966 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2967 span,
2968 tokens: None,
2969 }),
2970 span,
2971 ty,
2972 id: DUMMY_NODE_ID,
2973 is_placeholder: false,
2974 }
2975 }
2976}
2977
2978#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2985pub struct FnDecl {
2986 pub inputs: ThinVec<Param>,
2987 pub output: FnRetTy,
2988}
2989
2990impl FnDecl {
2991 pub fn has_self(&self) -> bool {
2992 self.inputs.get(0).is_some_and(Param::is_self)
2993 }
2994 pub fn c_variadic(&self) -> bool {
2995 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2996 }
2997}
2998
2999#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3001pub enum IsAuto {
3002 Yes,
3003 No,
3004}
3005
3006#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3008#[derive(HashStable_Generic, Walkable)]
3009pub enum Safety {
3010 Unsafe(Span),
3012 Safe(Span),
3014 Default,
3017}
3018
3019#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3025pub enum CoroutineKind {
3026 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3028 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3030 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3032}
3033
3034impl CoroutineKind {
3035 pub fn span(self) -> Span {
3036 match self {
3037 CoroutineKind::Async { span, .. } => span,
3038 CoroutineKind::Gen { span, .. } => span,
3039 CoroutineKind::AsyncGen { span, .. } => span,
3040 }
3041 }
3042
3043 pub fn as_str(self) -> &'static str {
3044 match self {
3045 CoroutineKind::Async { .. } => "async",
3046 CoroutineKind::Gen { .. } => "gen",
3047 CoroutineKind::AsyncGen { .. } => "async gen",
3048 }
3049 }
3050
3051 pub fn closure_id(self) -> NodeId {
3052 match self {
3053 CoroutineKind::Async { closure_id, .. }
3054 | CoroutineKind::Gen { closure_id, .. }
3055 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3056 }
3057 }
3058
3059 pub fn return_id(self) -> (NodeId, Span) {
3062 match self {
3063 CoroutineKind::Async { return_impl_trait_id, span, .. }
3064 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3065 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3066 (return_impl_trait_id, span)
3067 }
3068 }
3069 }
3070}
3071
3072#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3073#[derive(HashStable_Generic, Walkable)]
3074pub enum Const {
3075 Yes(Span),
3076 No,
3077}
3078
3079#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3082pub enum Defaultness {
3083 Default(Span),
3084 Final,
3085}
3086
3087#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3088pub enum ImplPolarity {
3089 Positive,
3091 Negative(Span),
3093}
3094
3095impl fmt::Debug for ImplPolarity {
3096 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3097 match *self {
3098 ImplPolarity::Positive => "positive".fmt(f),
3099 ImplPolarity::Negative(_) => "negative".fmt(f),
3100 }
3101 }
3102}
3103
3104#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3106#[derive(HashStable_Generic, Walkable)]
3107pub enum BoundPolarity {
3108 Positive,
3110 Negative(Span),
3112 Maybe(Span),
3114}
3115
3116impl BoundPolarity {
3117 pub fn as_str(self) -> &'static str {
3118 match self {
3119 Self::Positive => "",
3120 Self::Negative(_) => "!",
3121 Self::Maybe(_) => "?",
3122 }
3123 }
3124}
3125
3126#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3128#[derive(HashStable_Generic, Walkable)]
3129pub enum BoundConstness {
3130 Never,
3132 Always(Span),
3134 Maybe(Span),
3136}
3137
3138impl BoundConstness {
3139 pub fn as_str(self) -> &'static str {
3140 match self {
3141 Self::Never => "",
3142 Self::Always(_) => "const",
3143 Self::Maybe(_) => "[const]",
3144 }
3145 }
3146}
3147
3148#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3150#[derive(HashStable_Generic, Walkable)]
3151pub enum BoundAsyncness {
3152 Normal,
3154 Async(Span),
3156}
3157
3158impl BoundAsyncness {
3159 pub fn as_str(self) -> &'static str {
3160 match self {
3161 Self::Normal => "",
3162 Self::Async(_) => "async",
3163 }
3164 }
3165}
3166
3167#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3168pub enum FnRetTy {
3169 Default(Span),
3174 Ty(Box<Ty>),
3176}
3177
3178impl FnRetTy {
3179 pub fn span(&self) -> Span {
3180 match self {
3181 &FnRetTy::Default(span) => span,
3182 FnRetTy::Ty(ty) => ty.span,
3183 }
3184 }
3185}
3186
3187#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3188pub enum Inline {
3189 Yes,
3190 No { had_parse_error: Result<(), ErrorGuaranteed> },
3191}
3192
3193#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3195pub enum ModKind {
3196 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3201 Unloaded,
3203}
3204
3205#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3206pub struct ModSpans {
3207 pub inner_span: Span,
3210 pub inject_use_span: Span,
3211}
3212
3213#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3217pub struct ForeignMod {
3218 pub extern_span: Span,
3220 pub safety: Safety,
3223 pub abi: Option<StrLit>,
3224 pub items: ThinVec<Box<ForeignItem>>,
3225}
3226
3227#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3228pub struct EnumDef {
3229 pub variants: ThinVec<Variant>,
3230}
3231
3232#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3234pub struct Variant {
3235 pub attrs: AttrVec,
3237 pub id: NodeId,
3239 pub span: Span,
3241 pub vis: Visibility,
3243 pub ident: Ident,
3245
3246 pub data: VariantData,
3248 pub disr_expr: Option<AnonConst>,
3250 pub is_placeholder: bool,
3252}
3253
3254#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3256pub enum UseTreeKind {
3257 Simple(Option<Ident>),
3259 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3268 Glob,
3270}
3271
3272#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3275pub struct UseTree {
3276 pub prefix: Path,
3277 pub kind: UseTreeKind,
3278 pub span: Span,
3279}
3280
3281impl UseTree {
3282 pub fn ident(&self) -> Ident {
3283 match self.kind {
3284 UseTreeKind::Simple(Some(rename)) => rename,
3285 UseTreeKind::Simple(None) => {
3286 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3287 }
3288 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3289 }
3290 }
3291}
3292
3293#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3297pub enum AttrStyle {
3298 Outer,
3299 Inner,
3300}
3301
3302pub type AttrVec = ThinVec<Attribute>;
3304
3305#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3307pub struct Attribute {
3308 pub kind: AttrKind,
3309 pub id: AttrId,
3310 pub style: AttrStyle,
3313 pub span: Span,
3314}
3315
3316#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3317pub enum AttrKind {
3318 Normal(Box<NormalAttr>),
3320
3321 DocComment(CommentKind, Symbol),
3325}
3326
3327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3328pub struct NormalAttr {
3329 pub item: AttrItem,
3330 pub tokens: Option<LazyAttrTokenStream>,
3332}
3333
3334impl NormalAttr {
3335 pub fn from_ident(ident: Ident) -> Self {
3336 Self {
3337 item: AttrItem {
3338 unsafety: Safety::Default,
3339 path: Path::from_ident(ident),
3340 args: AttrArgs::Empty,
3341 tokens: None,
3342 },
3343 tokens: None,
3344 }
3345 }
3346}
3347
3348#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3349pub struct AttrItem {
3350 pub unsafety: Safety,
3351 pub path: Path,
3352 pub args: AttrArgs,
3353 pub tokens: Option<LazyAttrTokenStream>,
3355}
3356
3357impl AttrItem {
3358 pub fn is_valid_for_outer_style(&self) -> bool {
3359 self.path == sym::cfg_attr
3360 || self.path == sym::cfg
3361 || self.path == sym::forbid
3362 || self.path == sym::warn
3363 || self.path == sym::allow
3364 || self.path == sym::deny
3365 }
3366}
3367
3368#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3375pub struct TraitRef {
3376 pub path: Path,
3377 pub ref_id: NodeId,
3378}
3379
3380#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3382pub enum Parens {
3383 Yes,
3384 No,
3385}
3386
3387#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3388pub struct PolyTraitRef {
3389 pub bound_generic_params: ThinVec<GenericParam>,
3391
3392 pub modifiers: TraitBoundModifiers,
3394
3395 pub trait_ref: TraitRef,
3397
3398 pub span: Span,
3399
3400 pub parens: Parens,
3403}
3404
3405impl PolyTraitRef {
3406 pub fn new(
3407 generic_params: ThinVec<GenericParam>,
3408 path: Path,
3409 modifiers: TraitBoundModifiers,
3410 span: Span,
3411 parens: Parens,
3412 ) -> Self {
3413 PolyTraitRef {
3414 bound_generic_params: generic_params,
3415 modifiers,
3416 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3417 span,
3418 parens,
3419 }
3420 }
3421}
3422
3423#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3424pub struct Visibility {
3425 pub kind: VisibilityKind,
3426 pub span: Span,
3427 pub tokens: Option<LazyAttrTokenStream>,
3428}
3429
3430#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3431pub enum VisibilityKind {
3432 Public,
3433 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3434 Inherited,
3435}
3436
3437impl VisibilityKind {
3438 pub fn is_pub(&self) -> bool {
3439 matches!(self, VisibilityKind::Public)
3440 }
3441}
3442
3443#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3447pub struct FieldDef {
3448 pub attrs: AttrVec,
3449 pub id: NodeId,
3450 pub span: Span,
3451 pub vis: Visibility,
3452 pub safety: Safety,
3453 pub ident: Option<Ident>,
3454
3455 pub ty: Box<Ty>,
3456 pub default: Option<AnonConst>,
3457 pub is_placeholder: bool,
3458}
3459
3460#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3462pub enum Recovered {
3463 No,
3464 Yes(ErrorGuaranteed),
3465}
3466
3467#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3469pub enum VariantData {
3470 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3474 Tuple(ThinVec<FieldDef>, NodeId),
3478 Unit(NodeId),
3482}
3483
3484impl VariantData {
3485 pub fn fields(&self) -> &[FieldDef] {
3487 match self {
3488 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3489 _ => &[],
3490 }
3491 }
3492
3493 pub fn ctor_node_id(&self) -> Option<NodeId> {
3495 match *self {
3496 VariantData::Struct { .. } => None,
3497 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3498 }
3499 }
3500}
3501
3502#[derive(Clone, Encodable, Decodable, Debug)]
3504pub struct Item<K = ItemKind> {
3505 pub attrs: AttrVec,
3506 pub id: NodeId,
3507 pub span: Span,
3508 pub vis: Visibility,
3509
3510 pub kind: K,
3511
3512 pub tokens: Option<LazyAttrTokenStream>,
3520}
3521
3522impl Item {
3523 pub fn span_with_attributes(&self) -> Span {
3525 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3526 }
3527
3528 pub fn opt_generics(&self) -> Option<&Generics> {
3529 match &self.kind {
3530 ItemKind::ExternCrate(..)
3531 | ItemKind::Use(_)
3532 | ItemKind::Mod(..)
3533 | ItemKind::ForeignMod(_)
3534 | ItemKind::GlobalAsm(_)
3535 | ItemKind::MacCall(_)
3536 | ItemKind::Delegation(_)
3537 | ItemKind::DelegationMac(_)
3538 | ItemKind::MacroDef(..) => None,
3539 ItemKind::Static(_) => None,
3540 ItemKind::Const(i) => Some(&i.generics),
3541 ItemKind::Fn(i) => Some(&i.generics),
3542 ItemKind::TyAlias(i) => Some(&i.generics),
3543 ItemKind::TraitAlias(_, generics, _)
3544 | ItemKind::Enum(_, generics, _)
3545 | ItemKind::Struct(_, generics, _)
3546 | ItemKind::Union(_, generics, _) => Some(&generics),
3547 ItemKind::Trait(i) => Some(&i.generics),
3548 ItemKind::Impl(i) => Some(&i.generics),
3549 }
3550 }
3551}
3552
3553#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3555pub enum Extern {
3556 None,
3560 Implicit(Span),
3566 Explicit(StrLit, Span),
3570}
3571
3572impl Extern {
3573 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3574 match abi {
3575 Some(name) => Extern::Explicit(name, span),
3576 None => Extern::Implicit(span),
3577 }
3578 }
3579
3580 pub fn span(self) -> Option<Span> {
3581 match self {
3582 Extern::None => None,
3583 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3584 }
3585 }
3586}
3587
3588#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3593pub struct FnHeader {
3594 pub constness: Const,
3596 pub coroutine_kind: Option<CoroutineKind>,
3598 pub safety: Safety,
3600 pub ext: Extern,
3602}
3603
3604impl FnHeader {
3605 pub fn has_qualifiers(&self) -> bool {
3607 let Self { safety, coroutine_kind, constness, ext } = self;
3608 matches!(safety, Safety::Unsafe(_))
3609 || coroutine_kind.is_some()
3610 || matches!(constness, Const::Yes(_))
3611 || !matches!(ext, Extern::None)
3612 }
3613}
3614
3615impl Default for FnHeader {
3616 fn default() -> FnHeader {
3617 FnHeader {
3618 safety: Safety::Default,
3619 coroutine_kind: None,
3620 constness: Const::No,
3621 ext: Extern::None,
3622 }
3623 }
3624}
3625
3626#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3627pub struct Trait {
3628 pub constness: Const,
3629 pub safety: Safety,
3630 pub is_auto: IsAuto,
3631 pub ident: Ident,
3632 pub generics: Generics,
3633 #[visitable(extra = BoundKind::SuperTraits)]
3634 pub bounds: GenericBounds,
3635 #[visitable(extra = AssocCtxt::Trait)]
3636 pub items: ThinVec<Box<AssocItem>>,
3637}
3638
3639#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3658pub struct TyAliasWhereClause {
3659 pub has_where_token: bool,
3660 pub span: Span,
3661}
3662
3663#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3665pub struct TyAliasWhereClauses {
3666 pub before: TyAliasWhereClause,
3668 pub after: TyAliasWhereClause,
3670 pub split: usize,
3674}
3675
3676#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3677pub struct TyAlias {
3678 pub defaultness: Defaultness,
3679 pub ident: Ident,
3680 pub generics: Generics,
3681 pub where_clauses: TyAliasWhereClauses,
3682 #[visitable(extra = BoundKind::Bound)]
3683 pub bounds: GenericBounds,
3684 pub ty: Option<Box<Ty>>,
3685}
3686
3687#[derive(Clone, Encodable, Decodable, Debug)]
3688pub struct Impl {
3689 pub generics: Generics,
3690 pub of_trait: Option<Box<TraitImplHeader>>,
3691 pub self_ty: Box<Ty>,
3692 pub items: ThinVec<Box<AssocItem>>,
3693}
3694
3695#[derive(Clone, Encodable, Decodable, Debug)]
3696pub struct TraitImplHeader {
3697 pub defaultness: Defaultness,
3698 pub safety: Safety,
3699 pub constness: Const,
3700 pub polarity: ImplPolarity,
3701 pub trait_ref: TraitRef,
3702}
3703
3704#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3705pub struct FnContract {
3706 pub requires: Option<Box<Expr>>,
3707 pub ensures: Option<Box<Expr>>,
3708}
3709
3710#[derive(Clone, Encodable, Decodable, Debug)]
3711pub struct Fn {
3712 pub defaultness: Defaultness,
3713 pub ident: Ident,
3714 pub generics: Generics,
3715 pub sig: FnSig,
3716 pub contract: Option<Box<FnContract>>,
3717 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3718 pub body: Option<Box<Block>>,
3719}
3720
3721#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3722pub struct Delegation {
3723 pub id: NodeId,
3725 pub qself: Option<Box<QSelf>>,
3726 pub path: Path,
3727 pub ident: Ident,
3728 pub rename: Option<Ident>,
3729 pub body: Option<Box<Block>>,
3730 pub from_glob: bool,
3732}
3733
3734#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3735pub struct DelegationMac {
3736 pub qself: Option<Box<QSelf>>,
3737 pub prefix: Path,
3738 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3740 pub body: Option<Box<Block>>,
3741}
3742
3743#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3744pub struct StaticItem {
3745 pub ident: Ident,
3746 pub ty: Box<Ty>,
3747 pub safety: Safety,
3748 pub mutability: Mutability,
3749 pub expr: Option<Box<Expr>>,
3750 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3751}
3752
3753#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3754pub struct ConstItem {
3755 pub defaultness: Defaultness,
3756 pub ident: Ident,
3757 pub generics: Generics,
3758 pub ty: Box<Ty>,
3759 pub expr: Option<Box<Expr>>,
3760 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3761}
3762
3763#[derive(Clone, Encodable, Decodable, Debug)]
3765pub enum ItemKind {
3766 ExternCrate(Option<Symbol>, Ident),
3770 Use(UseTree),
3774 Static(Box<StaticItem>),
3778 Const(Box<ConstItem>),
3782 Fn(Box<Fn>),
3786 Mod(Safety, Ident, ModKind),
3792 ForeignMod(ForeignMod),
3796 GlobalAsm(Box<InlineAsm>),
3798 TyAlias(Box<TyAlias>),
3802 Enum(Ident, Generics, EnumDef),
3806 Struct(Ident, Generics, VariantData),
3810 Union(Ident, Generics, VariantData),
3814 Trait(Box<Trait>),
3818 TraitAlias(Ident, Generics, GenericBounds),
3822 Impl(Impl),
3826 MacCall(Box<MacCall>),
3830 MacroDef(Ident, MacroDef),
3832 Delegation(Box<Delegation>),
3836 DelegationMac(Box<DelegationMac>),
3839}
3840
3841impl ItemKind {
3842 pub fn ident(&self) -> Option<Ident> {
3843 match *self {
3844 ItemKind::ExternCrate(_, ident)
3845 | ItemKind::Static(box StaticItem { ident, .. })
3846 | ItemKind::Const(box ConstItem { ident, .. })
3847 | ItemKind::Fn(box Fn { ident, .. })
3848 | ItemKind::Mod(_, ident, _)
3849 | ItemKind::TyAlias(box TyAlias { ident, .. })
3850 | ItemKind::Enum(ident, ..)
3851 | ItemKind::Struct(ident, ..)
3852 | ItemKind::Union(ident, ..)
3853 | ItemKind::Trait(box Trait { ident, .. })
3854 | ItemKind::TraitAlias(ident, ..)
3855 | ItemKind::MacroDef(ident, _)
3856 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3857
3858 ItemKind::Use(_)
3859 | ItemKind::ForeignMod(_)
3860 | ItemKind::GlobalAsm(_)
3861 | ItemKind::Impl(_)
3862 | ItemKind::MacCall(_)
3863 | ItemKind::DelegationMac(_) => None,
3864 }
3865 }
3866
3867 pub fn article(&self) -> &'static str {
3869 use ItemKind::*;
3870 match self {
3871 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3872 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3873 | Delegation(..) | DelegationMac(..) => "a",
3874 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3875 }
3876 }
3877
3878 pub fn descr(&self) -> &'static str {
3879 match self {
3880 ItemKind::ExternCrate(..) => "extern crate",
3881 ItemKind::Use(..) => "`use` import",
3882 ItemKind::Static(..) => "static item",
3883 ItemKind::Const(..) => "constant item",
3884 ItemKind::Fn(..) => "function",
3885 ItemKind::Mod(..) => "module",
3886 ItemKind::ForeignMod(..) => "extern block",
3887 ItemKind::GlobalAsm(..) => "global asm item",
3888 ItemKind::TyAlias(..) => "type alias",
3889 ItemKind::Enum(..) => "enum",
3890 ItemKind::Struct(..) => "struct",
3891 ItemKind::Union(..) => "union",
3892 ItemKind::Trait(..) => "trait",
3893 ItemKind::TraitAlias(..) => "trait alias",
3894 ItemKind::MacCall(..) => "item macro invocation",
3895 ItemKind::MacroDef(..) => "macro definition",
3896 ItemKind::Impl { .. } => "implementation",
3897 ItemKind::Delegation(..) => "delegated function",
3898 ItemKind::DelegationMac(..) => "delegation",
3899 }
3900 }
3901
3902 pub fn generics(&self) -> Option<&Generics> {
3903 match self {
3904 Self::Fn(box Fn { generics, .. })
3905 | Self::TyAlias(box TyAlias { generics, .. })
3906 | Self::Const(box ConstItem { generics, .. })
3907 | Self::Enum(_, generics, _)
3908 | Self::Struct(_, generics, _)
3909 | Self::Union(_, generics, _)
3910 | Self::Trait(box Trait { generics, .. })
3911 | Self::TraitAlias(_, generics, _)
3912 | Self::Impl(Impl { generics, .. }) => Some(generics),
3913 _ => None,
3914 }
3915 }
3916}
3917
3918pub type AssocItem = Item<AssocItemKind>;
3921
3922#[derive(Clone, Encodable, Decodable, Debug)]
3930pub enum AssocItemKind {
3931 Const(Box<ConstItem>),
3934 Fn(Box<Fn>),
3936 Type(Box<TyAlias>),
3938 MacCall(Box<MacCall>),
3940 Delegation(Box<Delegation>),
3942 DelegationMac(Box<DelegationMac>),
3944}
3945
3946impl AssocItemKind {
3947 pub fn ident(&self) -> Option<Ident> {
3948 match *self {
3949 AssocItemKind::Const(box ConstItem { ident, .. })
3950 | AssocItemKind::Fn(box Fn { ident, .. })
3951 | AssocItemKind::Type(box TyAlias { ident, .. })
3952 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3953
3954 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3955 }
3956 }
3957
3958 pub fn defaultness(&self) -> Defaultness {
3959 match *self {
3960 Self::Const(box ConstItem { defaultness, .. })
3961 | Self::Fn(box Fn { defaultness, .. })
3962 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3963 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3964 Defaultness::Final
3965 }
3966 }
3967 }
3968}
3969
3970impl From<AssocItemKind> for ItemKind {
3971 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3972 match assoc_item_kind {
3973 AssocItemKind::Const(item) => ItemKind::Const(item),
3974 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3975 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3976 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3977 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3978 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3979 }
3980 }
3981}
3982
3983impl TryFrom<ItemKind> for AssocItemKind {
3984 type Error = ItemKind;
3985
3986 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3987 Ok(match item_kind {
3988 ItemKind::Const(item) => AssocItemKind::Const(item),
3989 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3990 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3991 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3992 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3993 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3994 _ => return Err(item_kind),
3995 })
3996 }
3997}
3998
3999#[derive(Clone, Encodable, Decodable, Debug)]
4001pub enum ForeignItemKind {
4002 Static(Box<StaticItem>),
4004 Fn(Box<Fn>),
4006 TyAlias(Box<TyAlias>),
4008 MacCall(Box<MacCall>),
4010}
4011
4012impl ForeignItemKind {
4013 pub fn ident(&self) -> Option<Ident> {
4014 match *self {
4015 ForeignItemKind::Static(box StaticItem { ident, .. })
4016 | ForeignItemKind::Fn(box Fn { ident, .. })
4017 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4018
4019 ForeignItemKind::MacCall(_) => None,
4020 }
4021 }
4022}
4023
4024impl From<ForeignItemKind> for ItemKind {
4025 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4026 match foreign_item_kind {
4027 ForeignItemKind::Static(box static_foreign_item) => {
4028 ItemKind::Static(Box::new(static_foreign_item))
4029 }
4030 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4031 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4032 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4033 }
4034 }
4035}
4036
4037impl TryFrom<ItemKind> for ForeignItemKind {
4038 type Error = ItemKind;
4039
4040 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4041 Ok(match item_kind {
4042 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4043 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4044 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4045 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4046 _ => return Err(item_kind),
4047 })
4048 }
4049}
4050
4051pub type ForeignItem = Item<ForeignItemKind>;
4052
4053#[cfg(target_pointer_width = "64")]
4055mod size_asserts {
4056 use rustc_data_structures::static_assert_size;
4057
4058 use super::*;
4059 static_assert_size!(AssocItem, 80);
4061 static_assert_size!(AssocItemKind, 16);
4062 static_assert_size!(Attribute, 32);
4063 static_assert_size!(Block, 32);
4064 static_assert_size!(Expr, 72);
4065 static_assert_size!(ExprKind, 40);
4066 static_assert_size!(Fn, 184);
4067 static_assert_size!(ForeignItem, 80);
4068 static_assert_size!(ForeignItemKind, 16);
4069 static_assert_size!(GenericArg, 24);
4070 static_assert_size!(GenericBound, 88);
4071 static_assert_size!(Generics, 40);
4072 static_assert_size!(Impl, 64);
4073 static_assert_size!(Item, 144);
4074 static_assert_size!(ItemKind, 80);
4075 static_assert_size!(LitKind, 24);
4076 static_assert_size!(Local, 96);
4077 static_assert_size!(MetaItemLit, 40);
4078 static_assert_size!(Param, 40);
4079 static_assert_size!(Pat, 80);
4080 static_assert_size!(PatKind, 56);
4081 static_assert_size!(Path, 24);
4082 static_assert_size!(PathSegment, 24);
4083 static_assert_size!(Stmt, 32);
4084 static_assert_size!(StmtKind, 16);
4085 static_assert_size!(TraitImplHeader, 80);
4086 static_assert_size!(Ty, 64);
4087 static_assert_size!(TyKind, 40);
4088 }