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) => {
1302 n.path.segments.len() == name.len()
1303 && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
1304 }
1305 _ => false,
1306 }
1307 }
1308
1309 #[inline]
1310 fn is_doc_comment(&self) -> bool {
1311 matches!(self, Attribute::Parsed(AttributeKind::DocComment { .. }))
1312 }
1313
1314 #[inline]
1315 fn span(&self) -> Span {
1316 match &self {
1317 Attribute::Unparsed(u) => u.span,
1318 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1320 Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
1321 Attribute::Parsed(AttributeKind::AllowInternalUnsafe(span)) => *span,
1322 Attribute::Parsed(AttributeKind::Linkage(_, span)) => *span,
1323 a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
1324 }
1325 }
1326
1327 #[inline]
1328 fn is_word(&self) -> bool {
1329 match &self {
1330 Attribute::Unparsed(n) => {
1331 matches!(n.args, AttrArgs::Empty)
1332 }
1333 _ => false,
1334 }
1335 }
1336
1337 #[inline]
1338 fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1339 match &self {
1340 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
1341 _ => None,
1342 }
1343 }
1344
1345 #[inline]
1346 fn doc_str(&self) -> Option<Symbol> {
1347 match &self {
1348 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
1349 Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(),
1350 _ => None,
1351 }
1352 }
1353
1354 fn is_automatically_derived_attr(&self) -> bool {
1355 matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
1356 }
1357
1358 #[inline]
1359 fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1360 match &self {
1361 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
1362 Some((*comment, *kind))
1363 }
1364 Attribute::Unparsed(_) if self.has_name(sym::doc) => {
1365 self.value_str().map(|s| (s, CommentKind::Line))
1366 }
1367 _ => None,
1368 }
1369 }
1370
1371 fn doc_resolution_scope(&self) -> Option<AttrStyle> {
1372 match self {
1373 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
1374 Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
1375 Some(attr.style)
1376 }
1377 _ => None,
1378 }
1379 }
1380
1381 fn is_proc_macro_attr(&self) -> bool {
1382 matches!(
1383 self,
1384 Attribute::Parsed(
1385 AttributeKind::ProcMacro(..)
1386 | AttributeKind::ProcMacroAttribute(..)
1387 | AttributeKind::ProcMacroDerive { .. }
1388 )
1389 )
1390 }
1391}
1392
1393impl Attribute {
1395 #[inline]
1396 pub fn id(&self) -> AttrId {
1397 AttributeExt::id(self)
1398 }
1399
1400 #[inline]
1401 pub fn name(&self) -> Option<Symbol> {
1402 AttributeExt::name(self)
1403 }
1404
1405 #[inline]
1406 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1407 AttributeExt::meta_item_list(self)
1408 }
1409
1410 #[inline]
1411 pub fn value_str(&self) -> Option<Symbol> {
1412 AttributeExt::value_str(self)
1413 }
1414
1415 #[inline]
1416 pub fn value_span(&self) -> Option<Span> {
1417 AttributeExt::value_span(self)
1418 }
1419
1420 #[inline]
1421 pub fn ident(&self) -> Option<Ident> {
1422 AttributeExt::ident(self)
1423 }
1424
1425 #[inline]
1426 pub fn path_matches(&self, name: &[Symbol]) -> bool {
1427 AttributeExt::path_matches(self, name)
1428 }
1429
1430 #[inline]
1431 pub fn is_doc_comment(&self) -> bool {
1432 AttributeExt::is_doc_comment(self)
1433 }
1434
1435 #[inline]
1436 pub fn has_name(&self, name: Symbol) -> bool {
1437 AttributeExt::has_name(self, name)
1438 }
1439
1440 #[inline]
1441 pub fn has_any_name(&self, names: &[Symbol]) -> bool {
1442 AttributeExt::has_any_name(self, names)
1443 }
1444
1445 #[inline]
1446 pub fn span(&self) -> Span {
1447 AttributeExt::span(self)
1448 }
1449
1450 #[inline]
1451 pub fn is_word(&self) -> bool {
1452 AttributeExt::is_word(self)
1453 }
1454
1455 #[inline]
1456 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1457 AttributeExt::path(self)
1458 }
1459
1460 #[inline]
1461 pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1462 AttributeExt::ident_path(self)
1463 }
1464
1465 #[inline]
1466 pub fn doc_str(&self) -> Option<Symbol> {
1467 AttributeExt::doc_str(self)
1468 }
1469
1470 #[inline]
1471 pub fn is_proc_macro_attr(&self) -> bool {
1472 AttributeExt::is_proc_macro_attr(self)
1473 }
1474
1475 #[inline]
1476 pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1477 AttributeExt::doc_str_and_comment_kind(self)
1478 }
1479}
1480
1481#[derive(Debug)]
1483pub struct AttributeMap<'tcx> {
1484 pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1485 pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
1487 pub opt_hash: Option<Fingerprint>,
1489}
1490
1491impl<'tcx> AttributeMap<'tcx> {
1492 pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1493 map: SortedMap::new(),
1494 opt_hash: Some(Fingerprint::ZERO),
1495 define_opaque: None,
1496 };
1497
1498 #[inline]
1499 pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1500 self.map.get(&id).copied().unwrap_or(&[])
1501 }
1502}
1503
1504pub struct OwnerNodes<'tcx> {
1508 pub opt_hash_including_bodies: Option<Fingerprint>,
1511 pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1516 pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1518}
1519
1520impl<'tcx> OwnerNodes<'tcx> {
1521 pub fn node(&self) -> OwnerNode<'tcx> {
1522 self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1524 }
1525}
1526
1527impl fmt::Debug for OwnerNodes<'_> {
1528 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1529 f.debug_struct("OwnerNodes")
1530 .field("node", &self.nodes[ItemLocalId::ZERO])
1532 .field(
1533 "parents",
1534 &fmt::from_fn(|f| {
1535 f.debug_list()
1536 .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1537 fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1538 }))
1539 .finish()
1540 }),
1541 )
1542 .field("bodies", &self.bodies)
1543 .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1544 .finish()
1545 }
1546}
1547
1548#[derive(Debug, HashStable_Generic)]
1550pub struct OwnerInfo<'hir> {
1551 pub nodes: OwnerNodes<'hir>,
1553 pub parenting: LocalDefIdMap<ItemLocalId>,
1555 pub attrs: AttributeMap<'hir>,
1557 pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1560
1561 pub delayed_lints: DelayedLints,
1564}
1565
1566impl<'tcx> OwnerInfo<'tcx> {
1567 #[inline]
1568 pub fn node(&self) -> OwnerNode<'tcx> {
1569 self.nodes.node()
1570 }
1571}
1572
1573#[derive(Copy, Clone, Debug, HashStable_Generic)]
1574pub enum MaybeOwner<'tcx> {
1575 Owner(&'tcx OwnerInfo<'tcx>),
1576 NonOwner(HirId),
1577 Phantom,
1579}
1580
1581impl<'tcx> MaybeOwner<'tcx> {
1582 pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1583 match self {
1584 MaybeOwner::Owner(i) => Some(i),
1585 MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1586 }
1587 }
1588
1589 pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1590 self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1591 }
1592}
1593
1594#[derive(Debug)]
1601pub struct Crate<'hir> {
1602 pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1603 pub opt_hir_hash: Option<Fingerprint>,
1605}
1606
1607#[derive(Debug, Clone, Copy, HashStable_Generic)]
1608pub struct Closure<'hir> {
1609 pub def_id: LocalDefId,
1610 pub binder: ClosureBinder,
1611 pub constness: Constness,
1612 pub capture_clause: CaptureBy,
1613 pub bound_generic_params: &'hir [GenericParam<'hir>],
1614 pub fn_decl: &'hir FnDecl<'hir>,
1615 pub body: BodyId,
1616 pub fn_decl_span: Span,
1618 pub fn_arg_span: Option<Span>,
1620 pub kind: ClosureKind,
1621}
1622
1623#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1624pub enum ClosureKind {
1625 Closure,
1627 Coroutine(CoroutineKind),
1632 CoroutineClosure(CoroutineDesugaring),
1637}
1638
1639#[derive(Debug, Clone, Copy, HashStable_Generic)]
1643pub struct Block<'hir> {
1644 pub stmts: &'hir [Stmt<'hir>],
1646 pub expr: Option<&'hir Expr<'hir>>,
1649 #[stable_hasher(ignore)]
1650 pub hir_id: HirId,
1651 pub rules: BlockCheckMode,
1653 pub span: Span,
1655 pub targeted_by_break: bool,
1659}
1660
1661impl<'hir> Block<'hir> {
1662 pub fn innermost_block(&self) -> &Block<'hir> {
1663 let mut block = self;
1664 while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1665 block = inner_block;
1666 }
1667 block
1668 }
1669}
1670
1671#[derive(Debug, Clone, Copy, HashStable_Generic)]
1672pub struct TyPat<'hir> {
1673 #[stable_hasher(ignore)]
1674 pub hir_id: HirId,
1675 pub kind: TyPatKind<'hir>,
1676 pub span: Span,
1677}
1678
1679#[derive(Debug, Clone, Copy, HashStable_Generic)]
1680pub struct Pat<'hir> {
1681 #[stable_hasher(ignore)]
1682 pub hir_id: HirId,
1683 pub kind: PatKind<'hir>,
1684 pub span: Span,
1685 pub default_binding_modes: bool,
1688}
1689
1690impl<'hir> Pat<'hir> {
1691 fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1692 if !it(self) {
1693 return false;
1694 }
1695
1696 use PatKind::*;
1697 match self.kind {
1698 Missing => unreachable!(),
1699 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1700 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
1701 Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1702 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1703 Slice(before, slice, after) => {
1704 before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1705 }
1706 }
1707 }
1708
1709 pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1716 self.walk_short_(&mut it)
1717 }
1718
1719 fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1720 if !it(self) {
1721 return;
1722 }
1723
1724 use PatKind::*;
1725 match self.kind {
1726 Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1727 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1728 Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1729 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1730 Slice(before, slice, after) => {
1731 before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1732 }
1733 }
1734 }
1735
1736 pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1740 self.walk_(&mut it)
1741 }
1742
1743 pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1747 self.walk(|p| {
1748 it(p);
1749 true
1750 })
1751 }
1752
1753 pub fn is_never_pattern(&self) -> bool {
1755 let mut is_never_pattern = false;
1756 self.walk(|pat| match &pat.kind {
1757 PatKind::Never => {
1758 is_never_pattern = true;
1759 false
1760 }
1761 PatKind::Or(s) => {
1762 is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1763 false
1764 }
1765 _ => true,
1766 });
1767 is_never_pattern
1768 }
1769}
1770
1771#[derive(Debug, Clone, Copy, HashStable_Generic)]
1777pub struct PatField<'hir> {
1778 #[stable_hasher(ignore)]
1779 pub hir_id: HirId,
1780 pub ident: Ident,
1782 pub pat: &'hir Pat<'hir>,
1784 pub is_shorthand: bool,
1785 pub span: Span,
1786}
1787
1788#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
1789pub enum RangeEnd {
1790 Included,
1791 Excluded,
1792}
1793
1794impl fmt::Display for RangeEnd {
1795 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1796 f.write_str(match self {
1797 RangeEnd::Included => "..=",
1798 RangeEnd::Excluded => "..",
1799 })
1800 }
1801}
1802
1803#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1807pub struct DotDotPos(u32);
1808
1809impl DotDotPos {
1810 pub fn new(n: Option<usize>) -> Self {
1812 match n {
1813 Some(n) => {
1814 assert!(n < u32::MAX as usize);
1815 Self(n as u32)
1816 }
1817 None => Self(u32::MAX),
1818 }
1819 }
1820
1821 pub fn as_opt_usize(&self) -> Option<usize> {
1822 if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1823 }
1824}
1825
1826impl fmt::Debug for DotDotPos {
1827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828 self.as_opt_usize().fmt(f)
1829 }
1830}
1831
1832#[derive(Debug, Clone, Copy, HashStable_Generic)]
1833pub struct PatExpr<'hir> {
1834 #[stable_hasher(ignore)]
1835 pub hir_id: HirId,
1836 pub span: Span,
1837 pub kind: PatExprKind<'hir>,
1838}
1839
1840#[derive(Debug, Clone, Copy, HashStable_Generic)]
1841pub enum PatExprKind<'hir> {
1842 Lit {
1843 lit: Lit,
1844 negated: bool,
1847 },
1848 ConstBlock(ConstBlock),
1849 Path(QPath<'hir>),
1851}
1852
1853#[derive(Debug, Clone, Copy, HashStable_Generic)]
1854pub enum TyPatKind<'hir> {
1855 Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
1857
1858 Or(&'hir [TyPat<'hir>]),
1860
1861 Err(ErrorGuaranteed),
1863}
1864
1865#[derive(Debug, Clone, Copy, HashStable_Generic)]
1866pub enum PatKind<'hir> {
1867 Missing,
1869
1870 Wild,
1872
1873 Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1884
1885 Struct(QPath<'hir>, &'hir [PatField<'hir>], Option<Span>),
1888
1889 TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1893
1894 Or(&'hir [Pat<'hir>]),
1897
1898 Never,
1900
1901 Tuple(&'hir [Pat<'hir>], DotDotPos),
1905
1906 Box(&'hir Pat<'hir>),
1908
1909 Deref(&'hir Pat<'hir>),
1911
1912 Ref(&'hir Pat<'hir>, Mutability),
1914
1915 Expr(&'hir PatExpr<'hir>),
1917
1918 Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1920
1921 Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
1923
1924 Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
1934
1935 Err(ErrorGuaranteed),
1937}
1938
1939#[derive(Debug, Clone, Copy, HashStable_Generic)]
1941pub struct Stmt<'hir> {
1942 #[stable_hasher(ignore)]
1943 pub hir_id: HirId,
1944 pub kind: StmtKind<'hir>,
1945 pub span: Span,
1946}
1947
1948#[derive(Debug, Clone, Copy, HashStable_Generic)]
1950pub enum StmtKind<'hir> {
1951 Let(&'hir LetStmt<'hir>),
1953
1954 Item(ItemId),
1956
1957 Expr(&'hir Expr<'hir>),
1959
1960 Semi(&'hir Expr<'hir>),
1962}
1963
1964#[derive(Debug, Clone, Copy, HashStable_Generic)]
1966pub struct LetStmt<'hir> {
1967 pub super_: Option<Span>,
1969 pub pat: &'hir Pat<'hir>,
1970 pub ty: Option<&'hir Ty<'hir>>,
1972 pub init: Option<&'hir Expr<'hir>>,
1974 pub els: Option<&'hir Block<'hir>>,
1976 #[stable_hasher(ignore)]
1977 pub hir_id: HirId,
1978 pub span: Span,
1979 pub source: LocalSource,
1983}
1984
1985#[derive(Debug, Clone, Copy, HashStable_Generic)]
1988pub struct Arm<'hir> {
1989 #[stable_hasher(ignore)]
1990 pub hir_id: HirId,
1991 pub span: Span,
1992 pub pat: &'hir Pat<'hir>,
1994 pub guard: Option<&'hir Expr<'hir>>,
1996 pub body: &'hir Expr<'hir>,
1998}
1999
2000#[derive(Debug, Clone, Copy, HashStable_Generic)]
2006pub struct LetExpr<'hir> {
2007 pub span: Span,
2008 pub pat: &'hir Pat<'hir>,
2009 pub ty: Option<&'hir Ty<'hir>>,
2010 pub init: &'hir Expr<'hir>,
2011 pub recovered: ast::Recovered,
2014}
2015
2016#[derive(Debug, Clone, Copy, HashStable_Generic)]
2017pub struct ExprField<'hir> {
2018 #[stable_hasher(ignore)]
2019 pub hir_id: HirId,
2020 pub ident: Ident,
2021 pub expr: &'hir Expr<'hir>,
2022 pub span: Span,
2023 pub is_shorthand: bool,
2024}
2025
2026#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2027pub enum BlockCheckMode {
2028 DefaultBlock,
2029 UnsafeBlock(UnsafeSource),
2030}
2031
2032#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2033pub enum UnsafeSource {
2034 CompilerGenerated,
2035 UserProvided,
2036}
2037
2038#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
2039pub struct BodyId {
2040 pub hir_id: HirId,
2041}
2042
2043#[derive(Debug, Clone, Copy, HashStable_Generic)]
2065pub struct Body<'hir> {
2066 pub params: &'hir [Param<'hir>],
2067 pub value: &'hir Expr<'hir>,
2068}
2069
2070impl<'hir> Body<'hir> {
2071 pub fn id(&self) -> BodyId {
2072 BodyId { hir_id: self.value.hir_id }
2073 }
2074}
2075
2076#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2078pub enum CoroutineKind {
2079 Desugared(CoroutineDesugaring, CoroutineSource),
2081
2082 Coroutine(Movability),
2084}
2085
2086impl CoroutineKind {
2087 pub fn movability(self) -> Movability {
2088 match self {
2089 CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
2090 | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
2091 CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
2092 CoroutineKind::Coroutine(mov) => mov,
2093 }
2094 }
2095
2096 pub fn is_fn_like(self) -> bool {
2097 matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
2098 }
2099
2100 pub fn to_plural_string(&self) -> String {
2101 match self {
2102 CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"),
2103 CoroutineKind::Desugared(d, CoroutineSource::Block) => format!("{d:#}blocks"),
2104 CoroutineKind::Desugared(d, CoroutineSource::Closure) => format!("{d:#}closure bodies"),
2105 CoroutineKind::Coroutine(_) => "coroutines".to_string(),
2106 }
2107 }
2108}
2109
2110impl fmt::Display for CoroutineKind {
2111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2112 match self {
2113 CoroutineKind::Desugared(d, k) => {
2114 d.fmt(f)?;
2115 k.fmt(f)
2116 }
2117 CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
2118 }
2119 }
2120}
2121
2122#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
2128pub enum CoroutineSource {
2129 Block,
2131
2132 Closure,
2134
2135 Fn,
2137}
2138
2139impl fmt::Display for CoroutineSource {
2140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2141 match self {
2142 CoroutineSource::Block => "block",
2143 CoroutineSource::Closure => "closure body",
2144 CoroutineSource::Fn => "fn body",
2145 }
2146 .fmt(f)
2147 }
2148}
2149
2150#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2151pub enum CoroutineDesugaring {
2152 Async,
2154
2155 Gen,
2157
2158 AsyncGen,
2161}
2162
2163impl fmt::Display for CoroutineDesugaring {
2164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2165 match self {
2166 CoroutineDesugaring::Async => {
2167 if f.alternate() {
2168 f.write_str("`async` ")?;
2169 } else {
2170 f.write_str("async ")?
2171 }
2172 }
2173 CoroutineDesugaring::Gen => {
2174 if f.alternate() {
2175 f.write_str("`gen` ")?;
2176 } else {
2177 f.write_str("gen ")?
2178 }
2179 }
2180 CoroutineDesugaring::AsyncGen => {
2181 if f.alternate() {
2182 f.write_str("`async gen` ")?;
2183 } else {
2184 f.write_str("async gen ")?
2185 }
2186 }
2187 }
2188
2189 Ok(())
2190 }
2191}
2192
2193#[derive(Copy, Clone, Debug)]
2194pub enum BodyOwnerKind {
2195 Fn,
2197
2198 Closure,
2200
2201 Const { inline: bool },
2203
2204 Static(Mutability),
2206
2207 GlobalAsm,
2209}
2210
2211impl BodyOwnerKind {
2212 pub fn is_fn_or_closure(self) -> bool {
2213 match self {
2214 BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
2215 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
2216 false
2217 }
2218 }
2219 }
2220}
2221
2222#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2224pub enum ConstContext {
2225 ConstFn,
2227
2228 Static(Mutability),
2230
2231 Const { inline: bool },
2241}
2242
2243impl ConstContext {
2244 pub fn keyword_name(self) -> &'static str {
2248 match self {
2249 Self::Const { .. } => "const",
2250 Self::Static(Mutability::Not) => "static",
2251 Self::Static(Mutability::Mut) => "static mut",
2252 Self::ConstFn => "const fn",
2253 }
2254 }
2255}
2256
2257impl fmt::Display for ConstContext {
2260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2261 match *self {
2262 Self::Const { .. } => write!(f, "constant"),
2263 Self::Static(_) => write!(f, "static"),
2264 Self::ConstFn => write!(f, "constant function"),
2265 }
2266 }
2267}
2268
2269impl IntoDiagArg for ConstContext {
2270 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
2271 DiagArgValue::Str(Cow::Borrowed(match self {
2272 ConstContext::ConstFn => "const_fn",
2273 ConstContext::Static(_) => "static",
2274 ConstContext::Const { .. } => "const",
2275 }))
2276 }
2277}
2278
2279pub type Lit = Spanned<LitKind>;
2281
2282#[derive(Copy, Clone, Debug, HashStable_Generic)]
2291pub struct AnonConst {
2292 #[stable_hasher(ignore)]
2293 pub hir_id: HirId,
2294 pub def_id: LocalDefId,
2295 pub body: BodyId,
2296 pub span: Span,
2297}
2298
2299#[derive(Copy, Clone, Debug, HashStable_Generic)]
2301pub struct ConstBlock {
2302 #[stable_hasher(ignore)]
2303 pub hir_id: HirId,
2304 pub def_id: LocalDefId,
2305 pub body: BodyId,
2306}
2307
2308#[derive(Debug, Clone, Copy, HashStable_Generic)]
2317pub struct Expr<'hir> {
2318 #[stable_hasher(ignore)]
2319 pub hir_id: HirId,
2320 pub kind: ExprKind<'hir>,
2321 pub span: Span,
2322}
2323
2324impl Expr<'_> {
2325 pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence {
2326 let prefix_attrs_precedence = || -> ExprPrecedence {
2327 if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
2328 };
2329
2330 match &self.kind {
2331 ExprKind::Closure(closure) => {
2332 match closure.fn_decl.output {
2333 FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2334 FnRetTy::Return(_) => prefix_attrs_precedence(),
2335 }
2336 }
2337
2338 ExprKind::Break(..)
2339 | ExprKind::Ret(..)
2340 | ExprKind::Yield(..)
2341 | ExprKind::Become(..) => ExprPrecedence::Jump,
2342
2343 ExprKind::Binary(op, ..) => op.node.precedence(),
2345 ExprKind::Cast(..) => ExprPrecedence::Cast,
2346
2347 ExprKind::Assign(..) |
2348 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2349
2350 ExprKind::AddrOf(..)
2352 | ExprKind::Let(..)
2357 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2358
2359 ExprKind::Array(_)
2361 | ExprKind::Block(..)
2362 | ExprKind::Call(..)
2363 | ExprKind::ConstBlock(_)
2364 | ExprKind::Continue(..)
2365 | ExprKind::Field(..)
2366 | ExprKind::If(..)
2367 | ExprKind::Index(..)
2368 | ExprKind::InlineAsm(..)
2369 | ExprKind::Lit(_)
2370 | ExprKind::Loop(..)
2371 | ExprKind::Match(..)
2372 | ExprKind::MethodCall(..)
2373 | ExprKind::OffsetOf(..)
2374 | ExprKind::Path(..)
2375 | ExprKind::Repeat(..)
2376 | ExprKind::Struct(..)
2377 | ExprKind::Tup(_)
2378 | ExprKind::Type(..)
2379 | ExprKind::UnsafeBinderCast(..)
2380 | ExprKind::Use(..)
2381 | ExprKind::Err(_) => prefix_attrs_precedence(),
2382
2383 ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr),
2384 }
2385 }
2386
2387 pub fn is_syntactic_place_expr(&self) -> bool {
2392 self.is_place_expr(|_| true)
2393 }
2394
2395 pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2400 match self.kind {
2401 ExprKind::Path(QPath::Resolved(_, ref path)) => {
2402 matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2403 }
2404
2405 ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2409
2410 ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2412
2413 ExprKind::Unary(UnOp::Deref, _) => true,
2414
2415 ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2416 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2417 }
2418
2419 ExprKind::Path(QPath::LangItem(..)) => false,
2421
2422 ExprKind::Err(_guar)
2424 | ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
2425
2426 ExprKind::Path(QPath::TypeRelative(..))
2429 | ExprKind::Call(..)
2430 | ExprKind::MethodCall(..)
2431 | ExprKind::Use(..)
2432 | ExprKind::Struct(..)
2433 | ExprKind::Tup(..)
2434 | ExprKind::If(..)
2435 | ExprKind::Match(..)
2436 | ExprKind::Closure { .. }
2437 | ExprKind::Block(..)
2438 | ExprKind::Repeat(..)
2439 | ExprKind::Array(..)
2440 | ExprKind::Break(..)
2441 | ExprKind::Continue(..)
2442 | ExprKind::Ret(..)
2443 | ExprKind::Become(..)
2444 | ExprKind::Let(..)
2445 | ExprKind::Loop(..)
2446 | ExprKind::Assign(..)
2447 | ExprKind::InlineAsm(..)
2448 | ExprKind::OffsetOf(..)
2449 | ExprKind::AssignOp(..)
2450 | ExprKind::Lit(_)
2451 | ExprKind::ConstBlock(..)
2452 | ExprKind::Unary(..)
2453 | ExprKind::AddrOf(..)
2454 | ExprKind::Binary(..)
2455 | ExprKind::Yield(..)
2456 | ExprKind::Cast(..)
2457 | ExprKind::DropTemps(..) => false,
2458 }
2459 }
2460
2461 pub fn is_size_lit(&self) -> bool {
2464 matches!(
2465 self.kind,
2466 ExprKind::Lit(Lit {
2467 node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2468 ..
2469 })
2470 )
2471 }
2472
2473 pub fn peel_drop_temps(&self) -> &Self {
2479 let mut expr = self;
2480 while let ExprKind::DropTemps(inner) = &expr.kind {
2481 expr = inner;
2482 }
2483 expr
2484 }
2485
2486 pub fn peel_blocks(&self) -> &Self {
2487 let mut expr = self;
2488 while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2489 expr = inner;
2490 }
2491 expr
2492 }
2493
2494 pub fn peel_borrows(&self) -> &Self {
2495 let mut expr = self;
2496 while let ExprKind::AddrOf(.., inner) = &expr.kind {
2497 expr = inner;
2498 }
2499 expr
2500 }
2501
2502 pub fn can_have_side_effects(&self) -> bool {
2503 match self.peel_drop_temps().kind {
2504 ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2505 false
2506 }
2507 ExprKind::Type(base, _)
2508 | ExprKind::Unary(_, base)
2509 | ExprKind::Field(base, _)
2510 | ExprKind::Index(base, _, _)
2511 | ExprKind::AddrOf(.., base)
2512 | ExprKind::Cast(base, _)
2513 | ExprKind::UnsafeBinderCast(_, base, _) => {
2514 base.can_have_side_effects()
2518 }
2519 ExprKind::Struct(_, fields, init) => {
2520 let init_side_effects = match init {
2521 StructTailExpr::Base(init) => init.can_have_side_effects(),
2522 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2523 };
2524 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2525 || init_side_effects
2526 }
2527
2528 ExprKind::Array(args)
2529 | ExprKind::Tup(args)
2530 | ExprKind::Call(
2531 Expr {
2532 kind:
2533 ExprKind::Path(QPath::Resolved(
2534 None,
2535 Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2536 )),
2537 ..
2538 },
2539 args,
2540 ) => args.iter().any(|arg| arg.can_have_side_effects()),
2541 ExprKind::If(..)
2542 | ExprKind::Match(..)
2543 | ExprKind::MethodCall(..)
2544 | ExprKind::Call(..)
2545 | ExprKind::Closure { .. }
2546 | ExprKind::Block(..)
2547 | ExprKind::Repeat(..)
2548 | ExprKind::Break(..)
2549 | ExprKind::Continue(..)
2550 | ExprKind::Ret(..)
2551 | ExprKind::Become(..)
2552 | ExprKind::Let(..)
2553 | ExprKind::Loop(..)
2554 | ExprKind::Assign(..)
2555 | ExprKind::InlineAsm(..)
2556 | ExprKind::AssignOp(..)
2557 | ExprKind::ConstBlock(..)
2558 | ExprKind::Binary(..)
2559 | ExprKind::Yield(..)
2560 | ExprKind::DropTemps(..)
2561 | ExprKind::Err(_) => true,
2562 }
2563 }
2564
2565 pub fn is_approximately_pattern(&self) -> bool {
2567 match &self.kind {
2568 ExprKind::Array(_)
2569 | ExprKind::Call(..)
2570 | ExprKind::Tup(_)
2571 | ExprKind::Lit(_)
2572 | ExprKind::Path(_)
2573 | ExprKind::Struct(..) => true,
2574 _ => false,
2575 }
2576 }
2577
2578 pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2583 match (self.kind, other.kind) {
2584 (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2585 (
2586 ExprKind::Path(QPath::LangItem(item1, _)),
2587 ExprKind::Path(QPath::LangItem(item2, _)),
2588 ) => item1 == item2,
2589 (
2590 ExprKind::Path(QPath::Resolved(None, path1)),
2591 ExprKind::Path(QPath::Resolved(None, path2)),
2592 ) => path1.res == path2.res,
2593 (
2594 ExprKind::Struct(
2595 QPath::LangItem(LangItem::RangeTo, _),
2596 [val1],
2597 StructTailExpr::None,
2598 ),
2599 ExprKind::Struct(
2600 QPath::LangItem(LangItem::RangeTo, _),
2601 [val2],
2602 StructTailExpr::None,
2603 ),
2604 )
2605 | (
2606 ExprKind::Struct(
2607 QPath::LangItem(LangItem::RangeToInclusive, _),
2608 [val1],
2609 StructTailExpr::None,
2610 ),
2611 ExprKind::Struct(
2612 QPath::LangItem(LangItem::RangeToInclusive, _),
2613 [val2],
2614 StructTailExpr::None,
2615 ),
2616 )
2617 | (
2618 ExprKind::Struct(
2619 QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2620 [val1],
2621 StructTailExpr::None,
2622 ),
2623 ExprKind::Struct(
2624 QPath::LangItem(LangItem::RangeToInclusiveCopy, _),
2625 [val2],
2626 StructTailExpr::None,
2627 ),
2628 )
2629 | (
2630 ExprKind::Struct(
2631 QPath::LangItem(LangItem::RangeFrom, _),
2632 [val1],
2633 StructTailExpr::None,
2634 ),
2635 ExprKind::Struct(
2636 QPath::LangItem(LangItem::RangeFrom, _),
2637 [val2],
2638 StructTailExpr::None,
2639 ),
2640 )
2641 | (
2642 ExprKind::Struct(
2643 QPath::LangItem(LangItem::RangeFromCopy, _),
2644 [val1],
2645 StructTailExpr::None,
2646 ),
2647 ExprKind::Struct(
2648 QPath::LangItem(LangItem::RangeFromCopy, _),
2649 [val2],
2650 StructTailExpr::None,
2651 ),
2652 ) => val1.expr.equivalent_for_indexing(val2.expr),
2653 (
2654 ExprKind::Struct(
2655 QPath::LangItem(LangItem::Range, _),
2656 [val1, val3],
2657 StructTailExpr::None,
2658 ),
2659 ExprKind::Struct(
2660 QPath::LangItem(LangItem::Range, _),
2661 [val2, val4],
2662 StructTailExpr::None,
2663 ),
2664 )
2665 | (
2666 ExprKind::Struct(
2667 QPath::LangItem(LangItem::RangeCopy, _),
2668 [val1, val3],
2669 StructTailExpr::None,
2670 ),
2671 ExprKind::Struct(
2672 QPath::LangItem(LangItem::RangeCopy, _),
2673 [val2, val4],
2674 StructTailExpr::None,
2675 ),
2676 )
2677 | (
2678 ExprKind::Struct(
2679 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2680 [val1, val3],
2681 StructTailExpr::None,
2682 ),
2683 ExprKind::Struct(
2684 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2685 [val2, val4],
2686 StructTailExpr::None,
2687 ),
2688 ) => {
2689 val1.expr.equivalent_for_indexing(val2.expr)
2690 && val3.expr.equivalent_for_indexing(val4.expr)
2691 }
2692 _ => false,
2693 }
2694 }
2695
2696 pub fn method_ident(&self) -> Option<Ident> {
2697 match self.kind {
2698 ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2699 ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2700 _ => None,
2701 }
2702 }
2703}
2704
2705pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2708 match expr.kind {
2709 ExprKind::Struct(ref qpath, _, _) => matches!(
2711 **qpath,
2712 QPath::LangItem(
2713 LangItem::Range
2714 | LangItem::RangeTo
2715 | LangItem::RangeFrom
2716 | LangItem::RangeFull
2717 | LangItem::RangeToInclusive
2718 | LangItem::RangeCopy
2719 | LangItem::RangeFromCopy
2720 | LangItem::RangeInclusiveCopy
2721 | LangItem::RangeToInclusiveCopy,
2722 ..
2723 )
2724 ),
2725
2726 ExprKind::Call(ref func, _) => {
2728 matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2729 }
2730
2731 _ => false,
2732 }
2733}
2734
2735pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2742 match expr.kind {
2743 ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2745 _ if is_range_literal(expr) => true,
2747 _ => false,
2748 }
2749}
2750
2751#[derive(Debug, Clone, Copy, HashStable_Generic)]
2752pub enum ExprKind<'hir> {
2753 ConstBlock(ConstBlock),
2755 Array(&'hir [Expr<'hir>]),
2757 Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2764 MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2781 Use(&'hir Expr<'hir>, Span),
2783 Tup(&'hir [Expr<'hir>]),
2785 Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2787 Unary(UnOp, &'hir Expr<'hir>),
2789 Lit(Lit),
2791 Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2793 Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2795 DropTemps(&'hir Expr<'hir>),
2801 Let(&'hir LetExpr<'hir>),
2806 If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2815 Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2821 Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2824 Closure(&'hir Closure<'hir>),
2831 Block(&'hir Block<'hir>, Option<Label>),
2833
2834 Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2836 AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2840 Field(&'hir Expr<'hir>, Ident),
2842 Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2846
2847 Path(QPath<'hir>),
2849
2850 AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2852 Break(Destination, Option<&'hir Expr<'hir>>),
2854 Continue(Destination),
2856 Ret(Option<&'hir Expr<'hir>>),
2858 Become(&'hir Expr<'hir>),
2860
2861 InlineAsm(&'hir InlineAsm<'hir>),
2863
2864 OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2866
2867 Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2872
2873 Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2878
2879 Yield(&'hir Expr<'hir>, YieldSource),
2881
2882 UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2885
2886 Err(rustc_span::ErrorGuaranteed),
2888}
2889
2890#[derive(Debug, Clone, Copy, HashStable_Generic)]
2891pub enum StructTailExpr<'hir> {
2892 None,
2894 Base(&'hir Expr<'hir>),
2897 DefaultFields(Span),
2901}
2902
2903#[derive(Debug, Clone, Copy, HashStable_Generic)]
2909pub enum QPath<'hir> {
2910 Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2917
2918 TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2925
2926 LangItem(LangItem, Span),
2928}
2929
2930impl<'hir> QPath<'hir> {
2931 pub fn span(&self) -> Span {
2933 match *self {
2934 QPath::Resolved(_, path) => path.span,
2935 QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2936 QPath::LangItem(_, span) => span,
2937 }
2938 }
2939
2940 pub fn qself_span(&self) -> Span {
2943 match *self {
2944 QPath::Resolved(_, path) => path.span,
2945 QPath::TypeRelative(qself, _) => qself.span,
2946 QPath::LangItem(_, span) => span,
2947 }
2948 }
2949}
2950
2951#[derive(Copy, Clone, Debug, HashStable_Generic)]
2953pub enum LocalSource {
2954 Normal,
2956 AsyncFn,
2967 AwaitDesugar,
2969 AssignDesugar(Span),
2972 Contract,
2974}
2975
2976#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2978pub enum MatchSource {
2979 Normal,
2981 Postfix,
2983 ForLoopDesugar,
2985 TryDesugar(HirId),
2987 AwaitDesugar,
2989 FormatArgs,
2991}
2992
2993impl MatchSource {
2994 #[inline]
2995 pub const fn name(self) -> &'static str {
2996 use MatchSource::*;
2997 match self {
2998 Normal => "match",
2999 Postfix => ".match",
3000 ForLoopDesugar => "for",
3001 TryDesugar(_) => "?",
3002 AwaitDesugar => ".await",
3003 FormatArgs => "format_args!()",
3004 }
3005 }
3006}
3007
3008#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3010pub enum LoopSource {
3011 Loop,
3013 While,
3015 ForLoop,
3017}
3018
3019impl LoopSource {
3020 pub fn name(self) -> &'static str {
3021 match self {
3022 LoopSource::Loop => "loop",
3023 LoopSource::While => "while",
3024 LoopSource::ForLoop => "for",
3025 }
3026 }
3027}
3028
3029#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3030pub enum LoopIdError {
3031 OutsideLoopScope,
3032 UnlabeledCfInWhileCondition,
3033 UnresolvedLabel,
3034}
3035
3036impl fmt::Display for LoopIdError {
3037 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3038 f.write_str(match self {
3039 LoopIdError::OutsideLoopScope => "not inside loop scope",
3040 LoopIdError::UnlabeledCfInWhileCondition => {
3041 "unlabeled control flow (break or continue) in while condition"
3042 }
3043 LoopIdError::UnresolvedLabel => "label not found",
3044 })
3045 }
3046}
3047
3048#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
3049pub struct Destination {
3050 pub label: Option<Label>,
3052
3053 pub target_id: Result<HirId, LoopIdError>,
3056}
3057
3058#[derive(Copy, Clone, Debug, HashStable_Generic)]
3060pub enum YieldSource {
3061 Await { expr: Option<HirId> },
3063 Yield,
3065}
3066
3067impl fmt::Display for YieldSource {
3068 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3069 f.write_str(match self {
3070 YieldSource::Await { .. } => "`await`",
3071 YieldSource::Yield => "`yield`",
3072 })
3073 }
3074}
3075
3076#[derive(Debug, Clone, Copy, HashStable_Generic)]
3079pub struct MutTy<'hir> {
3080 pub ty: &'hir Ty<'hir>,
3081 pub mutbl: Mutability,
3082}
3083
3084#[derive(Debug, Clone, Copy, HashStable_Generic)]
3087pub struct FnSig<'hir> {
3088 pub header: FnHeader,
3089 pub decl: &'hir FnDecl<'hir>,
3090 pub span: Span,
3091}
3092
3093#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3097pub struct TraitItemId {
3098 pub owner_id: OwnerId,
3099}
3100
3101impl TraitItemId {
3102 #[inline]
3103 pub fn hir_id(&self) -> HirId {
3104 HirId::make_owner(self.owner_id.def_id)
3106 }
3107}
3108
3109#[derive(Debug, Clone, Copy, HashStable_Generic)]
3114pub struct TraitItem<'hir> {
3115 pub ident: Ident,
3116 pub owner_id: OwnerId,
3117 pub generics: &'hir Generics<'hir>,
3118 pub kind: TraitItemKind<'hir>,
3119 pub span: Span,
3120 pub defaultness: Defaultness,
3121 pub has_delayed_lints: bool,
3122}
3123
3124macro_rules! expect_methods_self_kind {
3125 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3126 $(
3127 #[track_caller]
3128 pub fn $name(&self) -> $ret_ty {
3129 let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
3130 $ret_val
3131 }
3132 )*
3133 }
3134}
3135
3136macro_rules! expect_methods_self {
3137 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3138 $(
3139 #[track_caller]
3140 pub fn $name(&self) -> $ret_ty {
3141 let $pat = self else { expect_failed(stringify!($ident), self) };
3142 $ret_val
3143 }
3144 )*
3145 }
3146}
3147
3148#[track_caller]
3149fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
3150 panic!("{ident}: found {found:?}")
3151}
3152
3153impl<'hir> TraitItem<'hir> {
3154 #[inline]
3155 pub fn hir_id(&self) -> HirId {
3156 HirId::make_owner(self.owner_id.def_id)
3158 }
3159
3160 pub fn trait_item_id(&self) -> TraitItemId {
3161 TraitItemId { owner_id: self.owner_id }
3162 }
3163
3164 expect_methods_self_kind! {
3165 expect_const, (&'hir Ty<'hir>, Option<BodyId>),
3166 TraitItemKind::Const(ty, body), (ty, *body);
3167
3168 expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
3169 TraitItemKind::Fn(ty, trfn), (ty, trfn);
3170
3171 expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3172 TraitItemKind::Type(bounds, ty), (bounds, *ty);
3173 }
3174}
3175
3176#[derive(Debug, Clone, Copy, HashStable_Generic)]
3178pub enum TraitFn<'hir> {
3179 Required(&'hir [Option<Ident>]),
3181
3182 Provided(BodyId),
3184}
3185
3186#[derive(Debug, Clone, Copy, HashStable_Generic)]
3188pub enum TraitItemKind<'hir> {
3189 Const(&'hir Ty<'hir>, Option<BodyId>),
3191 Fn(FnSig<'hir>, TraitFn<'hir>),
3193 Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3196}
3197
3198#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3202pub struct ImplItemId {
3203 pub owner_id: OwnerId,
3204}
3205
3206impl ImplItemId {
3207 #[inline]
3208 pub fn hir_id(&self) -> HirId {
3209 HirId::make_owner(self.owner_id.def_id)
3211 }
3212}
3213
3214#[derive(Debug, Clone, Copy, HashStable_Generic)]
3218pub struct ImplItem<'hir> {
3219 pub ident: Ident,
3220 pub owner_id: OwnerId,
3221 pub generics: &'hir Generics<'hir>,
3222 pub kind: ImplItemKind<'hir>,
3223 pub impl_kind: ImplItemImplKind,
3224 pub span: Span,
3225 pub has_delayed_lints: bool,
3226}
3227
3228#[derive(Debug, Clone, Copy, HashStable_Generic)]
3229pub enum ImplItemImplKind {
3230 Inherent {
3231 vis_span: Span,
3232 },
3233 Trait {
3234 defaultness: Defaultness,
3235 trait_item_def_id: Result<DefId, ErrorGuaranteed>,
3237 },
3238}
3239
3240impl<'hir> ImplItem<'hir> {
3241 #[inline]
3242 pub fn hir_id(&self) -> HirId {
3243 HirId::make_owner(self.owner_id.def_id)
3245 }
3246
3247 pub fn impl_item_id(&self) -> ImplItemId {
3248 ImplItemId { owner_id: self.owner_id }
3249 }
3250
3251 pub fn vis_span(&self) -> Option<Span> {
3252 match self.impl_kind {
3253 ImplItemImplKind::Trait { .. } => None,
3254 ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
3255 }
3256 }
3257
3258 expect_methods_self_kind! {
3259 expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
3260 expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3261 expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3262 }
3263}
3264
3265#[derive(Debug, Clone, Copy, HashStable_Generic)]
3267pub enum ImplItemKind<'hir> {
3268 Const(&'hir Ty<'hir>, BodyId),
3271 Fn(FnSig<'hir>, BodyId),
3273 Type(&'hir Ty<'hir>),
3275}
3276
3277#[derive(Debug, Clone, Copy, HashStable_Generic)]
3288pub struct AssocItemConstraint<'hir> {
3289 #[stable_hasher(ignore)]
3290 pub hir_id: HirId,
3291 pub ident: Ident,
3292 pub gen_args: &'hir GenericArgs<'hir>,
3293 pub kind: AssocItemConstraintKind<'hir>,
3294 pub span: Span,
3295}
3296
3297impl<'hir> AssocItemConstraint<'hir> {
3298 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
3300 match self.kind {
3301 AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
3302 _ => None,
3303 }
3304 }
3305
3306 pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
3308 match self.kind {
3309 AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
3310 _ => None,
3311 }
3312 }
3313}
3314
3315#[derive(Debug, Clone, Copy, HashStable_Generic)]
3316pub enum Term<'hir> {
3317 Ty(&'hir Ty<'hir>),
3318 Const(&'hir ConstArg<'hir>),
3319}
3320
3321impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
3322 fn from(ty: &'hir Ty<'hir>) -> Self {
3323 Term::Ty(ty)
3324 }
3325}
3326
3327impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
3328 fn from(c: &'hir ConstArg<'hir>) -> Self {
3329 Term::Const(c)
3330 }
3331}
3332
3333#[derive(Debug, Clone, Copy, HashStable_Generic)]
3335pub enum AssocItemConstraintKind<'hir> {
3336 Equality { term: Term<'hir> },
3343 Bound { bounds: &'hir [GenericBound<'hir>] },
3345}
3346
3347impl<'hir> AssocItemConstraintKind<'hir> {
3348 pub fn descr(&self) -> &'static str {
3349 match self {
3350 AssocItemConstraintKind::Equality { .. } => "binding",
3351 AssocItemConstraintKind::Bound { .. } => "constraint",
3352 }
3353 }
3354}
3355
3356#[derive(Debug, Clone, Copy, HashStable_Generic)]
3360pub enum AmbigArg {}
3361
3362#[derive(Debug, Clone, Copy, HashStable_Generic)]
3367#[repr(C)]
3368pub struct Ty<'hir, Unambig = ()> {
3369 #[stable_hasher(ignore)]
3370 pub hir_id: HirId,
3371 pub span: Span,
3372 pub kind: TyKind<'hir, Unambig>,
3373}
3374
3375impl<'hir> Ty<'hir, AmbigArg> {
3376 pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3387 let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3390 unsafe { &*ptr }
3391 }
3392}
3393
3394impl<'hir> Ty<'hir> {
3395 pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3401 if let TyKind::Infer(()) = self.kind {
3402 return None;
3403 }
3404
3405 let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3409 Some(unsafe { &*ptr })
3410 }
3411}
3412
3413impl<'hir> Ty<'hir, AmbigArg> {
3414 pub fn peel_refs(&self) -> &Ty<'hir> {
3415 let mut final_ty = self.as_unambig_ty();
3416 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3417 final_ty = ty;
3418 }
3419 final_ty
3420 }
3421}
3422
3423impl<'hir> Ty<'hir> {
3424 pub fn peel_refs(&self) -> &Self {
3425 let mut final_ty = self;
3426 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3427 final_ty = ty;
3428 }
3429 final_ty
3430 }
3431
3432 pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3434 let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3435 return None;
3436 };
3437 let [segment] = &path.segments else {
3438 return None;
3439 };
3440 match path.res {
3441 Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3442 Some((def_id, segment.ident))
3443 }
3444 _ => None,
3445 }
3446 }
3447
3448 pub fn find_self_aliases(&self) -> Vec<Span> {
3449 use crate::intravisit::Visitor;
3450 struct MyVisitor(Vec<Span>);
3451 impl<'v> Visitor<'v> for MyVisitor {
3452 fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3453 if matches!(
3454 &t.kind,
3455 TyKind::Path(QPath::Resolved(
3456 _,
3457 Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3458 ))
3459 ) {
3460 self.0.push(t.span);
3461 return;
3462 }
3463 crate::intravisit::walk_ty(self, t);
3464 }
3465 }
3466
3467 let mut my_visitor = MyVisitor(vec![]);
3468 my_visitor.visit_ty_unambig(self);
3469 my_visitor.0
3470 }
3471
3472 pub fn is_suggestable_infer_ty(&self) -> bool {
3475 fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3476 generic_args.iter().any(|arg| match arg {
3477 GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3478 GenericArg::Infer(_) => true,
3479 _ => false,
3480 })
3481 }
3482 debug!(?self);
3483 match &self.kind {
3484 TyKind::Infer(()) => true,
3485 TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3486 TyKind::Array(ty, length) => {
3487 ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3488 }
3489 TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3490 TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3491 TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3492 ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3493 }
3494 TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3495 ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3496 || segments
3497 .iter()
3498 .any(|segment| are_suggestable_generic_args(segment.args().args))
3499 }
3500 _ => false,
3501 }
3502 }
3503}
3504
3505#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3507pub enum PrimTy {
3508 Int(IntTy),
3509 Uint(UintTy),
3510 Float(FloatTy),
3511 Str,
3512 Bool,
3513 Char,
3514}
3515
3516impl PrimTy {
3517 pub const ALL: [Self; 19] = [
3519 Self::Int(IntTy::I8),
3521 Self::Int(IntTy::I16),
3522 Self::Int(IntTy::I32),
3523 Self::Int(IntTy::I64),
3524 Self::Int(IntTy::I128),
3525 Self::Int(IntTy::Isize),
3526 Self::Uint(UintTy::U8),
3527 Self::Uint(UintTy::U16),
3528 Self::Uint(UintTy::U32),
3529 Self::Uint(UintTy::U64),
3530 Self::Uint(UintTy::U128),
3531 Self::Uint(UintTy::Usize),
3532 Self::Float(FloatTy::F16),
3533 Self::Float(FloatTy::F32),
3534 Self::Float(FloatTy::F64),
3535 Self::Float(FloatTy::F128),
3536 Self::Bool,
3537 Self::Char,
3538 Self::Str,
3539 ];
3540
3541 pub fn name_str(self) -> &'static str {
3545 match self {
3546 PrimTy::Int(i) => i.name_str(),
3547 PrimTy::Uint(u) => u.name_str(),
3548 PrimTy::Float(f) => f.name_str(),
3549 PrimTy::Str => "str",
3550 PrimTy::Bool => "bool",
3551 PrimTy::Char => "char",
3552 }
3553 }
3554
3555 pub fn name(self) -> Symbol {
3556 match self {
3557 PrimTy::Int(i) => i.name(),
3558 PrimTy::Uint(u) => u.name(),
3559 PrimTy::Float(f) => f.name(),
3560 PrimTy::Str => sym::str,
3561 PrimTy::Bool => sym::bool,
3562 PrimTy::Char => sym::char,
3563 }
3564 }
3565
3566 pub fn from_name(name: Symbol) -> Option<Self> {
3569 let ty = match name {
3570 sym::i8 => Self::Int(IntTy::I8),
3572 sym::i16 => Self::Int(IntTy::I16),
3573 sym::i32 => Self::Int(IntTy::I32),
3574 sym::i64 => Self::Int(IntTy::I64),
3575 sym::i128 => Self::Int(IntTy::I128),
3576 sym::isize => Self::Int(IntTy::Isize),
3577 sym::u8 => Self::Uint(UintTy::U8),
3578 sym::u16 => Self::Uint(UintTy::U16),
3579 sym::u32 => Self::Uint(UintTy::U32),
3580 sym::u64 => Self::Uint(UintTy::U64),
3581 sym::u128 => Self::Uint(UintTy::U128),
3582 sym::usize => Self::Uint(UintTy::Usize),
3583 sym::f16 => Self::Float(FloatTy::F16),
3584 sym::f32 => Self::Float(FloatTy::F32),
3585 sym::f64 => Self::Float(FloatTy::F64),
3586 sym::f128 => Self::Float(FloatTy::F128),
3587 sym::bool => Self::Bool,
3588 sym::char => Self::Char,
3589 sym::str => Self::Str,
3590 _ => return None,
3591 };
3592 Some(ty)
3593 }
3594}
3595
3596#[derive(Debug, Clone, Copy, HashStable_Generic)]
3597pub struct FnPtrTy<'hir> {
3598 pub safety: Safety,
3599 pub abi: ExternAbi,
3600 pub generic_params: &'hir [GenericParam<'hir>],
3601 pub decl: &'hir FnDecl<'hir>,
3602 pub param_idents: &'hir [Option<Ident>],
3605}
3606
3607#[derive(Debug, Clone, Copy, HashStable_Generic)]
3608pub struct UnsafeBinderTy<'hir> {
3609 pub generic_params: &'hir [GenericParam<'hir>],
3610 pub inner_ty: &'hir Ty<'hir>,
3611}
3612
3613#[derive(Debug, Clone, Copy, HashStable_Generic)]
3614pub struct OpaqueTy<'hir> {
3615 #[stable_hasher(ignore)]
3616 pub hir_id: HirId,
3617 pub def_id: LocalDefId,
3618 pub bounds: GenericBounds<'hir>,
3619 pub origin: OpaqueTyOrigin<LocalDefId>,
3620 pub span: Span,
3621}
3622
3623#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
3624pub enum PreciseCapturingArgKind<T, U> {
3625 Lifetime(T),
3626 Param(U),
3628}
3629
3630pub type PreciseCapturingArg<'hir> =
3631 PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
3632
3633impl PreciseCapturingArg<'_> {
3634 pub fn hir_id(self) -> HirId {
3635 match self {
3636 PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3637 PreciseCapturingArg::Param(param) => param.hir_id,
3638 }
3639 }
3640
3641 pub fn name(self) -> Symbol {
3642 match self {
3643 PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3644 PreciseCapturingArg::Param(param) => param.ident.name,
3645 }
3646 }
3647}
3648
3649#[derive(Debug, Clone, Copy, HashStable_Generic)]
3654pub struct PreciseCapturingNonLifetimeArg {
3655 #[stable_hasher(ignore)]
3656 pub hir_id: HirId,
3657 pub ident: Ident,
3658 pub res: Res,
3659}
3660
3661#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3662#[derive(HashStable_Generic, Encodable, Decodable)]
3663pub enum RpitContext {
3664 Trait,
3665 TraitImpl,
3666}
3667
3668#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3670#[derive(HashStable_Generic, Encodable, Decodable)]
3671pub enum OpaqueTyOrigin<D> {
3672 FnReturn {
3674 parent: D,
3676 in_trait_or_impl: Option<RpitContext>,
3678 },
3679 AsyncFn {
3681 parent: D,
3683 in_trait_or_impl: Option<RpitContext>,
3685 },
3686 TyAlias {
3688 parent: D,
3690 in_assoc_ty: bool,
3692 },
3693}
3694
3695#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3696pub enum InferDelegationKind {
3697 Input(usize),
3698 Output,
3699}
3700
3701#[repr(u8, C)]
3707#[derive(Debug, Clone, Copy, HashStable_Generic)]
3708pub enum TyKind<'hir, Unambig = ()> {
3709 InferDelegation(DefId, InferDelegationKind),
3711 Slice(&'hir Ty<'hir>),
3713 Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3715 Ptr(MutTy<'hir>),
3717 Ref(&'hir Lifetime, MutTy<'hir>),
3719 FnPtr(&'hir FnPtrTy<'hir>),
3721 UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3723 Never,
3725 Tup(&'hir [Ty<'hir>]),
3727 Path(QPath<'hir>),
3732 OpaqueDef(&'hir OpaqueTy<'hir>),
3734 TraitAscription(GenericBounds<'hir>),
3736 TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3742 Typeof(&'hir AnonConst),
3744 Err(rustc_span::ErrorGuaranteed),
3746 Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3748 Infer(Unambig),
3754}
3755
3756#[derive(Debug, Clone, Copy, HashStable_Generic)]
3757pub enum InlineAsmOperand<'hir> {
3758 In {
3759 reg: InlineAsmRegOrRegClass,
3760 expr: &'hir Expr<'hir>,
3761 },
3762 Out {
3763 reg: InlineAsmRegOrRegClass,
3764 late: bool,
3765 expr: Option<&'hir Expr<'hir>>,
3766 },
3767 InOut {
3768 reg: InlineAsmRegOrRegClass,
3769 late: bool,
3770 expr: &'hir Expr<'hir>,
3771 },
3772 SplitInOut {
3773 reg: InlineAsmRegOrRegClass,
3774 late: bool,
3775 in_expr: &'hir Expr<'hir>,
3776 out_expr: Option<&'hir Expr<'hir>>,
3777 },
3778 Const {
3779 anon_const: ConstBlock,
3780 },
3781 SymFn {
3782 expr: &'hir Expr<'hir>,
3783 },
3784 SymStatic {
3785 path: QPath<'hir>,
3786 def_id: DefId,
3787 },
3788 Label {
3789 block: &'hir Block<'hir>,
3790 },
3791}
3792
3793impl<'hir> InlineAsmOperand<'hir> {
3794 pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3795 match *self {
3796 Self::In { reg, .. }
3797 | Self::Out { reg, .. }
3798 | Self::InOut { reg, .. }
3799 | Self::SplitInOut { reg, .. } => Some(reg),
3800 Self::Const { .. }
3801 | Self::SymFn { .. }
3802 | Self::SymStatic { .. }
3803 | Self::Label { .. } => None,
3804 }
3805 }
3806
3807 pub fn is_clobber(&self) -> bool {
3808 matches!(
3809 self,
3810 InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3811 )
3812 }
3813}
3814
3815#[derive(Debug, Clone, Copy, HashStable_Generic)]
3816pub struct InlineAsm<'hir> {
3817 pub asm_macro: ast::AsmMacro,
3818 pub template: &'hir [InlineAsmTemplatePiece],
3819 pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3820 pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3821 pub options: InlineAsmOptions,
3822 pub line_spans: &'hir [Span],
3823}
3824
3825impl InlineAsm<'_> {
3826 pub fn contains_label(&self) -> bool {
3827 self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3828 }
3829}
3830
3831#[derive(Debug, Clone, Copy, HashStable_Generic)]
3833pub struct Param<'hir> {
3834 #[stable_hasher(ignore)]
3835 pub hir_id: HirId,
3836 pub pat: &'hir Pat<'hir>,
3837 pub ty_span: Span,
3838 pub span: Span,
3839}
3840
3841#[derive(Debug, Clone, Copy, HashStable_Generic)]
3843pub struct FnDecl<'hir> {
3844 pub inputs: &'hir [Ty<'hir>],
3848 pub output: FnRetTy<'hir>,
3849 pub c_variadic: bool,
3850 pub implicit_self: ImplicitSelfKind,
3852 pub lifetime_elision_allowed: bool,
3854}
3855
3856impl<'hir> FnDecl<'hir> {
3857 pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3858 if let FnRetTy::Return(ty) = self.output
3859 && let TyKind::InferDelegation(sig_id, _) = ty.kind
3860 {
3861 return Some(sig_id);
3862 }
3863 None
3864 }
3865}
3866
3867#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3869pub enum ImplicitSelfKind {
3870 Imm,
3872 Mut,
3874 RefImm,
3876 RefMut,
3878 None,
3881}
3882
3883impl ImplicitSelfKind {
3884 pub fn has_implicit_self(&self) -> bool {
3886 !matches!(*self, ImplicitSelfKind::None)
3887 }
3888}
3889
3890#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3891pub enum IsAsync {
3892 Async(Span),
3893 NotAsync,
3894}
3895
3896impl IsAsync {
3897 pub fn is_async(self) -> bool {
3898 matches!(self, IsAsync::Async(_))
3899 }
3900}
3901
3902#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3903pub enum Defaultness {
3904 Default { has_value: bool },
3905 Final,
3906}
3907
3908impl Defaultness {
3909 pub fn has_value(&self) -> bool {
3910 match *self {
3911 Defaultness::Default { has_value } => has_value,
3912 Defaultness::Final => true,
3913 }
3914 }
3915
3916 pub fn is_final(&self) -> bool {
3917 *self == Defaultness::Final
3918 }
3919
3920 pub fn is_default(&self) -> bool {
3921 matches!(*self, Defaultness::Default { .. })
3922 }
3923}
3924
3925#[derive(Debug, Clone, Copy, HashStable_Generic)]
3926pub enum FnRetTy<'hir> {
3927 DefaultReturn(Span),
3933 Return(&'hir Ty<'hir>),
3935}
3936
3937impl<'hir> FnRetTy<'hir> {
3938 #[inline]
3939 pub fn span(&self) -> Span {
3940 match *self {
3941 Self::DefaultReturn(span) => span,
3942 Self::Return(ref ty) => ty.span,
3943 }
3944 }
3945
3946 pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3947 if let Self::Return(ty) = self
3948 && ty.is_suggestable_infer_ty()
3949 {
3950 return Some(*ty);
3951 }
3952 None
3953 }
3954}
3955
3956#[derive(Copy, Clone, Debug, HashStable_Generic)]
3958pub enum ClosureBinder {
3959 Default,
3961 For { span: Span },
3965}
3966
3967#[derive(Debug, Clone, Copy, HashStable_Generic)]
3968pub struct Mod<'hir> {
3969 pub spans: ModSpans,
3970 pub item_ids: &'hir [ItemId],
3971}
3972
3973#[derive(Copy, Clone, Debug, HashStable_Generic)]
3974pub struct ModSpans {
3975 pub inner_span: Span,
3979 pub inject_use_span: Span,
3980}
3981
3982#[derive(Debug, Clone, Copy, HashStable_Generic)]
3983pub struct EnumDef<'hir> {
3984 pub variants: &'hir [Variant<'hir>],
3985}
3986
3987#[derive(Debug, Clone, Copy, HashStable_Generic)]
3988pub struct Variant<'hir> {
3989 pub ident: Ident,
3991 #[stable_hasher(ignore)]
3993 pub hir_id: HirId,
3994 pub def_id: LocalDefId,
3995 pub data: VariantData<'hir>,
3997 pub disr_expr: Option<&'hir AnonConst>,
3999 pub span: Span,
4001}
4002
4003#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4004pub enum UseKind {
4005 Single(Ident),
4012
4013 Glob,
4015
4016 ListStem,
4020}
4021
4022#[derive(Clone, Debug, Copy, HashStable_Generic)]
4029pub struct TraitRef<'hir> {
4030 pub path: &'hir Path<'hir>,
4031 #[stable_hasher(ignore)]
4033 pub hir_ref_id: HirId,
4034}
4035
4036impl TraitRef<'_> {
4037 pub fn trait_def_id(&self) -> Option<DefId> {
4039 match self.path.res {
4040 Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
4041 Res::Err => None,
4042 res => panic!("{res:?} did not resolve to a trait or trait alias"),
4043 }
4044 }
4045}
4046
4047#[derive(Clone, Debug, Copy, HashStable_Generic)]
4048pub struct PolyTraitRef<'hir> {
4049 pub bound_generic_params: &'hir [GenericParam<'hir>],
4051
4052 pub modifiers: TraitBoundModifiers,
4056
4057 pub trait_ref: TraitRef<'hir>,
4059
4060 pub span: Span,
4061}
4062
4063#[derive(Debug, Clone, Copy, HashStable_Generic)]
4064pub struct FieldDef<'hir> {
4065 pub span: Span,
4066 pub vis_span: Span,
4067 pub ident: Ident,
4068 #[stable_hasher(ignore)]
4069 pub hir_id: HirId,
4070 pub def_id: LocalDefId,
4071 pub ty: &'hir Ty<'hir>,
4072 pub safety: Safety,
4073 pub default: Option<&'hir AnonConst>,
4074}
4075
4076impl FieldDef<'_> {
4077 pub fn is_positional(&self) -> bool {
4079 self.ident.as_str().as_bytes()[0].is_ascii_digit()
4080 }
4081}
4082
4083#[derive(Debug, Clone, Copy, HashStable_Generic)]
4085pub enum VariantData<'hir> {
4086 Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
4090 Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
4094 Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
4098}
4099
4100impl<'hir> VariantData<'hir> {
4101 pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
4103 match *self {
4104 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
4105 _ => &[],
4106 }
4107 }
4108
4109 pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
4110 match *self {
4111 VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
4112 VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
4113 VariantData::Struct { .. } => None,
4114 }
4115 }
4116
4117 #[inline]
4118 pub fn ctor_kind(&self) -> Option<CtorKind> {
4119 self.ctor().map(|(kind, ..)| kind)
4120 }
4121
4122 #[inline]
4124 pub fn ctor_hir_id(&self) -> Option<HirId> {
4125 self.ctor().map(|(_, hir_id, _)| hir_id)
4126 }
4127
4128 #[inline]
4130 pub fn ctor_def_id(&self) -> Option<LocalDefId> {
4131 self.ctor().map(|(.., def_id)| def_id)
4132 }
4133}
4134
4135#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
4139pub struct ItemId {
4140 pub owner_id: OwnerId,
4141}
4142
4143impl ItemId {
4144 #[inline]
4145 pub fn hir_id(&self) -> HirId {
4146 HirId::make_owner(self.owner_id.def_id)
4148 }
4149}
4150
4151#[derive(Debug, Clone, Copy, HashStable_Generic)]
4160pub struct Item<'hir> {
4161 pub owner_id: OwnerId,
4162 pub kind: ItemKind<'hir>,
4163 pub span: Span,
4164 pub vis_span: Span,
4165 pub has_delayed_lints: bool,
4166}
4167
4168impl<'hir> Item<'hir> {
4169 #[inline]
4170 pub fn hir_id(&self) -> HirId {
4171 HirId::make_owner(self.owner_id.def_id)
4173 }
4174
4175 pub fn item_id(&self) -> ItemId {
4176 ItemId { owner_id: self.owner_id }
4177 }
4178
4179 pub fn is_adt(&self) -> bool {
4182 matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
4183 }
4184
4185 pub fn is_struct_or_union(&self) -> bool {
4187 matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
4188 }
4189
4190 expect_methods_self_kind! {
4191 expect_extern_crate, (Option<Symbol>, Ident),
4192 ItemKind::ExternCrate(s, ident), (*s, *ident);
4193
4194 expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
4195
4196 expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId),
4197 ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body);
4198
4199 expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4200 ItemKind::Const(ident, generics, ty, body), (*ident, generics, ty, *body);
4201
4202 expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
4203 ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
4204
4205 expect_macro, (Ident, &ast::MacroDef, MacroKinds),
4206 ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
4207
4208 expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
4209
4210 expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]),
4211 ItemKind::ForeignMod { abi, items }, (*abi, items);
4212
4213 expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
4214
4215 expect_ty_alias, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4216 ItemKind::TyAlias(ident, generics, ty), (*ident, generics, ty);
4217
4218 expect_enum, (Ident, &'hir Generics<'hir>, &EnumDef<'hir>),
4219 ItemKind::Enum(ident, generics, def), (*ident, generics, def);
4220
4221 expect_struct, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4222 ItemKind::Struct(ident, generics, data), (*ident, generics, data);
4223
4224 expect_union, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4225 ItemKind::Union(ident, generics, data), (*ident, generics, data);
4226
4227 expect_trait,
4228 (
4229 Constness,
4230 IsAuto,
4231 Safety,
4232 Ident,
4233 &'hir Generics<'hir>,
4234 GenericBounds<'hir>,
4235 &'hir [TraitItemId]
4236 ),
4237 ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
4238 (*constness, *is_auto, *safety, *ident, generics, bounds, items);
4239
4240 expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4241 ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
4242
4243 expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
4244 }
4245}
4246
4247#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4248#[derive(Encodable, Decodable, HashStable_Generic)]
4249pub enum Safety {
4250 Unsafe,
4251 Safe,
4252}
4253
4254impl Safety {
4255 pub fn prefix_str(self) -> &'static str {
4256 match self {
4257 Self::Unsafe => "unsafe ",
4258 Self::Safe => "",
4259 }
4260 }
4261
4262 #[inline]
4263 pub fn is_unsafe(self) -> bool {
4264 !self.is_safe()
4265 }
4266
4267 #[inline]
4268 pub fn is_safe(self) -> bool {
4269 match self {
4270 Self::Unsafe => false,
4271 Self::Safe => true,
4272 }
4273 }
4274}
4275
4276impl fmt::Display for Safety {
4277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4278 f.write_str(match *self {
4279 Self::Unsafe => "unsafe",
4280 Self::Safe => "safe",
4281 })
4282 }
4283}
4284
4285#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
4286pub enum Constness {
4287 Const,
4288 NotConst,
4289}
4290
4291impl fmt::Display for Constness {
4292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4293 f.write_str(match *self {
4294 Self::Const => "const",
4295 Self::NotConst => "non-const",
4296 })
4297 }
4298}
4299
4300#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
4305pub enum HeaderSafety {
4306 SafeTargetFeatures,
4312 Normal(Safety),
4313}
4314
4315impl From<Safety> for HeaderSafety {
4316 fn from(v: Safety) -> Self {
4317 Self::Normal(v)
4318 }
4319}
4320
4321#[derive(Copy, Clone, Debug, HashStable_Generic)]
4322pub struct FnHeader {
4323 pub safety: HeaderSafety,
4324 pub constness: Constness,
4325 pub asyncness: IsAsync,
4326 pub abi: ExternAbi,
4327}
4328
4329impl FnHeader {
4330 pub fn is_async(&self) -> bool {
4331 matches!(self.asyncness, IsAsync::Async(_))
4332 }
4333
4334 pub fn is_const(&self) -> bool {
4335 matches!(self.constness, Constness::Const)
4336 }
4337
4338 pub fn is_unsafe(&self) -> bool {
4339 self.safety().is_unsafe()
4340 }
4341
4342 pub fn is_safe(&self) -> bool {
4343 self.safety().is_safe()
4344 }
4345
4346 pub fn safety(&self) -> Safety {
4347 match self.safety {
4348 HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
4349 HeaderSafety::Normal(safety) => safety,
4350 }
4351 }
4352}
4353
4354#[derive(Debug, Clone, Copy, HashStable_Generic)]
4355pub enum ItemKind<'hir> {
4356 ExternCrate(Option<Symbol>, Ident),
4360
4361 Use(&'hir UsePath<'hir>, UseKind),
4367
4368 Static(Mutability, Ident, &'hir Ty<'hir>, BodyId),
4370 Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4372 Fn {
4374 sig: FnSig<'hir>,
4375 ident: Ident,
4376 generics: &'hir Generics<'hir>,
4377 body: BodyId,
4378 has_body: bool,
4382 },
4383 Macro(Ident, &'hir ast::MacroDef, MacroKinds),
4385 Mod(Ident, &'hir Mod<'hir>),
4387 ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] },
4389 GlobalAsm {
4391 asm: &'hir InlineAsm<'hir>,
4392 fake_body: BodyId,
4398 },
4399 TyAlias(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4401 Enum(Ident, &'hir Generics<'hir>, EnumDef<'hir>),
4403 Struct(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4405 Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4407 Trait(
4409 Constness,
4410 IsAuto,
4411 Safety,
4412 Ident,
4413 &'hir Generics<'hir>,
4414 GenericBounds<'hir>,
4415 &'hir [TraitItemId],
4416 ),
4417 TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4419
4420 Impl(Impl<'hir>),
4422}
4423
4424#[derive(Debug, Clone, Copy, HashStable_Generic)]
4429pub struct Impl<'hir> {
4430 pub generics: &'hir Generics<'hir>,
4431 pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
4432 pub self_ty: &'hir Ty<'hir>,
4433 pub items: &'hir [ImplItemId],
4434}
4435
4436#[derive(Debug, Clone, Copy, HashStable_Generic)]
4437pub struct TraitImplHeader<'hir> {
4438 pub constness: Constness,
4439 pub safety: Safety,
4440 pub polarity: ImplPolarity,
4441 pub defaultness: Defaultness,
4442 pub defaultness_span: Option<Span>,
4445 pub trait_ref: TraitRef<'hir>,
4446}
4447
4448impl ItemKind<'_> {
4449 pub fn ident(&self) -> Option<Ident> {
4450 match *self {
4451 ItemKind::ExternCrate(_, ident)
4452 | ItemKind::Use(_, UseKind::Single(ident))
4453 | ItemKind::Static(_, ident, ..)
4454 | ItemKind::Const(ident, ..)
4455 | ItemKind::Fn { ident, .. }
4456 | ItemKind::Macro(ident, ..)
4457 | ItemKind::Mod(ident, ..)
4458 | ItemKind::TyAlias(ident, ..)
4459 | ItemKind::Enum(ident, ..)
4460 | ItemKind::Struct(ident, ..)
4461 | ItemKind::Union(ident, ..)
4462 | ItemKind::Trait(_, _, _, ident, ..)
4463 | ItemKind::TraitAlias(ident, ..) => Some(ident),
4464
4465 ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
4466 | ItemKind::ForeignMod { .. }
4467 | ItemKind::GlobalAsm { .. }
4468 | ItemKind::Impl(_) => None,
4469 }
4470 }
4471
4472 pub fn generics(&self) -> Option<&Generics<'_>> {
4473 Some(match self {
4474 ItemKind::Fn { generics, .. }
4475 | ItemKind::TyAlias(_, generics, _)
4476 | ItemKind::Const(_, generics, _, _)
4477 | ItemKind::Enum(_, generics, _)
4478 | ItemKind::Struct(_, generics, _)
4479 | ItemKind::Union(_, generics, _)
4480 | ItemKind::Trait(_, _, _, _, generics, _, _)
4481 | ItemKind::TraitAlias(_, generics, _)
4482 | ItemKind::Impl(Impl { generics, .. }) => generics,
4483 _ => return None,
4484 })
4485 }
4486}
4487
4488#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4492pub struct ForeignItemId {
4493 pub owner_id: OwnerId,
4494}
4495
4496impl ForeignItemId {
4497 #[inline]
4498 pub fn hir_id(&self) -> HirId {
4499 HirId::make_owner(self.owner_id.def_id)
4501 }
4502}
4503
4504#[derive(Debug, Clone, Copy, HashStable_Generic)]
4505pub struct ForeignItem<'hir> {
4506 pub ident: Ident,
4507 pub kind: ForeignItemKind<'hir>,
4508 pub owner_id: OwnerId,
4509 pub span: Span,
4510 pub vis_span: Span,
4511 pub has_delayed_lints: bool,
4512}
4513
4514impl ForeignItem<'_> {
4515 #[inline]
4516 pub fn hir_id(&self) -> HirId {
4517 HirId::make_owner(self.owner_id.def_id)
4519 }
4520
4521 pub fn foreign_item_id(&self) -> ForeignItemId {
4522 ForeignItemId { owner_id: self.owner_id }
4523 }
4524}
4525
4526#[derive(Debug, Clone, Copy, HashStable_Generic)]
4528pub enum ForeignItemKind<'hir> {
4529 Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
4536 Static(&'hir Ty<'hir>, Mutability, Safety),
4538 Type,
4540}
4541
4542#[derive(Debug, Copy, Clone, HashStable_Generic)]
4544pub struct Upvar {
4545 pub span: Span,
4547}
4548
4549#[derive(Debug, Clone, HashStable_Generic)]
4553pub struct TraitCandidate {
4554 pub def_id: DefId,
4555 pub import_ids: SmallVec<[LocalDefId; 1]>,
4556}
4557
4558#[derive(Copy, Clone, Debug, HashStable_Generic)]
4559pub enum OwnerNode<'hir> {
4560 Item(&'hir Item<'hir>),
4561 ForeignItem(&'hir ForeignItem<'hir>),
4562 TraitItem(&'hir TraitItem<'hir>),
4563 ImplItem(&'hir ImplItem<'hir>),
4564 Crate(&'hir Mod<'hir>),
4565 Synthetic,
4566}
4567
4568impl<'hir> OwnerNode<'hir> {
4569 pub fn span(&self) -> Span {
4570 match self {
4571 OwnerNode::Item(Item { span, .. })
4572 | OwnerNode::ForeignItem(ForeignItem { span, .. })
4573 | OwnerNode::ImplItem(ImplItem { span, .. })
4574 | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4575 OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4576 OwnerNode::Synthetic => unreachable!(),
4577 }
4578 }
4579
4580 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4581 match self {
4582 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4583 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4584 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4585 | OwnerNode::ForeignItem(ForeignItem {
4586 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4587 }) => Some(fn_sig),
4588 _ => None,
4589 }
4590 }
4591
4592 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4593 match self {
4594 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4595 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4596 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4597 | OwnerNode::ForeignItem(ForeignItem {
4598 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4599 }) => Some(fn_sig.decl),
4600 _ => None,
4601 }
4602 }
4603
4604 pub fn body_id(&self) -> Option<BodyId> {
4605 match self {
4606 OwnerNode::Item(Item {
4607 kind:
4608 ItemKind::Static(_, _, _, body)
4609 | ItemKind::Const(_, _, _, body)
4610 | ItemKind::Fn { body, .. },
4611 ..
4612 })
4613 | OwnerNode::TraitItem(TraitItem {
4614 kind:
4615 TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4616 ..
4617 })
4618 | OwnerNode::ImplItem(ImplItem {
4619 kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4620 ..
4621 }) => Some(*body),
4622 _ => None,
4623 }
4624 }
4625
4626 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4627 Node::generics(self.into())
4628 }
4629
4630 pub fn def_id(self) -> OwnerId {
4631 match self {
4632 OwnerNode::Item(Item { owner_id, .. })
4633 | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4634 | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4635 | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4636 OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4637 OwnerNode::Synthetic => unreachable!(),
4638 }
4639 }
4640
4641 pub fn is_impl_block(&self) -> bool {
4643 matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4644 }
4645
4646 expect_methods_self! {
4647 expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
4648 expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4649 expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n;
4650 expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n;
4651 }
4652}
4653
4654impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4655 fn from(val: &'hir Item<'hir>) -> Self {
4656 OwnerNode::Item(val)
4657 }
4658}
4659
4660impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4661 fn from(val: &'hir ForeignItem<'hir>) -> Self {
4662 OwnerNode::ForeignItem(val)
4663 }
4664}
4665
4666impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4667 fn from(val: &'hir ImplItem<'hir>) -> Self {
4668 OwnerNode::ImplItem(val)
4669 }
4670}
4671
4672impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4673 fn from(val: &'hir TraitItem<'hir>) -> Self {
4674 OwnerNode::TraitItem(val)
4675 }
4676}
4677
4678impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4679 fn from(val: OwnerNode<'hir>) -> Self {
4680 match val {
4681 OwnerNode::Item(n) => Node::Item(n),
4682 OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4683 OwnerNode::ImplItem(n) => Node::ImplItem(n),
4684 OwnerNode::TraitItem(n) => Node::TraitItem(n),
4685 OwnerNode::Crate(n) => Node::Crate(n),
4686 OwnerNode::Synthetic => Node::Synthetic,
4687 }
4688 }
4689}
4690
4691#[derive(Copy, Clone, Debug, HashStable_Generic)]
4692pub enum Node<'hir> {
4693 Param(&'hir Param<'hir>),
4694 Item(&'hir Item<'hir>),
4695 ForeignItem(&'hir ForeignItem<'hir>),
4696 TraitItem(&'hir TraitItem<'hir>),
4697 ImplItem(&'hir ImplItem<'hir>),
4698 Variant(&'hir Variant<'hir>),
4699 Field(&'hir FieldDef<'hir>),
4700 AnonConst(&'hir AnonConst),
4701 ConstBlock(&'hir ConstBlock),
4702 ConstArg(&'hir ConstArg<'hir>),
4703 Expr(&'hir Expr<'hir>),
4704 ExprField(&'hir ExprField<'hir>),
4705 Stmt(&'hir Stmt<'hir>),
4706 PathSegment(&'hir PathSegment<'hir>),
4707 Ty(&'hir Ty<'hir>),
4708 AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4709 TraitRef(&'hir TraitRef<'hir>),
4710 OpaqueTy(&'hir OpaqueTy<'hir>),
4711 TyPat(&'hir TyPat<'hir>),
4712 Pat(&'hir Pat<'hir>),
4713 PatField(&'hir PatField<'hir>),
4714 PatExpr(&'hir PatExpr<'hir>),
4718 Arm(&'hir Arm<'hir>),
4719 Block(&'hir Block<'hir>),
4720 LetStmt(&'hir LetStmt<'hir>),
4721 Ctor(&'hir VariantData<'hir>),
4724 Lifetime(&'hir Lifetime),
4725 GenericParam(&'hir GenericParam<'hir>),
4726 Crate(&'hir Mod<'hir>),
4727 Infer(&'hir InferArg),
4728 WherePredicate(&'hir WherePredicate<'hir>),
4729 PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4730 Synthetic,
4732 Err(Span),
4733}
4734
4735impl<'hir> Node<'hir> {
4736 pub fn ident(&self) -> Option<Ident> {
4751 match self {
4752 Node::Item(item) => item.kind.ident(),
4753 Node::TraitItem(TraitItem { ident, .. })
4754 | Node::ImplItem(ImplItem { ident, .. })
4755 | Node::ForeignItem(ForeignItem { ident, .. })
4756 | Node::Field(FieldDef { ident, .. })
4757 | Node::Variant(Variant { ident, .. })
4758 | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4759 Node::Lifetime(lt) => Some(lt.ident),
4760 Node::GenericParam(p) => Some(p.name.ident()),
4761 Node::AssocItemConstraint(c) => Some(c.ident),
4762 Node::PatField(f) => Some(f.ident),
4763 Node::ExprField(f) => Some(f.ident),
4764 Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4765 Node::Param(..)
4766 | Node::AnonConst(..)
4767 | Node::ConstBlock(..)
4768 | Node::ConstArg(..)
4769 | Node::Expr(..)
4770 | Node::Stmt(..)
4771 | Node::Block(..)
4772 | Node::Ctor(..)
4773 | Node::Pat(..)
4774 | Node::TyPat(..)
4775 | Node::PatExpr(..)
4776 | Node::Arm(..)
4777 | Node::LetStmt(..)
4778 | Node::Crate(..)
4779 | Node::Ty(..)
4780 | Node::TraitRef(..)
4781 | Node::OpaqueTy(..)
4782 | Node::Infer(..)
4783 | Node::WherePredicate(..)
4784 | Node::Synthetic
4785 | Node::Err(..) => None,
4786 }
4787 }
4788
4789 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4790 match self {
4791 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4792 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4793 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4794 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4795 Some(fn_sig.decl)
4796 }
4797 Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4798 Some(fn_decl)
4799 }
4800 _ => None,
4801 }
4802 }
4803
4804 pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4806 if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4807 && let Some(of_trait) = impl_block.of_trait
4808 && let Some(trait_id) = of_trait.trait_ref.trait_def_id()
4809 && trait_id == trait_def_id
4810 {
4811 Some(impl_block)
4812 } else {
4813 None
4814 }
4815 }
4816
4817 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4818 match self {
4819 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4820 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4821 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4822 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4823 Some(fn_sig)
4824 }
4825 _ => None,
4826 }
4827 }
4828
4829 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4831 match self {
4832 Node::Item(it) => match it.kind {
4833 ItemKind::TyAlias(_, _, ty)
4834 | ItemKind::Static(_, _, ty, _)
4835 | ItemKind::Const(_, _, ty, _) => Some(ty),
4836 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4837 _ => None,
4838 },
4839 Node::TraitItem(it) => match it.kind {
4840 TraitItemKind::Const(ty, _) => Some(ty),
4841 TraitItemKind::Type(_, ty) => ty,
4842 _ => None,
4843 },
4844 Node::ImplItem(it) => match it.kind {
4845 ImplItemKind::Const(ty, _) => Some(ty),
4846 ImplItemKind::Type(ty) => Some(ty),
4847 _ => None,
4848 },
4849 Node::ForeignItem(it) => match it.kind {
4850 ForeignItemKind::Static(ty, ..) => Some(ty),
4851 _ => None,
4852 },
4853 _ => None,
4854 }
4855 }
4856
4857 pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4858 match self {
4859 Node::Item(Item { kind: ItemKind::TyAlias(_, _, ty), .. }) => Some(ty),
4860 _ => None,
4861 }
4862 }
4863
4864 #[inline]
4865 pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4866 match self {
4867 Node::Item(Item {
4868 owner_id,
4869 kind:
4870 ItemKind::Const(_, _, _, body)
4871 | ItemKind::Static(.., body)
4872 | ItemKind::Fn { body, .. },
4873 ..
4874 })
4875 | Node::TraitItem(TraitItem {
4876 owner_id,
4877 kind:
4878 TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4879 ..
4880 })
4881 | Node::ImplItem(ImplItem {
4882 owner_id,
4883 kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4884 ..
4885 }) => Some((owner_id.def_id, *body)),
4886
4887 Node::Item(Item {
4888 owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4889 }) => Some((owner_id.def_id, *fake_body)),
4890
4891 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4892 Some((*def_id, *body))
4893 }
4894
4895 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4896 Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4897
4898 _ => None,
4899 }
4900 }
4901
4902 pub fn body_id(&self) -> Option<BodyId> {
4903 Some(self.associated_body()?.1)
4904 }
4905
4906 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4907 match self {
4908 Node::ForeignItem(ForeignItem {
4909 kind: ForeignItemKind::Fn(_, _, generics), ..
4910 })
4911 | Node::TraitItem(TraitItem { generics, .. })
4912 | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4913 Node::Item(item) => item.kind.generics(),
4914 _ => None,
4915 }
4916 }
4917
4918 pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4919 match self {
4920 Node::Item(i) => Some(OwnerNode::Item(i)),
4921 Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4922 Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4923 Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4924 Node::Crate(i) => Some(OwnerNode::Crate(i)),
4925 Node::Synthetic => Some(OwnerNode::Synthetic),
4926 _ => None,
4927 }
4928 }
4929
4930 pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4931 match self {
4932 Node::Item(i) => match i.kind {
4933 ItemKind::Fn { ident, sig, generics, .. } => {
4934 Some(FnKind::ItemFn(ident, generics, sig.header))
4935 }
4936 _ => None,
4937 },
4938 Node::TraitItem(ti) => match ti.kind {
4939 TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4940 _ => None,
4941 },
4942 Node::ImplItem(ii) => match ii.kind {
4943 ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4944 _ => None,
4945 },
4946 Node::Expr(e) => match e.kind {
4947 ExprKind::Closure { .. } => Some(FnKind::Closure),
4948 _ => None,
4949 },
4950 _ => None,
4951 }
4952 }
4953
4954 expect_methods_self! {
4955 expect_param, &'hir Param<'hir>, Node::Param(n), n;
4956 expect_item, &'hir Item<'hir>, Node::Item(n), n;
4957 expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n;
4958 expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n;
4959 expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n;
4960 expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
4961 expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
4962 expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
4963 expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
4964 expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
4965 expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
4966 expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
4967 expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
4968 expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
4969 expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
4970 expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4971 expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
4972 expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
4973 expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
4974 expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
4975 expect_block, &'hir Block<'hir>, Node::Block(n), n;
4976 expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
4977 expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
4978 expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
4979 expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
4980 expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
4981 expect_infer, &'hir InferArg, Node::Infer(n), n;
4982 expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
4983 }
4984}
4985
4986#[cfg(target_pointer_width = "64")]
4988mod size_asserts {
4989 use rustc_data_structures::static_assert_size;
4990
4991 use super::*;
4992 static_assert_size!(Block<'_>, 48);
4994 static_assert_size!(Body<'_>, 24);
4995 static_assert_size!(Expr<'_>, 64);
4996 static_assert_size!(ExprKind<'_>, 48);
4997 static_assert_size!(FnDecl<'_>, 40);
4998 static_assert_size!(ForeignItem<'_>, 96);
4999 static_assert_size!(ForeignItemKind<'_>, 56);
5000 static_assert_size!(GenericArg<'_>, 16);
5001 static_assert_size!(GenericBound<'_>, 64);
5002 static_assert_size!(Generics<'_>, 56);
5003 static_assert_size!(Impl<'_>, 40);
5004 static_assert_size!(ImplItem<'_>, 88);
5005 static_assert_size!(ImplItemKind<'_>, 40);
5006 static_assert_size!(Item<'_>, 88);
5007 static_assert_size!(ItemKind<'_>, 64);
5008 static_assert_size!(LetStmt<'_>, 72);
5009 static_assert_size!(Param<'_>, 32);
5010 static_assert_size!(Pat<'_>, 80);
5011 static_assert_size!(PatKind<'_>, 56);
5012 static_assert_size!(Path<'_>, 40);
5013 static_assert_size!(PathSegment<'_>, 48);
5014 static_assert_size!(QPath<'_>, 24);
5015 static_assert_size!(Res, 12);
5016 static_assert_size!(Stmt<'_>, 32);
5017 static_assert_size!(StmtKind<'_>, 16);
5018 static_assert_size!(TraitImplHeader<'_>, 48);
5019 static_assert_size!(TraitItem<'_>, 88);
5020 static_assert_size!(TraitItemKind<'_>, 48);
5021 static_assert_size!(Ty<'_>, 48);
5022 static_assert_size!(TyKind<'_>, 32);
5023 }
5025
5026#[cfg(test)]
5027mod tests;