1use std::borrow::Cow;
3use std::fmt;
4
5use rustc_abi::ExternAbi;
6use rustc_ast::attr::AttributeExt;
7use rustc_ast::token::CommentKind;
8use rustc_ast::util::parser::ExprPrecedence;
9use rustc_ast::{
10 self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType,
11 LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind, join_path_idents,
12};
13pub use rustc_ast::{
14 AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind,
15 BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto,
16 MetaItemInner, MetaItemLit, Movability, Mutability, UnOp,
17};
18use rustc_data_structures::fingerprint::Fingerprint;
19use rustc_data_structures::sorted_map::SortedMap;
20use rustc_data_structures::tagged_ptr::TaggedRef;
21use rustc_error_messages::{DiagArgValue, IntoDiagArg};
22use rustc_index::IndexVec;
23use rustc_macros::{Decodable, Encodable, HashStable_Generic};
24use rustc_span::def_id::LocalDefId;
25use rustc_span::source_map::Spanned;
26use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
27use rustc_target::asm::InlineAsmRegOrRegClass;
28use smallvec::SmallVec;
29use thin_vec::ThinVec;
30use tracing::debug;
31
32use crate::LangItem;
33use crate::attrs::AttributeKind;
34use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
35use crate::def_id::{DefId, LocalDefIdMap};
36pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
37use crate::intravisit::{FnKind, VisitorExt};
38use crate::lints::DelayedLints;
39
40#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
41pub enum AngleBrackets {
42 Missing,
44 Empty,
46 Full,
48}
49
50#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
51pub enum LifetimeSource {
52 Reference,
54
55 Path { angle_brackets: AngleBrackets },
58
59 OutlivesBound,
61
62 PreciseCapturing,
64
65 Other,
72}
73
74#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
75pub enum LifetimeSyntax {
76 Implicit,
78
79 ExplicitAnonymous,
81
82 ExplicitBound,
84}
85
86impl From<Ident> for LifetimeSyntax {
87 fn from(ident: Ident) -> Self {
88 let name = ident.name;
89
90 if name == sym::empty {
91 unreachable!("A lifetime name should never be empty");
92 } else if name == kw::UnderscoreLifetime {
93 LifetimeSyntax::ExplicitAnonymous
94 } else {
95 debug_assert!(name.as_str().starts_with('\''));
96 LifetimeSyntax::ExplicitBound
97 }
98 }
99}
100
101#[derive(Debug, Copy, Clone, HashStable_Generic)]
152#[repr(align(4))]
157pub struct Lifetime {
158 #[stable_hasher(ignore)]
159 pub hir_id: HirId,
160
161 pub ident: Ident,
165
166 pub kind: LifetimeKind,
168
169 pub source: LifetimeSource,
172
173 pub syntax: LifetimeSyntax,
176}
177
178#[derive(Debug, Copy, Clone, HashStable_Generic)]
179pub enum ParamName {
180 Plain(Ident),
182
183 Error(Ident),
189
190 Fresh,
205}
206
207impl ParamName {
208 pub fn ident(&self) -> Ident {
209 match *self {
210 ParamName::Plain(ident) | ParamName::Error(ident) => ident,
211 ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
212 }
213 }
214}
215
216#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
217pub enum LifetimeKind {
218 Param(LocalDefId),
220
221 ImplicitObjectLifetimeDefault,
233
234 Error,
237
238 Infer,
242
243 Static,
245}
246
247impl LifetimeKind {
248 fn is_elided(&self) -> bool {
249 match self {
250 LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer => true,
251
252 LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
257 }
258 }
259}
260
261impl fmt::Display for Lifetime {
262 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
263 self.ident.name.fmt(f)
264 }
265}
266
267impl Lifetime {
268 pub fn new(
269 hir_id: HirId,
270 ident: Ident,
271 kind: LifetimeKind,
272 source: LifetimeSource,
273 syntax: LifetimeSyntax,
274 ) -> Lifetime {
275 let lifetime = Lifetime { hir_id, ident, kind, source, syntax };
276
277 #[cfg(debug_assertions)]
279 match (lifetime.is_elided(), lifetime.is_anonymous()) {
280 (false, false) => {} (false, true) => {} (true, true) => {} (true, false) => panic!("bad Lifetime"),
284 }
285
286 lifetime
287 }
288
289 pub fn is_elided(&self) -> bool {
290 self.kind.is_elided()
291 }
292
293 pub fn is_anonymous(&self) -> bool {
294 self.ident.name == kw::UnderscoreLifetime
295 }
296
297 pub fn is_implicit(&self) -> bool {
298 matches!(self.syntax, LifetimeSyntax::Implicit)
299 }
300
301 pub fn is_static(&self) -> bool {
302 self.kind == LifetimeKind::Static
303 }
304
305 pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
306 use LifetimeSource::*;
307 use LifetimeSyntax::*;
308
309 debug_assert!(new_lifetime.starts_with('\''));
310
311 match (self.syntax, self.source) {
312 (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")),
314
315 (Implicit, Path { angle_brackets: AngleBrackets::Full }) => {
317 (self.ident.span, format!("{new_lifetime}, "))
318 }
319
320 (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => {
322 (self.ident.span, format!("{new_lifetime}"))
323 }
324
325 (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => {
327 (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
328 }
329
330 (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")),
332
333 (Implicit, source) => {
334 unreachable!("can't suggest for a implicit lifetime of {source:?}")
335 }
336 }
337 }
338}
339
340#[derive(Debug, Clone, Copy, HashStable_Generic)]
344pub struct Path<'hir, R = Res> {
345 pub span: Span,
346 pub res: R,
348 pub segments: &'hir [PathSegment<'hir>],
350}
351
352pub type UsePath<'hir> = Path<'hir, PerNS<Option<Res>>>;
354
355impl Path<'_> {
356 pub fn is_global(&self) -> bool {
357 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
358 }
359}
360
361#[derive(Debug, Clone, Copy, HashStable_Generic)]
364pub struct PathSegment<'hir> {
365 pub ident: Ident,
367 #[stable_hasher(ignore)]
368 pub hir_id: HirId,
369 pub res: Res,
370
371 pub args: Option<&'hir GenericArgs<'hir>>,
377
378 pub infer_args: bool,
383}
384
385impl<'hir> PathSegment<'hir> {
386 pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
388 PathSegment { ident, hir_id, res, infer_args: true, args: None }
389 }
390
391 pub fn invalid() -> Self {
392 Self::new(Ident::dummy(), HirId::INVALID, Res::Err)
393 }
394
395 pub fn args(&self) -> &GenericArgs<'hir> {
396 if let Some(ref args) = self.args {
397 args
398 } else {
399 const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
400 DUMMY
401 }
402 }
403}
404
405#[derive(Clone, Copy, Debug, HashStable_Generic)]
419#[repr(C)]
420pub struct ConstArg<'hir, Unambig = ()> {
421 #[stable_hasher(ignore)]
422 pub hir_id: HirId,
423 pub kind: ConstArgKind<'hir, Unambig>,
424}
425
426impl<'hir> ConstArg<'hir, AmbigArg> {
427 pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
438 let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
441 unsafe { &*ptr }
442 }
443}
444
445impl<'hir> ConstArg<'hir> {
446 pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
452 if let ConstArgKind::Infer(_, ()) = self.kind {
453 return None;
454 }
455
456 let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
460 Some(unsafe { &*ptr })
461 }
462}
463
464impl<'hir, Unambig> ConstArg<'hir, Unambig> {
465 pub fn anon_const_hir_id(&self) -> Option<HirId> {
466 match self.kind {
467 ConstArgKind::Anon(ac) => Some(ac.hir_id),
468 _ => None,
469 }
470 }
471
472 pub fn span(&self) -> Span {
473 match self.kind {
474 ConstArgKind::Path(path) => path.span(),
475 ConstArgKind::Anon(anon) => anon.span,
476 ConstArgKind::Infer(span, _) => span,
477 }
478 }
479}
480
481#[derive(Clone, Copy, Debug, HashStable_Generic)]
483#[repr(u8, C)]
484pub enum ConstArgKind<'hir, Unambig = ()> {
485 Path(QPath<'hir>),
491 Anon(&'hir AnonConst),
492 Infer(Span, Unambig),
495}
496
497#[derive(Clone, Copy, Debug, HashStable_Generic)]
498pub struct InferArg {
499 #[stable_hasher(ignore)]
500 pub hir_id: HirId,
501 pub span: Span,
502}
503
504impl InferArg {
505 pub fn to_ty(&self) -> Ty<'static> {
506 Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
507 }
508}
509
510#[derive(Debug, Clone, Copy, HashStable_Generic)]
511pub enum GenericArg<'hir> {
512 Lifetime(&'hir Lifetime),
513 Type(&'hir Ty<'hir, AmbigArg>),
514 Const(&'hir ConstArg<'hir, AmbigArg>),
515 Infer(InferArg),
525}
526
527impl GenericArg<'_> {
528 pub fn span(&self) -> Span {
529 match self {
530 GenericArg::Lifetime(l) => l.ident.span,
531 GenericArg::Type(t) => t.span,
532 GenericArg::Const(c) => c.span(),
533 GenericArg::Infer(i) => i.span,
534 }
535 }
536
537 pub fn hir_id(&self) -> HirId {
538 match self {
539 GenericArg::Lifetime(l) => l.hir_id,
540 GenericArg::Type(t) => t.hir_id,
541 GenericArg::Const(c) => c.hir_id,
542 GenericArg::Infer(i) => i.hir_id,
543 }
544 }
545
546 pub fn descr(&self) -> &'static str {
547 match self {
548 GenericArg::Lifetime(_) => "lifetime",
549 GenericArg::Type(_) => "type",
550 GenericArg::Const(_) => "constant",
551 GenericArg::Infer(_) => "placeholder",
552 }
553 }
554
555 pub fn to_ord(&self) -> ast::ParamKindOrd {
556 match self {
557 GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
558 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
559 ast::ParamKindOrd::TypeOrConst
560 }
561 }
562 }
563
564 pub fn is_ty_or_const(&self) -> bool {
565 match self {
566 GenericArg::Lifetime(_) => false,
567 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
568 }
569 }
570}
571
572#[derive(Debug, Clone, Copy, HashStable_Generic)]
574pub struct GenericArgs<'hir> {
575 pub args: &'hir [GenericArg<'hir>],
577 pub constraints: &'hir [AssocItemConstraint<'hir>],
579 pub parenthesized: GenericArgsParentheses,
584 pub span_ext: Span,
597}
598
599impl<'hir> GenericArgs<'hir> {
600 pub const fn none() -> Self {
601 Self {
602 args: &[],
603 constraints: &[],
604 parenthesized: GenericArgsParentheses::No,
605 span_ext: DUMMY_SP,
606 }
607 }
608
609 pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
614 if self.parenthesized != GenericArgsParentheses::ParenSugar {
615 return None;
616 }
617
618 let inputs = self
619 .args
620 .iter()
621 .find_map(|arg| {
622 let GenericArg::Type(ty) = arg else { return None };
623 let TyKind::Tup(tys) = &ty.kind else { return None };
624 Some(tys)
625 })
626 .unwrap();
627
628 Some((inputs, self.paren_sugar_output_inner()))
629 }
630
631 pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
636 (self.parenthesized == GenericArgsParentheses::ParenSugar)
637 .then(|| self.paren_sugar_output_inner())
638 }
639
640 fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
641 let [constraint] = self.constraints.try_into().unwrap();
642 debug_assert_eq!(constraint.ident.name, sym::Output);
643 constraint.ty().unwrap()
644 }
645
646 pub fn has_err(&self) -> Option<ErrorGuaranteed> {
647 self.args
648 .iter()
649 .find_map(|arg| {
650 let GenericArg::Type(ty) = arg else { return None };
651 let TyKind::Err(guar) = ty.kind else { return None };
652 Some(guar)
653 })
654 .or_else(|| {
655 self.constraints.iter().find_map(|constraint| {
656 let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
657 Some(guar)
658 })
659 })
660 }
661
662 #[inline]
663 pub fn num_lifetime_params(&self) -> usize {
664 self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
665 }
666
667 #[inline]
668 pub fn has_lifetime_params(&self) -> bool {
669 self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
670 }
671
672 #[inline]
673 pub fn num_generic_params(&self) -> usize {
676 self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
677 }
678
679 pub fn span(&self) -> Option<Span> {
685 let span_ext = self.span_ext()?;
686 Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
687 }
688
689 pub fn span_ext(&self) -> Option<Span> {
691 Some(self.span_ext).filter(|span| !span.is_empty())
692 }
693
694 pub fn is_empty(&self) -> bool {
695 self.args.is_empty()
696 }
697}
698
699#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
700pub enum GenericArgsParentheses {
701 No,
702 ReturnTypeNotation,
705 ParenSugar,
707}
708
709#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
711pub struct TraitBoundModifiers {
712 pub constness: BoundConstness,
713 pub polarity: BoundPolarity,
714}
715
716impl TraitBoundModifiers {
717 pub const NONE: Self =
718 TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
719}
720
721#[derive(Clone, Copy, Debug, HashStable_Generic)]
722pub enum GenericBound<'hir> {
723 Trait(PolyTraitRef<'hir>),
724 Outlives(&'hir Lifetime),
725 Use(&'hir [PreciseCapturingArg<'hir>], Span),
726}
727
728impl GenericBound<'_> {
729 pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
730 match self {
731 GenericBound::Trait(data) => Some(&data.trait_ref),
732 _ => None,
733 }
734 }
735
736 pub fn span(&self) -> Span {
737 match self {
738 GenericBound::Trait(t, ..) => t.span,
739 GenericBound::Outlives(l) => l.ident.span,
740 GenericBound::Use(_, span) => *span,
741 }
742 }
743}
744
745pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
746
747#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
748pub enum MissingLifetimeKind {
749 Underscore,
751 Ampersand,
753 Comma,
755 Brackets,
757}
758
759#[derive(Copy, Clone, Debug, HashStable_Generic)]
760pub enum LifetimeParamKind {
761 Explicit,
764
765 Elided(MissingLifetimeKind),
768
769 Error,
771}
772
773#[derive(Debug, Clone, Copy, HashStable_Generic)]
774pub enum GenericParamKind<'hir> {
775 Lifetime {
777 kind: LifetimeParamKind,
778 },
779 Type {
780 default: Option<&'hir Ty<'hir>>,
781 synthetic: bool,
782 },
783 Const {
784 ty: &'hir Ty<'hir>,
785 default: Option<&'hir ConstArg<'hir>>,
787 },
788}
789
790#[derive(Debug, Clone, Copy, HashStable_Generic)]
791pub struct GenericParam<'hir> {
792 #[stable_hasher(ignore)]
793 pub hir_id: HirId,
794 pub def_id: LocalDefId,
795 pub name: ParamName,
796 pub span: Span,
797 pub pure_wrt_drop: bool,
798 pub kind: GenericParamKind<'hir>,
799 pub colon_span: Option<Span>,
800 pub source: GenericParamSource,
801}
802
803impl<'hir> GenericParam<'hir> {
804 pub fn is_impl_trait(&self) -> bool {
808 matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
809 }
810
811 pub fn is_elided_lifetime(&self) -> bool {
815 matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
816 }
817}
818
819#[derive(Debug, Clone, Copy, HashStable_Generic)]
826pub enum GenericParamSource {
827 Generics,
829 Binder,
831}
832
833#[derive(Default)]
834pub struct GenericParamCount {
835 pub lifetimes: usize,
836 pub types: usize,
837 pub consts: usize,
838 pub infer: usize,
839}
840
841#[derive(Debug, Clone, Copy, HashStable_Generic)]
844pub struct Generics<'hir> {
845 pub params: &'hir [GenericParam<'hir>],
846 pub predicates: &'hir [WherePredicate<'hir>],
847 pub has_where_clause_predicates: bool,
848 pub where_clause_span: Span,
849 pub span: Span,
850}
851
852impl<'hir> Generics<'hir> {
853 pub const fn empty() -> &'hir Generics<'hir> {
854 const NOPE: Generics<'_> = Generics {
855 params: &[],
856 predicates: &[],
857 has_where_clause_predicates: false,
858 where_clause_span: DUMMY_SP,
859 span: DUMMY_SP,
860 };
861 &NOPE
862 }
863
864 pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
865 self.params.iter().find(|¶m| name == param.name.ident().name)
866 }
867
868 pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
870 if let Some(first) = self.params.first()
871 && self.span.contains(first.span)
872 {
873 Some(first.span.shrink_to_lo())
876 } else {
877 None
878 }
879 }
880
881 pub fn span_for_param_suggestion(&self) -> Option<Span> {
883 self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
884 self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
887 })
888 }
889
890 pub fn tail_span_for_predicate_suggestion(&self) -> Span {
893 let end = self.where_clause_span.shrink_to_hi();
894 if self.has_where_clause_predicates {
895 self.predicates
896 .iter()
897 .rfind(|&p| p.kind.in_where_clause())
898 .map_or(end, |p| p.span)
899 .shrink_to_hi()
900 .to(end)
901 } else {
902 end
903 }
904 }
905
906 pub fn add_where_or_trailing_comma(&self) -> &'static str {
907 if self.has_where_clause_predicates {
908 ","
909 } else if self.where_clause_span.is_empty() {
910 " where"
911 } else {
912 ""
914 }
915 }
916
917 pub fn bounds_for_param(
918 &self,
919 param_def_id: LocalDefId,
920 ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
921 self.predicates.iter().filter_map(move |pred| match pred.kind {
922 WherePredicateKind::BoundPredicate(bp)
923 if bp.is_param_bound(param_def_id.to_def_id()) =>
924 {
925 Some(bp)
926 }
927 _ => None,
928 })
929 }
930
931 pub fn outlives_for_param(
932 &self,
933 param_def_id: LocalDefId,
934 ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
935 self.predicates.iter().filter_map(move |pred| match pred.kind {
936 WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
937 _ => None,
938 })
939 }
940
941 pub fn bounds_span_for_suggestions(
952 &self,
953 param_def_id: LocalDefId,
954 ) -> Option<(Span, Option<Span>)> {
955 self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
956 |bound| {
957 let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
958 && let [.., segment] = trait_ref.path.segments
959 && let Some(ret_ty) = segment.args().paren_sugar_output()
960 && let ret_ty = ret_ty.peel_refs()
961 && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
962 && let TraitObjectSyntax::Dyn = tagged_ptr.tag()
963 && ret_ty.span.can_be_used_for_suggestions()
964 {
965 Some(ret_ty.span)
966 } else {
967 None
968 };
969
970 span_for_parentheses.map_or_else(
971 || {
972 let bs = bound.span();
975 bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
976 },
977 |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
978 )
979 },
980 )
981 }
982
983 pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
984 let predicate = &self.predicates[pos];
985 let span = predicate.span;
986
987 if !predicate.kind.in_where_clause() {
988 return span;
991 }
992
993 if pos < self.predicates.len() - 1 {
995 let next_pred = &self.predicates[pos + 1];
996 if next_pred.kind.in_where_clause() {
997 return span.until(next_pred.span);
1000 }
1001 }
1002
1003 if pos > 0 {
1004 let prev_pred = &self.predicates[pos - 1];
1005 if prev_pred.kind.in_where_clause() {
1006 return prev_pred.span.shrink_to_hi().to(span);
1009 }
1010 }
1011
1012 self.where_clause_span
1016 }
1017
1018 pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
1019 let predicate = &self.predicates[predicate_pos];
1020 let bounds = predicate.kind.bounds();
1021
1022 if bounds.len() == 1 {
1023 return self.span_for_predicate_removal(predicate_pos);
1024 }
1025
1026 let bound_span = bounds[bound_pos].span();
1027 if bound_pos < bounds.len() - 1 {
1028 bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
1034 } else {
1035 bound_span.with_lo(bounds[bound_pos - 1].span().hi())
1041 }
1042 }
1043}
1044
1045#[derive(Debug, Clone, Copy, HashStable_Generic)]
1047pub struct WherePredicate<'hir> {
1048 #[stable_hasher(ignore)]
1049 pub hir_id: HirId,
1050 pub span: Span,
1051 pub kind: &'hir WherePredicateKind<'hir>,
1052}
1053
1054#[derive(Debug, Clone, Copy, HashStable_Generic)]
1056pub enum WherePredicateKind<'hir> {
1057 BoundPredicate(WhereBoundPredicate<'hir>),
1059 RegionPredicate(WhereRegionPredicate<'hir>),
1061 EqPredicate(WhereEqPredicate<'hir>),
1063}
1064
1065impl<'hir> WherePredicateKind<'hir> {
1066 pub fn in_where_clause(&self) -> bool {
1067 match self {
1068 WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
1069 WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
1070 WherePredicateKind::EqPredicate(_) => false,
1071 }
1072 }
1073
1074 pub fn bounds(&self) -> GenericBounds<'hir> {
1075 match self {
1076 WherePredicateKind::BoundPredicate(p) => p.bounds,
1077 WherePredicateKind::RegionPredicate(p) => p.bounds,
1078 WherePredicateKind::EqPredicate(_) => &[],
1079 }
1080 }
1081}
1082
1083#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
1084pub enum PredicateOrigin {
1085 WhereClause,
1086 GenericParam,
1087 ImplTrait,
1088}
1089
1090#[derive(Debug, Clone, Copy, HashStable_Generic)]
1092pub struct WhereBoundPredicate<'hir> {
1093 pub origin: PredicateOrigin,
1095 pub bound_generic_params: &'hir [GenericParam<'hir>],
1097 pub bounded_ty: &'hir Ty<'hir>,
1099 pub bounds: GenericBounds<'hir>,
1101}
1102
1103impl<'hir> WhereBoundPredicate<'hir> {
1104 pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
1106 self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
1107 }
1108}
1109
1110#[derive(Debug, Clone, Copy, HashStable_Generic)]
1112pub struct WhereRegionPredicate<'hir> {
1113 pub in_where_clause: bool,
1114 pub lifetime: &'hir Lifetime,
1115 pub bounds: GenericBounds<'hir>,
1116}
1117
1118impl<'hir> WhereRegionPredicate<'hir> {
1119 fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
1121 self.lifetime.kind == LifetimeKind::Param(param_def_id)
1122 }
1123}
1124
1125#[derive(Debug, Clone, Copy, HashStable_Generic)]
1127pub struct WhereEqPredicate<'hir> {
1128 pub lhs_ty: &'hir Ty<'hir>,
1129 pub rhs_ty: &'hir Ty<'hir>,
1130}
1131
1132#[derive(Clone, Copy, Debug)]
1136pub struct ParentedNode<'tcx> {
1137 pub parent: ItemLocalId,
1138 pub node: Node<'tcx>,
1139}
1140
1141#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1143pub enum AttrArgs {
1144 Empty,
1146 Delimited(DelimArgs),
1148 Eq {
1150 eq_span: Span,
1152 expr: MetaItemLit,
1154 },
1155}
1156
1157#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1158pub struct AttrPath {
1159 pub segments: Box<[Ident]>,
1160 pub span: Span,
1161}
1162
1163impl IntoDiagArg for AttrPath {
1164 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1165 self.to_string().into_diag_arg(path)
1166 }
1167}
1168
1169impl AttrPath {
1170 pub fn from_ast(path: &ast::Path) -> Self {
1171 AttrPath {
1172 segments: path.segments.iter().map(|i| i.ident).collect::<Vec<_>>().into_boxed_slice(),
1173 span: path.span,
1174 }
1175 }
1176}
1177
1178impl fmt::Display for AttrPath {
1179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1180 write!(f, "{}", join_path_idents(&self.segments))
1181 }
1182}
1183
1184#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1185pub struct AttrItem {
1186 pub path: AttrPath,
1188 pub args: AttrArgs,
1189 pub id: HashIgnoredAttrId,
1190 pub style: AttrStyle,
1193 pub span: Span,
1195}
1196
1197#[derive(Copy, Debug, Encodable, Decodable, Clone)]
1200pub struct HashIgnoredAttrId {
1201 pub attr_id: AttrId,
1202}
1203
1204#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
1205pub enum Attribute {
1206 Parsed(AttributeKind),
1212
1213 Unparsed(Box<AttrItem>),
1216}
1217
1218impl Attribute {
1219 pub fn get_normal_item(&self) -> &AttrItem {
1220 match &self {
1221 Attribute::Unparsed(normal) => &normal,
1222 _ => panic!("unexpected parsed attribute"),
1223 }
1224 }
1225
1226 pub fn unwrap_normal_item(self) -> AttrItem {
1227 match self {
1228 Attribute::Unparsed(normal) => *normal,
1229 _ => panic!("unexpected parsed attribute"),
1230 }
1231 }
1232
1233 pub fn value_lit(&self) -> Option<&MetaItemLit> {
1234 match &self {
1235 Attribute::Unparsed(n) => match n.as_ref() {
1236 AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1237 _ => None,
1238 },
1239 _ => None,
1240 }
1241 }
1242
1243 pub fn is_parsed_attr(&self) -> bool {
1244 match self {
1245 Attribute::Parsed(_) => true,
1246 Attribute::Unparsed(_) => false,
1247 }
1248 }
1249}
1250
1251impl AttributeExt for Attribute {
1252 #[inline]
1253 fn id(&self) -> AttrId {
1254 match &self {
1255 Attribute::Unparsed(u) => u.id.attr_id,
1256 _ => panic!(),
1257 }
1258 }
1259
1260 #[inline]
1261 fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1262 match &self {
1263 Attribute::Unparsed(n) => match n.as_ref() {
1264 AttrItem { args: AttrArgs::Delimited(d), .. } => {
1265 ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1266 }
1267 _ => None,
1268 },
1269 _ => None,
1270 }
1271 }
1272
1273 #[inline]
1274 fn value_str(&self) -> Option<Symbol> {
1275 self.value_lit().and_then(|x| x.value_str())
1276 }
1277
1278 #[inline]
1279 fn value_span(&self) -> Option<Span> {
1280 self.value_lit().map(|i| i.span)
1281 }
1282
1283 #[inline]
1285 fn ident(&self) -> Option<Ident> {
1286 match &self {
1287 Attribute::Unparsed(n) => {
1288 if let [ident] = n.path.segments.as_ref() {
1289 Some(*ident)
1290 } else {
1291 None
1292 }
1293 }
1294 _ => None,
1295 }
1296 }
1297
1298 #[inline]
1299 fn path_matches(&self, name: &[Symbol]) -> bool {
1300 match &self {
1301 Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name),
1302 _ => false,
1303 }
1304 }
1305
1306 #[inline]
1307 fn is_doc_comment(&self) -> Option<Span> {
1308 if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self {
1309 Some(*span)
1310 } else {
1311 None
1312 }
1313 }
1314
1315 #[inline]
1316 fn span(&self) -> Span {
1317 match &self {
1318 Attribute::Unparsed(u) => u.span,
1319 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1321 Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
1322 a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
1323 }
1324 }
1325
1326 #[inline]
1327 fn is_word(&self) -> bool {
1328 match &self {
1329 Attribute::Unparsed(n) => {
1330 matches!(n.args, AttrArgs::Empty)
1331 }
1332 _ => false,
1333 }
1334 }
1335
1336 #[inline]
1337 fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1338 match &self {
1339 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
1340 _ => None,
1341 }
1342 }
1343
1344 #[inline]
1345 fn doc_str(&self) -> Option<Symbol> {
1346 match &self {
1347 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
1348 Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(),
1349 _ => None,
1350 }
1351 }
1352
1353 fn is_automatically_derived_attr(&self) -> bool {
1354 matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
1355 }
1356
1357 #[inline]
1358 fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1359 match &self {
1360 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
1361 Some((*comment, *kind))
1362 }
1363 Attribute::Unparsed(_) if self.has_name(sym::doc) => {
1364 self.value_str().map(|s| (s, CommentKind::Line))
1365 }
1366 _ => None,
1367 }
1368 }
1369
1370 fn doc_resolution_scope(&self) -> Option<AttrStyle> {
1371 match self {
1372 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
1373 Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
1374 Some(attr.style)
1375 }
1376 _ => None,
1377 }
1378 }
1379
1380 fn is_proc_macro_attr(&self) -> bool {
1381 matches!(
1382 self,
1383 Attribute::Parsed(
1384 AttributeKind::ProcMacro(..)
1385 | AttributeKind::ProcMacroAttribute(..)
1386 | AttributeKind::ProcMacroDerive { .. }
1387 )
1388 )
1389 }
1390}
1391
1392impl Attribute {
1394 #[inline]
1395 pub fn id(&self) -> AttrId {
1396 AttributeExt::id(self)
1397 }
1398
1399 #[inline]
1400 pub fn name(&self) -> Option<Symbol> {
1401 AttributeExt::name(self)
1402 }
1403
1404 #[inline]
1405 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1406 AttributeExt::meta_item_list(self)
1407 }
1408
1409 #[inline]
1410 pub fn value_str(&self) -> Option<Symbol> {
1411 AttributeExt::value_str(self)
1412 }
1413
1414 #[inline]
1415 pub fn value_span(&self) -> Option<Span> {
1416 AttributeExt::value_span(self)
1417 }
1418
1419 #[inline]
1420 pub fn ident(&self) -> Option<Ident> {
1421 AttributeExt::ident(self)
1422 }
1423
1424 #[inline]
1425 pub fn path_matches(&self, name: &[Symbol]) -> bool {
1426 AttributeExt::path_matches(self, name)
1427 }
1428
1429 #[inline]
1430 pub fn is_doc_comment(&self) -> Option<Span> {
1431 AttributeExt::is_doc_comment(self)
1432 }
1433
1434 #[inline]
1435 pub fn has_name(&self, name: Symbol) -> bool {
1436 AttributeExt::has_name(self, name)
1437 }
1438
1439 #[inline]
1440 pub fn has_any_name(&self, names: &[Symbol]) -> bool {
1441 AttributeExt::has_any_name(self, names)
1442 }
1443
1444 #[inline]
1445 pub fn span(&self) -> Span {
1446 AttributeExt::span(self)
1447 }
1448
1449 #[inline]
1450 pub fn is_word(&self) -> bool {
1451 AttributeExt::is_word(self)
1452 }
1453
1454 #[inline]
1455 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1456 AttributeExt::path(self)
1457 }
1458
1459 #[inline]
1460 pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1461 AttributeExt::ident_path(self)
1462 }
1463
1464 #[inline]
1465 pub fn doc_str(&self) -> Option<Symbol> {
1466 AttributeExt::doc_str(self)
1467 }
1468
1469 #[inline]
1470 pub fn is_proc_macro_attr(&self) -> bool {
1471 AttributeExt::is_proc_macro_attr(self)
1472 }
1473
1474 #[inline]
1475 pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1476 AttributeExt::doc_str_and_comment_kind(self)
1477 }
1478}
1479
1480#[derive(Debug)]
1482pub struct AttributeMap<'tcx> {
1483 pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1484 pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
1486 pub opt_hash: Option<Fingerprint>,
1488}
1489
1490impl<'tcx> AttributeMap<'tcx> {
1491 pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1492 map: SortedMap::new(),
1493 opt_hash: Some(Fingerprint::ZERO),
1494 define_opaque: None,
1495 };
1496
1497 #[inline]
1498 pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1499 self.map.get(&id).copied().unwrap_or(&[])
1500 }
1501}
1502
1503pub struct OwnerNodes<'tcx> {
1507 pub opt_hash_including_bodies: Option<Fingerprint>,
1510 pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1515 pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1517}
1518
1519impl<'tcx> OwnerNodes<'tcx> {
1520 pub fn node(&self) -> OwnerNode<'tcx> {
1521 self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1523 }
1524}
1525
1526impl fmt::Debug for OwnerNodes<'_> {
1527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1528 f.debug_struct("OwnerNodes")
1529 .field("node", &self.nodes[ItemLocalId::ZERO])
1531 .field(
1532 "parents",
1533 &fmt::from_fn(|f| {
1534 f.debug_list()
1535 .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1536 fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1537 }))
1538 .finish()
1539 }),
1540 )
1541 .field("bodies", &self.bodies)
1542 .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1543 .finish()
1544 }
1545}
1546
1547#[derive(Debug, HashStable_Generic)]
1549pub struct OwnerInfo<'hir> {
1550 pub nodes: OwnerNodes<'hir>,
1552 pub parenting: LocalDefIdMap<ItemLocalId>,
1554 pub attrs: AttributeMap<'hir>,
1556 pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1559
1560 pub delayed_lints: DelayedLints,
1563}
1564
1565impl<'tcx> OwnerInfo<'tcx> {
1566 #[inline]
1567 pub fn node(&self) -> OwnerNode<'tcx> {
1568 self.nodes.node()
1569 }
1570}
1571
1572#[derive(Copy, Clone, Debug, HashStable_Generic)]
1573pub enum MaybeOwner<'tcx> {
1574 Owner(&'tcx OwnerInfo<'tcx>),
1575 NonOwner(HirId),
1576 Phantom,
1578}
1579
1580impl<'tcx> MaybeOwner<'tcx> {
1581 pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1582 match self {
1583 MaybeOwner::Owner(i) => Some(i),
1584 MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1585 }
1586 }
1587
1588 pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1589 self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1590 }
1591}
1592
1593#[derive(Debug)]
1600pub struct Crate<'hir> {
1601 pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1602 pub opt_hir_hash: Option<Fingerprint>,
1604}
1605
1606#[derive(Debug, Clone, Copy, HashStable_Generic)]
1607pub struct Closure<'hir> {
1608 pub def_id: LocalDefId,
1609 pub binder: ClosureBinder,
1610 pub constness: Constness,
1611 pub capture_clause: CaptureBy,
1612 pub bound_generic_params: &'hir [GenericParam<'hir>],
1613 pub fn_decl: &'hir FnDecl<'hir>,
1614 pub body: BodyId,
1615 pub fn_decl_span: Span,
1617 pub fn_arg_span: Option<Span>,
1619 pub kind: ClosureKind,
1620}
1621
1622#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1623pub enum ClosureKind {
1624 Closure,
1626 Coroutine(CoroutineKind),
1631 CoroutineClosure(CoroutineDesugaring),
1636}
1637
1638#[derive(Debug, Clone, Copy, HashStable_Generic)]
1642pub struct Block<'hir> {
1643 pub stmts: &'hir [Stmt<'hir>],
1645 pub expr: Option<&'hir Expr<'hir>>,
1648 #[stable_hasher(ignore)]
1649 pub hir_id: HirId,
1650 pub rules: BlockCheckMode,
1652 pub span: Span,
1654 pub targeted_by_break: bool,
1658}
1659
1660impl<'hir> Block<'hir> {
1661 pub fn innermost_block(&self) -> &Block<'hir> {
1662 let mut block = self;
1663 while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1664 block = inner_block;
1665 }
1666 block
1667 }
1668}
1669
1670#[derive(Debug, Clone, Copy, HashStable_Generic)]
1671pub struct TyPat<'hir> {
1672 #[stable_hasher(ignore)]
1673 pub hir_id: HirId,
1674 pub kind: TyPatKind<'hir>,
1675 pub span: Span,
1676}
1677
1678#[derive(Debug, Clone, Copy, HashStable_Generic)]
1679pub struct Pat<'hir> {
1680 #[stable_hasher(ignore)]
1681 pub hir_id: HirId,
1682 pub kind: PatKind<'hir>,
1683 pub span: Span,
1684 pub default_binding_modes: bool,
1687}
1688
1689impl<'hir> Pat<'hir> {
1690 fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1691 if !it(self) {
1692 return false;
1693 }
1694
1695 use PatKind::*;
1696 match self.kind {
1697 Missing => unreachable!(),
1698 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1699 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
1700 Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1701 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1702 Slice(before, slice, after) => {
1703 before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1704 }
1705 }
1706 }
1707
1708 pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1715 self.walk_short_(&mut it)
1716 }
1717
1718 fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1719 if !it(self) {
1720 return;
1721 }
1722
1723 use PatKind::*;
1724 match self.kind {
1725 Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1726 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1727 Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1728 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1729 Slice(before, slice, after) => {
1730 before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1731 }
1732 }
1733 }
1734
1735 pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1739 self.walk_(&mut it)
1740 }
1741
1742 pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1746 self.walk(|p| {
1747 it(p);
1748 true
1749 })
1750 }
1751
1752 pub fn is_never_pattern(&self) -> bool {
1754 let mut is_never_pattern = false;
1755 self.walk(|pat| match &pat.kind {
1756 PatKind::Never => {
1757 is_never_pattern = true;
1758 false
1759 }
1760 PatKind::Or(s) => {
1761 is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1762 false
1763 }
1764 _ => true,
1765 });
1766 is_never_pattern
1767 }
1768}
1769
1770#[derive(Debug, Clone, Copy, HashStable_Generic)]
1776pub struct PatField<'hir> {
1777 #[stable_hasher(ignore)]
1778 pub hir_id: HirId,
1779 pub ident: Ident,
1781 pub pat: &'hir Pat<'hir>,
1783 pub is_shorthand: bool,
1784 pub span: Span,
1785}
1786
1787#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
1788pub enum RangeEnd {
1789 Included,
1790 Excluded,
1791}
1792
1793impl fmt::Display for RangeEnd {
1794 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1795 f.write_str(match self {
1796 RangeEnd::Included => "..=",
1797 RangeEnd::Excluded => "..",
1798 })
1799 }
1800}
1801
1802#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1806pub struct DotDotPos(u32);
1807
1808impl DotDotPos {
1809 pub fn new(n: Option<usize>) -> Self {
1811 match n {
1812 Some(n) => {
1813 assert!(n < u32::MAX as usize);
1814 Self(n as u32)
1815 }
1816 None => Self(u32::MAX),
1817 }
1818 }
1819
1820 pub fn as_opt_usize(&self) -> Option<usize> {
1821 if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1822 }
1823}
1824
1825impl fmt::Debug for DotDotPos {
1826 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1827 self.as_opt_usize().fmt(f)
1828 }
1829}
1830
1831#[derive(Debug, Clone, Copy, HashStable_Generic)]
1832pub struct PatExpr<'hir> {
1833 #[stable_hasher(ignore)]
1834 pub hir_id: HirId,
1835 pub span: Span,
1836 pub kind: PatExprKind<'hir>,
1837}
1838
1839#[derive(Debug, Clone, Copy, HashStable_Generic)]
1840pub enum PatExprKind<'hir> {
1841 Lit {
1842 lit: Lit,
1843 negated: bool,
1846 },
1847 ConstBlock(ConstBlock),
1848 Path(QPath<'hir>),
1850}
1851
1852#[derive(Debug, Clone, Copy, HashStable_Generic)]
1853pub enum TyPatKind<'hir> {
1854 Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
1856
1857 NotNull,
1859
1860 Or(&'hir [TyPat<'hir>]),
1862
1863 Err(ErrorGuaranteed),
1865}
1866
1867#[derive(Debug, Clone, Copy, HashStable_Generic)]
1868pub enum PatKind<'hir> {
1869 Missing,
1871
1872 Wild,
1874
1875 Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1886
1887 Struct(QPath<'hir>, &'hir [PatField<'hir>], Option<Span>),
1890
1891 TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1895
1896 Or(&'hir [Pat<'hir>]),
1899
1900 Never,
1902
1903 Tuple(&'hir [Pat<'hir>], DotDotPos),
1907
1908 Box(&'hir Pat<'hir>),
1910
1911 Deref(&'hir Pat<'hir>),
1913
1914 Ref(&'hir Pat<'hir>, Mutability),
1916
1917 Expr(&'hir PatExpr<'hir>),
1919
1920 Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1922
1923 Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
1925
1926 Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
1936
1937 Err(ErrorGuaranteed),
1939}
1940
1941#[derive(Debug, Clone, Copy, HashStable_Generic)]
1943pub struct Stmt<'hir> {
1944 #[stable_hasher(ignore)]
1945 pub hir_id: HirId,
1946 pub kind: StmtKind<'hir>,
1947 pub span: Span,
1948}
1949
1950#[derive(Debug, Clone, Copy, HashStable_Generic)]
1952pub enum StmtKind<'hir> {
1953 Let(&'hir LetStmt<'hir>),
1955
1956 Item(ItemId),
1958
1959 Expr(&'hir Expr<'hir>),
1961
1962 Semi(&'hir Expr<'hir>),
1964}
1965
1966#[derive(Debug, Clone, Copy, HashStable_Generic)]
1968pub struct LetStmt<'hir> {
1969 pub super_: Option<Span>,
1971 pub pat: &'hir Pat<'hir>,
1972 pub ty: Option<&'hir Ty<'hir>>,
1974 pub init: Option<&'hir Expr<'hir>>,
1976 pub els: Option<&'hir Block<'hir>>,
1978 #[stable_hasher(ignore)]
1979 pub hir_id: HirId,
1980 pub span: Span,
1981 pub source: LocalSource,
1985}
1986
1987#[derive(Debug, Clone, Copy, HashStable_Generic)]
1990pub struct Arm<'hir> {
1991 #[stable_hasher(ignore)]
1992 pub hir_id: HirId,
1993 pub span: Span,
1994 pub pat: &'hir Pat<'hir>,
1996 pub guard: Option<&'hir Expr<'hir>>,
1998 pub body: &'hir Expr<'hir>,
2000}
2001
2002#[derive(Debug, Clone, Copy, HashStable_Generic)]
2008pub struct LetExpr<'hir> {
2009 pub span: Span,
2010 pub pat: &'hir Pat<'hir>,
2011 pub ty: Option<&'hir Ty<'hir>>,
2012 pub init: &'hir Expr<'hir>,
2013 pub recovered: ast::Recovered,
2016}
2017
2018#[derive(Debug, Clone, Copy, HashStable_Generic)]
2019pub struct ExprField<'hir> {
2020 #[stable_hasher(ignore)]
2021 pub hir_id: HirId,
2022 pub ident: Ident,
2023 pub expr: &'hir Expr<'hir>,
2024 pub span: Span,
2025 pub is_shorthand: bool,
2026}
2027
2028#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2029pub enum BlockCheckMode {
2030 DefaultBlock,
2031 UnsafeBlock(UnsafeSource),
2032}
2033
2034#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2035pub enum UnsafeSource {
2036 CompilerGenerated,
2037 UserProvided,
2038}
2039
2040#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
2041pub struct BodyId {
2042 pub hir_id: HirId,
2043}
2044
2045#[derive(Debug, Clone, Copy, HashStable_Generic)]
2067pub struct Body<'hir> {
2068 pub params: &'hir [Param<'hir>],
2069 pub value: &'hir Expr<'hir>,
2070}
2071
2072impl<'hir> Body<'hir> {
2073 pub fn id(&self) -> BodyId {
2074 BodyId { hir_id: self.value.hir_id }
2075 }
2076}
2077
2078#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2080pub enum CoroutineKind {
2081 Desugared(CoroutineDesugaring, CoroutineSource),
2083
2084 Coroutine(Movability),
2086}
2087
2088impl CoroutineKind {
2089 pub fn movability(self) -> Movability {
2090 match self {
2091 CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
2092 | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
2093 CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
2094 CoroutineKind::Coroutine(mov) => mov,
2095 }
2096 }
2097
2098 pub fn is_fn_like(self) -> bool {
2099 matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
2100 }
2101
2102 pub fn to_plural_string(&self) -> String {
2103 match self {
2104 CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"),
2105 CoroutineKind::Desugared(d, CoroutineSource::Block) => format!("{d:#}blocks"),
2106 CoroutineKind::Desugared(d, CoroutineSource::Closure) => format!("{d:#}closure bodies"),
2107 CoroutineKind::Coroutine(_) => "coroutines".to_string(),
2108 }
2109 }
2110}
2111
2112impl fmt::Display for CoroutineKind {
2113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2114 match self {
2115 CoroutineKind::Desugared(d, k) => {
2116 d.fmt(f)?;
2117 k.fmt(f)
2118 }
2119 CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
2120 }
2121 }
2122}
2123
2124#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
2130pub enum CoroutineSource {
2131 Block,
2133
2134 Closure,
2136
2137 Fn,
2139}
2140
2141impl fmt::Display for CoroutineSource {
2142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2143 match self {
2144 CoroutineSource::Block => "block",
2145 CoroutineSource::Closure => "closure body",
2146 CoroutineSource::Fn => "fn body",
2147 }
2148 .fmt(f)
2149 }
2150}
2151
2152#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2153pub enum CoroutineDesugaring {
2154 Async,
2156
2157 Gen,
2159
2160 AsyncGen,
2163}
2164
2165impl fmt::Display for CoroutineDesugaring {
2166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2167 match self {
2168 CoroutineDesugaring::Async => {
2169 if f.alternate() {
2170 f.write_str("`async` ")?;
2171 } else {
2172 f.write_str("async ")?
2173 }
2174 }
2175 CoroutineDesugaring::Gen => {
2176 if f.alternate() {
2177 f.write_str("`gen` ")?;
2178 } else {
2179 f.write_str("gen ")?
2180 }
2181 }
2182 CoroutineDesugaring::AsyncGen => {
2183 if f.alternate() {
2184 f.write_str("`async gen` ")?;
2185 } else {
2186 f.write_str("async gen ")?
2187 }
2188 }
2189 }
2190
2191 Ok(())
2192 }
2193}
2194
2195#[derive(Copy, Clone, Debug)]
2196pub enum BodyOwnerKind {
2197 Fn,
2199
2200 Closure,
2202
2203 Const { inline: bool },
2205
2206 Static(Mutability),
2208
2209 GlobalAsm,
2211}
2212
2213impl BodyOwnerKind {
2214 pub fn is_fn_or_closure(self) -> bool {
2215 match self {
2216 BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
2217 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
2218 false
2219 }
2220 }
2221 }
2222}
2223
2224#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2226pub enum ConstContext {
2227 ConstFn,
2229
2230 Static(Mutability),
2232
2233 Const { inline: bool },
2243}
2244
2245impl ConstContext {
2246 pub fn keyword_name(self) -> &'static str {
2250 match self {
2251 Self::Const { .. } => "const",
2252 Self::Static(Mutability::Not) => "static",
2253 Self::Static(Mutability::Mut) => "static mut",
2254 Self::ConstFn => "const fn",
2255 }
2256 }
2257}
2258
2259impl fmt::Display for ConstContext {
2262 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2263 match *self {
2264 Self::Const { .. } => write!(f, "constant"),
2265 Self::Static(_) => write!(f, "static"),
2266 Self::ConstFn => write!(f, "constant function"),
2267 }
2268 }
2269}
2270
2271impl IntoDiagArg for ConstContext {
2272 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
2273 DiagArgValue::Str(Cow::Borrowed(match self {
2274 ConstContext::ConstFn => "const_fn",
2275 ConstContext::Static(_) => "static",
2276 ConstContext::Const { .. } => "const",
2277 }))
2278 }
2279}
2280
2281pub type Lit = Spanned<LitKind>;
2283
2284#[derive(Copy, Clone, Debug, HashStable_Generic)]
2293pub struct AnonConst {
2294 #[stable_hasher(ignore)]
2295 pub hir_id: HirId,
2296 pub def_id: LocalDefId,
2297 pub body: BodyId,
2298 pub span: Span,
2299}
2300
2301#[derive(Copy, Clone, Debug, HashStable_Generic)]
2303pub struct ConstBlock {
2304 #[stable_hasher(ignore)]
2305 pub hir_id: HirId,
2306 pub def_id: LocalDefId,
2307 pub body: BodyId,
2308}
2309
2310#[derive(Debug, Clone, Copy, HashStable_Generic)]
2319pub struct Expr<'hir> {
2320 #[stable_hasher(ignore)]
2321 pub hir_id: HirId,
2322 pub kind: ExprKind<'hir>,
2323 pub span: Span,
2324}
2325
2326impl Expr<'_> {
2327 pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence {
2328 let prefix_attrs_precedence = || -> ExprPrecedence {
2329 if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
2330 };
2331
2332 match &self.kind {
2333 ExprKind::Closure(closure) => {
2334 match closure.fn_decl.output {
2335 FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2336 FnRetTy::Return(_) => prefix_attrs_precedence(),
2337 }
2338 }
2339
2340 ExprKind::Break(..)
2341 | ExprKind::Ret(..)
2342 | ExprKind::Yield(..)
2343 | ExprKind::Become(..) => ExprPrecedence::Jump,
2344
2345 ExprKind::Binary(op, ..) => op.node.precedence(),
2347 ExprKind::Cast(..) => ExprPrecedence::Cast,
2348
2349 ExprKind::Assign(..) |
2350 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2351
2352 ExprKind::AddrOf(..)
2354 | ExprKind::Let(..)
2359 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2360
2361 ExprKind::Array(_)
2363 | ExprKind::Block(..)
2364 | ExprKind::Call(..)
2365 | ExprKind::ConstBlock(_)
2366 | ExprKind::Continue(..)
2367 | ExprKind::Field(..)
2368 | ExprKind::If(..)
2369 | ExprKind::Index(..)
2370 | ExprKind::InlineAsm(..)
2371 | ExprKind::Lit(_)
2372 | ExprKind::Loop(..)
2373 | ExprKind::Match(..)
2374 | ExprKind::MethodCall(..)
2375 | ExprKind::OffsetOf(..)
2376 | ExprKind::Path(..)
2377 | ExprKind::Repeat(..)
2378 | ExprKind::Struct(..)
2379 | ExprKind::Tup(_)
2380 | ExprKind::Type(..)
2381 | ExprKind::UnsafeBinderCast(..)
2382 | ExprKind::Use(..)
2383 | ExprKind::Err(_) => prefix_attrs_precedence(),
2384
2385 ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr),
2386 }
2387 }
2388
2389 pub fn is_syntactic_place_expr(&self) -> bool {
2394 self.is_place_expr(|_| true)
2395 }
2396
2397 pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2402 match self.kind {
2403 ExprKind::Path(QPath::Resolved(_, ref path)) => {
2404 matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2405 }
2406
2407 ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2411
2412 ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2414
2415 ExprKind::Unary(UnOp::Deref, _) => true,
2416
2417 ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2418 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2419 }
2420
2421 ExprKind::Path(QPath::LangItem(..)) => false,
2423
2424 ExprKind::Err(_guar)
2426 | ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
2427
2428 ExprKind::Path(QPath::TypeRelative(..))
2431 | ExprKind::Call(..)
2432 | ExprKind::MethodCall(..)
2433 | ExprKind::Use(..)
2434 | ExprKind::Struct(..)
2435 | ExprKind::Tup(..)
2436 | ExprKind::If(..)
2437 | ExprKind::Match(..)
2438 | ExprKind::Closure { .. }
2439 | ExprKind::Block(..)
2440 | ExprKind::Repeat(..)
2441 | ExprKind::Array(..)
2442 | ExprKind::Break(..)
2443 | ExprKind::Continue(..)
2444 | ExprKind::Ret(..)
2445 | ExprKind::Become(..)
2446 | ExprKind::Let(..)
2447 | ExprKind::Loop(..)
2448 | ExprKind::Assign(..)
2449 | ExprKind::InlineAsm(..)
2450 | ExprKind::OffsetOf(..)
2451 | ExprKind::AssignOp(..)
2452 | ExprKind::Lit(_)
2453 | ExprKind::ConstBlock(..)
2454 | ExprKind::Unary(..)
2455 | ExprKind::AddrOf(..)
2456 | ExprKind::Binary(..)
2457 | ExprKind::Yield(..)
2458 | ExprKind::Cast(..)
2459 | ExprKind::DropTemps(..) => false,
2460 }
2461 }
2462
2463 pub fn is_size_lit(&self) -> bool {
2466 matches!(
2467 self.kind,
2468 ExprKind::Lit(Lit {
2469 node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2470 ..
2471 })
2472 )
2473 }
2474
2475 pub fn peel_drop_temps(&self) -> &Self {
2481 let mut expr = self;
2482 while let ExprKind::DropTemps(inner) = &expr.kind {
2483 expr = inner;
2484 }
2485 expr
2486 }
2487
2488 pub fn peel_blocks(&self) -> &Self {
2489 let mut expr = self;
2490 while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2491 expr = inner;
2492 }
2493 expr
2494 }
2495
2496 pub fn peel_borrows(&self) -> &Self {
2497 let mut expr = self;
2498 while let ExprKind::AddrOf(.., inner) = &expr.kind {
2499 expr = inner;
2500 }
2501 expr
2502 }
2503
2504 pub fn can_have_side_effects(&self) -> bool {
2505 match self.peel_drop_temps().kind {
2506 ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2507 false
2508 }
2509 ExprKind::Type(base, _)
2510 | ExprKind::Unary(_, base)
2511 | ExprKind::Field(base, _)
2512 | ExprKind::Index(base, _, _)
2513 | ExprKind::AddrOf(.., base)
2514 | ExprKind::Cast(base, _)
2515 | ExprKind::UnsafeBinderCast(_, base, _) => {
2516 base.can_have_side_effects()
2520 }
2521 ExprKind::Struct(_, fields, init) => {
2522 let init_side_effects = match init {
2523 StructTailExpr::Base(init) => init.can_have_side_effects(),
2524 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2525 };
2526 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2527 || init_side_effects
2528 }
2529
2530 ExprKind::Array(args)
2531 | ExprKind::Tup(args)
2532 | ExprKind::Call(
2533 Expr {
2534 kind:
2535 ExprKind::Path(QPath::Resolved(
2536 None,
2537 Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2538 )),
2539 ..
2540 },
2541 args,
2542 ) => args.iter().any(|arg| arg.can_have_side_effects()),
2543 ExprKind::If(..)
2544 | ExprKind::Match(..)
2545 | ExprKind::MethodCall(..)
2546 | ExprKind::Call(..)
2547 | ExprKind::Closure { .. }
2548 | ExprKind::Block(..)
2549 | ExprKind::Repeat(..)
2550 | ExprKind::Break(..)
2551 | ExprKind::Continue(..)
2552 | ExprKind::Ret(..)
2553 | ExprKind::Become(..)
2554 | ExprKind::Let(..)
2555 | ExprKind::Loop(..)
2556 | ExprKind::Assign(..)
2557 | ExprKind::InlineAsm(..)
2558 | ExprKind::AssignOp(..)
2559 | ExprKind::ConstBlock(..)
2560 | ExprKind::Binary(..)
2561 | ExprKind::Yield(..)
2562 | ExprKind::DropTemps(..)
2563 | ExprKind::Err(_) => true,
2564 }
2565 }
2566
2567 pub fn is_approximately_pattern(&self) -> bool {
2569 match &self.kind {
2570 ExprKind::Array(_)
2571 | ExprKind::Call(..)
2572 | ExprKind::Tup(_)
2573 | ExprKind::Lit(_)
2574 | ExprKind::Path(_)
2575 | ExprKind::Struct(..) => true,
2576 _ => false,
2577 }
2578 }
2579
2580 pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2585 match (self.kind, other.kind) {
2586 (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2587 (
2588 ExprKind::Path(QPath::LangItem(item1, _)),
2589 ExprKind::Path(QPath::LangItem(item2, _)),
2590 ) => item1 == item2,
2591 (
2592 ExprKind::Path(QPath::Resolved(None, path1)),
2593 ExprKind::Path(QPath::Resolved(None, path2)),
2594 ) => path1.res == path2.res,
2595 (
2596 ExprKind::Struct(
2597 QPath::LangItem(LangItem::RangeTo, _),
2598 [val1],
2599 StructTailExpr::None,
2600 ),
2601 ExprKind::Struct(
2602 QPath::LangItem(LangItem::RangeTo, _),
2603 [val2],
2604 StructTailExpr::None,
2605 ),
2606 )
2607 | (
2608 ExprKind::Struct(
2609 QPath::LangItem(LangItem::RangeToInclusive, _),
2610 [val1],
2611 StructTailExpr::None,
2612 ),
2613 ExprKind::Struct(
2614 QPath::LangItem(LangItem::RangeToInclusive, _),
2615 [val2],
2616 StructTailExpr::None,
2617 ),
2618 )
2619 | (
2620 ExprKind::Struct(
2621 QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2622 [val1],
2623 StructTailExpr::None,
2624 ),
2625 ExprKind::Struct(
2626 QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2627 [val2],
2628 StructTailExpr::None,
2629 ),
2630 )
2631 | (
2632 ExprKind::Struct(
2633 QPath::LangItem(LangItem::RangeFrom, _),
2634 [val1],
2635 StructTailExpr::None,
2636 ),
2637 ExprKind::Struct(
2638 QPath::LangItem(LangItem::RangeFrom, _),
2639 [val2],
2640 StructTailExpr::None,
2641 ),
2642 )
2643 | (
2644 ExprKind::Struct(
2645 QPath::LangItem(LangItem::RangeFromCopy, _),
2646 [val1],
2647 StructTailExpr::None,
2648 ),
2649 ExprKind::Struct(
2650 QPath::LangItem(LangItem::RangeFromCopy, _),
2651 [val2],
2652 StructTailExpr::None,
2653 ),
2654 ) => val1.expr.equivalent_for_indexing(val2.expr),
2655 (
2656 ExprKind::Struct(
2657 QPath::LangItem(LangItem::Range, _),
2658 [val1, val3],
2659 StructTailExpr::None,
2660 ),
2661 ExprKind::Struct(
2662 QPath::LangItem(LangItem::Range, _),
2663 [val2, val4],
2664 StructTailExpr::None,
2665 ),
2666 )
2667 | (
2668 ExprKind::Struct(
2669 QPath::LangItem(LangItem::RangeCopy, _),
2670 [val1, val3],
2671 StructTailExpr::None,
2672 ),
2673 ExprKind::Struct(
2674 QPath::LangItem(LangItem::RangeCopy, _),
2675 [val2, val4],
2676 StructTailExpr::None,
2677 ),
2678 )
2679 | (
2680 ExprKind::Struct(
2681 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2682 [val1, val3],
2683 StructTailExpr::None,
2684 ),
2685 ExprKind::Struct(
2686 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2687 [val2, val4],
2688 StructTailExpr::None,
2689 ),
2690 ) => {
2691 val1.expr.equivalent_for_indexing(val2.expr)
2692 && val3.expr.equivalent_for_indexing(val4.expr)
2693 }
2694 _ => false,
2695 }
2696 }
2697
2698 pub fn method_ident(&self) -> Option<Ident> {
2699 match self.kind {
2700 ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2701 ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2702 _ => None,
2703 }
2704 }
2705}
2706
2707pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2710 match expr.kind {
2711 ExprKind::Struct(ref qpath, _, _) => matches!(
2713 **qpath,
2714 QPath::LangItem(
2715 LangItem::Range
2716 | LangItem::RangeTo
2717 | LangItem::RangeFrom
2718 | LangItem::RangeFull
2719 | LangItem::RangeToInclusive
2720 | LangItem::RangeCopy
2721 | LangItem::RangeFromCopy
2722 | LangItem::RangeInclusiveCopy
2723 | LangItem::RangeToInclusiveCopy,
2724 ..
2725 )
2726 ),
2727
2728 ExprKind::Call(ref func, _) => {
2730 matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2731 }
2732
2733 _ => false,
2734 }
2735}
2736
2737pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2744 match expr.kind {
2745 ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2747 _ if is_range_literal(expr) => true,
2749 _ => false,
2750 }
2751}
2752
2753#[derive(Debug, Clone, Copy, HashStable_Generic)]
2754pub enum ExprKind<'hir> {
2755 ConstBlock(ConstBlock),
2757 Array(&'hir [Expr<'hir>]),
2759 Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2766 MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2783 Use(&'hir Expr<'hir>, Span),
2785 Tup(&'hir [Expr<'hir>]),
2787 Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2789 Unary(UnOp, &'hir Expr<'hir>),
2791 Lit(Lit),
2793 Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2795 Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2797 DropTemps(&'hir Expr<'hir>),
2803 Let(&'hir LetExpr<'hir>),
2808 If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2817 Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2823 Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2826 Closure(&'hir Closure<'hir>),
2833 Block(&'hir Block<'hir>, Option<Label>),
2835
2836 Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2838 AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2842 Field(&'hir Expr<'hir>, Ident),
2844 Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2848
2849 Path(QPath<'hir>),
2851
2852 AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2854 Break(Destination, Option<&'hir Expr<'hir>>),
2856 Continue(Destination),
2858 Ret(Option<&'hir Expr<'hir>>),
2860 Become(&'hir Expr<'hir>),
2862
2863 InlineAsm(&'hir InlineAsm<'hir>),
2865
2866 OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2868
2869 Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2874
2875 Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2880
2881 Yield(&'hir Expr<'hir>, YieldSource),
2883
2884 UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2887
2888 Err(rustc_span::ErrorGuaranteed),
2890}
2891
2892#[derive(Debug, Clone, Copy, HashStable_Generic)]
2893pub enum StructTailExpr<'hir> {
2894 None,
2896 Base(&'hir Expr<'hir>),
2899 DefaultFields(Span),
2903}
2904
2905#[derive(Debug, Clone, Copy, HashStable_Generic)]
2911pub enum QPath<'hir> {
2912 Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2919
2920 TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2927
2928 LangItem(LangItem, Span),
2930}
2931
2932impl<'hir> QPath<'hir> {
2933 pub fn span(&self) -> Span {
2935 match *self {
2936 QPath::Resolved(_, path) => path.span,
2937 QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2938 QPath::LangItem(_, span) => span,
2939 }
2940 }
2941
2942 pub fn qself_span(&self) -> Span {
2945 match *self {
2946 QPath::Resolved(_, path) => path.span,
2947 QPath::TypeRelative(qself, _) => qself.span,
2948 QPath::LangItem(_, span) => span,
2949 }
2950 }
2951}
2952
2953#[derive(Copy, Clone, Debug, HashStable_Generic)]
2955pub enum LocalSource {
2956 Normal,
2958 AsyncFn,
2969 AwaitDesugar,
2971 AssignDesugar(Span),
2974 Contract,
2976}
2977
2978#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2980pub enum MatchSource {
2981 Normal,
2983 Postfix,
2985 ForLoopDesugar,
2987 TryDesugar(HirId),
2989 AwaitDesugar,
2991 FormatArgs,
2993}
2994
2995impl MatchSource {
2996 #[inline]
2997 pub const fn name(self) -> &'static str {
2998 use MatchSource::*;
2999 match self {
3000 Normal => "match",
3001 Postfix => ".match",
3002 ForLoopDesugar => "for",
3003 TryDesugar(_) => "?",
3004 AwaitDesugar => ".await",
3005 FormatArgs => "format_args!()",
3006 }
3007 }
3008}
3009
3010#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3012pub enum LoopSource {
3013 Loop,
3015 While,
3017 ForLoop,
3019}
3020
3021impl LoopSource {
3022 pub fn name(self) -> &'static str {
3023 match self {
3024 LoopSource::Loop => "loop",
3025 LoopSource::While => "while",
3026 LoopSource::ForLoop => "for",
3027 }
3028 }
3029}
3030
3031#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3032pub enum LoopIdError {
3033 OutsideLoopScope,
3034 UnlabeledCfInWhileCondition,
3035 UnresolvedLabel,
3036}
3037
3038impl fmt::Display for LoopIdError {
3039 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3040 f.write_str(match self {
3041 LoopIdError::OutsideLoopScope => "not inside loop scope",
3042 LoopIdError::UnlabeledCfInWhileCondition => {
3043 "unlabeled control flow (break or continue) in while condition"
3044 }
3045 LoopIdError::UnresolvedLabel => "label not found",
3046 })
3047 }
3048}
3049
3050#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3051pub struct Destination {
3052 pub label: Option<Label>,
3054
3055 pub target_id: Result<HirId, LoopIdError>,
3058}
3059
3060#[derive(Copy, Clone, Debug, HashStable_Generic)]
3062pub enum YieldSource {
3063 Await { expr: Option<HirId> },
3065 Yield,
3067}
3068
3069impl fmt::Display for YieldSource {
3070 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3071 f.write_str(match self {
3072 YieldSource::Await { .. } => "`await`",
3073 YieldSource::Yield => "`yield`",
3074 })
3075 }
3076}
3077
3078#[derive(Debug, Clone, Copy, HashStable_Generic)]
3081pub struct MutTy<'hir> {
3082 pub ty: &'hir Ty<'hir>,
3083 pub mutbl: Mutability,
3084}
3085
3086#[derive(Debug, Clone, Copy, HashStable_Generic)]
3089pub struct FnSig<'hir> {
3090 pub header: FnHeader,
3091 pub decl: &'hir FnDecl<'hir>,
3092 pub span: Span,
3093}
3094
3095#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3099pub struct TraitItemId {
3100 pub owner_id: OwnerId,
3101}
3102
3103impl TraitItemId {
3104 #[inline]
3105 pub fn hir_id(&self) -> HirId {
3106 HirId::make_owner(self.owner_id.def_id)
3108 }
3109}
3110
3111#[derive(Debug, Clone, Copy, HashStable_Generic)]
3116pub struct TraitItem<'hir> {
3117 pub ident: Ident,
3118 pub owner_id: OwnerId,
3119 pub generics: &'hir Generics<'hir>,
3120 pub kind: TraitItemKind<'hir>,
3121 pub span: Span,
3122 pub defaultness: Defaultness,
3123 pub has_delayed_lints: bool,
3124}
3125
3126macro_rules! expect_methods_self_kind {
3127 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3128 $(
3129 #[track_caller]
3130 pub fn $name(&self) -> $ret_ty {
3131 let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
3132 $ret_val
3133 }
3134 )*
3135 }
3136}
3137
3138macro_rules! expect_methods_self {
3139 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3140 $(
3141 #[track_caller]
3142 pub fn $name(&self) -> $ret_ty {
3143 let $pat = self else { expect_failed(stringify!($ident), self) };
3144 $ret_val
3145 }
3146 )*
3147 }
3148}
3149
3150#[track_caller]
3151fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
3152 panic!("{ident}: found {found:?}")
3153}
3154
3155impl<'hir> TraitItem<'hir> {
3156 #[inline]
3157 pub fn hir_id(&self) -> HirId {
3158 HirId::make_owner(self.owner_id.def_id)
3160 }
3161
3162 pub fn trait_item_id(&self) -> TraitItemId {
3163 TraitItemId { owner_id: self.owner_id }
3164 }
3165
3166 expect_methods_self_kind! {
3167 expect_const, (&'hir Ty<'hir>, Option<BodyId>),
3168 TraitItemKind::Const(ty, body), (ty, *body);
3169
3170 expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
3171 TraitItemKind::Fn(ty, trfn), (ty, trfn);
3172
3173 expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3174 TraitItemKind::Type(bounds, ty), (bounds, *ty);
3175 }
3176}
3177
3178#[derive(Debug, Clone, Copy, HashStable_Generic)]
3180pub enum TraitFn<'hir> {
3181 Required(&'hir [Option<Ident>]),
3183
3184 Provided(BodyId),
3186}
3187
3188#[derive(Debug, Clone, Copy, HashStable_Generic)]
3190pub enum TraitItemKind<'hir> {
3191 Const(&'hir Ty<'hir>, Option<BodyId>),
3193 Fn(FnSig<'hir>, TraitFn<'hir>),
3195 Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3198}
3199
3200#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3204pub struct ImplItemId {
3205 pub owner_id: OwnerId,
3206}
3207
3208impl ImplItemId {
3209 #[inline]
3210 pub fn hir_id(&self) -> HirId {
3211 HirId::make_owner(self.owner_id.def_id)
3213 }
3214}
3215
3216#[derive(Debug, Clone, Copy, HashStable_Generic)]
3220pub struct ImplItem<'hir> {
3221 pub ident: Ident,
3222 pub owner_id: OwnerId,
3223 pub generics: &'hir Generics<'hir>,
3224 pub kind: ImplItemKind<'hir>,
3225 pub impl_kind: ImplItemImplKind,
3226 pub span: Span,
3227 pub has_delayed_lints: bool,
3228}
3229
3230#[derive(Debug, Clone, Copy, HashStable_Generic)]
3231pub enum ImplItemImplKind {
3232 Inherent {
3233 vis_span: Span,
3234 },
3235 Trait {
3236 defaultness: Defaultness,
3237 trait_item_def_id: Result<DefId, ErrorGuaranteed>,
3239 },
3240}
3241
3242impl<'hir> ImplItem<'hir> {
3243 #[inline]
3244 pub fn hir_id(&self) -> HirId {
3245 HirId::make_owner(self.owner_id.def_id)
3247 }
3248
3249 pub fn impl_item_id(&self) -> ImplItemId {
3250 ImplItemId { owner_id: self.owner_id }
3251 }
3252
3253 pub fn vis_span(&self) -> Option<Span> {
3254 match self.impl_kind {
3255 ImplItemImplKind::Trait { .. } => None,
3256 ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
3257 }
3258 }
3259
3260 expect_methods_self_kind! {
3261 expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
3262 expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3263 expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3264 }
3265}
3266
3267#[derive(Debug, Clone, Copy, HashStable_Generic)]
3269pub enum ImplItemKind<'hir> {
3270 Const(&'hir Ty<'hir>, BodyId),
3273 Fn(FnSig<'hir>, BodyId),
3275 Type(&'hir Ty<'hir>),
3277}
3278
3279#[derive(Debug, Clone, Copy, HashStable_Generic)]
3290pub struct AssocItemConstraint<'hir> {
3291 #[stable_hasher(ignore)]
3292 pub hir_id: HirId,
3293 pub ident: Ident,
3294 pub gen_args: &'hir GenericArgs<'hir>,
3295 pub kind: AssocItemConstraintKind<'hir>,
3296 pub span: Span,
3297}
3298
3299impl<'hir> AssocItemConstraint<'hir> {
3300 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
3302 match self.kind {
3303 AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
3304 _ => None,
3305 }
3306 }
3307
3308 pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
3310 match self.kind {
3311 AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
3312 _ => None,
3313 }
3314 }
3315}
3316
3317#[derive(Debug, Clone, Copy, HashStable_Generic)]
3318pub enum Term<'hir> {
3319 Ty(&'hir Ty<'hir>),
3320 Const(&'hir ConstArg<'hir>),
3321}
3322
3323impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
3324 fn from(ty: &'hir Ty<'hir>) -> Self {
3325 Term::Ty(ty)
3326 }
3327}
3328
3329impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
3330 fn from(c: &'hir ConstArg<'hir>) -> Self {
3331 Term::Const(c)
3332 }
3333}
3334
3335#[derive(Debug, Clone, Copy, HashStable_Generic)]
3337pub enum AssocItemConstraintKind<'hir> {
3338 Equality { term: Term<'hir> },
3345 Bound { bounds: &'hir [GenericBound<'hir>] },
3347}
3348
3349impl<'hir> AssocItemConstraintKind<'hir> {
3350 pub fn descr(&self) -> &'static str {
3351 match self {
3352 AssocItemConstraintKind::Equality { .. } => "binding",
3353 AssocItemConstraintKind::Bound { .. } => "constraint",
3354 }
3355 }
3356}
3357
3358#[derive(Debug, Clone, Copy, HashStable_Generic)]
3362pub enum AmbigArg {}
3363
3364#[derive(Debug, Clone, Copy, HashStable_Generic)]
3369#[repr(C)]
3370pub struct Ty<'hir, Unambig = ()> {
3371 #[stable_hasher(ignore)]
3372 pub hir_id: HirId,
3373 pub span: Span,
3374 pub kind: TyKind<'hir, Unambig>,
3375}
3376
3377impl<'hir> Ty<'hir, AmbigArg> {
3378 pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3389 let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3392 unsafe { &*ptr }
3393 }
3394}
3395
3396impl<'hir> Ty<'hir> {
3397 pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3403 if let TyKind::Infer(()) = self.kind {
3404 return None;
3405 }
3406
3407 let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3411 Some(unsafe { &*ptr })
3412 }
3413}
3414
3415impl<'hir> Ty<'hir, AmbigArg> {
3416 pub fn peel_refs(&self) -> &Ty<'hir> {
3417 let mut final_ty = self.as_unambig_ty();
3418 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3419 final_ty = ty;
3420 }
3421 final_ty
3422 }
3423}
3424
3425impl<'hir> Ty<'hir> {
3426 pub fn peel_refs(&self) -> &Self {
3427 let mut final_ty = self;
3428 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3429 final_ty = ty;
3430 }
3431 final_ty
3432 }
3433
3434 pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3436 let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3437 return None;
3438 };
3439 let [segment] = &path.segments else {
3440 return None;
3441 };
3442 match path.res {
3443 Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3444 Some((def_id, segment.ident))
3445 }
3446 _ => None,
3447 }
3448 }
3449
3450 pub fn find_self_aliases(&self) -> Vec<Span> {
3451 use crate::intravisit::Visitor;
3452 struct MyVisitor(Vec<Span>);
3453 impl<'v> Visitor<'v> for MyVisitor {
3454 fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3455 if matches!(
3456 &t.kind,
3457 TyKind::Path(QPath::Resolved(
3458 _,
3459 Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3460 ))
3461 ) {
3462 self.0.push(t.span);
3463 return;
3464 }
3465 crate::intravisit::walk_ty(self, t);
3466 }
3467 }
3468
3469 let mut my_visitor = MyVisitor(vec![]);
3470 my_visitor.visit_ty_unambig(self);
3471 my_visitor.0
3472 }
3473
3474 pub fn is_suggestable_infer_ty(&self) -> bool {
3477 fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3478 generic_args.iter().any(|arg| match arg {
3479 GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3480 GenericArg::Infer(_) => true,
3481 _ => false,
3482 })
3483 }
3484 debug!(?self);
3485 match &self.kind {
3486 TyKind::Infer(()) => true,
3487 TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3488 TyKind::Array(ty, length) => {
3489 ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3490 }
3491 TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3492 TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3493 TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3494 ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3495 }
3496 TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3497 ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3498 || segments
3499 .iter()
3500 .any(|segment| are_suggestable_generic_args(segment.args().args))
3501 }
3502 _ => false,
3503 }
3504 }
3505}
3506
3507#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3509pub enum PrimTy {
3510 Int(IntTy),
3511 Uint(UintTy),
3512 Float(FloatTy),
3513 Str,
3514 Bool,
3515 Char,
3516}
3517
3518impl PrimTy {
3519 pub const ALL: [Self; 19] = [
3521 Self::Int(IntTy::I8),
3523 Self::Int(IntTy::I16),
3524 Self::Int(IntTy::I32),
3525 Self::Int(IntTy::I64),
3526 Self::Int(IntTy::I128),
3527 Self::Int(IntTy::Isize),
3528 Self::Uint(UintTy::U8),
3529 Self::Uint(UintTy::U16),
3530 Self::Uint(UintTy::U32),
3531 Self::Uint(UintTy::U64),
3532 Self::Uint(UintTy::U128),
3533 Self::Uint(UintTy::Usize),
3534 Self::Float(FloatTy::F16),
3535 Self::Float(FloatTy::F32),
3536 Self::Float(FloatTy::F64),
3537 Self::Float(FloatTy::F128),
3538 Self::Bool,
3539 Self::Char,
3540 Self::Str,
3541 ];
3542
3543 pub fn name_str(self) -> &'static str {
3547 match self {
3548 PrimTy::Int(i) => i.name_str(),
3549 PrimTy::Uint(u) => u.name_str(),
3550 PrimTy::Float(f) => f.name_str(),
3551 PrimTy::Str => "str",
3552 PrimTy::Bool => "bool",
3553 PrimTy::Char => "char",
3554 }
3555 }
3556
3557 pub fn name(self) -> Symbol {
3558 match self {
3559 PrimTy::Int(i) => i.name(),
3560 PrimTy::Uint(u) => u.name(),
3561 PrimTy::Float(f) => f.name(),
3562 PrimTy::Str => sym::str,
3563 PrimTy::Bool => sym::bool,
3564 PrimTy::Char => sym::char,
3565 }
3566 }
3567
3568 pub fn from_name(name: Symbol) -> Option<Self> {
3571 let ty = match name {
3572 sym::i8 => Self::Int(IntTy::I8),
3574 sym::i16 => Self::Int(IntTy::I16),
3575 sym::i32 => Self::Int(IntTy::I32),
3576 sym::i64 => Self::Int(IntTy::I64),
3577 sym::i128 => Self::Int(IntTy::I128),
3578 sym::isize => Self::Int(IntTy::Isize),
3579 sym::u8 => Self::Uint(UintTy::U8),
3580 sym::u16 => Self::Uint(UintTy::U16),
3581 sym::u32 => Self::Uint(UintTy::U32),
3582 sym::u64 => Self::Uint(UintTy::U64),
3583 sym::u128 => Self::Uint(UintTy::U128),
3584 sym::usize => Self::Uint(UintTy::Usize),
3585 sym::f16 => Self::Float(FloatTy::F16),
3586 sym::f32 => Self::Float(FloatTy::F32),
3587 sym::f64 => Self::Float(FloatTy::F64),
3588 sym::f128 => Self::Float(FloatTy::F128),
3589 sym::bool => Self::Bool,
3590 sym::char => Self::Char,
3591 sym::str => Self::Str,
3592 _ => return None,
3593 };
3594 Some(ty)
3595 }
3596}
3597
3598#[derive(Debug, Clone, Copy, HashStable_Generic)]
3599pub struct FnPtrTy<'hir> {
3600 pub safety: Safety,
3601 pub abi: ExternAbi,
3602 pub generic_params: &'hir [GenericParam<'hir>],
3603 pub decl: &'hir FnDecl<'hir>,
3604 pub param_idents: &'hir [Option<Ident>],
3607}
3608
3609#[derive(Debug, Clone, Copy, HashStable_Generic)]
3610pub struct UnsafeBinderTy<'hir> {
3611 pub generic_params: &'hir [GenericParam<'hir>],
3612 pub inner_ty: &'hir Ty<'hir>,
3613}
3614
3615#[derive(Debug, Clone, Copy, HashStable_Generic)]
3616pub struct OpaqueTy<'hir> {
3617 #[stable_hasher(ignore)]
3618 pub hir_id: HirId,
3619 pub def_id: LocalDefId,
3620 pub bounds: GenericBounds<'hir>,
3621 pub origin: OpaqueTyOrigin<LocalDefId>,
3622 pub span: Span,
3623}
3624
3625#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
3626pub enum PreciseCapturingArgKind<T, U> {
3627 Lifetime(T),
3628 Param(U),
3630}
3631
3632pub type PreciseCapturingArg<'hir> =
3633 PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
3634
3635impl PreciseCapturingArg<'_> {
3636 pub fn hir_id(self) -> HirId {
3637 match self {
3638 PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3639 PreciseCapturingArg::Param(param) => param.hir_id,
3640 }
3641 }
3642
3643 pub fn name(self) -> Symbol {
3644 match self {
3645 PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3646 PreciseCapturingArg::Param(param) => param.ident.name,
3647 }
3648 }
3649}
3650
3651#[derive(Debug, Clone, Copy, HashStable_Generic)]
3656pub struct PreciseCapturingNonLifetimeArg {
3657 #[stable_hasher(ignore)]
3658 pub hir_id: HirId,
3659 pub ident: Ident,
3660 pub res: Res,
3661}
3662
3663#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3664#[derive(HashStable_Generic, Encodable, Decodable)]
3665pub enum RpitContext {
3666 Trait,
3667 TraitImpl,
3668}
3669
3670#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3672#[derive(HashStable_Generic, Encodable, Decodable)]
3673pub enum OpaqueTyOrigin<D> {
3674 FnReturn {
3676 parent: D,
3678 in_trait_or_impl: Option<RpitContext>,
3680 },
3681 AsyncFn {
3683 parent: D,
3685 in_trait_or_impl: Option<RpitContext>,
3687 },
3688 TyAlias {
3690 parent: D,
3692 in_assoc_ty: bool,
3694 },
3695}
3696
3697#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3698pub enum InferDelegationKind {
3699 Input(usize),
3700 Output,
3701}
3702
3703#[repr(u8, C)]
3709#[derive(Debug, Clone, Copy, HashStable_Generic)]
3710pub enum TyKind<'hir, Unambig = ()> {
3711 InferDelegation(DefId, InferDelegationKind),
3713 Slice(&'hir Ty<'hir>),
3715 Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3717 Ptr(MutTy<'hir>),
3719 Ref(&'hir Lifetime, MutTy<'hir>),
3721 FnPtr(&'hir FnPtrTy<'hir>),
3723 UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3725 Never,
3727 Tup(&'hir [Ty<'hir>]),
3729 Path(QPath<'hir>),
3734 OpaqueDef(&'hir OpaqueTy<'hir>),
3736 TraitAscription(GenericBounds<'hir>),
3738 TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3744 Typeof(&'hir AnonConst),
3746 Err(rustc_span::ErrorGuaranteed),
3748 Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3750 Infer(Unambig),
3756}
3757
3758#[derive(Debug, Clone, Copy, HashStable_Generic)]
3759pub enum InlineAsmOperand<'hir> {
3760 In {
3761 reg: InlineAsmRegOrRegClass,
3762 expr: &'hir Expr<'hir>,
3763 },
3764 Out {
3765 reg: InlineAsmRegOrRegClass,
3766 late: bool,
3767 expr: Option<&'hir Expr<'hir>>,
3768 },
3769 InOut {
3770 reg: InlineAsmRegOrRegClass,
3771 late: bool,
3772 expr: &'hir Expr<'hir>,
3773 },
3774 SplitInOut {
3775 reg: InlineAsmRegOrRegClass,
3776 late: bool,
3777 in_expr: &'hir Expr<'hir>,
3778 out_expr: Option<&'hir Expr<'hir>>,
3779 },
3780 Const {
3781 anon_const: ConstBlock,
3782 },
3783 SymFn {
3784 expr: &'hir Expr<'hir>,
3785 },
3786 SymStatic {
3787 path: QPath<'hir>,
3788 def_id: DefId,
3789 },
3790 Label {
3791 block: &'hir Block<'hir>,
3792 },
3793}
3794
3795impl<'hir> InlineAsmOperand<'hir> {
3796 pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3797 match *self {
3798 Self::In { reg, .. }
3799 | Self::Out { reg, .. }
3800 | Self::InOut { reg, .. }
3801 | Self::SplitInOut { reg, .. } => Some(reg),
3802 Self::Const { .. }
3803 | Self::SymFn { .. }
3804 | Self::SymStatic { .. }
3805 | Self::Label { .. } => None,
3806 }
3807 }
3808
3809 pub fn is_clobber(&self) -> bool {
3810 matches!(
3811 self,
3812 InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3813 )
3814 }
3815}
3816
3817#[derive(Debug, Clone, Copy, HashStable_Generic)]
3818pub struct InlineAsm<'hir> {
3819 pub asm_macro: ast::AsmMacro,
3820 pub template: &'hir [InlineAsmTemplatePiece],
3821 pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3822 pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3823 pub options: InlineAsmOptions,
3824 pub line_spans: &'hir [Span],
3825}
3826
3827impl InlineAsm<'_> {
3828 pub fn contains_label(&self) -> bool {
3829 self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3830 }
3831}
3832
3833#[derive(Debug, Clone, Copy, HashStable_Generic)]
3835pub struct Param<'hir> {
3836 #[stable_hasher(ignore)]
3837 pub hir_id: HirId,
3838 pub pat: &'hir Pat<'hir>,
3839 pub ty_span: Span,
3840 pub span: Span,
3841}
3842
3843#[derive(Debug, Clone, Copy, HashStable_Generic)]
3845pub struct FnDecl<'hir> {
3846 pub inputs: &'hir [Ty<'hir>],
3850 pub output: FnRetTy<'hir>,
3851 pub c_variadic: bool,
3852 pub implicit_self: ImplicitSelfKind,
3854 pub lifetime_elision_allowed: bool,
3856}
3857
3858impl<'hir> FnDecl<'hir> {
3859 pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3860 if let FnRetTy::Return(ty) = self.output
3861 && let TyKind::InferDelegation(sig_id, _) = ty.kind
3862 {
3863 return Some(sig_id);
3864 }
3865 None
3866 }
3867}
3868
3869#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3871pub enum ImplicitSelfKind {
3872 Imm,
3874 Mut,
3876 RefImm,
3878 RefMut,
3880 None,
3883}
3884
3885impl ImplicitSelfKind {
3886 pub fn has_implicit_self(&self) -> bool {
3888 !matches!(*self, ImplicitSelfKind::None)
3889 }
3890}
3891
3892#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3893pub enum IsAsync {
3894 Async(Span),
3895 NotAsync,
3896}
3897
3898impl IsAsync {
3899 pub fn is_async(self) -> bool {
3900 matches!(self, IsAsync::Async(_))
3901 }
3902}
3903
3904#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3905pub enum Defaultness {
3906 Default { has_value: bool },
3907 Final,
3908}
3909
3910impl Defaultness {
3911 pub fn has_value(&self) -> bool {
3912 match *self {
3913 Defaultness::Default { has_value } => has_value,
3914 Defaultness::Final => true,
3915 }
3916 }
3917
3918 pub fn is_final(&self) -> bool {
3919 *self == Defaultness::Final
3920 }
3921
3922 pub fn is_default(&self) -> bool {
3923 matches!(*self, Defaultness::Default { .. })
3924 }
3925}
3926
3927#[derive(Debug, Clone, Copy, HashStable_Generic)]
3928pub enum FnRetTy<'hir> {
3929 DefaultReturn(Span),
3935 Return(&'hir Ty<'hir>),
3937}
3938
3939impl<'hir> FnRetTy<'hir> {
3940 #[inline]
3941 pub fn span(&self) -> Span {
3942 match *self {
3943 Self::DefaultReturn(span) => span,
3944 Self::Return(ref ty) => ty.span,
3945 }
3946 }
3947
3948 pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3949 if let Self::Return(ty) = self
3950 && ty.is_suggestable_infer_ty()
3951 {
3952 return Some(*ty);
3953 }
3954 None
3955 }
3956}
3957
3958#[derive(Copy, Clone, Debug, HashStable_Generic)]
3960pub enum ClosureBinder {
3961 Default,
3963 For { span: Span },
3967}
3968
3969#[derive(Debug, Clone, Copy, HashStable_Generic)]
3970pub struct Mod<'hir> {
3971 pub spans: ModSpans,
3972 pub item_ids: &'hir [ItemId],
3973}
3974
3975#[derive(Copy, Clone, Debug, HashStable_Generic)]
3976pub struct ModSpans {
3977 pub inner_span: Span,
3981 pub inject_use_span: Span,
3982}
3983
3984#[derive(Debug, Clone, Copy, HashStable_Generic)]
3985pub struct EnumDef<'hir> {
3986 pub variants: &'hir [Variant<'hir>],
3987}
3988
3989#[derive(Debug, Clone, Copy, HashStable_Generic)]
3990pub struct Variant<'hir> {
3991 pub ident: Ident,
3993 #[stable_hasher(ignore)]
3995 pub hir_id: HirId,
3996 pub def_id: LocalDefId,
3997 pub data: VariantData<'hir>,
3999 pub disr_expr: Option<&'hir AnonConst>,
4001 pub span: Span,
4003}
4004
4005#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4006pub enum UseKind {
4007 Single(Ident),
4014
4015 Glob,
4017
4018 ListStem,
4022}
4023
4024#[derive(Clone, Debug, Copy, HashStable_Generic)]
4031pub struct TraitRef<'hir> {
4032 pub path: &'hir Path<'hir>,
4033 #[stable_hasher(ignore)]
4035 pub hir_ref_id: HirId,
4036}
4037
4038impl TraitRef<'_> {
4039 pub fn trait_def_id(&self) -> Option<DefId> {
4041 match self.path.res {
4042 Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
4043 Res::Err => None,
4044 res => panic!("{res:?} did not resolve to a trait or trait alias"),
4045 }
4046 }
4047}
4048
4049#[derive(Clone, Debug, Copy, HashStable_Generic)]
4050pub struct PolyTraitRef<'hir> {
4051 pub bound_generic_params: &'hir [GenericParam<'hir>],
4053
4054 pub modifiers: TraitBoundModifiers,
4058
4059 pub trait_ref: TraitRef<'hir>,
4061
4062 pub span: Span,
4063}
4064
4065#[derive(Debug, Clone, Copy, HashStable_Generic)]
4066pub struct FieldDef<'hir> {
4067 pub span: Span,
4068 pub vis_span: Span,
4069 pub ident: Ident,
4070 #[stable_hasher(ignore)]
4071 pub hir_id: HirId,
4072 pub def_id: LocalDefId,
4073 pub ty: &'hir Ty<'hir>,
4074 pub safety: Safety,
4075 pub default: Option<&'hir AnonConst>,
4076}
4077
4078impl FieldDef<'_> {
4079 pub fn is_positional(&self) -> bool {
4081 self.ident.as_str().as_bytes()[0].is_ascii_digit()
4082 }
4083}
4084
4085#[derive(Debug, Clone, Copy, HashStable_Generic)]
4087pub enum VariantData<'hir> {
4088 Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
4092 Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
4096 Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
4100}
4101
4102impl<'hir> VariantData<'hir> {
4103 pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
4105 match *self {
4106 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
4107 _ => &[],
4108 }
4109 }
4110
4111 pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
4112 match *self {
4113 VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
4114 VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
4115 VariantData::Struct { .. } => None,
4116 }
4117 }
4118
4119 #[inline]
4120 pub fn ctor_kind(&self) -> Option<CtorKind> {
4121 self.ctor().map(|(kind, ..)| kind)
4122 }
4123
4124 #[inline]
4126 pub fn ctor_hir_id(&self) -> Option<HirId> {
4127 self.ctor().map(|(_, hir_id, _)| hir_id)
4128 }
4129
4130 #[inline]
4132 pub fn ctor_def_id(&self) -> Option<LocalDefId> {
4133 self.ctor().map(|(.., def_id)| def_id)
4134 }
4135}
4136
4137#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
4141pub struct ItemId {
4142 pub owner_id: OwnerId,
4143}
4144
4145impl ItemId {
4146 #[inline]
4147 pub fn hir_id(&self) -> HirId {
4148 HirId::make_owner(self.owner_id.def_id)
4150 }
4151}
4152
4153#[derive(Debug, Clone, Copy, HashStable_Generic)]
4162pub struct Item<'hir> {
4163 pub owner_id: OwnerId,
4164 pub kind: ItemKind<'hir>,
4165 pub span: Span,
4166 pub vis_span: Span,
4167 pub has_delayed_lints: bool,
4168}
4169
4170impl<'hir> Item<'hir> {
4171 #[inline]
4172 pub fn hir_id(&self) -> HirId {
4173 HirId::make_owner(self.owner_id.def_id)
4175 }
4176
4177 pub fn item_id(&self) -> ItemId {
4178 ItemId { owner_id: self.owner_id }
4179 }
4180
4181 pub fn is_adt(&self) -> bool {
4184 matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
4185 }
4186
4187 pub fn is_struct_or_union(&self) -> bool {
4189 matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
4190 }
4191
4192 expect_methods_self_kind! {
4193 expect_extern_crate, (Option<Symbol>, Ident),
4194 ItemKind::ExternCrate(s, ident), (*s, *ident);
4195
4196 expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
4197
4198 expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId),
4199 ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body);
4200
4201 expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4202 ItemKind::Const(ident, generics, ty, body), (*ident, generics, ty, *body);
4203
4204 expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
4205 ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
4206
4207 expect_macro, (Ident, &ast::MacroDef, MacroKinds),
4208 ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
4209
4210 expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
4211
4212 expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]),
4213 ItemKind::ForeignMod { abi, items }, (*abi, items);
4214
4215 expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
4216
4217 expect_ty_alias, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4218 ItemKind::TyAlias(ident, generics, ty), (*ident, generics, ty);
4219
4220 expect_enum, (Ident, &'hir Generics<'hir>, &EnumDef<'hir>),
4221 ItemKind::Enum(ident, generics, def), (*ident, generics, def);
4222
4223 expect_struct, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4224 ItemKind::Struct(ident, generics, data), (*ident, generics, data);
4225
4226 expect_union, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4227 ItemKind::Union(ident, generics, data), (*ident, generics, data);
4228
4229 expect_trait,
4230 (
4231 Constness,
4232 IsAuto,
4233 Safety,
4234 Ident,
4235 &'hir Generics<'hir>,
4236 GenericBounds<'hir>,
4237 &'hir [TraitItemId]
4238 ),
4239 ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
4240 (*constness, *is_auto, *safety, *ident, generics, bounds, items);
4241
4242 expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4243 ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
4244
4245 expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
4246 }
4247}
4248
4249#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4250#[derive(Encodable, Decodable, HashStable_Generic)]
4251pub enum Safety {
4252 Unsafe,
4253 Safe,
4254}
4255
4256impl Safety {
4257 pub fn prefix_str(self) -> &'static str {
4258 match self {
4259 Self::Unsafe => "unsafe ",
4260 Self::Safe => "",
4261 }
4262 }
4263
4264 #[inline]
4265 pub fn is_unsafe(self) -> bool {
4266 !self.is_safe()
4267 }
4268
4269 #[inline]
4270 pub fn is_safe(self) -> bool {
4271 match self {
4272 Self::Unsafe => false,
4273 Self::Safe => true,
4274 }
4275 }
4276}
4277
4278impl fmt::Display for Safety {
4279 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4280 f.write_str(match *self {
4281 Self::Unsafe => "unsafe",
4282 Self::Safe => "safe",
4283 })
4284 }
4285}
4286
4287#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
4288pub enum Constness {
4289 Const,
4290 NotConst,
4291}
4292
4293impl fmt::Display for Constness {
4294 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4295 f.write_str(match *self {
4296 Self::Const => "const",
4297 Self::NotConst => "non-const",
4298 })
4299 }
4300}
4301
4302#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
4307pub enum HeaderSafety {
4308 SafeTargetFeatures,
4314 Normal(Safety),
4315}
4316
4317impl From<Safety> for HeaderSafety {
4318 fn from(v: Safety) -> Self {
4319 Self::Normal(v)
4320 }
4321}
4322
4323#[derive(Copy, Clone, Debug, HashStable_Generic)]
4324pub struct FnHeader {
4325 pub safety: HeaderSafety,
4326 pub constness: Constness,
4327 pub asyncness: IsAsync,
4328 pub abi: ExternAbi,
4329}
4330
4331impl FnHeader {
4332 pub fn is_async(&self) -> bool {
4333 matches!(self.asyncness, IsAsync::Async(_))
4334 }
4335
4336 pub fn is_const(&self) -> bool {
4337 matches!(self.constness, Constness::Const)
4338 }
4339
4340 pub fn is_unsafe(&self) -> bool {
4341 self.safety().is_unsafe()
4342 }
4343
4344 pub fn is_safe(&self) -> bool {
4345 self.safety().is_safe()
4346 }
4347
4348 pub fn safety(&self) -> Safety {
4349 match self.safety {
4350 HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
4351 HeaderSafety::Normal(safety) => safety,
4352 }
4353 }
4354}
4355
4356#[derive(Debug, Clone, Copy, HashStable_Generic)]
4357pub enum ItemKind<'hir> {
4358 ExternCrate(Option<Symbol>, Ident),
4362
4363 Use(&'hir UsePath<'hir>, UseKind),
4369
4370 Static(Mutability, Ident, &'hir Ty<'hir>, BodyId),
4372 Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4374 Fn {
4376 sig: FnSig<'hir>,
4377 ident: Ident,
4378 generics: &'hir Generics<'hir>,
4379 body: BodyId,
4380 has_body: bool,
4384 },
4385 Macro(Ident, &'hir ast::MacroDef, MacroKinds),
4387 Mod(Ident, &'hir Mod<'hir>),
4389 ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] },
4391 GlobalAsm {
4393 asm: &'hir InlineAsm<'hir>,
4394 fake_body: BodyId,
4400 },
4401 TyAlias(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4403 Enum(Ident, &'hir Generics<'hir>, EnumDef<'hir>),
4405 Struct(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4407 Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4409 Trait(
4411 Constness,
4412 IsAuto,
4413 Safety,
4414 Ident,
4415 &'hir Generics<'hir>,
4416 GenericBounds<'hir>,
4417 &'hir [TraitItemId],
4418 ),
4419 TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4421
4422 Impl(Impl<'hir>),
4424}
4425
4426#[derive(Debug, Clone, Copy, HashStable_Generic)]
4431pub struct Impl<'hir> {
4432 pub generics: &'hir Generics<'hir>,
4433 pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
4434 pub self_ty: &'hir Ty<'hir>,
4435 pub items: &'hir [ImplItemId],
4436}
4437
4438#[derive(Debug, Clone, Copy, HashStable_Generic)]
4439pub struct TraitImplHeader<'hir> {
4440 pub constness: Constness,
4441 pub safety: Safety,
4442 pub polarity: ImplPolarity,
4443 pub defaultness: Defaultness,
4444 pub defaultness_span: Option<Span>,
4447 pub trait_ref: TraitRef<'hir>,
4448}
4449
4450impl ItemKind<'_> {
4451 pub fn ident(&self) -> Option<Ident> {
4452 match *self {
4453 ItemKind::ExternCrate(_, ident)
4454 | ItemKind::Use(_, UseKind::Single(ident))
4455 | ItemKind::Static(_, ident, ..)
4456 | ItemKind::Const(ident, ..)
4457 | ItemKind::Fn { ident, .. }
4458 | ItemKind::Macro(ident, ..)
4459 | ItemKind::Mod(ident, ..)
4460 | ItemKind::TyAlias(ident, ..)
4461 | ItemKind::Enum(ident, ..)
4462 | ItemKind::Struct(ident, ..)
4463 | ItemKind::Union(ident, ..)
4464 | ItemKind::Trait(_, _, _, ident, ..)
4465 | ItemKind::TraitAlias(ident, ..) => Some(ident),
4466
4467 ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
4468 | ItemKind::ForeignMod { .. }
4469 | ItemKind::GlobalAsm { .. }
4470 | ItemKind::Impl(_) => None,
4471 }
4472 }
4473
4474 pub fn generics(&self) -> Option<&Generics<'_>> {
4475 Some(match self {
4476 ItemKind::Fn { generics, .. }
4477 | ItemKind::TyAlias(_, generics, _)
4478 | ItemKind::Const(_, generics, _, _)
4479 | ItemKind::Enum(_, generics, _)
4480 | ItemKind::Struct(_, generics, _)
4481 | ItemKind::Union(_, generics, _)
4482 | ItemKind::Trait(_, _, _, _, generics, _, _)
4483 | ItemKind::TraitAlias(_, generics, _)
4484 | ItemKind::Impl(Impl { generics, .. }) => generics,
4485 _ => return None,
4486 })
4487 }
4488}
4489
4490#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4494pub struct ForeignItemId {
4495 pub owner_id: OwnerId,
4496}
4497
4498impl ForeignItemId {
4499 #[inline]
4500 pub fn hir_id(&self) -> HirId {
4501 HirId::make_owner(self.owner_id.def_id)
4503 }
4504}
4505
4506#[derive(Debug, Clone, Copy, HashStable_Generic)]
4507pub struct ForeignItem<'hir> {
4508 pub ident: Ident,
4509 pub kind: ForeignItemKind<'hir>,
4510 pub owner_id: OwnerId,
4511 pub span: Span,
4512 pub vis_span: Span,
4513 pub has_delayed_lints: bool,
4514}
4515
4516impl ForeignItem<'_> {
4517 #[inline]
4518 pub fn hir_id(&self) -> HirId {
4519 HirId::make_owner(self.owner_id.def_id)
4521 }
4522
4523 pub fn foreign_item_id(&self) -> ForeignItemId {
4524 ForeignItemId { owner_id: self.owner_id }
4525 }
4526}
4527
4528#[derive(Debug, Clone, Copy, HashStable_Generic)]
4530pub enum ForeignItemKind<'hir> {
4531 Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
4538 Static(&'hir Ty<'hir>, Mutability, Safety),
4540 Type,
4542}
4543
4544#[derive(Debug, Copy, Clone, HashStable_Generic)]
4546pub struct Upvar {
4547 pub span: Span,
4549}
4550
4551#[derive(Debug, Clone, HashStable_Generic)]
4555pub struct TraitCandidate {
4556 pub def_id: DefId,
4557 pub import_ids: SmallVec<[LocalDefId; 1]>,
4558}
4559
4560#[derive(Copy, Clone, Debug, HashStable_Generic)]
4561pub enum OwnerNode<'hir> {
4562 Item(&'hir Item<'hir>),
4563 ForeignItem(&'hir ForeignItem<'hir>),
4564 TraitItem(&'hir TraitItem<'hir>),
4565 ImplItem(&'hir ImplItem<'hir>),
4566 Crate(&'hir Mod<'hir>),
4567 Synthetic,
4568}
4569
4570impl<'hir> OwnerNode<'hir> {
4571 pub fn span(&self) -> Span {
4572 match self {
4573 OwnerNode::Item(Item { span, .. })
4574 | OwnerNode::ForeignItem(ForeignItem { span, .. })
4575 | OwnerNode::ImplItem(ImplItem { span, .. })
4576 | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4577 OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4578 OwnerNode::Synthetic => unreachable!(),
4579 }
4580 }
4581
4582 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4583 match self {
4584 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4585 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4586 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4587 | OwnerNode::ForeignItem(ForeignItem {
4588 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4589 }) => Some(fn_sig),
4590 _ => None,
4591 }
4592 }
4593
4594 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4595 match self {
4596 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4597 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4598 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4599 | OwnerNode::ForeignItem(ForeignItem {
4600 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4601 }) => Some(fn_sig.decl),
4602 _ => None,
4603 }
4604 }
4605
4606 pub fn body_id(&self) -> Option<BodyId> {
4607 match self {
4608 OwnerNode::Item(Item {
4609 kind:
4610 ItemKind::Static(_, _, _, body)
4611 | ItemKind::Const(_, _, _, body)
4612 | ItemKind::Fn { body, .. },
4613 ..
4614 })
4615 | OwnerNode::TraitItem(TraitItem {
4616 kind:
4617 TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4618 ..
4619 })
4620 | OwnerNode::ImplItem(ImplItem {
4621 kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4622 ..
4623 }) => Some(*body),
4624 _ => None,
4625 }
4626 }
4627
4628 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4629 Node::generics(self.into())
4630 }
4631
4632 pub fn def_id(self) -> OwnerId {
4633 match self {
4634 OwnerNode::Item(Item { owner_id, .. })
4635 | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4636 | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4637 | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4638 OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4639 OwnerNode::Synthetic => unreachable!(),
4640 }
4641 }
4642
4643 pub fn is_impl_block(&self) -> bool {
4645 matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4646 }
4647
4648 expect_methods_self! {
4649 expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
4650 expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4651 expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n;
4652 expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n;
4653 }
4654}
4655
4656impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4657 fn from(val: &'hir Item<'hir>) -> Self {
4658 OwnerNode::Item(val)
4659 }
4660}
4661
4662impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4663 fn from(val: &'hir ForeignItem<'hir>) -> Self {
4664 OwnerNode::ForeignItem(val)
4665 }
4666}
4667
4668impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4669 fn from(val: &'hir ImplItem<'hir>) -> Self {
4670 OwnerNode::ImplItem(val)
4671 }
4672}
4673
4674impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4675 fn from(val: &'hir TraitItem<'hir>) -> Self {
4676 OwnerNode::TraitItem(val)
4677 }
4678}
4679
4680impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4681 fn from(val: OwnerNode<'hir>) -> Self {
4682 match val {
4683 OwnerNode::Item(n) => Node::Item(n),
4684 OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4685 OwnerNode::ImplItem(n) => Node::ImplItem(n),
4686 OwnerNode::TraitItem(n) => Node::TraitItem(n),
4687 OwnerNode::Crate(n) => Node::Crate(n),
4688 OwnerNode::Synthetic => Node::Synthetic,
4689 }
4690 }
4691}
4692
4693#[derive(Copy, Clone, Debug, HashStable_Generic)]
4694pub enum Node<'hir> {
4695 Param(&'hir Param<'hir>),
4696 Item(&'hir Item<'hir>),
4697 ForeignItem(&'hir ForeignItem<'hir>),
4698 TraitItem(&'hir TraitItem<'hir>),
4699 ImplItem(&'hir ImplItem<'hir>),
4700 Variant(&'hir Variant<'hir>),
4701 Field(&'hir FieldDef<'hir>),
4702 AnonConst(&'hir AnonConst),
4703 ConstBlock(&'hir ConstBlock),
4704 ConstArg(&'hir ConstArg<'hir>),
4705 Expr(&'hir Expr<'hir>),
4706 ExprField(&'hir ExprField<'hir>),
4707 Stmt(&'hir Stmt<'hir>),
4708 PathSegment(&'hir PathSegment<'hir>),
4709 Ty(&'hir Ty<'hir>),
4710 AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4711 TraitRef(&'hir TraitRef<'hir>),
4712 OpaqueTy(&'hir OpaqueTy<'hir>),
4713 TyPat(&'hir TyPat<'hir>),
4714 Pat(&'hir Pat<'hir>),
4715 PatField(&'hir PatField<'hir>),
4716 PatExpr(&'hir PatExpr<'hir>),
4720 Arm(&'hir Arm<'hir>),
4721 Block(&'hir Block<'hir>),
4722 LetStmt(&'hir LetStmt<'hir>),
4723 Ctor(&'hir VariantData<'hir>),
4726 Lifetime(&'hir Lifetime),
4727 GenericParam(&'hir GenericParam<'hir>),
4728 Crate(&'hir Mod<'hir>),
4729 Infer(&'hir InferArg),
4730 WherePredicate(&'hir WherePredicate<'hir>),
4731 PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4732 Synthetic,
4734 Err(Span),
4735}
4736
4737impl<'hir> Node<'hir> {
4738 pub fn ident(&self) -> Option<Ident> {
4753 match self {
4754 Node::Item(item) => item.kind.ident(),
4755 Node::TraitItem(TraitItem { ident, .. })
4756 | Node::ImplItem(ImplItem { ident, .. })
4757 | Node::ForeignItem(ForeignItem { ident, .. })
4758 | Node::Field(FieldDef { ident, .. })
4759 | Node::Variant(Variant { ident, .. })
4760 | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4761 Node::Lifetime(lt) => Some(lt.ident),
4762 Node::GenericParam(p) => Some(p.name.ident()),
4763 Node::AssocItemConstraint(c) => Some(c.ident),
4764 Node::PatField(f) => Some(f.ident),
4765 Node::ExprField(f) => Some(f.ident),
4766 Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4767 Node::Param(..)
4768 | Node::AnonConst(..)
4769 | Node::ConstBlock(..)
4770 | Node::ConstArg(..)
4771 | Node::Expr(..)
4772 | Node::Stmt(..)
4773 | Node::Block(..)
4774 | Node::Ctor(..)
4775 | Node::Pat(..)
4776 | Node::TyPat(..)
4777 | Node::PatExpr(..)
4778 | Node::Arm(..)
4779 | Node::LetStmt(..)
4780 | Node::Crate(..)
4781 | Node::Ty(..)
4782 | Node::TraitRef(..)
4783 | Node::OpaqueTy(..)
4784 | Node::Infer(..)
4785 | Node::WherePredicate(..)
4786 | Node::Synthetic
4787 | Node::Err(..) => None,
4788 }
4789 }
4790
4791 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4792 match self {
4793 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4794 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4795 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4796 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4797 Some(fn_sig.decl)
4798 }
4799 Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4800 Some(fn_decl)
4801 }
4802 _ => None,
4803 }
4804 }
4805
4806 pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4808 if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4809 && let Some(of_trait) = impl_block.of_trait
4810 && let Some(trait_id) = of_trait.trait_ref.trait_def_id()
4811 && trait_id == trait_def_id
4812 {
4813 Some(impl_block)
4814 } else {
4815 None
4816 }
4817 }
4818
4819 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4820 match self {
4821 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4822 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4823 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4824 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4825 Some(fn_sig)
4826 }
4827 _ => None,
4828 }
4829 }
4830
4831 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4833 match self {
4834 Node::Item(it) => match it.kind {
4835 ItemKind::TyAlias(_, _, ty)
4836 | ItemKind::Static(_, _, ty, _)
4837 | ItemKind::Const(_, _, ty, _) => Some(ty),
4838 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4839 _ => None,
4840 },
4841 Node::TraitItem(it) => match it.kind {
4842 TraitItemKind::Const(ty, _) => Some(ty),
4843 TraitItemKind::Type(_, ty) => ty,
4844 _ => None,
4845 },
4846 Node::ImplItem(it) => match it.kind {
4847 ImplItemKind::Const(ty, _) => Some(ty),
4848 ImplItemKind::Type(ty) => Some(ty),
4849 _ => None,
4850 },
4851 Node::ForeignItem(it) => match it.kind {
4852 ForeignItemKind::Static(ty, ..) => Some(ty),
4853 _ => None,
4854 },
4855 _ => None,
4856 }
4857 }
4858
4859 pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4860 match self {
4861 Node::Item(Item { kind: ItemKind::TyAlias(_, _, ty), .. }) => Some(ty),
4862 _ => None,
4863 }
4864 }
4865
4866 #[inline]
4867 pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4868 match self {
4869 Node::Item(Item {
4870 owner_id,
4871 kind:
4872 ItemKind::Const(_, _, _, body)
4873 | ItemKind::Static(.., body)
4874 | ItemKind::Fn { body, .. },
4875 ..
4876 })
4877 | Node::TraitItem(TraitItem {
4878 owner_id,
4879 kind:
4880 TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4881 ..
4882 })
4883 | Node::ImplItem(ImplItem {
4884 owner_id,
4885 kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4886 ..
4887 }) => Some((owner_id.def_id, *body)),
4888
4889 Node::Item(Item {
4890 owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4891 }) => Some((owner_id.def_id, *fake_body)),
4892
4893 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4894 Some((*def_id, *body))
4895 }
4896
4897 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4898 Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4899
4900 _ => None,
4901 }
4902 }
4903
4904 pub fn body_id(&self) -> Option<BodyId> {
4905 Some(self.associated_body()?.1)
4906 }
4907
4908 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4909 match self {
4910 Node::ForeignItem(ForeignItem {
4911 kind: ForeignItemKind::Fn(_, _, generics), ..
4912 })
4913 | Node::TraitItem(TraitItem { generics, .. })
4914 | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4915 Node::Item(item) => item.kind.generics(),
4916 _ => None,
4917 }
4918 }
4919
4920 pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4921 match self {
4922 Node::Item(i) => Some(OwnerNode::Item(i)),
4923 Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4924 Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4925 Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4926 Node::Crate(i) => Some(OwnerNode::Crate(i)),
4927 Node::Synthetic => Some(OwnerNode::Synthetic),
4928 _ => None,
4929 }
4930 }
4931
4932 pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4933 match self {
4934 Node::Item(i) => match i.kind {
4935 ItemKind::Fn { ident, sig, generics, .. } => {
4936 Some(FnKind::ItemFn(ident, generics, sig.header))
4937 }
4938 _ => None,
4939 },
4940 Node::TraitItem(ti) => match ti.kind {
4941 TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4942 _ => None,
4943 },
4944 Node::ImplItem(ii) => match ii.kind {
4945 ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4946 _ => None,
4947 },
4948 Node::Expr(e) => match e.kind {
4949 ExprKind::Closure { .. } => Some(FnKind::Closure),
4950 _ => None,
4951 },
4952 _ => None,
4953 }
4954 }
4955
4956 expect_methods_self! {
4957 expect_param, &'hir Param<'hir>, Node::Param(n), n;
4958 expect_item, &'hir Item<'hir>, Node::Item(n), n;
4959 expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n;
4960 expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n;
4961 expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n;
4962 expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
4963 expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
4964 expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
4965 expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
4966 expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
4967 expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
4968 expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
4969 expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
4970 expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
4971 expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
4972 expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4973 expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
4974 expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
4975 expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
4976 expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
4977 expect_block, &'hir Block<'hir>, Node::Block(n), n;
4978 expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
4979 expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
4980 expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
4981 expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
4982 expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
4983 expect_infer, &'hir InferArg, Node::Infer(n), n;
4984 expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
4985 }
4986}
4987
4988#[cfg(target_pointer_width = "64")]
4990mod size_asserts {
4991 use rustc_data_structures::static_assert_size;
4992
4993 use super::*;
4994 static_assert_size!(Block<'_>, 48);
4996 static_assert_size!(Body<'_>, 24);
4997 static_assert_size!(Expr<'_>, 64);
4998 static_assert_size!(ExprKind<'_>, 48);
4999 static_assert_size!(FnDecl<'_>, 40);
5000 static_assert_size!(ForeignItem<'_>, 96);
5001 static_assert_size!(ForeignItemKind<'_>, 56);
5002 static_assert_size!(GenericArg<'_>, 16);
5003 static_assert_size!(GenericBound<'_>, 64);
5004 static_assert_size!(Generics<'_>, 56);
5005 static_assert_size!(Impl<'_>, 40);
5006 static_assert_size!(ImplItem<'_>, 88);
5007 static_assert_size!(ImplItemKind<'_>, 40);
5008 static_assert_size!(Item<'_>, 88);
5009 static_assert_size!(ItemKind<'_>, 64);
5010 static_assert_size!(LetStmt<'_>, 72);
5011 static_assert_size!(Param<'_>, 32);
5012 static_assert_size!(Pat<'_>, 80);
5013 static_assert_size!(PatKind<'_>, 56);
5014 static_assert_size!(Path<'_>, 40);
5015 static_assert_size!(PathSegment<'_>, 48);
5016 static_assert_size!(QPath<'_>, 24);
5017 static_assert_size!(Res, 12);
5018 static_assert_size!(Stmt<'_>, 32);
5019 static_assert_size!(StmtKind<'_>, 16);
5020 static_assert_size!(TraitImplHeader<'_>, 48);
5021 static_assert_size!(TraitItem<'_>, 88);
5022 static_assert_size!(TraitItemKind<'_>, 48);
5023 static_assert_size!(Ty<'_>, 48);
5024 static_assert_size!(TyKind<'_>, 32);
5025 }
5027
5028#[cfg(test)]
5029mod tests;