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.len() == names.len()
118 && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
119 }
120}
121
122impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
123 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
124 self.segments.len().hash_stable(hcx, hasher);
125 for segment in &self.segments {
126 segment.ident.hash_stable(hcx, hasher);
127 }
128 }
129}
130
131impl Path {
132 pub fn from_ident(ident: Ident) -> Path {
135 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
136 }
137
138 pub fn is_global(&self) -> bool {
139 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
140 }
141
142 #[tracing::instrument(level = "debug", ret)]
152 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
153 allow_mgca_arg
154 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
155 }
156}
157
158pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
170 let mut iter = path.into_iter();
175 let len_hint = iter.size_hint().1.unwrap_or(1);
176 let mut s = String::with_capacity(len_hint * 8);
177
178 let first_sym = *iter.next().unwrap().borrow();
179 if first_sym != kw::PathRoot {
180 s.push_str(first_sym.as_str());
181 }
182 for sym in iter {
183 let sym = *sym.borrow();
184 debug_assert_ne!(sym, kw::PathRoot);
185 s.push_str("::");
186 s.push_str(sym.as_str());
187 }
188 s
189}
190
191pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
194 let mut iter = path.into_iter();
195 let len_hint = iter.size_hint().1.unwrap_or(1);
196 let mut s = String::with_capacity(len_hint * 8);
197
198 let first_ident = *iter.next().unwrap().borrow();
199 if first_ident.name != kw::PathRoot {
200 s.push_str(&first_ident.to_string());
201 }
202 for ident in iter {
203 let ident = *ident.borrow();
204 debug_assert_ne!(ident.name, kw::PathRoot);
205 s.push_str("::");
206 s.push_str(&ident.to_string());
207 }
208 s
209}
210
211#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
215pub struct PathSegment {
216 pub ident: Ident,
218
219 pub id: NodeId,
220
221 pub args: Option<Box<GenericArgs>>,
228}
229
230impl PartialEq<Symbol> for PathSegment {
232 #[inline]
233 fn eq(&self, name: &Symbol) -> bool {
234 self.args.is_none() && self.ident.name == *name
235 }
236}
237
238impl PathSegment {
239 pub fn from_ident(ident: Ident) -> Self {
240 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
241 }
242
243 pub fn path_root(span: Span) -> Self {
244 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
245 }
246
247 pub fn span(&self) -> Span {
248 match &self.args {
249 Some(args) => self.ident.span.to(args.span()),
250 None => self.ident.span,
251 }
252 }
253}
254
255#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
259pub enum GenericArgs {
260 AngleBracketed(AngleBracketedArgs),
262 Parenthesized(ParenthesizedArgs),
264 ParenthesizedElided(Span),
266}
267
268impl GenericArgs {
269 pub fn is_angle_bracketed(&self) -> bool {
270 matches!(self, AngleBracketed(..))
271 }
272
273 pub fn span(&self) -> Span {
274 match self {
275 AngleBracketed(data) => data.span,
276 Parenthesized(data) => data.span,
277 ParenthesizedElided(span) => *span,
278 }
279 }
280}
281
282#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
284pub enum GenericArg {
285 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
287 Type(Box<Ty>),
289 Const(AnonConst),
291}
292
293impl GenericArg {
294 pub fn span(&self) -> Span {
295 match self {
296 GenericArg::Lifetime(lt) => lt.ident.span,
297 GenericArg::Type(ty) => ty.span,
298 GenericArg::Const(ct) => ct.value.span,
299 }
300 }
301}
302
303#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
305pub struct AngleBracketedArgs {
306 pub span: Span,
308 pub args: ThinVec<AngleBracketedArg>,
310}
311
312#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
314pub enum AngleBracketedArg {
315 Arg(GenericArg),
317 Constraint(AssocItemConstraint),
319}
320
321impl AngleBracketedArg {
322 pub fn span(&self) -> Span {
323 match self {
324 AngleBracketedArg::Arg(arg) => arg.span(),
325 AngleBracketedArg::Constraint(constraint) => constraint.span,
326 }
327 }
328}
329
330impl From<AngleBracketedArgs> for Box<GenericArgs> {
331 fn from(val: AngleBracketedArgs) -> Self {
332 Box::new(GenericArgs::AngleBracketed(val))
333 }
334}
335
336impl From<ParenthesizedArgs> for Box<GenericArgs> {
337 fn from(val: ParenthesizedArgs) -> Self {
338 Box::new(GenericArgs::Parenthesized(val))
339 }
340}
341
342#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
344pub struct ParenthesizedArgs {
345 pub span: Span,
350
351 pub inputs: ThinVec<Box<Ty>>,
353
354 pub inputs_span: Span,
359
360 pub output: FnRetTy,
362}
363
364impl ParenthesizedArgs {
365 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
366 let args = self
367 .inputs
368 .iter()
369 .cloned()
370 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
371 .collect();
372 AngleBracketedArgs { span: self.inputs_span, args }
373 }
374}
375
376pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
377
378#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
380pub struct TraitBoundModifiers {
381 pub constness: BoundConstness,
382 pub asyncness: BoundAsyncness,
383 pub polarity: BoundPolarity,
384}
385
386impl TraitBoundModifiers {
387 pub const NONE: Self = Self {
388 constness: BoundConstness::Never,
389 asyncness: BoundAsyncness::Normal,
390 polarity: BoundPolarity::Positive,
391 };
392}
393
394#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
395pub enum GenericBound {
396 Trait(PolyTraitRef),
397 Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
398 Use(ThinVec<PreciseCapturingArg>, Span),
400}
401
402impl GenericBound {
403 pub fn span(&self) -> Span {
404 match self {
405 GenericBound::Trait(t, ..) => t.span,
406 GenericBound::Outlives(l) => l.ident.span,
407 GenericBound::Use(_, span) => *span,
408 }
409 }
410}
411
412pub type GenericBounds = Vec<GenericBound>;
413
414#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
418pub enum ParamKindOrd {
419 Lifetime,
420 TypeOrConst,
421}
422
423impl fmt::Display for ParamKindOrd {
424 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
425 match self {
426 ParamKindOrd::Lifetime => "lifetime".fmt(f),
427 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
428 }
429 }
430}
431
432#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
433pub enum GenericParamKind {
434 Lifetime,
436 Type {
437 default: Option<Box<Ty>>,
438 },
439 Const {
440 ty: Box<Ty>,
441 span: Span,
443 default: Option<AnonConst>,
445 },
446}
447
448#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
449pub struct GenericParam {
450 pub id: NodeId,
451 pub ident: Ident,
452 pub attrs: AttrVec,
453 #[visitable(extra = BoundKind::Bound)]
454 pub bounds: GenericBounds,
455 pub is_placeholder: bool,
456 pub kind: GenericParamKind,
457 pub colon_span: Option<Span>,
458}
459
460impl GenericParam {
461 pub fn span(&self) -> Span {
462 match &self.kind {
463 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
464 self.ident.span
465 }
466 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
467 GenericParamKind::Const { span, .. } => *span,
468 }
469 }
470}
471
472#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
475pub struct Generics {
476 pub params: ThinVec<GenericParam>,
477 pub where_clause: WhereClause,
478 pub span: Span,
479}
480
481#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
483pub struct WhereClause {
484 pub has_where_token: bool,
489 pub predicates: ThinVec<WherePredicate>,
490 pub span: Span,
491}
492
493impl WhereClause {
494 pub fn is_empty(&self) -> bool {
495 !self.has_where_token && self.predicates.is_empty()
496 }
497}
498
499#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
501pub struct WherePredicate {
502 pub attrs: AttrVec,
503 pub kind: WherePredicateKind,
504 pub id: NodeId,
505 pub span: Span,
506 pub is_placeholder: bool,
507}
508
509#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
511pub enum WherePredicateKind {
512 BoundPredicate(WhereBoundPredicate),
514 RegionPredicate(WhereRegionPredicate),
516 EqPredicate(WhereEqPredicate),
518}
519
520#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
524pub struct WhereBoundPredicate {
525 pub bound_generic_params: ThinVec<GenericParam>,
527 pub bounded_ty: Box<Ty>,
529 #[visitable(extra = BoundKind::Bound)]
531 pub bounds: GenericBounds,
532}
533
534#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
538pub struct WhereRegionPredicate {
539 #[visitable(extra = LifetimeCtxt::Bound)]
540 pub lifetime: Lifetime,
541 #[visitable(extra = BoundKind::Bound)]
542 pub bounds: GenericBounds,
543}
544
545#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
549pub struct WhereEqPredicate {
550 pub lhs_ty: Box<Ty>,
551 pub rhs_ty: Box<Ty>,
552}
553
554#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
555pub struct Crate {
556 pub id: NodeId,
559 pub attrs: AttrVec,
560 pub items: ThinVec<Box<Item>>,
561 pub spans: ModSpans,
562 pub is_placeholder: bool,
563}
564
565#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
572pub struct MetaItem {
573 pub unsafety: Safety,
574 pub path: Path,
575 pub kind: MetaItemKind,
576 pub span: Span,
577}
578
579#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
581pub enum MetaItemKind {
582 Word,
586
587 List(ThinVec<MetaItemInner>),
591
592 NameValue(MetaItemLit),
596}
597
598#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
602pub enum MetaItemInner {
603 MetaItem(MetaItem),
605
606 Lit(MetaItemLit),
610}
611
612#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
616pub struct Block {
617 pub stmts: ThinVec<Stmt>,
619 pub id: NodeId,
620 pub rules: BlockCheckMode,
622 pub span: Span,
623 pub tokens: Option<LazyAttrTokenStream>,
624}
625
626#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
630pub struct Pat {
631 pub id: NodeId,
632 pub kind: PatKind,
633 pub span: Span,
634 pub tokens: Option<LazyAttrTokenStream>,
635}
636
637impl Pat {
638 pub fn to_ty(&self) -> Option<Box<Ty>> {
641 let kind = match &self.kind {
642 PatKind::Missing => unreachable!(),
643 PatKind::Wild => TyKind::Infer,
645 PatKind::Ident(BindingMode::NONE, ident, None) => {
647 TyKind::Path(None, Path::from_ident(*ident))
648 }
649 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
650 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
651 PatKind::Ref(pat, mutbl) => {
653 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
654 }
655 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
658 pat.to_ty().map(TyKind::Slice)?
659 }
660 PatKind::Tuple(pats) => {
663 let mut tys = ThinVec::with_capacity(pats.len());
664 for pat in pats {
666 tys.push(pat.to_ty()?);
667 }
668 TyKind::Tup(tys)
669 }
670 _ => return None,
671 };
672
673 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
674 }
675
676 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
680 if !it(self) {
681 return;
682 }
683
684 match &self.kind {
685 PatKind::Ident(_, _, Some(p)) => p.walk(it),
687
688 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
690
691 PatKind::TupleStruct(_, _, s)
693 | PatKind::Tuple(s)
694 | PatKind::Slice(s)
695 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
696
697 PatKind::Box(s)
699 | PatKind::Deref(s)
700 | PatKind::Ref(s, _)
701 | PatKind::Paren(s)
702 | PatKind::Guard(s, _) => s.walk(it),
703
704 PatKind::Missing
706 | PatKind::Wild
707 | PatKind::Rest
708 | PatKind::Never
709 | PatKind::Expr(_)
710 | PatKind::Range(..)
711 | PatKind::Ident(..)
712 | PatKind::Path(..)
713 | PatKind::MacCall(_)
714 | PatKind::Err(_) => {}
715 }
716 }
717
718 pub fn is_rest(&self) -> bool {
720 matches!(self.kind, PatKind::Rest)
721 }
722
723 pub fn could_be_never_pattern(&self) -> bool {
726 let mut could_be_never_pattern = false;
727 self.walk(&mut |pat| match &pat.kind {
728 PatKind::Never | PatKind::MacCall(_) => {
729 could_be_never_pattern = true;
730 false
731 }
732 PatKind::Or(s) => {
733 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
734 false
735 }
736 _ => true,
737 });
738 could_be_never_pattern
739 }
740
741 pub fn contains_never_pattern(&self) -> bool {
744 let mut contains_never_pattern = false;
745 self.walk(&mut |pat| {
746 if matches!(pat.kind, PatKind::Never) {
747 contains_never_pattern = true;
748 }
749 true
750 });
751 contains_never_pattern
752 }
753
754 pub fn descr(&self) -> Option<String> {
756 match &self.kind {
757 PatKind::Missing => unreachable!(),
758 PatKind::Wild => Some("_".to_string()),
759 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
760 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
761 _ => None,
762 }
763 }
764}
765
766impl From<Box<Pat>> for Pat {
767 fn from(value: Box<Pat>) -> Self {
768 *value
769 }
770}
771
772#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
778pub struct PatField {
779 pub ident: Ident,
781 pub pat: Box<Pat>,
783 pub is_shorthand: bool,
784 pub attrs: AttrVec,
785 pub id: NodeId,
786 pub span: Span,
787 pub is_placeholder: bool,
788}
789
790#[derive(Clone, Copy, Debug, Eq, PartialEq)]
791#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
792pub enum ByRef {
793 Yes(Mutability),
794 No,
795}
796
797impl ByRef {
798 #[must_use]
799 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
800 if let ByRef::Yes(old_mutbl) = &mut self {
801 *old_mutbl = cmp::min(*old_mutbl, mutbl);
802 }
803 self
804 }
805}
806
807#[derive(Clone, Copy, Debug, Eq, PartialEq)]
813#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
814pub struct BindingMode(pub ByRef, pub Mutability);
815
816impl BindingMode {
817 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
818 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
819 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
820 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
821 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
822 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
823
824 pub fn prefix_str(self) -> &'static str {
825 match self {
826 Self::NONE => "",
827 Self::REF => "ref ",
828 Self::MUT => "mut ",
829 Self::REF_MUT => "ref mut ",
830 Self::MUT_REF => "mut ref ",
831 Self::MUT_REF_MUT => "mut ref mut ",
832 }
833 }
834}
835
836#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
837pub enum RangeEnd {
838 Included(RangeSyntax),
840 Excluded,
842}
843
844#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
845pub enum RangeSyntax {
846 DotDotDot,
848 DotDotEq,
850}
851
852#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
856pub enum PatKind {
857 Missing,
859
860 Wild,
862
863 Ident(BindingMode, Ident, Option<Box<Pat>>),
868
869 Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
871
872 TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Box<Pat>>),
874
875 Or(ThinVec<Box<Pat>>),
878
879 Path(Option<Box<QSelf>>, Path),
884
885 Tuple(ThinVec<Box<Pat>>),
887
888 Box(Box<Pat>),
890
891 Deref(Box<Pat>),
893
894 Ref(Box<Pat>, Mutability),
896
897 Expr(Box<Expr>),
899
900 Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
902
903 Slice(ThinVec<Box<Pat>>),
905
906 Rest,
919
920 Never,
922
923 Guard(Box<Pat>, Box<Expr>),
925
926 Paren(Box<Pat>),
928
929 MacCall(Box<MacCall>),
931
932 Err(ErrorGuaranteed),
934}
935
936#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
938pub enum PatFieldsRest {
939 Rest(Span),
941 Recovered(ErrorGuaranteed),
943 None,
945}
946
947#[derive(Clone, Copy, PartialEq, Eq, Debug)]
950#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
951pub enum BorrowKind {
952 Ref,
956 Raw,
960 Pin,
964}
965
966#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
967pub enum BinOpKind {
968 Add,
970 Sub,
972 Mul,
974 Div,
976 Rem,
978 And,
980 Or,
982 BitXor,
984 BitAnd,
986 BitOr,
988 Shl,
990 Shr,
992 Eq,
994 Lt,
996 Le,
998 Ne,
1000 Ge,
1002 Gt,
1004}
1005
1006impl BinOpKind {
1007 pub fn as_str(&self) -> &'static str {
1008 use BinOpKind::*;
1009 match self {
1010 Add => "+",
1011 Sub => "-",
1012 Mul => "*",
1013 Div => "/",
1014 Rem => "%",
1015 And => "&&",
1016 Or => "||",
1017 BitXor => "^",
1018 BitAnd => "&",
1019 BitOr => "|",
1020 Shl => "<<",
1021 Shr => ">>",
1022 Eq => "==",
1023 Lt => "<",
1024 Le => "<=",
1025 Ne => "!=",
1026 Ge => ">=",
1027 Gt => ">",
1028 }
1029 }
1030
1031 pub fn is_lazy(&self) -> bool {
1032 matches!(self, BinOpKind::And | BinOpKind::Or)
1033 }
1034
1035 pub fn precedence(&self) -> ExprPrecedence {
1036 use BinOpKind::*;
1037 match *self {
1038 Mul | Div | Rem => ExprPrecedence::Product,
1039 Add | Sub => ExprPrecedence::Sum,
1040 Shl | Shr => ExprPrecedence::Shift,
1041 BitAnd => ExprPrecedence::BitAnd,
1042 BitXor => ExprPrecedence::BitXor,
1043 BitOr => ExprPrecedence::BitOr,
1044 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1045 And => ExprPrecedence::LAnd,
1046 Or => ExprPrecedence::LOr,
1047 }
1048 }
1049
1050 pub fn fixity(&self) -> Fixity {
1051 use BinOpKind::*;
1052 match self {
1053 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1054 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1055 Fixity::Left
1056 }
1057 }
1058 }
1059
1060 pub fn is_comparison(self) -> bool {
1061 use BinOpKind::*;
1062 match self {
1063 Eq | Ne | Lt | Le | Gt | Ge => true,
1064 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1065 }
1066 }
1067
1068 pub fn is_by_value(self) -> bool {
1070 !self.is_comparison()
1071 }
1072}
1073
1074pub type BinOp = Spanned<BinOpKind>;
1075
1076impl From<AssignOpKind> for BinOpKind {
1080 fn from(op: AssignOpKind) -> BinOpKind {
1081 match op {
1082 AssignOpKind::AddAssign => BinOpKind::Add,
1083 AssignOpKind::SubAssign => BinOpKind::Sub,
1084 AssignOpKind::MulAssign => BinOpKind::Mul,
1085 AssignOpKind::DivAssign => BinOpKind::Div,
1086 AssignOpKind::RemAssign => BinOpKind::Rem,
1087 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1088 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1089 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1090 AssignOpKind::ShlAssign => BinOpKind::Shl,
1091 AssignOpKind::ShrAssign => BinOpKind::Shr,
1092 }
1093 }
1094}
1095
1096#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1097pub enum AssignOpKind {
1098 AddAssign,
1100 SubAssign,
1102 MulAssign,
1104 DivAssign,
1106 RemAssign,
1108 BitXorAssign,
1110 BitAndAssign,
1112 BitOrAssign,
1114 ShlAssign,
1116 ShrAssign,
1118}
1119
1120impl AssignOpKind {
1121 pub fn as_str(&self) -> &'static str {
1122 use AssignOpKind::*;
1123 match self {
1124 AddAssign => "+=",
1125 SubAssign => "-=",
1126 MulAssign => "*=",
1127 DivAssign => "/=",
1128 RemAssign => "%=",
1129 BitXorAssign => "^=",
1130 BitAndAssign => "&=",
1131 BitOrAssign => "|=",
1132 ShlAssign => "<<=",
1133 ShrAssign => ">>=",
1134 }
1135 }
1136
1137 pub fn is_by_value(self) -> bool {
1139 true
1140 }
1141}
1142
1143pub type AssignOp = Spanned<AssignOpKind>;
1144
1145#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1149pub enum UnOp {
1150 Deref,
1152 Not,
1154 Neg,
1156}
1157
1158impl UnOp {
1159 pub fn as_str(&self) -> &'static str {
1160 match self {
1161 UnOp::Deref => "*",
1162 UnOp::Not => "!",
1163 UnOp::Neg => "-",
1164 }
1165 }
1166
1167 pub fn is_by_value(self) -> bool {
1169 matches!(self, Self::Neg | Self::Not)
1170 }
1171}
1172
1173#[derive(Clone, Encodable, Decodable, Debug)]
1177pub struct Stmt {
1178 pub id: NodeId,
1179 pub kind: StmtKind,
1180 pub span: Span,
1181}
1182
1183impl Stmt {
1184 pub fn has_trailing_semicolon(&self) -> bool {
1185 match &self.kind {
1186 StmtKind::Semi(_) => true,
1187 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1188 _ => false,
1189 }
1190 }
1191
1192 pub fn add_trailing_semicolon(mut self) -> Self {
1200 self.kind = match self.kind {
1201 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1202 StmtKind::MacCall(mut mac) => {
1203 mac.style = MacStmtStyle::Semicolon;
1204 StmtKind::MacCall(mac)
1205 }
1206 kind => kind,
1207 };
1208
1209 self
1210 }
1211
1212 pub fn is_item(&self) -> bool {
1213 matches!(self.kind, StmtKind::Item(_))
1214 }
1215
1216 pub fn is_expr(&self) -> bool {
1217 matches!(self.kind, StmtKind::Expr(_))
1218 }
1219}
1220
1221#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1223pub enum StmtKind {
1224 Let(Box<Local>),
1226 Item(Box<Item>),
1228 Expr(Box<Expr>),
1230 Semi(Box<Expr>),
1232 Empty,
1234 MacCall(Box<MacCallStmt>),
1236}
1237
1238#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1239pub struct MacCallStmt {
1240 pub mac: Box<MacCall>,
1241 pub style: MacStmtStyle,
1242 pub attrs: AttrVec,
1243 pub tokens: Option<LazyAttrTokenStream>,
1244}
1245
1246#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1247pub enum MacStmtStyle {
1248 Semicolon,
1251 Braces,
1253 NoBraces,
1257}
1258
1259#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1261pub struct Local {
1262 pub id: NodeId,
1263 pub super_: Option<Span>,
1264 pub pat: Box<Pat>,
1265 pub ty: Option<Box<Ty>>,
1266 pub kind: LocalKind,
1267 pub span: Span,
1268 pub colon_sp: Option<Span>,
1269 pub attrs: AttrVec,
1270 pub tokens: Option<LazyAttrTokenStream>,
1271}
1272
1273#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1274pub enum LocalKind {
1275 Decl,
1278 Init(Box<Expr>),
1281 InitElse(Box<Expr>, Box<Block>),
1284}
1285
1286impl LocalKind {
1287 pub fn init(&self) -> Option<&Expr> {
1288 match self {
1289 Self::Decl => None,
1290 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1291 }
1292 }
1293
1294 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1295 match self {
1296 Self::Decl => None,
1297 Self::Init(init) => Some((init, None)),
1298 Self::InitElse(init, els) => Some((init, Some(els))),
1299 }
1300 }
1301}
1302
1303#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1314pub struct Arm {
1315 pub attrs: AttrVec,
1316 pub pat: Box<Pat>,
1318 pub guard: Option<Box<Expr>>,
1320 pub body: Option<Box<Expr>>,
1322 pub span: Span,
1323 pub id: NodeId,
1324 pub is_placeholder: bool,
1325}
1326
1327#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1329pub struct ExprField {
1330 pub attrs: AttrVec,
1331 pub id: NodeId,
1332 pub span: Span,
1333 pub ident: Ident,
1334 pub expr: Box<Expr>,
1335 pub is_shorthand: bool,
1336 pub is_placeholder: bool,
1337}
1338
1339#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1340pub enum BlockCheckMode {
1341 Default,
1342 Unsafe(UnsafeSource),
1343}
1344
1345#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1346pub enum UnsafeSource {
1347 CompilerGenerated,
1348 UserProvided,
1349}
1350
1351#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1357pub struct AnonConst {
1358 pub id: NodeId,
1359 pub value: Box<Expr>,
1360}
1361
1362#[derive(Clone, Encodable, Decodable, Debug)]
1364pub struct Expr {
1365 pub id: NodeId,
1366 pub kind: ExprKind,
1367 pub span: Span,
1368 pub attrs: AttrVec,
1369 pub tokens: Option<LazyAttrTokenStream>,
1370}
1371
1372impl Expr {
1373 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1387 let this = self.maybe_unwrap_block();
1388 if allow_mgca_arg {
1389 matches!(this.kind, ExprKind::Path(..))
1390 } else {
1391 if let ExprKind::Path(None, path) = &this.kind
1392 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1393 {
1394 true
1395 } else {
1396 false
1397 }
1398 }
1399 }
1400
1401 pub fn maybe_unwrap_block(&self) -> &Expr {
1403 if let ExprKind::Block(block, None) = &self.kind
1404 && let [stmt] = block.stmts.as_slice()
1405 && let StmtKind::Expr(expr) = &stmt.kind
1406 {
1407 expr
1408 } else {
1409 self
1410 }
1411 }
1412
1413 pub fn optionally_braced_mac_call(
1419 &self,
1420 already_stripped_block: bool,
1421 ) -> Option<(bool, NodeId)> {
1422 match &self.kind {
1423 ExprKind::Block(block, None)
1424 if let [stmt] = &*block.stmts
1425 && !already_stripped_block =>
1426 {
1427 match &stmt.kind {
1428 StmtKind::MacCall(_) => Some((true, stmt.id)),
1429 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1430 Some((true, expr.id))
1431 }
1432 _ => None,
1433 }
1434 }
1435 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1436 _ => None,
1437 }
1438 }
1439
1440 pub fn to_bound(&self) -> Option<GenericBound> {
1441 match &self.kind {
1442 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1443 ThinVec::new(),
1444 path.clone(),
1445 TraitBoundModifiers::NONE,
1446 self.span,
1447 Parens::No,
1448 ))),
1449 _ => None,
1450 }
1451 }
1452
1453 pub fn peel_parens(&self) -> &Expr {
1454 let mut expr = self;
1455 while let ExprKind::Paren(inner) = &expr.kind {
1456 expr = inner;
1457 }
1458 expr
1459 }
1460
1461 pub fn peel_parens_and_refs(&self) -> &Expr {
1462 let mut expr = self;
1463 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1464 {
1465 expr = inner;
1466 }
1467 expr
1468 }
1469
1470 pub fn to_ty(&self) -> Option<Box<Ty>> {
1472 let kind = match &self.kind {
1473 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1475 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1476
1477 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1478
1479 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1480 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1481 }
1482
1483 ExprKind::Repeat(expr, expr_len) => {
1484 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1485 }
1486
1487 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1488 expr.to_ty().map(TyKind::Slice)?
1489 }
1490
1491 ExprKind::Tup(exprs) => {
1492 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1493 TyKind::Tup(tys)
1494 }
1495
1496 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1500 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1501 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1502 } else {
1503 return None;
1504 }
1505 }
1506
1507 ExprKind::Underscore => TyKind::Infer,
1508
1509 _ => return None,
1511 };
1512
1513 Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1514 }
1515
1516 pub fn precedence(&self) -> ExprPrecedence {
1517 fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1518 for attr in attrs {
1519 if let AttrStyle::Outer = attr.style {
1520 return ExprPrecedence::Prefix;
1521 }
1522 }
1523 ExprPrecedence::Unambiguous
1524 }
1525
1526 match &self.kind {
1527 ExprKind::Closure(closure) => {
1528 match closure.fn_decl.output {
1529 FnRetTy::Default(_) => ExprPrecedence::Jump,
1530 FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1531 }
1532 }
1533
1534 ExprKind::Break(_ , value)
1535 | ExprKind::Ret(value)
1536 | ExprKind::Yield(YieldKind::Prefix(value))
1537 | ExprKind::Yeet(value) => match value {
1538 Some(_) => ExprPrecedence::Jump,
1539 None => prefix_attrs_precedence(&self.attrs),
1540 },
1541
1542 ExprKind::Become(_) => ExprPrecedence::Jump,
1543
1544 ExprKind::Range(..) => ExprPrecedence::Range,
1549
1550 ExprKind::Binary(op, ..) => op.node.precedence(),
1552 ExprKind::Cast(..) => ExprPrecedence::Cast,
1553
1554 ExprKind::Assign(..) |
1555 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1556
1557 ExprKind::AddrOf(..)
1559 | ExprKind::Let(..)
1564 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1565
1566 ExprKind::Array(_)
1568 | ExprKind::Await(..)
1569 | ExprKind::Use(..)
1570 | ExprKind::Block(..)
1571 | ExprKind::Call(..)
1572 | ExprKind::ConstBlock(_)
1573 | ExprKind::Continue(..)
1574 | ExprKind::Field(..)
1575 | ExprKind::ForLoop { .. }
1576 | ExprKind::FormatArgs(..)
1577 | ExprKind::Gen(..)
1578 | ExprKind::If(..)
1579 | ExprKind::IncludedBytes(..)
1580 | ExprKind::Index(..)
1581 | ExprKind::InlineAsm(..)
1582 | ExprKind::Lit(_)
1583 | ExprKind::Loop(..)
1584 | ExprKind::MacCall(..)
1585 | ExprKind::Match(..)
1586 | ExprKind::MethodCall(..)
1587 | ExprKind::OffsetOf(..)
1588 | ExprKind::Paren(..)
1589 | ExprKind::Path(..)
1590 | ExprKind::Repeat(..)
1591 | ExprKind::Struct(..)
1592 | ExprKind::Try(..)
1593 | ExprKind::TryBlock(..)
1594 | ExprKind::Tup(_)
1595 | ExprKind::Type(..)
1596 | ExprKind::Underscore
1597 | ExprKind::UnsafeBinderCast(..)
1598 | ExprKind::While(..)
1599 | ExprKind::Yield(YieldKind::Postfix(..))
1600 | ExprKind::Err(_)
1601 | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1602 }
1603 }
1604
1605 pub fn is_approximately_pattern(&self) -> bool {
1607 matches!(
1608 &self.peel_parens().kind,
1609 ExprKind::Array(_)
1610 | ExprKind::Call(_, _)
1611 | ExprKind::Tup(_)
1612 | ExprKind::Lit(_)
1613 | ExprKind::Range(_, _, _)
1614 | ExprKind::Underscore
1615 | ExprKind::Path(_, _)
1616 | ExprKind::Struct(_)
1617 )
1618 }
1619
1620 pub fn dummy() -> Expr {
1624 Expr {
1625 id: DUMMY_NODE_ID,
1626 kind: ExprKind::Dummy,
1627 span: DUMMY_SP,
1628 attrs: ThinVec::new(),
1629 tokens: None,
1630 }
1631 }
1632}
1633
1634impl From<Box<Expr>> for Expr {
1635 fn from(value: Box<Expr>) -> Self {
1636 *value
1637 }
1638}
1639
1640#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1641pub struct Closure {
1642 pub binder: ClosureBinder,
1643 pub capture_clause: CaptureBy,
1644 pub constness: Const,
1645 pub coroutine_kind: Option<CoroutineKind>,
1646 pub movability: Movability,
1647 pub fn_decl: Box<FnDecl>,
1648 pub body: Box<Expr>,
1649 pub fn_decl_span: Span,
1651 pub fn_arg_span: Span,
1653}
1654
1655#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1657pub enum RangeLimits {
1658 HalfOpen,
1660 Closed,
1662}
1663
1664impl RangeLimits {
1665 pub fn as_str(&self) -> &'static str {
1666 match self {
1667 RangeLimits::HalfOpen => "..",
1668 RangeLimits::Closed => "..=",
1669 }
1670 }
1671}
1672
1673#[derive(Clone, Encodable, Decodable, Debug)]
1675pub struct MethodCall {
1676 pub seg: PathSegment,
1678 pub receiver: Box<Expr>,
1680 pub args: ThinVec<Box<Expr>>,
1682 pub span: Span,
1685}
1686
1687#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1688pub enum StructRest {
1689 Base(Box<Expr>),
1691 Rest(Span),
1693 None,
1695}
1696
1697#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1698pub struct StructExpr {
1699 pub qself: Option<Box<QSelf>>,
1700 pub path: Path,
1701 pub fields: ThinVec<ExprField>,
1702 pub rest: StructRest,
1703}
1704
1705#[derive(Clone, Encodable, Decodable, Debug)]
1707pub enum ExprKind {
1708 Array(ThinVec<Box<Expr>>),
1710 ConstBlock(AnonConst),
1712 Call(Box<Expr>, ThinVec<Box<Expr>>),
1719 MethodCall(Box<MethodCall>),
1721 Tup(ThinVec<Box<Expr>>),
1723 Binary(BinOp, Box<Expr>, Box<Expr>),
1725 Unary(UnOp, Box<Expr>),
1727 Lit(token::Lit),
1729 Cast(Box<Expr>, Box<Ty>),
1731 Type(Box<Expr>, Box<Ty>),
1736 Let(Box<Pat>, Box<Expr>, Span, Recovered),
1741 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1748 While(Box<Expr>, Box<Block>, Option<Label>),
1752 ForLoop {
1758 pat: Box<Pat>,
1759 iter: Box<Expr>,
1760 body: Box<Block>,
1761 label: Option<Label>,
1762 kind: ForLoopKind,
1763 },
1764 Loop(Box<Block>, Option<Label>, Span),
1768 Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1770 Closure(Box<Closure>),
1772 Block(Box<Block>, Option<Label>),
1774 Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1780 Await(Box<Expr>, Span),
1782 Use(Box<Expr>, Span),
1784
1785 TryBlock(Box<Block>),
1787
1788 Assign(Box<Expr>, Box<Expr>, Span),
1791 AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1795 Field(Box<Expr>, Ident),
1797 Index(Box<Expr>, Box<Expr>, Span),
1800 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1802 Underscore,
1804
1805 Path(Option<Box<QSelf>>, Path),
1810
1811 AddrOf(BorrowKind, Mutability, Box<Expr>),
1813 Break(Option<Label>, Option<Box<Expr>>),
1815 Continue(Option<Label>),
1817 Ret(Option<Box<Expr>>),
1819
1820 InlineAsm(Box<InlineAsm>),
1822
1823 OffsetOf(Box<Ty>, Vec<Ident>),
1828
1829 MacCall(Box<MacCall>),
1831
1832 Struct(Box<StructExpr>),
1836
1837 Repeat(Box<Expr>, AnonConst),
1842
1843 Paren(Box<Expr>),
1845
1846 Try(Box<Expr>),
1848
1849 Yield(YieldKind),
1851
1852 Yeet(Option<Box<Expr>>),
1855
1856 Become(Box<Expr>),
1860
1861 IncludedBytes(ByteSymbol),
1873
1874 FormatArgs(Box<FormatArgs>),
1876
1877 UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1878
1879 Err(ErrorGuaranteed),
1881
1882 Dummy,
1884}
1885
1886#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1888pub enum ForLoopKind {
1889 For,
1890 ForAwait,
1891}
1892
1893#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1895pub enum GenBlockKind {
1896 Async,
1897 Gen,
1898 AsyncGen,
1899}
1900
1901impl fmt::Display for GenBlockKind {
1902 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1903 self.modifier().fmt(f)
1904 }
1905}
1906
1907impl GenBlockKind {
1908 pub fn modifier(&self) -> &'static str {
1909 match self {
1910 GenBlockKind::Async => "async",
1911 GenBlockKind::Gen => "gen",
1912 GenBlockKind::AsyncGen => "async gen",
1913 }
1914 }
1915}
1916
1917#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1919#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1920pub enum UnsafeBinderCastKind {
1921 Wrap,
1923 Unwrap,
1925}
1926
1927#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1942pub struct QSelf {
1943 pub ty: Box<Ty>,
1944
1945 pub path_span: Span,
1949 pub position: usize,
1950}
1951
1952#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1954pub enum CaptureBy {
1955 Value {
1957 move_kw: Span,
1959 },
1960 Ref,
1962 Use {
1968 use_kw: Span,
1970 },
1971}
1972
1973#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1975pub enum ClosureBinder {
1976 NotPresent,
1978 For {
1980 span: Span,
1987
1988 generic_params: ThinVec<GenericParam>,
1995 },
1996}
1997
1998#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2001pub struct MacCall {
2002 pub path: Path,
2003 pub args: Box<DelimArgs>,
2004}
2005
2006impl MacCall {
2007 pub fn span(&self) -> Span {
2008 self.path.span.to(self.args.dspan.entire())
2009 }
2010}
2011
2012#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2014pub enum AttrArgs {
2015 Empty,
2017 Delimited(DelimArgs),
2019 Eq {
2021 eq_span: Span,
2023 expr: Box<Expr>,
2024 },
2025}
2026
2027impl AttrArgs {
2028 pub fn span(&self) -> Option<Span> {
2029 match self {
2030 AttrArgs::Empty => None,
2031 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2032 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2033 }
2034 }
2035
2036 pub fn inner_tokens(&self) -> TokenStream {
2039 match self {
2040 AttrArgs::Empty => TokenStream::default(),
2041 AttrArgs::Delimited(args) => args.tokens.clone(),
2042 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2043 }
2044 }
2045}
2046
2047#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2049pub struct DelimArgs {
2050 pub dspan: DelimSpan,
2051 pub delim: Delimiter, pub tokens: TokenStream,
2053}
2054
2055impl DelimArgs {
2056 pub fn need_semicolon(&self) -> bool {
2059 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2060 }
2061}
2062
2063#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2065pub struct MacroDef {
2066 pub body: Box<DelimArgs>,
2067 pub macro_rules: bool,
2069}
2070
2071#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2072#[derive(HashStable_Generic, Walkable)]
2073pub enum StrStyle {
2074 Cooked,
2076 Raw(u8),
2080}
2081
2082#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2084pub enum MatchKind {
2085 Prefix,
2087 Postfix,
2089}
2090
2091#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2093pub enum YieldKind {
2094 Prefix(Option<Box<Expr>>),
2096 Postfix(Box<Expr>),
2098}
2099
2100impl YieldKind {
2101 pub const fn expr(&self) -> Option<&Box<Expr>> {
2105 match self {
2106 YieldKind::Prefix(expr) => expr.as_ref(),
2107 YieldKind::Postfix(expr) => Some(expr),
2108 }
2109 }
2110
2111 pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2113 match self {
2114 YieldKind::Prefix(expr) => expr.as_mut(),
2115 YieldKind::Postfix(expr) => Some(expr),
2116 }
2117 }
2118
2119 pub const fn same_kind(&self, other: &Self) -> bool {
2121 match (self, other) {
2122 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2123 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2124 _ => false,
2125 }
2126 }
2127}
2128
2129#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2131pub struct MetaItemLit {
2132 pub symbol: Symbol,
2134 pub suffix: Option<Symbol>,
2136 pub kind: LitKind,
2139 pub span: Span,
2140}
2141
2142#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2144pub struct StrLit {
2145 pub symbol: Symbol,
2147 pub suffix: Option<Symbol>,
2149 pub symbol_unescaped: Symbol,
2151 pub style: StrStyle,
2152 pub span: Span,
2153}
2154
2155impl StrLit {
2156 pub fn as_token_lit(&self) -> token::Lit {
2157 let token_kind = match self.style {
2158 StrStyle::Cooked => token::Str,
2159 StrStyle::Raw(n) => token::StrRaw(n),
2160 };
2161 token::Lit::new(token_kind, self.symbol, self.suffix)
2162 }
2163}
2164
2165#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2167#[derive(HashStable_Generic)]
2168pub enum LitIntType {
2169 Signed(IntTy),
2171 Unsigned(UintTy),
2173 Unsuffixed,
2175}
2176
2177#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2179#[derive(HashStable_Generic)]
2180pub enum LitFloatType {
2181 Suffixed(FloatTy),
2183 Unsuffixed,
2185}
2186
2187#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2194pub enum LitKind {
2195 Str(Symbol, StrStyle),
2198 ByteStr(ByteSymbol, StrStyle),
2201 CStr(ByteSymbol, StrStyle),
2205 Byte(u8),
2207 Char(char),
2209 Int(Pu128, LitIntType),
2211 Float(Symbol, LitFloatType),
2215 Bool(bool),
2217 Err(ErrorGuaranteed),
2219}
2220
2221impl LitKind {
2222 pub fn str(&self) -> Option<Symbol> {
2223 match *self {
2224 LitKind::Str(s, _) => Some(s),
2225 _ => None,
2226 }
2227 }
2228
2229 pub fn is_str(&self) -> bool {
2231 matches!(self, LitKind::Str(..))
2232 }
2233
2234 pub fn is_bytestr(&self) -> bool {
2236 matches!(self, LitKind::ByteStr(..))
2237 }
2238
2239 pub fn is_numeric(&self) -> bool {
2241 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2242 }
2243
2244 pub fn is_unsuffixed(&self) -> bool {
2247 !self.is_suffixed()
2248 }
2249
2250 pub fn is_suffixed(&self) -> bool {
2252 match *self {
2253 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2255 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2256 LitKind::Str(..)
2258 | LitKind::ByteStr(..)
2259 | LitKind::CStr(..)
2260 | LitKind::Byte(..)
2261 | LitKind::Char(..)
2262 | LitKind::Int(_, LitIntType::Unsuffixed)
2263 | LitKind::Float(_, LitFloatType::Unsuffixed)
2264 | LitKind::Bool(..)
2265 | LitKind::Err(_) => false,
2266 }
2267 }
2268}
2269
2270#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2273pub struct MutTy {
2274 pub ty: Box<Ty>,
2275 pub mutbl: Mutability,
2276}
2277
2278#[derive(Clone, Encodable, Decodable, Debug)]
2281pub struct FnSig {
2282 pub header: FnHeader,
2283 pub decl: Box<FnDecl>,
2284 pub span: Span,
2285}
2286
2287impl FnSig {
2288 pub fn header_span(&self) -> Span {
2290 match self.header.ext {
2291 Extern::Implicit(span) | Extern::Explicit(_, span) => {
2292 return self.span.with_hi(span.hi());
2293 }
2294 Extern::None => {}
2295 }
2296
2297 match self.header.safety {
2298 Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2299 Safety::Default => {}
2300 };
2301
2302 if let Some(coroutine_kind) = self.header.coroutine_kind {
2303 return self.span.with_hi(coroutine_kind.span().hi());
2304 }
2305
2306 if let Const::Yes(span) = self.header.constness {
2307 return self.span.with_hi(span.hi());
2308 }
2309
2310 self.span.shrink_to_lo()
2311 }
2312
2313 pub fn safety_span(&self) -> Span {
2315 match self.header.safety {
2316 Safety::Unsafe(span) | Safety::Safe(span) => span,
2317 Safety::Default => {
2318 if let Some(extern_span) = self.header.ext.span() {
2320 return extern_span.shrink_to_lo();
2321 }
2322
2323 self.header_span().shrink_to_hi()
2325 }
2326 }
2327 }
2328
2329 pub fn extern_span(&self) -> Span {
2331 self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2332 }
2333}
2334
2335#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2346pub struct AssocItemConstraint {
2347 pub id: NodeId,
2348 pub ident: Ident,
2349 pub gen_args: Option<GenericArgs>,
2350 pub kind: AssocItemConstraintKind,
2351 pub span: Span,
2352}
2353
2354#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2355pub enum Term {
2356 Ty(Box<Ty>),
2357 Const(AnonConst),
2358}
2359
2360impl From<Box<Ty>> for Term {
2361 fn from(v: Box<Ty>) -> Self {
2362 Term::Ty(v)
2363 }
2364}
2365
2366impl From<AnonConst> for Term {
2367 fn from(v: AnonConst) -> Self {
2368 Term::Const(v)
2369 }
2370}
2371
2372#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2374pub enum AssocItemConstraintKind {
2375 Equality { term: Term },
2382 Bound {
2384 #[visitable(extra = BoundKind::Bound)]
2385 bounds: GenericBounds,
2386 },
2387}
2388
2389#[derive(Encodable, Decodable, Debug, Walkable)]
2390pub struct Ty {
2391 pub id: NodeId,
2392 pub kind: TyKind,
2393 pub span: Span,
2394 pub tokens: Option<LazyAttrTokenStream>,
2395}
2396
2397impl Clone for Ty {
2398 fn clone(&self) -> Self {
2399 ensure_sufficient_stack(|| Self {
2400 id: self.id,
2401 kind: self.kind.clone(),
2402 span: self.span,
2403 tokens: self.tokens.clone(),
2404 })
2405 }
2406}
2407
2408impl From<Box<Ty>> for Ty {
2409 fn from(value: Box<Ty>) -> Self {
2410 *value
2411 }
2412}
2413
2414impl Ty {
2415 pub fn peel_refs(&self) -> &Self {
2416 let mut final_ty = self;
2417 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2418 {
2419 final_ty = ty;
2420 }
2421 final_ty
2422 }
2423
2424 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2425 match &self.kind {
2426 TyKind::Infer => true,
2427 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2428 _ => false,
2429 }
2430 }
2431}
2432
2433#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2434pub struct FnPtrTy {
2435 pub safety: Safety,
2436 pub ext: Extern,
2437 pub generic_params: ThinVec<GenericParam>,
2438 pub decl: Box<FnDecl>,
2439 pub decl_span: Span,
2442}
2443
2444#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2445pub struct UnsafeBinderTy {
2446 pub generic_params: ThinVec<GenericParam>,
2447 pub inner_ty: Box<Ty>,
2448}
2449
2450#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2454pub enum TyKind {
2455 Slice(Box<Ty>),
2457 Array(Box<Ty>, AnonConst),
2459 Ptr(MutTy),
2461 Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2463 PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2467 FnPtr(Box<FnPtrTy>),
2469 UnsafeBinder(Box<UnsafeBinderTy>),
2471 Never,
2473 Tup(ThinVec<Box<Ty>>),
2475 Path(Option<Box<QSelf>>, Path),
2480 TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2483 ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2490 Paren(Box<Ty>),
2492 Typeof(AnonConst),
2494 Infer,
2497 ImplicitSelf,
2499 MacCall(Box<MacCall>),
2501 CVarArgs,
2503 Pat(Box<Ty>, Box<TyPat>),
2506 Dummy,
2508 Err(ErrorGuaranteed),
2510}
2511
2512impl TyKind {
2513 pub fn is_implicit_self(&self) -> bool {
2514 matches!(self, TyKind::ImplicitSelf)
2515 }
2516
2517 pub fn is_unit(&self) -> bool {
2518 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2519 }
2520
2521 pub fn is_simple_path(&self) -> Option<Symbol> {
2522 if let TyKind::Path(None, Path { segments, .. }) = &self
2523 && let [segment] = &segments[..]
2524 && segment.args.is_none()
2525 {
2526 Some(segment.ident.name)
2527 } else {
2528 None
2529 }
2530 }
2531
2532 pub fn maybe_scalar(&self) -> bool {
2540 let Some(ty_sym) = self.is_simple_path() else {
2541 return self.is_unit();
2543 };
2544 matches!(
2545 ty_sym,
2546 sym::i8
2547 | sym::i16
2548 | sym::i32
2549 | sym::i64
2550 | sym::i128
2551 | sym::u8
2552 | sym::u16
2553 | sym::u32
2554 | sym::u64
2555 | sym::u128
2556 | sym::f16
2557 | sym::f32
2558 | sym::f64
2559 | sym::f128
2560 | sym::char
2561 | sym::bool
2562 )
2563 }
2564}
2565
2566#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2568pub struct TyPat {
2569 pub id: NodeId,
2570 pub kind: TyPatKind,
2571 pub span: Span,
2572 pub tokens: Option<LazyAttrTokenStream>,
2573}
2574
2575#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2579pub enum TyPatKind {
2580 Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2582
2583 Or(ThinVec<Box<TyPat>>),
2584
2585 Err(ErrorGuaranteed),
2587}
2588
2589#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2591#[repr(u8)]
2592pub enum TraitObjectSyntax {
2593 Dyn = 0,
2595 None = 1,
2596}
2597
2598unsafe impl Tag for TraitObjectSyntax {
2602 const BITS: u32 = 2;
2603
2604 fn into_usize(self) -> usize {
2605 self as u8 as usize
2606 }
2607
2608 unsafe fn from_usize(tag: usize) -> Self {
2609 match tag {
2610 0 => TraitObjectSyntax::Dyn,
2611 1 => TraitObjectSyntax::None,
2612 _ => unreachable!(),
2613 }
2614 }
2615}
2616
2617#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2618pub enum PreciseCapturingArg {
2619 Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2621 Arg(Path, NodeId),
2623}
2624
2625#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2629pub enum InlineAsmRegOrRegClass {
2630 Reg(Symbol),
2631 RegClass(Symbol),
2632}
2633
2634#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2635pub struct InlineAsmOptions(u16);
2636bitflags::bitflags! {
2637 impl InlineAsmOptions: u16 {
2638 const PURE = 1 << 0;
2639 const NOMEM = 1 << 1;
2640 const READONLY = 1 << 2;
2641 const PRESERVES_FLAGS = 1 << 3;
2642 const NORETURN = 1 << 4;
2643 const NOSTACK = 1 << 5;
2644 const ATT_SYNTAX = 1 << 6;
2645 const RAW = 1 << 7;
2646 const MAY_UNWIND = 1 << 8;
2647 }
2648}
2649
2650impl InlineAsmOptions {
2651 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2652
2653 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2654 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2655
2656 pub fn human_readable_names(&self) -> Vec<&'static str> {
2657 let mut options = vec![];
2658
2659 if self.contains(InlineAsmOptions::PURE) {
2660 options.push("pure");
2661 }
2662 if self.contains(InlineAsmOptions::NOMEM) {
2663 options.push("nomem");
2664 }
2665 if self.contains(InlineAsmOptions::READONLY) {
2666 options.push("readonly");
2667 }
2668 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2669 options.push("preserves_flags");
2670 }
2671 if self.contains(InlineAsmOptions::NORETURN) {
2672 options.push("noreturn");
2673 }
2674 if self.contains(InlineAsmOptions::NOSTACK) {
2675 options.push("nostack");
2676 }
2677 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2678 options.push("att_syntax");
2679 }
2680 if self.contains(InlineAsmOptions::RAW) {
2681 options.push("raw");
2682 }
2683 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2684 options.push("may_unwind");
2685 }
2686
2687 options
2688 }
2689}
2690
2691impl std::fmt::Debug for InlineAsmOptions {
2692 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2693 bitflags::parser::to_writer(self, f)
2694 }
2695}
2696
2697#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2698pub enum InlineAsmTemplatePiece {
2699 String(Cow<'static, str>),
2700 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2701}
2702
2703impl fmt::Display for InlineAsmTemplatePiece {
2704 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2705 match self {
2706 Self::String(s) => {
2707 for c in s.chars() {
2708 match c {
2709 '{' => f.write_str("{{")?,
2710 '}' => f.write_str("}}")?,
2711 _ => c.fmt(f)?,
2712 }
2713 }
2714 Ok(())
2715 }
2716 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2717 write!(f, "{{{operand_idx}:{modifier}}}")
2718 }
2719 Self::Placeholder { operand_idx, modifier: None, .. } => {
2720 write!(f, "{{{operand_idx}}}")
2721 }
2722 }
2723 }
2724}
2725
2726impl InlineAsmTemplatePiece {
2727 pub fn to_string(s: &[Self]) -> String {
2729 use fmt::Write;
2730 let mut out = String::new();
2731 for p in s.iter() {
2732 let _ = write!(out, "{p}");
2733 }
2734 out
2735 }
2736}
2737
2738#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2746pub struct InlineAsmSym {
2747 pub id: NodeId,
2748 pub qself: Option<Box<QSelf>>,
2749 pub path: Path,
2750}
2751
2752#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2756pub enum InlineAsmOperand {
2757 In {
2758 reg: InlineAsmRegOrRegClass,
2759 expr: Box<Expr>,
2760 },
2761 Out {
2762 reg: InlineAsmRegOrRegClass,
2763 late: bool,
2764 expr: Option<Box<Expr>>,
2765 },
2766 InOut {
2767 reg: InlineAsmRegOrRegClass,
2768 late: bool,
2769 expr: Box<Expr>,
2770 },
2771 SplitInOut {
2772 reg: InlineAsmRegOrRegClass,
2773 late: bool,
2774 in_expr: Box<Expr>,
2775 out_expr: Option<Box<Expr>>,
2776 },
2777 Const {
2778 anon_const: AnonConst,
2779 },
2780 Sym {
2781 sym: InlineAsmSym,
2782 },
2783 Label {
2784 block: Box<Block>,
2785 },
2786}
2787
2788impl InlineAsmOperand {
2789 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2790 match self {
2791 Self::In { reg, .. }
2792 | Self::Out { reg, .. }
2793 | Self::InOut { reg, .. }
2794 | Self::SplitInOut { reg, .. } => Some(reg),
2795 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2796 }
2797 }
2798}
2799
2800#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2801pub enum AsmMacro {
2802 Asm,
2804 GlobalAsm,
2806 NakedAsm,
2808}
2809
2810impl AsmMacro {
2811 pub const fn macro_name(self) -> &'static str {
2812 match self {
2813 AsmMacro::Asm => "asm",
2814 AsmMacro::GlobalAsm => "global_asm",
2815 AsmMacro::NakedAsm => "naked_asm",
2816 }
2817 }
2818
2819 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2820 match self {
2821 AsmMacro::Asm => true,
2822 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2823 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2824 }
2825 }
2826
2827 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2828 match self {
2829 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2830 AsmMacro::GlobalAsm => true,
2831 AsmMacro::NakedAsm => true,
2832 }
2833 }
2834}
2835
2836#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2840pub struct InlineAsm {
2841 pub asm_macro: AsmMacro,
2842 pub template: Vec<InlineAsmTemplatePiece>,
2843 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2844 pub operands: Vec<(InlineAsmOperand, Span)>,
2845 pub clobber_abis: Vec<(Symbol, Span)>,
2846 #[visitable(ignore)]
2847 pub options: InlineAsmOptions,
2848 pub line_spans: Vec<Span>,
2849}
2850
2851#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2855pub struct Param {
2856 pub attrs: AttrVec,
2857 pub ty: Box<Ty>,
2858 pub pat: Box<Pat>,
2859 pub id: NodeId,
2860 pub span: Span,
2861 pub is_placeholder: bool,
2862}
2863
2864#[derive(Clone, Encodable, Decodable, Debug)]
2868pub enum SelfKind {
2869 Value(Mutability),
2871 Region(Option<Lifetime>, Mutability),
2873 Pinned(Option<Lifetime>, Mutability),
2875 Explicit(Box<Ty>, Mutability),
2877}
2878
2879impl SelfKind {
2880 pub fn to_ref_suggestion(&self) -> String {
2881 match self {
2882 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2883 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2884 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2885 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2886 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2887 unreachable!("if we had an explicit self, we wouldn't be here")
2888 }
2889 }
2890 }
2891}
2892
2893pub type ExplicitSelf = Spanned<SelfKind>;
2894
2895impl Param {
2896 pub fn to_self(&self) -> Option<ExplicitSelf> {
2898 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2899 if ident.name == kw::SelfLower {
2900 return match self.ty.kind {
2901 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2902 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2903 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2904 }
2905 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2906 if ty.kind.is_implicit_self() =>
2907 {
2908 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2909 }
2910 _ => Some(respan(
2911 self.pat.span.to(self.ty.span),
2912 SelfKind::Explicit(self.ty.clone(), mutbl),
2913 )),
2914 };
2915 }
2916 }
2917 None
2918 }
2919
2920 pub fn is_self(&self) -> bool {
2922 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2923 ident.name == kw::SelfLower
2924 } else {
2925 false
2926 }
2927 }
2928
2929 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2931 let span = eself.span.to(eself_ident.span);
2932 let infer_ty = Box::new(Ty {
2933 id: DUMMY_NODE_ID,
2934 kind: TyKind::ImplicitSelf,
2935 span: eself_ident.span,
2936 tokens: None,
2937 });
2938 let (mutbl, ty) = match eself.node {
2939 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2940 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2941 SelfKind::Region(lt, mutbl) => (
2942 Mutability::Not,
2943 Box::new(Ty {
2944 id: DUMMY_NODE_ID,
2945 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2946 span,
2947 tokens: None,
2948 }),
2949 ),
2950 SelfKind::Pinned(lt, mutbl) => (
2951 mutbl,
2952 Box::new(Ty {
2953 id: DUMMY_NODE_ID,
2954 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2955 span,
2956 tokens: None,
2957 }),
2958 ),
2959 };
2960 Param {
2961 attrs,
2962 pat: Box::new(Pat {
2963 id: DUMMY_NODE_ID,
2964 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2965 span,
2966 tokens: None,
2967 }),
2968 span,
2969 ty,
2970 id: DUMMY_NODE_ID,
2971 is_placeholder: false,
2972 }
2973 }
2974}
2975
2976#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2983pub struct FnDecl {
2984 pub inputs: ThinVec<Param>,
2985 pub output: FnRetTy,
2986}
2987
2988impl FnDecl {
2989 pub fn has_self(&self) -> bool {
2990 self.inputs.get(0).is_some_and(Param::is_self)
2991 }
2992 pub fn c_variadic(&self) -> bool {
2993 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2994 }
2995}
2996
2997#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2999pub enum IsAuto {
3000 Yes,
3001 No,
3002}
3003
3004#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3006#[derive(HashStable_Generic, Walkable)]
3007pub enum Safety {
3008 Unsafe(Span),
3010 Safe(Span),
3012 Default,
3015}
3016
3017#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3023pub enum CoroutineKind {
3024 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3026 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3028 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3030}
3031
3032impl CoroutineKind {
3033 pub fn span(self) -> Span {
3034 match self {
3035 CoroutineKind::Async { span, .. } => span,
3036 CoroutineKind::Gen { span, .. } => span,
3037 CoroutineKind::AsyncGen { span, .. } => span,
3038 }
3039 }
3040
3041 pub fn as_str(self) -> &'static str {
3042 match self {
3043 CoroutineKind::Async { .. } => "async",
3044 CoroutineKind::Gen { .. } => "gen",
3045 CoroutineKind::AsyncGen { .. } => "async gen",
3046 }
3047 }
3048
3049 pub fn closure_id(self) -> NodeId {
3050 match self {
3051 CoroutineKind::Async { closure_id, .. }
3052 | CoroutineKind::Gen { closure_id, .. }
3053 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3054 }
3055 }
3056
3057 pub fn return_id(self) -> (NodeId, Span) {
3060 match self {
3061 CoroutineKind::Async { return_impl_trait_id, span, .. }
3062 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3063 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3064 (return_impl_trait_id, span)
3065 }
3066 }
3067 }
3068}
3069
3070#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3071#[derive(HashStable_Generic, Walkable)]
3072pub enum Const {
3073 Yes(Span),
3074 No,
3075}
3076
3077#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3080pub enum Defaultness {
3081 Default(Span),
3082 Final,
3083}
3084
3085#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3086pub enum ImplPolarity {
3087 Positive,
3089 Negative(Span),
3091}
3092
3093impl fmt::Debug for ImplPolarity {
3094 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3095 match *self {
3096 ImplPolarity::Positive => "positive".fmt(f),
3097 ImplPolarity::Negative(_) => "negative".fmt(f),
3098 }
3099 }
3100}
3101
3102#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3104#[derive(HashStable_Generic, Walkable)]
3105pub enum BoundPolarity {
3106 Positive,
3108 Negative(Span),
3110 Maybe(Span),
3112}
3113
3114impl BoundPolarity {
3115 pub fn as_str(self) -> &'static str {
3116 match self {
3117 Self::Positive => "",
3118 Self::Negative(_) => "!",
3119 Self::Maybe(_) => "?",
3120 }
3121 }
3122}
3123
3124#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3126#[derive(HashStable_Generic, Walkable)]
3127pub enum BoundConstness {
3128 Never,
3130 Always(Span),
3132 Maybe(Span),
3134}
3135
3136impl BoundConstness {
3137 pub fn as_str(self) -> &'static str {
3138 match self {
3139 Self::Never => "",
3140 Self::Always(_) => "const",
3141 Self::Maybe(_) => "[const]",
3142 }
3143 }
3144}
3145
3146#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3148#[derive(HashStable_Generic, Walkable)]
3149pub enum BoundAsyncness {
3150 Normal,
3152 Async(Span),
3154}
3155
3156impl BoundAsyncness {
3157 pub fn as_str(self) -> &'static str {
3158 match self {
3159 Self::Normal => "",
3160 Self::Async(_) => "async",
3161 }
3162 }
3163}
3164
3165#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3166pub enum FnRetTy {
3167 Default(Span),
3172 Ty(Box<Ty>),
3174}
3175
3176impl FnRetTy {
3177 pub fn span(&self) -> Span {
3178 match self {
3179 &FnRetTy::Default(span) => span,
3180 FnRetTy::Ty(ty) => ty.span,
3181 }
3182 }
3183}
3184
3185#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3186pub enum Inline {
3187 Yes,
3188 No { had_parse_error: Result<(), ErrorGuaranteed> },
3189}
3190
3191#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3193pub enum ModKind {
3194 Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3199 Unloaded,
3201}
3202
3203#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3204pub struct ModSpans {
3205 pub inner_span: Span,
3208 pub inject_use_span: Span,
3209}
3210
3211#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3215pub struct ForeignMod {
3216 pub extern_span: Span,
3218 pub safety: Safety,
3221 pub abi: Option<StrLit>,
3222 pub items: ThinVec<Box<ForeignItem>>,
3223}
3224
3225#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3226pub struct EnumDef {
3227 pub variants: ThinVec<Variant>,
3228}
3229
3230#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3232pub struct Variant {
3233 pub attrs: AttrVec,
3235 pub id: NodeId,
3237 pub span: Span,
3239 pub vis: Visibility,
3241 pub ident: Ident,
3243
3244 pub data: VariantData,
3246 pub disr_expr: Option<AnonConst>,
3248 pub is_placeholder: bool,
3250}
3251
3252#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3254pub enum UseTreeKind {
3255 Simple(Option<Ident>),
3257 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3266 Glob,
3268}
3269
3270#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3273pub struct UseTree {
3274 pub prefix: Path,
3275 pub kind: UseTreeKind,
3276 pub span: Span,
3277}
3278
3279impl UseTree {
3280 pub fn ident(&self) -> Ident {
3281 match self.kind {
3282 UseTreeKind::Simple(Some(rename)) => rename,
3283 UseTreeKind::Simple(None) => {
3284 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3285 }
3286 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3287 }
3288 }
3289}
3290
3291#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3295pub enum AttrStyle {
3296 Outer,
3297 Inner,
3298}
3299
3300pub type AttrVec = ThinVec<Attribute>;
3302
3303#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3305pub struct Attribute {
3306 pub kind: AttrKind,
3307 pub id: AttrId,
3308 pub style: AttrStyle,
3311 pub span: Span,
3312}
3313
3314#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3315pub enum AttrKind {
3316 Normal(Box<NormalAttr>),
3318
3319 DocComment(CommentKind, Symbol),
3323}
3324
3325#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3326pub struct NormalAttr {
3327 pub item: AttrItem,
3328 pub tokens: Option<LazyAttrTokenStream>,
3330}
3331
3332impl NormalAttr {
3333 pub fn from_ident(ident: Ident) -> Self {
3334 Self {
3335 item: AttrItem {
3336 unsafety: Safety::Default,
3337 path: Path::from_ident(ident),
3338 args: AttrArgs::Empty,
3339 tokens: None,
3340 },
3341 tokens: None,
3342 }
3343 }
3344}
3345
3346#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3347pub struct AttrItem {
3348 pub unsafety: Safety,
3349 pub path: Path,
3350 pub args: AttrArgs,
3351 pub tokens: Option<LazyAttrTokenStream>,
3353}
3354
3355impl AttrItem {
3356 pub fn is_valid_for_outer_style(&self) -> bool {
3357 self.path == sym::cfg_attr
3358 || self.path == sym::cfg
3359 || self.path == sym::forbid
3360 || self.path == sym::warn
3361 || self.path == sym::allow
3362 || self.path == sym::deny
3363 }
3364}
3365
3366#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3373pub struct TraitRef {
3374 pub path: Path,
3375 pub ref_id: NodeId,
3376}
3377
3378#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3380pub enum Parens {
3381 Yes,
3382 No,
3383}
3384
3385#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3386pub struct PolyTraitRef {
3387 pub bound_generic_params: ThinVec<GenericParam>,
3389
3390 pub modifiers: TraitBoundModifiers,
3392
3393 pub trait_ref: TraitRef,
3395
3396 pub span: Span,
3397
3398 pub parens: Parens,
3401}
3402
3403impl PolyTraitRef {
3404 pub fn new(
3405 generic_params: ThinVec<GenericParam>,
3406 path: Path,
3407 modifiers: TraitBoundModifiers,
3408 span: Span,
3409 parens: Parens,
3410 ) -> Self {
3411 PolyTraitRef {
3412 bound_generic_params: generic_params,
3413 modifiers,
3414 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3415 span,
3416 parens,
3417 }
3418 }
3419}
3420
3421#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3422pub struct Visibility {
3423 pub kind: VisibilityKind,
3424 pub span: Span,
3425 pub tokens: Option<LazyAttrTokenStream>,
3426}
3427
3428#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3429pub enum VisibilityKind {
3430 Public,
3431 Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3432 Inherited,
3433}
3434
3435impl VisibilityKind {
3436 pub fn is_pub(&self) -> bool {
3437 matches!(self, VisibilityKind::Public)
3438 }
3439}
3440
3441#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3445pub struct FieldDef {
3446 pub attrs: AttrVec,
3447 pub id: NodeId,
3448 pub span: Span,
3449 pub vis: Visibility,
3450 pub safety: Safety,
3451 pub ident: Option<Ident>,
3452
3453 pub ty: Box<Ty>,
3454 pub default: Option<AnonConst>,
3455 pub is_placeholder: bool,
3456}
3457
3458#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3460pub enum Recovered {
3461 No,
3462 Yes(ErrorGuaranteed),
3463}
3464
3465#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3467pub enum VariantData {
3468 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3472 Tuple(ThinVec<FieldDef>, NodeId),
3476 Unit(NodeId),
3480}
3481
3482impl VariantData {
3483 pub fn fields(&self) -> &[FieldDef] {
3485 match self {
3486 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3487 _ => &[],
3488 }
3489 }
3490
3491 pub fn ctor_node_id(&self) -> Option<NodeId> {
3493 match *self {
3494 VariantData::Struct { .. } => None,
3495 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3496 }
3497 }
3498}
3499
3500#[derive(Clone, Encodable, Decodable, Debug)]
3502pub struct Item<K = ItemKind> {
3503 pub attrs: AttrVec,
3504 pub id: NodeId,
3505 pub span: Span,
3506 pub vis: Visibility,
3507
3508 pub kind: K,
3509
3510 pub tokens: Option<LazyAttrTokenStream>,
3518}
3519
3520impl Item {
3521 pub fn span_with_attributes(&self) -> Span {
3523 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3524 }
3525
3526 pub fn opt_generics(&self) -> Option<&Generics> {
3527 match &self.kind {
3528 ItemKind::ExternCrate(..)
3529 | ItemKind::Use(_)
3530 | ItemKind::Mod(..)
3531 | ItemKind::ForeignMod(_)
3532 | ItemKind::GlobalAsm(_)
3533 | ItemKind::MacCall(_)
3534 | ItemKind::Delegation(_)
3535 | ItemKind::DelegationMac(_)
3536 | ItemKind::MacroDef(..) => None,
3537 ItemKind::Static(_) => None,
3538 ItemKind::Const(i) => Some(&i.generics),
3539 ItemKind::Fn(i) => Some(&i.generics),
3540 ItemKind::TyAlias(i) => Some(&i.generics),
3541 ItemKind::TraitAlias(_, generics, _)
3542 | ItemKind::Enum(_, generics, _)
3543 | ItemKind::Struct(_, generics, _)
3544 | ItemKind::Union(_, generics, _) => Some(&generics),
3545 ItemKind::Trait(i) => Some(&i.generics),
3546 ItemKind::Impl(i) => Some(&i.generics),
3547 }
3548 }
3549}
3550
3551#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3553pub enum Extern {
3554 None,
3558 Implicit(Span),
3564 Explicit(StrLit, Span),
3568}
3569
3570impl Extern {
3571 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3572 match abi {
3573 Some(name) => Extern::Explicit(name, span),
3574 None => Extern::Implicit(span),
3575 }
3576 }
3577
3578 pub fn span(self) -> Option<Span> {
3579 match self {
3580 Extern::None => None,
3581 Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3582 }
3583 }
3584}
3585
3586#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3591pub struct FnHeader {
3592 pub constness: Const,
3594 pub coroutine_kind: Option<CoroutineKind>,
3596 pub safety: Safety,
3598 pub ext: Extern,
3600}
3601
3602impl FnHeader {
3603 pub fn has_qualifiers(&self) -> bool {
3605 let Self { safety, coroutine_kind, constness, ext } = self;
3606 matches!(safety, Safety::Unsafe(_))
3607 || coroutine_kind.is_some()
3608 || matches!(constness, Const::Yes(_))
3609 || !matches!(ext, Extern::None)
3610 }
3611}
3612
3613impl Default for FnHeader {
3614 fn default() -> FnHeader {
3615 FnHeader {
3616 safety: Safety::Default,
3617 coroutine_kind: None,
3618 constness: Const::No,
3619 ext: Extern::None,
3620 }
3621 }
3622}
3623
3624#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3625pub struct Trait {
3626 pub constness: Const,
3627 pub safety: Safety,
3628 pub is_auto: IsAuto,
3629 pub ident: Ident,
3630 pub generics: Generics,
3631 #[visitable(extra = BoundKind::SuperTraits)]
3632 pub bounds: GenericBounds,
3633 #[visitable(extra = AssocCtxt::Trait)]
3634 pub items: ThinVec<Box<AssocItem>>,
3635}
3636
3637#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3656pub struct TyAliasWhereClause {
3657 pub has_where_token: bool,
3658 pub span: Span,
3659}
3660
3661#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3663pub struct TyAliasWhereClauses {
3664 pub before: TyAliasWhereClause,
3666 pub after: TyAliasWhereClause,
3668 pub split: usize,
3672}
3673
3674#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3675pub struct TyAlias {
3676 pub defaultness: Defaultness,
3677 pub ident: Ident,
3678 pub generics: Generics,
3679 pub where_clauses: TyAliasWhereClauses,
3680 #[visitable(extra = BoundKind::Bound)]
3681 pub bounds: GenericBounds,
3682 pub ty: Option<Box<Ty>>,
3683}
3684
3685#[derive(Clone, Encodable, Decodable, Debug)]
3686pub struct Impl {
3687 pub generics: Generics,
3688 pub of_trait: Option<Box<TraitImplHeader>>,
3689 pub self_ty: Box<Ty>,
3690 pub items: ThinVec<Box<AssocItem>>,
3691}
3692
3693#[derive(Clone, Encodable, Decodable, Debug)]
3694pub struct TraitImplHeader {
3695 pub defaultness: Defaultness,
3696 pub safety: Safety,
3697 pub constness: Const,
3698 pub polarity: ImplPolarity,
3699 pub trait_ref: TraitRef,
3700}
3701
3702#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3703pub struct FnContract {
3704 pub requires: Option<Box<Expr>>,
3705 pub ensures: Option<Box<Expr>>,
3706}
3707
3708#[derive(Clone, Encodable, Decodable, Debug)]
3709pub struct Fn {
3710 pub defaultness: Defaultness,
3711 pub ident: Ident,
3712 pub generics: Generics,
3713 pub sig: FnSig,
3714 pub contract: Option<Box<FnContract>>,
3715 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3716 pub body: Option<Box<Block>>,
3717}
3718
3719#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3720pub struct Delegation {
3721 pub id: NodeId,
3723 pub qself: Option<Box<QSelf>>,
3724 pub path: Path,
3725 pub ident: Ident,
3726 pub rename: Option<Ident>,
3727 pub body: Option<Box<Block>>,
3728 pub from_glob: bool,
3730}
3731
3732#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3733pub struct DelegationMac {
3734 pub qself: Option<Box<QSelf>>,
3735 pub prefix: Path,
3736 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3738 pub body: Option<Box<Block>>,
3739}
3740
3741#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3742pub struct StaticItem {
3743 pub ident: Ident,
3744 pub ty: Box<Ty>,
3745 pub safety: Safety,
3746 pub mutability: Mutability,
3747 pub expr: Option<Box<Expr>>,
3748 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3749}
3750
3751#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3752pub struct ConstItem {
3753 pub defaultness: Defaultness,
3754 pub ident: Ident,
3755 pub generics: Generics,
3756 pub ty: Box<Ty>,
3757 pub expr: Option<Box<Expr>>,
3758 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3759}
3760
3761#[derive(Clone, Encodable, Decodable, Debug)]
3763pub enum ItemKind {
3764 ExternCrate(Option<Symbol>, Ident),
3768 Use(UseTree),
3772 Static(Box<StaticItem>),
3776 Const(Box<ConstItem>),
3780 Fn(Box<Fn>),
3784 Mod(Safety, Ident, ModKind),
3790 ForeignMod(ForeignMod),
3794 GlobalAsm(Box<InlineAsm>),
3796 TyAlias(Box<TyAlias>),
3800 Enum(Ident, Generics, EnumDef),
3804 Struct(Ident, Generics, VariantData),
3808 Union(Ident, Generics, VariantData),
3812 Trait(Box<Trait>),
3816 TraitAlias(Ident, Generics, GenericBounds),
3820 Impl(Impl),
3824 MacCall(Box<MacCall>),
3828 MacroDef(Ident, MacroDef),
3830 Delegation(Box<Delegation>),
3834 DelegationMac(Box<DelegationMac>),
3837}
3838
3839impl ItemKind {
3840 pub fn ident(&self) -> Option<Ident> {
3841 match *self {
3842 ItemKind::ExternCrate(_, ident)
3843 | ItemKind::Static(box StaticItem { ident, .. })
3844 | ItemKind::Const(box ConstItem { ident, .. })
3845 | ItemKind::Fn(box Fn { ident, .. })
3846 | ItemKind::Mod(_, ident, _)
3847 | ItemKind::TyAlias(box TyAlias { ident, .. })
3848 | ItemKind::Enum(ident, ..)
3849 | ItemKind::Struct(ident, ..)
3850 | ItemKind::Union(ident, ..)
3851 | ItemKind::Trait(box Trait { ident, .. })
3852 | ItemKind::TraitAlias(ident, ..)
3853 | ItemKind::MacroDef(ident, _)
3854 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3855
3856 ItemKind::Use(_)
3857 | ItemKind::ForeignMod(_)
3858 | ItemKind::GlobalAsm(_)
3859 | ItemKind::Impl(_)
3860 | ItemKind::MacCall(_)
3861 | ItemKind::DelegationMac(_) => None,
3862 }
3863 }
3864
3865 pub fn article(&self) -> &'static str {
3867 use ItemKind::*;
3868 match self {
3869 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3870 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3871 | Delegation(..) | DelegationMac(..) => "a",
3872 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3873 }
3874 }
3875
3876 pub fn descr(&self) -> &'static str {
3877 match self {
3878 ItemKind::ExternCrate(..) => "extern crate",
3879 ItemKind::Use(..) => "`use` import",
3880 ItemKind::Static(..) => "static item",
3881 ItemKind::Const(..) => "constant item",
3882 ItemKind::Fn(..) => "function",
3883 ItemKind::Mod(..) => "module",
3884 ItemKind::ForeignMod(..) => "extern block",
3885 ItemKind::GlobalAsm(..) => "global asm item",
3886 ItemKind::TyAlias(..) => "type alias",
3887 ItemKind::Enum(..) => "enum",
3888 ItemKind::Struct(..) => "struct",
3889 ItemKind::Union(..) => "union",
3890 ItemKind::Trait(..) => "trait",
3891 ItemKind::TraitAlias(..) => "trait alias",
3892 ItemKind::MacCall(..) => "item macro invocation",
3893 ItemKind::MacroDef(..) => "macro definition",
3894 ItemKind::Impl { .. } => "implementation",
3895 ItemKind::Delegation(..) => "delegated function",
3896 ItemKind::DelegationMac(..) => "delegation",
3897 }
3898 }
3899
3900 pub fn generics(&self) -> Option<&Generics> {
3901 match self {
3902 Self::Fn(box Fn { generics, .. })
3903 | Self::TyAlias(box TyAlias { generics, .. })
3904 | Self::Const(box ConstItem { generics, .. })
3905 | Self::Enum(_, generics, _)
3906 | Self::Struct(_, generics, _)
3907 | Self::Union(_, generics, _)
3908 | Self::Trait(box Trait { generics, .. })
3909 | Self::TraitAlias(_, generics, _)
3910 | Self::Impl(Impl { generics, .. }) => Some(generics),
3911 _ => None,
3912 }
3913 }
3914}
3915
3916pub type AssocItem = Item<AssocItemKind>;
3919
3920#[derive(Clone, Encodable, Decodable, Debug)]
3928pub enum AssocItemKind {
3929 Const(Box<ConstItem>),
3932 Fn(Box<Fn>),
3934 Type(Box<TyAlias>),
3936 MacCall(Box<MacCall>),
3938 Delegation(Box<Delegation>),
3940 DelegationMac(Box<DelegationMac>),
3942}
3943
3944impl AssocItemKind {
3945 pub fn ident(&self) -> Option<Ident> {
3946 match *self {
3947 AssocItemKind::Const(box ConstItem { ident, .. })
3948 | AssocItemKind::Fn(box Fn { ident, .. })
3949 | AssocItemKind::Type(box TyAlias { ident, .. })
3950 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3951
3952 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3953 }
3954 }
3955
3956 pub fn defaultness(&self) -> Defaultness {
3957 match *self {
3958 Self::Const(box ConstItem { defaultness, .. })
3959 | Self::Fn(box Fn { defaultness, .. })
3960 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3961 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3962 Defaultness::Final
3963 }
3964 }
3965 }
3966}
3967
3968impl From<AssocItemKind> for ItemKind {
3969 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3970 match assoc_item_kind {
3971 AssocItemKind::Const(item) => ItemKind::Const(item),
3972 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3973 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3974 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3975 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3976 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3977 }
3978 }
3979}
3980
3981impl TryFrom<ItemKind> for AssocItemKind {
3982 type Error = ItemKind;
3983
3984 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3985 Ok(match item_kind {
3986 ItemKind::Const(item) => AssocItemKind::Const(item),
3987 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3988 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3989 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3990 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3991 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3992 _ => return Err(item_kind),
3993 })
3994 }
3995}
3996
3997#[derive(Clone, Encodable, Decodable, Debug)]
3999pub enum ForeignItemKind {
4000 Static(Box<StaticItem>),
4002 Fn(Box<Fn>),
4004 TyAlias(Box<TyAlias>),
4006 MacCall(Box<MacCall>),
4008}
4009
4010impl ForeignItemKind {
4011 pub fn ident(&self) -> Option<Ident> {
4012 match *self {
4013 ForeignItemKind::Static(box StaticItem { ident, .. })
4014 | ForeignItemKind::Fn(box Fn { ident, .. })
4015 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4016
4017 ForeignItemKind::MacCall(_) => None,
4018 }
4019 }
4020}
4021
4022impl From<ForeignItemKind> for ItemKind {
4023 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4024 match foreign_item_kind {
4025 ForeignItemKind::Static(box static_foreign_item) => {
4026 ItemKind::Static(Box::new(static_foreign_item))
4027 }
4028 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4029 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4030 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4031 }
4032 }
4033}
4034
4035impl TryFrom<ItemKind> for ForeignItemKind {
4036 type Error = ItemKind;
4037
4038 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4039 Ok(match item_kind {
4040 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4041 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4042 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4043 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4044 _ => return Err(item_kind),
4045 })
4046 }
4047}
4048
4049pub type ForeignItem = Item<ForeignItemKind>;
4050
4051#[cfg(target_pointer_width = "64")]
4053mod size_asserts {
4054 use rustc_data_structures::static_assert_size;
4055
4056 use super::*;
4057 static_assert_size!(AssocItem, 80);
4059 static_assert_size!(AssocItemKind, 16);
4060 static_assert_size!(Attribute, 32);
4061 static_assert_size!(Block, 32);
4062 static_assert_size!(Expr, 72);
4063 static_assert_size!(ExprKind, 40);
4064 static_assert_size!(Fn, 184);
4065 static_assert_size!(ForeignItem, 80);
4066 static_assert_size!(ForeignItemKind, 16);
4067 static_assert_size!(GenericArg, 24);
4068 static_assert_size!(GenericBound, 88);
4069 static_assert_size!(Generics, 40);
4070 static_assert_size!(Impl, 64);
4071 static_assert_size!(Item, 144);
4072 static_assert_size!(ItemKind, 80);
4073 static_assert_size!(LitKind, 24);
4074 static_assert_size!(Local, 96);
4075 static_assert_size!(MetaItemLit, 40);
4076 static_assert_size!(Param, 40);
4077 static_assert_size!(Pat, 80);
4078 static_assert_size!(PatKind, 56);
4079 static_assert_size!(Path, 24);
4080 static_assert_size!(PathSegment, 24);
4081 static_assert_size!(Stmt, 32);
4082 static_assert_size!(StmtKind, 16);
4083 static_assert_size!(TraitImplHeader, 80);
4084 static_assert_size!(Ty, 64);
4085 static_assert_size!(TyKind, 40);
4086 }