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<Box<Pat>>),
873
874 Or(ThinVec<Box<Pat>>),
877
878 Path(Option<Box<QSelf>>, Path),
883
884 Tuple(ThinVec<Box<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<Box<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 Or(ThinVec<Box<TyPat>>),
2583
2584 Err(ErrorGuaranteed),
2586}
2587
2588#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2590#[repr(u8)]
2591pub enum TraitObjectSyntax {
2592 Dyn = 0,
2594 None = 1,
2595}
2596
2597unsafe impl Tag for TraitObjectSyntax {
2601 const BITS: u32 = 2;
2602
2603 fn into_usize(self) -> usize {
2604 self as u8 as usize
2605 }
2606
2607 unsafe fn from_usize(tag: usize) -> Self {
2608 match tag {
2609 0 => TraitObjectSyntax::Dyn,
2610 1 => TraitObjectSyntax::None,
2611 _ => unreachable!(),
2612 }
2613 }
2614}
2615
2616#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2617pub enum PreciseCapturingArg {
2618 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2620 Arg(Path, NodeId),
2622}
2623
2624#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2628pub enum InlineAsmRegOrRegClass {
2629 Reg(Symbol),
2630 RegClass(Symbol),
2631}
2632
2633#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2634pub struct InlineAsmOptions(u16);
2635bitflags::bitflags! {
2636 impl InlineAsmOptions: u16 {
2637 const PURE = 1 << 0;
2638 const NOMEM = 1 << 1;
2639 const READONLY = 1 << 2;
2640 const PRESERVES_FLAGS = 1 << 3;
2641 const NORETURN = 1 << 4;
2642 const NOSTACK = 1 << 5;
2643 const ATT_SYNTAX = 1 << 6;
2644 const RAW = 1 << 7;
2645 const MAY_UNWIND = 1 << 8;
2646 }
2647}
2648
2649impl InlineAsmOptions {
2650 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2651
2652 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2653 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2654
2655 pub fn human_readable_names(&self) -> Vec<&'static str> {
2656 let mut options = vec![];
2657
2658 if self.contains(InlineAsmOptions::PURE) {
2659 options.push("pure");
2660 }
2661 if self.contains(InlineAsmOptions::NOMEM) {
2662 options.push("nomem");
2663 }
2664 if self.contains(InlineAsmOptions::READONLY) {
2665 options.push("readonly");
2666 }
2667 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2668 options.push("preserves_flags");
2669 }
2670 if self.contains(InlineAsmOptions::NORETURN) {
2671 options.push("noreturn");
2672 }
2673 if self.contains(InlineAsmOptions::NOSTACK) {
2674 options.push("nostack");
2675 }
2676 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2677 options.push("att_syntax");
2678 }
2679 if self.contains(InlineAsmOptions::RAW) {
2680 options.push("raw");
2681 }
2682 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2683 options.push("may_unwind");
2684 }
2685
2686 options
2687 }
2688}
2689
2690impl std::fmt::Debug for InlineAsmOptions {
2691 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2692 bitflags::parser::to_writer(self, f)
2693 }
2694}
2695
2696#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2697pub enum InlineAsmTemplatePiece {
2698 String(Cow<'static, str>),
2699 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2700}
2701
2702impl fmt::Display for InlineAsmTemplatePiece {
2703 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2704 match self {
2705 Self::String(s) => {
2706 for c in s.chars() {
2707 match c {
2708 '{' => f.write_str("{{")?,
2709 '}' => f.write_str("}}")?,
2710 _ => c.fmt(f)?,
2711 }
2712 }
2713 Ok(())
2714 }
2715 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2716 write!(f, "{{{operand_idx}:{modifier}}}")
2717 }
2718 Self::Placeholder { operand_idx, modifier: None, .. } => {
2719 write!(f, "{{{operand_idx}}}")
2720 }
2721 }
2722 }
2723}
2724
2725impl InlineAsmTemplatePiece {
2726 pub fn to_string(s: &[Self]) -> String {
2728 use fmt::Write;
2729 let mut out = String::new();
2730 for p in s.iter() {
2731 let _ = write!(out, "{p}");
2732 }
2733 out
2734 }
2735}
2736
2737#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2745pub struct InlineAsmSym {
2746 pub id: NodeId,
2747 pub qself: Option<Box<QSelf>>,
2748 pub path: Path,
2749}
2750
2751#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2755pub enum InlineAsmOperand {
2756 In {
2757 reg: InlineAsmRegOrRegClass,
2758 expr: Box<Expr>,
2759 },
2760 Out {
2761 reg: InlineAsmRegOrRegClass,
2762 late: bool,
2763 expr: Option<Box<Expr>>,
2764 },
2765 InOut {
2766 reg: InlineAsmRegOrRegClass,
2767 late: bool,
2768 expr: Box<Expr>,
2769 },
2770 SplitInOut {
2771 reg: InlineAsmRegOrRegClass,
2772 late: bool,
2773 in_expr: Box<Expr>,
2774 out_expr: Option<Box<Expr>>,
2775 },
2776 Const {
2777 anon_const: AnonConst,
2778 },
2779 Sym {
2780 sym: InlineAsmSym,
2781 },
2782 Label {
2783 block: Box<Block>,
2784 },
2785}
2786
2787impl InlineAsmOperand {
2788 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2789 match self {
2790 Self::In { reg, .. }
2791 | Self::Out { reg, .. }
2792 | Self::InOut { reg, .. }
2793 | Self::SplitInOut { reg, .. } => Some(reg),
2794 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2795 }
2796 }
2797}
2798
2799#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2800pub enum AsmMacro {
2801 Asm,
2803 GlobalAsm,
2805 NakedAsm,
2807}
2808
2809impl AsmMacro {
2810 pub const fn macro_name(self) -> &'static str {
2811 match self {
2812 AsmMacro::Asm => "asm",
2813 AsmMacro::GlobalAsm => "global_asm",
2814 AsmMacro::NakedAsm => "naked_asm",
2815 }
2816 }
2817
2818 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2819 match self {
2820 AsmMacro::Asm => true,
2821 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2822 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2823 }
2824 }
2825
2826 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2827 match self {
2828 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2829 AsmMacro::GlobalAsm => true,
2830 AsmMacro::NakedAsm => true,
2831 }
2832 }
2833}
2834
2835#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2839pub struct InlineAsm {
2840 pub asm_macro: AsmMacro,
2841 pub template: Vec<InlineAsmTemplatePiece>,
2842 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2843 pub operands: Vec<(InlineAsmOperand, Span)>,
2844 pub clobber_abis: Vec<(Symbol, Span)>,
2845 #[visitable(ignore)]
2846 pub options: InlineAsmOptions,
2847 pub line_spans: Vec<Span>,
2848}
2849
2850#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2854pub struct Param {
2855 pub attrs: AttrVec,
2856 pub ty: Box<Ty>,
2857 pub pat: Box<Pat>,
2858 pub id: NodeId,
2859 pub span: Span,
2860 pub is_placeholder: bool,
2861}
2862
2863#[derive(Clone, Encodable, Decodable, Debug)]
2867pub enum SelfKind {
2868 Value(Mutability),
2870 Region(Option<Lifetime>, Mutability),
2872 Pinned(Option<Lifetime>, Mutability),
2874 Explicit(Box<Ty>, Mutability),
2876}
2877
2878impl SelfKind {
2879 pub fn to_ref_suggestion(&self) -> String {
2880 match self {
2881 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2882 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2883 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2884 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2885 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2886 unreachable!("if we had an explicit self, we wouldn't be here")
2887 }
2888 }
2889 }
2890}
2891
2892pub type ExplicitSelf = Spanned<SelfKind>;
2893
2894impl Param {
2895 pub fn to_self(&self) -> Option<ExplicitSelf> {
2897 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2898 if ident.name == kw::SelfLower {
2899 return match self.ty.kind {
2900 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2901 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2902 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2903 }
2904 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2905 if ty.kind.is_implicit_self() =>
2906 {
2907 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2908 }
2909 _ => Some(respan(
2910 self.pat.span.to(self.ty.span),
2911 SelfKind::Explicit(self.ty.clone(), mutbl),
2912 )),
2913 };
2914 }
2915 }
2916 None
2917 }
2918
2919 pub fn is_self(&self) -> bool {
2921 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2922 ident.name == kw::SelfLower
2923 } else {
2924 false
2925 }
2926 }
2927
2928 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2930 let span = eself.span.to(eself_ident.span);
2931 let infer_ty = Box::new(Ty {
2932 id: DUMMY_NODE_ID,
2933 kind: TyKind::ImplicitSelf,
2934 span: eself_ident.span,
2935 tokens: None,
2936 });
2937 let (mutbl, ty) = match eself.node {
2938 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2939 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2940 SelfKind::Region(lt, mutbl) => (
2941 Mutability::Not,
2942 Box::new(Ty {
2943 id: DUMMY_NODE_ID,
2944 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2945 span,
2946 tokens: None,
2947 }),
2948 ),
2949 SelfKind::Pinned(lt, mutbl) => (
2950 mutbl,
2951 Box::new(Ty {
2952 id: DUMMY_NODE_ID,
2953 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2954 span,
2955 tokens: None,
2956 }),
2957 ),
2958 };
2959 Param {
2960 attrs,
2961 pat: Box::new(Pat {
2962 id: DUMMY_NODE_ID,
2963 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2964 span,
2965 tokens: None,
2966 }),
2967 span,
2968 ty,
2969 id: DUMMY_NODE_ID,
2970 is_placeholder: false,
2971 }
2972 }
2973}
2974
2975#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2982pub struct FnDecl {
2983 pub inputs: ThinVec<Param>,
2984 pub output: FnRetTy,
2985}
2986
2987impl FnDecl {
2988 pub fn has_self(&self) -> bool {
2989 self.inputs.get(0).is_some_and(Param::is_self)
2990 }
2991 pub fn c_variadic(&self) -> bool {
2992 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2993 }
2994}
2995
2996#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2998pub enum IsAuto {
2999 Yes,
3000 No,
3001}
3002
3003#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3005#[derive(HashStable_Generic, Walkable)]
3006pub enum Safety {
3007 Unsafe(Span),
3009 Safe(Span),
3011 Default,
3014}
3015
3016#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3022pub enum CoroutineKind {
3023 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3025 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3027 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3029}
3030
3031impl CoroutineKind {
3032 pub fn span(self) -> Span {
3033 match self {
3034 CoroutineKind::Async { span, .. } => span,
3035 CoroutineKind::Gen { span, .. } => span,
3036 CoroutineKind::AsyncGen { span, .. } => span,
3037 }
3038 }
3039
3040 pub fn as_str(self) -> &'static str {
3041 match self {
3042 CoroutineKind::Async { .. } => "async",
3043 CoroutineKind::Gen { .. } => "gen",
3044 CoroutineKind::AsyncGen { .. } => "async gen",
3045 }
3046 }
3047
3048 pub fn closure_id(self) -> NodeId {
3049 match self {
3050 CoroutineKind::Async { closure_id, .. }
3051 | CoroutineKind::Gen { closure_id, .. }
3052 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3053 }
3054 }
3055
3056 pub fn return_id(self) -> (NodeId, Span) {
3059 match self {
3060 CoroutineKind::Async { return_impl_trait_id, span, .. }
3061 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3062 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3063 (return_impl_trait_id, span)
3064 }
3065 }
3066 }
3067}
3068
3069#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3070#[derive(HashStable_Generic, Walkable)]
3071pub enum Const {
3072 Yes(Span),
3073 No,
3074}
3075
3076#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3079pub enum Defaultness {
3080 Default(Span),
3081 Final,
3082}
3083
3084#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3085pub enum ImplPolarity {
3086 Positive,
3088 Negative(Span),
3090}
3091
3092impl fmt::Debug for ImplPolarity {
3093 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3094 match *self {
3095 ImplPolarity::Positive => "positive".fmt(f),
3096 ImplPolarity::Negative(_) => "negative".fmt(f),
3097 }
3098 }
3099}
3100
3101#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3103#[derive(HashStable_Generic, Walkable)]
3104pub enum BoundPolarity {
3105 Positive,
3107 Negative(Span),
3109 Maybe(Span),
3111}
3112
3113impl BoundPolarity {
3114 pub fn as_str(self) -> &'static str {
3115 match self {
3116 Self::Positive => "",
3117 Self::Negative(_) => "!",
3118 Self::Maybe(_) => "?",
3119 }
3120 }
3121}
3122
3123#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3125#[derive(HashStable_Generic, Walkable)]
3126pub enum BoundConstness {
3127 Never,
3129 Always(Span),
3131 Maybe(Span),
3133}
3134
3135impl BoundConstness {
3136 pub fn as_str(self) -> &'static str {
3137 match self {
3138 Self::Never => "",
3139 Self::Always(_) => "const",
3140 Self::Maybe(_) => "[const]",
3141 }
3142 }
3143}
3144
3145#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3147#[derive(HashStable_Generic, Walkable)]
3148pub enum BoundAsyncness {
3149 Normal,
3151 Async(Span),
3153}
3154
3155impl BoundAsyncness {
3156 pub fn as_str(self) -> &'static str {
3157 match self {
3158 Self::Normal => "",
3159 Self::Async(_) => "async",
3160 }
3161 }
3162}
3163
3164#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3165pub enum FnRetTy {
3166 Default(Span),
3171 Ty(Box<Ty>),
3173}
3174
3175impl FnRetTy {
3176 pub fn span(&self) -> Span {
3177 match self {
3178 &FnRetTy::Default(span) => span,
3179 FnRetTy::Ty(ty) => ty.span,
3180 }
3181 }
3182}
3183
3184#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3185pub enum Inline {
3186 Yes,
3187 No { had_parse_error: Result<(), ErrorGuaranteed> },
3188}
3189
3190#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3192pub enum ModKind {
3193 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3198 Unloaded,
3200}
3201
3202#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3203pub struct ModSpans {
3204 pub inner_span: Span,
3207 pub inject_use_span: Span,
3208}
3209
3210#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3214pub struct ForeignMod {
3215 pub extern_span: Span,
3217 pub safety: Safety,
3220 pub abi: Option<StrLit>,
3221 pub items: ThinVec<Box<ForeignItem>>,
3222}
3223
3224#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3225pub struct EnumDef {
3226 pub variants: ThinVec<Variant>,
3227}
3228
3229#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3231pub struct Variant {
3232 pub attrs: AttrVec,
3234 pub id: NodeId,
3236 pub span: Span,
3238 pub vis: Visibility,
3240 pub ident: Ident,
3242
3243 pub data: VariantData,
3245 pub disr_expr: Option<AnonConst>,
3247 pub is_placeholder: bool,
3249}
3250
3251#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3253pub enum UseTreeKind {
3254 Simple(Option<Ident>),
3256 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3265 Glob,
3267}
3268
3269#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3272pub struct UseTree {
3273 pub prefix: Path,
3274 pub kind: UseTreeKind,
3275 pub span: Span,
3276}
3277
3278impl UseTree {
3279 pub fn ident(&self) -> Ident {
3280 match self.kind {
3281 UseTreeKind::Simple(Some(rename)) => rename,
3282 UseTreeKind::Simple(None) => {
3283 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3284 }
3285 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3286 }
3287 }
3288}
3289
3290#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3294pub enum AttrStyle {
3295 Outer,
3296 Inner,
3297}
3298
3299pub type AttrVec = ThinVec<Attribute>;
3301
3302#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3304pub struct Attribute {
3305 pub kind: AttrKind,
3306 pub id: AttrId,
3307 pub style: AttrStyle,
3310 pub span: Span,
3311}
3312
3313#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3314pub enum AttrKind {
3315 Normal(Box<NormalAttr>),
3317
3318 DocComment(CommentKind, Symbol),
3322}
3323
3324#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3325pub struct NormalAttr {
3326 pub item: AttrItem,
3327 pub tokens: Option<LazyAttrTokenStream>,
3329}
3330
3331impl NormalAttr {
3332 pub fn from_ident(ident: Ident) -> Self {
3333 Self {
3334 item: AttrItem {
3335 unsafety: Safety::Default,
3336 path: Path::from_ident(ident),
3337 args: AttrArgs::Empty,
3338 tokens: None,
3339 },
3340 tokens: None,
3341 }
3342 }
3343}
3344
3345#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3346pub struct AttrItem {
3347 pub unsafety: Safety,
3348 pub path: Path,
3349 pub args: AttrArgs,
3350 pub tokens: Option<LazyAttrTokenStream>,
3352}
3353
3354impl AttrItem {
3355 pub fn is_valid_for_outer_style(&self) -> bool {
3356 self.path == sym::cfg_attr
3357 || self.path == sym::cfg
3358 || self.path == sym::forbid
3359 || self.path == sym::warn
3360 || self.path == sym::allow
3361 || self.path == sym::deny
3362 }
3363}
3364
3365#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3372pub struct TraitRef {
3373 pub path: Path,
3374 pub ref_id: NodeId,
3375}
3376
3377#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3379pub enum Parens {
3380 Yes,
3381 No,
3382}
3383
3384#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3385pub struct PolyTraitRef {
3386 pub bound_generic_params: ThinVec<GenericParam>,
3388
3389 pub modifiers: TraitBoundModifiers,
3391
3392 pub trait_ref: TraitRef,
3394
3395 pub span: Span,
3396
3397 pub parens: Parens,
3400}
3401
3402impl PolyTraitRef {
3403 pub fn new(
3404 generic_params: ThinVec<GenericParam>,
3405 path: Path,
3406 modifiers: TraitBoundModifiers,
3407 span: Span,
3408 parens: Parens,
3409 ) -> Self {
3410 PolyTraitRef {
3411 bound_generic_params: generic_params,
3412 modifiers,
3413 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3414 span,
3415 parens,
3416 }
3417 }
3418}
3419
3420#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3421pub struct Visibility {
3422 pub kind: VisibilityKind,
3423 pub span: Span,
3424 pub tokens: Option<LazyAttrTokenStream>,
3425}
3426
3427#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3428pub enum VisibilityKind {
3429 Public,
3430 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3431 Inherited,
3432}
3433
3434impl VisibilityKind {
3435 pub fn is_pub(&self) -> bool {
3436 matches!(self, VisibilityKind::Public)
3437 }
3438}
3439
3440#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3444pub struct FieldDef {
3445 pub attrs: AttrVec,
3446 pub id: NodeId,
3447 pub span: Span,
3448 pub vis: Visibility,
3449 pub safety: Safety,
3450 pub ident: Option<Ident>,
3451
3452 pub ty: Box<Ty>,
3453 pub default: Option<AnonConst>,
3454 pub is_placeholder: bool,
3455}
3456
3457#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3459pub enum Recovered {
3460 No,
3461 Yes(ErrorGuaranteed),
3462}
3463
3464#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3466pub enum VariantData {
3467 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3471 Tuple(ThinVec<FieldDef>, NodeId),
3475 Unit(NodeId),
3479}
3480
3481impl VariantData {
3482 pub fn fields(&self) -> &[FieldDef] {
3484 match self {
3485 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3486 _ => &[],
3487 }
3488 }
3489
3490 pub fn ctor_node_id(&self) -> Option<NodeId> {
3492 match *self {
3493 VariantData::Struct { .. } => None,
3494 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3495 }
3496 }
3497}
3498
3499#[derive(Clone, Encodable, Decodable, Debug)]
3501pub struct Item<K = ItemKind> {
3502 pub attrs: AttrVec,
3503 pub id: NodeId,
3504 pub span: Span,
3505 pub vis: Visibility,
3506
3507 pub kind: K,
3508
3509 pub tokens: Option<LazyAttrTokenStream>,
3517}
3518
3519impl Item {
3520 pub fn span_with_attributes(&self) -> Span {
3522 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3523 }
3524
3525 pub fn opt_generics(&self) -> Option<&Generics> {
3526 match &self.kind {
3527 ItemKind::ExternCrate(..)
3528 | ItemKind::Use(_)
3529 | ItemKind::Mod(..)
3530 | ItemKind::ForeignMod(_)
3531 | ItemKind::GlobalAsm(_)
3532 | ItemKind::MacCall(_)
3533 | ItemKind::Delegation(_)
3534 | ItemKind::DelegationMac(_)
3535 | ItemKind::MacroDef(..) => None,
3536 ItemKind::Static(_) => None,
3537 ItemKind::Const(i) => Some(&i.generics),
3538 ItemKind::Fn(i) => Some(&i.generics),
3539 ItemKind::TyAlias(i) => Some(&i.generics),
3540 ItemKind::TraitAlias(_, generics, _)
3541 | ItemKind::Enum(_, generics, _)
3542 | ItemKind::Struct(_, generics, _)
3543 | ItemKind::Union(_, generics, _) => Some(&generics),
3544 ItemKind::Trait(i) => Some(&i.generics),
3545 ItemKind::Impl(i) => Some(&i.generics),
3546 }
3547 }
3548}
3549
3550#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3552pub enum Extern {
3553 None,
3557 Implicit(Span),
3563 Explicit(StrLit, Span),
3567}
3568
3569impl Extern {
3570 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3571 match abi {
3572 Some(name) => Extern::Explicit(name, span),
3573 None => Extern::Implicit(span),
3574 }
3575 }
3576
3577 pub fn span(self) -> Option<Span> {
3578 match self {
3579 Extern::None => None,
3580 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3581 }
3582 }
3583}
3584
3585#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3590pub struct FnHeader {
3591 pub constness: Const,
3593 pub coroutine_kind: Option<CoroutineKind>,
3595 pub safety: Safety,
3597 pub ext: Extern,
3599}
3600
3601impl FnHeader {
3602 pub fn has_qualifiers(&self) -> bool {
3604 let Self { safety, coroutine_kind, constness, ext } = self;
3605 matches!(safety, Safety::Unsafe(_))
3606 || coroutine_kind.is_some()
3607 || matches!(constness, Const::Yes(_))
3608 || !matches!(ext, Extern::None)
3609 }
3610}
3611
3612impl Default for FnHeader {
3613 fn default() -> FnHeader {
3614 FnHeader {
3615 safety: Safety::Default,
3616 coroutine_kind: None,
3617 constness: Const::No,
3618 ext: Extern::None,
3619 }
3620 }
3621}
3622
3623#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3624pub struct Trait {
3625 pub constness: Const,
3626 pub safety: Safety,
3627 pub is_auto: IsAuto,
3628 pub ident: Ident,
3629 pub generics: Generics,
3630 #[visitable(extra = BoundKind::SuperTraits)]
3631 pub bounds: GenericBounds,
3632 #[visitable(extra = AssocCtxt::Trait)]
3633 pub items: ThinVec<Box<AssocItem>>,
3634}
3635
3636#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3655pub struct TyAliasWhereClause {
3656 pub has_where_token: bool,
3657 pub span: Span,
3658}
3659
3660#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3662pub struct TyAliasWhereClauses {
3663 pub before: TyAliasWhereClause,
3665 pub after: TyAliasWhereClause,
3667 pub split: usize,
3671}
3672
3673#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3674pub struct TyAlias {
3675 pub defaultness: Defaultness,
3676 pub ident: Ident,
3677 pub generics: Generics,
3678 pub where_clauses: TyAliasWhereClauses,
3679 #[visitable(extra = BoundKind::Bound)]
3680 pub bounds: GenericBounds,
3681 pub ty: Option<Box<Ty>>,
3682}
3683
3684#[derive(Clone, Encodable, Decodable, Debug)]
3685pub struct Impl {
3686 pub generics: Generics,
3687 pub of_trait: Option<Box<TraitImplHeader>>,
3688 pub self_ty: Box<Ty>,
3689 pub items: ThinVec<Box<AssocItem>>,
3690}
3691
3692#[derive(Clone, Encodable, Decodable, Debug)]
3693pub struct TraitImplHeader {
3694 pub defaultness: Defaultness,
3695 pub safety: Safety,
3696 pub constness: Const,
3697 pub polarity: ImplPolarity,
3698 pub trait_ref: TraitRef,
3699}
3700
3701#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3702pub struct FnContract {
3703 pub requires: Option<Box<Expr>>,
3704 pub ensures: Option<Box<Expr>>,
3705}
3706
3707#[derive(Clone, Encodable, Decodable, Debug)]
3708pub struct Fn {
3709 pub defaultness: Defaultness,
3710 pub ident: Ident,
3711 pub generics: Generics,
3712 pub sig: FnSig,
3713 pub contract: Option<Box<FnContract>>,
3714 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3715 pub body: Option<Box<Block>>,
3716}
3717
3718#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3719pub struct Delegation {
3720 pub id: NodeId,
3722 pub qself: Option<Box<QSelf>>,
3723 pub path: Path,
3724 pub ident: Ident,
3725 pub rename: Option<Ident>,
3726 pub body: Option<Box<Block>>,
3727 pub from_glob: bool,
3729}
3730
3731#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3732pub struct DelegationMac {
3733 pub qself: Option<Box<QSelf>>,
3734 pub prefix: Path,
3735 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3737 pub body: Option<Box<Block>>,
3738}
3739
3740#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3741pub struct StaticItem {
3742 pub ident: Ident,
3743 pub ty: Box<Ty>,
3744 pub safety: Safety,
3745 pub mutability: Mutability,
3746 pub expr: Option<Box<Expr>>,
3747 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3748}
3749
3750#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3751pub struct ConstItem {
3752 pub defaultness: Defaultness,
3753 pub ident: Ident,
3754 pub generics: Generics,
3755 pub ty: Box<Ty>,
3756 pub expr: Option<Box<Expr>>,
3757 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3758}
3759
3760#[derive(Clone, Encodable, Decodable, Debug)]
3762pub enum ItemKind {
3763 ExternCrate(Option<Symbol>, Ident),
3767 Use(UseTree),
3771 Static(Box<StaticItem>),
3775 Const(Box<ConstItem>),
3779 Fn(Box<Fn>),
3783 Mod(Safety, Ident, ModKind),
3789 ForeignMod(ForeignMod),
3793 GlobalAsm(Box<InlineAsm>),
3795 TyAlias(Box<TyAlias>),
3799 Enum(Ident, Generics, EnumDef),
3803 Struct(Ident, Generics, VariantData),
3807 Union(Ident, Generics, VariantData),
3811 Trait(Box<Trait>),
3815 TraitAlias(Ident, Generics, GenericBounds),
3819 Impl(Impl),
3823 MacCall(Box<MacCall>),
3827 MacroDef(Ident, MacroDef),
3829 Delegation(Box<Delegation>),
3833 DelegationMac(Box<DelegationMac>),
3836}
3837
3838impl ItemKind {
3839 pub fn ident(&self) -> Option<Ident> {
3840 match *self {
3841 ItemKind::ExternCrate(_, ident)
3842 | ItemKind::Static(box StaticItem { ident, .. })
3843 | ItemKind::Const(box ConstItem { ident, .. })
3844 | ItemKind::Fn(box Fn { ident, .. })
3845 | ItemKind::Mod(_, ident, _)
3846 | ItemKind::TyAlias(box TyAlias { ident, .. })
3847 | ItemKind::Enum(ident, ..)
3848 | ItemKind::Struct(ident, ..)
3849 | ItemKind::Union(ident, ..)
3850 | ItemKind::Trait(box Trait { ident, .. })
3851 | ItemKind::TraitAlias(ident, ..)
3852 | ItemKind::MacroDef(ident, _)
3853 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3854
3855 ItemKind::Use(_)
3856 | ItemKind::ForeignMod(_)
3857 | ItemKind::GlobalAsm(_)
3858 | ItemKind::Impl(_)
3859 | ItemKind::MacCall(_)
3860 | ItemKind::DelegationMac(_) => None,
3861 }
3862 }
3863
3864 pub fn article(&self) -> &'static str {
3866 use ItemKind::*;
3867 match self {
3868 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3869 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3870 | Delegation(..) | DelegationMac(..) => "a",
3871 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3872 }
3873 }
3874
3875 pub fn descr(&self) -> &'static str {
3876 match self {
3877 ItemKind::ExternCrate(..) => "extern crate",
3878 ItemKind::Use(..) => "`use` import",
3879 ItemKind::Static(..) => "static item",
3880 ItemKind::Const(..) => "constant item",
3881 ItemKind::Fn(..) => "function",
3882 ItemKind::Mod(..) => "module",
3883 ItemKind::ForeignMod(..) => "extern block",
3884 ItemKind::GlobalAsm(..) => "global asm item",
3885 ItemKind::TyAlias(..) => "type alias",
3886 ItemKind::Enum(..) => "enum",
3887 ItemKind::Struct(..) => "struct",
3888 ItemKind::Union(..) => "union",
3889 ItemKind::Trait(..) => "trait",
3890 ItemKind::TraitAlias(..) => "trait alias",
3891 ItemKind::MacCall(..) => "item macro invocation",
3892 ItemKind::MacroDef(..) => "macro definition",
3893 ItemKind::Impl { .. } => "implementation",
3894 ItemKind::Delegation(..) => "delegated function",
3895 ItemKind::DelegationMac(..) => "delegation",
3896 }
3897 }
3898
3899 pub fn generics(&self) -> Option<&Generics> {
3900 match self {
3901 Self::Fn(box Fn { generics, .. })
3902 | Self::TyAlias(box TyAlias { generics, .. })
3903 | Self::Const(box ConstItem { generics, .. })
3904 | Self::Enum(_, generics, _)
3905 | Self::Struct(_, generics, _)
3906 | Self::Union(_, generics, _)
3907 | Self::Trait(box Trait { generics, .. })
3908 | Self::TraitAlias(_, generics, _)
3909 | Self::Impl(Impl { generics, .. }) => Some(generics),
3910 _ => None,
3911 }
3912 }
3913}
3914
3915pub type AssocItem = Item<AssocItemKind>;
3918
3919#[derive(Clone, Encodable, Decodable, Debug)]
3927pub enum AssocItemKind {
3928 Const(Box<ConstItem>),
3931 Fn(Box<Fn>),
3933 Type(Box<TyAlias>),
3935 MacCall(Box<MacCall>),
3937 Delegation(Box<Delegation>),
3939 DelegationMac(Box<DelegationMac>),
3941}
3942
3943impl AssocItemKind {
3944 pub fn ident(&self) -> Option<Ident> {
3945 match *self {
3946 AssocItemKind::Const(box ConstItem { ident, .. })
3947 | AssocItemKind::Fn(box Fn { ident, .. })
3948 | AssocItemKind::Type(box TyAlias { ident, .. })
3949 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3950
3951 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3952 }
3953 }
3954
3955 pub fn defaultness(&self) -> Defaultness {
3956 match *self {
3957 Self::Const(box ConstItem { defaultness, .. })
3958 | Self::Fn(box Fn { defaultness, .. })
3959 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3960 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3961 Defaultness::Final
3962 }
3963 }
3964 }
3965}
3966
3967impl From<AssocItemKind> for ItemKind {
3968 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3969 match assoc_item_kind {
3970 AssocItemKind::Const(item) => ItemKind::Const(item),
3971 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3972 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3973 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3974 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3975 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3976 }
3977 }
3978}
3979
3980impl TryFrom<ItemKind> for AssocItemKind {
3981 type Error = ItemKind;
3982
3983 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3984 Ok(match item_kind {
3985 ItemKind::Const(item) => AssocItemKind::Const(item),
3986 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3987 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3988 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3989 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3990 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3991 _ => return Err(item_kind),
3992 })
3993 }
3994}
3995
3996#[derive(Clone, Encodable, Decodable, Debug)]
3998pub enum ForeignItemKind {
3999 Static(Box<StaticItem>),
4001 Fn(Box<Fn>),
4003 TyAlias(Box<TyAlias>),
4005 MacCall(Box<MacCall>),
4007}
4008
4009impl ForeignItemKind {
4010 pub fn ident(&self) -> Option<Ident> {
4011 match *self {
4012 ForeignItemKind::Static(box StaticItem { ident, .. })
4013 | ForeignItemKind::Fn(box Fn { ident, .. })
4014 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4015
4016 ForeignItemKind::MacCall(_) => None,
4017 }
4018 }
4019}
4020
4021impl From<ForeignItemKind> for ItemKind {
4022 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4023 match foreign_item_kind {
4024 ForeignItemKind::Static(box static_foreign_item) => {
4025 ItemKind::Static(Box::new(static_foreign_item))
4026 }
4027 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4028 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4029 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4030 }
4031 }
4032}
4033
4034impl TryFrom<ItemKind> for ForeignItemKind {
4035 type Error = ItemKind;
4036
4037 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4038 Ok(match item_kind {
4039 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4040 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4041 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4042 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4043 _ => return Err(item_kind),
4044 })
4045 }
4046}
4047
4048pub type ForeignItem = Item<ForeignItemKind>;
4049
4050#[cfg(target_pointer_width = "64")]
4052mod size_asserts {
4053 use rustc_data_structures::static_assert_size;
4054
4055 use super::*;
4056 static_assert_size!(AssocItem, 80);
4058 static_assert_size!(AssocItemKind, 16);
4059 static_assert_size!(Attribute, 32);
4060 static_assert_size!(Block, 32);
4061 static_assert_size!(Expr, 72);
4062 static_assert_size!(ExprKind, 40);
4063 static_assert_size!(Fn, 184);
4064 static_assert_size!(ForeignItem, 80);
4065 static_assert_size!(ForeignItemKind, 16);
4066 static_assert_size!(GenericArg, 24);
4067 static_assert_size!(GenericBound, 88);
4068 static_assert_size!(Generics, 40);
4069 static_assert_size!(Impl, 64);
4070 static_assert_size!(Item, 144);
4071 static_assert_size!(ItemKind, 80);
4072 static_assert_size!(LitKind, 24);
4073 static_assert_size!(Local, 96);
4074 static_assert_size!(MetaItemLit, 40);
4075 static_assert_size!(Param, 40);
4076 static_assert_size!(Pat, 80);
4077 static_assert_size!(PatKind, 56);
4078 static_assert_size!(Path, 24);
4079 static_assert_size!(PathSegment, 24);
4080 static_assert_size!(Stmt, 32);
4081 static_assert_size!(StmtKind, 16);
4082 static_assert_size!(TraitImplHeader, 80);
4083 static_assert_size!(Ty, 64);
4084 static_assert_size!(TyKind, 40);
4085 }