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