1use std::borrow::Cow;
22use std::sync::Arc;
23use std::{cmp, fmt};
24
25pub use GenericArgs::*;
26pub use UnsafeSource::*;
27pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
28use rustc_data_structures::packed::Pu128;
29use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30use rustc_data_structures::stack::ensure_sufficient_stack;
31use rustc_data_structures::tagged_ptr::Tag;
32use rustc_macros::{Decodable, Encodable, HashStable_Generic};
33pub use rustc_span::AttrId;
34use rustc_span::source_map::{Spanned, respan};
35use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
36use thin_vec::{ThinVec, thin_vec};
37
38pub use crate::format::*;
39use crate::ptr::P;
40use crate::token::{self, CommentKind, Delimiter};
41use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42use crate::util::parser::{ExprPrecedence, Fixity};
43
44#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq)]
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)]
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)]
92pub struct Path {
93 pub span: Span,
94 pub segments: ThinVec<PathSegment>,
97 pub tokens: Option<LazyAttrTokenStream>,
98}
99
100impl PartialEq<Symbol> for Path {
101 #[inline]
102 fn eq(&self, name: &Symbol) -> bool {
103 if let [segment] = self.segments.as_ref()
104 && segment.args.is_none()
105 && segment.ident.name == *name
106 {
107 true
108 } else {
109 false
110 }
111 }
112}
113
114impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
115 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
116 self.segments.len().hash_stable(hcx, hasher);
117 for segment in &self.segments {
118 segment.ident.hash_stable(hcx, hasher);
119 }
120 }
121}
122
123impl Path {
124 pub fn from_ident(ident: Ident) -> Path {
127 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
128 }
129
130 pub fn is_global(&self) -> bool {
131 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
132 }
133
134 #[tracing::instrument(level = "debug", ret)]
144 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
145 allow_mgca_arg
146 || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
147 }
148}
149
150#[derive(Clone, Encodable, Decodable, Debug)]
154pub struct PathSegment {
155 pub ident: Ident,
157
158 pub id: NodeId,
159
160 pub args: Option<P<GenericArgs>>,
167}
168
169impl PathSegment {
170 pub fn from_ident(ident: Ident) -> Self {
171 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
172 }
173
174 pub fn path_root(span: Span) -> Self {
175 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
176 }
177
178 pub fn span(&self) -> Span {
179 match &self.args {
180 Some(args) => self.ident.span.to(args.span()),
181 None => self.ident.span,
182 }
183 }
184}
185
186#[derive(Clone, Encodable, Decodable, Debug)]
190pub enum GenericArgs {
191 AngleBracketed(AngleBracketedArgs),
193 Parenthesized(ParenthesizedArgs),
195 ParenthesizedElided(Span),
197}
198
199impl GenericArgs {
200 pub fn is_angle_bracketed(&self) -> bool {
201 matches!(self, AngleBracketed(..))
202 }
203
204 pub fn span(&self) -> Span {
205 match self {
206 AngleBracketed(data) => data.span,
207 Parenthesized(data) => data.span,
208 ParenthesizedElided(span) => *span,
209 }
210 }
211}
212
213#[derive(Clone, Encodable, Decodable, Debug)]
215pub enum GenericArg {
216 Lifetime(Lifetime),
218 Type(P<Ty>),
220 Const(AnonConst),
222}
223
224impl GenericArg {
225 pub fn span(&self) -> Span {
226 match self {
227 GenericArg::Lifetime(lt) => lt.ident.span,
228 GenericArg::Type(ty) => ty.span,
229 GenericArg::Const(ct) => ct.value.span,
230 }
231 }
232}
233
234#[derive(Clone, Encodable, Decodable, Debug, Default)]
236pub struct AngleBracketedArgs {
237 pub span: Span,
239 pub args: ThinVec<AngleBracketedArg>,
241}
242
243#[derive(Clone, Encodable, Decodable, Debug)]
245pub enum AngleBracketedArg {
246 Arg(GenericArg),
248 Constraint(AssocItemConstraint),
250}
251
252impl AngleBracketedArg {
253 pub fn span(&self) -> Span {
254 match self {
255 AngleBracketedArg::Arg(arg) => arg.span(),
256 AngleBracketedArg::Constraint(constraint) => constraint.span,
257 }
258 }
259}
260
261impl From<AngleBracketedArgs> for P<GenericArgs> {
262 fn from(val: AngleBracketedArgs) -> Self {
263 P(GenericArgs::AngleBracketed(val))
264 }
265}
266
267impl From<ParenthesizedArgs> for P<GenericArgs> {
268 fn from(val: ParenthesizedArgs) -> Self {
269 P(GenericArgs::Parenthesized(val))
270 }
271}
272
273#[derive(Clone, Encodable, Decodable, Debug)]
275pub struct ParenthesizedArgs {
276 pub span: Span,
281
282 pub inputs: ThinVec<P<Ty>>,
284
285 pub inputs_span: Span,
290
291 pub output: FnRetTy,
293}
294
295impl ParenthesizedArgs {
296 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
297 let args = self
298 .inputs
299 .iter()
300 .cloned()
301 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
302 .collect();
303 AngleBracketedArgs { span: self.inputs_span, args }
304 }
305}
306
307pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
308
309#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
311pub struct TraitBoundModifiers {
312 pub constness: BoundConstness,
313 pub asyncness: BoundAsyncness,
314 pub polarity: BoundPolarity,
315}
316
317impl TraitBoundModifiers {
318 pub const NONE: Self = Self {
319 constness: BoundConstness::Never,
320 asyncness: BoundAsyncness::Normal,
321 polarity: BoundPolarity::Positive,
322 };
323}
324
325#[derive(Clone, Encodable, Decodable, Debug)]
326pub enum GenericBound {
327 Trait(PolyTraitRef),
328 Outlives(Lifetime),
329 Use(ThinVec<PreciseCapturingArg>, Span),
331}
332
333impl GenericBound {
334 pub fn span(&self) -> Span {
335 match self {
336 GenericBound::Trait(t, ..) => t.span,
337 GenericBound::Outlives(l) => l.ident.span,
338 GenericBound::Use(_, span) => *span,
339 }
340 }
341}
342
343pub type GenericBounds = Vec<GenericBound>;
344
345#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
349pub enum ParamKindOrd {
350 Lifetime,
351 TypeOrConst,
352}
353
354impl fmt::Display for ParamKindOrd {
355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356 match self {
357 ParamKindOrd::Lifetime => "lifetime".fmt(f),
358 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
359 }
360 }
361}
362
363#[derive(Clone, Encodable, Decodable, Debug)]
364pub enum GenericParamKind {
365 Lifetime,
367 Type {
368 default: Option<P<Ty>>,
369 },
370 Const {
371 ty: P<Ty>,
372 kw_span: Span,
374 default: Option<AnonConst>,
376 },
377}
378
379#[derive(Clone, Encodable, Decodable, Debug)]
380pub struct GenericParam {
381 pub id: NodeId,
382 pub ident: Ident,
383 pub attrs: AttrVec,
384 pub bounds: GenericBounds,
385 pub is_placeholder: bool,
386 pub kind: GenericParamKind,
387 pub colon_span: Option<Span>,
388}
389
390impl GenericParam {
391 pub fn span(&self) -> Span {
392 match &self.kind {
393 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
394 self.ident.span
395 }
396 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
397 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
398 kw_span.to(default.value.span)
399 }
400 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
401 }
402 }
403}
404
405#[derive(Clone, Encodable, Decodable, Debug, Default)]
408pub struct Generics {
409 pub params: ThinVec<GenericParam>,
410 pub where_clause: WhereClause,
411 pub span: Span,
412}
413
414#[derive(Clone, Encodable, Decodable, Debug, Default)]
416pub struct WhereClause {
417 pub has_where_token: bool,
422 pub predicates: ThinVec<WherePredicate>,
423 pub span: Span,
424}
425
426impl WhereClause {
427 pub fn is_empty(&self) -> bool {
428 !self.has_where_token && self.predicates.is_empty()
429 }
430}
431
432#[derive(Clone, Encodable, Decodable, Debug)]
434pub struct WherePredicate {
435 pub attrs: AttrVec,
436 pub kind: WherePredicateKind,
437 pub id: NodeId,
438 pub span: Span,
439 pub is_placeholder: bool,
440}
441
442#[derive(Clone, Encodable, Decodable, Debug)]
444pub enum WherePredicateKind {
445 BoundPredicate(WhereBoundPredicate),
447 RegionPredicate(WhereRegionPredicate),
449 EqPredicate(WhereEqPredicate),
451}
452
453#[derive(Clone, Encodable, Decodable, Debug)]
457pub struct WhereBoundPredicate {
458 pub bound_generic_params: ThinVec<GenericParam>,
460 pub bounded_ty: P<Ty>,
462 pub bounds: GenericBounds,
464}
465
466#[derive(Clone, Encodable, Decodable, Debug)]
470pub struct WhereRegionPredicate {
471 pub lifetime: Lifetime,
472 pub bounds: GenericBounds,
473}
474
475#[derive(Clone, Encodable, Decodable, Debug)]
479pub struct WhereEqPredicate {
480 pub lhs_ty: P<Ty>,
481 pub rhs_ty: P<Ty>,
482}
483
484#[derive(Clone, Encodable, Decodable, Debug)]
485pub struct Crate {
486 pub attrs: AttrVec,
487 pub items: ThinVec<P<Item>>,
488 pub spans: ModSpans,
489 pub id: NodeId,
492 pub is_placeholder: bool,
493}
494
495#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
502pub struct MetaItem {
503 pub unsafety: Safety,
504 pub path: Path,
505 pub kind: MetaItemKind,
506 pub span: Span,
507}
508
509#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
511pub enum MetaItemKind {
512 Word,
516
517 List(ThinVec<MetaItemInner>),
521
522 NameValue(MetaItemLit),
526}
527
528#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
532pub enum MetaItemInner {
533 MetaItem(MetaItem),
535
536 Lit(MetaItemLit),
540}
541
542#[derive(Clone, Encodable, Decodable, Debug)]
546pub struct Block {
547 pub stmts: ThinVec<Stmt>,
549 pub id: NodeId,
550 pub rules: BlockCheckMode,
552 pub span: Span,
553 pub tokens: Option<LazyAttrTokenStream>,
554}
555
556#[derive(Clone, Encodable, Decodable, Debug)]
560pub struct Pat {
561 pub id: NodeId,
562 pub kind: PatKind,
563 pub span: Span,
564 pub tokens: Option<LazyAttrTokenStream>,
565}
566
567impl Pat {
568 pub fn to_ty(&self) -> Option<P<Ty>> {
571 let kind = match &self.kind {
572 PatKind::Missing => unreachable!(),
573 PatKind::Wild => TyKind::Infer,
575 PatKind::Ident(BindingMode::NONE, ident, None) => {
577 TyKind::Path(None, Path::from_ident(*ident))
578 }
579 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
580 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
581 PatKind::Ref(pat, mutbl) => {
583 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
584 }
585 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
588 pat.to_ty().map(TyKind::Slice)?
589 }
590 PatKind::Tuple(pats) => {
593 let mut tys = ThinVec::with_capacity(pats.len());
594 for pat in pats {
596 tys.push(pat.to_ty()?);
597 }
598 TyKind::Tup(tys)
599 }
600 _ => return None,
601 };
602
603 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
604 }
605
606 pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
610 if !it(self) {
611 return;
612 }
613
614 match &self.kind {
615 PatKind::Ident(_, _, Some(p)) => p.walk(it),
617
618 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
620
621 PatKind::TupleStruct(_, _, s)
623 | PatKind::Tuple(s)
624 | PatKind::Slice(s)
625 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
626
627 PatKind::Box(s)
629 | PatKind::Deref(s)
630 | PatKind::Ref(s, _)
631 | PatKind::Paren(s)
632 | PatKind::Guard(s, _) => s.walk(it),
633
634 PatKind::Missing
636 | PatKind::Wild
637 | PatKind::Rest
638 | PatKind::Never
639 | PatKind::Expr(_)
640 | PatKind::Range(..)
641 | PatKind::Ident(..)
642 | PatKind::Path(..)
643 | PatKind::MacCall(_)
644 | PatKind::Err(_) => {}
645 }
646 }
647
648 pub fn is_rest(&self) -> bool {
650 matches!(self.kind, PatKind::Rest)
651 }
652
653 pub fn could_be_never_pattern(&self) -> bool {
656 let mut could_be_never_pattern = false;
657 self.walk(&mut |pat| match &pat.kind {
658 PatKind::Never | PatKind::MacCall(_) => {
659 could_be_never_pattern = true;
660 false
661 }
662 PatKind::Or(s) => {
663 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
664 false
665 }
666 _ => true,
667 });
668 could_be_never_pattern
669 }
670
671 pub fn contains_never_pattern(&self) -> bool {
674 let mut contains_never_pattern = false;
675 self.walk(&mut |pat| {
676 if matches!(pat.kind, PatKind::Never) {
677 contains_never_pattern = true;
678 }
679 true
680 });
681 contains_never_pattern
682 }
683
684 pub fn descr(&self) -> Option<String> {
686 match &self.kind {
687 PatKind::Missing => unreachable!(),
688 PatKind::Wild => Some("_".to_string()),
689 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
690 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
691 _ => None,
692 }
693 }
694}
695
696#[derive(Clone, Encodable, Decodable, Debug)]
702pub struct PatField {
703 pub ident: Ident,
705 pub pat: P<Pat>,
707 pub is_shorthand: bool,
708 pub attrs: AttrVec,
709 pub id: NodeId,
710 pub span: Span,
711 pub is_placeholder: bool,
712}
713
714#[derive(Clone, Copy, Debug, Eq, PartialEq)]
715#[derive(Encodable, Decodable, HashStable_Generic)]
716pub enum ByRef {
717 Yes(Mutability),
718 No,
719}
720
721impl ByRef {
722 #[must_use]
723 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
724 if let ByRef::Yes(old_mutbl) = &mut self {
725 *old_mutbl = cmp::min(*old_mutbl, mutbl);
726 }
727 self
728 }
729}
730
731#[derive(Clone, Copy, Debug, Eq, PartialEq)]
737#[derive(Encodable, Decodable, HashStable_Generic)]
738pub struct BindingMode(pub ByRef, pub Mutability);
739
740impl BindingMode {
741 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
742 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
743 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
744 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
745 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
746 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
747
748 pub fn prefix_str(self) -> &'static str {
749 match self {
750 Self::NONE => "",
751 Self::REF => "ref ",
752 Self::MUT => "mut ",
753 Self::REF_MUT => "ref mut ",
754 Self::MUT_REF => "mut ref ",
755 Self::MUT_REF_MUT => "mut ref mut ",
756 }
757 }
758}
759
760#[derive(Clone, Encodable, Decodable, Debug)]
761pub enum RangeEnd {
762 Included(RangeSyntax),
764 Excluded,
766}
767
768#[derive(Clone, Encodable, Decodable, Debug)]
769pub enum RangeSyntax {
770 DotDotDot,
772 DotDotEq,
774}
775
776#[derive(Clone, Encodable, Decodable, Debug)]
780pub enum PatKind {
781 Missing,
783
784 Wild,
786
787 Ident(BindingMode, Ident, Option<P<Pat>>),
792
793 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
795
796 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
798
799 Or(ThinVec<P<Pat>>),
802
803 Path(Option<P<QSelf>>, Path),
808
809 Tuple(ThinVec<P<Pat>>),
811
812 Box(P<Pat>),
814
815 Deref(P<Pat>),
817
818 Ref(P<Pat>, Mutability),
820
821 Expr(P<Expr>),
823
824 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
826
827 Slice(ThinVec<P<Pat>>),
829
830 Rest,
843
844 Never,
846
847 Guard(P<Pat>, P<Expr>),
849
850 Paren(P<Pat>),
852
853 MacCall(P<MacCall>),
855
856 Err(ErrorGuaranteed),
858}
859
860#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
862pub enum PatFieldsRest {
863 Rest,
865 Recovered(ErrorGuaranteed),
867 None,
869}
870
871#[derive(Clone, Copy, PartialEq, Eq, Debug)]
874#[derive(Encodable, Decodable, HashStable_Generic)]
875pub enum BorrowKind {
876 Ref,
880 Raw,
884}
885
886#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
887pub enum BinOpKind {
888 Add,
890 Sub,
892 Mul,
894 Div,
896 Rem,
898 And,
900 Or,
902 BitXor,
904 BitAnd,
906 BitOr,
908 Shl,
910 Shr,
912 Eq,
914 Lt,
916 Le,
918 Ne,
920 Ge,
922 Gt,
924}
925
926impl BinOpKind {
927 pub fn as_str(&self) -> &'static str {
928 use BinOpKind::*;
929 match self {
930 Add => "+",
931 Sub => "-",
932 Mul => "*",
933 Div => "/",
934 Rem => "%",
935 And => "&&",
936 Or => "||",
937 BitXor => "^",
938 BitAnd => "&",
939 BitOr => "|",
940 Shl => "<<",
941 Shr => ">>",
942 Eq => "==",
943 Lt => "<",
944 Le => "<=",
945 Ne => "!=",
946 Ge => ">=",
947 Gt => ">",
948 }
949 }
950
951 pub fn is_lazy(&self) -> bool {
952 matches!(self, BinOpKind::And | BinOpKind::Or)
953 }
954
955 pub fn precedence(&self) -> ExprPrecedence {
956 use BinOpKind::*;
957 match *self {
958 Mul | Div | Rem => ExprPrecedence::Product,
959 Add | Sub => ExprPrecedence::Sum,
960 Shl | Shr => ExprPrecedence::Shift,
961 BitAnd => ExprPrecedence::BitAnd,
962 BitXor => ExprPrecedence::BitXor,
963 BitOr => ExprPrecedence::BitOr,
964 Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
965 And => ExprPrecedence::LAnd,
966 Or => ExprPrecedence::LOr,
967 }
968 }
969
970 pub fn fixity(&self) -> Fixity {
971 use BinOpKind::*;
972 match self {
973 Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
974 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
975 Fixity::Left
976 }
977 }
978 }
979
980 pub fn is_comparison(self) -> bool {
981 use BinOpKind::*;
982 match self {
983 Eq | Ne | Lt | Le | Gt | Ge => true,
984 Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
985 }
986 }
987
988 pub fn is_by_value(self) -> bool {
990 !self.is_comparison()
991 }
992}
993
994pub type BinOp = Spanned<BinOpKind>;
995
996impl From<AssignOpKind> for BinOpKind {
1000 fn from(op: AssignOpKind) -> BinOpKind {
1001 match op {
1002 AssignOpKind::AddAssign => BinOpKind::Add,
1003 AssignOpKind::SubAssign => BinOpKind::Sub,
1004 AssignOpKind::MulAssign => BinOpKind::Mul,
1005 AssignOpKind::DivAssign => BinOpKind::Div,
1006 AssignOpKind::RemAssign => BinOpKind::Rem,
1007 AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1008 AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1009 AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1010 AssignOpKind::ShlAssign => BinOpKind::Shl,
1011 AssignOpKind::ShrAssign => BinOpKind::Shr,
1012 }
1013 }
1014}
1015
1016#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1017pub enum AssignOpKind {
1018 AddAssign,
1020 SubAssign,
1022 MulAssign,
1024 DivAssign,
1026 RemAssign,
1028 BitXorAssign,
1030 BitAndAssign,
1032 BitOrAssign,
1034 ShlAssign,
1036 ShrAssign,
1038}
1039
1040impl AssignOpKind {
1041 pub fn as_str(&self) -> &'static str {
1042 use AssignOpKind::*;
1043 match self {
1044 AddAssign => "+=",
1045 SubAssign => "-=",
1046 MulAssign => "*=",
1047 DivAssign => "/=",
1048 RemAssign => "%=",
1049 BitXorAssign => "^=",
1050 BitAndAssign => "&=",
1051 BitOrAssign => "|=",
1052 ShlAssign => "<<=",
1053 ShrAssign => ">>=",
1054 }
1055 }
1056
1057 pub fn is_by_value(self) -> bool {
1059 true
1060 }
1061}
1062
1063pub type AssignOp = Spanned<AssignOpKind>;
1064
1065#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
1069pub enum UnOp {
1070 Deref,
1072 Not,
1074 Neg,
1076}
1077
1078impl UnOp {
1079 pub fn as_str(&self) -> &'static str {
1080 match self {
1081 UnOp::Deref => "*",
1082 UnOp::Not => "!",
1083 UnOp::Neg => "-",
1084 }
1085 }
1086
1087 pub fn is_by_value(self) -> bool {
1089 matches!(self, Self::Neg | Self::Not)
1090 }
1091}
1092
1093#[derive(Clone, Encodable, Decodable, Debug)]
1097pub struct Stmt {
1098 pub id: NodeId,
1099 pub kind: StmtKind,
1100 pub span: Span,
1101}
1102
1103impl Stmt {
1104 pub fn has_trailing_semicolon(&self) -> bool {
1105 match &self.kind {
1106 StmtKind::Semi(_) => true,
1107 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1108 _ => false,
1109 }
1110 }
1111
1112 pub fn add_trailing_semicolon(mut self) -> Self {
1120 self.kind = match self.kind {
1121 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1122 StmtKind::MacCall(mac) => {
1123 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1124 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1125 }))
1126 }
1127 kind => kind,
1128 };
1129
1130 self
1131 }
1132
1133 pub fn is_item(&self) -> bool {
1134 matches!(self.kind, StmtKind::Item(_))
1135 }
1136
1137 pub fn is_expr(&self) -> bool {
1138 matches!(self.kind, StmtKind::Expr(_))
1139 }
1140}
1141
1142#[derive(Clone, Encodable, Decodable, Debug)]
1144pub enum StmtKind {
1145 Let(P<Local>),
1147 Item(P<Item>),
1149 Expr(P<Expr>),
1151 Semi(P<Expr>),
1153 Empty,
1155 MacCall(P<MacCallStmt>),
1157}
1158
1159#[derive(Clone, Encodable, Decodable, Debug)]
1160pub struct MacCallStmt {
1161 pub mac: P<MacCall>,
1162 pub style: MacStmtStyle,
1163 pub attrs: AttrVec,
1164 pub tokens: Option<LazyAttrTokenStream>,
1165}
1166
1167#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1168pub enum MacStmtStyle {
1169 Semicolon,
1172 Braces,
1174 NoBraces,
1178}
1179
1180#[derive(Clone, Encodable, Decodable, Debug)]
1182pub struct Local {
1183 pub id: NodeId,
1184 pub super_: Option<Span>,
1185 pub pat: P<Pat>,
1186 pub ty: Option<P<Ty>>,
1187 pub kind: LocalKind,
1188 pub span: Span,
1189 pub colon_sp: Option<Span>,
1190 pub attrs: AttrVec,
1191 pub tokens: Option<LazyAttrTokenStream>,
1192}
1193
1194#[derive(Clone, Encodable, Decodable, Debug)]
1195pub enum LocalKind {
1196 Decl,
1199 Init(P<Expr>),
1202 InitElse(P<Expr>, P<Block>),
1205}
1206
1207impl LocalKind {
1208 pub fn init(&self) -> Option<&Expr> {
1209 match self {
1210 Self::Decl => None,
1211 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1212 }
1213 }
1214
1215 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1216 match self {
1217 Self::Decl => None,
1218 Self::Init(init) => Some((init, None)),
1219 Self::InitElse(init, els) => Some((init, Some(els))),
1220 }
1221 }
1222}
1223
1224#[derive(Clone, Encodable, Decodable, Debug)]
1235pub struct Arm {
1236 pub attrs: AttrVec,
1237 pub pat: P<Pat>,
1239 pub guard: Option<P<Expr>>,
1241 pub body: Option<P<Expr>>,
1243 pub span: Span,
1244 pub id: NodeId,
1245 pub is_placeholder: bool,
1246}
1247
1248#[derive(Clone, Encodable, Decodable, Debug)]
1250pub struct ExprField {
1251 pub attrs: AttrVec,
1252 pub id: NodeId,
1253 pub span: Span,
1254 pub ident: Ident,
1255 pub expr: P<Expr>,
1256 pub is_shorthand: bool,
1257 pub is_placeholder: bool,
1258}
1259
1260#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1261pub enum BlockCheckMode {
1262 Default,
1263 Unsafe(UnsafeSource),
1264}
1265
1266#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1267pub enum UnsafeSource {
1268 CompilerGenerated,
1269 UserProvided,
1270}
1271
1272#[derive(Clone, Encodable, Decodable, Debug)]
1278pub struct AnonConst {
1279 pub id: NodeId,
1280 pub value: P<Expr>,
1281}
1282
1283#[derive(Clone, Encodable, Decodable, Debug)]
1285pub struct Expr {
1286 pub id: NodeId,
1287 pub kind: ExprKind,
1288 pub span: Span,
1289 pub attrs: AttrVec,
1290 pub tokens: Option<LazyAttrTokenStream>,
1291}
1292
1293impl Expr {
1294 pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1308 let this = self.maybe_unwrap_block();
1309 if allow_mgca_arg {
1310 matches!(this.kind, ExprKind::Path(..))
1311 } else {
1312 if let ExprKind::Path(None, path) = &this.kind
1313 && path.is_potential_trivial_const_arg(allow_mgca_arg)
1314 {
1315 true
1316 } else {
1317 false
1318 }
1319 }
1320 }
1321
1322 pub fn maybe_unwrap_block(&self) -> &Expr {
1324 if let ExprKind::Block(block, None) = &self.kind
1325 && let [stmt] = block.stmts.as_slice()
1326 && let StmtKind::Expr(expr) = &stmt.kind
1327 {
1328 expr
1329 } else {
1330 self
1331 }
1332 }
1333
1334 pub fn optionally_braced_mac_call(
1340 &self,
1341 already_stripped_block: bool,
1342 ) -> Option<(bool, NodeId)> {
1343 match &self.kind {
1344 ExprKind::Block(block, None)
1345 if let [stmt] = &*block.stmts
1346 && !already_stripped_block =>
1347 {
1348 match &stmt.kind {
1349 StmtKind::MacCall(_) => Some((true, stmt.id)),
1350 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1351 Some((true, expr.id))
1352 }
1353 _ => None,
1354 }
1355 }
1356 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1357 _ => None,
1358 }
1359 }
1360
1361 pub fn to_bound(&self) -> Option<GenericBound> {
1362 match &self.kind {
1363 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1364 ThinVec::new(),
1365 path.clone(),
1366 TraitBoundModifiers::NONE,
1367 self.span,
1368 ))),
1369 _ => None,
1370 }
1371 }
1372
1373 pub fn peel_parens(&self) -> &Expr {
1374 let mut expr = self;
1375 while let ExprKind::Paren(inner) = &expr.kind {
1376 expr = inner;
1377 }
1378 expr
1379 }
1380
1381 pub fn peel_parens_and_refs(&self) -> &Expr {
1382 let mut expr = self;
1383 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1384 {
1385 expr = inner;
1386 }
1387 expr
1388 }
1389
1390 pub fn to_ty(&self) -> Option<P<Ty>> {
1392 let kind = match &self.kind {
1393 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1395 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1396
1397 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1398
1399 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1400 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1401 }
1402
1403 ExprKind::Repeat(expr, expr_len) => {
1404 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1405 }
1406
1407 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1408 expr.to_ty().map(TyKind::Slice)?
1409 }
1410
1411 ExprKind::Tup(exprs) => {
1412 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1413 TyKind::Tup(tys)
1414 }
1415
1416 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1420 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1421 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1422 } else {
1423 return None;
1424 }
1425 }
1426
1427 ExprKind::Underscore => TyKind::Infer,
1428
1429 _ => return None,
1431 };
1432
1433 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1434 }
1435
1436 pub fn precedence(&self) -> ExprPrecedence {
1437 match &self.kind {
1438 ExprKind::Closure(closure) => {
1439 match closure.fn_decl.output {
1440 FnRetTy::Default(_) => ExprPrecedence::Jump,
1441 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1442 }
1443 }
1444
1445 ExprKind::Break(..)
1446 | ExprKind::Ret(..)
1447 | ExprKind::Yield(..)
1448 | ExprKind::Yeet(..)
1449 | ExprKind::Become(..) => ExprPrecedence::Jump,
1450
1451 ExprKind::Range(..) => ExprPrecedence::Range,
1456
1457 ExprKind::Binary(op, ..) => op.node.precedence(),
1459 ExprKind::Cast(..) => ExprPrecedence::Cast,
1460
1461 ExprKind::Assign(..) |
1462 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1463
1464 ExprKind::AddrOf(..)
1466 | ExprKind::Let(..)
1471 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1472
1473 ExprKind::Array(_)
1475 | ExprKind::Await(..)
1476 | ExprKind::Use(..)
1477 | ExprKind::Block(..)
1478 | ExprKind::Call(..)
1479 | ExprKind::ConstBlock(_)
1480 | ExprKind::Continue(..)
1481 | ExprKind::Field(..)
1482 | ExprKind::ForLoop { .. }
1483 | ExprKind::FormatArgs(..)
1484 | ExprKind::Gen(..)
1485 | ExprKind::If(..)
1486 | ExprKind::IncludedBytes(..)
1487 | ExprKind::Index(..)
1488 | ExprKind::InlineAsm(..)
1489 | ExprKind::Lit(_)
1490 | ExprKind::Loop(..)
1491 | ExprKind::MacCall(..)
1492 | ExprKind::Match(..)
1493 | ExprKind::MethodCall(..)
1494 | ExprKind::OffsetOf(..)
1495 | ExprKind::Paren(..)
1496 | ExprKind::Path(..)
1497 | ExprKind::Repeat(..)
1498 | ExprKind::Struct(..)
1499 | ExprKind::Try(..)
1500 | ExprKind::TryBlock(..)
1501 | ExprKind::Tup(_)
1502 | ExprKind::Type(..)
1503 | ExprKind::Underscore
1504 | ExprKind::UnsafeBinderCast(..)
1505 | ExprKind::While(..)
1506 | ExprKind::Err(_)
1507 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1508 }
1509 }
1510
1511 pub fn is_approximately_pattern(&self) -> bool {
1513 matches!(
1514 &self.peel_parens().kind,
1515 ExprKind::Array(_)
1516 | ExprKind::Call(_, _)
1517 | ExprKind::Tup(_)
1518 | ExprKind::Lit(_)
1519 | ExprKind::Range(_, _, _)
1520 | ExprKind::Underscore
1521 | ExprKind::Path(_, _)
1522 | ExprKind::Struct(_)
1523 )
1524 }
1525
1526 pub fn dummy() -> P<Expr> {
1530 P(Expr {
1531 id: DUMMY_NODE_ID,
1532 kind: ExprKind::Dummy,
1533 span: DUMMY_SP,
1534 attrs: ThinVec::new(),
1535 tokens: None,
1536 })
1537 }
1538}
1539
1540#[derive(Clone, Encodable, Decodable, Debug)]
1541pub struct Closure {
1542 pub binder: ClosureBinder,
1543 pub capture_clause: CaptureBy,
1544 pub constness: Const,
1545 pub coroutine_kind: Option<CoroutineKind>,
1546 pub movability: Movability,
1547 pub fn_decl: P<FnDecl>,
1548 pub body: P<Expr>,
1549 pub fn_decl_span: Span,
1551 pub fn_arg_span: Span,
1553}
1554
1555#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1557pub enum RangeLimits {
1558 HalfOpen,
1560 Closed,
1562}
1563
1564impl RangeLimits {
1565 pub fn as_str(&self) -> &'static str {
1566 match self {
1567 RangeLimits::HalfOpen => "..",
1568 RangeLimits::Closed => "..=",
1569 }
1570 }
1571}
1572
1573#[derive(Clone, Encodable, Decodable, Debug)]
1575pub struct MethodCall {
1576 pub seg: PathSegment,
1578 pub receiver: P<Expr>,
1580 pub args: ThinVec<P<Expr>>,
1582 pub span: Span,
1585}
1586
1587#[derive(Clone, Encodable, Decodable, Debug)]
1588pub enum StructRest {
1589 Base(P<Expr>),
1591 Rest(Span),
1593 None,
1595}
1596
1597#[derive(Clone, Encodable, Decodable, Debug)]
1598pub struct StructExpr {
1599 pub qself: Option<P<QSelf>>,
1600 pub path: Path,
1601 pub fields: ThinVec<ExprField>,
1602 pub rest: StructRest,
1603}
1604
1605#[derive(Clone, Encodable, Decodable, Debug)]
1607pub enum ExprKind {
1608 Array(ThinVec<P<Expr>>),
1610 ConstBlock(AnonConst),
1612 Call(P<Expr>, ThinVec<P<Expr>>),
1619 MethodCall(Box<MethodCall>),
1621 Tup(ThinVec<P<Expr>>),
1623 Binary(BinOp, P<Expr>, P<Expr>),
1625 Unary(UnOp, P<Expr>),
1627 Lit(token::Lit),
1629 Cast(P<Expr>, P<Ty>),
1631 Type(P<Expr>, P<Ty>),
1636 Let(P<Pat>, P<Expr>, Span, Recovered),
1641 If(P<Expr>, P<Block>, Option<P<Expr>>),
1648 While(P<Expr>, P<Block>, Option<Label>),
1652 ForLoop {
1658 pat: P<Pat>,
1659 iter: P<Expr>,
1660 body: P<Block>,
1661 label: Option<Label>,
1662 kind: ForLoopKind,
1663 },
1664 Loop(P<Block>, Option<Label>, Span),
1668 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1670 Closure(Box<Closure>),
1672 Block(P<Block>, Option<Label>),
1674 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1680 Await(P<Expr>, Span),
1682 Use(P<Expr>, Span),
1684
1685 TryBlock(P<Block>),
1687
1688 Assign(P<Expr>, P<Expr>, Span),
1691 AssignOp(AssignOp, P<Expr>, P<Expr>),
1695 Field(P<Expr>, Ident),
1697 Index(P<Expr>, P<Expr>, Span),
1700 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1702 Underscore,
1704
1705 Path(Option<P<QSelf>>, Path),
1710
1711 AddrOf(BorrowKind, Mutability, P<Expr>),
1713 Break(Option<Label>, Option<P<Expr>>),
1715 Continue(Option<Label>),
1717 Ret(Option<P<Expr>>),
1719
1720 InlineAsm(P<InlineAsm>),
1722
1723 OffsetOf(P<Ty>, P<[Ident]>),
1728
1729 MacCall(P<MacCall>),
1731
1732 Struct(P<StructExpr>),
1736
1737 Repeat(P<Expr>, AnonConst),
1742
1743 Paren(P<Expr>),
1745
1746 Try(P<Expr>),
1748
1749 Yield(YieldKind),
1751
1752 Yeet(Option<P<Expr>>),
1755
1756 Become(P<Expr>),
1760
1761 IncludedBytes(Arc<[u8]>),
1766
1767 FormatArgs(P<FormatArgs>),
1769
1770 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1771
1772 Err(ErrorGuaranteed),
1774
1775 Dummy,
1777}
1778
1779#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1781pub enum ForLoopKind {
1782 For,
1783 ForAwait,
1784}
1785
1786#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1788pub enum GenBlockKind {
1789 Async,
1790 Gen,
1791 AsyncGen,
1792}
1793
1794impl fmt::Display for GenBlockKind {
1795 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1796 self.modifier().fmt(f)
1797 }
1798}
1799
1800impl GenBlockKind {
1801 pub fn modifier(&self) -> &'static str {
1802 match self {
1803 GenBlockKind::Async => "async",
1804 GenBlockKind::Gen => "gen",
1805 GenBlockKind::AsyncGen => "async gen",
1806 }
1807 }
1808}
1809
1810#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1812#[derive(Encodable, Decodable, HashStable_Generic)]
1813pub enum UnsafeBinderCastKind {
1814 Wrap,
1816 Unwrap,
1818}
1819
1820#[derive(Clone, Encodable, Decodable, Debug)]
1835pub struct QSelf {
1836 pub ty: P<Ty>,
1837
1838 pub path_span: Span,
1842 pub position: usize,
1843}
1844
1845#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1847pub enum CaptureBy {
1848 Value {
1850 move_kw: Span,
1852 },
1853 Ref,
1855 Use {
1861 use_kw: Span,
1863 },
1864}
1865
1866#[derive(Clone, Encodable, Decodable, Debug)]
1868pub enum ClosureBinder {
1869 NotPresent,
1871 For {
1873 span: Span,
1880
1881 generic_params: ThinVec<GenericParam>,
1888 },
1889}
1890
1891#[derive(Clone, Encodable, Decodable, Debug)]
1894pub struct MacCall {
1895 pub path: Path,
1896 pub args: P<DelimArgs>,
1897}
1898
1899impl MacCall {
1900 pub fn span(&self) -> Span {
1901 self.path.span.to(self.args.dspan.entire())
1902 }
1903}
1904
1905#[derive(Clone, Encodable, Decodable, Debug)]
1907pub enum AttrArgs {
1908 Empty,
1910 Delimited(DelimArgs),
1912 Eq {
1914 eq_span: Span,
1916 expr: P<Expr>,
1917 },
1918}
1919
1920impl AttrArgs {
1921 pub fn span(&self) -> Option<Span> {
1922 match self {
1923 AttrArgs::Empty => None,
1924 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1925 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1926 }
1927 }
1928
1929 pub fn inner_tokens(&self) -> TokenStream {
1932 match self {
1933 AttrArgs::Empty => TokenStream::default(),
1934 AttrArgs::Delimited(args) => args.tokens.clone(),
1935 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1936 }
1937 }
1938}
1939
1940#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1942pub struct DelimArgs {
1943 pub dspan: DelimSpan,
1944 pub delim: Delimiter, pub tokens: TokenStream,
1946}
1947
1948impl DelimArgs {
1949 pub fn need_semicolon(&self) -> bool {
1952 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1953 }
1954}
1955
1956#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1958pub struct MacroDef {
1959 pub body: P<DelimArgs>,
1960 pub macro_rules: bool,
1962}
1963
1964#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1965#[derive(HashStable_Generic)]
1966pub enum StrStyle {
1967 Cooked,
1969 Raw(u8),
1973}
1974
1975#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1977pub enum MatchKind {
1978 Prefix,
1980 Postfix,
1982}
1983
1984#[derive(Clone, Encodable, Decodable, Debug)]
1986pub enum YieldKind {
1987 Prefix(Option<P<Expr>>),
1989 Postfix(P<Expr>),
1991}
1992
1993impl YieldKind {
1994 pub const fn expr(&self) -> Option<&P<Expr>> {
1998 match self {
1999 YieldKind::Prefix(expr) => expr.as_ref(),
2000 YieldKind::Postfix(expr) => Some(expr),
2001 }
2002 }
2003
2004 pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
2006 match self {
2007 YieldKind::Prefix(expr) => expr.as_mut(),
2008 YieldKind::Postfix(expr) => Some(expr),
2009 }
2010 }
2011
2012 pub const fn same_kind(&self, other: &Self) -> bool {
2014 match (self, other) {
2015 (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2016 (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2017 _ => false,
2018 }
2019 }
2020}
2021
2022#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
2024pub struct MetaItemLit {
2025 pub symbol: Symbol,
2027 pub suffix: Option<Symbol>,
2029 pub kind: LitKind,
2032 pub span: Span,
2033}
2034
2035#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2037pub struct StrLit {
2038 pub symbol: Symbol,
2040 pub suffix: Option<Symbol>,
2042 pub symbol_unescaped: Symbol,
2044 pub style: StrStyle,
2045 pub span: Span,
2046}
2047
2048impl StrLit {
2049 pub fn as_token_lit(&self) -> token::Lit {
2050 let token_kind = match self.style {
2051 StrStyle::Cooked => token::Str,
2052 StrStyle::Raw(n) => token::StrRaw(n),
2053 };
2054 token::Lit::new(token_kind, self.symbol, self.suffix)
2055 }
2056}
2057
2058#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2060#[derive(HashStable_Generic)]
2061pub enum LitIntType {
2062 Signed(IntTy),
2064 Unsigned(UintTy),
2066 Unsuffixed,
2068}
2069
2070#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2072#[derive(HashStable_Generic)]
2073pub enum LitFloatType {
2074 Suffixed(FloatTy),
2076 Unsuffixed,
2078}
2079
2080#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2087pub enum LitKind {
2088 Str(Symbol, StrStyle),
2091 ByteStr(Arc<[u8]>, StrStyle),
2094 CStr(Arc<[u8]>, StrStyle),
2096 Byte(u8),
2098 Char(char),
2100 Int(Pu128, LitIntType),
2102 Float(Symbol, LitFloatType),
2106 Bool(bool),
2108 Err(ErrorGuaranteed),
2110}
2111
2112impl LitKind {
2113 pub fn str(&self) -> Option<Symbol> {
2114 match *self {
2115 LitKind::Str(s, _) => Some(s),
2116 _ => None,
2117 }
2118 }
2119
2120 pub fn is_str(&self) -> bool {
2122 matches!(self, LitKind::Str(..))
2123 }
2124
2125 pub fn is_bytestr(&self) -> bool {
2127 matches!(self, LitKind::ByteStr(..))
2128 }
2129
2130 pub fn is_numeric(&self) -> bool {
2132 matches!(self, LitKind::Int(..) | LitKind::Float(..))
2133 }
2134
2135 pub fn is_unsuffixed(&self) -> bool {
2138 !self.is_suffixed()
2139 }
2140
2141 pub fn is_suffixed(&self) -> bool {
2143 match *self {
2144 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2146 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2147 LitKind::Str(..)
2149 | LitKind::ByteStr(..)
2150 | LitKind::CStr(..)
2151 | LitKind::Byte(..)
2152 | LitKind::Char(..)
2153 | LitKind::Int(_, LitIntType::Unsuffixed)
2154 | LitKind::Float(_, LitFloatType::Unsuffixed)
2155 | LitKind::Bool(..)
2156 | LitKind::Err(_) => false,
2157 }
2158 }
2159}
2160
2161#[derive(Clone, Encodable, Decodable, Debug)]
2164pub struct MutTy {
2165 pub ty: P<Ty>,
2166 pub mutbl: Mutability,
2167}
2168
2169#[derive(Clone, Encodable, Decodable, Debug)]
2172pub struct FnSig {
2173 pub header: FnHeader,
2174 pub decl: P<FnDecl>,
2175 pub span: Span,
2176}
2177
2178#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2179#[derive(Encodable, Decodable, HashStable_Generic)]
2180pub enum FloatTy {
2181 F16,
2182 F32,
2183 F64,
2184 F128,
2185}
2186
2187impl FloatTy {
2188 pub fn name_str(self) -> &'static str {
2189 match self {
2190 FloatTy::F16 => "f16",
2191 FloatTy::F32 => "f32",
2192 FloatTy::F64 => "f64",
2193 FloatTy::F128 => "f128",
2194 }
2195 }
2196
2197 pub fn name(self) -> Symbol {
2198 match self {
2199 FloatTy::F16 => sym::f16,
2200 FloatTy::F32 => sym::f32,
2201 FloatTy::F64 => sym::f64,
2202 FloatTy::F128 => sym::f128,
2203 }
2204 }
2205}
2206
2207#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2208#[derive(Encodable, Decodable, HashStable_Generic)]
2209pub enum IntTy {
2210 Isize,
2211 I8,
2212 I16,
2213 I32,
2214 I64,
2215 I128,
2216}
2217
2218impl IntTy {
2219 pub fn name_str(&self) -> &'static str {
2220 match *self {
2221 IntTy::Isize => "isize",
2222 IntTy::I8 => "i8",
2223 IntTy::I16 => "i16",
2224 IntTy::I32 => "i32",
2225 IntTy::I64 => "i64",
2226 IntTy::I128 => "i128",
2227 }
2228 }
2229
2230 pub fn name(&self) -> Symbol {
2231 match *self {
2232 IntTy::Isize => sym::isize,
2233 IntTy::I8 => sym::i8,
2234 IntTy::I16 => sym::i16,
2235 IntTy::I32 => sym::i32,
2236 IntTy::I64 => sym::i64,
2237 IntTy::I128 => sym::i128,
2238 }
2239 }
2240}
2241
2242#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2243#[derive(Encodable, Decodable, HashStable_Generic)]
2244pub enum UintTy {
2245 Usize,
2246 U8,
2247 U16,
2248 U32,
2249 U64,
2250 U128,
2251}
2252
2253impl UintTy {
2254 pub fn name_str(&self) -> &'static str {
2255 match *self {
2256 UintTy::Usize => "usize",
2257 UintTy::U8 => "u8",
2258 UintTy::U16 => "u16",
2259 UintTy::U32 => "u32",
2260 UintTy::U64 => "u64",
2261 UintTy::U128 => "u128",
2262 }
2263 }
2264
2265 pub fn name(&self) -> Symbol {
2266 match *self {
2267 UintTy::Usize => sym::usize,
2268 UintTy::U8 => sym::u8,
2269 UintTy::U16 => sym::u16,
2270 UintTy::U32 => sym::u32,
2271 UintTy::U64 => sym::u64,
2272 UintTy::U128 => sym::u128,
2273 }
2274 }
2275}
2276
2277#[derive(Clone, Encodable, Decodable, Debug)]
2288pub struct AssocItemConstraint {
2289 pub id: NodeId,
2290 pub ident: Ident,
2291 pub gen_args: Option<GenericArgs>,
2292 pub kind: AssocItemConstraintKind,
2293 pub span: Span,
2294}
2295
2296#[derive(Clone, Encodable, Decodable, Debug)]
2297pub enum Term {
2298 Ty(P<Ty>),
2299 Const(AnonConst),
2300}
2301
2302impl From<P<Ty>> for Term {
2303 fn from(v: P<Ty>) -> Self {
2304 Term::Ty(v)
2305 }
2306}
2307
2308impl From<AnonConst> for Term {
2309 fn from(v: AnonConst) -> Self {
2310 Term::Const(v)
2311 }
2312}
2313
2314#[derive(Clone, Encodable, Decodable, Debug)]
2316pub enum AssocItemConstraintKind {
2317 Equality { term: Term },
2324 Bound { bounds: GenericBounds },
2326}
2327
2328#[derive(Encodable, Decodable, Debug)]
2329pub struct Ty {
2330 pub id: NodeId,
2331 pub kind: TyKind,
2332 pub span: Span,
2333 pub tokens: Option<LazyAttrTokenStream>,
2334}
2335
2336impl Clone for Ty {
2337 fn clone(&self) -> Self {
2338 ensure_sufficient_stack(|| Self {
2339 id: self.id,
2340 kind: self.kind.clone(),
2341 span: self.span,
2342 tokens: self.tokens.clone(),
2343 })
2344 }
2345}
2346
2347impl Ty {
2348 pub fn peel_refs(&self) -> &Self {
2349 let mut final_ty = self;
2350 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2351 {
2352 final_ty = ty;
2353 }
2354 final_ty
2355 }
2356
2357 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2358 match &self.kind {
2359 TyKind::Infer => true,
2360 TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2361 _ => false,
2362 }
2363 }
2364}
2365
2366#[derive(Clone, Encodable, Decodable, Debug)]
2367pub struct BareFnTy {
2368 pub safety: Safety,
2369 pub ext: Extern,
2370 pub generic_params: ThinVec<GenericParam>,
2371 pub decl: P<FnDecl>,
2372 pub decl_span: Span,
2375}
2376
2377#[derive(Clone, Encodable, Decodable, Debug)]
2378pub struct UnsafeBinderTy {
2379 pub generic_params: ThinVec<GenericParam>,
2380 pub inner_ty: P<Ty>,
2381}
2382
2383#[derive(Clone, Encodable, Decodable, Debug)]
2387pub enum TyKind {
2388 Slice(P<Ty>),
2390 Array(P<Ty>, AnonConst),
2392 Ptr(MutTy),
2394 Ref(Option<Lifetime>, MutTy),
2396 PinnedRef(Option<Lifetime>, MutTy),
2400 BareFn(P<BareFnTy>),
2402 UnsafeBinder(P<UnsafeBinderTy>),
2404 Never,
2406 Tup(ThinVec<P<Ty>>),
2408 Path(Option<P<QSelf>>, Path),
2413 TraitObject(GenericBounds, TraitObjectSyntax),
2416 ImplTrait(NodeId, GenericBounds),
2423 Paren(P<Ty>),
2425 Typeof(AnonConst),
2427 Infer,
2430 ImplicitSelf,
2432 MacCall(P<MacCall>),
2434 CVarArgs,
2436 Pat(P<Ty>, P<TyPat>),
2439 Dummy,
2441 Err(ErrorGuaranteed),
2443}
2444
2445impl TyKind {
2446 pub fn is_implicit_self(&self) -> bool {
2447 matches!(self, TyKind::ImplicitSelf)
2448 }
2449
2450 pub fn is_unit(&self) -> bool {
2451 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2452 }
2453
2454 pub fn is_simple_path(&self) -> Option<Symbol> {
2455 if let TyKind::Path(None, Path { segments, .. }) = &self
2456 && let [segment] = &segments[..]
2457 && segment.args.is_none()
2458 {
2459 Some(segment.ident.name)
2460 } else {
2461 None
2462 }
2463 }
2464
2465 pub fn maybe_scalar(&self) -> bool {
2473 let Some(ty_sym) = self.is_simple_path() else {
2474 return self.is_unit();
2476 };
2477 matches!(
2478 ty_sym,
2479 sym::i8
2480 | sym::i16
2481 | sym::i32
2482 | sym::i64
2483 | sym::i128
2484 | sym::u8
2485 | sym::u16
2486 | sym::u32
2487 | sym::u64
2488 | sym::u128
2489 | sym::f16
2490 | sym::f32
2491 | sym::f64
2492 | sym::f128
2493 | sym::char
2494 | sym::bool
2495 )
2496 }
2497}
2498
2499#[derive(Clone, Encodable, Decodable, Debug)]
2501pub struct TyPat {
2502 pub id: NodeId,
2503 pub kind: TyPatKind,
2504 pub span: Span,
2505 pub tokens: Option<LazyAttrTokenStream>,
2506}
2507
2508#[derive(Clone, Encodable, Decodable, Debug)]
2512pub enum TyPatKind {
2513 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2515
2516 Or(ThinVec<P<TyPat>>),
2517
2518 Err(ErrorGuaranteed),
2520}
2521
2522#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2524#[repr(u8)]
2525pub enum TraitObjectSyntax {
2526 Dyn = 0,
2528 DynStar = 1,
2529 None = 2,
2530}
2531
2532unsafe impl Tag for TraitObjectSyntax {
2536 const BITS: u32 = 2;
2537
2538 fn into_usize(self) -> usize {
2539 self as u8 as usize
2540 }
2541
2542 unsafe fn from_usize(tag: usize) -> Self {
2543 match tag {
2544 0 => TraitObjectSyntax::Dyn,
2545 1 => TraitObjectSyntax::DynStar,
2546 2 => TraitObjectSyntax::None,
2547 _ => unreachable!(),
2548 }
2549 }
2550}
2551
2552#[derive(Clone, Encodable, Decodable, Debug)]
2553pub enum PreciseCapturingArg {
2554 Lifetime(Lifetime),
2556 Arg(Path, NodeId),
2558}
2559
2560#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2564pub enum InlineAsmRegOrRegClass {
2565 Reg(Symbol),
2566 RegClass(Symbol),
2567}
2568
2569#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2570pub struct InlineAsmOptions(u16);
2571bitflags::bitflags! {
2572 impl InlineAsmOptions: u16 {
2573 const PURE = 1 << 0;
2574 const NOMEM = 1 << 1;
2575 const READONLY = 1 << 2;
2576 const PRESERVES_FLAGS = 1 << 3;
2577 const NORETURN = 1 << 4;
2578 const NOSTACK = 1 << 5;
2579 const ATT_SYNTAX = 1 << 6;
2580 const RAW = 1 << 7;
2581 const MAY_UNWIND = 1 << 8;
2582 }
2583}
2584
2585impl InlineAsmOptions {
2586 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2587
2588 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2589 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2590
2591 pub fn human_readable_names(&self) -> Vec<&'static str> {
2592 let mut options = vec![];
2593
2594 if self.contains(InlineAsmOptions::PURE) {
2595 options.push("pure");
2596 }
2597 if self.contains(InlineAsmOptions::NOMEM) {
2598 options.push("nomem");
2599 }
2600 if self.contains(InlineAsmOptions::READONLY) {
2601 options.push("readonly");
2602 }
2603 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2604 options.push("preserves_flags");
2605 }
2606 if self.contains(InlineAsmOptions::NORETURN) {
2607 options.push("noreturn");
2608 }
2609 if self.contains(InlineAsmOptions::NOSTACK) {
2610 options.push("nostack");
2611 }
2612 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2613 options.push("att_syntax");
2614 }
2615 if self.contains(InlineAsmOptions::RAW) {
2616 options.push("raw");
2617 }
2618 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2619 options.push("may_unwind");
2620 }
2621
2622 options
2623 }
2624}
2625
2626impl std::fmt::Debug for InlineAsmOptions {
2627 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2628 bitflags::parser::to_writer(self, f)
2629 }
2630}
2631
2632#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2633pub enum InlineAsmTemplatePiece {
2634 String(Cow<'static, str>),
2635 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2636}
2637
2638impl fmt::Display for InlineAsmTemplatePiece {
2639 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2640 match self {
2641 Self::String(s) => {
2642 for c in s.chars() {
2643 match c {
2644 '{' => f.write_str("{{")?,
2645 '}' => f.write_str("}}")?,
2646 _ => c.fmt(f)?,
2647 }
2648 }
2649 Ok(())
2650 }
2651 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2652 write!(f, "{{{operand_idx}:{modifier}}}")
2653 }
2654 Self::Placeholder { operand_idx, modifier: None, .. } => {
2655 write!(f, "{{{operand_idx}}}")
2656 }
2657 }
2658 }
2659}
2660
2661impl InlineAsmTemplatePiece {
2662 pub fn to_string(s: &[Self]) -> String {
2664 use fmt::Write;
2665 let mut out = String::new();
2666 for p in s.iter() {
2667 let _ = write!(out, "{p}");
2668 }
2669 out
2670 }
2671}
2672
2673#[derive(Clone, Encodable, Decodable, Debug)]
2681pub struct InlineAsmSym {
2682 pub id: NodeId,
2683 pub qself: Option<P<QSelf>>,
2684 pub path: Path,
2685}
2686
2687#[derive(Clone, Encodable, Decodable, Debug)]
2691pub enum InlineAsmOperand {
2692 In {
2693 reg: InlineAsmRegOrRegClass,
2694 expr: P<Expr>,
2695 },
2696 Out {
2697 reg: InlineAsmRegOrRegClass,
2698 late: bool,
2699 expr: Option<P<Expr>>,
2700 },
2701 InOut {
2702 reg: InlineAsmRegOrRegClass,
2703 late: bool,
2704 expr: P<Expr>,
2705 },
2706 SplitInOut {
2707 reg: InlineAsmRegOrRegClass,
2708 late: bool,
2709 in_expr: P<Expr>,
2710 out_expr: Option<P<Expr>>,
2711 },
2712 Const {
2713 anon_const: AnonConst,
2714 },
2715 Sym {
2716 sym: InlineAsmSym,
2717 },
2718 Label {
2719 block: P<Block>,
2720 },
2721}
2722
2723impl InlineAsmOperand {
2724 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2725 match self {
2726 Self::In { reg, .. }
2727 | Self::Out { reg, .. }
2728 | Self::InOut { reg, .. }
2729 | Self::SplitInOut { reg, .. } => Some(reg),
2730 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2731 }
2732 }
2733}
2734
2735#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2736pub enum AsmMacro {
2737 Asm,
2739 GlobalAsm,
2741 NakedAsm,
2743}
2744
2745impl AsmMacro {
2746 pub const fn macro_name(self) -> &'static str {
2747 match self {
2748 AsmMacro::Asm => "asm",
2749 AsmMacro::GlobalAsm => "global_asm",
2750 AsmMacro::NakedAsm => "naked_asm",
2751 }
2752 }
2753
2754 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2755 match self {
2756 AsmMacro::Asm => true,
2757 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2758 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2759 }
2760 }
2761
2762 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2763 match self {
2764 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2765 AsmMacro::GlobalAsm => true,
2766 AsmMacro::NakedAsm => true,
2767 }
2768 }
2769}
2770
2771#[derive(Clone, Encodable, Decodable, Debug)]
2775pub struct InlineAsm {
2776 pub asm_macro: AsmMacro,
2777 pub template: Vec<InlineAsmTemplatePiece>,
2778 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2779 pub operands: Vec<(InlineAsmOperand, Span)>,
2780 pub clobber_abis: Vec<(Symbol, Span)>,
2781 pub options: InlineAsmOptions,
2782 pub line_spans: Vec<Span>,
2783}
2784
2785#[derive(Clone, Encodable, Decodable, Debug)]
2789pub struct Param {
2790 pub attrs: AttrVec,
2791 pub ty: P<Ty>,
2792 pub pat: P<Pat>,
2793 pub id: NodeId,
2794 pub span: Span,
2795 pub is_placeholder: bool,
2796}
2797
2798#[derive(Clone, Encodable, Decodable, Debug)]
2802pub enum SelfKind {
2803 Value(Mutability),
2805 Region(Option<Lifetime>, Mutability),
2807 Pinned(Option<Lifetime>, Mutability),
2809 Explicit(P<Ty>, Mutability),
2811}
2812
2813impl SelfKind {
2814 pub fn to_ref_suggestion(&self) -> String {
2815 match self {
2816 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2817 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2818 SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2819 SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2820 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2821 unreachable!("if we had an explicit self, we wouldn't be here")
2822 }
2823 }
2824 }
2825}
2826
2827pub type ExplicitSelf = Spanned<SelfKind>;
2828
2829impl Param {
2830 pub fn to_self(&self) -> Option<ExplicitSelf> {
2832 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2833 if ident.name == kw::SelfLower {
2834 return match self.ty.kind {
2835 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2836 TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2837 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2838 }
2839 TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2840 if ty.kind.is_implicit_self() =>
2841 {
2842 Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2843 }
2844 _ => Some(respan(
2845 self.pat.span.to(self.ty.span),
2846 SelfKind::Explicit(self.ty.clone(), mutbl),
2847 )),
2848 };
2849 }
2850 }
2851 None
2852 }
2853
2854 pub fn is_self(&self) -> bool {
2856 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2857 ident.name == kw::SelfLower
2858 } else {
2859 false
2860 }
2861 }
2862
2863 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2865 let span = eself.span.to(eself_ident.span);
2866 let infer_ty = P(Ty {
2867 id: DUMMY_NODE_ID,
2868 kind: TyKind::ImplicitSelf,
2869 span: eself_ident.span,
2870 tokens: None,
2871 });
2872 let (mutbl, ty) = match eself.node {
2873 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2874 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2875 SelfKind::Region(lt, mutbl) => (
2876 Mutability::Not,
2877 P(Ty {
2878 id: DUMMY_NODE_ID,
2879 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2880 span,
2881 tokens: None,
2882 }),
2883 ),
2884 SelfKind::Pinned(lt, mutbl) => (
2885 mutbl,
2886 P(Ty {
2887 id: DUMMY_NODE_ID,
2888 kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2889 span,
2890 tokens: None,
2891 }),
2892 ),
2893 };
2894 Param {
2895 attrs,
2896 pat: P(Pat {
2897 id: DUMMY_NODE_ID,
2898 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2899 span,
2900 tokens: None,
2901 }),
2902 span,
2903 ty,
2904 id: DUMMY_NODE_ID,
2905 is_placeholder: false,
2906 }
2907 }
2908}
2909
2910#[derive(Clone, Encodable, Decodable, Debug)]
2917pub struct FnDecl {
2918 pub inputs: ThinVec<Param>,
2919 pub output: FnRetTy,
2920}
2921
2922impl FnDecl {
2923 pub fn has_self(&self) -> bool {
2924 self.inputs.get(0).is_some_and(Param::is_self)
2925 }
2926 pub fn c_variadic(&self) -> bool {
2927 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2928 }
2929}
2930
2931#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2933pub enum IsAuto {
2934 Yes,
2935 No,
2936}
2937
2938#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2940#[derive(HashStable_Generic)]
2941pub enum Safety {
2942 Unsafe(Span),
2944 Safe(Span),
2946 Default,
2949}
2950
2951#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2957pub enum CoroutineKind {
2958 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2960 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2962 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2964}
2965
2966impl CoroutineKind {
2967 pub fn span(self) -> Span {
2968 match self {
2969 CoroutineKind::Async { span, .. } => span,
2970 CoroutineKind::Gen { span, .. } => span,
2971 CoroutineKind::AsyncGen { span, .. } => span,
2972 }
2973 }
2974
2975 pub fn as_str(self) -> &'static str {
2976 match self {
2977 CoroutineKind::Async { .. } => "async",
2978 CoroutineKind::Gen { .. } => "gen",
2979 CoroutineKind::AsyncGen { .. } => "async gen",
2980 }
2981 }
2982
2983 pub fn closure_id(self) -> NodeId {
2984 match self {
2985 CoroutineKind::Async { closure_id, .. }
2986 | CoroutineKind::Gen { closure_id, .. }
2987 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2988 }
2989 }
2990
2991 pub fn return_id(self) -> (NodeId, Span) {
2994 match self {
2995 CoroutineKind::Async { return_impl_trait_id, span, .. }
2996 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2997 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2998 (return_impl_trait_id, span)
2999 }
3000 }
3001 }
3002}
3003
3004#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3005#[derive(HashStable_Generic)]
3006pub enum Const {
3007 Yes(Span),
3008 No,
3009}
3010
3011#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
3014pub enum Defaultness {
3015 Default(Span),
3016 Final,
3017}
3018
3019#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
3020pub enum ImplPolarity {
3021 Positive,
3023 Negative(Span),
3025}
3026
3027impl fmt::Debug for ImplPolarity {
3028 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3029 match *self {
3030 ImplPolarity::Positive => "positive".fmt(f),
3031 ImplPolarity::Negative(_) => "negative".fmt(f),
3032 }
3033 }
3034}
3035
3036#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3038#[derive(HashStable_Generic)]
3039pub enum BoundPolarity {
3040 Positive,
3042 Negative(Span),
3044 Maybe(Span),
3046}
3047
3048impl BoundPolarity {
3049 pub fn as_str(self) -> &'static str {
3050 match self {
3051 Self::Positive => "",
3052 Self::Negative(_) => "!",
3053 Self::Maybe(_) => "?",
3054 }
3055 }
3056}
3057
3058#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3060#[derive(HashStable_Generic)]
3061pub enum BoundConstness {
3062 Never,
3064 Always(Span),
3066 Maybe(Span),
3068}
3069
3070impl BoundConstness {
3071 pub fn as_str(self) -> &'static str {
3072 match self {
3073 Self::Never => "",
3074 Self::Always(_) => "const",
3075 Self::Maybe(_) => "~const",
3076 }
3077 }
3078}
3079
3080#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3082#[derive(HashStable_Generic)]
3083pub enum BoundAsyncness {
3084 Normal,
3086 Async(Span),
3088}
3089
3090impl BoundAsyncness {
3091 pub fn as_str(self) -> &'static str {
3092 match self {
3093 Self::Normal => "",
3094 Self::Async(_) => "async",
3095 }
3096 }
3097}
3098
3099#[derive(Clone, Encodable, Decodable, Debug)]
3100pub enum FnRetTy {
3101 Default(Span),
3106 Ty(P<Ty>),
3108}
3109
3110impl FnRetTy {
3111 pub fn span(&self) -> Span {
3112 match self {
3113 &FnRetTy::Default(span) => span,
3114 FnRetTy::Ty(ty) => ty.span,
3115 }
3116 }
3117}
3118
3119#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
3120pub enum Inline {
3121 Yes,
3122 No,
3123}
3124
3125#[derive(Clone, Encodable, Decodable, Debug)]
3127pub enum ModKind {
3128 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
3133 Unloaded,
3135}
3136
3137#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3138pub struct ModSpans {
3139 pub inner_span: Span,
3142 pub inject_use_span: Span,
3143}
3144
3145#[derive(Clone, Encodable, Decodable, Debug)]
3149pub struct ForeignMod {
3150 pub extern_span: Span,
3152 pub safety: Safety,
3155 pub abi: Option<StrLit>,
3156 pub items: ThinVec<P<ForeignItem>>,
3157}
3158
3159#[derive(Clone, Encodable, Decodable, Debug)]
3160pub struct EnumDef {
3161 pub variants: ThinVec<Variant>,
3162}
3163#[derive(Clone, Encodable, Decodable, Debug)]
3165pub struct Variant {
3166 pub attrs: AttrVec,
3168 pub id: NodeId,
3170 pub span: Span,
3172 pub vis: Visibility,
3174 pub ident: Ident,
3176
3177 pub data: VariantData,
3179 pub disr_expr: Option<AnonConst>,
3181 pub is_placeholder: bool,
3183}
3184
3185#[derive(Clone, Encodable, Decodable, Debug)]
3187pub enum UseTreeKind {
3188 Simple(Option<Ident>),
3190 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3199 Glob,
3201}
3202
3203#[derive(Clone, Encodable, Decodable, Debug)]
3206pub struct UseTree {
3207 pub prefix: Path,
3208 pub kind: UseTreeKind,
3209 pub span: Span,
3210}
3211
3212impl UseTree {
3213 pub fn ident(&self) -> Ident {
3214 match self.kind {
3215 UseTreeKind::Simple(Some(rename)) => rename,
3216 UseTreeKind::Simple(None) => {
3217 self.prefix.segments.last().expect("empty prefix in a simple import").ident
3218 }
3219 _ => panic!("`UseTree::ident` can only be used on a simple import"),
3220 }
3221 }
3222}
3223
3224#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
3228pub enum AttrStyle {
3229 Outer,
3230 Inner,
3231}
3232
3233pub type AttrVec = ThinVec<Attribute>;
3235
3236#[derive(Clone, Encodable, Decodable, Debug)]
3238pub struct Attribute {
3239 pub kind: AttrKind,
3240 pub id: AttrId,
3241 pub style: AttrStyle,
3244 pub span: Span,
3245}
3246
3247#[derive(Clone, Encodable, Decodable, Debug)]
3248pub enum AttrKind {
3249 Normal(P<NormalAttr>),
3251
3252 DocComment(CommentKind, Symbol),
3256}
3257
3258#[derive(Clone, Encodable, Decodable, Debug)]
3259pub struct NormalAttr {
3260 pub item: AttrItem,
3261 pub tokens: Option<LazyAttrTokenStream>,
3263}
3264
3265impl NormalAttr {
3266 pub fn from_ident(ident: Ident) -> Self {
3267 Self {
3268 item: AttrItem {
3269 unsafety: Safety::Default,
3270 path: Path::from_ident(ident),
3271 args: AttrArgs::Empty,
3272 tokens: None,
3273 },
3274 tokens: None,
3275 }
3276 }
3277}
3278
3279#[derive(Clone, Encodable, Decodable, Debug)]
3280pub struct AttrItem {
3281 pub unsafety: Safety,
3282 pub path: Path,
3283 pub args: AttrArgs,
3284 pub tokens: Option<LazyAttrTokenStream>,
3286}
3287
3288impl AttrItem {
3289 pub fn is_valid_for_outer_style(&self) -> bool {
3290 self.path == sym::cfg_attr
3291 || self.path == sym::cfg
3292 || self.path == sym::forbid
3293 || self.path == sym::warn
3294 || self.path == sym::allow
3295 || self.path == sym::deny
3296 }
3297}
3298
3299#[derive(Clone, Encodable, Decodable, Debug)]
3306pub struct TraitRef {
3307 pub path: Path,
3308 pub ref_id: NodeId,
3309}
3310
3311#[derive(Clone, Encodable, Decodable, Debug)]
3312pub struct PolyTraitRef {
3313 pub bound_generic_params: ThinVec<GenericParam>,
3315
3316 pub modifiers: TraitBoundModifiers,
3318
3319 pub trait_ref: TraitRef,
3321
3322 pub span: Span,
3323}
3324
3325impl PolyTraitRef {
3326 pub fn new(
3327 generic_params: ThinVec<GenericParam>,
3328 path: Path,
3329 modifiers: TraitBoundModifiers,
3330 span: Span,
3331 ) -> Self {
3332 PolyTraitRef {
3333 bound_generic_params: generic_params,
3334 modifiers,
3335 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3336 span,
3337 }
3338 }
3339}
3340
3341#[derive(Clone, Encodable, Decodable, Debug)]
3342pub struct Visibility {
3343 pub kind: VisibilityKind,
3344 pub span: Span,
3345 pub tokens: Option<LazyAttrTokenStream>,
3346}
3347
3348#[derive(Clone, Encodable, Decodable, Debug)]
3349pub enum VisibilityKind {
3350 Public,
3351 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3352 Inherited,
3353}
3354
3355impl VisibilityKind {
3356 pub fn is_pub(&self) -> bool {
3357 matches!(self, VisibilityKind::Public)
3358 }
3359}
3360
3361#[derive(Clone, Encodable, Decodable, Debug)]
3365pub struct FieldDef {
3366 pub attrs: AttrVec,
3367 pub id: NodeId,
3368 pub span: Span,
3369 pub vis: Visibility,
3370 pub safety: Safety,
3371 pub ident: Option<Ident>,
3372
3373 pub ty: P<Ty>,
3374 pub default: Option<AnonConst>,
3375 pub is_placeholder: bool,
3376}
3377
3378#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3380pub enum Recovered {
3381 No,
3382 Yes(ErrorGuaranteed),
3383}
3384
3385#[derive(Clone, Encodable, Decodable, Debug)]
3387pub enum VariantData {
3388 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3392 Tuple(ThinVec<FieldDef>, NodeId),
3396 Unit(NodeId),
3400}
3401
3402impl VariantData {
3403 pub fn fields(&self) -> &[FieldDef] {
3405 match self {
3406 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3407 _ => &[],
3408 }
3409 }
3410
3411 pub fn ctor_node_id(&self) -> Option<NodeId> {
3413 match *self {
3414 VariantData::Struct { .. } => None,
3415 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3416 }
3417 }
3418}
3419
3420#[derive(Clone, Encodable, Decodable, Debug)]
3422pub struct Item<K = ItemKind> {
3423 pub attrs: AttrVec,
3424 pub id: NodeId,
3425 pub span: Span,
3426 pub vis: Visibility,
3427
3428 pub kind: K,
3429
3430 pub tokens: Option<LazyAttrTokenStream>,
3438}
3439
3440impl Item {
3441 pub fn span_with_attributes(&self) -> Span {
3443 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3444 }
3445
3446 pub fn opt_generics(&self) -> Option<&Generics> {
3447 match &self.kind {
3448 ItemKind::ExternCrate(..)
3449 | ItemKind::Use(_)
3450 | ItemKind::Mod(..)
3451 | ItemKind::ForeignMod(_)
3452 | ItemKind::GlobalAsm(_)
3453 | ItemKind::MacCall(_)
3454 | ItemKind::Delegation(_)
3455 | ItemKind::DelegationMac(_)
3456 | ItemKind::MacroDef(..) => None,
3457 ItemKind::Static(_) => None,
3458 ItemKind::Const(i) => Some(&i.generics),
3459 ItemKind::Fn(i) => Some(&i.generics),
3460 ItemKind::TyAlias(i) => Some(&i.generics),
3461 ItemKind::TraitAlias(_, generics, _)
3462 | ItemKind::Enum(_, generics, _)
3463 | ItemKind::Struct(_, generics, _)
3464 | ItemKind::Union(_, generics, _) => Some(&generics),
3465 ItemKind::Trait(i) => Some(&i.generics),
3466 ItemKind::Impl(i) => Some(&i.generics),
3467 }
3468 }
3469}
3470
3471#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3473pub enum Extern {
3474 None,
3478 Implicit(Span),
3484 Explicit(StrLit, Span),
3488}
3489
3490impl Extern {
3491 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3492 match abi {
3493 Some(name) => Extern::Explicit(name, span),
3494 None => Extern::Implicit(span),
3495 }
3496 }
3497}
3498
3499#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3504pub struct FnHeader {
3505 pub safety: Safety,
3507 pub coroutine_kind: Option<CoroutineKind>,
3509 pub constness: Const,
3511 pub ext: Extern,
3513}
3514
3515impl FnHeader {
3516 pub fn has_qualifiers(&self) -> bool {
3518 let Self { safety, coroutine_kind, constness, ext } = self;
3519 matches!(safety, Safety::Unsafe(_))
3520 || coroutine_kind.is_some()
3521 || matches!(constness, Const::Yes(_))
3522 || !matches!(ext, Extern::None)
3523 }
3524}
3525
3526impl Default for FnHeader {
3527 fn default() -> FnHeader {
3528 FnHeader {
3529 safety: Safety::Default,
3530 coroutine_kind: None,
3531 constness: Const::No,
3532 ext: Extern::None,
3533 }
3534 }
3535}
3536
3537#[derive(Clone, Encodable, Decodable, Debug)]
3538pub struct Trait {
3539 pub safety: Safety,
3540 pub is_auto: IsAuto,
3541 pub ident: Ident,
3542 pub generics: Generics,
3543 pub bounds: GenericBounds,
3544 pub items: ThinVec<P<AssocItem>>,
3545}
3546
3547#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3566pub struct TyAliasWhereClause {
3567 pub has_where_token: bool,
3568 pub span: Span,
3569}
3570
3571#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3573pub struct TyAliasWhereClauses {
3574 pub before: TyAliasWhereClause,
3576 pub after: TyAliasWhereClause,
3578 pub split: usize,
3582}
3583
3584#[derive(Clone, Encodable, Decodable, Debug)]
3585pub struct TyAlias {
3586 pub defaultness: Defaultness,
3587 pub ident: Ident,
3588 pub generics: Generics,
3589 pub where_clauses: TyAliasWhereClauses,
3590 pub bounds: GenericBounds,
3591 pub ty: Option<P<Ty>>,
3592}
3593
3594#[derive(Clone, Encodable, Decodable, Debug)]
3595pub struct Impl {
3596 pub defaultness: Defaultness,
3597 pub safety: Safety,
3598 pub generics: Generics,
3599 pub constness: Const,
3600 pub polarity: ImplPolarity,
3601 pub of_trait: Option<TraitRef>,
3603 pub self_ty: P<Ty>,
3604 pub items: ThinVec<P<AssocItem>>,
3605}
3606
3607#[derive(Clone, Encodable, Decodable, Debug, Default)]
3608pub struct FnContract {
3609 pub requires: Option<P<Expr>>,
3610 pub ensures: Option<P<Expr>>,
3611}
3612
3613#[derive(Clone, Encodable, Decodable, Debug)]
3614pub struct Fn {
3615 pub defaultness: Defaultness,
3616 pub ident: Ident,
3617 pub generics: Generics,
3618 pub sig: FnSig,
3619 pub contract: Option<P<FnContract>>,
3620 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3621 pub body: Option<P<Block>>,
3622}
3623
3624#[derive(Clone, Encodable, Decodable, Debug)]
3625pub struct Delegation {
3626 pub id: NodeId,
3628 pub qself: Option<P<QSelf>>,
3629 pub path: Path,
3630 pub ident: Ident,
3631 pub rename: Option<Ident>,
3632 pub body: Option<P<Block>>,
3633 pub from_glob: bool,
3635}
3636
3637#[derive(Clone, Encodable, Decodable, Debug)]
3638pub struct DelegationMac {
3639 pub qself: Option<P<QSelf>>,
3640 pub prefix: Path,
3641 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3643 pub body: Option<P<Block>>,
3644}
3645
3646#[derive(Clone, Encodable, Decodable, Debug)]
3647pub struct StaticItem {
3648 pub ident: Ident,
3649 pub ty: P<Ty>,
3650 pub safety: Safety,
3651 pub mutability: Mutability,
3652 pub expr: Option<P<Expr>>,
3653 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3654}
3655
3656#[derive(Clone, Encodable, Decodable, Debug)]
3657pub struct ConstItem {
3658 pub defaultness: Defaultness,
3659 pub ident: Ident,
3660 pub generics: Generics,
3661 pub ty: P<Ty>,
3662 pub expr: Option<P<Expr>>,
3663 pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3664}
3665
3666#[derive(Clone, Encodable, Decodable, Debug)]
3668pub enum ItemKind {
3669 ExternCrate(Option<Symbol>, Ident),
3673 Use(UseTree),
3677 Static(Box<StaticItem>),
3681 Const(Box<ConstItem>),
3685 Fn(Box<Fn>),
3689 Mod(Safety, Ident, ModKind),
3695 ForeignMod(ForeignMod),
3699 GlobalAsm(Box<InlineAsm>),
3701 TyAlias(Box<TyAlias>),
3705 Enum(Ident, Generics, EnumDef),
3709 Struct(Ident, Generics, VariantData),
3713 Union(Ident, Generics, VariantData),
3717 Trait(Box<Trait>),
3721 TraitAlias(Ident, Generics, GenericBounds),
3725 Impl(Box<Impl>),
3729 MacCall(P<MacCall>),
3733 MacroDef(Ident, MacroDef),
3735 Delegation(Box<Delegation>),
3739 DelegationMac(Box<DelegationMac>),
3742}
3743
3744impl ItemKind {
3745 pub fn ident(&self) -> Option<Ident> {
3746 match *self {
3747 ItemKind::ExternCrate(_, ident)
3748 | ItemKind::Static(box StaticItem { ident, .. })
3749 | ItemKind::Const(box ConstItem { ident, .. })
3750 | ItemKind::Fn(box Fn { ident, .. })
3751 | ItemKind::Mod(_, ident, _)
3752 | ItemKind::TyAlias(box TyAlias { ident, .. })
3753 | ItemKind::Enum(ident, ..)
3754 | ItemKind::Struct(ident, ..)
3755 | ItemKind::Union(ident, ..)
3756 | ItemKind::Trait(box Trait { ident, .. })
3757 | ItemKind::TraitAlias(ident, ..)
3758 | ItemKind::MacroDef(ident, _)
3759 | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3760
3761 ItemKind::Use(_)
3762 | ItemKind::ForeignMod(_)
3763 | ItemKind::GlobalAsm(_)
3764 | ItemKind::Impl(_)
3765 | ItemKind::MacCall(_)
3766 | ItemKind::DelegationMac(_) => None,
3767 }
3768 }
3769
3770 pub fn article(&self) -> &'static str {
3772 use ItemKind::*;
3773 match self {
3774 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3775 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3776 | Delegation(..) | DelegationMac(..) => "a",
3777 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3778 }
3779 }
3780
3781 pub fn descr(&self) -> &'static str {
3782 match self {
3783 ItemKind::ExternCrate(..) => "extern crate",
3784 ItemKind::Use(..) => "`use` import",
3785 ItemKind::Static(..) => "static item",
3786 ItemKind::Const(..) => "constant item",
3787 ItemKind::Fn(..) => "function",
3788 ItemKind::Mod(..) => "module",
3789 ItemKind::ForeignMod(..) => "extern block",
3790 ItemKind::GlobalAsm(..) => "global asm item",
3791 ItemKind::TyAlias(..) => "type alias",
3792 ItemKind::Enum(..) => "enum",
3793 ItemKind::Struct(..) => "struct",
3794 ItemKind::Union(..) => "union",
3795 ItemKind::Trait(..) => "trait",
3796 ItemKind::TraitAlias(..) => "trait alias",
3797 ItemKind::MacCall(..) => "item macro invocation",
3798 ItemKind::MacroDef(..) => "macro definition",
3799 ItemKind::Impl { .. } => "implementation",
3800 ItemKind::Delegation(..) => "delegated function",
3801 ItemKind::DelegationMac(..) => "delegation",
3802 }
3803 }
3804
3805 pub fn generics(&self) -> Option<&Generics> {
3806 match self {
3807 Self::Fn(box Fn { generics, .. })
3808 | Self::TyAlias(box TyAlias { generics, .. })
3809 | Self::Const(box ConstItem { generics, .. })
3810 | Self::Enum(_, generics, _)
3811 | Self::Struct(_, generics, _)
3812 | Self::Union(_, generics, _)
3813 | Self::Trait(box Trait { generics, .. })
3814 | Self::TraitAlias(_, generics, _)
3815 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3816 _ => None,
3817 }
3818 }
3819}
3820
3821pub type AssocItem = Item<AssocItemKind>;
3824
3825#[derive(Clone, Encodable, Decodable, Debug)]
3833pub enum AssocItemKind {
3834 Const(Box<ConstItem>),
3837 Fn(Box<Fn>),
3839 Type(Box<TyAlias>),
3841 MacCall(P<MacCall>),
3843 Delegation(Box<Delegation>),
3845 DelegationMac(Box<DelegationMac>),
3847}
3848
3849impl AssocItemKind {
3850 pub fn ident(&self) -> Option<Ident> {
3851 match *self {
3852 AssocItemKind::Const(box ConstItem { ident, .. })
3853 | AssocItemKind::Fn(box Fn { ident, .. })
3854 | AssocItemKind::Type(box TyAlias { ident, .. })
3855 | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3856
3857 AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3858 }
3859 }
3860
3861 pub fn defaultness(&self) -> Defaultness {
3862 match *self {
3863 Self::Const(box ConstItem { defaultness, .. })
3864 | Self::Fn(box Fn { defaultness, .. })
3865 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3866 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3867 Defaultness::Final
3868 }
3869 }
3870 }
3871}
3872
3873impl From<AssocItemKind> for ItemKind {
3874 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3875 match assoc_item_kind {
3876 AssocItemKind::Const(item) => ItemKind::Const(item),
3877 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3878 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3879 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3880 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3881 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3882 }
3883 }
3884}
3885
3886impl TryFrom<ItemKind> for AssocItemKind {
3887 type Error = ItemKind;
3888
3889 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3890 Ok(match item_kind {
3891 ItemKind::Const(item) => AssocItemKind::Const(item),
3892 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3893 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3894 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3895 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3896 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3897 _ => return Err(item_kind),
3898 })
3899 }
3900}
3901
3902#[derive(Clone, Encodable, Decodable, Debug)]
3904pub enum ForeignItemKind {
3905 Static(Box<StaticItem>),
3907 Fn(Box<Fn>),
3909 TyAlias(Box<TyAlias>),
3911 MacCall(P<MacCall>),
3913}
3914
3915impl ForeignItemKind {
3916 pub fn ident(&self) -> Option<Ident> {
3917 match *self {
3918 ForeignItemKind::Static(box StaticItem { ident, .. })
3919 | ForeignItemKind::Fn(box Fn { ident, .. })
3920 | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
3921
3922 ForeignItemKind::MacCall(_) => None,
3923 }
3924 }
3925}
3926
3927impl From<ForeignItemKind> for ItemKind {
3928 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3929 match foreign_item_kind {
3930 ForeignItemKind::Static(box static_foreign_item) => {
3931 ItemKind::Static(Box::new(static_foreign_item))
3932 }
3933 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3934 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3935 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3936 }
3937 }
3938}
3939
3940impl TryFrom<ItemKind> for ForeignItemKind {
3941 type Error = ItemKind;
3942
3943 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3944 Ok(match item_kind {
3945 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3946 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3947 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3948 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3949 _ => return Err(item_kind),
3950 })
3951 }
3952}
3953
3954pub type ForeignItem = Item<ForeignItemKind>;
3955
3956#[cfg(target_pointer_width = "64")]
3958mod size_asserts {
3959 use rustc_data_structures::static_assert_size;
3960
3961 use super::*;
3962 static_assert_size!(AssocItem, 80);
3964 static_assert_size!(AssocItemKind, 16);
3965 static_assert_size!(Attribute, 32);
3966 static_assert_size!(Block, 32);
3967 static_assert_size!(Expr, 72);
3968 static_assert_size!(ExprKind, 40);
3969 static_assert_size!(Fn, 184);
3970 static_assert_size!(ForeignItem, 80);
3971 static_assert_size!(ForeignItemKind, 16);
3972 static_assert_size!(GenericArg, 24);
3973 static_assert_size!(GenericBound, 88);
3974 static_assert_size!(Generics, 40);
3975 static_assert_size!(Impl, 136);
3976 static_assert_size!(Item, 144);
3977 static_assert_size!(ItemKind, 80);
3978 static_assert_size!(LitKind, 24);
3979 static_assert_size!(Local, 96);
3980 static_assert_size!(MetaItemLit, 40);
3981 static_assert_size!(Param, 40);
3982 static_assert_size!(Pat, 72);
3983 static_assert_size!(Path, 24);
3984 static_assert_size!(PathSegment, 24);
3985 static_assert_size!(PatKind, 48);
3986 static_assert_size!(Stmt, 32);
3987 static_assert_size!(StmtKind, 16);
3988 static_assert_size!(Ty, 64);
3989 static_assert_size!(TyKind, 40);
3990 }