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::ptr::P;
39use crate::token::{self, CommentKind, Delimiter};
40use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
41use crate::util::parser::{ExprPrecedence, Fixity};
42use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
55pub struct Label {
56 pub ident: Ident,
57}
58
59impl fmt::Debug for Label {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "label({:?})", self.ident)
62 }
63}
64
65#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
68pub struct Lifetime {
69 pub id: NodeId,
70 pub ident: Ident,
71}
72
73impl fmt::Debug for Lifetime {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "lifetime({}: {})", self.id, self)
76 }
77}
78
79impl fmt::Display for Lifetime {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}", self.ident.name)
82 }
83}
84
85#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
102 #[inline]
103 fn eq(&self, name: &Symbol) -> bool {
104 if let [segment] = self.segments.as_ref()
105 && segment == name
106 {
107 true
108 } else {
109 false
110 }
111 }
112}
113
114impl PartialEq<&[Symbol]> for Path {
116 #[inline]
117 fn eq(&self, names: &&[Symbol]) -> bool {
118 self.segments.len() == names.len()
119 && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
120 }
121}
122
123impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
124 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
125 self.segments.len().hash_stable(hcx, hasher);
126 for segment in &self.segments {
127 segment.ident.hash_stable(hcx, hasher);
128 }
129 }
130}
131
132impl Path {
133 pub fn from_ident(ident: Ident) -> Path {
136 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
137 }
138
139 pub fn is_global(&self) -> bool {
140 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
141 }
142
143 #[tracing::instrument(level = "debug", ret)]
153 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
154 allow_mgca_arg
155 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
156 }
157}
158
159pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
171 let mut iter = path.into_iter();
176 let len_hint = iter.size_hint().1.unwrap_or(1);
177 let mut s = String::with_capacity(len_hint * 8);
178
179 let first_sym = *iter.next().unwrap().borrow();
180 if first_sym != kw::PathRoot {
181 s.push_str(first_sym.as_str());
182 }
183 for sym in iter {
184 let sym = *sym.borrow();
185 debug_assert_ne!(sym, kw::PathRoot);
186 s.push_str("::");
187 s.push_str(sym.as_str());
188 }
189 s
190}
191
192pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
195 let mut iter = path.into_iter();
196 let len_hint = iter.size_hint().1.unwrap_or(1);
197 let mut s = String::with_capacity(len_hint * 8);
198
199 let first_ident = *iter.next().unwrap().borrow();
200 if first_ident.name != kw::PathRoot {
201 s.push_str(&first_ident.to_string());
202 }
203 for ident in iter {
204 let ident = *ident.borrow();
205 debug_assert_ne!(ident.name, kw::PathRoot);
206 s.push_str("::");
207 s.push_str(&ident.to_string());
208 }
209 s
210}
211
212#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
216pub struct PathSegment {
217 pub ident: Ident,
219
220 pub id: NodeId,
221
222 pub args: Option<P<GenericArgs>>,
229}
230
231impl PartialEq<Symbol> for PathSegment {
233 #[inline]
234 fn eq(&self, name: &Symbol) -> bool {
235 self.args.is_none() && self.ident.name == *name
236 }
237}
238
239impl PathSegment {
240 pub fn from_ident(ident: Ident) -> Self {
241 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
242 }
243
244 pub fn path_root(span: Span) -> Self {
245 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
246 }
247
248 pub fn span(&self) -> Span {
249 match &self.args {
250 Some(args) => self.ident.span.to(args.span()),
251 None => self.ident.span,
252 }
253 }
254}
255
256#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
260pub enum GenericArgs {
261 AngleBracketed(AngleBracketedArgs),
263 Parenthesized(ParenthesizedArgs),
265 ParenthesizedElided(Span),
267}
268
269impl GenericArgs {
270 pub fn is_angle_bracketed(&self) -> bool {
271 matches!(self, AngleBracketed(..))
272 }
273
274 pub fn span(&self) -> Span {
275 match self {
276 AngleBracketed(data) => data.span,
277 Parenthesized(data) => data.span,
278 ParenthesizedElided(span) => *span,
279 }
280 }
281}
282
283#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
285pub enum GenericArg {
286 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
288 Type(P<Ty>),
290 Const(AnonConst),
292}
293
294impl GenericArg {
295 pub fn span(&self) -> Span {
296 match self {
297 GenericArg::Lifetime(lt) => lt.ident.span,
298 GenericArg::Type(ty) => ty.span,
299 GenericArg::Const(ct) => ct.value.span,
300 }
301 }
302}
303
304#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
306pub struct AngleBracketedArgs {
307 pub span: Span,
309 pub args: ThinVec<AngleBracketedArg>,
311}
312
313#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
315pub enum AngleBracketedArg {
316 Arg(GenericArg),
318 Constraint(AssocItemConstraint),
320}
321
322impl AngleBracketedArg {
323 pub fn span(&self) -> Span {
324 match self {
325 AngleBracketedArg::Arg(arg) => arg.span(),
326 AngleBracketedArg::Constraint(constraint) => constraint.span,
327 }
328 }
329}
330
331impl From<AngleBracketedArgs> for P<GenericArgs> {
332 fn from(val: AngleBracketedArgs) -> Self {
333 P(GenericArgs::AngleBracketed(val))
334 }
335}
336
337impl From<ParenthesizedArgs> for P<GenericArgs> {
338 fn from(val: ParenthesizedArgs) -> Self {
339 P(GenericArgs::Parenthesized(val))
340 }
341}
342
343#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
345pub struct ParenthesizedArgs {
346 pub span: Span,
351
352 pub inputs: ThinVec<P<Ty>>,
354
355 pub inputs_span: Span,
360
361 pub output: FnRetTy,
363}
364
365impl ParenthesizedArgs {
366 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
367 let args = self
368 .inputs
369 .iter()
370 .cloned()
371 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
372 .collect();
373 AngleBracketedArgs { span: self.inputs_span, args }
374 }
375}
376
377pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
378
379#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
381pub struct TraitBoundModifiers {
382 pub constness: BoundConstness,
383 pub asyncness: BoundAsyncness,
384 pub polarity: BoundPolarity,
385}
386
387impl TraitBoundModifiers {
388 pub const NONE: Self = Self {
389 constness: BoundConstness::Never,
390 asyncness: BoundAsyncness::Normal,
391 polarity: BoundPolarity::Positive,
392 };
393}
394
395#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
396pub enum GenericBound {
397 Trait(PolyTraitRef),
398 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
399 Use(ThinVec<PreciseCapturingArg>, Span),
401}
402
403impl GenericBound {
404 pub fn span(&self) -> Span {
405 match self {
406 GenericBound::Trait(t, ..) => t.span,
407 GenericBound::Outlives(l) => l.ident.span,
408 GenericBound::Use(_, span) => *span,
409 }
410 }
411}
412
413pub type GenericBounds = Vec<GenericBound>;
414
415#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
419pub enum ParamKindOrd {
420 Lifetime,
421 TypeOrConst,
422}
423
424impl fmt::Display for ParamKindOrd {
425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426 match self {
427 ParamKindOrd::Lifetime => "lifetime".fmt(f),
428 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
429 }
430 }
431}
432
433#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
434pub enum GenericParamKind {
435 Lifetime,
437 Type {
438 default: Option<P<Ty>>,
439 },
440 Const {
441 ty: P<Ty>,
442 span: Span,
444 default: Option<AnonConst>,
446 },
447}
448
449#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
450pub struct GenericParam {
451 pub id: NodeId,
452 pub ident: Ident,
453 pub attrs: AttrVec,
454 #[visitable(extra = BoundKind::Bound)]
455 pub bounds: GenericBounds,
456 pub is_placeholder: bool,
457 pub kind: GenericParamKind,
458 pub colon_span: Option<Span>,
459}
460
461impl GenericParam {
462 pub fn span(&self) -> Span {
463 match &self.kind {
464 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
465 self.ident.span
466 }
467 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
468 GenericParamKind::Const { span, .. } => *span,
469 }
470 }
471}
472
473#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
476pub struct Generics {
477 pub params: ThinVec<GenericParam>,
478 pub where_clause: WhereClause,
479 pub span: Span,
480}
481
482#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
484pub struct WhereClause {
485 pub has_where_token: bool,
490 pub predicates: ThinVec<WherePredicate>,
491 pub span: Span,
492}
493
494impl WhereClause {
495 pub fn is_empty(&self) -> bool {
496 !self.has_where_token && self.predicates.is_empty()
497 }
498}
499
500#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
502pub struct WherePredicate {
503 pub attrs: AttrVec,
504 pub kind: WherePredicateKind,
505 pub id: NodeId,
506 pub span: Span,
507 pub is_placeholder: bool,
508}
509
510#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
512pub enum WherePredicateKind {
513 BoundPredicate(WhereBoundPredicate),
515 RegionPredicate(WhereRegionPredicate),
517 EqPredicate(WhereEqPredicate),
519}
520
521#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
525pub struct WhereBoundPredicate {
526 pub bound_generic_params: ThinVec<GenericParam>,
528 pub bounded_ty: P<Ty>,
530 #[visitable(extra = BoundKind::Bound)]
532 pub bounds: GenericBounds,
533}
534
535#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
539pub struct WhereRegionPredicate {
540 #[visitable(extra = LifetimeCtxt::Bound)]
541 pub lifetime: Lifetime,
542 #[visitable(extra = BoundKind::Bound)]
543 pub bounds: GenericBounds,
544}
545
546#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
550pub struct WhereEqPredicate {
551 pub lhs_ty: P<Ty>,
552 pub rhs_ty: P<Ty>,
553}
554
555#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
556pub struct Crate {
557 pub id: NodeId,
560 pub attrs: AttrVec,
561 pub items: ThinVec<P<Item>>,
562 pub spans: ModSpans,
563 pub is_placeholder: bool,
564}
565
566#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
573pub struct MetaItem {
574 pub unsafety: Safety,
575 pub path: Path,
576 pub kind: MetaItemKind,
577 pub span: Span,
578}
579
580#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
582pub enum MetaItemKind {
583 Word,
587
588 List(ThinVec<MetaItemInner>),
592
593 NameValue(MetaItemLit),
597}
598
599#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
603pub enum MetaItemInner {
604 MetaItem(MetaItem),
606
607 Lit(MetaItemLit),
611}
612
613#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
617pub struct Block {
618 pub stmts: ThinVec<Stmt>,
620 pub id: NodeId,
621 pub rules: BlockCheckMode,
623 pub span: Span,
624 pub tokens: Option<LazyAttrTokenStream>,
625}
626
627#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
631pub struct Pat {
632 pub id: NodeId,
633 pub kind: PatKind,
634 pub span: Span,
635 pub tokens: Option<LazyAttrTokenStream>,
636}
637
638impl Pat {
639 pub fn to_ty(&self) -> Option<P<Ty>> {
642 let kind = match &self.kind {
643 PatKind::Missing => unreachable!(),
644 PatKind::Wild => TyKind::Infer,
646 PatKind::Ident(BindingMode::NONE, ident, None) => {
648 TyKind::Path(None, Path::from_ident(*ident))
649 }
650 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
651 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
652 PatKind::Ref(pat, mutbl) => {
654 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
655 }
656 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
659 pat.to_ty().map(TyKind::Slice)?
660 }
661 PatKind::Tuple(pats) => {
664 let mut tys = ThinVec::with_capacity(pats.len());
665 for pat in pats {
667 tys.push(pat.to_ty()?);
668 }
669 TyKind::Tup(tys)
670 }
671 _ => return None,
672 };
673
674 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
675 }
676
677 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
681 if !it(self) {
682 return;
683 }
684
685 match &self.kind {
686 PatKind::Ident(_, _, Some(p)) => p.walk(it),
688
689 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
691
692 PatKind::TupleStruct(_, _, s)
694 | PatKind::Tuple(s)
695 | PatKind::Slice(s)
696 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
697
698 PatKind::Box(s)
700 | PatKind::Deref(s)
701 | PatKind::Ref(s, _)
702 | PatKind::Paren(s)
703 | PatKind::Guard(s, _) => s.walk(it),
704
705 PatKind::Missing
707 | PatKind::Wild
708 | PatKind::Rest
709 | PatKind::Never
710 | PatKind::Expr(_)
711 | PatKind::Range(..)
712 | PatKind::Ident(..)
713 | PatKind::Path(..)
714 | PatKind::MacCall(_)
715 | PatKind::Err(_) => {}
716 }
717 }
718
719 pub fn is_rest(&self) -> bool {
721 matches!(self.kind, PatKind::Rest)
722 }
723
724 pub fn could_be_never_pattern(&self) -> bool {
727 let mut could_be_never_pattern = false;
728 self.walk(&mut |pat| match &pat.kind {
729 PatKind::Never | PatKind::MacCall(_) => {
730 could_be_never_pattern = true;
731 false
732 }
733 PatKind::Or(s) => {
734 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
735 false
736 }
737 _ => true,
738 });
739 could_be_never_pattern
740 }
741
742 pub fn contains_never_pattern(&self) -> bool {
745 let mut contains_never_pattern = false;
746 self.walk(&mut |pat| {
747 if matches!(pat.kind, PatKind::Never) {
748 contains_never_pattern = true;
749 }
750 true
751 });
752 contains_never_pattern
753 }
754
755 pub fn descr(&self) -> Option<String> {
757 match &self.kind {
758 PatKind::Missing => unreachable!(),
759 PatKind::Wild => Some("_".to_string()),
760 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
761 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
762 _ => None,
763 }
764 }
765}
766
767impl From<P<Pat>> for Pat {
768 fn from(value: P<Pat>) -> Self {
769 *value
770 }
771}
772
773#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
779pub struct PatField {
780 pub ident: Ident,
782 pub pat: P<Pat>,
784 pub is_shorthand: bool,
785 pub attrs: AttrVec,
786 pub id: NodeId,
787 pub span: Span,
788 pub is_placeholder: bool,
789}
790
791#[derive(Clone, Copy, Debug, Eq, PartialEq)]
792#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
793pub enum ByRef {
794 Yes(Mutability),
795 No,
796}
797
798impl ByRef {
799 #[must_use]
800 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
801 if let ByRef::Yes(old_mutbl) = &mut self {
802 *old_mutbl = cmp::min(*old_mutbl, mutbl);
803 }
804 self
805 }
806}
807
808#[derive(Clone, Copy, Debug, Eq, PartialEq)]
814#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
815pub struct BindingMode(pub ByRef, pub Mutability);
816
817impl BindingMode {
818 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
819 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
820 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
821 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
822 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
823 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
824
825 pub fn prefix_str(self) -> &'static str {
826 match self {
827 Self::NONE => "",
828 Self::REF => "ref ",
829 Self::MUT => "mut ",
830 Self::REF_MUT => "ref mut ",
831 Self::MUT_REF => "mut ref ",
832 Self::MUT_REF_MUT => "mut ref mut ",
833 }
834 }
835}
836
837#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
838pub enum RangeEnd {
839 Included(RangeSyntax),
841 Excluded,
843}
844
845#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
846pub enum RangeSyntax {
847 DotDotDot,
849 DotDotEq,
851}
852
853#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
857pub enum PatKind {
858 Missing,
860
861 Wild,
863
864 Ident(BindingMode, Ident, Option<P<Pat>>),
869
870 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
872
873 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
875
876 Or(ThinVec<P<Pat>>),
879
880 Path(Option<P<QSelf>>, Path),
885
886 Tuple(ThinVec<P<Pat>>),
888
889 Box(P<Pat>),
891
892 Deref(P<Pat>),
894
895 Ref(P<Pat>, Mutability),
897
898 Expr(P<Expr>),
900
901 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
903
904 Slice(ThinVec<P<Pat>>),
906
907 Rest,
920
921 Never,
923
924 Guard(P<Pat>, P<Expr>),
926
927 Paren(P<Pat>),
929
930 MacCall(P<MacCall>),
932
933 Err(ErrorGuaranteed),
935}
936
937#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
939pub enum PatFieldsRest {
940 Rest,
942 Recovered(ErrorGuaranteed),
944 None,
946}
947
948#[derive(Clone, Copy, PartialEq, Eq, Debug)]
951#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
952pub enum BorrowKind {
953 Ref,
957 Raw,
961 Pin,
965}
966
967#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
968pub enum BinOpKind {
969 Add,
971 Sub,
973 Mul,
975 Div,
977 Rem,
979 And,
981 Or,
983 BitXor,
985 BitAnd,
987 BitOr,
989 Shl,
991 Shr,
993 Eq,
995 Lt,
997 Le,
999 Ne,
1001 Ge,
1003 Gt,
1005}
1006
1007impl BinOpKind {
1008 pub fn as_str(&self) -> &'static str {
1009 use BinOpKind::*;
1010 match self {
1011 Add => "+",
1012 Sub => "-",
1013 Mul => "*",
1014 Div => "/",
1015 Rem => "%",
1016 And => "&&",
1017 Or => "||",
1018 BitXor => "^",
1019 BitAnd => "&",
1020 BitOr => "|",
1021 Shl => "<<",
1022 Shr => ">>",
1023 Eq => "==",
1024 Lt => "<",
1025 Le => "<=",
1026 Ne => "!=",
1027 Ge => ">=",
1028 Gt => ">",
1029 }
1030 }
1031
1032 pub fn is_lazy(&self) -> bool {
1033 matches!(self, BinOpKind::And | BinOpKind::Or)
1034 }
1035
1036 pub fn precedence(&self) -> ExprPrecedence {
1037 use BinOpKind::*;
1038 match *self {
1039 Mul | Div | Rem => ExprPrecedence::Product,
1040 Add | Sub => ExprPrecedence::Sum,
1041 Shl | Shr => ExprPrecedence::Shift,
1042 BitAnd => ExprPrecedence::BitAnd,
1043 BitXor => ExprPrecedence::BitXor,
1044 BitOr => ExprPrecedence::BitOr,
1045 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1046 And => ExprPrecedence::LAnd,
1047 Or => ExprPrecedence::LOr,
1048 }
1049 }
1050
1051 pub fn fixity(&self) -> Fixity {
1052 use BinOpKind::*;
1053 match self {
1054 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1055 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1056 Fixity::Left
1057 }
1058 }
1059 }
1060
1061 pub fn is_comparison(self) -> bool {
1062 use BinOpKind::*;
1063 match self {
1064 Eq | Ne | Lt | Le | Gt | Ge => true,
1065 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1066 }
1067 }
1068
1069 pub fn is_by_value(self) -> bool {
1071 !self.is_comparison()
1072 }
1073}
1074
1075pub type BinOp = Spanned<BinOpKind>;
1076
1077impl From<AssignOpKind> for BinOpKind {
1081 fn from(op: AssignOpKind) -> BinOpKind {
1082 match op {
1083 AssignOpKind::AddAssign => BinOpKind::Add,
1084 AssignOpKind::SubAssign => BinOpKind::Sub,
1085 AssignOpKind::MulAssign => BinOpKind::Mul,
1086 AssignOpKind::DivAssign => BinOpKind::Div,
1087 AssignOpKind::RemAssign => BinOpKind::Rem,
1088 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1089 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1090 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1091 AssignOpKind::ShlAssign => BinOpKind::Shl,
1092 AssignOpKind::ShrAssign => BinOpKind::Shr,
1093 }
1094 }
1095}
1096
1097#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1098pub enum AssignOpKind {
1099 AddAssign,
1101 SubAssign,
1103 MulAssign,
1105 DivAssign,
1107 RemAssign,
1109 BitXorAssign,
1111 BitAndAssign,
1113 BitOrAssign,
1115 ShlAssign,
1117 ShrAssign,
1119}
1120
1121impl AssignOpKind {
1122 pub fn as_str(&self) -> &'static str {
1123 use AssignOpKind::*;
1124 match self {
1125 AddAssign => "+=",
1126 SubAssign => "-=",
1127 MulAssign => "*=",
1128 DivAssign => "/=",
1129 RemAssign => "%=",
1130 BitXorAssign => "^=",
1131 BitAndAssign => "&=",
1132 BitOrAssign => "|=",
1133 ShlAssign => "<<=",
1134 ShrAssign => ">>=",
1135 }
1136 }
1137
1138 pub fn is_by_value(self) -> bool {
1140 true
1141 }
1142}
1143
1144pub type AssignOp = Spanned<AssignOpKind>;
1145
1146#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1150pub enum UnOp {
1151 Deref,
1153 Not,
1155 Neg,
1157}
1158
1159impl UnOp {
1160 pub fn as_str(&self) -> &'static str {
1161 match self {
1162 UnOp::Deref => "*",
1163 UnOp::Not => "!",
1164 UnOp::Neg => "-",
1165 }
1166 }
1167
1168 pub fn is_by_value(self) -> bool {
1170 matches!(self, Self::Neg | Self::Not)
1171 }
1172}
1173
1174#[derive(Clone, Encodable, Decodable, Debug)]
1178pub struct Stmt {
1179 pub id: NodeId,
1180 pub kind: StmtKind,
1181 pub span: Span,
1182}
1183
1184impl Stmt {
1185 pub fn has_trailing_semicolon(&self) -> bool {
1186 match &self.kind {
1187 StmtKind::Semi(_) => true,
1188 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1189 _ => false,
1190 }
1191 }
1192
1193 pub fn add_trailing_semicolon(mut self) -> Self {
1201 self.kind = match self.kind {
1202 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1203 StmtKind::MacCall(mut mac) => {
1204 mac.style = MacStmtStyle::Semicolon;
1205 StmtKind::MacCall(mac)
1206 }
1207 kind => kind,
1208 };
1209
1210 self
1211 }
1212
1213 pub fn is_item(&self) -> bool {
1214 matches!(self.kind, StmtKind::Item(_))
1215 }
1216
1217 pub fn is_expr(&self) -> bool {
1218 matches!(self.kind, StmtKind::Expr(_))
1219 }
1220}
1221
1222#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1224pub enum StmtKind {
1225 Let(P<Local>),
1227 Item(P<Item>),
1229 Expr(P<Expr>),
1231 Semi(P<Expr>),
1233 Empty,
1235 MacCall(P<MacCallStmt>),
1237}
1238
1239#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1240pub struct MacCallStmt {
1241 pub mac: P<MacCall>,
1242 pub style: MacStmtStyle,
1243 pub attrs: AttrVec,
1244 pub tokens: Option<LazyAttrTokenStream>,
1245}
1246
1247#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1248pub enum MacStmtStyle {
1249 Semicolon,
1252 Braces,
1254 NoBraces,
1258}
1259
1260#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1262pub struct Local {
1263 pub id: NodeId,
1264 pub super_: Option<Span>,
1265 pub pat: P<Pat>,
1266 pub ty: Option<P<Ty>>,
1267 pub kind: LocalKind,
1268 pub span: Span,
1269 pub colon_sp: Option<Span>,
1270 pub attrs: AttrVec,
1271 pub tokens: Option<LazyAttrTokenStream>,
1272}
1273
1274#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1275pub enum LocalKind {
1276 Decl,
1279 Init(P<Expr>),
1282 InitElse(P<Expr>, P<Block>),
1285}
1286
1287impl LocalKind {
1288 pub fn init(&self) -> Option<&Expr> {
1289 match self {
1290 Self::Decl => None,
1291 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1292 }
1293 }
1294
1295 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1296 match self {
1297 Self::Decl => None,
1298 Self::Init(init) => Some((init, None)),
1299 Self::InitElse(init, els) => Some((init, Some(els))),
1300 }
1301 }
1302}
1303
1304#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1315pub struct Arm {
1316 pub attrs: AttrVec,
1317 pub pat: P<Pat>,
1319 pub guard: Option<P<Expr>>,
1321 pub body: Option<P<Expr>>,
1323 pub span: Span,
1324 pub id: NodeId,
1325 pub is_placeholder: bool,
1326}
1327
1328#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1330pub struct ExprField {
1331 pub attrs: AttrVec,
1332 pub id: NodeId,
1333 pub span: Span,
1334 pub ident: Ident,
1335 pub expr: P<Expr>,
1336 pub is_shorthand: bool,
1337 pub is_placeholder: bool,
1338}
1339
1340#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1341pub enum BlockCheckMode {
1342 Default,
1343 Unsafe(UnsafeSource),
1344}
1345
1346#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1347pub enum UnsafeSource {
1348 CompilerGenerated,
1349 UserProvided,
1350}
1351
1352#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1358pub struct AnonConst {
1359 pub id: NodeId,
1360 pub value: P<Expr>,
1361}
1362
1363#[derive(Clone, Encodable, Decodable, Debug)]
1365pub struct Expr {
1366 pub id: NodeId,
1367 pub kind: ExprKind,
1368 pub span: Span,
1369 pub attrs: AttrVec,
1370 pub tokens: Option<LazyAttrTokenStream>,
1371}
1372
1373impl Expr {
1374 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1388 let this = self.maybe_unwrap_block();
1389 if allow_mgca_arg {
1390 matches!(this.kind, ExprKind::Path(..))
1391 } else {
1392 if let ExprKind::Path(None, path) = &this.kind
1393 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1394 {
1395 true
1396 } else {
1397 false
1398 }
1399 }
1400 }
1401
1402 pub fn maybe_unwrap_block(&self) -> &Expr {
1404 if let ExprKind::Block(block, None) = &self.kind
1405 && let [stmt] = block.stmts.as_slice()
1406 && let StmtKind::Expr(expr) = &stmt.kind
1407 {
1408 expr
1409 } else {
1410 self
1411 }
1412 }
1413
1414 pub fn optionally_braced_mac_call(
1420 &self,
1421 already_stripped_block: bool,
1422 ) -> Option<(bool, NodeId)> {
1423 match &self.kind {
1424 ExprKind::Block(block, None)
1425 if let [stmt] = &*block.stmts
1426 && !already_stripped_block =>
1427 {
1428 match &stmt.kind {
1429 StmtKind::MacCall(_) => Some((true, stmt.id)),
1430 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1431 Some((true, expr.id))
1432 }
1433 _ => None,
1434 }
1435 }
1436 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1437 _ => None,
1438 }
1439 }
1440
1441 pub fn to_bound(&self) -> Option<GenericBound> {
1442 match &self.kind {
1443 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1444 ThinVec::new(),
1445 path.clone(),
1446 TraitBoundModifiers::NONE,
1447 self.span,
1448 Parens::No,
1449 ))),
1450 _ => None,
1451 }
1452 }
1453
1454 pub fn peel_parens(&self) -> &Expr {
1455 let mut expr = self;
1456 while let ExprKind::Paren(inner) = &expr.kind {
1457 expr = inner;
1458 }
1459 expr
1460 }
1461
1462 pub fn peel_parens_and_refs(&self) -> &Expr {
1463 let mut expr = self;
1464 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1465 {
1466 expr = inner;
1467 }
1468 expr
1469 }
1470
1471 pub fn to_ty(&self) -> Option<P<Ty>> {
1473 let kind = match &self.kind {
1474 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1476 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1477
1478 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1479
1480 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1481 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1482 }
1483
1484 ExprKind::Repeat(expr, expr_len) => {
1485 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1486 }
1487
1488 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1489 expr.to_ty().map(TyKind::Slice)?
1490 }
1491
1492 ExprKind::Tup(exprs) => {
1493 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1494 TyKind::Tup(tys)
1495 }
1496
1497 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1501 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1502 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1503 } else {
1504 return None;
1505 }
1506 }
1507
1508 ExprKind::Underscore => TyKind::Infer,
1509
1510 _ => return None,
1512 };
1513
1514 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1515 }
1516
1517 pub fn precedence(&self) -> ExprPrecedence {
1518 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1519 for attr in attrs {
1520 if let AttrStyle::Outer = attr.style {
1521 return ExprPrecedence::Prefix;
1522 }
1523 }
1524 ExprPrecedence::Unambiguous
1525 }
1526
1527 match &self.kind {
1528 ExprKind::Closure(closure) => {
1529 match closure.fn_decl.output {
1530 FnRetTy::Default(_) => ExprPrecedence::Jump,
1531 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1532 }
1533 }
1534
1535 ExprKind::Break(_ , value)
1536 | ExprKind::Ret(value)
1537 | ExprKind::Yield(YieldKind::Prefix(value))
1538 | ExprKind::Yeet(value) => match value {
1539 Some(_) => ExprPrecedence::Jump,
1540 None => prefix_attrs_precedence(&self.attrs),
1541 },
1542
1543 ExprKind::Become(_) => ExprPrecedence::Jump,
1544
1545 ExprKind::Range(..) => ExprPrecedence::Range,
1550
1551 ExprKind::Binary(op, ..) => op.node.precedence(),
1553 ExprKind::Cast(..) => ExprPrecedence::Cast,
1554
1555 ExprKind::Assign(..) |
1556 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1557
1558 ExprKind::AddrOf(..)
1560 | ExprKind::Let(..)
1565 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1566
1567 ExprKind::Array(_)
1569 | ExprKind::Await(..)
1570 | ExprKind::Use(..)
1571 | ExprKind::Block(..)
1572 | ExprKind::Call(..)
1573 | ExprKind::ConstBlock(_)
1574 | ExprKind::Continue(..)
1575 | ExprKind::Field(..)
1576 | ExprKind::ForLoop { .. }
1577 | ExprKind::FormatArgs(..)
1578 | ExprKind::Gen(..)
1579 | ExprKind::If(..)
1580 | ExprKind::IncludedBytes(..)
1581 | ExprKind::Index(..)
1582 | ExprKind::InlineAsm(..)
1583 | ExprKind::Lit(_)
1584 | ExprKind::Loop(..)
1585 | ExprKind::MacCall(..)
1586 | ExprKind::Match(..)
1587 | ExprKind::MethodCall(..)
1588 | ExprKind::OffsetOf(..)
1589 | ExprKind::Paren(..)
1590 | ExprKind::Path(..)
1591 | ExprKind::Repeat(..)
1592 | ExprKind::Struct(..)
1593 | ExprKind::Try(..)
1594 | ExprKind::TryBlock(..)
1595 | ExprKind::Tup(_)
1596 | ExprKind::Type(..)
1597 | ExprKind::Underscore
1598 | ExprKind::UnsafeBinderCast(..)
1599 | ExprKind::While(..)
1600 | ExprKind::Yield(YieldKind::Postfix(..))
1601 | ExprKind::Err(_)
1602 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1603 }
1604 }
1605
1606 pub fn is_approximately_pattern(&self) -> bool {
1608 matches!(
1609 &self.peel_parens().kind,
1610 ExprKind::Array(_)
1611 | ExprKind::Call(_, _)
1612 | ExprKind::Tup(_)
1613 | ExprKind::Lit(_)
1614 | ExprKind::Range(_, _, _)
1615 | ExprKind::Underscore
1616 | ExprKind::Path(_, _)
1617 | ExprKind::Struct(_)
1618 )
1619 }
1620
1621 pub fn dummy() -> Expr {
1625 Expr {
1626 id: DUMMY_NODE_ID,
1627 kind: ExprKind::Dummy,
1628 span: DUMMY_SP,
1629 attrs: ThinVec::new(),
1630 tokens: None,
1631 }
1632 }
1633}
1634
1635impl From<P<Expr>> for Expr {
1636 fn from(value: P<Expr>) -> Self {
1637 *value
1638 }
1639}
1640
1641#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1642pub struct Closure {
1643 pub binder: ClosureBinder,
1644 pub capture_clause: CaptureBy,
1645 pub constness: Const,
1646 pub coroutine_kind: Option<CoroutineKind>,
1647 pub movability: Movability,
1648 pub fn_decl: P<FnDecl>,
1649 pub body: P<Expr>,
1650 pub fn_decl_span: Span,
1652 pub fn_arg_span: Span,
1654}
1655
1656#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1658pub enum RangeLimits {
1659 HalfOpen,
1661 Closed,
1663}
1664
1665impl RangeLimits {
1666 pub fn as_str(&self) -> &'static str {
1667 match self {
1668 RangeLimits::HalfOpen => "..",
1669 RangeLimits::Closed => "..=",
1670 }
1671 }
1672}
1673
1674#[derive(Clone, Encodable, Decodable, Debug)]
1676pub struct MethodCall {
1677 pub seg: PathSegment,
1679 pub receiver: P<Expr>,
1681 pub args: ThinVec<P<Expr>>,
1683 pub span: Span,
1686}
1687
1688#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1689pub enum StructRest {
1690 Base(P<Expr>),
1692 Rest(Span),
1694 None,
1696}
1697
1698#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1699pub struct StructExpr {
1700 pub qself: Option<P<QSelf>>,
1701 pub path: Path,
1702 pub fields: ThinVec<ExprField>,
1703 pub rest: StructRest,
1704}
1705
1706#[derive(Clone, Encodable, Decodable, Debug)]
1708pub enum ExprKind {
1709 Array(ThinVec<P<Expr>>),
1711 ConstBlock(AnonConst),
1713 Call(P<Expr>, ThinVec<P<Expr>>),
1720 MethodCall(Box<MethodCall>),
1722 Tup(ThinVec<P<Expr>>),
1724 Binary(BinOp, P<Expr>, P<Expr>),
1726 Unary(UnOp, P<Expr>),
1728 Lit(token::Lit),
1730 Cast(P<Expr>, P<Ty>),
1732 Type(P<Expr>, P<Ty>),
1737 Let(P<Pat>, P<Expr>, Span, Recovered),
1742 If(P<Expr>, P<Block>, Option<P<Expr>>),
1749 While(P<Expr>, P<Block>, Option<Label>),
1753 ForLoop {
1759 pat: P<Pat>,
1760 iter: P<Expr>,
1761 body: P<Block>,
1762 label: Option<Label>,
1763 kind: ForLoopKind,
1764 },
1765 Loop(P<Block>, Option<Label>, Span),
1769 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1771 Closure(Box<Closure>),
1773 Block(P<Block>, Option<Label>),
1775 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1781 Await(P<Expr>, Span),
1783 Use(P<Expr>, Span),
1785
1786 TryBlock(P<Block>),
1788
1789 Assign(P<Expr>, P<Expr>, Span),
1792 AssignOp(AssignOp, P<Expr>, P<Expr>),
1796 Field(P<Expr>, Ident),
1798 Index(P<Expr>, P<Expr>, Span),
1801 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1803 Underscore,
1805
1806 Path(Option<P<QSelf>>, Path),
1811
1812 AddrOf(BorrowKind, Mutability, P<Expr>),
1814 Break(Option<Label>, Option<P<Expr>>),
1816 Continue(Option<Label>),
1818 Ret(Option<P<Expr>>),
1820
1821 InlineAsm(P<InlineAsm>),
1823
1824 OffsetOf(P<Ty>, Vec<Ident>),
1829
1830 MacCall(P<MacCall>),
1832
1833 Struct(P<StructExpr>),
1837
1838 Repeat(P<Expr>, AnonConst),
1843
1844 Paren(P<Expr>),
1846
1847 Try(P<Expr>),
1849
1850 Yield(YieldKind),
1852
1853 Yeet(Option<P<Expr>>),
1856
1857 Become(P<Expr>),
1861
1862 IncludedBytes(ByteSymbol),
1874
1875 FormatArgs(P<FormatArgs>),
1877
1878 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1879
1880 Err(ErrorGuaranteed),
1882
1883 Dummy,
1885}
1886
1887#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1889pub enum ForLoopKind {
1890 For,
1891 ForAwait,
1892}
1893
1894#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1896pub enum GenBlockKind {
1897 Async,
1898 Gen,
1899 AsyncGen,
1900}
1901
1902impl fmt::Display for GenBlockKind {
1903 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1904 self.modifier().fmt(f)
1905 }
1906}
1907
1908impl GenBlockKind {
1909 pub fn modifier(&self) -> &'static str {
1910 match self {
1911 GenBlockKind::Async => "async",
1912 GenBlockKind::Gen => "gen",
1913 GenBlockKind::AsyncGen => "async gen",
1914 }
1915 }
1916}
1917
1918#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1920#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1921pub enum UnsafeBinderCastKind {
1922 Wrap,
1924 Unwrap,
1926}
1927
1928#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1943pub struct QSelf {
1944 pub ty: P<Ty>,
1945
1946 pub path_span: Span,
1950 pub position: usize,
1951}
1952
1953#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1955pub enum CaptureBy {
1956 Value {
1958 move_kw: Span,
1960 },
1961 Ref,
1963 Use {
1969 use_kw: Span,
1971 },
1972}
1973
1974#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1976pub enum ClosureBinder {
1977 NotPresent,
1979 For {
1981 span: Span,
1988
1989 generic_params: ThinVec<GenericParam>,
1996 },
1997}
1998
1999#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2002pub struct MacCall {
2003 pub path: Path,
2004 pub args: P<DelimArgs>,
2005}
2006
2007impl MacCall {
2008 pub fn span(&self) -> Span {
2009 self.path.span.to(self.args.dspan.entire())
2010 }
2011}
2012
2013#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2015pub enum AttrArgs {
2016 Empty,
2018 Delimited(DelimArgs),
2020 Eq {
2022 eq_span: Span,
2024 expr: P<Expr>,
2025 },
2026}
2027
2028impl AttrArgs {
2029 pub fn span(&self) -> Option<Span> {
2030 match self {
2031 AttrArgs::Empty => None,
2032 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2033 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2034 }
2035 }
2036
2037 pub fn inner_tokens(&self) -> TokenStream {
2040 match self {
2041 AttrArgs::Empty => TokenStream::default(),
2042 AttrArgs::Delimited(args) => args.tokens.clone(),
2043 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2044 }
2045 }
2046}
2047
2048#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2050pub struct DelimArgs {
2051 pub dspan: DelimSpan,
2052 pub delim: Delimiter, pub tokens: TokenStream,
2054}
2055
2056impl DelimArgs {
2057 pub fn need_semicolon(&self) -> bool {
2060 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2061 }
2062}
2063
2064#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2066pub struct MacroDef {
2067 pub body: P<DelimArgs>,
2068 pub macro_rules: bool,
2070}
2071
2072#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2073#[derive(HashStable_Generic, Walkable)]
2074pub enum StrStyle {
2075 Cooked,
2077 Raw(u8),
2081}
2082
2083#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2085pub enum MatchKind {
2086 Prefix,
2088 Postfix,
2090}
2091
2092#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2094pub enum YieldKind {
2095 Prefix(Option<P<Expr>>),
2097 Postfix(P<Expr>),
2099}
2100
2101impl YieldKind {
2102 pub const fn expr(&self) -> Option<&P<Expr>> {
2106 match self {
2107 YieldKind::Prefix(expr) => expr.as_ref(),
2108 YieldKind::Postfix(expr) => Some(expr),
2109 }
2110 }
2111
2112 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2114 match self {
2115 YieldKind::Prefix(expr) => expr.as_mut(),
2116 YieldKind::Postfix(expr) => Some(expr),
2117 }
2118 }
2119
2120 pub const fn same_kind(&self, other: &Self) -> bool {
2122 match (self, other) {
2123 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2124 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2125 _ => false,
2126 }
2127 }
2128}
2129
2130#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2132pub struct MetaItemLit {
2133 pub symbol: Symbol,
2135 pub suffix: Option<Symbol>,
2137 pub kind: LitKind,
2140 pub span: Span,
2141}
2142
2143#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2145pub struct StrLit {
2146 pub symbol: Symbol,
2148 pub suffix: Option<Symbol>,
2150 pub symbol_unescaped: Symbol,
2152 pub style: StrStyle,
2153 pub span: Span,
2154}
2155
2156impl StrLit {
2157 pub fn as_token_lit(&self) -> token::Lit {
2158 let token_kind = match self.style {
2159 StrStyle::Cooked => token::Str,
2160 StrStyle::Raw(n) => token::StrRaw(n),
2161 };
2162 token::Lit::new(token_kind, self.symbol, self.suffix)
2163 }
2164}
2165
2166#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2168#[derive(HashStable_Generic)]
2169pub enum LitIntType {
2170 Signed(IntTy),
2172 Unsigned(UintTy),
2174 Unsuffixed,
2176}
2177
2178#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2180#[derive(HashStable_Generic)]
2181pub enum LitFloatType {
2182 Suffixed(FloatTy),
2184 Unsuffixed,
2186}
2187
2188#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2195pub enum LitKind {
2196 Str(Symbol, StrStyle),
2199 ByteStr(ByteSymbol, StrStyle),
2202 CStr(ByteSymbol, StrStyle),
2206 Byte(u8),
2208 Char(char),
2210 Int(Pu128, LitIntType),
2212 Float(Symbol, LitFloatType),
2216 Bool(bool),
2218 Err(ErrorGuaranteed),
2220}
2221
2222impl LitKind {
2223 pub fn str(&self) -> Option<Symbol> {
2224 match *self {
2225 LitKind::Str(s, _) => Some(s),
2226 _ => None,
2227 }
2228 }
2229
2230 pub fn is_str(&self) -> bool {
2232 matches!(self, LitKind::Str(..))
2233 }
2234
2235 pub fn is_bytestr(&self) -> bool {
2237 matches!(self, LitKind::ByteStr(..))
2238 }
2239
2240 pub fn is_numeric(&self) -> bool {
2242 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2243 }
2244
2245 pub fn is_unsuffixed(&self) -> bool {
2248 !self.is_suffixed()
2249 }
2250
2251 pub fn is_suffixed(&self) -> bool {
2253 match *self {
2254 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2256 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2257 LitKind::Str(..)
2259 | LitKind::ByteStr(..)
2260 | LitKind::CStr(..)
2261 | LitKind::Byte(..)
2262 | LitKind::Char(..)
2263 | LitKind::Int(_, LitIntType::Unsuffixed)
2264 | LitKind::Float(_, LitFloatType::Unsuffixed)
2265 | LitKind::Bool(..)
2266 | LitKind::Err(_) => false,
2267 }
2268 }
2269}
2270
2271#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2274pub struct MutTy {
2275 pub ty: P<Ty>,
2276 pub mutbl: Mutability,
2277}
2278
2279#[derive(Clone, Encodable, Decodable, Debug)]
2282pub struct FnSig {
2283 pub header: FnHeader,
2284 pub decl: P<FnDecl>,
2285 pub span: Span,
2286}
2287
2288#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2299pub struct AssocItemConstraint {
2300 pub id: NodeId,
2301 pub ident: Ident,
2302 pub gen_args: Option<GenericArgs>,
2303 pub kind: AssocItemConstraintKind,
2304 pub span: Span,
2305}
2306
2307#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2308pub enum Term {
2309 Ty(P<Ty>),
2310 Const(AnonConst),
2311}
2312
2313impl From<P<Ty>> for Term {
2314 fn from(v: P<Ty>) -> Self {
2315 Term::Ty(v)
2316 }
2317}
2318
2319impl From<AnonConst> for Term {
2320 fn from(v: AnonConst) -> Self {
2321 Term::Const(v)
2322 }
2323}
2324
2325#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2327pub enum AssocItemConstraintKind {
2328 Equality { term: Term },
2335 Bound {
2337 #[visitable(extra = BoundKind::Bound)]
2338 bounds: GenericBounds,
2339 },
2340}
2341
2342#[derive(Encodable, Decodable, Debug, Walkable)]
2343pub struct Ty {
2344 pub id: NodeId,
2345 pub kind: TyKind,
2346 pub span: Span,
2347 pub tokens: Option<LazyAttrTokenStream>,
2348}
2349
2350impl Clone for Ty {
2351 fn clone(&self) -> Self {
2352 ensure_sufficient_stack(|| Self {
2353 id: self.id,
2354 kind: self.kind.clone(),
2355 span: self.span,
2356 tokens: self.tokens.clone(),
2357 })
2358 }
2359}
2360
2361impl From<P<Ty>> for Ty {
2362 fn from(value: P<Ty>) -> Self {
2363 *value
2364 }
2365}
2366
2367impl Ty {
2368 pub fn peel_refs(&self) -> &Self {
2369 let mut final_ty = self;
2370 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2371 {
2372 final_ty = ty;
2373 }
2374 final_ty
2375 }
2376
2377 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2378 match &self.kind {
2379 TyKind::Infer => true,
2380 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2381 _ => false,
2382 }
2383 }
2384}
2385
2386#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2387pub struct FnPtrTy {
2388 pub safety: Safety,
2389 pub ext: Extern,
2390 pub generic_params: ThinVec<GenericParam>,
2391 pub decl: P<FnDecl>,
2392 pub decl_span: Span,
2395}
2396
2397#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2398pub struct UnsafeBinderTy {
2399 pub generic_params: ThinVec<GenericParam>,
2400 pub inner_ty: P<Ty>,
2401}
2402
2403#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2407pub enum TyKind {
2408 Slice(P<Ty>),
2410 Array(P<Ty>, AnonConst),
2412 Ptr(MutTy),
2414 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2416 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2420 FnPtr(P<FnPtrTy>),
2422 UnsafeBinder(P<UnsafeBinderTy>),
2424 Never,
2426 Tup(ThinVec<P<Ty>>),
2428 Path(Option<P<QSelf>>, Path),
2433 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2436 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2443 Paren(P<Ty>),
2445 Typeof(AnonConst),
2447 Infer,
2450 ImplicitSelf,
2452 MacCall(P<MacCall>),
2454 CVarArgs,
2456 Pat(P<Ty>, P<TyPat>),
2459 Dummy,
2461 Err(ErrorGuaranteed),
2463}
2464
2465impl TyKind {
2466 pub fn is_implicit_self(&self) -> bool {
2467 matches!(self, TyKind::ImplicitSelf)
2468 }
2469
2470 pub fn is_unit(&self) -> bool {
2471 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2472 }
2473
2474 pub fn is_simple_path(&self) -> Option<Symbol> {
2475 if let TyKind::Path(None, Path { segments, .. }) = &self
2476 && let [segment] = &segments[..]
2477 && segment.args.is_none()
2478 {
2479 Some(segment.ident.name)
2480 } else {
2481 None
2482 }
2483 }
2484
2485 pub fn maybe_scalar(&self) -> bool {
2493 let Some(ty_sym) = self.is_simple_path() else {
2494 return self.is_unit();
2496 };
2497 matches!(
2498 ty_sym,
2499 sym::i8
2500 | sym::i16
2501 | sym::i32
2502 | sym::i64
2503 | sym::i128
2504 | sym::u8
2505 | sym::u16
2506 | sym::u32
2507 | sym::u64
2508 | sym::u128
2509 | sym::f16
2510 | sym::f32
2511 | sym::f64
2512 | sym::f128
2513 | sym::char
2514 | sym::bool
2515 )
2516 }
2517}
2518
2519#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2521pub struct TyPat {
2522 pub id: NodeId,
2523 pub kind: TyPatKind,
2524 pub span: Span,
2525 pub tokens: Option<LazyAttrTokenStream>,
2526}
2527
2528#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2532pub enum TyPatKind {
2533 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2535
2536 Or(ThinVec<P<TyPat>>),
2537
2538 Err(ErrorGuaranteed),
2540}
2541
2542#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2544#[repr(u8)]
2545pub enum TraitObjectSyntax {
2546 Dyn = 0,
2548 None = 1,
2549}
2550
2551unsafe impl Tag for TraitObjectSyntax {
2555 const BITS: u32 = 2;
2556
2557 fn into_usize(self) -> usize {
2558 self as u8 as usize
2559 }
2560
2561 unsafe fn from_usize(tag: usize) -> Self {
2562 match tag {
2563 0 => TraitObjectSyntax::Dyn,
2564 1 => TraitObjectSyntax::None,
2565 _ => unreachable!(),
2566 }
2567 }
2568}
2569
2570#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2571pub enum PreciseCapturingArg {
2572 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2574 Arg(Path, NodeId),
2576}
2577
2578#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2582pub enum InlineAsmRegOrRegClass {
2583 Reg(Symbol),
2584 RegClass(Symbol),
2585}
2586
2587#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2588pub struct InlineAsmOptions(u16);
2589bitflags::bitflags! {
2590 impl InlineAsmOptions: u16 {
2591 const PURE = 1 << 0;
2592 const NOMEM = 1 << 1;
2593 const READONLY = 1 << 2;
2594 const PRESERVES_FLAGS = 1 << 3;
2595 const NORETURN = 1 << 4;
2596 const NOSTACK = 1 << 5;
2597 const ATT_SYNTAX = 1 << 6;
2598 const RAW = 1 << 7;
2599 const MAY_UNWIND = 1 << 8;
2600 }
2601}
2602
2603impl InlineAsmOptions {
2604 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2605
2606 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2607 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2608
2609 pub fn human_readable_names(&self) -> Vec<&'static str> {
2610 let mut options = vec![];
2611
2612 if self.contains(InlineAsmOptions::PURE) {
2613 options.push("pure");
2614 }
2615 if self.contains(InlineAsmOptions::NOMEM) {
2616 options.push("nomem");
2617 }
2618 if self.contains(InlineAsmOptions::READONLY) {
2619 options.push("readonly");
2620 }
2621 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2622 options.push("preserves_flags");
2623 }
2624 if self.contains(InlineAsmOptions::NORETURN) {
2625 options.push("noreturn");
2626 }
2627 if self.contains(InlineAsmOptions::NOSTACK) {
2628 options.push("nostack");
2629 }
2630 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2631 options.push("att_syntax");
2632 }
2633 if self.contains(InlineAsmOptions::RAW) {
2634 options.push("raw");
2635 }
2636 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2637 options.push("may_unwind");
2638 }
2639
2640 options
2641 }
2642}
2643
2644impl std::fmt::Debug for InlineAsmOptions {
2645 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2646 bitflags::parser::to_writer(self, f)
2647 }
2648}
2649
2650#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2651pub enum InlineAsmTemplatePiece {
2652 String(Cow<'static, str>),
2653 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2654}
2655
2656impl fmt::Display for InlineAsmTemplatePiece {
2657 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2658 match self {
2659 Self::String(s) => {
2660 for c in s.chars() {
2661 match c {
2662 '{' => f.write_str("{{")?,
2663 '}' => f.write_str("}}")?,
2664 _ => c.fmt(f)?,
2665 }
2666 }
2667 Ok(())
2668 }
2669 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2670 write!(f, "{{{operand_idx}:{modifier}}}")
2671 }
2672 Self::Placeholder { operand_idx, modifier: None, .. } => {
2673 write!(f, "{{{operand_idx}}}")
2674 }
2675 }
2676 }
2677}
2678
2679impl InlineAsmTemplatePiece {
2680 pub fn to_string(s: &[Self]) -> String {
2682 use fmt::Write;
2683 let mut out = String::new();
2684 for p in s.iter() {
2685 let _ = write!(out, "{p}");
2686 }
2687 out
2688 }
2689}
2690
2691#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2699pub struct InlineAsmSym {
2700 pub id: NodeId,
2701 pub qself: Option<P<QSelf>>,
2702 pub path: Path,
2703}
2704
2705#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2709pub enum InlineAsmOperand {
2710 In {
2711 reg: InlineAsmRegOrRegClass,
2712 expr: P<Expr>,
2713 },
2714 Out {
2715 reg: InlineAsmRegOrRegClass,
2716 late: bool,
2717 expr: Option<P<Expr>>,
2718 },
2719 InOut {
2720 reg: InlineAsmRegOrRegClass,
2721 late: bool,
2722 expr: P<Expr>,
2723 },
2724 SplitInOut {
2725 reg: InlineAsmRegOrRegClass,
2726 late: bool,
2727 in_expr: P<Expr>,
2728 out_expr: Option<P<Expr>>,
2729 },
2730 Const {
2731 anon_const: AnonConst,
2732 },
2733 Sym {
2734 sym: InlineAsmSym,
2735 },
2736 Label {
2737 block: P<Block>,
2738 },
2739}
2740
2741impl InlineAsmOperand {
2742 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2743 match self {
2744 Self::In { reg, .. }
2745 | Self::Out { reg, .. }
2746 | Self::InOut { reg, .. }
2747 | Self::SplitInOut { reg, .. } => Some(reg),
2748 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2749 }
2750 }
2751}
2752
2753#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2754pub enum AsmMacro {
2755 Asm,
2757 GlobalAsm,
2759 NakedAsm,
2761}
2762
2763impl AsmMacro {
2764 pub const fn macro_name(self) -> &'static str {
2765 match self {
2766 AsmMacro::Asm => "asm",
2767 AsmMacro::GlobalAsm => "global_asm",
2768 AsmMacro::NakedAsm => "naked_asm",
2769 }
2770 }
2771
2772 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2773 match self {
2774 AsmMacro::Asm => true,
2775 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2776 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2777 }
2778 }
2779
2780 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2781 match self {
2782 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2783 AsmMacro::GlobalAsm => true,
2784 AsmMacro::NakedAsm => true,
2785 }
2786 }
2787}
2788
2789#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2793pub struct InlineAsm {
2794 pub asm_macro: AsmMacro,
2795 pub template: Vec<InlineAsmTemplatePiece>,
2796 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2797 pub operands: Vec<(InlineAsmOperand, Span)>,
2798 pub clobber_abis: Vec<(Symbol, Span)>,
2799 #[visitable(ignore)]
2800 pub options: InlineAsmOptions,
2801 pub line_spans: Vec<Span>,
2802}
2803
2804#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2808pub struct Param {
2809 pub attrs: AttrVec,
2810 pub ty: P<Ty>,
2811 pub pat: P<Pat>,
2812 pub id: NodeId,
2813 pub span: Span,
2814 pub is_placeholder: bool,
2815}
2816
2817#[derive(Clone, Encodable, Decodable, Debug)]
2821pub enum SelfKind {
2822 Value(Mutability),
2824 Region(Option<Lifetime>, Mutability),
2826 Pinned(Option<Lifetime>, Mutability),
2828 Explicit(P<Ty>, Mutability),
2830}
2831
2832impl SelfKind {
2833 pub fn to_ref_suggestion(&self) -> String {
2834 match self {
2835 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2836 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2837 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2838 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2839 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2840 unreachable!("if we had an explicit self, we wouldn't be here")
2841 }
2842 }
2843 }
2844}
2845
2846pub type ExplicitSelf = Spanned<SelfKind>;
2847
2848impl Param {
2849 pub fn to_self(&self) -> Option<ExplicitSelf> {
2851 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2852 if ident.name == kw::SelfLower {
2853 return match self.ty.kind {
2854 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2855 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2856 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2857 }
2858 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2859 if ty.kind.is_implicit_self() =>
2860 {
2861 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2862 }
2863 _ => Some(respan(
2864 self.pat.span.to(self.ty.span),
2865 SelfKind::Explicit(self.ty.clone(), mutbl),
2866 )),
2867 };
2868 }
2869 }
2870 None
2871 }
2872
2873 pub fn is_self(&self) -> bool {
2875 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2876 ident.name == kw::SelfLower
2877 } else {
2878 false
2879 }
2880 }
2881
2882 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2884 let span = eself.span.to(eself_ident.span);
2885 let infer_ty = P(Ty {
2886 id: DUMMY_NODE_ID,
2887 kind: TyKind::ImplicitSelf,
2888 span: eself_ident.span,
2889 tokens: None,
2890 });
2891 let (mutbl, ty) = match eself.node {
2892 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2893 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2894 SelfKind::Region(lt, mutbl) => (
2895 Mutability::Not,
2896 P(Ty {
2897 id: DUMMY_NODE_ID,
2898 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2899 span,
2900 tokens: None,
2901 }),
2902 ),
2903 SelfKind::Pinned(lt, mutbl) => (
2904 mutbl,
2905 P(Ty {
2906 id: DUMMY_NODE_ID,
2907 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2908 span,
2909 tokens: None,
2910 }),
2911 ),
2912 };
2913 Param {
2914 attrs,
2915 pat: P(Pat {
2916 id: DUMMY_NODE_ID,
2917 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2918 span,
2919 tokens: None,
2920 }),
2921 span,
2922 ty,
2923 id: DUMMY_NODE_ID,
2924 is_placeholder: false,
2925 }
2926 }
2927}
2928
2929#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2936pub struct FnDecl {
2937 pub inputs: ThinVec<Param>,
2938 pub output: FnRetTy,
2939}
2940
2941impl FnDecl {
2942 pub fn has_self(&self) -> bool {
2943 self.inputs.get(0).is_some_and(Param::is_self)
2944 }
2945 pub fn c_variadic(&self) -> bool {
2946 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2947 }
2948}
2949
2950#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2952pub enum IsAuto {
2953 Yes,
2954 No,
2955}
2956
2957#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2959#[derive(HashStable_Generic, Walkable)]
2960pub enum Safety {
2961 Unsafe(Span),
2963 Safe(Span),
2965 Default,
2968}
2969
2970#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
2976pub enum CoroutineKind {
2977 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2979 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2981 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2983}
2984
2985impl CoroutineKind {
2986 pub fn span(self) -> Span {
2987 match self {
2988 CoroutineKind::Async { span, .. } => span,
2989 CoroutineKind::Gen { span, .. } => span,
2990 CoroutineKind::AsyncGen { span, .. } => span,
2991 }
2992 }
2993
2994 pub fn as_str(self) -> &'static str {
2995 match self {
2996 CoroutineKind::Async { .. } => "async",
2997 CoroutineKind::Gen { .. } => "gen",
2998 CoroutineKind::AsyncGen { .. } => "async gen",
2999 }
3000 }
3001
3002 pub fn closure_id(self) -> NodeId {
3003 match self {
3004 CoroutineKind::Async { closure_id, .. }
3005 | CoroutineKind::Gen { closure_id, .. }
3006 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3007 }
3008 }
3009
3010 pub fn return_id(self) -> (NodeId, Span) {
3013 match self {
3014 CoroutineKind::Async { return_impl_trait_id, span, .. }
3015 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3016 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3017 (return_impl_trait_id, span)
3018 }
3019 }
3020 }
3021}
3022
3023#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3024#[derive(HashStable_Generic, Walkable)]
3025pub enum Const {
3026 Yes(Span),
3027 No,
3028}
3029
3030#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3033pub enum Defaultness {
3034 Default(Span),
3035 Final,
3036}
3037
3038#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3039pub enum ImplPolarity {
3040 Positive,
3042 Negative(Span),
3044}
3045
3046impl fmt::Debug for ImplPolarity {
3047 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3048 match *self {
3049 ImplPolarity::Positive => "positive".fmt(f),
3050 ImplPolarity::Negative(_) => "negative".fmt(f),
3051 }
3052 }
3053}
3054
3055#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3057#[derive(HashStable_Generic, Walkable)]
3058pub enum BoundPolarity {
3059 Positive,
3061 Negative(Span),
3063 Maybe(Span),
3065}
3066
3067impl BoundPolarity {
3068 pub fn as_str(self) -> &'static str {
3069 match self {
3070 Self::Positive => "",
3071 Self::Negative(_) => "!",
3072 Self::Maybe(_) => "?",
3073 }
3074 }
3075}
3076
3077#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3079#[derive(HashStable_Generic, Walkable)]
3080pub enum BoundConstness {
3081 Never,
3083 Always(Span),
3085 Maybe(Span),
3087}
3088
3089impl BoundConstness {
3090 pub fn as_str(self) -> &'static str {
3091 match self {
3092 Self::Never => "",
3093 Self::Always(_) => "const",
3094 Self::Maybe(_) => "[const]",
3095 }
3096 }
3097}
3098
3099#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3101#[derive(HashStable_Generic, Walkable)]
3102pub enum BoundAsyncness {
3103 Normal,
3105 Async(Span),
3107}
3108
3109impl BoundAsyncness {
3110 pub fn as_str(self) -> &'static str {
3111 match self {
3112 Self::Normal => "",
3113 Self::Async(_) => "async",
3114 }
3115 }
3116}
3117
3118#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3119pub enum FnRetTy {
3120 Default(Span),
3125 Ty(P<Ty>),
3127}
3128
3129impl FnRetTy {
3130 pub fn span(&self) -> Span {
3131 match self {
3132 &FnRetTy::Default(span) => span,
3133 FnRetTy::Ty(ty) => ty.span,
3134 }
3135 }
3136}
3137
3138#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3139pub enum Inline {
3140 Yes,
3141 No,
3142}
3143
3144#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3146pub enum ModKind {
3147 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3152 Unloaded,
3154}
3155
3156#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3157pub struct ModSpans {
3158 pub inner_span: Span,
3161 pub inject_use_span: Span,
3162}
3163
3164#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3168pub struct ForeignMod {
3169 pub extern_span: Span,
3171 pub safety: Safety,
3174 pub abi: Option<StrLit>,
3175 pub items: ThinVec<P<ForeignItem>>,
3176}
3177
3178#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3179pub struct EnumDef {
3180 pub variants: ThinVec<Variant>,
3181}
3182
3183#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3185pub struct Variant {
3186 pub attrs: AttrVec,
3188 pub id: NodeId,
3190 pub span: Span,
3192 pub vis: Visibility,
3194 pub ident: Ident,
3196
3197 pub data: VariantData,
3199 pub disr_expr: Option<AnonConst>,
3201 pub is_placeholder: bool,
3203}
3204
3205#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3207pub enum UseTreeKind {
3208 Simple(Option<Ident>),
3210 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3219 Glob,
3221}
3222
3223#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3226pub struct UseTree {
3227 pub prefix: Path,
3228 pub kind: UseTreeKind,
3229 pub span: Span,
3230}
3231
3232impl UseTree {
3233 pub fn ident(&self) -> Ident {
3234 match self.kind {
3235 UseTreeKind::Simple(Some(rename)) => rename,
3236 UseTreeKind::Simple(None) => {
3237 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3238 }
3239 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3240 }
3241 }
3242}
3243
3244#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3248pub enum AttrStyle {
3249 Outer,
3250 Inner,
3251}
3252
3253pub type AttrVec = ThinVec<Attribute>;
3255
3256#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3258pub struct Attribute {
3259 pub kind: AttrKind,
3260 pub id: AttrId,
3261 pub style: AttrStyle,
3264 pub span: Span,
3265}
3266
3267#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3268pub enum AttrKind {
3269 Normal(P<NormalAttr>),
3271
3272 DocComment(CommentKind, Symbol),
3276}
3277
3278#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3279pub struct NormalAttr {
3280 pub item: AttrItem,
3281 pub tokens: Option<LazyAttrTokenStream>,
3283}
3284
3285impl NormalAttr {
3286 pub fn from_ident(ident: Ident) -> Self {
3287 Self {
3288 item: AttrItem {
3289 unsafety: Safety::Default,
3290 path: Path::from_ident(ident),
3291 args: AttrArgs::Empty,
3292 tokens: None,
3293 },
3294 tokens: None,
3295 }
3296 }
3297}
3298
3299#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3300pub struct AttrItem {
3301 pub unsafety: Safety,
3302 pub path: Path,
3303 pub args: AttrArgs,
3304 pub tokens: Option<LazyAttrTokenStream>,
3306}
3307
3308impl AttrItem {
3309 pub fn is_valid_for_outer_style(&self) -> bool {
3310 self.path == sym::cfg_attr
3311 || self.path == sym::cfg
3312 || self.path == sym::forbid
3313 || self.path == sym::warn
3314 || self.path == sym::allow
3315 || self.path == sym::deny
3316 }
3317}
3318
3319#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3326pub struct TraitRef {
3327 pub path: Path,
3328 pub ref_id: NodeId,
3329}
3330
3331#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3333pub enum Parens {
3334 Yes,
3335 No,
3336}
3337
3338#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3339pub struct PolyTraitRef {
3340 pub bound_generic_params: ThinVec<GenericParam>,
3342
3343 pub modifiers: TraitBoundModifiers,
3345
3346 pub trait_ref: TraitRef,
3348
3349 pub span: Span,
3350
3351 pub parens: Parens,
3354}
3355
3356impl PolyTraitRef {
3357 pub fn new(
3358 generic_params: ThinVec<GenericParam>,
3359 path: Path,
3360 modifiers: TraitBoundModifiers,
3361 span: Span,
3362 parens: Parens,
3363 ) -> Self {
3364 PolyTraitRef {
3365 bound_generic_params: generic_params,
3366 modifiers,
3367 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3368 span,
3369 parens,
3370 }
3371 }
3372}
3373
3374#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3375pub struct Visibility {
3376 pub kind: VisibilityKind,
3377 pub span: Span,
3378 pub tokens: Option<LazyAttrTokenStream>,
3379}
3380
3381#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3382pub enum VisibilityKind {
3383 Public,
3384 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3385 Inherited,
3386}
3387
3388impl VisibilityKind {
3389 pub fn is_pub(&self) -> bool {
3390 matches!(self, VisibilityKind::Public)
3391 }
3392}
3393
3394#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3398pub struct FieldDef {
3399 pub attrs: AttrVec,
3400 pub id: NodeId,
3401 pub span: Span,
3402 pub vis: Visibility,
3403 pub safety: Safety,
3404 pub ident: Option<Ident>,
3405
3406 pub ty: P<Ty>,
3407 pub default: Option<AnonConst>,
3408 pub is_placeholder: bool,
3409}
3410
3411#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3413pub enum Recovered {
3414 No,
3415 Yes(ErrorGuaranteed),
3416}
3417
3418#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3420pub enum VariantData {
3421 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3425 Tuple(ThinVec<FieldDef>, NodeId),
3429 Unit(NodeId),
3433}
3434
3435impl VariantData {
3436 pub fn fields(&self) -> &[FieldDef] {
3438 match self {
3439 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3440 _ => &[],
3441 }
3442 }
3443
3444 pub fn ctor_node_id(&self) -> Option<NodeId> {
3446 match *self {
3447 VariantData::Struct { .. } => None,
3448 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3449 }
3450 }
3451}
3452
3453#[derive(Clone, Encodable, Decodable, Debug)]
3455pub struct Item<K = ItemKind> {
3456 pub attrs: AttrVec,
3457 pub id: NodeId,
3458 pub span: Span,
3459 pub vis: Visibility,
3460
3461 pub kind: K,
3462
3463 pub tokens: Option<LazyAttrTokenStream>,
3471}
3472
3473impl Item {
3474 pub fn span_with_attributes(&self) -> Span {
3476 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3477 }
3478
3479 pub fn opt_generics(&self) -> Option<&Generics> {
3480 match &self.kind {
3481 ItemKind::ExternCrate(..)
3482 | ItemKind::Use(_)
3483 | ItemKind::Mod(..)
3484 | ItemKind::ForeignMod(_)
3485 | ItemKind::GlobalAsm(_)
3486 | ItemKind::MacCall(_)
3487 | ItemKind::Delegation(_)
3488 | ItemKind::DelegationMac(_)
3489 | ItemKind::MacroDef(..) => None,
3490 ItemKind::Static(_) => None,
3491 ItemKind::Const(i) => Some(&i.generics),
3492 ItemKind::Fn(i) => Some(&i.generics),
3493 ItemKind::TyAlias(i) => Some(&i.generics),
3494 ItemKind::TraitAlias(_, generics, _)
3495 | ItemKind::Enum(_, generics, _)
3496 | ItemKind::Struct(_, generics, _)
3497 | ItemKind::Union(_, generics, _) => Some(&generics),
3498 ItemKind::Trait(i) => Some(&i.generics),
3499 ItemKind::Impl(i) => Some(&i.generics),
3500 }
3501 }
3502}
3503
3504#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3506pub enum Extern {
3507 None,
3511 Implicit(Span),
3517 Explicit(StrLit, Span),
3521}
3522
3523impl Extern {
3524 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3525 match abi {
3526 Some(name) => Extern::Explicit(name, span),
3527 None => Extern::Implicit(span),
3528 }
3529 }
3530}
3531
3532#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3537pub struct FnHeader {
3538 pub safety: Safety,
3540 pub coroutine_kind: Option<CoroutineKind>,
3542 pub constness: Const,
3544 pub ext: Extern,
3546}
3547
3548impl FnHeader {
3549 pub fn has_qualifiers(&self) -> bool {
3551 let Self { safety, coroutine_kind, constness, ext } = self;
3552 matches!(safety, Safety::Unsafe(_))
3553 || coroutine_kind.is_some()
3554 || matches!(constness, Const::Yes(_))
3555 || !matches!(ext, Extern::None)
3556 }
3557
3558 pub fn span(&self) -> Option<Span> {
3560 fn append(a: &mut Option<Span>, b: Span) {
3561 *a = match a {
3562 None => Some(b),
3563 Some(x) => Some(x.to(b)),
3564 }
3565 }
3566
3567 let mut full_span = None;
3568
3569 match self.safety {
3570 Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3571 Safety::Default => {}
3572 };
3573
3574 if let Some(coroutine_kind) = self.coroutine_kind {
3575 append(&mut full_span, coroutine_kind.span());
3576 }
3577
3578 if let Const::Yes(span) = self.constness {
3579 append(&mut full_span, span);
3580 }
3581
3582 match self.ext {
3583 Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3584 Extern::None => {}
3585 }
3586
3587 full_span
3588 }
3589}
3590
3591impl Default for FnHeader {
3592 fn default() -> FnHeader {
3593 FnHeader {
3594 safety: Safety::Default,
3595 coroutine_kind: None,
3596 constness: Const::No,
3597 ext: Extern::None,
3598 }
3599 }
3600}
3601
3602#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3603pub struct Trait {
3604 pub constness: Const,
3605 pub safety: Safety,
3606 pub is_auto: IsAuto,
3607 pub ident: Ident,
3608 pub generics: Generics,
3609 #[visitable(extra = BoundKind::SuperTraits)]
3610 pub bounds: GenericBounds,
3611 #[visitable(extra = AssocCtxt::Trait)]
3612 pub items: ThinVec<P<AssocItem>>,
3613}
3614
3615#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3634pub struct TyAliasWhereClause {
3635 pub has_where_token: bool,
3636 pub span: Span,
3637}
3638
3639#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3641pub struct TyAliasWhereClauses {
3642 pub before: TyAliasWhereClause,
3644 pub after: TyAliasWhereClause,
3646 pub split: usize,
3650}
3651
3652#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3653pub struct TyAlias {
3654 pub defaultness: Defaultness,
3655 pub ident: Ident,
3656 pub generics: Generics,
3657 pub where_clauses: TyAliasWhereClauses,
3658 #[visitable(extra = BoundKind::Bound)]
3659 pub bounds: GenericBounds,
3660 pub ty: Option<P<Ty>>,
3661}
3662
3663#[derive(Clone, Encodable, Decodable, Debug)]
3664pub struct Impl {
3665 pub defaultness: Defaultness,
3666 pub safety: Safety,
3667 pub generics: Generics,
3668 pub constness: Const,
3669 pub polarity: ImplPolarity,
3670 pub of_trait: Option<TraitRef>,
3672 pub self_ty: P<Ty>,
3673 pub items: ThinVec<P<AssocItem>>,
3674}
3675
3676#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3677pub struct FnContract {
3678 pub requires: Option<P<Expr>>,
3679 pub ensures: Option<P<Expr>>,
3680}
3681
3682#[derive(Clone, Encodable, Decodable, Debug)]
3683pub struct Fn {
3684 pub defaultness: Defaultness,
3685 pub ident: Ident,
3686 pub generics: Generics,
3687 pub sig: FnSig,
3688 pub contract: Option<P<FnContract>>,
3689 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3690 pub body: Option<P<Block>>,
3691}
3692
3693#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3694pub struct Delegation {
3695 pub id: NodeId,
3697 pub qself: Option<P<QSelf>>,
3698 pub path: Path,
3699 pub ident: Ident,
3700 pub rename: Option<Ident>,
3701 pub body: Option<P<Block>>,
3702 pub from_glob: bool,
3704}
3705
3706#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3707pub struct DelegationMac {
3708 pub qself: Option<P<QSelf>>,
3709 pub prefix: Path,
3710 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3712 pub body: Option<P<Block>>,
3713}
3714
3715#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3716pub struct StaticItem {
3717 pub ident: Ident,
3718 pub ty: P<Ty>,
3719 pub safety: Safety,
3720 pub mutability: Mutability,
3721 pub expr: Option<P<Expr>>,
3722 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3723}
3724
3725#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3726pub struct ConstItem {
3727 pub defaultness: Defaultness,
3728 pub ident: Ident,
3729 pub generics: Generics,
3730 pub ty: P<Ty>,
3731 pub expr: Option<P<Expr>>,
3732 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3733}
3734
3735#[derive(Clone, Encodable, Decodable, Debug)]
3737pub enum ItemKind {
3738 ExternCrate(Option<Symbol>, Ident),
3742 Use(UseTree),
3746 Static(Box<StaticItem>),
3750 Const(Box<ConstItem>),
3754 Fn(Box<Fn>),
3758 Mod(Safety, Ident, ModKind),
3764 ForeignMod(ForeignMod),
3768 GlobalAsm(Box<InlineAsm>),
3770 TyAlias(Box<TyAlias>),
3774 Enum(Ident, Generics, EnumDef),
3778 Struct(Ident, Generics, VariantData),
3782 Union(Ident, Generics, VariantData),
3786 Trait(Box<Trait>),
3790 TraitAlias(Ident, Generics, GenericBounds),
3794 Impl(Box<Impl>),
3798 MacCall(P<MacCall>),
3802 MacroDef(Ident, MacroDef),
3804 Delegation(Box<Delegation>),
3808 DelegationMac(Box<DelegationMac>),
3811}
3812
3813impl ItemKind {
3814 pub fn ident(&self) -> Option<Ident> {
3815 match *self {
3816 ItemKind::ExternCrate(_, ident)
3817 | ItemKind::Static(box StaticItem { ident, .. })
3818 | ItemKind::Const(box ConstItem { ident, .. })
3819 | ItemKind::Fn(box Fn { ident, .. })
3820 | ItemKind::Mod(_, ident, _)
3821 | ItemKind::TyAlias(box TyAlias { ident, .. })
3822 | ItemKind::Enum(ident, ..)
3823 | ItemKind::Struct(ident, ..)
3824 | ItemKind::Union(ident, ..)
3825 | ItemKind::Trait(box Trait { ident, .. })
3826 | ItemKind::TraitAlias(ident, ..)
3827 | ItemKind::MacroDef(ident, _)
3828 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3829
3830 ItemKind::Use(_)
3831 | ItemKind::ForeignMod(_)
3832 | ItemKind::GlobalAsm(_)
3833 | ItemKind::Impl(_)
3834 | ItemKind::MacCall(_)
3835 | ItemKind::DelegationMac(_) => None,
3836 }
3837 }
3838
3839 pub fn article(&self) -> &'static str {
3841 use ItemKind::*;
3842 match self {
3843 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3844 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3845 | Delegation(..) | DelegationMac(..) => "a",
3846 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3847 }
3848 }
3849
3850 pub fn descr(&self) -> &'static str {
3851 match self {
3852 ItemKind::ExternCrate(..) => "extern crate",
3853 ItemKind::Use(..) => "`use` import",
3854 ItemKind::Static(..) => "static item",
3855 ItemKind::Const(..) => "constant item",
3856 ItemKind::Fn(..) => "function",
3857 ItemKind::Mod(..) => "module",
3858 ItemKind::ForeignMod(..) => "extern block",
3859 ItemKind::GlobalAsm(..) => "global asm item",
3860 ItemKind::TyAlias(..) => "type alias",
3861 ItemKind::Enum(..) => "enum",
3862 ItemKind::Struct(..) => "struct",
3863 ItemKind::Union(..) => "union",
3864 ItemKind::Trait(..) => "trait",
3865 ItemKind::TraitAlias(..) => "trait alias",
3866 ItemKind::MacCall(..) => "item macro invocation",
3867 ItemKind::MacroDef(..) => "macro definition",
3868 ItemKind::Impl { .. } => "implementation",
3869 ItemKind::Delegation(..) => "delegated function",
3870 ItemKind::DelegationMac(..) => "delegation",
3871 }
3872 }
3873
3874 pub fn generics(&self) -> Option<&Generics> {
3875 match self {
3876 Self::Fn(box Fn { generics, .. })
3877 | Self::TyAlias(box TyAlias { generics, .. })
3878 | Self::Const(box ConstItem { generics, .. })
3879 | Self::Enum(_, generics, _)
3880 | Self::Struct(_, generics, _)
3881 | Self::Union(_, generics, _)
3882 | Self::Trait(box Trait { generics, .. })
3883 | Self::TraitAlias(_, generics, _)
3884 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3885 _ => None,
3886 }
3887 }
3888}
3889
3890pub type AssocItem = Item<AssocItemKind>;
3893
3894#[derive(Clone, Encodable, Decodable, Debug)]
3902pub enum AssocItemKind {
3903 Const(Box<ConstItem>),
3906 Fn(Box<Fn>),
3908 Type(Box<TyAlias>),
3910 MacCall(P<MacCall>),
3912 Delegation(Box<Delegation>),
3914 DelegationMac(Box<DelegationMac>),
3916}
3917
3918impl AssocItemKind {
3919 pub fn ident(&self) -> Option<Ident> {
3920 match *self {
3921 AssocItemKind::Const(box ConstItem { ident, .. })
3922 | AssocItemKind::Fn(box Fn { ident, .. })
3923 | AssocItemKind::Type(box TyAlias { ident, .. })
3924 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3925
3926 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3927 }
3928 }
3929
3930 pub fn defaultness(&self) -> Defaultness {
3931 match *self {
3932 Self::Const(box ConstItem { defaultness, .. })
3933 | Self::Fn(box Fn { defaultness, .. })
3934 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3935 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3936 Defaultness::Final
3937 }
3938 }
3939 }
3940}
3941
3942impl From<AssocItemKind> for ItemKind {
3943 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3944 match assoc_item_kind {
3945 AssocItemKind::Const(item) => ItemKind::Const(item),
3946 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3947 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3948 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3949 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3950 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3951 }
3952 }
3953}
3954
3955impl TryFrom<ItemKind> for AssocItemKind {
3956 type Error = ItemKind;
3957
3958 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3959 Ok(match item_kind {
3960 ItemKind::Const(item) => AssocItemKind::Const(item),
3961 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3962 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3963 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3964 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3965 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3966 _ => return Err(item_kind),
3967 })
3968 }
3969}
3970
3971#[derive(Clone, Encodable, Decodable, Debug)]
3973pub enum ForeignItemKind {
3974 Static(Box<StaticItem>),
3976 Fn(Box<Fn>),
3978 TyAlias(Box<TyAlias>),
3980 MacCall(P<MacCall>),
3982}
3983
3984impl ForeignItemKind {
3985 pub fn ident(&self) -> Option<Ident> {
3986 match *self {
3987 ForeignItemKind::Static(box StaticItem { ident, .. })
3988 | ForeignItemKind::Fn(box Fn { ident, .. })
3989 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3990
3991 ForeignItemKind::MacCall(_) => None,
3992 }
3993 }
3994}
3995
3996impl From<ForeignItemKind> for ItemKind {
3997 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3998 match foreign_item_kind {
3999 ForeignItemKind::Static(box static_foreign_item) => {
4000 ItemKind::Static(Box::new(static_foreign_item))
4001 }
4002 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4003 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4004 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4005 }
4006 }
4007}
4008
4009impl TryFrom<ItemKind> for ForeignItemKind {
4010 type Error = ItemKind;
4011
4012 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4013 Ok(match item_kind {
4014 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4015 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4016 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4017 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4018 _ => return Err(item_kind),
4019 })
4020 }
4021}
4022
4023pub type ForeignItem = Item<ForeignItemKind>;
4024
4025#[cfg(target_pointer_width = "64")]
4027mod size_asserts {
4028 use rustc_data_structures::static_assert_size;
4029
4030 use super::*;
4031 static_assert_size!(AssocItem, 80);
4033 static_assert_size!(AssocItemKind, 16);
4034 static_assert_size!(Attribute, 32);
4035 static_assert_size!(Block, 32);
4036 static_assert_size!(Expr, 72);
4037 static_assert_size!(ExprKind, 40);
4038 static_assert_size!(Fn, 184);
4039 static_assert_size!(ForeignItem, 80);
4040 static_assert_size!(ForeignItemKind, 16);
4041 static_assert_size!(GenericArg, 24);
4042 static_assert_size!(GenericBound, 88);
4043 static_assert_size!(Generics, 40);
4044 static_assert_size!(Impl, 136);
4045 static_assert_size!(Item, 144);
4046 static_assert_size!(ItemKind, 80);
4047 static_assert_size!(LitKind, 24);
4048 static_assert_size!(Local, 96);
4049 static_assert_size!(MetaItemLit, 40);
4050 static_assert_size!(Param, 40);
4051 static_assert_size!(Pat, 72);
4052 static_assert_size!(PatKind, 48);
4053 static_assert_size!(Path, 24);
4054 static_assert_size!(PathSegment, 24);
4055 static_assert_size!(Stmt, 32);
4056 static_assert_size!(StmtKind, 16);
4057 static_assert_size!(Ty, 64);
4058 static_assert_size!(TyKind, 40);
4059 }