1use std::borrow::Cow;
3use std::fmt;
4
5use rustc_abi::ExternAbi;
6use rustc_ast::attr::AttributeExt;
7use rustc_ast::token::DocFragmentKind;
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, Pinnedness, 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::{
27 BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Symbol, kw, sym,
28};
29use rustc_target::asm::InlineAsmRegOrRegClass;
30use smallvec::SmallVec;
31use thin_vec::ThinVec;
32use tracing::debug;
33
34use crate::attrs::AttributeKind;
35use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
36use crate::def_id::{DefId, LocalDefIdMap};
37pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
38use crate::intravisit::{FnKind, VisitorExt};
39use crate::lints::DelayedLints;
40
41#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
42pub enum AngleBrackets {
43 Missing,
45 Empty,
47 Full,
49}
50
51#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
52pub enum LifetimeSource {
53 Reference,
55
56 Path { angle_brackets: AngleBrackets },
59
60 OutlivesBound,
62
63 PreciseCapturing,
65
66 Other,
73}
74
75#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
76pub enum LifetimeSyntax {
77 Implicit,
79
80 ExplicitAnonymous,
82
83 ExplicitBound,
85}
86
87impl From<Ident> for LifetimeSyntax {
88 fn from(ident: Ident) -> Self {
89 let name = ident.name;
90
91 if name == sym::empty {
92 unreachable!("A lifetime name should never be empty");
93 } else if name == kw::UnderscoreLifetime {
94 LifetimeSyntax::ExplicitAnonymous
95 } else {
96 debug_assert!(name.as_str().starts_with('\''));
97 LifetimeSyntax::ExplicitBound
98 }
99 }
100}
101
102#[derive(Debug, Copy, Clone, HashStable_Generic)]
153#[repr(align(4))]
161pub struct Lifetime {
162 #[stable_hasher(ignore)]
163 pub hir_id: HirId,
164
165 pub ident: Ident,
169
170 pub kind: LifetimeKind,
172
173 pub source: LifetimeSource,
176
177 pub syntax: LifetimeSyntax,
180}
181
182#[derive(Debug, Copy, Clone, HashStable_Generic)]
183pub enum ParamName {
184 Plain(Ident),
186
187 Error(Ident),
193
194 Fresh,
209}
210
211impl ParamName {
212 pub fn ident(&self) -> Ident {
213 match *self {
214 ParamName::Plain(ident) | ParamName::Error(ident) => ident,
215 ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
216 }
217 }
218}
219
220#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
221pub enum LifetimeKind {
222 Param(LocalDefId),
224
225 ImplicitObjectLifetimeDefault,
237
238 Error,
241
242 Infer,
246
247 Static,
249}
250
251impl LifetimeKind {
252 fn is_elided(&self) -> bool {
253 match self {
254 LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer => true,
255
256 LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
261 }
262 }
263}
264
265impl fmt::Display for Lifetime {
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 self.ident.name.fmt(f)
268 }
269}
270
271impl Lifetime {
272 pub fn new(
273 hir_id: HirId,
274 ident: Ident,
275 kind: LifetimeKind,
276 source: LifetimeSource,
277 syntax: LifetimeSyntax,
278 ) -> Lifetime {
279 let lifetime = Lifetime { hir_id, ident, kind, source, syntax };
280
281 #[cfg(debug_assertions)]
283 match (lifetime.is_elided(), lifetime.is_anonymous()) {
284 (false, false) => {} (false, true) => {} (true, true) => {} (true, false) => panic!("bad Lifetime"),
288 }
289
290 lifetime
291 }
292
293 pub fn is_elided(&self) -> bool {
294 self.kind.is_elided()
295 }
296
297 pub fn is_anonymous(&self) -> bool {
298 self.ident.name == kw::UnderscoreLifetime
299 }
300
301 pub fn is_implicit(&self) -> bool {
302 matches!(self.syntax, LifetimeSyntax::Implicit)
303 }
304
305 pub fn is_static(&self) -> bool {
306 self.kind == LifetimeKind::Static
307 }
308
309 pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
310 use LifetimeSource::*;
311 use LifetimeSyntax::*;
312
313 debug_assert!(new_lifetime.starts_with('\''));
314
315 match (self.syntax, self.source) {
316 (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")),
318
319 (Implicit, Path { angle_brackets: AngleBrackets::Full }) => {
321 (self.ident.span, format!("{new_lifetime}, "))
322 }
323
324 (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => {
326 (self.ident.span, format!("{new_lifetime}"))
327 }
328
329 (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => {
331 (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
332 }
333
334 (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")),
336
337 (Implicit, source) => {
338 unreachable!("can't suggest for a implicit lifetime of {source:?}")
339 }
340 }
341 }
342}
343
344#[derive(Debug, Clone, Copy, HashStable_Generic)]
348pub struct Path<'hir, R = Res> {
349 pub span: Span,
350 pub res: R,
352 pub segments: &'hir [PathSegment<'hir>],
354}
355
356pub type UsePath<'hir> = Path<'hir, PerNS<Option<Res>>>;
358
359impl Path<'_> {
360 pub fn is_global(&self) -> bool {
361 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
362 }
363}
364
365#[derive(Debug, Clone, Copy, HashStable_Generic)]
368pub struct PathSegment<'hir> {
369 pub ident: Ident,
371 #[stable_hasher(ignore)]
372 pub hir_id: HirId,
373 pub res: Res,
374
375 pub args: Option<&'hir GenericArgs<'hir>>,
381
382 pub infer_args: bool,
387}
388
389impl<'hir> PathSegment<'hir> {
390 pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
392 PathSegment { ident, hir_id, res, infer_args: true, args: None }
393 }
394
395 pub fn invalid() -> Self {
396 Self::new(Ident::dummy(), HirId::INVALID, Res::Err)
397 }
398
399 pub fn args(&self) -> &GenericArgs<'hir> {
400 if let Some(ref args) = self.args {
401 args
402 } else {
403 const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
404 DUMMY
405 }
406 }
407}
408
409#[derive(Clone, Copy, Debug, HashStable_Generic)]
410pub enum ConstItemRhs<'hir> {
411 Body(BodyId),
412 TypeConst(&'hir ConstArg<'hir>),
413}
414
415impl<'hir> ConstItemRhs<'hir> {
416 pub fn hir_id(&self) -> HirId {
417 match self {
418 ConstItemRhs::Body(body_id) => body_id.hir_id,
419 ConstItemRhs::TypeConst(ct_arg) => ct_arg.hir_id,
420 }
421 }
422
423 pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span {
424 match self {
425 ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span,
426 ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(),
427 }
428 }
429}
430
431#[derive(Clone, Copy, Debug, HashStable_Generic)]
445#[repr(C)]
446pub struct ConstArg<'hir, Unambig = ()> {
447 #[stable_hasher(ignore)]
448 pub hir_id: HirId,
449 pub kind: ConstArgKind<'hir, Unambig>,
450}
451
452impl<'hir> ConstArg<'hir, AmbigArg> {
453 pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
464 let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
467 unsafe { &*ptr }
468 }
469}
470
471impl<'hir> ConstArg<'hir> {
472 pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
478 if let ConstArgKind::Infer(_, ()) = self.kind {
479 return None;
480 }
481
482 let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
486 Some(unsafe { &*ptr })
487 }
488}
489
490impl<'hir, Unambig> ConstArg<'hir, Unambig> {
491 pub fn anon_const_hir_id(&self) -> Option<HirId> {
492 match self.kind {
493 ConstArgKind::Anon(ac) => Some(ac.hir_id),
494 _ => None,
495 }
496 }
497
498 pub fn span(&self) -> Span {
499 match self.kind {
500 ConstArgKind::Struct(path, _) => path.span(),
501 ConstArgKind::Path(path) => path.span(),
502 ConstArgKind::Anon(anon) => anon.span,
503 ConstArgKind::Error(span, _) => span,
504 ConstArgKind::Infer(span, _) => span,
505 }
506 }
507}
508
509#[derive(Clone, Copy, Debug, HashStable_Generic)]
511#[repr(u8, C)]
512pub enum ConstArgKind<'hir, Unambig = ()> {
513 Path(QPath<'hir>),
519 Anon(&'hir AnonConst),
520 Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]),
522 Error(Span, ErrorGuaranteed),
524 Infer(Span, Unambig),
527}
528
529#[derive(Clone, Copy, Debug, HashStable_Generic)]
530pub struct ConstArgExprField<'hir> {
531 pub hir_id: HirId,
532 pub span: Span,
533 pub field: Ident,
534 pub expr: &'hir ConstArg<'hir>,
535}
536
537#[derive(Clone, Copy, Debug, HashStable_Generic)]
538pub struct InferArg {
539 #[stable_hasher(ignore)]
540 pub hir_id: HirId,
541 pub span: Span,
542}
543
544impl InferArg {
545 pub fn to_ty(&self) -> Ty<'static> {
546 Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
547 }
548}
549
550#[derive(Debug, Clone, Copy, HashStable_Generic)]
551pub enum GenericArg<'hir> {
552 Lifetime(&'hir Lifetime),
553 Type(&'hir Ty<'hir, AmbigArg>),
554 Const(&'hir ConstArg<'hir, AmbigArg>),
555 Infer(InferArg),
565}
566
567impl GenericArg<'_> {
568 pub fn span(&self) -> Span {
569 match self {
570 GenericArg::Lifetime(l) => l.ident.span,
571 GenericArg::Type(t) => t.span,
572 GenericArg::Const(c) => c.span(),
573 GenericArg::Infer(i) => i.span,
574 }
575 }
576
577 pub fn hir_id(&self) -> HirId {
578 match self {
579 GenericArg::Lifetime(l) => l.hir_id,
580 GenericArg::Type(t) => t.hir_id,
581 GenericArg::Const(c) => c.hir_id,
582 GenericArg::Infer(i) => i.hir_id,
583 }
584 }
585
586 pub fn descr(&self) -> &'static str {
587 match self {
588 GenericArg::Lifetime(_) => "lifetime",
589 GenericArg::Type(_) => "type",
590 GenericArg::Const(_) => "constant",
591 GenericArg::Infer(_) => "placeholder",
592 }
593 }
594
595 pub fn to_ord(&self) -> ast::ParamKindOrd {
596 match self {
597 GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
598 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
599 ast::ParamKindOrd::TypeOrConst
600 }
601 }
602 }
603
604 pub fn is_ty_or_const(&self) -> bool {
605 match self {
606 GenericArg::Lifetime(_) => false,
607 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
608 }
609 }
610}
611
612#[derive(Debug, Clone, Copy, HashStable_Generic)]
614pub struct GenericArgs<'hir> {
615 pub args: &'hir [GenericArg<'hir>],
617 pub constraints: &'hir [AssocItemConstraint<'hir>],
619 pub parenthesized: GenericArgsParentheses,
624 pub span_ext: Span,
637}
638
639impl<'hir> GenericArgs<'hir> {
640 pub const fn none() -> Self {
641 Self {
642 args: &[],
643 constraints: &[],
644 parenthesized: GenericArgsParentheses::No,
645 span_ext: DUMMY_SP,
646 }
647 }
648
649 pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
654 if self.parenthesized != GenericArgsParentheses::ParenSugar {
655 return None;
656 }
657
658 let inputs = self
659 .args
660 .iter()
661 .find_map(|arg| {
662 let GenericArg::Type(ty) = arg else { return None };
663 let TyKind::Tup(tys) = &ty.kind else { return None };
664 Some(tys)
665 })
666 .unwrap();
667
668 Some((inputs, self.paren_sugar_output_inner()))
669 }
670
671 pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
676 (self.parenthesized == GenericArgsParentheses::ParenSugar)
677 .then(|| self.paren_sugar_output_inner())
678 }
679
680 fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
681 let [constraint] = self.constraints.try_into().unwrap();
682 debug_assert_eq!(constraint.ident.name, sym::Output);
683 constraint.ty().unwrap()
684 }
685
686 pub fn has_err(&self) -> Option<ErrorGuaranteed> {
687 self.args
688 .iter()
689 .find_map(|arg| {
690 let GenericArg::Type(ty) = arg else { return None };
691 let TyKind::Err(guar) = ty.kind else { return None };
692 Some(guar)
693 })
694 .or_else(|| {
695 self.constraints.iter().find_map(|constraint| {
696 let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
697 Some(guar)
698 })
699 })
700 }
701
702 #[inline]
703 pub fn num_lifetime_params(&self) -> usize {
704 self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
705 }
706
707 #[inline]
708 pub fn has_lifetime_params(&self) -> bool {
709 self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
710 }
711
712 #[inline]
713 pub fn num_generic_params(&self) -> usize {
716 self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
717 }
718
719 pub fn span(&self) -> Option<Span> {
725 let span_ext = self.span_ext()?;
726 Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
727 }
728
729 pub fn span_ext(&self) -> Option<Span> {
731 Some(self.span_ext).filter(|span| !span.is_empty())
732 }
733
734 pub fn is_empty(&self) -> bool {
735 self.args.is_empty()
736 }
737}
738
739#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
740pub enum GenericArgsParentheses {
741 No,
742 ReturnTypeNotation,
745 ParenSugar,
747}
748
749#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
751pub struct TraitBoundModifiers {
752 pub constness: BoundConstness,
753 pub polarity: BoundPolarity,
754}
755
756impl TraitBoundModifiers {
757 pub const NONE: Self =
758 TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
759}
760
761#[derive(Clone, Copy, Debug, HashStable_Generic)]
762pub enum GenericBound<'hir> {
763 Trait(PolyTraitRef<'hir>),
764 Outlives(&'hir Lifetime),
765 Use(&'hir [PreciseCapturingArg<'hir>], Span),
766}
767
768impl GenericBound<'_> {
769 pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
770 match self {
771 GenericBound::Trait(data) => Some(&data.trait_ref),
772 _ => None,
773 }
774 }
775
776 pub fn span(&self) -> Span {
777 match self {
778 GenericBound::Trait(t, ..) => t.span,
779 GenericBound::Outlives(l) => l.ident.span,
780 GenericBound::Use(_, span) => *span,
781 }
782 }
783}
784
785pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
786
787#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
788pub enum MissingLifetimeKind {
789 Underscore,
791 Ampersand,
793 Comma,
795 Brackets,
797}
798
799#[derive(Copy, Clone, Debug, HashStable_Generic)]
800pub enum LifetimeParamKind {
801 Explicit,
804
805 Elided(MissingLifetimeKind),
808
809 Error,
811}
812
813#[derive(Debug, Clone, Copy, HashStable_Generic)]
814pub enum GenericParamKind<'hir> {
815 Lifetime {
817 kind: LifetimeParamKind,
818 },
819 Type {
820 default: Option<&'hir Ty<'hir>>,
821 synthetic: bool,
822 },
823 Const {
824 ty: &'hir Ty<'hir>,
825 default: Option<&'hir ConstArg<'hir>>,
827 },
828}
829
830#[derive(Debug, Clone, Copy, HashStable_Generic)]
831pub struct GenericParam<'hir> {
832 #[stable_hasher(ignore)]
833 pub hir_id: HirId,
834 pub def_id: LocalDefId,
835 pub name: ParamName,
836 pub span: Span,
837 pub pure_wrt_drop: bool,
838 pub kind: GenericParamKind<'hir>,
839 pub colon_span: Option<Span>,
840 pub source: GenericParamSource,
841}
842
843impl<'hir> GenericParam<'hir> {
844 pub fn is_impl_trait(&self) -> bool {
848 matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
849 }
850
851 pub fn is_elided_lifetime(&self) -> bool {
855 matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
856 }
857}
858
859#[derive(Debug, Clone, Copy, HashStable_Generic)]
866pub enum GenericParamSource {
867 Generics,
869 Binder,
871}
872
873#[derive(Default)]
874pub struct GenericParamCount {
875 pub lifetimes: usize,
876 pub types: usize,
877 pub consts: usize,
878 pub infer: usize,
879}
880
881#[derive(Debug, Clone, Copy, HashStable_Generic)]
884pub struct Generics<'hir> {
885 pub params: &'hir [GenericParam<'hir>],
886 pub predicates: &'hir [WherePredicate<'hir>],
887 pub has_where_clause_predicates: bool,
888 pub where_clause_span: Span,
889 pub span: Span,
890}
891
892impl<'hir> Generics<'hir> {
893 pub const fn empty() -> &'hir Generics<'hir> {
894 const NOPE: Generics<'_> = Generics {
895 params: &[],
896 predicates: &[],
897 has_where_clause_predicates: false,
898 where_clause_span: DUMMY_SP,
899 span: DUMMY_SP,
900 };
901 &NOPE
902 }
903
904 pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
905 self.params.iter().find(|¶m| name == param.name.ident().name)
906 }
907
908 pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
910 if let Some(first) = self.params.first()
911 && self.span.contains(first.span)
912 {
913 Some(first.span.shrink_to_lo())
916 } else {
917 None
918 }
919 }
920
921 pub fn span_for_param_suggestion(&self) -> Option<Span> {
923 self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
924 self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
927 })
928 }
929
930 pub fn tail_span_for_predicate_suggestion(&self) -> Span {
933 let end = self.where_clause_span.shrink_to_hi();
934 if self.has_where_clause_predicates {
935 self.predicates
936 .iter()
937 .rfind(|&p| p.kind.in_where_clause())
938 .map_or(end, |p| p.span)
939 .shrink_to_hi()
940 .to(end)
941 } else {
942 end
943 }
944 }
945
946 pub fn add_where_or_trailing_comma(&self) -> &'static str {
947 if self.has_where_clause_predicates {
948 ","
949 } else if self.where_clause_span.is_empty() {
950 " where"
951 } else {
952 ""
954 }
955 }
956
957 pub fn bounds_for_param(
958 &self,
959 param_def_id: LocalDefId,
960 ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
961 self.predicates.iter().filter_map(move |pred| match pred.kind {
962 WherePredicateKind::BoundPredicate(bp)
963 if bp.is_param_bound(param_def_id.to_def_id()) =>
964 {
965 Some(bp)
966 }
967 _ => None,
968 })
969 }
970
971 pub fn outlives_for_param(
972 &self,
973 param_def_id: LocalDefId,
974 ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
975 self.predicates.iter().filter_map(move |pred| match pred.kind {
976 WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
977 _ => None,
978 })
979 }
980
981 pub fn bounds_span_for_suggestions(
992 &self,
993 param_def_id: LocalDefId,
994 ) -> Option<(Span, Option<Span>)> {
995 self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
996 |bound| {
997 let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
998 && let [.., segment] = trait_ref.path.segments
999 && let Some(ret_ty) = segment.args().paren_sugar_output()
1000 && let ret_ty = ret_ty.peel_refs()
1001 && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
1002 && let TraitObjectSyntax::Dyn = tagged_ptr.tag()
1003 && ret_ty.span.can_be_used_for_suggestions()
1004 {
1005 Some(ret_ty.span)
1006 } else {
1007 None
1008 };
1009
1010 span_for_parentheses.map_or_else(
1011 || {
1012 let bs = bound.span();
1015 bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
1016 },
1017 |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
1018 )
1019 },
1020 )
1021 }
1022
1023 pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
1024 let predicate = &self.predicates[pos];
1025 let span = predicate.span;
1026
1027 if !predicate.kind.in_where_clause() {
1028 return span;
1031 }
1032
1033 if pos < self.predicates.len() - 1 {
1035 let next_pred = &self.predicates[pos + 1];
1036 if next_pred.kind.in_where_clause() {
1037 return span.until(next_pred.span);
1040 }
1041 }
1042
1043 if pos > 0 {
1044 let prev_pred = &self.predicates[pos - 1];
1045 if prev_pred.kind.in_where_clause() {
1046 return prev_pred.span.shrink_to_hi().to(span);
1049 }
1050 }
1051
1052 self.where_clause_span
1056 }
1057
1058 pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
1059 let predicate = &self.predicates[predicate_pos];
1060 let bounds = predicate.kind.bounds();
1061
1062 if bounds.len() == 1 {
1063 return self.span_for_predicate_removal(predicate_pos);
1064 }
1065
1066 let bound_span = bounds[bound_pos].span();
1067 if bound_pos < bounds.len() - 1 {
1068 bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
1074 } else {
1075 bound_span.with_lo(bounds[bound_pos - 1].span().hi())
1081 }
1082 }
1083}
1084
1085#[derive(Debug, Clone, Copy, HashStable_Generic)]
1087pub struct WherePredicate<'hir> {
1088 #[stable_hasher(ignore)]
1089 pub hir_id: HirId,
1090 pub span: Span,
1091 pub kind: &'hir WherePredicateKind<'hir>,
1092}
1093
1094#[derive(Debug, Clone, Copy, HashStable_Generic)]
1096pub enum WherePredicateKind<'hir> {
1097 BoundPredicate(WhereBoundPredicate<'hir>),
1099 RegionPredicate(WhereRegionPredicate<'hir>),
1101 EqPredicate(WhereEqPredicate<'hir>),
1103}
1104
1105impl<'hir> WherePredicateKind<'hir> {
1106 pub fn in_where_clause(&self) -> bool {
1107 match self {
1108 WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
1109 WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
1110 WherePredicateKind::EqPredicate(_) => false,
1111 }
1112 }
1113
1114 pub fn bounds(&self) -> GenericBounds<'hir> {
1115 match self {
1116 WherePredicateKind::BoundPredicate(p) => p.bounds,
1117 WherePredicateKind::RegionPredicate(p) => p.bounds,
1118 WherePredicateKind::EqPredicate(_) => &[],
1119 }
1120 }
1121}
1122
1123#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
1124pub enum PredicateOrigin {
1125 WhereClause,
1126 GenericParam,
1127 ImplTrait,
1128}
1129
1130#[derive(Debug, Clone, Copy, HashStable_Generic)]
1132pub struct WhereBoundPredicate<'hir> {
1133 pub origin: PredicateOrigin,
1135 pub bound_generic_params: &'hir [GenericParam<'hir>],
1137 pub bounded_ty: &'hir Ty<'hir>,
1139 pub bounds: GenericBounds<'hir>,
1141}
1142
1143impl<'hir> WhereBoundPredicate<'hir> {
1144 pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
1146 self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
1147 }
1148}
1149
1150#[derive(Debug, Clone, Copy, HashStable_Generic)]
1152pub struct WhereRegionPredicate<'hir> {
1153 pub in_where_clause: bool,
1154 pub lifetime: &'hir Lifetime,
1155 pub bounds: GenericBounds<'hir>,
1156}
1157
1158impl<'hir> WhereRegionPredicate<'hir> {
1159 fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
1161 self.lifetime.kind == LifetimeKind::Param(param_def_id)
1162 }
1163}
1164
1165#[derive(Debug, Clone, Copy, HashStable_Generic)]
1167pub struct WhereEqPredicate<'hir> {
1168 pub lhs_ty: &'hir Ty<'hir>,
1169 pub rhs_ty: &'hir Ty<'hir>,
1170}
1171
1172#[derive(Clone, Copy, Debug)]
1176pub struct ParentedNode<'tcx> {
1177 pub parent: ItemLocalId,
1178 pub node: Node<'tcx>,
1179}
1180
1181#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1183pub enum AttrArgs {
1184 Empty,
1186 Delimited(DelimArgs),
1188 Eq {
1190 eq_span: Span,
1192 expr: MetaItemLit,
1194 },
1195}
1196
1197#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1198pub struct AttrPath {
1199 pub segments: Box<[Ident]>,
1200 pub span: Span,
1201}
1202
1203impl IntoDiagArg for AttrPath {
1204 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1205 self.to_string().into_diag_arg(path)
1206 }
1207}
1208
1209impl AttrPath {
1210 pub fn from_ast(path: &ast::Path, lower_span: impl Copy + Fn(Span) -> Span) -> Self {
1211 AttrPath {
1212 segments: path
1213 .segments
1214 .iter()
1215 .map(|i| Ident { name: i.ident.name, span: lower_span(i.ident.span) })
1216 .collect::<Vec<_>>()
1217 .into_boxed_slice(),
1218 span: lower_span(path.span),
1219 }
1220 }
1221}
1222
1223impl fmt::Display for AttrPath {
1224 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1225 write!(f, "{}", join_path_idents(&self.segments))
1226 }
1227}
1228
1229#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1230pub struct AttrItem {
1231 pub path: AttrPath,
1233 pub args: AttrArgs,
1234 pub id: HashIgnoredAttrId,
1235 pub style: AttrStyle,
1238 pub span: Span,
1240}
1241
1242#[derive(Copy, Debug, Encodable, Decodable, Clone)]
1245pub struct HashIgnoredAttrId {
1246 pub attr_id: AttrId,
1247}
1248
1249#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
1250pub enum Attribute {
1251 Parsed(AttributeKind),
1257
1258 Unparsed(Box<AttrItem>),
1261}
1262
1263impl Attribute {
1264 pub fn get_normal_item(&self) -> &AttrItem {
1265 match &self {
1266 Attribute::Unparsed(normal) => &normal,
1267 _ => panic!("unexpected parsed attribute"),
1268 }
1269 }
1270
1271 pub fn unwrap_normal_item(self) -> AttrItem {
1272 match self {
1273 Attribute::Unparsed(normal) => *normal,
1274 _ => panic!("unexpected parsed attribute"),
1275 }
1276 }
1277
1278 pub fn value_lit(&self) -> Option<&MetaItemLit> {
1279 match &self {
1280 Attribute::Unparsed(n) => match n.as_ref() {
1281 AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1282 _ => None,
1283 },
1284 _ => None,
1285 }
1286 }
1287
1288 pub fn is_parsed_attr(&self) -> bool {
1289 match self {
1290 Attribute::Parsed(_) => true,
1291 Attribute::Unparsed(_) => false,
1292 }
1293 }
1294}
1295
1296impl AttributeExt for Attribute {
1297 #[inline]
1298 fn id(&self) -> AttrId {
1299 match &self {
1300 Attribute::Unparsed(u) => u.id.attr_id,
1301 _ => panic!(),
1302 }
1303 }
1304
1305 #[inline]
1306 fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1307 match &self {
1308 Attribute::Unparsed(n) => match n.as_ref() {
1309 AttrItem { args: AttrArgs::Delimited(d), .. } => {
1310 ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1311 }
1312 _ => None,
1313 },
1314 _ => None,
1315 }
1316 }
1317
1318 #[inline]
1319 fn value_str(&self) -> Option<Symbol> {
1320 self.value_lit().and_then(|x| x.value_str())
1321 }
1322
1323 #[inline]
1324 fn value_span(&self) -> Option<Span> {
1325 self.value_lit().map(|i| i.span)
1326 }
1327
1328 #[inline]
1330 fn ident(&self) -> Option<Ident> {
1331 match &self {
1332 Attribute::Unparsed(n) => {
1333 if let [ident] = n.path.segments.as_ref() {
1334 Some(*ident)
1335 } else {
1336 None
1337 }
1338 }
1339 _ => None,
1340 }
1341 }
1342
1343 #[inline]
1344 fn path_matches(&self, name: &[Symbol]) -> bool {
1345 match &self {
1346 Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name),
1347 _ => false,
1348 }
1349 }
1350
1351 #[inline]
1352 fn is_doc_comment(&self) -> Option<Span> {
1353 if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self {
1354 Some(*span)
1355 } else {
1356 None
1357 }
1358 }
1359
1360 #[inline]
1361 fn span(&self) -> Span {
1362 match &self {
1363 Attribute::Unparsed(u) => u.span,
1364 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1366 Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
1367 a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
1368 }
1369 }
1370
1371 #[inline]
1372 fn is_word(&self) -> bool {
1373 match &self {
1374 Attribute::Unparsed(n) => {
1375 matches!(n.args, AttrArgs::Empty)
1376 }
1377 _ => false,
1378 }
1379 }
1380
1381 #[inline]
1382 fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1383 match &self {
1384 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
1385 _ => None,
1386 }
1387 }
1388
1389 #[inline]
1390 fn doc_str(&self) -> Option<Symbol> {
1391 match &self {
1392 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
1393 _ => None,
1394 }
1395 }
1396
1397 fn is_automatically_derived_attr(&self) -> bool {
1398 matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
1399 }
1400
1401 #[inline]
1402 fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> {
1403 match &self {
1404 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
1405 Some((*comment, *kind))
1406 }
1407 _ => None,
1408 }
1409 }
1410
1411 fn doc_resolution_scope(&self) -> Option<AttrStyle> {
1412 match self {
1413 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
1414 Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
1415 Some(attr.style)
1416 }
1417 _ => None,
1418 }
1419 }
1420
1421 fn is_proc_macro_attr(&self) -> bool {
1422 matches!(
1423 self,
1424 Attribute::Parsed(
1425 AttributeKind::ProcMacro(..)
1426 | AttributeKind::ProcMacroAttribute(..)
1427 | AttributeKind::ProcMacroDerive { .. }
1428 )
1429 )
1430 }
1431
1432 fn is_doc_hidden(&self) -> bool {
1433 matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some())
1434 }
1435
1436 fn is_doc_keyword_or_attribute(&self) -> bool {
1437 matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some())
1438 }
1439}
1440
1441impl Attribute {
1443 #[inline]
1444 pub fn id(&self) -> AttrId {
1445 AttributeExt::id(self)
1446 }
1447
1448 #[inline]
1449 pub fn name(&self) -> Option<Symbol> {
1450 AttributeExt::name(self)
1451 }
1452
1453 #[inline]
1454 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1455 AttributeExt::meta_item_list(self)
1456 }
1457
1458 #[inline]
1459 pub fn value_str(&self) -> Option<Symbol> {
1460 AttributeExt::value_str(self)
1461 }
1462
1463 #[inline]
1464 pub fn value_span(&self) -> Option<Span> {
1465 AttributeExt::value_span(self)
1466 }
1467
1468 #[inline]
1469 pub fn ident(&self) -> Option<Ident> {
1470 AttributeExt::ident(self)
1471 }
1472
1473 #[inline]
1474 pub fn path_matches(&self, name: &[Symbol]) -> bool {
1475 AttributeExt::path_matches(self, name)
1476 }
1477
1478 #[inline]
1479 pub fn is_doc_comment(&self) -> Option<Span> {
1480 AttributeExt::is_doc_comment(self)
1481 }
1482
1483 #[inline]
1484 pub fn has_name(&self, name: Symbol) -> bool {
1485 AttributeExt::has_name(self, name)
1486 }
1487
1488 #[inline]
1489 pub fn has_any_name(&self, names: &[Symbol]) -> bool {
1490 AttributeExt::has_any_name(self, names)
1491 }
1492
1493 #[inline]
1494 pub fn span(&self) -> Span {
1495 AttributeExt::span(self)
1496 }
1497
1498 #[inline]
1499 pub fn is_word(&self) -> bool {
1500 AttributeExt::is_word(self)
1501 }
1502
1503 #[inline]
1504 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1505 AttributeExt::path(self)
1506 }
1507
1508 #[inline]
1509 pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1510 AttributeExt::ident_path(self)
1511 }
1512
1513 #[inline]
1514 pub fn doc_str(&self) -> Option<Symbol> {
1515 AttributeExt::doc_str(self)
1516 }
1517
1518 #[inline]
1519 pub fn is_proc_macro_attr(&self) -> bool {
1520 AttributeExt::is_proc_macro_attr(self)
1521 }
1522
1523 #[inline]
1524 pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> {
1525 AttributeExt::doc_str_and_fragment_kind(self)
1526 }
1527}
1528
1529#[derive(Debug)]
1531pub struct AttributeMap<'tcx> {
1532 pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1533 pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
1535 pub opt_hash: Option<Fingerprint>,
1537}
1538
1539impl<'tcx> AttributeMap<'tcx> {
1540 pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1541 map: SortedMap::new(),
1542 opt_hash: Some(Fingerprint::ZERO),
1543 define_opaque: None,
1544 };
1545
1546 #[inline]
1547 pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1548 self.map.get(&id).copied().unwrap_or(&[])
1549 }
1550}
1551
1552pub struct OwnerNodes<'tcx> {
1556 pub opt_hash_including_bodies: Option<Fingerprint>,
1559 pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1564 pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1566}
1567
1568impl<'tcx> OwnerNodes<'tcx> {
1569 pub fn node(&self) -> OwnerNode<'tcx> {
1570 self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1572 }
1573}
1574
1575impl fmt::Debug for OwnerNodes<'_> {
1576 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1577 f.debug_struct("OwnerNodes")
1578 .field("node", &self.nodes[ItemLocalId::ZERO])
1580 .field(
1581 "parents",
1582 &fmt::from_fn(|f| {
1583 f.debug_list()
1584 .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1585 fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1586 }))
1587 .finish()
1588 }),
1589 )
1590 .field("bodies", &self.bodies)
1591 .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1592 .finish()
1593 }
1594}
1595
1596#[derive(Debug, HashStable_Generic)]
1598pub struct OwnerInfo<'hir> {
1599 pub nodes: OwnerNodes<'hir>,
1601 pub parenting: LocalDefIdMap<ItemLocalId>,
1603 pub attrs: AttributeMap<'hir>,
1605 pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1608
1609 pub delayed_lints: DelayedLints,
1612}
1613
1614impl<'tcx> OwnerInfo<'tcx> {
1615 #[inline]
1616 pub fn node(&self) -> OwnerNode<'tcx> {
1617 self.nodes.node()
1618 }
1619}
1620
1621#[derive(Copy, Clone, Debug, HashStable_Generic)]
1622pub enum MaybeOwner<'tcx> {
1623 Owner(&'tcx OwnerInfo<'tcx>),
1624 NonOwner(HirId),
1625 Phantom,
1627}
1628
1629impl<'tcx> MaybeOwner<'tcx> {
1630 pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1631 match self {
1632 MaybeOwner::Owner(i) => Some(i),
1633 MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1634 }
1635 }
1636
1637 pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1638 self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1639 }
1640}
1641
1642#[derive(Debug)]
1649pub struct Crate<'hir> {
1650 pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1651 pub opt_hir_hash: Option<Fingerprint>,
1653}
1654
1655#[derive(Debug, Clone, Copy, HashStable_Generic)]
1656pub struct Closure<'hir> {
1657 pub def_id: LocalDefId,
1658 pub binder: ClosureBinder,
1659 pub constness: Constness,
1660 pub capture_clause: CaptureBy,
1661 pub bound_generic_params: &'hir [GenericParam<'hir>],
1662 pub fn_decl: &'hir FnDecl<'hir>,
1663 pub body: BodyId,
1664 pub fn_decl_span: Span,
1666 pub fn_arg_span: Option<Span>,
1668 pub kind: ClosureKind,
1669}
1670
1671#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1672pub enum ClosureKind {
1673 Closure,
1675 Coroutine(CoroutineKind),
1680 CoroutineClosure(CoroutineDesugaring),
1685}
1686
1687#[derive(Debug, Clone, Copy, HashStable_Generic)]
1691pub struct Block<'hir> {
1692 pub stmts: &'hir [Stmt<'hir>],
1694 pub expr: Option<&'hir Expr<'hir>>,
1697 #[stable_hasher(ignore)]
1698 pub hir_id: HirId,
1699 pub rules: BlockCheckMode,
1701 pub span: Span,
1703 pub targeted_by_break: bool,
1707}
1708
1709impl<'hir> Block<'hir> {
1710 pub fn innermost_block(&self) -> &Block<'hir> {
1711 let mut block = self;
1712 while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1713 block = inner_block;
1714 }
1715 block
1716 }
1717}
1718
1719#[derive(Debug, Clone, Copy, HashStable_Generic)]
1720pub struct TyPat<'hir> {
1721 #[stable_hasher(ignore)]
1722 pub hir_id: HirId,
1723 pub kind: TyPatKind<'hir>,
1724 pub span: Span,
1725}
1726
1727#[derive(Debug, Clone, Copy, HashStable_Generic)]
1728pub struct Pat<'hir> {
1729 #[stable_hasher(ignore)]
1730 pub hir_id: HirId,
1731 pub kind: PatKind<'hir>,
1732 pub span: Span,
1733 pub default_binding_modes: bool,
1736}
1737
1738impl<'hir> Pat<'hir> {
1739 fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1740 if !it(self) {
1741 return false;
1742 }
1743
1744 use PatKind::*;
1745 match self.kind {
1746 Missing => unreachable!(),
1747 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1748 Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => {
1749 s.walk_short_(it)
1750 }
1751 Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1752 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1753 Slice(before, slice, after) => {
1754 before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1755 }
1756 }
1757 }
1758
1759 pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1766 self.walk_short_(&mut it)
1767 }
1768
1769 fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1770 if !it(self) {
1771 return;
1772 }
1773
1774 use PatKind::*;
1775 match self.kind {
1776 Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1777 Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1778 Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1779 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1780 Slice(before, slice, after) => {
1781 before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1782 }
1783 }
1784 }
1785
1786 pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1790 self.walk_(&mut it)
1791 }
1792
1793 pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1797 self.walk(|p| {
1798 it(p);
1799 true
1800 })
1801 }
1802
1803 pub fn is_never_pattern(&self) -> bool {
1805 let mut is_never_pattern = false;
1806 self.walk(|pat| match &pat.kind {
1807 PatKind::Never => {
1808 is_never_pattern = true;
1809 false
1810 }
1811 PatKind::Or(s) => {
1812 is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1813 false
1814 }
1815 _ => true,
1816 });
1817 is_never_pattern
1818 }
1819
1820 pub fn is_guaranteed_to_constitute_read_for_never(&self) -> bool {
1829 match self.kind {
1830 PatKind::Wild => false,
1832
1833 PatKind::Guard(pat, _) => pat.is_guaranteed_to_constitute_read_for_never(),
1836
1837 PatKind::Or(subpats) => {
1846 subpats.iter().all(|pat| pat.is_guaranteed_to_constitute_read_for_never())
1847 }
1848
1849 PatKind::Never => true,
1851
1852 PatKind::Missing
1855 | PatKind::Binding(_, _, _, _)
1856 | PatKind::Struct(_, _, _)
1857 | PatKind::TupleStruct(_, _, _)
1858 | PatKind::Tuple(_, _)
1859 | PatKind::Box(_)
1860 | PatKind::Ref(_, _, _)
1861 | PatKind::Deref(_)
1862 | PatKind::Expr(_)
1863 | PatKind::Range(_, _, _)
1864 | PatKind::Slice(_, _, _)
1865 | PatKind::Err(_) => true,
1866 }
1867 }
1868}
1869
1870#[derive(Debug, Clone, Copy, HashStable_Generic)]
1876pub struct PatField<'hir> {
1877 #[stable_hasher(ignore)]
1878 pub hir_id: HirId,
1879 pub ident: Ident,
1881 pub pat: &'hir Pat<'hir>,
1883 pub is_shorthand: bool,
1884 pub span: Span,
1885}
1886
1887#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
1888pub enum RangeEnd {
1889 Included,
1890 Excluded,
1891}
1892
1893impl fmt::Display for RangeEnd {
1894 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1895 f.write_str(match self {
1896 RangeEnd::Included => "..=",
1897 RangeEnd::Excluded => "..",
1898 })
1899 }
1900}
1901
1902#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1906pub struct DotDotPos(u32);
1907
1908impl DotDotPos {
1909 pub fn new(n: Option<usize>) -> Self {
1911 match n {
1912 Some(n) => {
1913 assert!(n < u32::MAX as usize);
1914 Self(n as u32)
1915 }
1916 None => Self(u32::MAX),
1917 }
1918 }
1919
1920 pub fn as_opt_usize(&self) -> Option<usize> {
1921 if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1922 }
1923}
1924
1925impl fmt::Debug for DotDotPos {
1926 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1927 self.as_opt_usize().fmt(f)
1928 }
1929}
1930
1931#[derive(Debug, Clone, Copy, HashStable_Generic)]
1932pub struct PatExpr<'hir> {
1933 #[stable_hasher(ignore)]
1934 pub hir_id: HirId,
1935 pub span: Span,
1936 pub kind: PatExprKind<'hir>,
1937}
1938
1939#[derive(Debug, Clone, Copy, HashStable_Generic)]
1940pub enum PatExprKind<'hir> {
1941 Lit {
1942 lit: Lit,
1943 negated: bool,
1946 },
1947 ConstBlock(ConstBlock),
1948 Path(QPath<'hir>),
1950}
1951
1952#[derive(Debug, Clone, Copy, HashStable_Generic)]
1953pub enum TyPatKind<'hir> {
1954 Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
1956
1957 NotNull,
1959
1960 Or(&'hir [TyPat<'hir>]),
1962
1963 Err(ErrorGuaranteed),
1965}
1966
1967#[derive(Debug, Clone, Copy, HashStable_Generic)]
1968pub enum PatKind<'hir> {
1969 Missing,
1971
1972 Wild,
1974
1975 Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1986
1987 Struct(QPath<'hir>, &'hir [PatField<'hir>], Option<Span>),
1990
1991 TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1995
1996 Or(&'hir [Pat<'hir>]),
1999
2000 Never,
2002
2003 Tuple(&'hir [Pat<'hir>], DotDotPos),
2007
2008 Box(&'hir Pat<'hir>),
2010
2011 Deref(&'hir Pat<'hir>),
2013
2014 Ref(&'hir Pat<'hir>, Pinnedness, Mutability),
2016
2017 Expr(&'hir PatExpr<'hir>),
2019
2020 Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
2022
2023 Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
2025
2026 Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
2036
2037 Err(ErrorGuaranteed),
2039}
2040
2041#[derive(Debug, Clone, Copy, HashStable_Generic)]
2043pub struct Stmt<'hir> {
2044 #[stable_hasher(ignore)]
2045 pub hir_id: HirId,
2046 pub kind: StmtKind<'hir>,
2047 pub span: Span,
2048}
2049
2050#[derive(Debug, Clone, Copy, HashStable_Generic)]
2052pub enum StmtKind<'hir> {
2053 Let(&'hir LetStmt<'hir>),
2055
2056 Item(ItemId),
2058
2059 Expr(&'hir Expr<'hir>),
2061
2062 Semi(&'hir Expr<'hir>),
2064}
2065
2066#[derive(Debug, Clone, Copy, HashStable_Generic)]
2068pub struct LetStmt<'hir> {
2069 pub super_: Option<Span>,
2071 pub pat: &'hir Pat<'hir>,
2072 pub ty: Option<&'hir Ty<'hir>>,
2074 pub init: Option<&'hir Expr<'hir>>,
2076 pub els: Option<&'hir Block<'hir>>,
2078 #[stable_hasher(ignore)]
2079 pub hir_id: HirId,
2080 pub span: Span,
2081 pub source: LocalSource,
2085}
2086
2087#[derive(Debug, Clone, Copy, HashStable_Generic)]
2090pub struct Arm<'hir> {
2091 #[stable_hasher(ignore)]
2092 pub hir_id: HirId,
2093 pub span: Span,
2094 pub pat: &'hir Pat<'hir>,
2096 pub guard: Option<&'hir Expr<'hir>>,
2098 pub body: &'hir Expr<'hir>,
2100}
2101
2102#[derive(Debug, Clone, Copy, HashStable_Generic)]
2108pub struct LetExpr<'hir> {
2109 pub span: Span,
2110 pub pat: &'hir Pat<'hir>,
2111 pub ty: Option<&'hir Ty<'hir>>,
2112 pub init: &'hir Expr<'hir>,
2113 pub recovered: ast::Recovered,
2116}
2117
2118#[derive(Debug, Clone, Copy, HashStable_Generic)]
2119pub struct ExprField<'hir> {
2120 #[stable_hasher(ignore)]
2121 pub hir_id: HirId,
2122 pub ident: Ident,
2123 pub expr: &'hir Expr<'hir>,
2124 pub span: Span,
2125 pub is_shorthand: bool,
2126}
2127
2128#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2129pub enum BlockCheckMode {
2130 DefaultBlock,
2131 UnsafeBlock(UnsafeSource),
2132}
2133
2134#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2135pub enum UnsafeSource {
2136 CompilerGenerated,
2137 UserProvided,
2138}
2139
2140#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
2141pub struct BodyId {
2142 pub hir_id: HirId,
2143}
2144
2145#[derive(Debug, Clone, Copy, HashStable_Generic)]
2167pub struct Body<'hir> {
2168 pub params: &'hir [Param<'hir>],
2169 pub value: &'hir Expr<'hir>,
2170}
2171
2172impl<'hir> Body<'hir> {
2173 pub fn id(&self) -> BodyId {
2174 BodyId { hir_id: self.value.hir_id }
2175 }
2176}
2177
2178#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2180pub enum CoroutineKind {
2181 Desugared(CoroutineDesugaring, CoroutineSource),
2183
2184 Coroutine(Movability),
2186}
2187
2188impl CoroutineKind {
2189 pub fn movability(self) -> Movability {
2190 match self {
2191 CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
2192 | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
2193 CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
2194 CoroutineKind::Coroutine(mov) => mov,
2195 }
2196 }
2197
2198 pub fn is_fn_like(self) -> bool {
2199 matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
2200 }
2201
2202 pub fn to_plural_string(&self) -> String {
2203 match self {
2204 CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"),
2205 CoroutineKind::Desugared(d, CoroutineSource::Block) => format!("{d:#}blocks"),
2206 CoroutineKind::Desugared(d, CoroutineSource::Closure) => format!("{d:#}closure bodies"),
2207 CoroutineKind::Coroutine(_) => "coroutines".to_string(),
2208 }
2209 }
2210}
2211
2212impl fmt::Display for CoroutineKind {
2213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2214 match self {
2215 CoroutineKind::Desugared(d, k) => {
2216 d.fmt(f)?;
2217 k.fmt(f)
2218 }
2219 CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
2220 }
2221 }
2222}
2223
2224#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
2230pub enum CoroutineSource {
2231 Block,
2233
2234 Closure,
2236
2237 Fn,
2239}
2240
2241impl fmt::Display for CoroutineSource {
2242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2243 match self {
2244 CoroutineSource::Block => "block",
2245 CoroutineSource::Closure => "closure body",
2246 CoroutineSource::Fn => "fn body",
2247 }
2248 .fmt(f)
2249 }
2250}
2251
2252#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2253pub enum CoroutineDesugaring {
2254 Async,
2256
2257 Gen,
2259
2260 AsyncGen,
2263}
2264
2265impl fmt::Display for CoroutineDesugaring {
2266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2267 match self {
2268 CoroutineDesugaring::Async => {
2269 if f.alternate() {
2270 f.write_str("`async` ")?;
2271 } else {
2272 f.write_str("async ")?
2273 }
2274 }
2275 CoroutineDesugaring::Gen => {
2276 if f.alternate() {
2277 f.write_str("`gen` ")?;
2278 } else {
2279 f.write_str("gen ")?
2280 }
2281 }
2282 CoroutineDesugaring::AsyncGen => {
2283 if f.alternate() {
2284 f.write_str("`async gen` ")?;
2285 } else {
2286 f.write_str("async gen ")?
2287 }
2288 }
2289 }
2290
2291 Ok(())
2292 }
2293}
2294
2295#[derive(Copy, Clone, Debug)]
2296pub enum BodyOwnerKind {
2297 Fn,
2299
2300 Closure,
2302
2303 Const { inline: bool },
2305
2306 Static(Mutability),
2308
2309 GlobalAsm,
2311}
2312
2313impl BodyOwnerKind {
2314 pub fn is_fn_or_closure(self) -> bool {
2315 match self {
2316 BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
2317 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
2318 false
2319 }
2320 }
2321 }
2322}
2323
2324#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2326pub enum ConstContext {
2327 ConstFn,
2329
2330 Static(Mutability),
2332
2333 Const { inline: bool },
2343}
2344
2345impl ConstContext {
2346 pub fn keyword_name(self) -> &'static str {
2350 match self {
2351 Self::Const { .. } => "const",
2352 Self::Static(Mutability::Not) => "static",
2353 Self::Static(Mutability::Mut) => "static mut",
2354 Self::ConstFn => "const fn",
2355 }
2356 }
2357}
2358
2359impl fmt::Display for ConstContext {
2362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2363 match *self {
2364 Self::Const { .. } => write!(f, "constant"),
2365 Self::Static(_) => write!(f, "static"),
2366 Self::ConstFn => write!(f, "constant function"),
2367 }
2368 }
2369}
2370
2371impl IntoDiagArg for ConstContext {
2372 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
2373 DiagArgValue::Str(Cow::Borrowed(match self {
2374 ConstContext::ConstFn => "const_fn",
2375 ConstContext::Static(_) => "static",
2376 ConstContext::Const { .. } => "const",
2377 }))
2378 }
2379}
2380
2381pub type Lit = Spanned<LitKind>;
2383
2384#[derive(Copy, Clone, Debug, HashStable_Generic)]
2393pub struct AnonConst {
2394 #[stable_hasher(ignore)]
2395 pub hir_id: HirId,
2396 pub def_id: LocalDefId,
2397 pub body: BodyId,
2398 pub span: Span,
2399}
2400
2401#[derive(Copy, Clone, Debug, HashStable_Generic)]
2403pub struct ConstBlock {
2404 #[stable_hasher(ignore)]
2405 pub hir_id: HirId,
2406 pub def_id: LocalDefId,
2407 pub body: BodyId,
2408}
2409
2410#[derive(Debug, Clone, Copy, HashStable_Generic)]
2419pub struct Expr<'hir> {
2420 #[stable_hasher(ignore)]
2421 pub hir_id: HirId,
2422 pub kind: ExprKind<'hir>,
2423 pub span: Span,
2424}
2425
2426impl Expr<'_> {
2427 pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence {
2428 let prefix_attrs_precedence = || -> ExprPrecedence {
2429 if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
2430 };
2431
2432 match &self.kind {
2433 ExprKind::Closure(closure) => {
2434 match closure.fn_decl.output {
2435 FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2436 FnRetTy::Return(_) => prefix_attrs_precedence(),
2437 }
2438 }
2439
2440 ExprKind::Break(..)
2441 | ExprKind::Ret(..)
2442 | ExprKind::Yield(..)
2443 | ExprKind::Become(..) => ExprPrecedence::Jump,
2444
2445 ExprKind::Binary(op, ..) => op.node.precedence(),
2447 ExprKind::Cast(..) => ExprPrecedence::Cast,
2448
2449 ExprKind::Assign(..) |
2450 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2451
2452 ExprKind::AddrOf(..)
2454 | ExprKind::Let(..)
2459 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2460
2461 ExprKind::Array(_)
2463 | ExprKind::Block(..)
2464 | ExprKind::Call(..)
2465 | ExprKind::ConstBlock(_)
2466 | ExprKind::Continue(..)
2467 | ExprKind::Field(..)
2468 | ExprKind::If(..)
2469 | ExprKind::Index(..)
2470 | ExprKind::InlineAsm(..)
2471 | ExprKind::Lit(_)
2472 | ExprKind::Loop(..)
2473 | ExprKind::Match(..)
2474 | ExprKind::MethodCall(..)
2475 | ExprKind::OffsetOf(..)
2476 | ExprKind::Path(..)
2477 | ExprKind::Repeat(..)
2478 | ExprKind::Struct(..)
2479 | ExprKind::Tup(_)
2480 | ExprKind::Type(..)
2481 | ExprKind::UnsafeBinderCast(..)
2482 | ExprKind::Use(..)
2483 | ExprKind::Err(_) => prefix_attrs_precedence(),
2484
2485 ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr),
2486 }
2487 }
2488
2489 pub fn is_syntactic_place_expr(&self) -> bool {
2494 self.is_place_expr(|_| true)
2495 }
2496
2497 pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2502 match self.kind {
2503 ExprKind::Path(QPath::Resolved(_, ref path)) => {
2504 matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2505 }
2506
2507 ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2511
2512 ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2514
2515 ExprKind::Unary(UnOp::Deref, _) => true,
2516
2517 ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2518 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2519 }
2520
2521 ExprKind::Err(_guar)
2523 | ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
2524
2525 ExprKind::Path(QPath::TypeRelative(..))
2528 | ExprKind::Call(..)
2529 | ExprKind::MethodCall(..)
2530 | ExprKind::Use(..)
2531 | ExprKind::Struct(..)
2532 | ExprKind::Tup(..)
2533 | ExprKind::If(..)
2534 | ExprKind::Match(..)
2535 | ExprKind::Closure { .. }
2536 | ExprKind::Block(..)
2537 | ExprKind::Repeat(..)
2538 | ExprKind::Array(..)
2539 | ExprKind::Break(..)
2540 | ExprKind::Continue(..)
2541 | ExprKind::Ret(..)
2542 | ExprKind::Become(..)
2543 | ExprKind::Let(..)
2544 | ExprKind::Loop(..)
2545 | ExprKind::Assign(..)
2546 | ExprKind::InlineAsm(..)
2547 | ExprKind::OffsetOf(..)
2548 | ExprKind::AssignOp(..)
2549 | ExprKind::Lit(_)
2550 | ExprKind::ConstBlock(..)
2551 | ExprKind::Unary(..)
2552 | ExprKind::AddrOf(..)
2553 | ExprKind::Binary(..)
2554 | ExprKind::Yield(..)
2555 | ExprKind::Cast(..)
2556 | ExprKind::DropTemps(..) => false,
2557 }
2558 }
2559
2560 pub fn range_span(&self) -> Option<Span> {
2563 is_range_literal(self).then(|| self.span.parent_callsite().unwrap())
2564 }
2565
2566 pub fn is_size_lit(&self) -> bool {
2569 matches!(
2570 self.kind,
2571 ExprKind::Lit(Lit {
2572 node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2573 ..
2574 })
2575 )
2576 }
2577
2578 pub fn peel_drop_temps(&self) -> &Self {
2584 let mut expr = self;
2585 while let ExprKind::DropTemps(inner) = &expr.kind {
2586 expr = inner;
2587 }
2588 expr
2589 }
2590
2591 pub fn peel_blocks(&self) -> &Self {
2592 let mut expr = self;
2593 while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2594 expr = inner;
2595 }
2596 expr
2597 }
2598
2599 pub fn peel_borrows(&self) -> &Self {
2600 let mut expr = self;
2601 while let ExprKind::AddrOf(.., inner) = &expr.kind {
2602 expr = inner;
2603 }
2604 expr
2605 }
2606
2607 pub fn can_have_side_effects(&self) -> bool {
2608 match self.peel_drop_temps().kind {
2609 ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2610 false
2611 }
2612 ExprKind::Type(base, _)
2613 | ExprKind::Unary(_, base)
2614 | ExprKind::Field(base, _)
2615 | ExprKind::Index(base, _, _)
2616 | ExprKind::AddrOf(.., base)
2617 | ExprKind::Cast(base, _)
2618 | ExprKind::UnsafeBinderCast(_, base, _) => {
2619 base.can_have_side_effects()
2623 }
2624 ExprKind::Struct(_, fields, init) => {
2625 let init_side_effects = match init {
2626 StructTailExpr::Base(init) => init.can_have_side_effects(),
2627 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2628 };
2629 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2630 || init_side_effects
2631 }
2632
2633 ExprKind::Array(args)
2634 | ExprKind::Tup(args)
2635 | ExprKind::Call(
2636 Expr {
2637 kind:
2638 ExprKind::Path(QPath::Resolved(
2639 None,
2640 Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2641 )),
2642 ..
2643 },
2644 args,
2645 ) => args.iter().any(|arg| arg.can_have_side_effects()),
2646 ExprKind::If(..)
2647 | ExprKind::Match(..)
2648 | ExprKind::MethodCall(..)
2649 | ExprKind::Call(..)
2650 | ExprKind::Closure { .. }
2651 | ExprKind::Block(..)
2652 | ExprKind::Repeat(..)
2653 | ExprKind::Break(..)
2654 | ExprKind::Continue(..)
2655 | ExprKind::Ret(..)
2656 | ExprKind::Become(..)
2657 | ExprKind::Let(..)
2658 | ExprKind::Loop(..)
2659 | ExprKind::Assign(..)
2660 | ExprKind::InlineAsm(..)
2661 | ExprKind::AssignOp(..)
2662 | ExprKind::ConstBlock(..)
2663 | ExprKind::Binary(..)
2664 | ExprKind::Yield(..)
2665 | ExprKind::DropTemps(..)
2666 | ExprKind::Err(_) => true,
2667 }
2668 }
2669
2670 pub fn is_approximately_pattern(&self) -> bool {
2672 match &self.kind {
2673 ExprKind::Array(_)
2674 | ExprKind::Call(..)
2675 | ExprKind::Tup(_)
2676 | ExprKind::Lit(_)
2677 | ExprKind::Path(_)
2678 | ExprKind::Struct(..) => true,
2679 _ => false,
2680 }
2681 }
2682
2683 pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2688 match (self.kind, other.kind) {
2689 (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2690 (
2691 ExprKind::Path(QPath::Resolved(None, path1)),
2692 ExprKind::Path(QPath::Resolved(None, path2)),
2693 ) => path1.res == path2.res,
2694 (
2695 ExprKind::Struct(
2696 &QPath::Resolved(None, &Path { res: Res::Def(_, path1_def_id), .. }),
2697 args1,
2698 StructTailExpr::None,
2699 ),
2700 ExprKind::Struct(
2701 &QPath::Resolved(None, &Path { res: Res::Def(_, path2_def_id), .. }),
2702 args2,
2703 StructTailExpr::None,
2704 ),
2705 ) => {
2706 path2_def_id == path1_def_id
2707 && is_range_literal(self)
2708 && is_range_literal(other)
2709 && std::iter::zip(args1, args2)
2710 .all(|(a, b)| a.expr.equivalent_for_indexing(b.expr))
2711 }
2712 _ => false,
2713 }
2714 }
2715
2716 pub fn method_ident(&self) -> Option<Ident> {
2717 match self.kind {
2718 ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2719 ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2720 _ => None,
2721 }
2722 }
2723}
2724
2725pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2728 if let ExprKind::Struct(QPath::Resolved(None, path), _, StructTailExpr::None) = expr.kind
2729 && let [.., segment] = path.segments
2730 && let sym::RangeFrom
2731 | sym::RangeFull
2732 | sym::Range
2733 | sym::RangeToInclusive
2734 | sym::RangeTo
2735 | sym::RangeFromCopy
2736 | sym::RangeCopy
2737 | sym::RangeInclusiveCopy
2738 | sym::RangeToInclusiveCopy = segment.ident.name
2739 && expr.span.is_desugaring(DesugaringKind::RangeExpr)
2740 {
2741 true
2742 } else if let ExprKind::Call(func, _) = &expr.kind
2743 && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
2744 && let [.., segment] = path.segments
2745 && let sym::range_inclusive_new = segment.ident.name
2746 && expr.span.is_desugaring(DesugaringKind::RangeExpr)
2747 {
2748 true
2749 } else {
2750 false
2751 }
2752}
2753
2754pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2761 match expr.kind {
2762 ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2764 _ if is_range_literal(expr) => true,
2766 _ => false,
2767 }
2768}
2769
2770#[derive(Debug, Clone, Copy, HashStable_Generic)]
2771pub enum ExprKind<'hir> {
2772 ConstBlock(ConstBlock),
2774 Array(&'hir [Expr<'hir>]),
2776 Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2783 MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2800 Use(&'hir Expr<'hir>, Span),
2802 Tup(&'hir [Expr<'hir>]),
2804 Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2806 Unary(UnOp, &'hir Expr<'hir>),
2808 Lit(Lit),
2810 Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2812 Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2814 DropTemps(&'hir Expr<'hir>),
2820 Let(&'hir LetExpr<'hir>),
2825 If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2834 Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2840 Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2843 Closure(&'hir Closure<'hir>),
2850 Block(&'hir Block<'hir>, Option<Label>),
2852
2853 Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2855 AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2859 Field(&'hir Expr<'hir>, Ident),
2861 Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2865
2866 Path(QPath<'hir>),
2868
2869 AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2871 Break(Destination, Option<&'hir Expr<'hir>>),
2873 Continue(Destination),
2875 Ret(Option<&'hir Expr<'hir>>),
2877 Become(&'hir Expr<'hir>),
2879
2880 InlineAsm(&'hir InlineAsm<'hir>),
2882
2883 OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2885
2886 Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2891
2892 Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2897
2898 Yield(&'hir Expr<'hir>, YieldSource),
2900
2901 UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2904
2905 Err(rustc_span::ErrorGuaranteed),
2907}
2908
2909#[derive(Debug, Clone, Copy, HashStable_Generic)]
2910pub enum StructTailExpr<'hir> {
2911 None,
2913 Base(&'hir Expr<'hir>),
2916 DefaultFields(Span),
2920}
2921
2922#[derive(Debug, Clone, Copy, HashStable_Generic)]
2928pub enum QPath<'hir> {
2929 Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2936
2937 TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2944}
2945
2946impl<'hir> QPath<'hir> {
2947 pub fn span(&self) -> Span {
2949 match *self {
2950 QPath::Resolved(_, path) => path.span,
2951 QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2952 }
2953 }
2954
2955 pub fn qself_span(&self) -> Span {
2958 match *self {
2959 QPath::Resolved(_, path) => path.span,
2960 QPath::TypeRelative(qself, _) => qself.span,
2961 }
2962 }
2963}
2964
2965#[derive(Copy, Clone, Debug, HashStable_Generic)]
2967pub enum LocalSource {
2968 Normal,
2970 AsyncFn,
2981 AwaitDesugar,
2983 AssignDesugar,
2985 Contract,
2987}
2988
2989#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2991pub enum MatchSource {
2992 Normal,
2994 Postfix,
2996 ForLoopDesugar,
2998 TryDesugar(HirId),
3000 AwaitDesugar,
3002 FormatArgs,
3004}
3005
3006impl MatchSource {
3007 #[inline]
3008 pub const fn name(self) -> &'static str {
3009 use MatchSource::*;
3010 match self {
3011 Normal => "match",
3012 Postfix => ".match",
3013 ForLoopDesugar => "for",
3014 TryDesugar(_) => "?",
3015 AwaitDesugar => ".await",
3016 FormatArgs => "format_args!()",
3017 }
3018 }
3019}
3020
3021#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3023pub enum LoopSource {
3024 Loop,
3026 While,
3028 ForLoop,
3030}
3031
3032impl LoopSource {
3033 pub fn name(self) -> &'static str {
3034 match self {
3035 LoopSource::Loop => "loop",
3036 LoopSource::While => "while",
3037 LoopSource::ForLoop => "for",
3038 }
3039 }
3040}
3041
3042#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3043pub enum LoopIdError {
3044 OutsideLoopScope,
3045 UnlabeledCfInWhileCondition,
3046 UnresolvedLabel,
3047}
3048
3049impl fmt::Display for LoopIdError {
3050 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3051 f.write_str(match self {
3052 LoopIdError::OutsideLoopScope => "not inside loop scope",
3053 LoopIdError::UnlabeledCfInWhileCondition => {
3054 "unlabeled control flow (break or continue) in while condition"
3055 }
3056 LoopIdError::UnresolvedLabel => "label not found",
3057 })
3058 }
3059}
3060
3061#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3062pub struct Destination {
3063 pub label: Option<Label>,
3065
3066 pub target_id: Result<HirId, LoopIdError>,
3069}
3070
3071#[derive(Copy, Clone, Debug, HashStable_Generic)]
3073pub enum YieldSource {
3074 Await { expr: Option<HirId> },
3076 Yield,
3078}
3079
3080impl fmt::Display for YieldSource {
3081 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3082 f.write_str(match self {
3083 YieldSource::Await { .. } => "`await`",
3084 YieldSource::Yield => "`yield`",
3085 })
3086 }
3087}
3088
3089#[derive(Debug, Clone, Copy, HashStable_Generic)]
3092pub struct MutTy<'hir> {
3093 pub ty: &'hir Ty<'hir>,
3094 pub mutbl: Mutability,
3095}
3096
3097#[derive(Debug, Clone, Copy, HashStable_Generic)]
3100pub struct FnSig<'hir> {
3101 pub header: FnHeader,
3102 pub decl: &'hir FnDecl<'hir>,
3103 pub span: Span,
3104}
3105
3106#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3110pub struct TraitItemId {
3111 pub owner_id: OwnerId,
3112}
3113
3114impl TraitItemId {
3115 #[inline]
3116 pub fn hir_id(&self) -> HirId {
3117 HirId::make_owner(self.owner_id.def_id)
3119 }
3120}
3121
3122#[derive(Debug, Clone, Copy, HashStable_Generic)]
3127pub struct TraitItem<'hir> {
3128 pub ident: Ident,
3129 pub owner_id: OwnerId,
3130 pub generics: &'hir Generics<'hir>,
3131 pub kind: TraitItemKind<'hir>,
3132 pub span: Span,
3133 pub defaultness: Defaultness,
3134 pub has_delayed_lints: bool,
3135}
3136
3137macro_rules! expect_methods_self_kind {
3138 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3139 $(
3140 #[track_caller]
3141 pub fn $name(&self) -> $ret_ty {
3142 let $pat = &self.kind else { expect_failed(stringify!($name), self) };
3143 $ret_val
3144 }
3145 )*
3146 }
3147}
3148
3149macro_rules! expect_methods_self {
3150 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3151 $(
3152 #[track_caller]
3153 pub fn $name(&self) -> $ret_ty {
3154 let $pat = self else { expect_failed(stringify!($name), self) };
3155 $ret_val
3156 }
3157 )*
3158 }
3159}
3160
3161#[track_caller]
3162fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
3163 panic!("{ident}: found {found:?}")
3164}
3165
3166impl<'hir> TraitItem<'hir> {
3167 #[inline]
3168 pub fn hir_id(&self) -> HirId {
3169 HirId::make_owner(self.owner_id.def_id)
3171 }
3172
3173 pub fn trait_item_id(&self) -> TraitItemId {
3174 TraitItemId { owner_id: self.owner_id }
3175 }
3176
3177 expect_methods_self_kind! {
3178 expect_const, (&'hir Ty<'hir>, Option<ConstItemRhs<'hir>>),
3179 TraitItemKind::Const(ty, rhs), (ty, *rhs);
3180
3181 expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
3182 TraitItemKind::Fn(ty, trfn), (ty, trfn);
3183
3184 expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3185 TraitItemKind::Type(bounds, ty), (bounds, *ty);
3186 }
3187}
3188
3189#[derive(Debug, Clone, Copy, HashStable_Generic)]
3191pub enum TraitFn<'hir> {
3192 Required(&'hir [Option<Ident>]),
3194
3195 Provided(BodyId),
3197}
3198
3199#[derive(Debug, Clone, Copy, HashStable_Generic)]
3201pub enum TraitItemKind<'hir> {
3202 Const(&'hir Ty<'hir>, Option<ConstItemRhs<'hir>>),
3204 Fn(FnSig<'hir>, TraitFn<'hir>),
3206 Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3209}
3210
3211#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3215pub struct ImplItemId {
3216 pub owner_id: OwnerId,
3217}
3218
3219impl ImplItemId {
3220 #[inline]
3221 pub fn hir_id(&self) -> HirId {
3222 HirId::make_owner(self.owner_id.def_id)
3224 }
3225}
3226
3227#[derive(Debug, Clone, Copy, HashStable_Generic)]
3231pub struct ImplItem<'hir> {
3232 pub ident: Ident,
3233 pub owner_id: OwnerId,
3234 pub generics: &'hir Generics<'hir>,
3235 pub kind: ImplItemKind<'hir>,
3236 pub impl_kind: ImplItemImplKind,
3237 pub span: Span,
3238 pub has_delayed_lints: bool,
3239}
3240
3241#[derive(Debug, Clone, Copy, HashStable_Generic)]
3242pub enum ImplItemImplKind {
3243 Inherent {
3244 vis_span: Span,
3245 },
3246 Trait {
3247 defaultness: Defaultness,
3248 trait_item_def_id: Result<DefId, ErrorGuaranteed>,
3250 },
3251}
3252
3253impl<'hir> ImplItem<'hir> {
3254 #[inline]
3255 pub fn hir_id(&self) -> HirId {
3256 HirId::make_owner(self.owner_id.def_id)
3258 }
3259
3260 pub fn impl_item_id(&self) -> ImplItemId {
3261 ImplItemId { owner_id: self.owner_id }
3262 }
3263
3264 pub fn vis_span(&self) -> Option<Span> {
3265 match self.impl_kind {
3266 ImplItemImplKind::Trait { .. } => None,
3267 ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
3268 }
3269 }
3270
3271 expect_methods_self_kind! {
3272 expect_const, (&'hir Ty<'hir>, ConstItemRhs<'hir>), ImplItemKind::Const(ty, rhs), (ty, *rhs);
3273 expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3274 expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3275 }
3276}
3277
3278#[derive(Debug, Clone, Copy, HashStable_Generic)]
3280pub enum ImplItemKind<'hir> {
3281 Const(&'hir Ty<'hir>, ConstItemRhs<'hir>),
3284 Fn(FnSig<'hir>, BodyId),
3286 Type(&'hir Ty<'hir>),
3288}
3289
3290#[derive(Debug, Clone, Copy, HashStable_Generic)]
3301pub struct AssocItemConstraint<'hir> {
3302 #[stable_hasher(ignore)]
3303 pub hir_id: HirId,
3304 pub ident: Ident,
3305 pub gen_args: &'hir GenericArgs<'hir>,
3306 pub kind: AssocItemConstraintKind<'hir>,
3307 pub span: Span,
3308}
3309
3310impl<'hir> AssocItemConstraint<'hir> {
3311 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
3313 match self.kind {
3314 AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
3315 _ => None,
3316 }
3317 }
3318
3319 pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
3321 match self.kind {
3322 AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
3323 _ => None,
3324 }
3325 }
3326}
3327
3328#[derive(Debug, Clone, Copy, HashStable_Generic)]
3329pub enum Term<'hir> {
3330 Ty(&'hir Ty<'hir>),
3331 Const(&'hir ConstArg<'hir>),
3332}
3333
3334impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
3335 fn from(ty: &'hir Ty<'hir>) -> Self {
3336 Term::Ty(ty)
3337 }
3338}
3339
3340impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
3341 fn from(c: &'hir ConstArg<'hir>) -> Self {
3342 Term::Const(c)
3343 }
3344}
3345
3346#[derive(Debug, Clone, Copy, HashStable_Generic)]
3348pub enum AssocItemConstraintKind<'hir> {
3349 Equality { term: Term<'hir> },
3356 Bound { bounds: &'hir [GenericBound<'hir>] },
3358}
3359
3360impl<'hir> AssocItemConstraintKind<'hir> {
3361 pub fn descr(&self) -> &'static str {
3362 match self {
3363 AssocItemConstraintKind::Equality { .. } => "binding",
3364 AssocItemConstraintKind::Bound { .. } => "constraint",
3365 }
3366 }
3367}
3368
3369#[derive(Debug, Clone, Copy, HashStable_Generic)]
3373pub enum AmbigArg {}
3374
3375#[derive(Debug, Clone, Copy, HashStable_Generic)]
3380#[repr(C)]
3381pub struct Ty<'hir, Unambig = ()> {
3382 #[stable_hasher(ignore)]
3383 pub hir_id: HirId,
3384 pub span: Span,
3385 pub kind: TyKind<'hir, Unambig>,
3386}
3387
3388impl<'hir> Ty<'hir, AmbigArg> {
3389 pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3400 let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3403 unsafe { &*ptr }
3404 }
3405}
3406
3407impl<'hir> Ty<'hir> {
3408 pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3414 if let TyKind::Infer(()) = self.kind {
3415 return None;
3416 }
3417
3418 let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3422 Some(unsafe { &*ptr })
3423 }
3424}
3425
3426impl<'hir> Ty<'hir, AmbigArg> {
3427 pub fn peel_refs(&self) -> &Ty<'hir> {
3428 let mut final_ty = self.as_unambig_ty();
3429 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3430 final_ty = ty;
3431 }
3432 final_ty
3433 }
3434}
3435
3436impl<'hir> Ty<'hir> {
3437 pub fn peel_refs(&self) -> &Self {
3438 let mut final_ty = self;
3439 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3440 final_ty = ty;
3441 }
3442 final_ty
3443 }
3444
3445 pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3447 let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3448 return None;
3449 };
3450 let [segment] = &path.segments else {
3451 return None;
3452 };
3453 match path.res {
3454 Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3455 Some((def_id, segment.ident))
3456 }
3457 _ => None,
3458 }
3459 }
3460
3461 pub fn find_self_aliases(&self) -> Vec<Span> {
3462 use crate::intravisit::Visitor;
3463 struct MyVisitor(Vec<Span>);
3464 impl<'v> Visitor<'v> for MyVisitor {
3465 fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3466 if matches!(
3467 &t.kind,
3468 TyKind::Path(QPath::Resolved(
3469 _,
3470 Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3471 ))
3472 ) {
3473 self.0.push(t.span);
3474 return;
3475 }
3476 crate::intravisit::walk_ty(self, t);
3477 }
3478 }
3479
3480 let mut my_visitor = MyVisitor(vec![]);
3481 my_visitor.visit_ty_unambig(self);
3482 my_visitor.0
3483 }
3484
3485 pub fn is_suggestable_infer_ty(&self) -> bool {
3488 fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3489 generic_args.iter().any(|arg| match arg {
3490 GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3491 GenericArg::Infer(_) => true,
3492 _ => false,
3493 })
3494 }
3495 debug!(?self);
3496 match &self.kind {
3497 TyKind::Infer(()) => true,
3498 TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3499 TyKind::Array(ty, length) => {
3500 ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3501 }
3502 TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3503 TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3504 TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3505 ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3506 }
3507 TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3508 ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3509 || segments
3510 .iter()
3511 .any(|segment| are_suggestable_generic_args(segment.args().args))
3512 }
3513 _ => false,
3514 }
3515 }
3516}
3517
3518#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3520pub enum PrimTy {
3521 Int(IntTy),
3522 Uint(UintTy),
3523 Float(FloatTy),
3524 Str,
3525 Bool,
3526 Char,
3527}
3528
3529impl PrimTy {
3530 pub const ALL: [Self; 19] = [
3532 Self::Int(IntTy::I8),
3534 Self::Int(IntTy::I16),
3535 Self::Int(IntTy::I32),
3536 Self::Int(IntTy::I64),
3537 Self::Int(IntTy::I128),
3538 Self::Int(IntTy::Isize),
3539 Self::Uint(UintTy::U8),
3540 Self::Uint(UintTy::U16),
3541 Self::Uint(UintTy::U32),
3542 Self::Uint(UintTy::U64),
3543 Self::Uint(UintTy::U128),
3544 Self::Uint(UintTy::Usize),
3545 Self::Float(FloatTy::F16),
3546 Self::Float(FloatTy::F32),
3547 Self::Float(FloatTy::F64),
3548 Self::Float(FloatTy::F128),
3549 Self::Bool,
3550 Self::Char,
3551 Self::Str,
3552 ];
3553
3554 pub fn name_str(self) -> &'static str {
3558 match self {
3559 PrimTy::Int(i) => i.name_str(),
3560 PrimTy::Uint(u) => u.name_str(),
3561 PrimTy::Float(f) => f.name_str(),
3562 PrimTy::Str => "str",
3563 PrimTy::Bool => "bool",
3564 PrimTy::Char => "char",
3565 }
3566 }
3567
3568 pub fn name(self) -> Symbol {
3569 match self {
3570 PrimTy::Int(i) => i.name(),
3571 PrimTy::Uint(u) => u.name(),
3572 PrimTy::Float(f) => f.name(),
3573 PrimTy::Str => sym::str,
3574 PrimTy::Bool => sym::bool,
3575 PrimTy::Char => sym::char,
3576 }
3577 }
3578
3579 pub fn from_name(name: Symbol) -> Option<Self> {
3582 let ty = match name {
3583 sym::i8 => Self::Int(IntTy::I8),
3585 sym::i16 => Self::Int(IntTy::I16),
3586 sym::i32 => Self::Int(IntTy::I32),
3587 sym::i64 => Self::Int(IntTy::I64),
3588 sym::i128 => Self::Int(IntTy::I128),
3589 sym::isize => Self::Int(IntTy::Isize),
3590 sym::u8 => Self::Uint(UintTy::U8),
3591 sym::u16 => Self::Uint(UintTy::U16),
3592 sym::u32 => Self::Uint(UintTy::U32),
3593 sym::u64 => Self::Uint(UintTy::U64),
3594 sym::u128 => Self::Uint(UintTy::U128),
3595 sym::usize => Self::Uint(UintTy::Usize),
3596 sym::f16 => Self::Float(FloatTy::F16),
3597 sym::f32 => Self::Float(FloatTy::F32),
3598 sym::f64 => Self::Float(FloatTy::F64),
3599 sym::f128 => Self::Float(FloatTy::F128),
3600 sym::bool => Self::Bool,
3601 sym::char => Self::Char,
3602 sym::str => Self::Str,
3603 _ => return None,
3604 };
3605 Some(ty)
3606 }
3607}
3608
3609#[derive(Debug, Clone, Copy, HashStable_Generic)]
3610pub struct FnPtrTy<'hir> {
3611 pub safety: Safety,
3612 pub abi: ExternAbi,
3613 pub generic_params: &'hir [GenericParam<'hir>],
3614 pub decl: &'hir FnDecl<'hir>,
3615 pub param_idents: &'hir [Option<Ident>],
3618}
3619
3620#[derive(Debug, Clone, Copy, HashStable_Generic)]
3621pub struct UnsafeBinderTy<'hir> {
3622 pub generic_params: &'hir [GenericParam<'hir>],
3623 pub inner_ty: &'hir Ty<'hir>,
3624}
3625
3626#[derive(Debug, Clone, Copy, HashStable_Generic)]
3627pub struct OpaqueTy<'hir> {
3628 #[stable_hasher(ignore)]
3629 pub hir_id: HirId,
3630 pub def_id: LocalDefId,
3631 pub bounds: GenericBounds<'hir>,
3632 pub origin: OpaqueTyOrigin<LocalDefId>,
3633 pub span: Span,
3634}
3635
3636#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
3637pub enum PreciseCapturingArgKind<T, U> {
3638 Lifetime(T),
3639 Param(U),
3641}
3642
3643pub type PreciseCapturingArg<'hir> =
3644 PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
3645
3646impl PreciseCapturingArg<'_> {
3647 pub fn hir_id(self) -> HirId {
3648 match self {
3649 PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3650 PreciseCapturingArg::Param(param) => param.hir_id,
3651 }
3652 }
3653
3654 pub fn name(self) -> Symbol {
3655 match self {
3656 PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3657 PreciseCapturingArg::Param(param) => param.ident.name,
3658 }
3659 }
3660}
3661
3662#[derive(Debug, Clone, Copy, HashStable_Generic)]
3667pub struct PreciseCapturingNonLifetimeArg {
3668 #[stable_hasher(ignore)]
3669 pub hir_id: HirId,
3670 pub ident: Ident,
3671 pub res: Res,
3672}
3673
3674#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3675#[derive(HashStable_Generic, Encodable, Decodable)]
3676pub enum RpitContext {
3677 Trait,
3678 TraitImpl,
3679}
3680
3681#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3683#[derive(HashStable_Generic, Encodable, Decodable)]
3684pub enum OpaqueTyOrigin<D> {
3685 FnReturn {
3687 parent: D,
3689 in_trait_or_impl: Option<RpitContext>,
3691 },
3692 AsyncFn {
3694 parent: D,
3696 in_trait_or_impl: Option<RpitContext>,
3698 },
3699 TyAlias {
3701 parent: D,
3703 in_assoc_ty: bool,
3705 },
3706}
3707
3708#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3709pub enum InferDelegationKind {
3710 Input(usize),
3711 Output,
3712}
3713
3714#[repr(u8, C)]
3720#[derive(Debug, Clone, Copy, HashStable_Generic)]
3721pub enum TyKind<'hir, Unambig = ()> {
3722 InferDelegation(DefId, InferDelegationKind),
3724 Slice(&'hir Ty<'hir>),
3726 Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3728 Ptr(MutTy<'hir>),
3730 Ref(&'hir Lifetime, MutTy<'hir>),
3732 FnPtr(&'hir FnPtrTy<'hir>),
3734 UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3736 Never,
3738 Tup(&'hir [Ty<'hir>]),
3740 Path(QPath<'hir>),
3745 OpaqueDef(&'hir OpaqueTy<'hir>),
3747 TraitAscription(GenericBounds<'hir>),
3749 TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3755 Err(rustc_span::ErrorGuaranteed),
3757 Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3759 Infer(Unambig),
3765}
3766
3767#[derive(Debug, Clone, Copy, HashStable_Generic)]
3768pub enum InlineAsmOperand<'hir> {
3769 In {
3770 reg: InlineAsmRegOrRegClass,
3771 expr: &'hir Expr<'hir>,
3772 },
3773 Out {
3774 reg: InlineAsmRegOrRegClass,
3775 late: bool,
3776 expr: Option<&'hir Expr<'hir>>,
3777 },
3778 InOut {
3779 reg: InlineAsmRegOrRegClass,
3780 late: bool,
3781 expr: &'hir Expr<'hir>,
3782 },
3783 SplitInOut {
3784 reg: InlineAsmRegOrRegClass,
3785 late: bool,
3786 in_expr: &'hir Expr<'hir>,
3787 out_expr: Option<&'hir Expr<'hir>>,
3788 },
3789 Const {
3790 anon_const: ConstBlock,
3791 },
3792 SymFn {
3793 expr: &'hir Expr<'hir>,
3794 },
3795 SymStatic {
3796 path: QPath<'hir>,
3797 def_id: DefId,
3798 },
3799 Label {
3800 block: &'hir Block<'hir>,
3801 },
3802}
3803
3804impl<'hir> InlineAsmOperand<'hir> {
3805 pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3806 match *self {
3807 Self::In { reg, .. }
3808 | Self::Out { reg, .. }
3809 | Self::InOut { reg, .. }
3810 | Self::SplitInOut { reg, .. } => Some(reg),
3811 Self::Const { .. }
3812 | Self::SymFn { .. }
3813 | Self::SymStatic { .. }
3814 | Self::Label { .. } => None,
3815 }
3816 }
3817
3818 pub fn is_clobber(&self) -> bool {
3819 matches!(
3820 self,
3821 InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3822 )
3823 }
3824}
3825
3826#[derive(Debug, Clone, Copy, HashStable_Generic)]
3827pub struct InlineAsm<'hir> {
3828 pub asm_macro: ast::AsmMacro,
3829 pub template: &'hir [InlineAsmTemplatePiece],
3830 pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3831 pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3832 pub options: InlineAsmOptions,
3833 pub line_spans: &'hir [Span],
3834}
3835
3836impl InlineAsm<'_> {
3837 pub fn contains_label(&self) -> bool {
3838 self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3839 }
3840}
3841
3842#[derive(Debug, Clone, Copy, HashStable_Generic)]
3844pub struct Param<'hir> {
3845 #[stable_hasher(ignore)]
3846 pub hir_id: HirId,
3847 pub pat: &'hir Pat<'hir>,
3848 pub ty_span: Span,
3849 pub span: Span,
3850}
3851
3852#[derive(Debug, Clone, Copy, HashStable_Generic)]
3854pub struct FnDecl<'hir> {
3855 pub inputs: &'hir [Ty<'hir>],
3859 pub output: FnRetTy<'hir>,
3860 pub c_variadic: bool,
3861 pub implicit_self: ImplicitSelfKind,
3863 pub lifetime_elision_allowed: bool,
3865}
3866
3867impl<'hir> FnDecl<'hir> {
3868 pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3869 if let FnRetTy::Return(ty) = self.output
3870 && let TyKind::InferDelegation(sig_id, _) = ty.kind
3871 {
3872 return Some(sig_id);
3873 }
3874 None
3875 }
3876}
3877
3878#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3880pub enum ImplicitSelfKind {
3881 Imm,
3883 Mut,
3885 RefImm,
3887 RefMut,
3889 None,
3892}
3893
3894impl ImplicitSelfKind {
3895 pub fn has_implicit_self(&self) -> bool {
3897 !matches!(*self, ImplicitSelfKind::None)
3898 }
3899}
3900
3901#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3902pub enum IsAsync {
3903 Async(Span),
3904 NotAsync,
3905}
3906
3907impl IsAsync {
3908 pub fn is_async(self) -> bool {
3909 matches!(self, IsAsync::Async(_))
3910 }
3911}
3912
3913#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3914#[derive(Default)]
3915pub enum Defaultness {
3916 Default {
3917 has_value: bool,
3918 },
3919 #[default]
3920 Final,
3921}
3922
3923impl Defaultness {
3924 pub fn has_value(&self) -> bool {
3925 match *self {
3926 Defaultness::Default { has_value } => has_value,
3927 Defaultness::Final => true,
3928 }
3929 }
3930
3931 pub fn is_final(&self) -> bool {
3932 *self == Defaultness::Final
3933 }
3934
3935 pub fn is_default(&self) -> bool {
3936 matches!(*self, Defaultness::Default { .. })
3937 }
3938}
3939
3940#[derive(Debug, Clone, Copy, HashStable_Generic)]
3941pub enum FnRetTy<'hir> {
3942 DefaultReturn(Span),
3948 Return(&'hir Ty<'hir>),
3950}
3951
3952impl<'hir> FnRetTy<'hir> {
3953 #[inline]
3954 pub fn span(&self) -> Span {
3955 match *self {
3956 Self::DefaultReturn(span) => span,
3957 Self::Return(ref ty) => ty.span,
3958 }
3959 }
3960
3961 pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3962 if let Self::Return(ty) = self
3963 && ty.is_suggestable_infer_ty()
3964 {
3965 return Some(*ty);
3966 }
3967 None
3968 }
3969}
3970
3971#[derive(Copy, Clone, Debug, HashStable_Generic)]
3973pub enum ClosureBinder {
3974 Default,
3976 For { span: Span },
3980}
3981
3982#[derive(Debug, Clone, Copy, HashStable_Generic)]
3983pub struct Mod<'hir> {
3984 pub spans: ModSpans,
3985 pub item_ids: &'hir [ItemId],
3986}
3987
3988#[derive(Copy, Clone, Debug, HashStable_Generic)]
3989pub struct ModSpans {
3990 pub inner_span: Span,
3994 pub inject_use_span: Span,
3995}
3996
3997#[derive(Debug, Clone, Copy, HashStable_Generic)]
3998pub struct EnumDef<'hir> {
3999 pub variants: &'hir [Variant<'hir>],
4000}
4001
4002#[derive(Debug, Clone, Copy, HashStable_Generic)]
4003pub struct Variant<'hir> {
4004 pub ident: Ident,
4006 #[stable_hasher(ignore)]
4008 pub hir_id: HirId,
4009 pub def_id: LocalDefId,
4010 pub data: VariantData<'hir>,
4012 pub disr_expr: Option<&'hir AnonConst>,
4014 pub span: Span,
4016}
4017
4018#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4019pub enum UseKind {
4020 Single(Ident),
4027
4028 Glob,
4030
4031 ListStem,
4035}
4036
4037#[derive(Clone, Debug, Copy, HashStable_Generic)]
4044pub struct TraitRef<'hir> {
4045 pub path: &'hir Path<'hir>,
4046 #[stable_hasher(ignore)]
4048 pub hir_ref_id: HirId,
4049}
4050
4051impl TraitRef<'_> {
4052 pub fn trait_def_id(&self) -> Option<DefId> {
4054 match self.path.res {
4055 Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
4056 Res::Err => None,
4057 res => panic!("{res:?} did not resolve to a trait or trait alias"),
4058 }
4059 }
4060}
4061
4062#[derive(Clone, Debug, Copy, HashStable_Generic)]
4063pub struct PolyTraitRef<'hir> {
4064 pub bound_generic_params: &'hir [GenericParam<'hir>],
4066
4067 pub modifiers: TraitBoundModifiers,
4071
4072 pub trait_ref: TraitRef<'hir>,
4074
4075 pub span: Span,
4076}
4077
4078#[derive(Debug, Clone, Copy, HashStable_Generic)]
4079pub struct FieldDef<'hir> {
4080 pub span: Span,
4081 pub vis_span: Span,
4082 pub ident: Ident,
4083 #[stable_hasher(ignore)]
4084 pub hir_id: HirId,
4085 pub def_id: LocalDefId,
4086 pub ty: &'hir Ty<'hir>,
4087 pub safety: Safety,
4088 pub default: Option<&'hir AnonConst>,
4089}
4090
4091impl FieldDef<'_> {
4092 pub fn is_positional(&self) -> bool {
4094 self.ident.as_str().as_bytes()[0].is_ascii_digit()
4095 }
4096}
4097
4098#[derive(Debug, Clone, Copy, HashStable_Generic)]
4100pub enum VariantData<'hir> {
4101 Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
4105 Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
4109 Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
4113}
4114
4115impl<'hir> VariantData<'hir> {
4116 pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
4118 match *self {
4119 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
4120 _ => &[],
4121 }
4122 }
4123
4124 pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
4125 match *self {
4126 VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
4127 VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
4128 VariantData::Struct { .. } => None,
4129 }
4130 }
4131
4132 #[inline]
4133 pub fn ctor_kind(&self) -> Option<CtorKind> {
4134 self.ctor().map(|(kind, ..)| kind)
4135 }
4136
4137 #[inline]
4139 pub fn ctor_hir_id(&self) -> Option<HirId> {
4140 self.ctor().map(|(_, hir_id, _)| hir_id)
4141 }
4142
4143 #[inline]
4145 pub fn ctor_def_id(&self) -> Option<LocalDefId> {
4146 self.ctor().map(|(.., def_id)| def_id)
4147 }
4148}
4149
4150#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
4154pub struct ItemId {
4155 pub owner_id: OwnerId,
4156}
4157
4158impl ItemId {
4159 #[inline]
4160 pub fn hir_id(&self) -> HirId {
4161 HirId::make_owner(self.owner_id.def_id)
4163 }
4164}
4165
4166#[derive(Debug, Clone, Copy, HashStable_Generic)]
4175pub struct Item<'hir> {
4176 pub owner_id: OwnerId,
4177 pub kind: ItemKind<'hir>,
4178 pub span: Span,
4179 pub vis_span: Span,
4180 pub has_delayed_lints: bool,
4181 pub eii: bool,
4184}
4185
4186impl<'hir> Item<'hir> {
4187 #[inline]
4188 pub fn hir_id(&self) -> HirId {
4189 HirId::make_owner(self.owner_id.def_id)
4191 }
4192
4193 pub fn item_id(&self) -> ItemId {
4194 ItemId { owner_id: self.owner_id }
4195 }
4196
4197 pub fn is_adt(&self) -> bool {
4200 matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
4201 }
4202
4203 pub fn is_struct_or_union(&self) -> bool {
4205 matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
4206 }
4207
4208 expect_methods_self_kind! {
4209 expect_extern_crate, (Option<Symbol>, Ident),
4210 ItemKind::ExternCrate(s, ident), (*s, *ident);
4211
4212 expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
4213
4214 expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId),
4215 ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body);
4216
4217 expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>),
4218 ItemKind::Const(ident, generics, ty, rhs), (*ident, generics, ty, *rhs);
4219
4220 expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
4221 ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
4222
4223 expect_macro, (Ident, &ast::MacroDef, MacroKinds),
4224 ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
4225
4226 expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
4227
4228 expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]),
4229 ItemKind::ForeignMod { abi, items }, (*abi, items);
4230
4231 expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
4232
4233 expect_ty_alias, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4234 ItemKind::TyAlias(ident, generics, ty), (*ident, generics, ty);
4235
4236 expect_enum, (Ident, &'hir Generics<'hir>, &EnumDef<'hir>),
4237 ItemKind::Enum(ident, generics, def), (*ident, generics, def);
4238
4239 expect_struct, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4240 ItemKind::Struct(ident, generics, data), (*ident, generics, data);
4241
4242 expect_union, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4243 ItemKind::Union(ident, generics, data), (*ident, generics, data);
4244
4245 expect_trait,
4246 (
4247 Constness,
4248 IsAuto,
4249 Safety,
4250 Ident,
4251 &'hir Generics<'hir>,
4252 GenericBounds<'hir>,
4253 &'hir [TraitItemId]
4254 ),
4255 ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
4256 (*constness, *is_auto, *safety, *ident, generics, bounds, items);
4257
4258 expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4259 ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);
4260
4261 expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
4262 }
4263}
4264
4265#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4266#[derive(Encodable, Decodable, HashStable_Generic, Default)]
4267pub enum Safety {
4268 #[default]
4273 Unsafe,
4274 Safe,
4275}
4276
4277impl Safety {
4278 pub fn prefix_str(self) -> &'static str {
4279 match self {
4280 Self::Unsafe => "unsafe ",
4281 Self::Safe => "",
4282 }
4283 }
4284
4285 #[inline]
4286 pub fn is_unsafe(self) -> bool {
4287 !self.is_safe()
4288 }
4289
4290 #[inline]
4291 pub fn is_safe(self) -> bool {
4292 match self {
4293 Self::Unsafe => false,
4294 Self::Safe => true,
4295 }
4296 }
4297}
4298
4299impl fmt::Display for Safety {
4300 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4301 f.write_str(match *self {
4302 Self::Unsafe => "unsafe",
4303 Self::Safe => "safe",
4304 })
4305 }
4306}
4307
4308#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
4309#[derive(Default)]
4310pub enum Constness {
4311 #[default]
4312 Const,
4313 NotConst,
4314}
4315
4316impl fmt::Display for Constness {
4317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4318 f.write_str(match *self {
4319 Self::Const => "const",
4320 Self::NotConst => "non-const",
4321 })
4322 }
4323}
4324
4325#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
4330pub enum HeaderSafety {
4331 SafeTargetFeatures,
4337 Normal(Safety),
4338}
4339
4340impl From<Safety> for HeaderSafety {
4341 fn from(v: Safety) -> Self {
4342 Self::Normal(v)
4343 }
4344}
4345
4346#[derive(Copy, Clone, Debug, HashStable_Generic)]
4347pub struct FnHeader {
4348 pub safety: HeaderSafety,
4349 pub constness: Constness,
4350 pub asyncness: IsAsync,
4351 pub abi: ExternAbi,
4352}
4353
4354impl FnHeader {
4355 pub fn is_async(&self) -> bool {
4356 matches!(self.asyncness, IsAsync::Async(_))
4357 }
4358
4359 pub fn is_const(&self) -> bool {
4360 matches!(self.constness, Constness::Const)
4361 }
4362
4363 pub fn is_unsafe(&self) -> bool {
4364 self.safety().is_unsafe()
4365 }
4366
4367 pub fn is_safe(&self) -> bool {
4368 self.safety().is_safe()
4369 }
4370
4371 pub fn safety(&self) -> Safety {
4372 match self.safety {
4373 HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
4374 HeaderSafety::Normal(safety) => safety,
4375 }
4376 }
4377}
4378
4379#[derive(Debug, Clone, Copy, HashStable_Generic)]
4380pub enum ItemKind<'hir> {
4381 ExternCrate(Option<Symbol>, Ident),
4385
4386 Use(&'hir UsePath<'hir>, UseKind),
4392
4393 Static(Mutability, Ident, &'hir Ty<'hir>, BodyId),
4395 Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>),
4397 Fn {
4399 sig: FnSig<'hir>,
4400 ident: Ident,
4401 generics: &'hir Generics<'hir>,
4402 body: BodyId,
4403 has_body: bool,
4407 },
4408 Macro(Ident, &'hir ast::MacroDef, MacroKinds),
4410 Mod(Ident, &'hir Mod<'hir>),
4412 ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] },
4414 GlobalAsm {
4416 asm: &'hir InlineAsm<'hir>,
4417 fake_body: BodyId,
4423 },
4424 TyAlias(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4426 Enum(Ident, &'hir Generics<'hir>, EnumDef<'hir>),
4428 Struct(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4430 Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4432 Trait(
4434 Constness,
4435 IsAuto,
4436 Safety,
4437 Ident,
4438 &'hir Generics<'hir>,
4439 GenericBounds<'hir>,
4440 &'hir [TraitItemId],
4441 ),
4442 TraitAlias(Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4444
4445 Impl(Impl<'hir>),
4447}
4448
4449#[derive(Debug, Clone, Copy, HashStable_Generic)]
4454pub struct Impl<'hir> {
4455 pub generics: &'hir Generics<'hir>,
4456 pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
4457 pub self_ty: &'hir Ty<'hir>,
4458 pub items: &'hir [ImplItemId],
4459 pub constness: Constness,
4460}
4461
4462#[derive(Debug, Clone, Copy, HashStable_Generic)]
4463pub struct TraitImplHeader<'hir> {
4464 pub safety: Safety,
4465 pub polarity: ImplPolarity,
4466 pub defaultness: Defaultness,
4467 pub defaultness_span: Option<Span>,
4470 pub trait_ref: TraitRef<'hir>,
4471}
4472
4473impl ItemKind<'_> {
4474 pub fn ident(&self) -> Option<Ident> {
4475 match *self {
4476 ItemKind::ExternCrate(_, ident)
4477 | ItemKind::Use(_, UseKind::Single(ident))
4478 | ItemKind::Static(_, ident, ..)
4479 | ItemKind::Const(ident, ..)
4480 | ItemKind::Fn { ident, .. }
4481 | ItemKind::Macro(ident, ..)
4482 | ItemKind::Mod(ident, ..)
4483 | ItemKind::TyAlias(ident, ..)
4484 | ItemKind::Enum(ident, ..)
4485 | ItemKind::Struct(ident, ..)
4486 | ItemKind::Union(ident, ..)
4487 | ItemKind::Trait(_, _, _, ident, ..)
4488 | ItemKind::TraitAlias(_, ident, ..) => Some(ident),
4489
4490 ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
4491 | ItemKind::ForeignMod { .. }
4492 | ItemKind::GlobalAsm { .. }
4493 | ItemKind::Impl(_) => None,
4494 }
4495 }
4496
4497 pub fn generics(&self) -> Option<&Generics<'_>> {
4498 Some(match self {
4499 ItemKind::Fn { generics, .. }
4500 | ItemKind::TyAlias(_, generics, _)
4501 | ItemKind::Const(_, generics, _, _)
4502 | ItemKind::Enum(_, generics, _)
4503 | ItemKind::Struct(_, generics, _)
4504 | ItemKind::Union(_, generics, _)
4505 | ItemKind::Trait(_, _, _, _, generics, _, _)
4506 | ItemKind::TraitAlias(_, _, generics, _)
4507 | ItemKind::Impl(Impl { generics, .. }) => generics,
4508 _ => return None,
4509 })
4510 }
4511}
4512
4513#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4517pub struct ForeignItemId {
4518 pub owner_id: OwnerId,
4519}
4520
4521impl ForeignItemId {
4522 #[inline]
4523 pub fn hir_id(&self) -> HirId {
4524 HirId::make_owner(self.owner_id.def_id)
4526 }
4527}
4528
4529#[derive(Debug, Clone, Copy, HashStable_Generic)]
4530pub struct ForeignItem<'hir> {
4531 pub ident: Ident,
4532 pub kind: ForeignItemKind<'hir>,
4533 pub owner_id: OwnerId,
4534 pub span: Span,
4535 pub vis_span: Span,
4536 pub has_delayed_lints: bool,
4537}
4538
4539impl ForeignItem<'_> {
4540 #[inline]
4541 pub fn hir_id(&self) -> HirId {
4542 HirId::make_owner(self.owner_id.def_id)
4544 }
4545
4546 pub fn foreign_item_id(&self) -> ForeignItemId {
4547 ForeignItemId { owner_id: self.owner_id }
4548 }
4549}
4550
4551#[derive(Debug, Clone, Copy, HashStable_Generic)]
4553pub enum ForeignItemKind<'hir> {
4554 Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
4561 Static(&'hir Ty<'hir>, Mutability, Safety),
4563 Type,
4565}
4566
4567#[derive(Debug, Copy, Clone, HashStable_Generic)]
4569pub struct Upvar {
4570 pub span: Span,
4572}
4573
4574#[derive(Debug, Clone, HashStable_Generic)]
4578pub struct TraitCandidate {
4579 pub def_id: DefId,
4580 pub import_ids: SmallVec<[LocalDefId; 1]>,
4581}
4582
4583#[derive(Copy, Clone, Debug, HashStable_Generic)]
4584pub enum OwnerNode<'hir> {
4585 Item(&'hir Item<'hir>),
4586 ForeignItem(&'hir ForeignItem<'hir>),
4587 TraitItem(&'hir TraitItem<'hir>),
4588 ImplItem(&'hir ImplItem<'hir>),
4589 Crate(&'hir Mod<'hir>),
4590 Synthetic,
4591}
4592
4593impl<'hir> OwnerNode<'hir> {
4594 pub fn span(&self) -> Span {
4595 match self {
4596 OwnerNode::Item(Item { span, .. })
4597 | OwnerNode::ForeignItem(ForeignItem { span, .. })
4598 | OwnerNode::ImplItem(ImplItem { span, .. })
4599 | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4600 OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4601 OwnerNode::Synthetic => unreachable!(),
4602 }
4603 }
4604
4605 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4606 match self {
4607 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4608 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4609 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4610 | OwnerNode::ForeignItem(ForeignItem {
4611 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4612 }) => Some(fn_sig),
4613 _ => None,
4614 }
4615 }
4616
4617 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4618 match self {
4619 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4620 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4621 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4622 | OwnerNode::ForeignItem(ForeignItem {
4623 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4624 }) => Some(fn_sig.decl),
4625 _ => None,
4626 }
4627 }
4628
4629 pub fn body_id(&self) -> Option<BodyId> {
4630 match self {
4631 OwnerNode::Item(Item {
4632 kind:
4633 ItemKind::Static(_, _, _, body)
4634 | ItemKind::Const(.., ConstItemRhs::Body(body))
4635 | ItemKind::Fn { body, .. },
4636 ..
4637 })
4638 | OwnerNode::TraitItem(TraitItem {
4639 kind:
4640 TraitItemKind::Fn(_, TraitFn::Provided(body))
4641 | TraitItemKind::Const(_, Some(ConstItemRhs::Body(body))),
4642 ..
4643 })
4644 | OwnerNode::ImplItem(ImplItem {
4645 kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, ConstItemRhs::Body(body)),
4646 ..
4647 }) => Some(*body),
4648 _ => None,
4649 }
4650 }
4651
4652 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4653 Node::generics(self.into())
4654 }
4655
4656 pub fn def_id(self) -> OwnerId {
4657 match self {
4658 OwnerNode::Item(Item { owner_id, .. })
4659 | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4660 | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4661 | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4662 OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4663 OwnerNode::Synthetic => unreachable!(),
4664 }
4665 }
4666
4667 pub fn is_impl_block(&self) -> bool {
4669 matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4670 }
4671
4672 expect_methods_self! {
4673 expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
4674 expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4675 expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n;
4676 expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n;
4677 }
4678}
4679
4680impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4681 fn from(val: &'hir Item<'hir>) -> Self {
4682 OwnerNode::Item(val)
4683 }
4684}
4685
4686impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4687 fn from(val: &'hir ForeignItem<'hir>) -> Self {
4688 OwnerNode::ForeignItem(val)
4689 }
4690}
4691
4692impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4693 fn from(val: &'hir ImplItem<'hir>) -> Self {
4694 OwnerNode::ImplItem(val)
4695 }
4696}
4697
4698impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4699 fn from(val: &'hir TraitItem<'hir>) -> Self {
4700 OwnerNode::TraitItem(val)
4701 }
4702}
4703
4704impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4705 fn from(val: OwnerNode<'hir>) -> Self {
4706 match val {
4707 OwnerNode::Item(n) => Node::Item(n),
4708 OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4709 OwnerNode::ImplItem(n) => Node::ImplItem(n),
4710 OwnerNode::TraitItem(n) => Node::TraitItem(n),
4711 OwnerNode::Crate(n) => Node::Crate(n),
4712 OwnerNode::Synthetic => Node::Synthetic,
4713 }
4714 }
4715}
4716
4717#[derive(Copy, Clone, Debug, HashStable_Generic)]
4718pub enum Node<'hir> {
4719 Param(&'hir Param<'hir>),
4720 Item(&'hir Item<'hir>),
4721 ForeignItem(&'hir ForeignItem<'hir>),
4722 TraitItem(&'hir TraitItem<'hir>),
4723 ImplItem(&'hir ImplItem<'hir>),
4724 Variant(&'hir Variant<'hir>),
4725 Field(&'hir FieldDef<'hir>),
4726 AnonConst(&'hir AnonConst),
4727 ConstBlock(&'hir ConstBlock),
4728 ConstArg(&'hir ConstArg<'hir>),
4729 Expr(&'hir Expr<'hir>),
4730 ExprField(&'hir ExprField<'hir>),
4731 ConstArgExprField(&'hir ConstArgExprField<'hir>),
4732 Stmt(&'hir Stmt<'hir>),
4733 PathSegment(&'hir PathSegment<'hir>),
4734 Ty(&'hir Ty<'hir>),
4735 AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4736 TraitRef(&'hir TraitRef<'hir>),
4737 OpaqueTy(&'hir OpaqueTy<'hir>),
4738 TyPat(&'hir TyPat<'hir>),
4739 Pat(&'hir Pat<'hir>),
4740 PatField(&'hir PatField<'hir>),
4741 PatExpr(&'hir PatExpr<'hir>),
4745 Arm(&'hir Arm<'hir>),
4746 Block(&'hir Block<'hir>),
4747 LetStmt(&'hir LetStmt<'hir>),
4748 Ctor(&'hir VariantData<'hir>),
4751 Lifetime(&'hir Lifetime),
4752 GenericParam(&'hir GenericParam<'hir>),
4753 Crate(&'hir Mod<'hir>),
4754 Infer(&'hir InferArg),
4755 WherePredicate(&'hir WherePredicate<'hir>),
4756 PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4757 Synthetic,
4759 Err(Span),
4760}
4761
4762impl<'hir> Node<'hir> {
4763 pub fn ident(&self) -> Option<Ident> {
4778 match self {
4779 Node::Item(item) => item.kind.ident(),
4780 Node::TraitItem(TraitItem { ident, .. })
4781 | Node::ImplItem(ImplItem { ident, .. })
4782 | Node::ForeignItem(ForeignItem { ident, .. })
4783 | Node::Field(FieldDef { ident, .. })
4784 | Node::Variant(Variant { ident, .. })
4785 | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4786 Node::Lifetime(lt) => Some(lt.ident),
4787 Node::GenericParam(p) => Some(p.name.ident()),
4788 Node::AssocItemConstraint(c) => Some(c.ident),
4789 Node::PatField(f) => Some(f.ident),
4790 Node::ExprField(f) => Some(f.ident),
4791 Node::ConstArgExprField(f) => Some(f.field),
4792 Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4793 Node::Param(..)
4794 | Node::AnonConst(..)
4795 | Node::ConstBlock(..)
4796 | Node::ConstArg(..)
4797 | Node::Expr(..)
4798 | Node::Stmt(..)
4799 | Node::Block(..)
4800 | Node::Ctor(..)
4801 | Node::Pat(..)
4802 | Node::TyPat(..)
4803 | Node::PatExpr(..)
4804 | Node::Arm(..)
4805 | Node::LetStmt(..)
4806 | Node::Crate(..)
4807 | Node::Ty(..)
4808 | Node::TraitRef(..)
4809 | Node::OpaqueTy(..)
4810 | Node::Infer(..)
4811 | Node::WherePredicate(..)
4812 | Node::Synthetic
4813 | Node::Err(..) => None,
4814 }
4815 }
4816
4817 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4818 match self {
4819 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4820 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4821 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4822 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4823 Some(fn_sig.decl)
4824 }
4825 Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4826 Some(fn_decl)
4827 }
4828 _ => None,
4829 }
4830 }
4831
4832 pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4834 if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4835 && let Some(of_trait) = impl_block.of_trait
4836 && let Some(trait_id) = of_trait.trait_ref.trait_def_id()
4837 && trait_id == trait_def_id
4838 {
4839 Some(impl_block)
4840 } else {
4841 None
4842 }
4843 }
4844
4845 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4846 match self {
4847 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4848 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4849 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4850 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4851 Some(fn_sig)
4852 }
4853 _ => None,
4854 }
4855 }
4856
4857 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4859 match self {
4860 Node::Item(it) => match it.kind {
4861 ItemKind::TyAlias(_, _, ty)
4862 | ItemKind::Static(_, _, ty, _)
4863 | ItemKind::Const(_, _, ty, _) => Some(ty),
4864 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4865 _ => None,
4866 },
4867 Node::TraitItem(it) => match it.kind {
4868 TraitItemKind::Const(ty, _) => Some(ty),
4869 TraitItemKind::Type(_, ty) => ty,
4870 _ => None,
4871 },
4872 Node::ImplItem(it) => match it.kind {
4873 ImplItemKind::Const(ty, _) => Some(ty),
4874 ImplItemKind::Type(ty) => Some(ty),
4875 _ => None,
4876 },
4877 Node::ForeignItem(it) => match it.kind {
4878 ForeignItemKind::Static(ty, ..) => Some(ty),
4879 _ => None,
4880 },
4881 Node::GenericParam(param) => match param.kind {
4882 GenericParamKind::Lifetime { .. } => None,
4883 GenericParamKind::Type { default, .. } => default,
4884 GenericParamKind::Const { ty, .. } => Some(ty),
4885 },
4886 _ => None,
4887 }
4888 }
4889
4890 pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4891 match self {
4892 Node::Item(Item { kind: ItemKind::TyAlias(_, _, ty), .. }) => Some(ty),
4893 _ => None,
4894 }
4895 }
4896
4897 #[inline]
4898 pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4899 match self {
4900 Node::Item(Item {
4901 owner_id,
4902 kind:
4903 ItemKind::Const(.., ConstItemRhs::Body(body))
4904 | ItemKind::Static(.., body)
4905 | ItemKind::Fn { body, .. },
4906 ..
4907 })
4908 | Node::TraitItem(TraitItem {
4909 owner_id,
4910 kind:
4911 TraitItemKind::Const(.., Some(ConstItemRhs::Body(body)))
4912 | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4913 ..
4914 })
4915 | Node::ImplItem(ImplItem {
4916 owner_id,
4917 kind: ImplItemKind::Const(.., ConstItemRhs::Body(body)) | ImplItemKind::Fn(_, body),
4918 ..
4919 }) => Some((owner_id.def_id, *body)),
4920
4921 Node::Item(Item {
4922 owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4923 }) => Some((owner_id.def_id, *fake_body)),
4924
4925 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4926 Some((*def_id, *body))
4927 }
4928
4929 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4930 Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4931
4932 _ => None,
4933 }
4934 }
4935
4936 pub fn body_id(&self) -> Option<BodyId> {
4937 Some(self.associated_body()?.1)
4938 }
4939
4940 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4941 match self {
4942 Node::ForeignItem(ForeignItem {
4943 kind: ForeignItemKind::Fn(_, _, generics), ..
4944 })
4945 | Node::TraitItem(TraitItem { generics, .. })
4946 | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4947 Node::Item(item) => item.kind.generics(),
4948 _ => None,
4949 }
4950 }
4951
4952 pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4953 match self {
4954 Node::Item(i) => Some(OwnerNode::Item(i)),
4955 Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4956 Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4957 Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4958 Node::Crate(i) => Some(OwnerNode::Crate(i)),
4959 Node::Synthetic => Some(OwnerNode::Synthetic),
4960 _ => None,
4961 }
4962 }
4963
4964 pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4965 match self {
4966 Node::Item(i) => match i.kind {
4967 ItemKind::Fn { ident, sig, generics, .. } => {
4968 Some(FnKind::ItemFn(ident, generics, sig.header))
4969 }
4970 _ => None,
4971 },
4972 Node::TraitItem(ti) => match ti.kind {
4973 TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4974 _ => None,
4975 },
4976 Node::ImplItem(ii) => match ii.kind {
4977 ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4978 _ => None,
4979 },
4980 Node::Expr(e) => match e.kind {
4981 ExprKind::Closure { .. } => Some(FnKind::Closure),
4982 _ => None,
4983 },
4984 _ => None,
4985 }
4986 }
4987
4988 expect_methods_self! {
4989 expect_param, &'hir Param<'hir>, Node::Param(n), n;
4990 expect_item, &'hir Item<'hir>, Node::Item(n), n;
4991 expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n;
4992 expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n;
4993 expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n;
4994 expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
4995 expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
4996 expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
4997 expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
4998 expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
4999 expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
5000 expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
5001 expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
5002 expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
5003 expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
5004 expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
5005 expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
5006 expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
5007 expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
5008 expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
5009 expect_block, &'hir Block<'hir>, Node::Block(n), n;
5010 expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
5011 expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
5012 expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
5013 expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
5014 expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
5015 expect_infer, &'hir InferArg, Node::Infer(n), n;
5016 expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
5017 }
5018}
5019
5020#[cfg(target_pointer_width = "64")]
5022mod size_asserts {
5023 use rustc_data_structures::static_assert_size;
5024
5025 use super::*;
5026 static_assert_size!(Block<'_>, 48);
5028 static_assert_size!(Body<'_>, 24);
5029 static_assert_size!(Expr<'_>, 64);
5030 static_assert_size!(ExprKind<'_>, 48);
5031 static_assert_size!(FnDecl<'_>, 40);
5032 static_assert_size!(ForeignItem<'_>, 96);
5033 static_assert_size!(ForeignItemKind<'_>, 56);
5034 static_assert_size!(GenericArg<'_>, 16);
5035 static_assert_size!(GenericBound<'_>, 64);
5036 static_assert_size!(Generics<'_>, 56);
5037 static_assert_size!(Impl<'_>, 48);
5038 static_assert_size!(ImplItem<'_>, 88);
5039 static_assert_size!(ImplItemKind<'_>, 40);
5040 static_assert_size!(Item<'_>, 88);
5041 static_assert_size!(ItemKind<'_>, 64);
5042 static_assert_size!(LetStmt<'_>, 64);
5043 static_assert_size!(Param<'_>, 32);
5044 static_assert_size!(Pat<'_>, 80);
5045 static_assert_size!(PatKind<'_>, 56);
5046 static_assert_size!(Path<'_>, 40);
5047 static_assert_size!(PathSegment<'_>, 48);
5048 static_assert_size!(QPath<'_>, 24);
5049 static_assert_size!(Res, 12);
5050 static_assert_size!(Stmt<'_>, 32);
5051 static_assert_size!(StmtKind<'_>, 16);
5052 static_assert_size!(TraitImplHeader<'_>, 48);
5053 static_assert_size!(TraitItem<'_>, 88);
5054 static_assert_size!(TraitItemKind<'_>, 48);
5055 static_assert_size!(Ty<'_>, 48);
5056 static_assert_size!(TyKind<'_>, 32);
5057 }
5059
5060#[cfg(test)]
5061mod tests;