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::{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::{AssocOp, ExprPrecedence};
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, symbol: &Symbol) -> bool {
103 matches!(&self.segments[..], [segment] if segment.ident.name == *symbol)
104 }
105}
106
107impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
108 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
109 self.segments.len().hash_stable(hcx, hasher);
110 for segment in &self.segments {
111 segment.ident.hash_stable(hcx, hasher);
112 }
113 }
114}
115
116impl Path {
117 pub fn from_ident(ident: Ident) -> Path {
120 Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
121 }
122
123 pub fn is_global(&self) -> bool {
124 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
125 }
126
127 pub fn is_potential_trivial_const_arg(&self) -> bool {
130 matches!(self.segments[..], [PathSegment { args: None, .. }])
131 }
132}
133
134#[derive(Clone, Encodable, Decodable, Debug)]
138pub struct PathSegment {
139 pub ident: Ident,
141
142 pub id: NodeId,
143
144 pub args: Option<P<GenericArgs>>,
151}
152
153impl PathSegment {
154 pub fn from_ident(ident: Ident) -> Self {
155 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
156 }
157
158 pub fn path_root(span: Span) -> Self {
159 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
160 }
161
162 pub fn span(&self) -> Span {
163 match &self.args {
164 Some(args) => self.ident.span.to(args.span()),
165 None => self.ident.span,
166 }
167 }
168}
169
170#[derive(Clone, Encodable, Decodable, Debug)]
174pub enum GenericArgs {
175 AngleBracketed(AngleBracketedArgs),
177 Parenthesized(ParenthesizedArgs),
179 ParenthesizedElided(Span),
181}
182
183impl GenericArgs {
184 pub fn is_angle_bracketed(&self) -> bool {
185 matches!(self, AngleBracketed(..))
186 }
187
188 pub fn span(&self) -> Span {
189 match self {
190 AngleBracketed(data) => data.span,
191 Parenthesized(data) => data.span,
192 ParenthesizedElided(span) => *span,
193 }
194 }
195}
196
197#[derive(Clone, Encodable, Decodable, Debug)]
199pub enum GenericArg {
200 Lifetime(Lifetime),
202 Type(P<Ty>),
204 Const(AnonConst),
206}
207
208impl GenericArg {
209 pub fn span(&self) -> Span {
210 match self {
211 GenericArg::Lifetime(lt) => lt.ident.span,
212 GenericArg::Type(ty) => ty.span,
213 GenericArg::Const(ct) => ct.value.span,
214 }
215 }
216}
217
218#[derive(Clone, Encodable, Decodable, Debug, Default)]
220pub struct AngleBracketedArgs {
221 pub span: Span,
223 pub args: ThinVec<AngleBracketedArg>,
225}
226
227#[derive(Clone, Encodable, Decodable, Debug)]
229pub enum AngleBracketedArg {
230 Arg(GenericArg),
232 Constraint(AssocItemConstraint),
234}
235
236impl AngleBracketedArg {
237 pub fn span(&self) -> Span {
238 match self {
239 AngleBracketedArg::Arg(arg) => arg.span(),
240 AngleBracketedArg::Constraint(constraint) => constraint.span,
241 }
242 }
243}
244
245impl From<AngleBracketedArgs> for P<GenericArgs> {
246 fn from(val: AngleBracketedArgs) -> Self {
247 P(GenericArgs::AngleBracketed(val))
248 }
249}
250
251impl From<ParenthesizedArgs> for P<GenericArgs> {
252 fn from(val: ParenthesizedArgs) -> Self {
253 P(GenericArgs::Parenthesized(val))
254 }
255}
256
257#[derive(Clone, Encodable, Decodable, Debug)]
259pub struct ParenthesizedArgs {
260 pub span: Span,
265
266 pub inputs: ThinVec<P<Ty>>,
268
269 pub inputs_span: Span,
274
275 pub output: FnRetTy,
277}
278
279impl ParenthesizedArgs {
280 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
281 let args = self
282 .inputs
283 .iter()
284 .cloned()
285 .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
286 .collect();
287 AngleBracketedArgs { span: self.inputs_span, args }
288 }
289}
290
291use crate::AstDeref;
292pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
293
294#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
296pub struct TraitBoundModifiers {
297 pub constness: BoundConstness,
298 pub asyncness: BoundAsyncness,
299 pub polarity: BoundPolarity,
300}
301
302impl TraitBoundModifiers {
303 pub const NONE: Self = Self {
304 constness: BoundConstness::Never,
305 asyncness: BoundAsyncness::Normal,
306 polarity: BoundPolarity::Positive,
307 };
308}
309
310#[derive(Clone, Encodable, Decodable, Debug)]
311pub enum GenericBound {
312 Trait(PolyTraitRef),
313 Outlives(Lifetime),
314 Use(ThinVec<PreciseCapturingArg>, Span),
316}
317
318impl GenericBound {
319 pub fn span(&self) -> Span {
320 match self {
321 GenericBound::Trait(t, ..) => t.span,
322 GenericBound::Outlives(l) => l.ident.span,
323 GenericBound::Use(_, span) => *span,
324 }
325 }
326}
327
328pub type GenericBounds = Vec<GenericBound>;
329
330#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
334pub enum ParamKindOrd {
335 Lifetime,
336 TypeOrConst,
337}
338
339impl fmt::Display for ParamKindOrd {
340 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341 match self {
342 ParamKindOrd::Lifetime => "lifetime".fmt(f),
343 ParamKindOrd::TypeOrConst => "type and const".fmt(f),
344 }
345 }
346}
347
348#[derive(Clone, Encodable, Decodable, Debug)]
349pub enum GenericParamKind {
350 Lifetime,
352 Type {
353 default: Option<P<Ty>>,
354 },
355 Const {
356 ty: P<Ty>,
357 kw_span: Span,
359 default: Option<AnonConst>,
361 },
362}
363
364#[derive(Clone, Encodable, Decodable, Debug)]
365pub struct GenericParam {
366 pub id: NodeId,
367 pub ident: Ident,
368 pub attrs: AttrVec,
369 pub bounds: GenericBounds,
370 pub is_placeholder: bool,
371 pub kind: GenericParamKind,
372 pub colon_span: Option<Span>,
373}
374
375impl GenericParam {
376 pub fn span(&self) -> Span {
377 match &self.kind {
378 GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
379 self.ident.span
380 }
381 GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
382 GenericParamKind::Const { kw_span, default: Some(default), .. } => {
383 kw_span.to(default.value.span)
384 }
385 GenericParamKind::Const { kw_span, default: None, ty } => kw_span.to(ty.span),
386 }
387 }
388}
389
390#[derive(Clone, Encodable, Decodable, Debug, Default)]
393pub struct Generics {
394 pub params: ThinVec<GenericParam>,
395 pub where_clause: WhereClause,
396 pub span: Span,
397}
398
399#[derive(Clone, Encodable, Decodable, Debug, Default)]
401pub struct WhereClause {
402 pub has_where_token: bool,
407 pub predicates: ThinVec<WherePredicate>,
408 pub span: Span,
409}
410
411impl WhereClause {
412 pub fn is_empty(&self) -> bool {
413 !self.has_where_token && self.predicates.is_empty()
414 }
415}
416
417#[derive(Clone, Encodable, Decodable, Debug)]
419pub struct WherePredicate {
420 pub kind: WherePredicateKind,
421 pub id: NodeId,
422 pub span: Span,
423}
424
425#[derive(Clone, Encodable, Decodable, Debug)]
427pub enum WherePredicateKind {
428 BoundPredicate(WhereBoundPredicate),
430 RegionPredicate(WhereRegionPredicate),
432 EqPredicate(WhereEqPredicate),
434}
435
436#[derive(Clone, Encodable, Decodable, Debug)]
440pub struct WhereBoundPredicate {
441 pub bound_generic_params: ThinVec<GenericParam>,
443 pub bounded_ty: P<Ty>,
445 pub bounds: GenericBounds,
447}
448
449#[derive(Clone, Encodable, Decodable, Debug)]
453pub struct WhereRegionPredicate {
454 pub lifetime: Lifetime,
455 pub bounds: GenericBounds,
456}
457
458#[derive(Clone, Encodable, Decodable, Debug)]
462pub struct WhereEqPredicate {
463 pub lhs_ty: P<Ty>,
464 pub rhs_ty: P<Ty>,
465}
466
467#[derive(Clone, Encodable, Decodable, Debug)]
468pub struct Crate {
469 pub attrs: AttrVec,
470 pub items: ThinVec<P<Item>>,
471 pub spans: ModSpans,
472 pub id: NodeId,
475 pub is_placeholder: bool,
476}
477
478#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
485pub struct MetaItem {
486 pub unsafety: Safety,
487 pub path: Path,
488 pub kind: MetaItemKind,
489 pub span: Span,
490}
491
492#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
494pub enum MetaItemKind {
495 Word,
499
500 List(ThinVec<MetaItemInner>),
504
505 NameValue(MetaItemLit),
509}
510
511#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
515pub enum MetaItemInner {
516 MetaItem(MetaItem),
518
519 Lit(MetaItemLit),
523}
524
525#[derive(Clone, Encodable, Decodable, Debug)]
529pub struct Block {
530 pub stmts: ThinVec<Stmt>,
532 pub id: NodeId,
533 pub rules: BlockCheckMode,
535 pub span: Span,
536 pub tokens: Option<LazyAttrTokenStream>,
537 pub could_be_bare_literal: bool,
545}
546
547#[derive(Clone, Encodable, Decodable, Debug)]
551pub struct Pat {
552 pub id: NodeId,
553 pub kind: PatKind,
554 pub span: Span,
555 pub tokens: Option<LazyAttrTokenStream>,
556}
557
558impl Pat {
559 pub fn to_ty(&self) -> Option<P<Ty>> {
562 let kind = match &self.kind {
563 PatKind::Wild => TyKind::Infer,
565 PatKind::Ident(BindingMode::NONE, ident, None) => {
567 TyKind::Path(None, Path::from_ident(*ident))
568 }
569 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
570 PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
571 PatKind::Ref(pat, mutbl) => {
573 pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
574 }
575 PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
578 pat.to_ty().map(TyKind::Slice)?
579 }
580 PatKind::Tuple(pats) => {
583 let mut tys = ThinVec::with_capacity(pats.len());
584 for pat in pats {
586 tys.push(pat.to_ty()?);
587 }
588 TyKind::Tup(tys)
589 }
590 _ => return None,
591 };
592
593 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
594 }
595
596 pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
600 if !it(self) {
601 return;
602 }
603
604 match &self.kind {
605 PatKind::Ident(_, _, Some(p)) => p.walk(it),
607
608 PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
610
611 PatKind::TupleStruct(_, _, s)
613 | PatKind::Tuple(s)
614 | PatKind::Slice(s)
615 | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
616
617 PatKind::Box(s)
619 | PatKind::Deref(s)
620 | PatKind::Ref(s, _)
621 | PatKind::Paren(s)
622 | PatKind::Guard(s, _) => s.walk(it),
623
624 PatKind::Wild
626 | PatKind::Rest
627 | PatKind::Never
628 | PatKind::Expr(_)
629 | PatKind::Range(..)
630 | PatKind::Ident(..)
631 | PatKind::Path(..)
632 | PatKind::MacCall(_)
633 | PatKind::Err(_) => {}
634 }
635 }
636
637 pub fn is_rest(&self) -> bool {
639 matches!(self.kind, PatKind::Rest)
640 }
641
642 pub fn could_be_never_pattern(&self) -> bool {
645 let mut could_be_never_pattern = false;
646 self.walk(&mut |pat| match &pat.kind {
647 PatKind::Never | PatKind::MacCall(_) => {
648 could_be_never_pattern = true;
649 false
650 }
651 PatKind::Or(s) => {
652 could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
653 false
654 }
655 _ => true,
656 });
657 could_be_never_pattern
658 }
659
660 pub fn contains_never_pattern(&self) -> bool {
663 let mut contains_never_pattern = false;
664 self.walk(&mut |pat| {
665 if matches!(pat.kind, PatKind::Never) {
666 contains_never_pattern = true;
667 }
668 true
669 });
670 contains_never_pattern
671 }
672
673 pub fn descr(&self) -> Option<String> {
675 match &self.kind {
676 PatKind::Wild => Some("_".to_string()),
677 PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
678 PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
679 _ => None,
680 }
681 }
682}
683
684#[derive(Clone, Encodable, Decodable, Debug)]
690pub struct PatField {
691 pub ident: Ident,
693 pub pat: P<Pat>,
695 pub is_shorthand: bool,
696 pub attrs: AttrVec,
697 pub id: NodeId,
698 pub span: Span,
699 pub is_placeholder: bool,
700}
701
702#[derive(Clone, Copy, Debug, Eq, PartialEq)]
703#[derive(Encodable, Decodable, HashStable_Generic)]
704pub enum ByRef {
705 Yes(Mutability),
706 No,
707}
708
709impl ByRef {
710 #[must_use]
711 pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
712 if let ByRef::Yes(old_mutbl) = &mut self {
713 *old_mutbl = cmp::min(*old_mutbl, mutbl);
714 }
715 self
716 }
717}
718
719#[derive(Clone, Copy, Debug, Eq, PartialEq)]
725#[derive(Encodable, Decodable, HashStable_Generic)]
726pub struct BindingMode(pub ByRef, pub Mutability);
727
728impl BindingMode {
729 pub const NONE: Self = Self(ByRef::No, Mutability::Not);
730 pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
731 pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
732 pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
733 pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
734 pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);
735
736 pub fn prefix_str(self) -> &'static str {
737 match self {
738 Self::NONE => "",
739 Self::REF => "ref ",
740 Self::MUT => "mut ",
741 Self::REF_MUT => "ref mut ",
742 Self::MUT_REF => "mut ref ",
743 Self::MUT_REF_MUT => "mut ref mut ",
744 }
745 }
746}
747
748#[derive(Clone, Encodable, Decodable, Debug)]
749pub enum RangeEnd {
750 Included(RangeSyntax),
752 Excluded,
754}
755
756#[derive(Clone, Encodable, Decodable, Debug)]
757pub enum RangeSyntax {
758 DotDotDot,
760 DotDotEq,
762}
763
764#[derive(Clone, Encodable, Decodable, Debug)]
768pub enum PatKind {
769 Wild,
771
772 Ident(BindingMode, Ident, Option<P<Pat>>),
777
778 Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
780
781 TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
783
784 Or(ThinVec<P<Pat>>),
787
788 Path(Option<P<QSelf>>, Path),
793
794 Tuple(ThinVec<P<Pat>>),
796
797 Box(P<Pat>),
799
800 Deref(P<Pat>),
802
803 Ref(P<Pat>, Mutability),
805
806 Expr(P<Expr>),
808
809 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
811
812 Slice(ThinVec<P<Pat>>),
814
815 Rest,
828
829 Never,
831
832 Guard(P<Pat>, P<Expr>),
834
835 Paren(P<Pat>),
837
838 MacCall(P<MacCall>),
840
841 Err(ErrorGuaranteed),
843}
844
845#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
847pub enum PatFieldsRest {
848 Rest,
850 Recovered(ErrorGuaranteed),
852 None,
854}
855
856#[derive(Clone, Copy, PartialEq, Eq, Debug)]
859#[derive(Encodable, Decodable, HashStable_Generic)]
860pub enum BorrowKind {
861 Ref,
865 Raw,
869}
870
871#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
872pub enum BinOpKind {
873 Add,
875 Sub,
877 Mul,
879 Div,
881 Rem,
883 And,
885 Or,
887 BitXor,
889 BitAnd,
891 BitOr,
893 Shl,
895 Shr,
897 Eq,
899 Lt,
901 Le,
903 Ne,
905 Ge,
907 Gt,
909}
910
911impl BinOpKind {
912 pub fn as_str(&self) -> &'static str {
913 use BinOpKind::*;
914 match self {
915 Add => "+",
916 Sub => "-",
917 Mul => "*",
918 Div => "/",
919 Rem => "%",
920 And => "&&",
921 Or => "||",
922 BitXor => "^",
923 BitAnd => "&",
924 BitOr => "|",
925 Shl => "<<",
926 Shr => ">>",
927 Eq => "==",
928 Lt => "<",
929 Le => "<=",
930 Ne => "!=",
931 Ge => ">=",
932 Gt => ">",
933 }
934 }
935
936 pub fn is_lazy(&self) -> bool {
937 matches!(self, BinOpKind::And | BinOpKind::Or)
938 }
939
940 pub fn is_comparison(self) -> bool {
941 crate::util::parser::AssocOp::from_ast_binop(self).is_comparison()
942 }
943
944 pub fn is_by_value(self) -> bool {
946 !self.is_comparison()
947 }
948}
949
950pub type BinOp = Spanned<BinOpKind>;
951
952#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
956pub enum UnOp {
957 Deref,
959 Not,
961 Neg,
963}
964
965impl UnOp {
966 pub fn as_str(&self) -> &'static str {
967 match self {
968 UnOp::Deref => "*",
969 UnOp::Not => "!",
970 UnOp::Neg => "-",
971 }
972 }
973
974 pub fn is_by_value(self) -> bool {
976 matches!(self, Self::Neg | Self::Not)
977 }
978}
979
980#[derive(Clone, Encodable, Decodable, Debug)]
984pub struct Stmt {
985 pub id: NodeId,
986 pub kind: StmtKind,
987 pub span: Span,
988}
989
990impl Stmt {
991 pub fn has_trailing_semicolon(&self) -> bool {
992 match &self.kind {
993 StmtKind::Semi(_) => true,
994 StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
995 _ => false,
996 }
997 }
998
999 pub fn add_trailing_semicolon(mut self) -> Self {
1007 self.kind = match self.kind {
1008 StmtKind::Expr(expr) => StmtKind::Semi(expr),
1009 StmtKind::MacCall(mac) => {
1010 StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs, tokens }| {
1011 MacCallStmt { mac, style: MacStmtStyle::Semicolon, attrs, tokens }
1012 }))
1013 }
1014 kind => kind,
1015 };
1016
1017 self
1018 }
1019
1020 pub fn is_item(&self) -> bool {
1021 matches!(self.kind, StmtKind::Item(_))
1022 }
1023
1024 pub fn is_expr(&self) -> bool {
1025 matches!(self.kind, StmtKind::Expr(_))
1026 }
1027}
1028
1029#[derive(Clone, Encodable, Decodable, Debug)]
1031pub enum StmtKind {
1032 Let(P<Local>),
1034 Item(P<Item>),
1036 Expr(P<Expr>),
1038 Semi(P<Expr>),
1040 Empty,
1042 MacCall(P<MacCallStmt>),
1044}
1045
1046#[derive(Clone, Encodable, Decodable, Debug)]
1047pub struct MacCallStmt {
1048 pub mac: P<MacCall>,
1049 pub style: MacStmtStyle,
1050 pub attrs: AttrVec,
1051 pub tokens: Option<LazyAttrTokenStream>,
1052}
1053
1054#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
1055pub enum MacStmtStyle {
1056 Semicolon,
1059 Braces,
1061 NoBraces,
1065}
1066
1067#[derive(Clone, Encodable, Decodable, Debug)]
1069pub struct Local {
1070 pub id: NodeId,
1071 pub pat: P<Pat>,
1072 pub ty: Option<P<Ty>>,
1073 pub kind: LocalKind,
1074 pub span: Span,
1075 pub colon_sp: Option<Span>,
1076 pub attrs: AttrVec,
1077 pub tokens: Option<LazyAttrTokenStream>,
1078}
1079
1080#[derive(Clone, Encodable, Decodable, Debug)]
1081pub enum LocalKind {
1082 Decl,
1085 Init(P<Expr>),
1088 InitElse(P<Expr>, P<Block>),
1091}
1092
1093impl LocalKind {
1094 pub fn init(&self) -> Option<&Expr> {
1095 match self {
1096 Self::Decl => None,
1097 Self::Init(i) | Self::InitElse(i, _) => Some(i),
1098 }
1099 }
1100
1101 pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1102 match self {
1103 Self::Decl => None,
1104 Self::Init(init) => Some((init, None)),
1105 Self::InitElse(init, els) => Some((init, Some(els))),
1106 }
1107 }
1108}
1109
1110#[derive(Clone, Encodable, Decodable, Debug)]
1121pub struct Arm {
1122 pub attrs: AttrVec,
1123 pub pat: P<Pat>,
1125 pub guard: Option<P<Expr>>,
1127 pub body: Option<P<Expr>>,
1129 pub span: Span,
1130 pub id: NodeId,
1131 pub is_placeholder: bool,
1132}
1133
1134#[derive(Clone, Encodable, Decodable, Debug)]
1136pub struct ExprField {
1137 pub attrs: AttrVec,
1138 pub id: NodeId,
1139 pub span: Span,
1140 pub ident: Ident,
1141 pub expr: P<Expr>,
1142 pub is_shorthand: bool,
1143 pub is_placeholder: bool,
1144}
1145
1146#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1147pub enum BlockCheckMode {
1148 Default,
1149 Unsafe(UnsafeSource),
1150}
1151
1152#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
1153pub enum UnsafeSource {
1154 CompilerGenerated,
1155 UserProvided,
1156}
1157
1158#[derive(Clone, Encodable, Decodable, Debug)]
1164pub struct AnonConst {
1165 pub id: NodeId,
1166 pub value: P<Expr>,
1167}
1168
1169#[derive(Clone, Encodable, Decodable, Debug)]
1171pub struct Expr {
1172 pub id: NodeId,
1173 pub kind: ExprKind,
1174 pub span: Span,
1175 pub attrs: AttrVec,
1176 pub tokens: Option<LazyAttrTokenStream>,
1177}
1178
1179impl Expr {
1180 pub fn is_potential_trivial_const_arg(&self) -> bool {
1188 let this = self.maybe_unwrap_block();
1189
1190 if let ExprKind::Path(None, path) = &this.kind
1191 && path.is_potential_trivial_const_arg()
1192 {
1193 true
1194 } else {
1195 false
1196 }
1197 }
1198
1199 pub fn maybe_unwrap_block(&self) -> &Expr {
1201 if let ExprKind::Block(block, None) = &self.kind
1202 && let [stmt] = block.stmts.as_slice()
1203 && let StmtKind::Expr(expr) = &stmt.kind
1204 {
1205 expr
1206 } else {
1207 self
1208 }
1209 }
1210
1211 pub fn optionally_braced_mac_call(
1217 &self,
1218 already_stripped_block: bool,
1219 ) -> Option<(bool, NodeId)> {
1220 match &self.kind {
1221 ExprKind::Block(block, None)
1222 if let [stmt] = &*block.stmts
1223 && !already_stripped_block =>
1224 {
1225 match &stmt.kind {
1226 StmtKind::MacCall(_) => Some((true, stmt.id)),
1227 StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1228 Some((true, expr.id))
1229 }
1230 _ => None,
1231 }
1232 }
1233 ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1234 _ => None,
1235 }
1236 }
1237
1238 pub fn to_bound(&self) -> Option<GenericBound> {
1239 match &self.kind {
1240 ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1241 ThinVec::new(),
1242 path.clone(),
1243 TraitBoundModifiers::NONE,
1244 self.span,
1245 ))),
1246 _ => None,
1247 }
1248 }
1249
1250 pub fn peel_parens(&self) -> &Expr {
1251 let mut expr = self;
1252 while let ExprKind::Paren(inner) = &expr.kind {
1253 expr = inner;
1254 }
1255 expr
1256 }
1257
1258 pub fn peel_parens_and_refs(&self) -> &Expr {
1259 let mut expr = self;
1260 while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1261 {
1262 expr = inner;
1263 }
1264 expr
1265 }
1266
1267 pub fn to_ty(&self) -> Option<P<Ty>> {
1269 let kind = match &self.kind {
1270 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1272 ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1273
1274 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1275
1276 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1277 expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1278 }
1279
1280 ExprKind::Repeat(expr, expr_len) => {
1281 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1282 }
1283
1284 ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1285 expr.to_ty().map(TyKind::Slice)?
1286 }
1287
1288 ExprKind::Tup(exprs) => {
1289 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1290 TyKind::Tup(tys)
1291 }
1292
1293 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1297 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1298 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1299 } else {
1300 return None;
1301 }
1302 }
1303
1304 ExprKind::Underscore => TyKind::Infer,
1305
1306 _ => return None,
1308 };
1309
1310 Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
1311 }
1312
1313 pub fn precedence(&self) -> ExprPrecedence {
1314 match &self.kind {
1315 ExprKind::Closure(closure) => {
1316 match closure.fn_decl.output {
1317 FnRetTy::Default(_) => ExprPrecedence::Jump,
1318 FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
1319 }
1320 }
1321
1322 ExprKind::Break(..)
1323 | ExprKind::Ret(..)
1324 | ExprKind::Yield(..)
1325 | ExprKind::Yeet(..)
1326 | ExprKind::Become(..) => ExprPrecedence::Jump,
1327
1328 ExprKind::Range(..) => ExprPrecedence::Range,
1333
1334 ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(),
1336 ExprKind::Cast(..) => ExprPrecedence::Cast,
1337
1338 ExprKind::Assign(..) |
1339 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1340
1341 ExprKind::AddrOf(..)
1343 | ExprKind::Let(..)
1348 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1349
1350 ExprKind::Array(_)
1352 | ExprKind::Await(..)
1353 | ExprKind::Block(..)
1354 | ExprKind::Call(..)
1355 | ExprKind::ConstBlock(_)
1356 | ExprKind::Continue(..)
1357 | ExprKind::Field(..)
1358 | ExprKind::ForLoop { .. }
1359 | ExprKind::FormatArgs(..)
1360 | ExprKind::Gen(..)
1361 | ExprKind::If(..)
1362 | ExprKind::IncludedBytes(..)
1363 | ExprKind::Index(..)
1364 | ExprKind::InlineAsm(..)
1365 | ExprKind::Lit(_)
1366 | ExprKind::Loop(..)
1367 | ExprKind::MacCall(..)
1368 | ExprKind::Match(..)
1369 | ExprKind::MethodCall(..)
1370 | ExprKind::OffsetOf(..)
1371 | ExprKind::Paren(..)
1372 | ExprKind::Path(..)
1373 | ExprKind::Repeat(..)
1374 | ExprKind::Struct(..)
1375 | ExprKind::Try(..)
1376 | ExprKind::TryBlock(..)
1377 | ExprKind::Tup(_)
1378 | ExprKind::Type(..)
1379 | ExprKind::Underscore
1380 | ExprKind::UnsafeBinderCast(..)
1381 | ExprKind::While(..)
1382 | ExprKind::Err(_)
1383 | ExprKind::Dummy => ExprPrecedence::Unambiguous,
1384 }
1385 }
1386
1387 pub fn is_approximately_pattern(&self) -> bool {
1389 matches!(
1390 &self.peel_parens().kind,
1391 ExprKind::Array(_)
1392 | ExprKind::Call(_, _)
1393 | ExprKind::Tup(_)
1394 | ExprKind::Lit(_)
1395 | ExprKind::Range(_, _, _)
1396 | ExprKind::Underscore
1397 | ExprKind::Path(_, _)
1398 | ExprKind::Struct(_)
1399 )
1400 }
1401}
1402
1403#[derive(Clone, Encodable, Decodable, Debug)]
1404pub struct Closure {
1405 pub binder: ClosureBinder,
1406 pub capture_clause: CaptureBy,
1407 pub constness: Const,
1408 pub coroutine_kind: Option<CoroutineKind>,
1409 pub movability: Movability,
1410 pub fn_decl: P<FnDecl>,
1411 pub body: P<Expr>,
1412 pub fn_decl_span: Span,
1414 pub fn_arg_span: Span,
1416}
1417
1418#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
1420pub enum RangeLimits {
1421 HalfOpen,
1423 Closed,
1425}
1426
1427#[derive(Clone, Encodable, Decodable, Debug)]
1429pub struct MethodCall {
1430 pub seg: PathSegment,
1432 pub receiver: P<Expr>,
1434 pub args: ThinVec<P<Expr>>,
1436 pub span: Span,
1439}
1440
1441#[derive(Clone, Encodable, Decodable, Debug)]
1442pub enum StructRest {
1443 Base(P<Expr>),
1445 Rest(Span),
1447 None,
1449}
1450
1451#[derive(Clone, Encodable, Decodable, Debug)]
1452pub struct StructExpr {
1453 pub qself: Option<P<QSelf>>,
1454 pub path: Path,
1455 pub fields: ThinVec<ExprField>,
1456 pub rest: StructRest,
1457}
1458
1459#[derive(Clone, Encodable, Decodable, Debug)]
1461pub enum ExprKind {
1462 Array(ThinVec<P<Expr>>),
1464 ConstBlock(AnonConst),
1466 Call(P<Expr>, ThinVec<P<Expr>>),
1473 MethodCall(Box<MethodCall>),
1475 Tup(ThinVec<P<Expr>>),
1477 Binary(BinOp, P<Expr>, P<Expr>),
1479 Unary(UnOp, P<Expr>),
1481 Lit(token::Lit),
1483 Cast(P<Expr>, P<Ty>),
1485 Type(P<Expr>, P<Ty>),
1490 Let(P<Pat>, P<Expr>, Span, Recovered),
1495 If(P<Expr>, P<Block>, Option<P<Expr>>),
1499 While(P<Expr>, P<Block>, Option<Label>),
1503 ForLoop {
1509 pat: P<Pat>,
1510 iter: P<Expr>,
1511 body: P<Block>,
1512 label: Option<Label>,
1513 kind: ForLoopKind,
1514 },
1515 Loop(P<Block>, Option<Label>, Span),
1519 Match(P<Expr>, ThinVec<Arm>, MatchKind),
1521 Closure(Box<Closure>),
1523 Block(P<Block>, Option<Label>),
1525 Gen(CaptureBy, P<Block>, GenBlockKind, Span),
1531 Await(P<Expr>, Span),
1533
1534 TryBlock(P<Block>),
1536
1537 Assign(P<Expr>, P<Expr>, Span),
1540 AssignOp(BinOp, P<Expr>, P<Expr>),
1544 Field(P<Expr>, Ident),
1546 Index(P<Expr>, P<Expr>, Span),
1549 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1551 Underscore,
1553
1554 Path(Option<P<QSelf>>, Path),
1559
1560 AddrOf(BorrowKind, Mutability, P<Expr>),
1562 Break(Option<Label>, Option<P<Expr>>),
1564 Continue(Option<Label>),
1566 Ret(Option<P<Expr>>),
1568
1569 InlineAsm(P<InlineAsm>),
1571
1572 OffsetOf(P<Ty>, P<[Ident]>),
1577
1578 MacCall(P<MacCall>),
1580
1581 Struct(P<StructExpr>),
1585
1586 Repeat(P<Expr>, AnonConst),
1591
1592 Paren(P<Expr>),
1594
1595 Try(P<Expr>),
1597
1598 Yield(Option<P<Expr>>),
1600
1601 Yeet(Option<P<Expr>>),
1604
1605 Become(P<Expr>),
1609
1610 IncludedBytes(Arc<[u8]>),
1615
1616 FormatArgs(P<FormatArgs>),
1618
1619 UnsafeBinderCast(UnsafeBinderCastKind, P<Expr>, Option<P<Ty>>),
1620
1621 Err(ErrorGuaranteed),
1623
1624 Dummy,
1626}
1627
1628#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1630pub enum ForLoopKind {
1631 For,
1632 ForAwait,
1633}
1634
1635#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
1637pub enum GenBlockKind {
1638 Async,
1639 Gen,
1640 AsyncGen,
1641}
1642
1643impl fmt::Display for GenBlockKind {
1644 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1645 self.modifier().fmt(f)
1646 }
1647}
1648
1649impl GenBlockKind {
1650 pub fn modifier(&self) -> &'static str {
1651 match self {
1652 GenBlockKind::Async => "async",
1653 GenBlockKind::Gen => "gen",
1654 GenBlockKind::AsyncGen => "async gen",
1655 }
1656 }
1657}
1658
1659#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1661#[derive(Encodable, Decodable, HashStable_Generic)]
1662pub enum UnsafeBinderCastKind {
1663 Wrap,
1665 Unwrap,
1667}
1668
1669#[derive(Clone, Encodable, Decodable, Debug)]
1684pub struct QSelf {
1685 pub ty: P<Ty>,
1686
1687 pub path_span: Span,
1691 pub position: usize,
1692}
1693
1694#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
1696pub enum CaptureBy {
1697 Value {
1699 move_kw: Span,
1701 },
1702 Ref,
1704}
1705
1706#[derive(Clone, Encodable, Decodable, Debug)]
1708pub enum ClosureBinder {
1709 NotPresent,
1711 For {
1713 span: Span,
1720
1721 generic_params: ThinVec<GenericParam>,
1728 },
1729}
1730
1731#[derive(Clone, Encodable, Decodable, Debug)]
1734pub struct MacCall {
1735 pub path: Path,
1736 pub args: P<DelimArgs>,
1737}
1738
1739impl MacCall {
1740 pub fn span(&self) -> Span {
1741 self.path.span.to(self.args.dspan.entire())
1742 }
1743}
1744
1745#[derive(Clone, Encodable, Decodable, Debug)]
1747pub enum AttrArgs {
1748 Empty,
1750 Delimited(DelimArgs),
1752 Eq {
1754 eq_span: Span,
1756 expr: P<Expr>,
1757 },
1758}
1759
1760impl AttrArgs {
1761 pub fn span(&self) -> Option<Span> {
1762 match self {
1763 AttrArgs::Empty => None,
1764 AttrArgs::Delimited(args) => Some(args.dspan.entire()),
1765 AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
1766 }
1767 }
1768
1769 pub fn inner_tokens(&self) -> TokenStream {
1772 match self {
1773 AttrArgs::Empty => TokenStream::default(),
1774 AttrArgs::Delimited(args) => args.tokens.clone(),
1775 AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
1776 }
1777 }
1778}
1779
1780#[derive(Clone, Encodable, Decodable, Debug)]
1782pub struct DelimArgs {
1783 pub dspan: DelimSpan,
1784 pub delim: Delimiter, pub tokens: TokenStream,
1786}
1787
1788impl DelimArgs {
1789 pub fn need_semicolon(&self) -> bool {
1792 !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
1793 }
1794}
1795
1796impl<CTX> HashStable<CTX> for DelimArgs
1797where
1798 CTX: crate::HashStableContext,
1799{
1800 fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
1801 let DelimArgs { dspan, delim, tokens } = self;
1802 dspan.hash_stable(ctx, hasher);
1803 delim.hash_stable(ctx, hasher);
1804 tokens.hash_stable(ctx, hasher);
1805 }
1806}
1807
1808#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1810pub struct MacroDef {
1811 pub body: P<DelimArgs>,
1812 pub macro_rules: bool,
1814}
1815
1816#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
1817#[derive(HashStable_Generic)]
1818pub enum StrStyle {
1819 Cooked,
1821 Raw(u8),
1825}
1826
1827#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1829pub enum MatchKind {
1830 Prefix,
1832 Postfix,
1834}
1835
1836#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
1838pub struct MetaItemLit {
1839 pub symbol: Symbol,
1841 pub suffix: Option<Symbol>,
1843 pub kind: LitKind,
1846 pub span: Span,
1847}
1848
1849#[derive(Clone, Copy, Encodable, Decodable, Debug)]
1851pub struct StrLit {
1852 pub symbol: Symbol,
1854 pub suffix: Option<Symbol>,
1856 pub symbol_unescaped: Symbol,
1858 pub style: StrStyle,
1859 pub span: Span,
1860}
1861
1862impl StrLit {
1863 pub fn as_token_lit(&self) -> token::Lit {
1864 let token_kind = match self.style {
1865 StrStyle::Cooked => token::Str,
1866 StrStyle::Raw(n) => token::StrRaw(n),
1867 };
1868 token::Lit::new(token_kind, self.symbol, self.suffix)
1869 }
1870}
1871
1872#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1874#[derive(HashStable_Generic)]
1875pub enum LitIntType {
1876 Signed(IntTy),
1878 Unsigned(UintTy),
1880 Unsuffixed,
1882}
1883
1884#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
1886#[derive(HashStable_Generic)]
1887pub enum LitFloatType {
1888 Suffixed(FloatTy),
1890 Unsuffixed,
1892}
1893
1894#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
1901pub enum LitKind {
1902 Str(Symbol, StrStyle),
1905 ByteStr(Arc<[u8]>, StrStyle),
1908 CStr(Arc<[u8]>, StrStyle),
1910 Byte(u8),
1912 Char(char),
1914 Int(Pu128, LitIntType),
1916 Float(Symbol, LitFloatType),
1920 Bool(bool),
1922 Err(ErrorGuaranteed),
1924}
1925
1926impl LitKind {
1927 pub fn str(&self) -> Option<Symbol> {
1928 match *self {
1929 LitKind::Str(s, _) => Some(s),
1930 _ => None,
1931 }
1932 }
1933
1934 pub fn is_str(&self) -> bool {
1936 matches!(self, LitKind::Str(..))
1937 }
1938
1939 pub fn is_bytestr(&self) -> bool {
1941 matches!(self, LitKind::ByteStr(..))
1942 }
1943
1944 pub fn is_numeric(&self) -> bool {
1946 matches!(self, LitKind::Int(..) | LitKind::Float(..))
1947 }
1948
1949 pub fn is_unsuffixed(&self) -> bool {
1952 !self.is_suffixed()
1953 }
1954
1955 pub fn is_suffixed(&self) -> bool {
1957 match *self {
1958 LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
1960 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
1961 LitKind::Str(..)
1963 | LitKind::ByteStr(..)
1964 | LitKind::CStr(..)
1965 | LitKind::Byte(..)
1966 | LitKind::Char(..)
1967 | LitKind::Int(_, LitIntType::Unsuffixed)
1968 | LitKind::Float(_, LitFloatType::Unsuffixed)
1969 | LitKind::Bool(..)
1970 | LitKind::Err(_) => false,
1971 }
1972 }
1973}
1974
1975#[derive(Clone, Encodable, Decodable, Debug)]
1978pub struct MutTy {
1979 pub ty: P<Ty>,
1980 pub mutbl: Mutability,
1981}
1982
1983#[derive(Clone, Encodable, Decodable, Debug)]
1986pub struct FnSig {
1987 pub header: FnHeader,
1988 pub decl: P<FnDecl>,
1989 pub span: Span,
1990}
1991
1992#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
1993#[derive(Encodable, Decodable, HashStable_Generic)]
1994pub enum FloatTy {
1995 F16,
1996 F32,
1997 F64,
1998 F128,
1999}
2000
2001impl FloatTy {
2002 pub fn name_str(self) -> &'static str {
2003 match self {
2004 FloatTy::F16 => "f16",
2005 FloatTy::F32 => "f32",
2006 FloatTy::F64 => "f64",
2007 FloatTy::F128 => "f128",
2008 }
2009 }
2010
2011 pub fn name(self) -> Symbol {
2012 match self {
2013 FloatTy::F16 => sym::f16,
2014 FloatTy::F32 => sym::f32,
2015 FloatTy::F64 => sym::f64,
2016 FloatTy::F128 => sym::f128,
2017 }
2018 }
2019}
2020
2021#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
2022#[derive(Encodable, Decodable, HashStable_Generic)]
2023pub enum IntTy {
2024 Isize,
2025 I8,
2026 I16,
2027 I32,
2028 I64,
2029 I128,
2030}
2031
2032impl IntTy {
2033 pub fn name_str(&self) -> &'static str {
2034 match *self {
2035 IntTy::Isize => "isize",
2036 IntTy::I8 => "i8",
2037 IntTy::I16 => "i16",
2038 IntTy::I32 => "i32",
2039 IntTy::I64 => "i64",
2040 IntTy::I128 => "i128",
2041 }
2042 }
2043
2044 pub fn name(&self) -> Symbol {
2045 match *self {
2046 IntTy::Isize => sym::isize,
2047 IntTy::I8 => sym::i8,
2048 IntTy::I16 => sym::i16,
2049 IntTy::I32 => sym::i32,
2050 IntTy::I64 => sym::i64,
2051 IntTy::I128 => sym::i128,
2052 }
2053 }
2054}
2055
2056#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
2057#[derive(Encodable, Decodable, HashStable_Generic)]
2058pub enum UintTy {
2059 Usize,
2060 U8,
2061 U16,
2062 U32,
2063 U64,
2064 U128,
2065}
2066
2067impl UintTy {
2068 pub fn name_str(&self) -> &'static str {
2069 match *self {
2070 UintTy::Usize => "usize",
2071 UintTy::U8 => "u8",
2072 UintTy::U16 => "u16",
2073 UintTy::U32 => "u32",
2074 UintTy::U64 => "u64",
2075 UintTy::U128 => "u128",
2076 }
2077 }
2078
2079 pub fn name(&self) -> Symbol {
2080 match *self {
2081 UintTy::Usize => sym::usize,
2082 UintTy::U8 => sym::u8,
2083 UintTy::U16 => sym::u16,
2084 UintTy::U32 => sym::u32,
2085 UintTy::U64 => sym::u64,
2086 UintTy::U128 => sym::u128,
2087 }
2088 }
2089}
2090
2091#[derive(Clone, Encodable, Decodable, Debug)]
2102pub struct AssocItemConstraint {
2103 pub id: NodeId,
2104 pub ident: Ident,
2105 pub gen_args: Option<GenericArgs>,
2106 pub kind: AssocItemConstraintKind,
2107 pub span: Span,
2108}
2109
2110#[derive(Clone, Encodable, Decodable, Debug)]
2111pub enum Term {
2112 Ty(P<Ty>),
2113 Const(AnonConst),
2114}
2115
2116impl From<P<Ty>> for Term {
2117 fn from(v: P<Ty>) -> Self {
2118 Term::Ty(v)
2119 }
2120}
2121
2122impl From<AnonConst> for Term {
2123 fn from(v: AnonConst) -> Self {
2124 Term::Const(v)
2125 }
2126}
2127
2128#[derive(Clone, Encodable, Decodable, Debug)]
2130pub enum AssocItemConstraintKind {
2131 Equality { term: Term },
2138 Bound { bounds: GenericBounds },
2140}
2141
2142#[derive(Encodable, Decodable, Debug)]
2143pub struct Ty {
2144 pub id: NodeId,
2145 pub kind: TyKind,
2146 pub span: Span,
2147 pub tokens: Option<LazyAttrTokenStream>,
2148}
2149
2150impl Clone for Ty {
2151 fn clone(&self) -> Self {
2152 ensure_sufficient_stack(|| Self {
2153 id: self.id,
2154 kind: self.kind.clone(),
2155 span: self.span,
2156 tokens: self.tokens.clone(),
2157 })
2158 }
2159}
2160
2161impl Ty {
2162 pub fn peel_refs(&self) -> &Self {
2163 let mut final_ty = self;
2164 while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2165 {
2166 final_ty = ty;
2167 }
2168 final_ty
2169 }
2170
2171 pub fn is_maybe_parenthesised_infer(&self) -> bool {
2172 match &self.kind {
2173 TyKind::Infer => true,
2174 TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
2175 _ => false,
2176 }
2177 }
2178}
2179
2180#[derive(Clone, Encodable, Decodable, Debug)]
2181pub struct BareFnTy {
2182 pub safety: Safety,
2183 pub ext: Extern,
2184 pub generic_params: ThinVec<GenericParam>,
2185 pub decl: P<FnDecl>,
2186 pub decl_span: Span,
2189}
2190
2191#[derive(Clone, Encodable, Decodable, Debug)]
2192pub struct UnsafeBinderTy {
2193 pub generic_params: ThinVec<GenericParam>,
2194 pub inner_ty: P<Ty>,
2195}
2196
2197#[derive(Clone, Encodable, Decodable, Debug)]
2201pub enum TyKind {
2202 Slice(P<Ty>),
2204 Array(P<Ty>, AnonConst),
2206 Ptr(MutTy),
2208 Ref(Option<Lifetime>, MutTy),
2210 PinnedRef(Option<Lifetime>, MutTy),
2214 BareFn(P<BareFnTy>),
2216 UnsafeBinder(P<UnsafeBinderTy>),
2218 Never,
2220 Tup(ThinVec<P<Ty>>),
2222 Path(Option<P<QSelf>>, Path),
2227 TraitObject(GenericBounds, TraitObjectSyntax),
2230 ImplTrait(NodeId, GenericBounds),
2237 Paren(P<Ty>),
2239 Typeof(AnonConst),
2241 Infer,
2244 ImplicitSelf,
2246 MacCall(P<MacCall>),
2248 CVarArgs,
2250 Pat(P<Ty>, P<TyPat>),
2253 Dummy,
2255 Err(ErrorGuaranteed),
2257}
2258
2259impl TyKind {
2260 pub fn is_implicit_self(&self) -> bool {
2261 matches!(self, TyKind::ImplicitSelf)
2262 }
2263
2264 pub fn is_unit(&self) -> bool {
2265 matches!(self, TyKind::Tup(tys) if tys.is_empty())
2266 }
2267
2268 pub fn is_simple_path(&self) -> Option<Symbol> {
2269 if let TyKind::Path(None, Path { segments, .. }) = &self
2270 && let [segment] = &segments[..]
2271 && segment.args.is_none()
2272 {
2273 Some(segment.ident.name)
2274 } else {
2275 None
2276 }
2277 }
2278}
2279
2280#[derive(Clone, Encodable, Decodable, Debug)]
2282pub struct TyPat {
2283 pub id: NodeId,
2284 pub kind: TyPatKind,
2285 pub span: Span,
2286 pub tokens: Option<LazyAttrTokenStream>,
2287}
2288
2289#[derive(Clone, Encodable, Decodable, Debug)]
2293pub enum TyPatKind {
2294 Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2296
2297 Err(ErrorGuaranteed),
2299}
2300
2301#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2303#[repr(u8)]
2304pub enum TraitObjectSyntax {
2305 Dyn = 0,
2307 DynStar = 1,
2308 None = 2,
2309}
2310
2311unsafe impl Tag for TraitObjectSyntax {
2315 const BITS: u32 = 2;
2316
2317 fn into_usize(self) -> usize {
2318 self as u8 as usize
2319 }
2320
2321 unsafe fn from_usize(tag: usize) -> Self {
2322 match tag {
2323 0 => TraitObjectSyntax::Dyn,
2324 1 => TraitObjectSyntax::DynStar,
2325 2 => TraitObjectSyntax::None,
2326 _ => unreachable!(),
2327 }
2328 }
2329}
2330
2331#[derive(Clone, Encodable, Decodable, Debug)]
2332pub enum PreciseCapturingArg {
2333 Lifetime(Lifetime),
2335 Arg(Path, NodeId),
2337}
2338
2339#[derive(Clone, Copy, Encodable, Decodable, Debug)]
2343pub enum InlineAsmRegOrRegClass {
2344 Reg(Symbol),
2345 RegClass(Symbol),
2346}
2347
2348#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2349pub struct InlineAsmOptions(u16);
2350bitflags::bitflags! {
2351 impl InlineAsmOptions: u16 {
2352 const PURE = 1 << 0;
2353 const NOMEM = 1 << 1;
2354 const READONLY = 1 << 2;
2355 const PRESERVES_FLAGS = 1 << 3;
2356 const NORETURN = 1 << 4;
2357 const NOSTACK = 1 << 5;
2358 const ATT_SYNTAX = 1 << 6;
2359 const RAW = 1 << 7;
2360 const MAY_UNWIND = 1 << 8;
2361 }
2362}
2363
2364impl InlineAsmOptions {
2365 pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2366
2367 pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2368 pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2369
2370 pub fn human_readable_names(&self) -> Vec<&'static str> {
2371 let mut options = vec![];
2372
2373 if self.contains(InlineAsmOptions::PURE) {
2374 options.push("pure");
2375 }
2376 if self.contains(InlineAsmOptions::NOMEM) {
2377 options.push("nomem");
2378 }
2379 if self.contains(InlineAsmOptions::READONLY) {
2380 options.push("readonly");
2381 }
2382 if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2383 options.push("preserves_flags");
2384 }
2385 if self.contains(InlineAsmOptions::NORETURN) {
2386 options.push("noreturn");
2387 }
2388 if self.contains(InlineAsmOptions::NOSTACK) {
2389 options.push("nostack");
2390 }
2391 if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2392 options.push("att_syntax");
2393 }
2394 if self.contains(InlineAsmOptions::RAW) {
2395 options.push("raw");
2396 }
2397 if self.contains(InlineAsmOptions::MAY_UNWIND) {
2398 options.push("may_unwind");
2399 }
2400
2401 options
2402 }
2403}
2404
2405impl std::fmt::Debug for InlineAsmOptions {
2406 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2407 bitflags::parser::to_writer(self, f)
2408 }
2409}
2410
2411#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
2412pub enum InlineAsmTemplatePiece {
2413 String(Cow<'static, str>),
2414 Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2415}
2416
2417impl fmt::Display for InlineAsmTemplatePiece {
2418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2419 match self {
2420 Self::String(s) => {
2421 for c in s.chars() {
2422 match c {
2423 '{' => f.write_str("{{")?,
2424 '}' => f.write_str("}}")?,
2425 _ => c.fmt(f)?,
2426 }
2427 }
2428 Ok(())
2429 }
2430 Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2431 write!(f, "{{{operand_idx}:{modifier}}}")
2432 }
2433 Self::Placeholder { operand_idx, modifier: None, .. } => {
2434 write!(f, "{{{operand_idx}}}")
2435 }
2436 }
2437 }
2438}
2439
2440impl InlineAsmTemplatePiece {
2441 pub fn to_string(s: &[Self]) -> String {
2443 use fmt::Write;
2444 let mut out = String::new();
2445 for p in s.iter() {
2446 let _ = write!(out, "{p}");
2447 }
2448 out
2449 }
2450}
2451
2452#[derive(Clone, Encodable, Decodable, Debug)]
2460pub struct InlineAsmSym {
2461 pub id: NodeId,
2462 pub qself: Option<P<QSelf>>,
2463 pub path: Path,
2464}
2465
2466#[derive(Clone, Encodable, Decodable, Debug)]
2470pub enum InlineAsmOperand {
2471 In {
2472 reg: InlineAsmRegOrRegClass,
2473 expr: P<Expr>,
2474 },
2475 Out {
2476 reg: InlineAsmRegOrRegClass,
2477 late: bool,
2478 expr: Option<P<Expr>>,
2479 },
2480 InOut {
2481 reg: InlineAsmRegOrRegClass,
2482 late: bool,
2483 expr: P<Expr>,
2484 },
2485 SplitInOut {
2486 reg: InlineAsmRegOrRegClass,
2487 late: bool,
2488 in_expr: P<Expr>,
2489 out_expr: Option<P<Expr>>,
2490 },
2491 Const {
2492 anon_const: AnonConst,
2493 },
2494 Sym {
2495 sym: InlineAsmSym,
2496 },
2497 Label {
2498 block: P<Block>,
2499 },
2500}
2501
2502impl InlineAsmOperand {
2503 pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2504 match self {
2505 Self::In { reg, .. }
2506 | Self::Out { reg, .. }
2507 | Self::InOut { reg, .. }
2508 | Self::SplitInOut { reg, .. } => Some(reg),
2509 Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2510 }
2511 }
2512}
2513
2514#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2515pub enum AsmMacro {
2516 Asm,
2518 GlobalAsm,
2520 NakedAsm,
2522}
2523
2524impl AsmMacro {
2525 pub const fn macro_name(self) -> &'static str {
2526 match self {
2527 AsmMacro::Asm => "asm",
2528 AsmMacro::GlobalAsm => "global_asm",
2529 AsmMacro::NakedAsm => "naked_asm",
2530 }
2531 }
2532
2533 pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2534 match self {
2535 AsmMacro::Asm => true,
2536 AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2537 AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2538 }
2539 }
2540
2541 pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2542 match self {
2543 AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2544 AsmMacro::GlobalAsm => true,
2545 AsmMacro::NakedAsm => true,
2546 }
2547 }
2548}
2549
2550#[derive(Clone, Encodable, Decodable, Debug)]
2554pub struct InlineAsm {
2555 pub asm_macro: AsmMacro,
2556 pub template: Vec<InlineAsmTemplatePiece>,
2557 pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2558 pub operands: Vec<(InlineAsmOperand, Span)>,
2559 pub clobber_abis: Vec<(Symbol, Span)>,
2560 pub options: InlineAsmOptions,
2561 pub line_spans: Vec<Span>,
2562}
2563
2564#[derive(Clone, Encodable, Decodable, Debug)]
2568pub struct Param {
2569 pub attrs: AttrVec,
2570 pub ty: P<Ty>,
2571 pub pat: P<Pat>,
2572 pub id: NodeId,
2573 pub span: Span,
2574 pub is_placeholder: bool,
2575}
2576
2577#[derive(Clone, Encodable, Decodable, Debug)]
2581pub enum SelfKind {
2582 Value(Mutability),
2584 Region(Option<Lifetime>, Mutability),
2586 Explicit(P<Ty>, Mutability),
2588}
2589
2590impl SelfKind {
2591 pub fn to_ref_suggestion(&self) -> String {
2592 match self {
2593 SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2594 SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2595 SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2596 unreachable!("if we had an explicit self, we wouldn't be here")
2597 }
2598 }
2599 }
2600}
2601
2602pub type ExplicitSelf = Spanned<SelfKind>;
2603
2604impl Param {
2605 pub fn to_self(&self) -> Option<ExplicitSelf> {
2607 if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2608 if ident.name == kw::SelfLower {
2609 return match self.ty.kind {
2610 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2611 TyKind::Ref(lt, MutTy { ref ty, mutbl })
2612 | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2613 if ty.kind.is_implicit_self() =>
2614 {
2615 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2616 }
2617 _ => Some(respan(
2618 self.pat.span.to(self.ty.span),
2619 SelfKind::Explicit(self.ty.clone(), mutbl),
2620 )),
2621 };
2622 }
2623 }
2624 None
2625 }
2626
2627 pub fn is_self(&self) -> bool {
2629 if let PatKind::Ident(_, ident, _) = self.pat.kind {
2630 ident.name == kw::SelfLower
2631 } else {
2632 false
2633 }
2634 }
2635
2636 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2638 let span = eself.span.to(eself_ident.span);
2639 let infer_ty = P(Ty {
2640 id: DUMMY_NODE_ID,
2641 kind: TyKind::ImplicitSelf,
2642 span: eself_ident.span,
2643 tokens: None,
2644 });
2645 let (mutbl, ty) = match eself.node {
2646 SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2647 SelfKind::Value(mutbl) => (mutbl, infer_ty),
2648 SelfKind::Region(lt, mutbl) => (
2649 Mutability::Not,
2650 P(Ty {
2651 id: DUMMY_NODE_ID,
2652 kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2653 span,
2654 tokens: None,
2655 }),
2656 ),
2657 };
2658 Param {
2659 attrs,
2660 pat: P(Pat {
2661 id: DUMMY_NODE_ID,
2662 kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2663 span,
2664 tokens: None,
2665 }),
2666 span,
2667 ty,
2668 id: DUMMY_NODE_ID,
2669 is_placeholder: false,
2670 }
2671 }
2672}
2673
2674#[derive(Clone, Encodable, Decodable, Debug)]
2681pub struct FnDecl {
2682 pub inputs: ThinVec<Param>,
2683 pub output: FnRetTy,
2684}
2685
2686impl FnDecl {
2687 pub fn has_self(&self) -> bool {
2688 self.inputs.get(0).is_some_and(Param::is_self)
2689 }
2690 pub fn c_variadic(&self) -> bool {
2691 self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
2692 }
2693}
2694
2695#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2697pub enum IsAuto {
2698 Yes,
2699 No,
2700}
2701
2702#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2704#[derive(HashStable_Generic)]
2705pub enum Safety {
2706 Unsafe(Span),
2708 Safe(Span),
2710 Default,
2713}
2714
2715#[derive(Copy, Clone, Encodable, Decodable, Debug)]
2721pub enum CoroutineKind {
2722 Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2724 Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2726 AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2728}
2729
2730impl CoroutineKind {
2731 pub fn span(self) -> Span {
2732 match self {
2733 CoroutineKind::Async { span, .. } => span,
2734 CoroutineKind::Gen { span, .. } => span,
2735 CoroutineKind::AsyncGen { span, .. } => span,
2736 }
2737 }
2738
2739 pub fn as_str(self) -> &'static str {
2740 match self {
2741 CoroutineKind::Async { .. } => "async",
2742 CoroutineKind::Gen { .. } => "gen",
2743 CoroutineKind::AsyncGen { .. } => "async gen",
2744 }
2745 }
2746
2747 pub fn closure_id(self) -> NodeId {
2748 match self {
2749 CoroutineKind::Async { closure_id, .. }
2750 | CoroutineKind::Gen { closure_id, .. }
2751 | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
2752 }
2753 }
2754
2755 pub fn return_id(self) -> (NodeId, Span) {
2758 match self {
2759 CoroutineKind::Async { return_impl_trait_id, span, .. }
2760 | CoroutineKind::Gen { return_impl_trait_id, span, .. }
2761 | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
2762 (return_impl_trait_id, span)
2763 }
2764 }
2765 }
2766}
2767
2768#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
2769#[derive(HashStable_Generic)]
2770pub enum Const {
2771 Yes(Span),
2772 No,
2773}
2774
2775#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
2778pub enum Defaultness {
2779 Default(Span),
2780 Final,
2781}
2782
2783#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
2784pub enum ImplPolarity {
2785 Positive,
2787 Negative(Span),
2789}
2790
2791impl fmt::Debug for ImplPolarity {
2792 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2793 match *self {
2794 ImplPolarity::Positive => "positive".fmt(f),
2795 ImplPolarity::Negative(_) => "negative".fmt(f),
2796 }
2797 }
2798}
2799
2800#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2802#[derive(HashStable_Generic)]
2803pub enum BoundPolarity {
2804 Positive,
2806 Negative(Span),
2808 Maybe(Span),
2810}
2811
2812impl BoundPolarity {
2813 pub fn as_str(self) -> &'static str {
2814 match self {
2815 Self::Positive => "",
2816 Self::Negative(_) => "!",
2817 Self::Maybe(_) => "?",
2818 }
2819 }
2820}
2821
2822#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
2824#[derive(HashStable_Generic)]
2825pub enum BoundConstness {
2826 Never,
2828 Always(Span),
2830 Maybe(Span),
2832}
2833
2834impl BoundConstness {
2835 pub fn as_str(self) -> &'static str {
2836 match self {
2837 Self::Never => "",
2838 Self::Always(_) => "const",
2839 Self::Maybe(_) => "~const",
2840 }
2841 }
2842}
2843
2844#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
2846#[derive(HashStable_Generic)]
2847pub enum BoundAsyncness {
2848 Normal,
2850 Async(Span),
2852}
2853
2854impl BoundAsyncness {
2855 pub fn as_str(self) -> &'static str {
2856 match self {
2857 Self::Normal => "",
2858 Self::Async(_) => "async",
2859 }
2860 }
2861}
2862
2863#[derive(Clone, Encodable, Decodable, Debug)]
2864pub enum FnRetTy {
2865 Default(Span),
2870 Ty(P<Ty>),
2872}
2873
2874impl FnRetTy {
2875 pub fn span(&self) -> Span {
2876 match self {
2877 &FnRetTy::Default(span) => span,
2878 FnRetTy::Ty(ty) => ty.span,
2879 }
2880 }
2881}
2882
2883#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
2884pub enum Inline {
2885 Yes,
2886 No,
2887}
2888
2889#[derive(Clone, Encodable, Decodable, Debug)]
2891pub enum ModKind {
2892 Loaded(ThinVec<P<Item>>, Inline, ModSpans, Result<(), ErrorGuaranteed>),
2897 Unloaded,
2899}
2900
2901#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
2902pub struct ModSpans {
2903 pub inner_span: Span,
2906 pub inject_use_span: Span,
2907}
2908
2909#[derive(Clone, Encodable, Decodable, Debug)]
2913pub struct ForeignMod {
2914 pub extern_span: Span,
2916 pub safety: Safety,
2919 pub abi: Option<StrLit>,
2920 pub items: ThinVec<P<ForeignItem>>,
2921}
2922
2923#[derive(Clone, Encodable, Decodable, Debug)]
2924pub struct EnumDef {
2925 pub variants: ThinVec<Variant>,
2926}
2927#[derive(Clone, Encodable, Decodable, Debug)]
2929pub struct Variant {
2930 pub attrs: AttrVec,
2932 pub id: NodeId,
2934 pub span: Span,
2936 pub vis: Visibility,
2938 pub ident: Ident,
2940
2941 pub data: VariantData,
2943 pub disr_expr: Option<AnonConst>,
2945 pub is_placeholder: bool,
2947}
2948
2949#[derive(Clone, Encodable, Decodable, Debug)]
2951pub enum UseTreeKind {
2952 Simple(Option<Ident>),
2954 Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
2963 Glob,
2965}
2966
2967#[derive(Clone, Encodable, Decodable, Debug)]
2970pub struct UseTree {
2971 pub prefix: Path,
2972 pub kind: UseTreeKind,
2973 pub span: Span,
2974}
2975
2976impl UseTree {
2977 pub fn ident(&self) -> Ident {
2978 match self.kind {
2979 UseTreeKind::Simple(Some(rename)) => rename,
2980 UseTreeKind::Simple(None) => {
2981 self.prefix.segments.last().expect("empty prefix in a simple import").ident
2982 }
2983 _ => panic!("`UseTree::ident` can only be used on a simple import"),
2984 }
2985 }
2986}
2987
2988#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic)]
2992pub enum AttrStyle {
2993 Outer,
2994 Inner,
2995}
2996
2997pub type AttrVec = ThinVec<Attribute>;
2999
3000#[derive(Clone, Encodable, Decodable, Debug)]
3002pub struct Attribute {
3003 pub kind: AttrKind,
3004 pub id: AttrId,
3005 pub style: AttrStyle,
3008 pub span: Span,
3009}
3010
3011#[derive(Clone, Encodable, Decodable, Debug)]
3012pub enum AttrKind {
3013 Normal(P<NormalAttr>),
3015
3016 DocComment(CommentKind, Symbol),
3020}
3021
3022#[derive(Clone, Encodable, Decodable, Debug)]
3023pub struct NormalAttr {
3024 pub item: AttrItem,
3025 pub tokens: Option<LazyAttrTokenStream>,
3027}
3028
3029impl NormalAttr {
3030 pub fn from_ident(ident: Ident) -> Self {
3031 Self {
3032 item: AttrItem {
3033 unsafety: Safety::Default,
3034 path: Path::from_ident(ident),
3035 args: AttrArgs::Empty,
3036 tokens: None,
3037 },
3038 tokens: None,
3039 }
3040 }
3041}
3042
3043#[derive(Clone, Encodable, Decodable, Debug)]
3044pub struct AttrItem {
3045 pub unsafety: Safety,
3046 pub path: Path,
3047 pub args: AttrArgs,
3048 pub tokens: Option<LazyAttrTokenStream>,
3050}
3051
3052impl AttrItem {
3053 pub fn is_valid_for_outer_style(&self) -> bool {
3054 self.path == sym::cfg_attr
3055 || self.path == sym::cfg
3056 || self.path == sym::forbid
3057 || self.path == sym::warn
3058 || self.path == sym::allow
3059 || self.path == sym::deny
3060 }
3061}
3062
3063#[derive(Clone, Encodable, Decodable, Debug)]
3070pub struct TraitRef {
3071 pub path: Path,
3072 pub ref_id: NodeId,
3073}
3074
3075#[derive(Clone, Encodable, Decodable, Debug)]
3076pub struct PolyTraitRef {
3077 pub bound_generic_params: ThinVec<GenericParam>,
3079
3080 pub modifiers: TraitBoundModifiers,
3082
3083 pub trait_ref: TraitRef,
3085
3086 pub span: Span,
3087}
3088
3089impl PolyTraitRef {
3090 pub fn new(
3091 generic_params: ThinVec<GenericParam>,
3092 path: Path,
3093 modifiers: TraitBoundModifiers,
3094 span: Span,
3095 ) -> Self {
3096 PolyTraitRef {
3097 bound_generic_params: generic_params,
3098 modifiers,
3099 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3100 span,
3101 }
3102 }
3103}
3104
3105#[derive(Clone, Encodable, Decodable, Debug)]
3106pub struct Visibility {
3107 pub kind: VisibilityKind,
3108 pub span: Span,
3109 pub tokens: Option<LazyAttrTokenStream>,
3110}
3111
3112#[derive(Clone, Encodable, Decodable, Debug)]
3113pub enum VisibilityKind {
3114 Public,
3115 Restricted { path: P<Path>, id: NodeId, shorthand: bool },
3116 Inherited,
3117}
3118
3119impl VisibilityKind {
3120 pub fn is_pub(&self) -> bool {
3121 matches!(self, VisibilityKind::Public)
3122 }
3123}
3124
3125#[derive(Clone, Encodable, Decodable, Debug)]
3129pub struct FieldDef {
3130 pub attrs: AttrVec,
3131 pub id: NodeId,
3132 pub span: Span,
3133 pub vis: Visibility,
3134 pub safety: Safety,
3135 pub ident: Option<Ident>,
3136
3137 pub ty: P<Ty>,
3138 pub default: Option<AnonConst>,
3139 pub is_placeholder: bool,
3140}
3141
3142#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
3144pub enum Recovered {
3145 No,
3146 Yes(ErrorGuaranteed),
3147}
3148
3149#[derive(Clone, Encodable, Decodable, Debug)]
3151pub enum VariantData {
3152 Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3156 Tuple(ThinVec<FieldDef>, NodeId),
3160 Unit(NodeId),
3164}
3165
3166impl VariantData {
3167 pub fn fields(&self) -> &[FieldDef] {
3169 match self {
3170 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3171 _ => &[],
3172 }
3173 }
3174
3175 pub fn ctor_node_id(&self) -> Option<NodeId> {
3177 match *self {
3178 VariantData::Struct { .. } => None,
3179 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3180 }
3181 }
3182}
3183
3184#[derive(Clone, Encodable, Decodable, Debug)]
3186pub struct Item<K = ItemKind> {
3187 pub attrs: AttrVec,
3188 pub id: NodeId,
3189 pub span: Span,
3190 pub vis: Visibility,
3191 pub ident: Ident,
3194
3195 pub kind: K,
3196
3197 pub tokens: Option<LazyAttrTokenStream>,
3205}
3206
3207impl Item {
3208 pub fn span_with_attributes(&self) -> Span {
3210 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3211 }
3212
3213 pub fn opt_generics(&self) -> Option<&Generics> {
3214 match &self.kind {
3215 ItemKind::ExternCrate(_)
3216 | ItemKind::Use(_)
3217 | ItemKind::Mod(_, _)
3218 | ItemKind::ForeignMod(_)
3219 | ItemKind::GlobalAsm(_)
3220 | ItemKind::MacCall(_)
3221 | ItemKind::Delegation(_)
3222 | ItemKind::DelegationMac(_)
3223 | ItemKind::MacroDef(_) => None,
3224 ItemKind::Static(_) => None,
3225 ItemKind::Const(i) => Some(&i.generics),
3226 ItemKind::Fn(i) => Some(&i.generics),
3227 ItemKind::TyAlias(i) => Some(&i.generics),
3228 ItemKind::TraitAlias(generics, _)
3229 | ItemKind::Enum(_, generics)
3230 | ItemKind::Struct(_, generics)
3231 | ItemKind::Union(_, generics) => Some(&generics),
3232 ItemKind::Trait(i) => Some(&i.generics),
3233 ItemKind::Impl(i) => Some(&i.generics),
3234 }
3235 }
3236}
3237
3238#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3240pub enum Extern {
3241 None,
3245 Implicit(Span),
3251 Explicit(StrLit, Span),
3255}
3256
3257impl Extern {
3258 pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3259 match abi {
3260 Some(name) => Extern::Explicit(name, span),
3261 None => Extern::Implicit(span),
3262 }
3263 }
3264}
3265
3266#[derive(Clone, Copy, Encodable, Decodable, Debug)]
3271pub struct FnHeader {
3272 pub safety: Safety,
3274 pub coroutine_kind: Option<CoroutineKind>,
3276 pub constness: Const,
3278 pub ext: Extern,
3280}
3281
3282impl FnHeader {
3283 pub fn has_qualifiers(&self) -> bool {
3285 let Self { safety, coroutine_kind, constness, ext } = self;
3286 matches!(safety, Safety::Unsafe(_))
3287 || coroutine_kind.is_some()
3288 || matches!(constness, Const::Yes(_))
3289 || !matches!(ext, Extern::None)
3290 }
3291}
3292
3293impl Default for FnHeader {
3294 fn default() -> FnHeader {
3295 FnHeader {
3296 safety: Safety::Default,
3297 coroutine_kind: None,
3298 constness: Const::No,
3299 ext: Extern::None,
3300 }
3301 }
3302}
3303
3304#[derive(Clone, Encodable, Decodable, Debug)]
3305pub struct Trait {
3306 pub safety: Safety,
3307 pub is_auto: IsAuto,
3308 pub generics: Generics,
3309 pub bounds: GenericBounds,
3310 pub items: ThinVec<P<AssocItem>>,
3311}
3312
3313#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3332pub struct TyAliasWhereClause {
3333 pub has_where_token: bool,
3334 pub span: Span,
3335}
3336
3337#[derive(Copy, Clone, Encodable, Decodable, Debug, Default)]
3339pub struct TyAliasWhereClauses {
3340 pub before: TyAliasWhereClause,
3342 pub after: TyAliasWhereClause,
3344 pub split: usize,
3348}
3349
3350#[derive(Clone, Encodable, Decodable, Debug)]
3351pub struct TyAlias {
3352 pub defaultness: Defaultness,
3353 pub generics: Generics,
3354 pub where_clauses: TyAliasWhereClauses,
3355 pub bounds: GenericBounds,
3356 pub ty: Option<P<Ty>>,
3357}
3358
3359#[derive(Clone, Encodable, Decodable, Debug)]
3360pub struct Impl {
3361 pub defaultness: Defaultness,
3362 pub safety: Safety,
3363 pub generics: Generics,
3364 pub constness: Const,
3365 pub polarity: ImplPolarity,
3366 pub of_trait: Option<TraitRef>,
3368 pub self_ty: P<Ty>,
3369 pub items: ThinVec<P<AssocItem>>,
3370}
3371
3372#[derive(Clone, Encodable, Decodable, Debug, Default)]
3373pub struct FnContract {
3374 pub requires: Option<P<Expr>>,
3375 pub ensures: Option<P<Expr>>,
3376}
3377
3378#[derive(Clone, Encodable, Decodable, Debug)]
3379pub struct Fn {
3380 pub defaultness: Defaultness,
3381 pub generics: Generics,
3382 pub sig: FnSig,
3383 pub contract: Option<P<FnContract>>,
3384 pub body: Option<P<Block>>,
3385}
3386
3387#[derive(Clone, Encodable, Decodable, Debug)]
3388pub struct Delegation {
3389 pub id: NodeId,
3391 pub qself: Option<P<QSelf>>,
3392 pub path: Path,
3393 pub rename: Option<Ident>,
3394 pub body: Option<P<Block>>,
3395 pub from_glob: bool,
3397}
3398
3399#[derive(Clone, Encodable, Decodable, Debug)]
3400pub struct DelegationMac {
3401 pub qself: Option<P<QSelf>>,
3402 pub prefix: Path,
3403 pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3405 pub body: Option<P<Block>>,
3406}
3407
3408#[derive(Clone, Encodable, Decodable, Debug)]
3409pub struct StaticItem {
3410 pub ty: P<Ty>,
3411 pub safety: Safety,
3412 pub mutability: Mutability,
3413 pub expr: Option<P<Expr>>,
3414}
3415
3416#[derive(Clone, Encodable, Decodable, Debug)]
3417pub struct ConstItem {
3418 pub defaultness: Defaultness,
3419 pub generics: Generics,
3420 pub ty: P<Ty>,
3421 pub expr: Option<P<Expr>>,
3422}
3423
3424#[derive(Clone, Encodable, Decodable, Debug)]
3426pub enum ItemKind {
3427 ExternCrate(Option<Symbol>),
3431 Use(UseTree),
3435 Static(Box<StaticItem>),
3439 Const(Box<ConstItem>),
3443 Fn(Box<Fn>),
3447 Mod(Safety, ModKind),
3453 ForeignMod(ForeignMod),
3457 GlobalAsm(Box<InlineAsm>),
3459 TyAlias(Box<TyAlias>),
3463 Enum(EnumDef, Generics),
3467 Struct(VariantData, Generics),
3471 Union(VariantData, Generics),
3475 Trait(Box<Trait>),
3479 TraitAlias(Generics, GenericBounds),
3483 Impl(Box<Impl>),
3487 MacCall(P<MacCall>),
3491
3492 MacroDef(MacroDef),
3494
3495 Delegation(Box<Delegation>),
3499 DelegationMac(Box<DelegationMac>),
3502}
3503
3504impl ItemKind {
3505 pub fn article(&self) -> &'static str {
3507 use ItemKind::*;
3508 match self {
3509 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3510 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3511 | Delegation(..) | DelegationMac(..) => "a",
3512 ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3513 }
3514 }
3515
3516 pub fn descr(&self) -> &'static str {
3517 match self {
3518 ItemKind::ExternCrate(..) => "extern crate",
3519 ItemKind::Use(..) => "`use` import",
3520 ItemKind::Static(..) => "static item",
3521 ItemKind::Const(..) => "constant item",
3522 ItemKind::Fn(..) => "function",
3523 ItemKind::Mod(..) => "module",
3524 ItemKind::ForeignMod(..) => "extern block",
3525 ItemKind::GlobalAsm(..) => "global asm item",
3526 ItemKind::TyAlias(..) => "type alias",
3527 ItemKind::Enum(..) => "enum",
3528 ItemKind::Struct(..) => "struct",
3529 ItemKind::Union(..) => "union",
3530 ItemKind::Trait(..) => "trait",
3531 ItemKind::TraitAlias(..) => "trait alias",
3532 ItemKind::MacCall(..) => "item macro invocation",
3533 ItemKind::MacroDef(..) => "macro definition",
3534 ItemKind::Impl { .. } => "implementation",
3535 ItemKind::Delegation(..) => "delegated function",
3536 ItemKind::DelegationMac(..) => "delegation",
3537 }
3538 }
3539
3540 pub fn generics(&self) -> Option<&Generics> {
3541 match self {
3542 Self::Fn(box Fn { generics, .. })
3543 | Self::TyAlias(box TyAlias { generics, .. })
3544 | Self::Const(box ConstItem { generics, .. })
3545 | Self::Enum(_, generics)
3546 | Self::Struct(_, generics)
3547 | Self::Union(_, generics)
3548 | Self::Trait(box Trait { generics, .. })
3549 | Self::TraitAlias(generics, _)
3550 | Self::Impl(box Impl { generics, .. }) => Some(generics),
3551 _ => None,
3552 }
3553 }
3554}
3555
3556pub type AssocItem = Item<AssocItemKind>;
3559
3560#[derive(Clone, Encodable, Decodable, Debug)]
3568pub enum AssocItemKind {
3569 Const(Box<ConstItem>),
3572 Fn(Box<Fn>),
3574 Type(Box<TyAlias>),
3576 MacCall(P<MacCall>),
3578 Delegation(Box<Delegation>),
3580 DelegationMac(Box<DelegationMac>),
3582}
3583
3584impl AssocItemKind {
3585 pub fn defaultness(&self) -> Defaultness {
3586 match *self {
3587 Self::Const(box ConstItem { defaultness, .. })
3588 | Self::Fn(box Fn { defaultness, .. })
3589 | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3590 Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3591 Defaultness::Final
3592 }
3593 }
3594 }
3595}
3596
3597impl From<AssocItemKind> for ItemKind {
3598 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
3599 match assoc_item_kind {
3600 AssocItemKind::Const(item) => ItemKind::Const(item),
3601 AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3602 AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3603 AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
3604 AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
3605 AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
3606 }
3607 }
3608}
3609
3610impl TryFrom<ItemKind> for AssocItemKind {
3611 type Error = ItemKind;
3612
3613 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
3614 Ok(match item_kind {
3615 ItemKind::Const(item) => AssocItemKind::Const(item),
3616 ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
3617 ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
3618 ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
3619 ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
3620 ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
3621 _ => return Err(item_kind),
3622 })
3623 }
3624}
3625
3626#[derive(Clone, Encodable, Decodable, Debug)]
3628pub enum ForeignItemKind {
3629 Static(Box<StaticItem>),
3631 Fn(Box<Fn>),
3633 TyAlias(Box<TyAlias>),
3635 MacCall(P<MacCall>),
3637}
3638
3639impl From<ForeignItemKind> for ItemKind {
3640 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
3641 match foreign_item_kind {
3642 ForeignItemKind::Static(box static_foreign_item) => {
3643 ItemKind::Static(Box::new(static_foreign_item))
3644 }
3645 ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
3646 ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
3647 ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
3648 }
3649 }
3650}
3651
3652impl TryFrom<ItemKind> for ForeignItemKind {
3653 type Error = ItemKind;
3654
3655 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
3656 Ok(match item_kind {
3657 ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
3658 ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
3659 ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
3660 ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
3661 _ => return Err(item_kind),
3662 })
3663 }
3664}
3665
3666pub type ForeignItem = Item<ForeignItemKind>;
3667
3668#[cfg(target_pointer_width = "64")]
3670mod size_asserts {
3671 use rustc_data_structures::static_assert_size;
3672
3673 use super::*;
3674 static_assert_size!(AssocItem, 88);
3676 static_assert_size!(AssocItemKind, 16);
3677 static_assert_size!(Attribute, 32);
3678 static_assert_size!(Block, 32);
3679 static_assert_size!(Expr, 72);
3680 static_assert_size!(ExprKind, 40);
3681 static_assert_size!(Fn, 168);
3682 static_assert_size!(ForeignItem, 88);
3683 static_assert_size!(ForeignItemKind, 16);
3684 static_assert_size!(GenericArg, 24);
3685 static_assert_size!(GenericBound, 88);
3686 static_assert_size!(Generics, 40);
3687 static_assert_size!(Impl, 136);
3688 static_assert_size!(Item, 136);
3689 static_assert_size!(ItemKind, 64);
3690 static_assert_size!(LitKind, 24);
3691 static_assert_size!(Local, 80);
3692 static_assert_size!(MetaItemLit, 40);
3693 static_assert_size!(Param, 40);
3694 static_assert_size!(Pat, 72);
3695 static_assert_size!(Path, 24);
3696 static_assert_size!(PathSegment, 24);
3697 static_assert_size!(PatKind, 48);
3698 static_assert_size!(Stmt, 32);
3699 static_assert_size!(StmtKind, 16);
3700 static_assert_size!(Ty, 64);
3701 static_assert_size!(TyKind, 40);
3702 }