1use std::fmt;
3
4use rustc_abi::ExternAbi;
5use rustc_ast::attr::AttributeExt;
6use rustc_ast::token::CommentKind;
7use rustc_ast::util::parser::ExprPrecedence;
8use rustc_ast::{
9 self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType,
10 LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind,
11};
12pub use rustc_ast::{
13 AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind,
14 BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto,
15 MetaItemInner, MetaItemLit, Movability, Mutability, UnOp,
16};
17use rustc_attr_data_structures::AttributeKind;
18use rustc_data_structures::fingerprint::Fingerprint;
19use rustc_data_structures::sorted_map::SortedMap;
20use rustc_data_structures::tagged_ptr::TaggedRef;
21use rustc_index::IndexVec;
22use rustc_macros::{Decodable, Encodable, HashStable_Generic};
23use rustc_span::def_id::LocalDefId;
24use rustc_span::hygiene::MacroKind;
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::def::{CtorKind, DefKind, PerNS, Res};
34use crate::def_id::{DefId, LocalDefIdMap};
35pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
36use crate::intravisit::{FnKind, VisitorExt};
37
38#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
39pub enum AngleBrackets {
40 Missing,
42 Empty,
44 Full,
46}
47
48#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
49pub enum LifetimeSource {
50 Reference,
52
53 Path { angle_brackets: AngleBrackets },
56
57 OutlivesBound,
59
60 PreciseCapturing,
62
63 Other,
70}
71
72#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
73pub enum LifetimeSyntax {
74 Implicit,
76
77 ExplicitAnonymous,
79
80 ExplicitBound,
82}
83
84impl From<Ident> for LifetimeSyntax {
85 fn from(ident: Ident) -> Self {
86 let name = ident.name;
87
88 if name == sym::empty {
89 unreachable!("A lifetime name should never be empty");
90 } else if name == kw::UnderscoreLifetime {
91 LifetimeSyntax::ExplicitAnonymous
92 } else {
93 debug_assert!(name.as_str().starts_with('\''));
94 LifetimeSyntax::ExplicitBound
95 }
96 }
97}
98
99#[derive(Debug, Copy, Clone, HashStable_Generic)]
150pub struct Lifetime {
151 #[stable_hasher(ignore)]
152 pub hir_id: HirId,
153
154 pub ident: Ident,
158
159 pub kind: LifetimeKind,
161
162 pub source: LifetimeSource,
165
166 pub syntax: LifetimeSyntax,
169}
170
171#[derive(Debug, Copy, Clone, HashStable_Generic)]
172pub enum ParamName {
173 Plain(Ident),
175
176 Error(Ident),
182
183 Fresh,
198}
199
200impl ParamName {
201 pub fn ident(&self) -> Ident {
202 match *self {
203 ParamName::Plain(ident) | ParamName::Error(ident) => ident,
204 ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
205 }
206 }
207}
208
209#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
210pub enum LifetimeKind {
211 Param(LocalDefId),
213
214 ImplicitObjectLifetimeDefault,
226
227 Error,
230
231 Infer,
235
236 Static,
238}
239
240impl LifetimeKind {
241 fn is_elided(&self) -> bool {
242 match self {
243 LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer => true,
244
245 LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
250 }
251 }
252}
253
254impl fmt::Display for Lifetime {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 self.ident.name.fmt(f)
257 }
258}
259
260impl Lifetime {
261 pub fn new(
262 hir_id: HirId,
263 ident: Ident,
264 kind: LifetimeKind,
265 source: LifetimeSource,
266 syntax: LifetimeSyntax,
267 ) -> Lifetime {
268 let lifetime = Lifetime { hir_id, ident, kind, source, syntax };
269
270 #[cfg(debug_assertions)]
272 match (lifetime.is_elided(), lifetime.is_anonymous()) {
273 (false, false) => {} (false, true) => {} (true, true) => {} (true, false) => panic!("bad Lifetime"),
277 }
278
279 lifetime
280 }
281
282 pub fn is_elided(&self) -> bool {
283 self.kind.is_elided()
284 }
285
286 pub fn is_anonymous(&self) -> bool {
287 self.ident.name == kw::UnderscoreLifetime
288 }
289
290 pub fn is_implicit(&self) -> bool {
291 matches!(self.syntax, LifetimeSyntax::Implicit)
292 }
293
294 pub fn is_static(&self) -> bool {
295 self.kind == LifetimeKind::Static
296 }
297
298 pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
299 use LifetimeSource::*;
300 use LifetimeSyntax::*;
301
302 debug_assert!(new_lifetime.starts_with('\''));
303
304 match (self.syntax, self.source) {
305 (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")),
307
308 (Implicit, Path { angle_brackets: AngleBrackets::Full }) => {
310 (self.ident.span, format!("{new_lifetime}, "))
311 }
312
313 (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => {
315 (self.ident.span, format!("{new_lifetime}"))
316 }
317
318 (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => {
320 (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
321 }
322
323 (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")),
325
326 (Implicit, source) => {
327 unreachable!("can't suggest for a implicit lifetime of {source:?}")
328 }
329 }
330 }
331}
332
333#[derive(Debug, Clone, Copy, HashStable_Generic)]
337pub struct Path<'hir, R = Res> {
338 pub span: Span,
339 pub res: R,
341 pub segments: &'hir [PathSegment<'hir>],
343}
344
345pub type UsePath<'hir> = Path<'hir, PerNS<Option<Res>>>;
347
348impl Path<'_> {
349 pub fn is_global(&self) -> bool {
350 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
351 }
352}
353
354#[derive(Debug, Clone, Copy, HashStable_Generic)]
357pub struct PathSegment<'hir> {
358 pub ident: Ident,
360 #[stable_hasher(ignore)]
361 pub hir_id: HirId,
362 pub res: Res,
363
364 pub args: Option<&'hir GenericArgs<'hir>>,
370
371 pub infer_args: bool,
376}
377
378impl<'hir> PathSegment<'hir> {
379 pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
381 PathSegment { ident, hir_id, res, infer_args: true, args: None }
382 }
383
384 pub fn invalid() -> Self {
385 Self::new(Ident::dummy(), HirId::INVALID, Res::Err)
386 }
387
388 pub fn args(&self) -> &GenericArgs<'hir> {
389 if let Some(ref args) = self.args {
390 args
391 } else {
392 const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
393 DUMMY
394 }
395 }
396}
397
398#[derive(Clone, Copy, Debug, HashStable_Generic)]
414#[repr(C)]
415pub struct ConstArg<'hir, Unambig = ()> {
416 #[stable_hasher(ignore)]
417 pub hir_id: HirId,
418 pub kind: ConstArgKind<'hir, Unambig>,
419}
420
421impl<'hir> ConstArg<'hir, AmbigArg> {
422 pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
433 let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
436 unsafe { &*ptr }
437 }
438}
439
440impl<'hir> ConstArg<'hir> {
441 pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
447 if let ConstArgKind::Infer(_, ()) = self.kind {
448 return None;
449 }
450
451 let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
455 Some(unsafe { &*ptr })
456 }
457}
458
459impl<'hir, Unambig> ConstArg<'hir, Unambig> {
460 pub fn anon_const_hir_id(&self) -> Option<HirId> {
461 match self.kind {
462 ConstArgKind::Anon(ac) => Some(ac.hir_id),
463 _ => None,
464 }
465 }
466
467 pub fn span(&self) -> Span {
468 match self.kind {
469 ConstArgKind::Path(path) => path.span(),
470 ConstArgKind::Anon(anon) => anon.span,
471 ConstArgKind::Infer(span, _) => span,
472 }
473 }
474}
475
476#[derive(Clone, Copy, Debug, HashStable_Generic)]
478#[repr(u8, C)]
479pub enum ConstArgKind<'hir, Unambig = ()> {
480 Path(QPath<'hir>),
486 Anon(&'hir AnonConst),
487 Infer(Span, Unambig),
490}
491
492#[derive(Clone, Copy, Debug, HashStable_Generic)]
493pub struct InferArg {
494 #[stable_hasher(ignore)]
495 pub hir_id: HirId,
496 pub span: Span,
497}
498
499impl InferArg {
500 pub fn to_ty(&self) -> Ty<'static> {
501 Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
502 }
503}
504
505#[derive(Debug, Clone, Copy, HashStable_Generic)]
506pub enum GenericArg<'hir> {
507 Lifetime(&'hir Lifetime),
508 Type(&'hir Ty<'hir, AmbigArg>),
509 Const(&'hir ConstArg<'hir, AmbigArg>),
510 Infer(InferArg),
520}
521
522impl GenericArg<'_> {
523 pub fn span(&self) -> Span {
524 match self {
525 GenericArg::Lifetime(l) => l.ident.span,
526 GenericArg::Type(t) => t.span,
527 GenericArg::Const(c) => c.span(),
528 GenericArg::Infer(i) => i.span,
529 }
530 }
531
532 pub fn hir_id(&self) -> HirId {
533 match self {
534 GenericArg::Lifetime(l) => l.hir_id,
535 GenericArg::Type(t) => t.hir_id,
536 GenericArg::Const(c) => c.hir_id,
537 GenericArg::Infer(i) => i.hir_id,
538 }
539 }
540
541 pub fn descr(&self) -> &'static str {
542 match self {
543 GenericArg::Lifetime(_) => "lifetime",
544 GenericArg::Type(_) => "type",
545 GenericArg::Const(_) => "constant",
546 GenericArg::Infer(_) => "placeholder",
547 }
548 }
549
550 pub fn to_ord(&self) -> ast::ParamKindOrd {
551 match self {
552 GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
553 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
554 ast::ParamKindOrd::TypeOrConst
555 }
556 }
557 }
558
559 pub fn is_ty_or_const(&self) -> bool {
560 match self {
561 GenericArg::Lifetime(_) => false,
562 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
563 }
564 }
565}
566
567#[derive(Debug, Clone, Copy, HashStable_Generic)]
569pub struct GenericArgs<'hir> {
570 pub args: &'hir [GenericArg<'hir>],
572 pub constraints: &'hir [AssocItemConstraint<'hir>],
574 pub parenthesized: GenericArgsParentheses,
579 pub span_ext: Span,
592}
593
594impl<'hir> GenericArgs<'hir> {
595 pub const fn none() -> Self {
596 Self {
597 args: &[],
598 constraints: &[],
599 parenthesized: GenericArgsParentheses::No,
600 span_ext: DUMMY_SP,
601 }
602 }
603
604 pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
609 if self.parenthesized != GenericArgsParentheses::ParenSugar {
610 return None;
611 }
612
613 let inputs = self
614 .args
615 .iter()
616 .find_map(|arg| {
617 let GenericArg::Type(ty) = arg else { return None };
618 let TyKind::Tup(tys) = &ty.kind else { return None };
619 Some(tys)
620 })
621 .unwrap();
622
623 Some((inputs, self.paren_sugar_output_inner()))
624 }
625
626 pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
631 (self.parenthesized == GenericArgsParentheses::ParenSugar)
632 .then(|| self.paren_sugar_output_inner())
633 }
634
635 fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
636 let [constraint] = self.constraints.try_into().unwrap();
637 debug_assert_eq!(constraint.ident.name, sym::Output);
638 constraint.ty().unwrap()
639 }
640
641 pub fn has_err(&self) -> Option<ErrorGuaranteed> {
642 self.args
643 .iter()
644 .find_map(|arg| {
645 let GenericArg::Type(ty) = arg else { return None };
646 let TyKind::Err(guar) = ty.kind else { return None };
647 Some(guar)
648 })
649 .or_else(|| {
650 self.constraints.iter().find_map(|constraint| {
651 let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
652 Some(guar)
653 })
654 })
655 }
656
657 #[inline]
658 pub fn num_lifetime_params(&self) -> usize {
659 self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
660 }
661
662 #[inline]
663 pub fn has_lifetime_params(&self) -> bool {
664 self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
665 }
666
667 #[inline]
668 pub fn num_generic_params(&self) -> usize {
671 self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
672 }
673
674 pub fn span(&self) -> Option<Span> {
680 let span_ext = self.span_ext()?;
681 Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
682 }
683
684 pub fn span_ext(&self) -> Option<Span> {
686 Some(self.span_ext).filter(|span| !span.is_empty())
687 }
688
689 pub fn is_empty(&self) -> bool {
690 self.args.is_empty()
691 }
692}
693
694#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
695pub enum GenericArgsParentheses {
696 No,
697 ReturnTypeNotation,
700 ParenSugar,
702}
703
704#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
706pub struct TraitBoundModifiers {
707 pub constness: BoundConstness,
708 pub polarity: BoundPolarity,
709}
710
711impl TraitBoundModifiers {
712 pub const NONE: Self =
713 TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
714}
715
716#[derive(Clone, Copy, Debug, HashStable_Generic)]
717pub enum GenericBound<'hir> {
718 Trait(PolyTraitRef<'hir>),
719 Outlives(&'hir Lifetime),
720 Use(&'hir [PreciseCapturingArg<'hir>], Span),
721}
722
723impl GenericBound<'_> {
724 pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
725 match self {
726 GenericBound::Trait(data) => Some(&data.trait_ref),
727 _ => None,
728 }
729 }
730
731 pub fn span(&self) -> Span {
732 match self {
733 GenericBound::Trait(t, ..) => t.span,
734 GenericBound::Outlives(l) => l.ident.span,
735 GenericBound::Use(_, span) => *span,
736 }
737 }
738}
739
740pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
741
742#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
743pub enum MissingLifetimeKind {
744 Underscore,
746 Ampersand,
748 Comma,
750 Brackets,
752}
753
754#[derive(Copy, Clone, Debug, HashStable_Generic)]
755pub enum LifetimeParamKind {
756 Explicit,
759
760 Elided(MissingLifetimeKind),
763
764 Error,
766}
767
768#[derive(Debug, Clone, Copy, HashStable_Generic)]
769pub enum GenericParamKind<'hir> {
770 Lifetime {
772 kind: LifetimeParamKind,
773 },
774 Type {
775 default: Option<&'hir Ty<'hir>>,
776 synthetic: bool,
777 },
778 Const {
779 ty: &'hir Ty<'hir>,
780 default: Option<&'hir ConstArg<'hir>>,
782 synthetic: bool,
783 },
784}
785
786#[derive(Debug, Clone, Copy, HashStable_Generic)]
787pub struct GenericParam<'hir> {
788 #[stable_hasher(ignore)]
789 pub hir_id: HirId,
790 pub def_id: LocalDefId,
791 pub name: ParamName,
792 pub span: Span,
793 pub pure_wrt_drop: bool,
794 pub kind: GenericParamKind<'hir>,
795 pub colon_span: Option<Span>,
796 pub source: GenericParamSource,
797}
798
799impl<'hir> GenericParam<'hir> {
800 pub fn is_impl_trait(&self) -> bool {
804 matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
805 }
806
807 pub fn is_elided_lifetime(&self) -> bool {
811 matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
812 }
813}
814
815#[derive(Debug, Clone, Copy, HashStable_Generic)]
822pub enum GenericParamSource {
823 Generics,
825 Binder,
827}
828
829#[derive(Default)]
830pub struct GenericParamCount {
831 pub lifetimes: usize,
832 pub types: usize,
833 pub consts: usize,
834 pub infer: usize,
835}
836
837#[derive(Debug, Clone, Copy, HashStable_Generic)]
840pub struct Generics<'hir> {
841 pub params: &'hir [GenericParam<'hir>],
842 pub predicates: &'hir [WherePredicate<'hir>],
843 pub has_where_clause_predicates: bool,
844 pub where_clause_span: Span,
845 pub span: Span,
846}
847
848impl<'hir> Generics<'hir> {
849 pub const fn empty() -> &'hir Generics<'hir> {
850 const NOPE: Generics<'_> = Generics {
851 params: &[],
852 predicates: &[],
853 has_where_clause_predicates: false,
854 where_clause_span: DUMMY_SP,
855 span: DUMMY_SP,
856 };
857 &NOPE
858 }
859
860 pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
861 self.params.iter().find(|¶m| name == param.name.ident().name)
862 }
863
864 pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
866 if let Some(first) = self.params.first()
867 && self.span.contains(first.span)
868 {
869 Some(first.span.shrink_to_lo())
872 } else {
873 None
874 }
875 }
876
877 pub fn span_for_param_suggestion(&self) -> Option<Span> {
879 self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
880 self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
883 })
884 }
885
886 pub fn tail_span_for_predicate_suggestion(&self) -> Span {
889 let end = self.where_clause_span.shrink_to_hi();
890 if self.has_where_clause_predicates {
891 self.predicates
892 .iter()
893 .rfind(|&p| p.kind.in_where_clause())
894 .map_or(end, |p| p.span)
895 .shrink_to_hi()
896 .to(end)
897 } else {
898 end
899 }
900 }
901
902 pub fn add_where_or_trailing_comma(&self) -> &'static str {
903 if self.has_where_clause_predicates {
904 ","
905 } else if self.where_clause_span.is_empty() {
906 " where"
907 } else {
908 ""
910 }
911 }
912
913 pub fn bounds_for_param(
914 &self,
915 param_def_id: LocalDefId,
916 ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
917 self.predicates.iter().filter_map(move |pred| match pred.kind {
918 WherePredicateKind::BoundPredicate(bp)
919 if bp.is_param_bound(param_def_id.to_def_id()) =>
920 {
921 Some(bp)
922 }
923 _ => None,
924 })
925 }
926
927 pub fn outlives_for_param(
928 &self,
929 param_def_id: LocalDefId,
930 ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
931 self.predicates.iter().filter_map(move |pred| match pred.kind {
932 WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
933 _ => None,
934 })
935 }
936
937 pub fn bounds_span_for_suggestions(
948 &self,
949 param_def_id: LocalDefId,
950 ) -> Option<(Span, Option<Span>)> {
951 self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
952 |bound| {
953 let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
954 && let [.., segment] = trait_ref.path.segments
955 && let Some(ret_ty) = segment.args().paren_sugar_output()
956 && let ret_ty = ret_ty.peel_refs()
957 && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
958 && let TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar = tagged_ptr.tag()
959 && ret_ty.span.can_be_used_for_suggestions()
960 {
961 Some(ret_ty.span)
962 } else {
963 None
964 };
965
966 span_for_parentheses.map_or_else(
967 || {
968 let bs = bound.span();
971 bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
972 },
973 |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
974 )
975 },
976 )
977 }
978
979 pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
980 let predicate = &self.predicates[pos];
981 let span = predicate.span;
982
983 if !predicate.kind.in_where_clause() {
984 return span;
987 }
988
989 if pos < self.predicates.len() - 1 {
991 let next_pred = &self.predicates[pos + 1];
992 if next_pred.kind.in_where_clause() {
993 return span.until(next_pred.span);
996 }
997 }
998
999 if pos > 0 {
1000 let prev_pred = &self.predicates[pos - 1];
1001 if prev_pred.kind.in_where_clause() {
1002 return prev_pred.span.shrink_to_hi().to(span);
1005 }
1006 }
1007
1008 self.where_clause_span
1012 }
1013
1014 pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
1015 let predicate = &self.predicates[predicate_pos];
1016 let bounds = predicate.kind.bounds();
1017
1018 if bounds.len() == 1 {
1019 return self.span_for_predicate_removal(predicate_pos);
1020 }
1021
1022 let bound_span = bounds[bound_pos].span();
1023 if bound_pos < bounds.len() - 1 {
1024 bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
1030 } else {
1031 bound_span.with_lo(bounds[bound_pos - 1].span().hi())
1037 }
1038 }
1039}
1040
1041#[derive(Debug, Clone, Copy, HashStable_Generic)]
1043pub struct WherePredicate<'hir> {
1044 #[stable_hasher(ignore)]
1045 pub hir_id: HirId,
1046 pub span: Span,
1047 pub kind: &'hir WherePredicateKind<'hir>,
1048}
1049
1050#[derive(Debug, Clone, Copy, HashStable_Generic)]
1052pub enum WherePredicateKind<'hir> {
1053 BoundPredicate(WhereBoundPredicate<'hir>),
1055 RegionPredicate(WhereRegionPredicate<'hir>),
1057 EqPredicate(WhereEqPredicate<'hir>),
1059}
1060
1061impl<'hir> WherePredicateKind<'hir> {
1062 pub fn in_where_clause(&self) -> bool {
1063 match self {
1064 WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
1065 WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
1066 WherePredicateKind::EqPredicate(_) => false,
1067 }
1068 }
1069
1070 pub fn bounds(&self) -> GenericBounds<'hir> {
1071 match self {
1072 WherePredicateKind::BoundPredicate(p) => p.bounds,
1073 WherePredicateKind::RegionPredicate(p) => p.bounds,
1074 WherePredicateKind::EqPredicate(_) => &[],
1075 }
1076 }
1077}
1078
1079#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
1080pub enum PredicateOrigin {
1081 WhereClause,
1082 GenericParam,
1083 ImplTrait,
1084}
1085
1086#[derive(Debug, Clone, Copy, HashStable_Generic)]
1088pub struct WhereBoundPredicate<'hir> {
1089 pub origin: PredicateOrigin,
1091 pub bound_generic_params: &'hir [GenericParam<'hir>],
1093 pub bounded_ty: &'hir Ty<'hir>,
1095 pub bounds: GenericBounds<'hir>,
1097}
1098
1099impl<'hir> WhereBoundPredicate<'hir> {
1100 pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
1102 self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
1103 }
1104}
1105
1106#[derive(Debug, Clone, Copy, HashStable_Generic)]
1108pub struct WhereRegionPredicate<'hir> {
1109 pub in_where_clause: bool,
1110 pub lifetime: &'hir Lifetime,
1111 pub bounds: GenericBounds<'hir>,
1112}
1113
1114impl<'hir> WhereRegionPredicate<'hir> {
1115 fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
1117 self.lifetime.kind == LifetimeKind::Param(param_def_id)
1118 }
1119}
1120
1121#[derive(Debug, Clone, Copy, HashStable_Generic)]
1123pub struct WhereEqPredicate<'hir> {
1124 pub lhs_ty: &'hir Ty<'hir>,
1125 pub rhs_ty: &'hir Ty<'hir>,
1126}
1127
1128#[derive(Clone, Copy, Debug)]
1132pub struct ParentedNode<'tcx> {
1133 pub parent: ItemLocalId,
1134 pub node: Node<'tcx>,
1135}
1136
1137#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1139pub enum AttrArgs {
1140 Empty,
1142 Delimited(DelimArgs),
1144 Eq {
1146 eq_span: Span,
1148 expr: MetaItemLit,
1150 },
1151}
1152
1153#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1154pub struct AttrPath {
1155 pub segments: Box<[Ident]>,
1156 pub span: Span,
1157}
1158
1159impl AttrPath {
1160 pub fn from_ast(path: &ast::Path) -> Self {
1161 AttrPath {
1162 segments: path.segments.iter().map(|i| i.ident).collect::<Vec<_>>().into_boxed_slice(),
1163 span: path.span,
1164 }
1165 }
1166}
1167
1168impl fmt::Display for AttrPath {
1169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1170 write!(f, "{}", self.segments.iter().map(|i| i.to_string()).collect::<Vec<_>>().join("::"))
1171 }
1172}
1173
1174#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1175pub struct AttrItem {
1176 pub path: AttrPath,
1178 pub args: AttrArgs,
1179 pub id: HashIgnoredAttrId,
1180 pub style: AttrStyle,
1183 pub span: Span,
1185}
1186
1187#[derive(Copy, Debug, Encodable, Decodable, Clone)]
1190pub struct HashIgnoredAttrId {
1191 pub attr_id: AttrId,
1192}
1193
1194#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
1195pub enum Attribute {
1196 Parsed(AttributeKind),
1202
1203 Unparsed(Box<AttrItem>),
1206}
1207
1208impl Attribute {
1209 pub fn get_normal_item(&self) -> &AttrItem {
1210 match &self {
1211 Attribute::Unparsed(normal) => &normal,
1212 _ => panic!("unexpected parsed attribute"),
1213 }
1214 }
1215
1216 pub fn unwrap_normal_item(self) -> AttrItem {
1217 match self {
1218 Attribute::Unparsed(normal) => *normal,
1219 _ => panic!("unexpected parsed attribute"),
1220 }
1221 }
1222
1223 pub fn value_lit(&self) -> Option<&MetaItemLit> {
1224 match &self {
1225 Attribute::Unparsed(n) => match n.as_ref() {
1226 AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1227 _ => None,
1228 },
1229 _ => None,
1230 }
1231 }
1232}
1233
1234impl AttributeExt for Attribute {
1235 #[inline]
1236 fn id(&self) -> AttrId {
1237 match &self {
1238 Attribute::Unparsed(u) => u.id.attr_id,
1239 _ => panic!(),
1240 }
1241 }
1242
1243 #[inline]
1244 fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1245 match &self {
1246 Attribute::Unparsed(n) => match n.as_ref() {
1247 AttrItem { args: AttrArgs::Delimited(d), .. } => {
1248 ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1249 }
1250 _ => None,
1251 },
1252 _ => None,
1253 }
1254 }
1255
1256 #[inline]
1257 fn value_str(&self) -> Option<Symbol> {
1258 self.value_lit().and_then(|x| x.value_str())
1259 }
1260
1261 #[inline]
1262 fn value_span(&self) -> Option<Span> {
1263 self.value_lit().map(|i| i.span)
1264 }
1265
1266 #[inline]
1268 fn ident(&self) -> Option<Ident> {
1269 match &self {
1270 Attribute::Unparsed(n) => {
1271 if let [ident] = n.path.segments.as_ref() {
1272 Some(*ident)
1273 } else {
1274 None
1275 }
1276 }
1277 _ => None,
1278 }
1279 }
1280
1281 #[inline]
1282 fn path_matches(&self, name: &[Symbol]) -> bool {
1283 match &self {
1284 Attribute::Unparsed(n) => {
1285 n.path.segments.len() == name.len()
1286 && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
1287 }
1288 _ => false,
1289 }
1290 }
1291
1292 #[inline]
1293 fn is_doc_comment(&self) -> bool {
1294 matches!(self, Attribute::Parsed(AttributeKind::DocComment { .. }))
1295 }
1296
1297 #[inline]
1298 fn span(&self) -> Span {
1299 match &self {
1300 Attribute::Unparsed(u) => u.span,
1301 Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
1303 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1304 a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
1305 }
1306 }
1307
1308 #[inline]
1309 fn is_word(&self) -> bool {
1310 match &self {
1311 Attribute::Unparsed(n) => {
1312 matches!(n.args, AttrArgs::Empty)
1313 }
1314 _ => false,
1315 }
1316 }
1317
1318 #[inline]
1319 fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1320 match &self {
1321 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
1322 _ => None,
1323 }
1324 }
1325
1326 #[inline]
1327 fn doc_str(&self) -> Option<Symbol> {
1328 match &self {
1329 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
1330 Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(),
1331 _ => None,
1332 }
1333 }
1334 #[inline]
1335 fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1336 match &self {
1337 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
1338 Some((*comment, *kind))
1339 }
1340 Attribute::Unparsed(_) if self.has_name(sym::doc) => {
1341 self.value_str().map(|s| (s, CommentKind::Line))
1342 }
1343 _ => None,
1344 }
1345 }
1346
1347 #[inline]
1348 fn style(&self) -> AttrStyle {
1349 match &self {
1350 Attribute::Unparsed(u) => u.style,
1351 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => *style,
1352 _ => panic!(),
1353 }
1354 }
1355}
1356
1357impl Attribute {
1359 #[inline]
1360 pub fn id(&self) -> AttrId {
1361 AttributeExt::id(self)
1362 }
1363
1364 #[inline]
1365 pub fn name(&self) -> Option<Symbol> {
1366 AttributeExt::name(self)
1367 }
1368
1369 #[inline]
1370 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1371 AttributeExt::meta_item_list(self)
1372 }
1373
1374 #[inline]
1375 pub fn value_str(&self) -> Option<Symbol> {
1376 AttributeExt::value_str(self)
1377 }
1378
1379 #[inline]
1380 pub fn value_span(&self) -> Option<Span> {
1381 AttributeExt::value_span(self)
1382 }
1383
1384 #[inline]
1385 pub fn ident(&self) -> Option<Ident> {
1386 AttributeExt::ident(self)
1387 }
1388
1389 #[inline]
1390 pub fn path_matches(&self, name: &[Symbol]) -> bool {
1391 AttributeExt::path_matches(self, name)
1392 }
1393
1394 #[inline]
1395 pub fn is_doc_comment(&self) -> bool {
1396 AttributeExt::is_doc_comment(self)
1397 }
1398
1399 #[inline]
1400 pub fn has_name(&self, name: Symbol) -> bool {
1401 AttributeExt::has_name(self, name)
1402 }
1403
1404 #[inline]
1405 pub fn has_any_name(&self, names: &[Symbol]) -> bool {
1406 AttributeExt::has_any_name(self, names)
1407 }
1408
1409 #[inline]
1410 pub fn span(&self) -> Span {
1411 AttributeExt::span(self)
1412 }
1413
1414 #[inline]
1415 pub fn is_word(&self) -> bool {
1416 AttributeExt::is_word(self)
1417 }
1418
1419 #[inline]
1420 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1421 AttributeExt::path(self)
1422 }
1423
1424 #[inline]
1425 pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1426 AttributeExt::ident_path(self)
1427 }
1428
1429 #[inline]
1430 pub fn doc_str(&self) -> Option<Symbol> {
1431 AttributeExt::doc_str(self)
1432 }
1433
1434 #[inline]
1435 pub fn is_proc_macro_attr(&self) -> bool {
1436 AttributeExt::is_proc_macro_attr(self)
1437 }
1438
1439 #[inline]
1440 pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1441 AttributeExt::doc_str_and_comment_kind(self)
1442 }
1443
1444 #[inline]
1445 pub fn style(&self) -> AttrStyle {
1446 AttributeExt::style(self)
1447 }
1448}
1449
1450#[derive(Debug)]
1452pub struct AttributeMap<'tcx> {
1453 pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1454 pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
1456 pub opt_hash: Option<Fingerprint>,
1458}
1459
1460impl<'tcx> AttributeMap<'tcx> {
1461 pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1462 map: SortedMap::new(),
1463 opt_hash: Some(Fingerprint::ZERO),
1464 define_opaque: None,
1465 };
1466
1467 #[inline]
1468 pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1469 self.map.get(&id).copied().unwrap_or(&[])
1470 }
1471}
1472
1473pub struct OwnerNodes<'tcx> {
1477 pub opt_hash_including_bodies: Option<Fingerprint>,
1480 pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1485 pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1487}
1488
1489impl<'tcx> OwnerNodes<'tcx> {
1490 pub fn node(&self) -> OwnerNode<'tcx> {
1491 self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1493 }
1494}
1495
1496impl fmt::Debug for OwnerNodes<'_> {
1497 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1498 f.debug_struct("OwnerNodes")
1499 .field("node", &self.nodes[ItemLocalId::ZERO])
1501 .field(
1502 "parents",
1503 &fmt::from_fn(|f| {
1504 f.debug_list()
1505 .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1506 fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1507 }))
1508 .finish()
1509 }),
1510 )
1511 .field("bodies", &self.bodies)
1512 .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1513 .finish()
1514 }
1515}
1516
1517#[derive(Debug, HashStable_Generic)]
1519pub struct OwnerInfo<'hir> {
1520 pub nodes: OwnerNodes<'hir>,
1522 pub parenting: LocalDefIdMap<ItemLocalId>,
1524 pub attrs: AttributeMap<'hir>,
1526 pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1529}
1530
1531impl<'tcx> OwnerInfo<'tcx> {
1532 #[inline]
1533 pub fn node(&self) -> OwnerNode<'tcx> {
1534 self.nodes.node()
1535 }
1536}
1537
1538#[derive(Copy, Clone, Debug, HashStable_Generic)]
1539pub enum MaybeOwner<'tcx> {
1540 Owner(&'tcx OwnerInfo<'tcx>),
1541 NonOwner(HirId),
1542 Phantom,
1544}
1545
1546impl<'tcx> MaybeOwner<'tcx> {
1547 pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1548 match self {
1549 MaybeOwner::Owner(i) => Some(i),
1550 MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1551 }
1552 }
1553
1554 pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1555 self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1556 }
1557}
1558
1559#[derive(Debug)]
1566pub struct Crate<'hir> {
1567 pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1568 pub opt_hir_hash: Option<Fingerprint>,
1570}
1571
1572#[derive(Debug, Clone, Copy, HashStable_Generic)]
1573pub struct Closure<'hir> {
1574 pub def_id: LocalDefId,
1575 pub binder: ClosureBinder,
1576 pub constness: Constness,
1577 pub capture_clause: CaptureBy,
1578 pub bound_generic_params: &'hir [GenericParam<'hir>],
1579 pub fn_decl: &'hir FnDecl<'hir>,
1580 pub body: BodyId,
1581 pub fn_decl_span: Span,
1583 pub fn_arg_span: Option<Span>,
1585 pub kind: ClosureKind,
1586}
1587
1588#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1589pub enum ClosureKind {
1590 Closure,
1592 Coroutine(CoroutineKind),
1597 CoroutineClosure(CoroutineDesugaring),
1602}
1603
1604#[derive(Debug, Clone, Copy, HashStable_Generic)]
1608pub struct Block<'hir> {
1609 pub stmts: &'hir [Stmt<'hir>],
1611 pub expr: Option<&'hir Expr<'hir>>,
1614 #[stable_hasher(ignore)]
1615 pub hir_id: HirId,
1616 pub rules: BlockCheckMode,
1618 pub span: Span,
1620 pub targeted_by_break: bool,
1624}
1625
1626impl<'hir> Block<'hir> {
1627 pub fn innermost_block(&self) -> &Block<'hir> {
1628 let mut block = self;
1629 while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1630 block = inner_block;
1631 }
1632 block
1633 }
1634}
1635
1636#[derive(Debug, Clone, Copy, HashStable_Generic)]
1637pub struct TyPat<'hir> {
1638 #[stable_hasher(ignore)]
1639 pub hir_id: HirId,
1640 pub kind: TyPatKind<'hir>,
1641 pub span: Span,
1642}
1643
1644#[derive(Debug, Clone, Copy, HashStable_Generic)]
1645pub struct Pat<'hir> {
1646 #[stable_hasher(ignore)]
1647 pub hir_id: HirId,
1648 pub kind: PatKind<'hir>,
1649 pub span: Span,
1650 pub default_binding_modes: bool,
1653}
1654
1655impl<'hir> Pat<'hir> {
1656 fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1657 if !it(self) {
1658 return false;
1659 }
1660
1661 use PatKind::*;
1662 match self.kind {
1663 Missing => unreachable!(),
1664 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1665 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
1666 Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1667 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1668 Slice(before, slice, after) => {
1669 before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1670 }
1671 }
1672 }
1673
1674 pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1681 self.walk_short_(&mut it)
1682 }
1683
1684 fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1685 if !it(self) {
1686 return;
1687 }
1688
1689 use PatKind::*;
1690 match self.kind {
1691 Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1692 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1693 Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1694 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1695 Slice(before, slice, after) => {
1696 before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1697 }
1698 }
1699 }
1700
1701 pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1705 self.walk_(&mut it)
1706 }
1707
1708 pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1712 self.walk(|p| {
1713 it(p);
1714 true
1715 })
1716 }
1717
1718 pub fn is_never_pattern(&self) -> bool {
1720 let mut is_never_pattern = false;
1721 self.walk(|pat| match &pat.kind {
1722 PatKind::Never => {
1723 is_never_pattern = true;
1724 false
1725 }
1726 PatKind::Or(s) => {
1727 is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1728 false
1729 }
1730 _ => true,
1731 });
1732 is_never_pattern
1733 }
1734}
1735
1736#[derive(Debug, Clone, Copy, HashStable_Generic)]
1742pub struct PatField<'hir> {
1743 #[stable_hasher(ignore)]
1744 pub hir_id: HirId,
1745 pub ident: Ident,
1747 pub pat: &'hir Pat<'hir>,
1749 pub is_shorthand: bool,
1750 pub span: Span,
1751}
1752
1753#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
1754pub enum RangeEnd {
1755 Included,
1756 Excluded,
1757}
1758
1759impl fmt::Display for RangeEnd {
1760 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1761 f.write_str(match self {
1762 RangeEnd::Included => "..=",
1763 RangeEnd::Excluded => "..",
1764 })
1765 }
1766}
1767
1768#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1772pub struct DotDotPos(u32);
1773
1774impl DotDotPos {
1775 pub fn new(n: Option<usize>) -> Self {
1777 match n {
1778 Some(n) => {
1779 assert!(n < u32::MAX as usize);
1780 Self(n as u32)
1781 }
1782 None => Self(u32::MAX),
1783 }
1784 }
1785
1786 pub fn as_opt_usize(&self) -> Option<usize> {
1787 if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1788 }
1789}
1790
1791impl fmt::Debug for DotDotPos {
1792 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1793 self.as_opt_usize().fmt(f)
1794 }
1795}
1796
1797#[derive(Debug, Clone, Copy, HashStable_Generic)]
1798pub struct PatExpr<'hir> {
1799 #[stable_hasher(ignore)]
1800 pub hir_id: HirId,
1801 pub span: Span,
1802 pub kind: PatExprKind<'hir>,
1803}
1804
1805#[derive(Debug, Clone, Copy, HashStable_Generic)]
1806pub enum PatExprKind<'hir> {
1807 Lit {
1808 lit: &'hir Lit,
1809 negated: bool,
1812 },
1813 ConstBlock(ConstBlock),
1814 Path(QPath<'hir>),
1816}
1817
1818#[derive(Debug, Clone, Copy, HashStable_Generic)]
1819pub enum TyPatKind<'hir> {
1820 Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
1822
1823 Or(&'hir [TyPat<'hir>]),
1825
1826 Err(ErrorGuaranteed),
1828}
1829
1830#[derive(Debug, Clone, Copy, HashStable_Generic)]
1831pub enum PatKind<'hir> {
1832 Missing,
1834
1835 Wild,
1837
1838 Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1849
1850 Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
1853
1854 TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1858
1859 Or(&'hir [Pat<'hir>]),
1862
1863 Never,
1865
1866 Tuple(&'hir [Pat<'hir>], DotDotPos),
1870
1871 Box(&'hir Pat<'hir>),
1873
1874 Deref(&'hir Pat<'hir>),
1876
1877 Ref(&'hir Pat<'hir>, Mutability),
1879
1880 Expr(&'hir PatExpr<'hir>),
1882
1883 Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1885
1886 Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
1888
1889 Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
1899
1900 Err(ErrorGuaranteed),
1902}
1903
1904#[derive(Debug, Clone, Copy, HashStable_Generic)]
1906pub struct Stmt<'hir> {
1907 #[stable_hasher(ignore)]
1908 pub hir_id: HirId,
1909 pub kind: StmtKind<'hir>,
1910 pub span: Span,
1911}
1912
1913#[derive(Debug, Clone, Copy, HashStable_Generic)]
1915pub enum StmtKind<'hir> {
1916 Let(&'hir LetStmt<'hir>),
1918
1919 Item(ItemId),
1921
1922 Expr(&'hir Expr<'hir>),
1924
1925 Semi(&'hir Expr<'hir>),
1927}
1928
1929#[derive(Debug, Clone, Copy, HashStable_Generic)]
1931pub struct LetStmt<'hir> {
1932 pub super_: Option<Span>,
1934 pub pat: &'hir Pat<'hir>,
1935 pub ty: Option<&'hir Ty<'hir>>,
1937 pub init: Option<&'hir Expr<'hir>>,
1939 pub els: Option<&'hir Block<'hir>>,
1941 #[stable_hasher(ignore)]
1942 pub hir_id: HirId,
1943 pub span: Span,
1944 pub source: LocalSource,
1948}
1949
1950#[derive(Debug, Clone, Copy, HashStable_Generic)]
1953pub struct Arm<'hir> {
1954 #[stable_hasher(ignore)]
1955 pub hir_id: HirId,
1956 pub span: Span,
1957 pub pat: &'hir Pat<'hir>,
1959 pub guard: Option<&'hir Expr<'hir>>,
1961 pub body: &'hir Expr<'hir>,
1963}
1964
1965#[derive(Debug, Clone, Copy, HashStable_Generic)]
1971pub struct LetExpr<'hir> {
1972 pub span: Span,
1973 pub pat: &'hir Pat<'hir>,
1974 pub ty: Option<&'hir Ty<'hir>>,
1975 pub init: &'hir Expr<'hir>,
1976 pub recovered: ast::Recovered,
1979}
1980
1981#[derive(Debug, Clone, Copy, HashStable_Generic)]
1982pub struct ExprField<'hir> {
1983 #[stable_hasher(ignore)]
1984 pub hir_id: HirId,
1985 pub ident: Ident,
1986 pub expr: &'hir Expr<'hir>,
1987 pub span: Span,
1988 pub is_shorthand: bool,
1989}
1990
1991#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1992pub enum BlockCheckMode {
1993 DefaultBlock,
1994 UnsafeBlock(UnsafeSource),
1995}
1996
1997#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1998pub enum UnsafeSource {
1999 CompilerGenerated,
2000 UserProvided,
2001}
2002
2003#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
2004pub struct BodyId {
2005 pub hir_id: HirId,
2006}
2007
2008#[derive(Debug, Clone, Copy, HashStable_Generic)]
2030pub struct Body<'hir> {
2031 pub params: &'hir [Param<'hir>],
2032 pub value: &'hir Expr<'hir>,
2033}
2034
2035impl<'hir> Body<'hir> {
2036 pub fn id(&self) -> BodyId {
2037 BodyId { hir_id: self.value.hir_id }
2038 }
2039}
2040
2041#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2043pub enum CoroutineKind {
2044 Desugared(CoroutineDesugaring, CoroutineSource),
2046
2047 Coroutine(Movability),
2049}
2050
2051impl CoroutineKind {
2052 pub fn movability(self) -> Movability {
2053 match self {
2054 CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
2055 | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
2056 CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
2057 CoroutineKind::Coroutine(mov) => mov,
2058 }
2059 }
2060
2061 pub fn is_fn_like(self) -> bool {
2062 matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
2063 }
2064
2065 pub fn to_plural_string(&self) -> String {
2066 match self {
2067 CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"),
2068 CoroutineKind::Desugared(d, CoroutineSource::Block) => format!("{d:#}blocks"),
2069 CoroutineKind::Desugared(d, CoroutineSource::Closure) => format!("{d:#}closure bodies"),
2070 CoroutineKind::Coroutine(_) => "coroutines".to_string(),
2071 }
2072 }
2073}
2074
2075impl fmt::Display for CoroutineKind {
2076 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2077 match self {
2078 CoroutineKind::Desugared(d, k) => {
2079 d.fmt(f)?;
2080 k.fmt(f)
2081 }
2082 CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
2083 }
2084 }
2085}
2086
2087#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
2093pub enum CoroutineSource {
2094 Block,
2096
2097 Closure,
2099
2100 Fn,
2102}
2103
2104impl fmt::Display for CoroutineSource {
2105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2106 match self {
2107 CoroutineSource::Block => "block",
2108 CoroutineSource::Closure => "closure body",
2109 CoroutineSource::Fn => "fn body",
2110 }
2111 .fmt(f)
2112 }
2113}
2114
2115#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
2116pub enum CoroutineDesugaring {
2117 Async,
2119
2120 Gen,
2122
2123 AsyncGen,
2126}
2127
2128impl fmt::Display for CoroutineDesugaring {
2129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2130 match self {
2131 CoroutineDesugaring::Async => {
2132 if f.alternate() {
2133 f.write_str("`async` ")?;
2134 } else {
2135 f.write_str("async ")?
2136 }
2137 }
2138 CoroutineDesugaring::Gen => {
2139 if f.alternate() {
2140 f.write_str("`gen` ")?;
2141 } else {
2142 f.write_str("gen ")?
2143 }
2144 }
2145 CoroutineDesugaring::AsyncGen => {
2146 if f.alternate() {
2147 f.write_str("`async gen` ")?;
2148 } else {
2149 f.write_str("async gen ")?
2150 }
2151 }
2152 }
2153
2154 Ok(())
2155 }
2156}
2157
2158#[derive(Copy, Clone, Debug)]
2159pub enum BodyOwnerKind {
2160 Fn,
2162
2163 Closure,
2165
2166 Const { inline: bool },
2168
2169 Static(Mutability),
2171
2172 GlobalAsm,
2174}
2175
2176impl BodyOwnerKind {
2177 pub fn is_fn_or_closure(self) -> bool {
2178 match self {
2179 BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
2180 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
2181 false
2182 }
2183 }
2184 }
2185}
2186
2187#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2189pub enum ConstContext {
2190 ConstFn,
2192
2193 Static(Mutability),
2195
2196 Const { inline: bool },
2206}
2207
2208impl ConstContext {
2209 pub fn keyword_name(self) -> &'static str {
2213 match self {
2214 Self::Const { .. } => "const",
2215 Self::Static(Mutability::Not) => "static",
2216 Self::Static(Mutability::Mut) => "static mut",
2217 Self::ConstFn => "const fn",
2218 }
2219 }
2220}
2221
2222impl fmt::Display for ConstContext {
2225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2226 match *self {
2227 Self::Const { .. } => write!(f, "constant"),
2228 Self::Static(_) => write!(f, "static"),
2229 Self::ConstFn => write!(f, "constant function"),
2230 }
2231 }
2232}
2233
2234pub type Lit = Spanned<LitKind>;
2239
2240#[derive(Copy, Clone, Debug, HashStable_Generic)]
2249pub struct AnonConst {
2250 #[stable_hasher(ignore)]
2251 pub hir_id: HirId,
2252 pub def_id: LocalDefId,
2253 pub body: BodyId,
2254 pub span: Span,
2255}
2256
2257#[derive(Copy, Clone, Debug, HashStable_Generic)]
2259pub struct ConstBlock {
2260 #[stable_hasher(ignore)]
2261 pub hir_id: HirId,
2262 pub def_id: LocalDefId,
2263 pub body: BodyId,
2264}
2265
2266#[derive(Debug, Clone, Copy, HashStable_Generic)]
2275pub struct Expr<'hir> {
2276 #[stable_hasher(ignore)]
2277 pub hir_id: HirId,
2278 pub kind: ExprKind<'hir>,
2279 pub span: Span,
2280}
2281
2282impl Expr<'_> {
2283 pub fn precedence(&self) -> ExprPrecedence {
2284 match &self.kind {
2285 ExprKind::Closure(closure) => {
2286 match closure.fn_decl.output {
2287 FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2288 FnRetTy::Return(_) => ExprPrecedence::Unambiguous,
2289 }
2290 }
2291
2292 ExprKind::Break(..)
2293 | ExprKind::Ret(..)
2294 | ExprKind::Yield(..)
2295 | ExprKind::Become(..) => ExprPrecedence::Jump,
2296
2297 ExprKind::Binary(op, ..) => op.node.precedence(),
2299 ExprKind::Cast(..) => ExprPrecedence::Cast,
2300
2301 ExprKind::Assign(..) |
2302 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2303
2304 ExprKind::AddrOf(..)
2306 | ExprKind::Let(..)
2311 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2312
2313 ExprKind::Array(_)
2315 | ExprKind::Block(..)
2316 | ExprKind::Call(..)
2317 | ExprKind::ConstBlock(_)
2318 | ExprKind::Continue(..)
2319 | ExprKind::Field(..)
2320 | ExprKind::If(..)
2321 | ExprKind::Index(..)
2322 | ExprKind::InlineAsm(..)
2323 | ExprKind::Lit(_)
2324 | ExprKind::Loop(..)
2325 | ExprKind::Match(..)
2326 | ExprKind::MethodCall(..)
2327 | ExprKind::OffsetOf(..)
2328 | ExprKind::Path(..)
2329 | ExprKind::Repeat(..)
2330 | ExprKind::Struct(..)
2331 | ExprKind::Tup(_)
2332 | ExprKind::Type(..)
2333 | ExprKind::UnsafeBinderCast(..)
2334 | ExprKind::Use(..)
2335 | ExprKind::Err(_) => ExprPrecedence::Unambiguous,
2336
2337 ExprKind::DropTemps(expr, ..) => expr.precedence(),
2338 }
2339 }
2340
2341 pub fn is_syntactic_place_expr(&self) -> bool {
2346 self.is_place_expr(|_| true)
2347 }
2348
2349 pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2354 match self.kind {
2355 ExprKind::Path(QPath::Resolved(_, ref path)) => {
2356 matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2357 }
2358
2359 ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2363
2364 ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2366
2367 ExprKind::Unary(UnOp::Deref, _) => true,
2368
2369 ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2370 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2371 }
2372
2373 ExprKind::Path(QPath::LangItem(..)) => false,
2375
2376 ExprKind::Err(_guar)
2378 | ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
2379
2380 ExprKind::Path(QPath::TypeRelative(..))
2383 | ExprKind::Call(..)
2384 | ExprKind::MethodCall(..)
2385 | ExprKind::Use(..)
2386 | ExprKind::Struct(..)
2387 | ExprKind::Tup(..)
2388 | ExprKind::If(..)
2389 | ExprKind::Match(..)
2390 | ExprKind::Closure { .. }
2391 | ExprKind::Block(..)
2392 | ExprKind::Repeat(..)
2393 | ExprKind::Array(..)
2394 | ExprKind::Break(..)
2395 | ExprKind::Continue(..)
2396 | ExprKind::Ret(..)
2397 | ExprKind::Become(..)
2398 | ExprKind::Let(..)
2399 | ExprKind::Loop(..)
2400 | ExprKind::Assign(..)
2401 | ExprKind::InlineAsm(..)
2402 | ExprKind::OffsetOf(..)
2403 | ExprKind::AssignOp(..)
2404 | ExprKind::Lit(_)
2405 | ExprKind::ConstBlock(..)
2406 | ExprKind::Unary(..)
2407 | ExprKind::AddrOf(..)
2408 | ExprKind::Binary(..)
2409 | ExprKind::Yield(..)
2410 | ExprKind::Cast(..)
2411 | ExprKind::DropTemps(..) => false,
2412 }
2413 }
2414
2415 pub fn is_size_lit(&self) -> bool {
2418 matches!(
2419 self.kind,
2420 ExprKind::Lit(Lit {
2421 node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2422 ..
2423 })
2424 )
2425 }
2426
2427 pub fn peel_drop_temps(&self) -> &Self {
2433 let mut expr = self;
2434 while let ExprKind::DropTemps(inner) = &expr.kind {
2435 expr = inner;
2436 }
2437 expr
2438 }
2439
2440 pub fn peel_blocks(&self) -> &Self {
2441 let mut expr = self;
2442 while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2443 expr = inner;
2444 }
2445 expr
2446 }
2447
2448 pub fn peel_borrows(&self) -> &Self {
2449 let mut expr = self;
2450 while let ExprKind::AddrOf(.., inner) = &expr.kind {
2451 expr = inner;
2452 }
2453 expr
2454 }
2455
2456 pub fn can_have_side_effects(&self) -> bool {
2457 match self.peel_drop_temps().kind {
2458 ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2459 false
2460 }
2461 ExprKind::Type(base, _)
2462 | ExprKind::Unary(_, base)
2463 | ExprKind::Field(base, _)
2464 | ExprKind::Index(base, _, _)
2465 | ExprKind::AddrOf(.., base)
2466 | ExprKind::Cast(base, _)
2467 | ExprKind::UnsafeBinderCast(_, base, _) => {
2468 base.can_have_side_effects()
2472 }
2473 ExprKind::Struct(_, fields, init) => {
2474 let init_side_effects = match init {
2475 StructTailExpr::Base(init) => init.can_have_side_effects(),
2476 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2477 };
2478 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2479 || init_side_effects
2480 }
2481
2482 ExprKind::Array(args)
2483 | ExprKind::Tup(args)
2484 | ExprKind::Call(
2485 Expr {
2486 kind:
2487 ExprKind::Path(QPath::Resolved(
2488 None,
2489 Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2490 )),
2491 ..
2492 },
2493 args,
2494 ) => args.iter().any(|arg| arg.can_have_side_effects()),
2495 ExprKind::If(..)
2496 | ExprKind::Match(..)
2497 | ExprKind::MethodCall(..)
2498 | ExprKind::Call(..)
2499 | ExprKind::Closure { .. }
2500 | ExprKind::Block(..)
2501 | ExprKind::Repeat(..)
2502 | ExprKind::Break(..)
2503 | ExprKind::Continue(..)
2504 | ExprKind::Ret(..)
2505 | ExprKind::Become(..)
2506 | ExprKind::Let(..)
2507 | ExprKind::Loop(..)
2508 | ExprKind::Assign(..)
2509 | ExprKind::InlineAsm(..)
2510 | ExprKind::AssignOp(..)
2511 | ExprKind::ConstBlock(..)
2512 | ExprKind::Binary(..)
2513 | ExprKind::Yield(..)
2514 | ExprKind::DropTemps(..)
2515 | ExprKind::Err(_) => true,
2516 }
2517 }
2518
2519 pub fn is_approximately_pattern(&self) -> bool {
2521 match &self.kind {
2522 ExprKind::Array(_)
2523 | ExprKind::Call(..)
2524 | ExprKind::Tup(_)
2525 | ExprKind::Lit(_)
2526 | ExprKind::Path(_)
2527 | ExprKind::Struct(..) => true,
2528 _ => false,
2529 }
2530 }
2531
2532 pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2537 match (self.kind, other.kind) {
2538 (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2539 (
2540 ExprKind::Path(QPath::LangItem(item1, _)),
2541 ExprKind::Path(QPath::LangItem(item2, _)),
2542 ) => item1 == item2,
2543 (
2544 ExprKind::Path(QPath::Resolved(None, path1)),
2545 ExprKind::Path(QPath::Resolved(None, path2)),
2546 ) => path1.res == path2.res,
2547 (
2548 ExprKind::Struct(
2549 QPath::LangItem(LangItem::RangeTo, _),
2550 [val1],
2551 StructTailExpr::None,
2552 ),
2553 ExprKind::Struct(
2554 QPath::LangItem(LangItem::RangeTo, _),
2555 [val2],
2556 StructTailExpr::None,
2557 ),
2558 )
2559 | (
2560 ExprKind::Struct(
2561 QPath::LangItem(LangItem::RangeToInclusive, _),
2562 [val1],
2563 StructTailExpr::None,
2564 ),
2565 ExprKind::Struct(
2566 QPath::LangItem(LangItem::RangeToInclusive, _),
2567 [val2],
2568 StructTailExpr::None,
2569 ),
2570 )
2571 | (
2572 ExprKind::Struct(
2573 QPath::LangItem(LangItem::RangeFrom, _),
2574 [val1],
2575 StructTailExpr::None,
2576 ),
2577 ExprKind::Struct(
2578 QPath::LangItem(LangItem::RangeFrom, _),
2579 [val2],
2580 StructTailExpr::None,
2581 ),
2582 )
2583 | (
2584 ExprKind::Struct(
2585 QPath::LangItem(LangItem::RangeFromCopy, _),
2586 [val1],
2587 StructTailExpr::None,
2588 ),
2589 ExprKind::Struct(
2590 QPath::LangItem(LangItem::RangeFromCopy, _),
2591 [val2],
2592 StructTailExpr::None,
2593 ),
2594 ) => val1.expr.equivalent_for_indexing(val2.expr),
2595 (
2596 ExprKind::Struct(
2597 QPath::LangItem(LangItem::Range, _),
2598 [val1, val3],
2599 StructTailExpr::None,
2600 ),
2601 ExprKind::Struct(
2602 QPath::LangItem(LangItem::Range, _),
2603 [val2, val4],
2604 StructTailExpr::None,
2605 ),
2606 )
2607 | (
2608 ExprKind::Struct(
2609 QPath::LangItem(LangItem::RangeCopy, _),
2610 [val1, val3],
2611 StructTailExpr::None,
2612 ),
2613 ExprKind::Struct(
2614 QPath::LangItem(LangItem::RangeCopy, _),
2615 [val2, val4],
2616 StructTailExpr::None,
2617 ),
2618 )
2619 | (
2620 ExprKind::Struct(
2621 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2622 [val1, val3],
2623 StructTailExpr::None,
2624 ),
2625 ExprKind::Struct(
2626 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2627 [val2, val4],
2628 StructTailExpr::None,
2629 ),
2630 ) => {
2631 val1.expr.equivalent_for_indexing(val2.expr)
2632 && val3.expr.equivalent_for_indexing(val4.expr)
2633 }
2634 _ => false,
2635 }
2636 }
2637
2638 pub fn method_ident(&self) -> Option<Ident> {
2639 match self.kind {
2640 ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2641 ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2642 _ => None,
2643 }
2644 }
2645}
2646
2647pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2650 match expr.kind {
2651 ExprKind::Struct(ref qpath, _, _) => matches!(
2653 **qpath,
2654 QPath::LangItem(
2655 LangItem::Range
2656 | LangItem::RangeTo
2657 | LangItem::RangeFrom
2658 | LangItem::RangeFull
2659 | LangItem::RangeToInclusive
2660 | LangItem::RangeCopy
2661 | LangItem::RangeFromCopy
2662 | LangItem::RangeInclusiveCopy,
2663 ..
2664 )
2665 ),
2666
2667 ExprKind::Call(ref func, _) => {
2669 matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2670 }
2671
2672 _ => false,
2673 }
2674}
2675
2676pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2683 match expr.kind {
2684 ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2686 _ if is_range_literal(expr) => true,
2688 _ => false,
2689 }
2690}
2691
2692#[derive(Debug, Clone, Copy, HashStable_Generic)]
2693pub enum ExprKind<'hir> {
2694 ConstBlock(ConstBlock),
2696 Array(&'hir [Expr<'hir>]),
2698 Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2705 MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2722 Use(&'hir Expr<'hir>, Span),
2724 Tup(&'hir [Expr<'hir>]),
2726 Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2728 Unary(UnOp, &'hir Expr<'hir>),
2730 Lit(&'hir Lit),
2732 Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2734 Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2736 DropTemps(&'hir Expr<'hir>),
2742 Let(&'hir LetExpr<'hir>),
2747 If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2756 Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2762 Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2765 Closure(&'hir Closure<'hir>),
2772 Block(&'hir Block<'hir>, Option<Label>),
2774
2775 Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2777 AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2781 Field(&'hir Expr<'hir>, Ident),
2783 Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2787
2788 Path(QPath<'hir>),
2790
2791 AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2793 Break(Destination, Option<&'hir Expr<'hir>>),
2795 Continue(Destination),
2797 Ret(Option<&'hir Expr<'hir>>),
2799 Become(&'hir Expr<'hir>),
2801
2802 InlineAsm(&'hir InlineAsm<'hir>),
2804
2805 OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2807
2808 Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2813
2814 Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2819
2820 Yield(&'hir Expr<'hir>, YieldSource),
2822
2823 UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2826
2827 Err(rustc_span::ErrorGuaranteed),
2829}
2830
2831#[derive(Debug, Clone, Copy, HashStable_Generic)]
2832pub enum StructTailExpr<'hir> {
2833 None,
2835 Base(&'hir Expr<'hir>),
2838 DefaultFields(Span),
2842}
2843
2844#[derive(Debug, Clone, Copy, HashStable_Generic)]
2850pub enum QPath<'hir> {
2851 Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2858
2859 TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2866
2867 LangItem(LangItem, Span),
2869}
2870
2871impl<'hir> QPath<'hir> {
2872 pub fn span(&self) -> Span {
2874 match *self {
2875 QPath::Resolved(_, path) => path.span,
2876 QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2877 QPath::LangItem(_, span) => span,
2878 }
2879 }
2880
2881 pub fn qself_span(&self) -> Span {
2884 match *self {
2885 QPath::Resolved(_, path) => path.span,
2886 QPath::TypeRelative(qself, _) => qself.span,
2887 QPath::LangItem(_, span) => span,
2888 }
2889 }
2890}
2891
2892#[derive(Copy, Clone, Debug, HashStable_Generic)]
2894pub enum LocalSource {
2895 Normal,
2897 AsyncFn,
2908 AwaitDesugar,
2910 AssignDesugar(Span),
2913 Contract,
2915}
2916
2917#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2919pub enum MatchSource {
2920 Normal,
2922 Postfix,
2924 ForLoopDesugar,
2926 TryDesugar(HirId),
2928 AwaitDesugar,
2930 FormatArgs,
2932}
2933
2934impl MatchSource {
2935 #[inline]
2936 pub const fn name(self) -> &'static str {
2937 use MatchSource::*;
2938 match self {
2939 Normal => "match",
2940 Postfix => ".match",
2941 ForLoopDesugar => "for",
2942 TryDesugar(_) => "?",
2943 AwaitDesugar => ".await",
2944 FormatArgs => "format_args!()",
2945 }
2946 }
2947}
2948
2949#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2951pub enum LoopSource {
2952 Loop,
2954 While,
2956 ForLoop,
2958}
2959
2960impl LoopSource {
2961 pub fn name(self) -> &'static str {
2962 match self {
2963 LoopSource::Loop => "loop",
2964 LoopSource::While => "while",
2965 LoopSource::ForLoop => "for",
2966 }
2967 }
2968}
2969
2970#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
2971pub enum LoopIdError {
2972 OutsideLoopScope,
2973 UnlabeledCfInWhileCondition,
2974 UnresolvedLabel,
2975}
2976
2977impl fmt::Display for LoopIdError {
2978 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2979 f.write_str(match self {
2980 LoopIdError::OutsideLoopScope => "not inside loop scope",
2981 LoopIdError::UnlabeledCfInWhileCondition => {
2982 "unlabeled control flow (break or continue) in while condition"
2983 }
2984 LoopIdError::UnresolvedLabel => "label not found",
2985 })
2986 }
2987}
2988
2989#[derive(Copy, Clone, Debug, HashStable_Generic)]
2990pub struct Destination {
2991 pub label: Option<Label>,
2993
2994 pub target_id: Result<HirId, LoopIdError>,
2997}
2998
2999#[derive(Copy, Clone, Debug, HashStable_Generic)]
3001pub enum YieldSource {
3002 Await { expr: Option<HirId> },
3004 Yield,
3006}
3007
3008impl fmt::Display for YieldSource {
3009 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3010 f.write_str(match self {
3011 YieldSource::Await { .. } => "`await`",
3012 YieldSource::Yield => "`yield`",
3013 })
3014 }
3015}
3016
3017#[derive(Debug, Clone, Copy, HashStable_Generic)]
3020pub struct MutTy<'hir> {
3021 pub ty: &'hir Ty<'hir>,
3022 pub mutbl: Mutability,
3023}
3024
3025#[derive(Debug, Clone, Copy, HashStable_Generic)]
3028pub struct FnSig<'hir> {
3029 pub header: FnHeader,
3030 pub decl: &'hir FnDecl<'hir>,
3031 pub span: Span,
3032}
3033
3034#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3038pub struct TraitItemId {
3039 pub owner_id: OwnerId,
3040}
3041
3042impl TraitItemId {
3043 #[inline]
3044 pub fn hir_id(&self) -> HirId {
3045 HirId::make_owner(self.owner_id.def_id)
3047 }
3048}
3049
3050#[derive(Debug, Clone, Copy, HashStable_Generic)]
3055pub struct TraitItem<'hir> {
3056 pub ident: Ident,
3057 pub owner_id: OwnerId,
3058 pub generics: &'hir Generics<'hir>,
3059 pub kind: TraitItemKind<'hir>,
3060 pub span: Span,
3061 pub defaultness: Defaultness,
3062}
3063
3064macro_rules! expect_methods_self_kind {
3065 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3066 $(
3067 #[track_caller]
3068 pub fn $name(&self) -> $ret_ty {
3069 let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
3070 $ret_val
3071 }
3072 )*
3073 }
3074}
3075
3076macro_rules! expect_methods_self {
3077 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
3078 $(
3079 #[track_caller]
3080 pub fn $name(&self) -> $ret_ty {
3081 let $pat = self else { expect_failed(stringify!($ident), self) };
3082 $ret_val
3083 }
3084 )*
3085 }
3086}
3087
3088#[track_caller]
3089fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
3090 panic!("{ident}: found {found:?}")
3091}
3092
3093impl<'hir> TraitItem<'hir> {
3094 #[inline]
3095 pub fn hir_id(&self) -> HirId {
3096 HirId::make_owner(self.owner_id.def_id)
3098 }
3099
3100 pub fn trait_item_id(&self) -> TraitItemId {
3101 TraitItemId { owner_id: self.owner_id }
3102 }
3103
3104 expect_methods_self_kind! {
3105 expect_const, (&'hir Ty<'hir>, Option<BodyId>),
3106 TraitItemKind::Const(ty, body), (ty, *body);
3107
3108 expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
3109 TraitItemKind::Fn(ty, trfn), (ty, trfn);
3110
3111 expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3112 TraitItemKind::Type(bounds, ty), (bounds, *ty);
3113 }
3114}
3115
3116#[derive(Debug, Clone, Copy, HashStable_Generic)]
3118pub enum TraitFn<'hir> {
3119 Required(&'hir [Option<Ident>]),
3121
3122 Provided(BodyId),
3124}
3125
3126#[derive(Debug, Clone, Copy, HashStable_Generic)]
3128pub enum TraitItemKind<'hir> {
3129 Const(&'hir Ty<'hir>, Option<BodyId>),
3131 Fn(FnSig<'hir>, TraitFn<'hir>),
3133 Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3136}
3137
3138#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3142pub struct ImplItemId {
3143 pub owner_id: OwnerId,
3144}
3145
3146impl ImplItemId {
3147 #[inline]
3148 pub fn hir_id(&self) -> HirId {
3149 HirId::make_owner(self.owner_id.def_id)
3151 }
3152}
3153
3154#[derive(Debug, Clone, Copy, HashStable_Generic)]
3158pub struct ImplItem<'hir> {
3159 pub ident: Ident,
3160 pub owner_id: OwnerId,
3161 pub generics: &'hir Generics<'hir>,
3162 pub kind: ImplItemKind<'hir>,
3163 pub defaultness: Defaultness,
3164 pub span: Span,
3165 pub vis_span: Span,
3166}
3167
3168impl<'hir> ImplItem<'hir> {
3169 #[inline]
3170 pub fn hir_id(&self) -> HirId {
3171 HirId::make_owner(self.owner_id.def_id)
3173 }
3174
3175 pub fn impl_item_id(&self) -> ImplItemId {
3176 ImplItemId { owner_id: self.owner_id }
3177 }
3178
3179 expect_methods_self_kind! {
3180 expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
3181 expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3182 expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3183 }
3184}
3185
3186#[derive(Debug, Clone, Copy, HashStable_Generic)]
3188pub enum ImplItemKind<'hir> {
3189 Const(&'hir Ty<'hir>, BodyId),
3192 Fn(FnSig<'hir>, BodyId),
3194 Type(&'hir Ty<'hir>),
3196}
3197
3198#[derive(Debug, Clone, Copy, HashStable_Generic)]
3209pub struct AssocItemConstraint<'hir> {
3210 #[stable_hasher(ignore)]
3211 pub hir_id: HirId,
3212 pub ident: Ident,
3213 pub gen_args: &'hir GenericArgs<'hir>,
3214 pub kind: AssocItemConstraintKind<'hir>,
3215 pub span: Span,
3216}
3217
3218impl<'hir> AssocItemConstraint<'hir> {
3219 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
3221 match self.kind {
3222 AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
3223 _ => None,
3224 }
3225 }
3226
3227 pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
3229 match self.kind {
3230 AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
3231 _ => None,
3232 }
3233 }
3234}
3235
3236#[derive(Debug, Clone, Copy, HashStable_Generic)]
3237pub enum Term<'hir> {
3238 Ty(&'hir Ty<'hir>),
3239 Const(&'hir ConstArg<'hir>),
3240}
3241
3242impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
3243 fn from(ty: &'hir Ty<'hir>) -> Self {
3244 Term::Ty(ty)
3245 }
3246}
3247
3248impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
3249 fn from(c: &'hir ConstArg<'hir>) -> Self {
3250 Term::Const(c)
3251 }
3252}
3253
3254#[derive(Debug, Clone, Copy, HashStable_Generic)]
3256pub enum AssocItemConstraintKind<'hir> {
3257 Equality { term: Term<'hir> },
3264 Bound { bounds: &'hir [GenericBound<'hir>] },
3266}
3267
3268impl<'hir> AssocItemConstraintKind<'hir> {
3269 pub fn descr(&self) -> &'static str {
3270 match self {
3271 AssocItemConstraintKind::Equality { .. } => "binding",
3272 AssocItemConstraintKind::Bound { .. } => "constraint",
3273 }
3274 }
3275}
3276
3277#[derive(Debug, Clone, Copy, HashStable_Generic)]
3281pub enum AmbigArg {}
3282
3283#[derive(Debug, Clone, Copy, HashStable_Generic)]
3284#[repr(C)]
3285pub struct Ty<'hir, Unambig = ()> {
3292 #[stable_hasher(ignore)]
3293 pub hir_id: HirId,
3294 pub span: Span,
3295 pub kind: TyKind<'hir, Unambig>,
3296}
3297
3298impl<'hir> Ty<'hir, AmbigArg> {
3299 pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3310 let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3313 unsafe { &*ptr }
3314 }
3315}
3316
3317impl<'hir> Ty<'hir> {
3318 pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3324 if let TyKind::Infer(()) = self.kind {
3325 return None;
3326 }
3327
3328 let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3332 Some(unsafe { &*ptr })
3333 }
3334}
3335
3336impl<'hir> Ty<'hir, AmbigArg> {
3337 pub fn peel_refs(&self) -> &Ty<'hir> {
3338 let mut final_ty = self.as_unambig_ty();
3339 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3340 final_ty = ty;
3341 }
3342 final_ty
3343 }
3344}
3345
3346impl<'hir> Ty<'hir> {
3347 pub fn peel_refs(&self) -> &Self {
3348 let mut final_ty = self;
3349 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3350 final_ty = ty;
3351 }
3352 final_ty
3353 }
3354
3355 pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3357 let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3358 return None;
3359 };
3360 let [segment] = &path.segments else {
3361 return None;
3362 };
3363 match path.res {
3364 Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3365 Some((def_id, segment.ident))
3366 }
3367 _ => None,
3368 }
3369 }
3370
3371 pub fn find_self_aliases(&self) -> Vec<Span> {
3372 use crate::intravisit::Visitor;
3373 struct MyVisitor(Vec<Span>);
3374 impl<'v> Visitor<'v> for MyVisitor {
3375 fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3376 if matches!(
3377 &t.kind,
3378 TyKind::Path(QPath::Resolved(
3379 _,
3380 Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3381 ))
3382 ) {
3383 self.0.push(t.span);
3384 return;
3385 }
3386 crate::intravisit::walk_ty(self, t);
3387 }
3388 }
3389
3390 let mut my_visitor = MyVisitor(vec![]);
3391 my_visitor.visit_ty_unambig(self);
3392 my_visitor.0
3393 }
3394
3395 pub fn is_suggestable_infer_ty(&self) -> bool {
3398 fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3399 generic_args.iter().any(|arg| match arg {
3400 GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3401 GenericArg::Infer(_) => true,
3402 _ => false,
3403 })
3404 }
3405 debug!(?self);
3406 match &self.kind {
3407 TyKind::Infer(()) => true,
3408 TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3409 TyKind::Array(ty, length) => {
3410 ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3411 }
3412 TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3413 TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3414 TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3415 ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3416 }
3417 TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3418 ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3419 || segments
3420 .iter()
3421 .any(|segment| are_suggestable_generic_args(segment.args().args))
3422 }
3423 _ => false,
3424 }
3425 }
3426}
3427
3428#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3430pub enum PrimTy {
3431 Int(IntTy),
3432 Uint(UintTy),
3433 Float(FloatTy),
3434 Str,
3435 Bool,
3436 Char,
3437}
3438
3439impl PrimTy {
3440 pub const ALL: [Self; 19] = [
3442 Self::Int(IntTy::I8),
3444 Self::Int(IntTy::I16),
3445 Self::Int(IntTy::I32),
3446 Self::Int(IntTy::I64),
3447 Self::Int(IntTy::I128),
3448 Self::Int(IntTy::Isize),
3449 Self::Uint(UintTy::U8),
3450 Self::Uint(UintTy::U16),
3451 Self::Uint(UintTy::U32),
3452 Self::Uint(UintTy::U64),
3453 Self::Uint(UintTy::U128),
3454 Self::Uint(UintTy::Usize),
3455 Self::Float(FloatTy::F16),
3456 Self::Float(FloatTy::F32),
3457 Self::Float(FloatTy::F64),
3458 Self::Float(FloatTy::F128),
3459 Self::Bool,
3460 Self::Char,
3461 Self::Str,
3462 ];
3463
3464 pub fn name_str(self) -> &'static str {
3468 match self {
3469 PrimTy::Int(i) => i.name_str(),
3470 PrimTy::Uint(u) => u.name_str(),
3471 PrimTy::Float(f) => f.name_str(),
3472 PrimTy::Str => "str",
3473 PrimTy::Bool => "bool",
3474 PrimTy::Char => "char",
3475 }
3476 }
3477
3478 pub fn name(self) -> Symbol {
3479 match self {
3480 PrimTy::Int(i) => i.name(),
3481 PrimTy::Uint(u) => u.name(),
3482 PrimTy::Float(f) => f.name(),
3483 PrimTy::Str => sym::str,
3484 PrimTy::Bool => sym::bool,
3485 PrimTy::Char => sym::char,
3486 }
3487 }
3488
3489 pub fn from_name(name: Symbol) -> Option<Self> {
3492 let ty = match name {
3493 sym::i8 => Self::Int(IntTy::I8),
3495 sym::i16 => Self::Int(IntTy::I16),
3496 sym::i32 => Self::Int(IntTy::I32),
3497 sym::i64 => Self::Int(IntTy::I64),
3498 sym::i128 => Self::Int(IntTy::I128),
3499 sym::isize => Self::Int(IntTy::Isize),
3500 sym::u8 => Self::Uint(UintTy::U8),
3501 sym::u16 => Self::Uint(UintTy::U16),
3502 sym::u32 => Self::Uint(UintTy::U32),
3503 sym::u64 => Self::Uint(UintTy::U64),
3504 sym::u128 => Self::Uint(UintTy::U128),
3505 sym::usize => Self::Uint(UintTy::Usize),
3506 sym::f16 => Self::Float(FloatTy::F16),
3507 sym::f32 => Self::Float(FloatTy::F32),
3508 sym::f64 => Self::Float(FloatTy::F64),
3509 sym::f128 => Self::Float(FloatTy::F128),
3510 sym::bool => Self::Bool,
3511 sym::char => Self::Char,
3512 sym::str => Self::Str,
3513 _ => return None,
3514 };
3515 Some(ty)
3516 }
3517}
3518
3519#[derive(Debug, Clone, Copy, HashStable_Generic)]
3520pub struct BareFnTy<'hir> {
3521 pub safety: Safety,
3522 pub abi: ExternAbi,
3523 pub generic_params: &'hir [GenericParam<'hir>],
3524 pub decl: &'hir FnDecl<'hir>,
3525 pub param_idents: &'hir [Option<Ident>],
3528}
3529
3530#[derive(Debug, Clone, Copy, HashStable_Generic)]
3531pub struct UnsafeBinderTy<'hir> {
3532 pub generic_params: &'hir [GenericParam<'hir>],
3533 pub inner_ty: &'hir Ty<'hir>,
3534}
3535
3536#[derive(Debug, Clone, Copy, HashStable_Generic)]
3537pub struct OpaqueTy<'hir> {
3538 #[stable_hasher(ignore)]
3539 pub hir_id: HirId,
3540 pub def_id: LocalDefId,
3541 pub bounds: GenericBounds<'hir>,
3542 pub origin: OpaqueTyOrigin<LocalDefId>,
3543 pub span: Span,
3544}
3545
3546#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
3547pub enum PreciseCapturingArgKind<T, U> {
3548 Lifetime(T),
3549 Param(U),
3551}
3552
3553pub type PreciseCapturingArg<'hir> =
3554 PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
3555
3556impl PreciseCapturingArg<'_> {
3557 pub fn hir_id(self) -> HirId {
3558 match self {
3559 PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3560 PreciseCapturingArg::Param(param) => param.hir_id,
3561 }
3562 }
3563
3564 pub fn name(self) -> Symbol {
3565 match self {
3566 PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3567 PreciseCapturingArg::Param(param) => param.ident.name,
3568 }
3569 }
3570}
3571
3572#[derive(Debug, Clone, Copy, HashStable_Generic)]
3577pub struct PreciseCapturingNonLifetimeArg {
3578 #[stable_hasher(ignore)]
3579 pub hir_id: HirId,
3580 pub ident: Ident,
3581 pub res: Res,
3582}
3583
3584#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3585#[derive(HashStable_Generic, Encodable, Decodable)]
3586pub enum RpitContext {
3587 Trait,
3588 TraitImpl,
3589}
3590
3591#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3593#[derive(HashStable_Generic, Encodable, Decodable)]
3594pub enum OpaqueTyOrigin<D> {
3595 FnReturn {
3597 parent: D,
3599 in_trait_or_impl: Option<RpitContext>,
3601 },
3602 AsyncFn {
3604 parent: D,
3606 in_trait_or_impl: Option<RpitContext>,
3608 },
3609 TyAlias {
3611 parent: D,
3613 in_assoc_ty: bool,
3615 },
3616}
3617
3618#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3619pub enum InferDelegationKind {
3620 Input(usize),
3621 Output,
3622}
3623
3624#[derive(Debug, Clone, Copy, HashStable_Generic)]
3626#[repr(u8, C)]
3628pub enum TyKind<'hir, Unambig = ()> {
3629 InferDelegation(DefId, InferDelegationKind),
3631 Slice(&'hir Ty<'hir>),
3633 Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3635 Ptr(MutTy<'hir>),
3637 Ref(&'hir Lifetime, MutTy<'hir>),
3639 BareFn(&'hir BareFnTy<'hir>),
3641 UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3643 Never,
3645 Tup(&'hir [Ty<'hir>]),
3647 Path(QPath<'hir>),
3652 OpaqueDef(&'hir OpaqueTy<'hir>),
3654 TraitAscription(GenericBounds<'hir>),
3656 TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3662 Typeof(&'hir AnonConst),
3664 Err(rustc_span::ErrorGuaranteed),
3666 Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3668 Infer(Unambig),
3674}
3675
3676#[derive(Debug, Clone, Copy, HashStable_Generic)]
3677pub enum InlineAsmOperand<'hir> {
3678 In {
3679 reg: InlineAsmRegOrRegClass,
3680 expr: &'hir Expr<'hir>,
3681 },
3682 Out {
3683 reg: InlineAsmRegOrRegClass,
3684 late: bool,
3685 expr: Option<&'hir Expr<'hir>>,
3686 },
3687 InOut {
3688 reg: InlineAsmRegOrRegClass,
3689 late: bool,
3690 expr: &'hir Expr<'hir>,
3691 },
3692 SplitInOut {
3693 reg: InlineAsmRegOrRegClass,
3694 late: bool,
3695 in_expr: &'hir Expr<'hir>,
3696 out_expr: Option<&'hir Expr<'hir>>,
3697 },
3698 Const {
3699 anon_const: ConstBlock,
3700 },
3701 SymFn {
3702 expr: &'hir Expr<'hir>,
3703 },
3704 SymStatic {
3705 path: QPath<'hir>,
3706 def_id: DefId,
3707 },
3708 Label {
3709 block: &'hir Block<'hir>,
3710 },
3711}
3712
3713impl<'hir> InlineAsmOperand<'hir> {
3714 pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3715 match *self {
3716 Self::In { reg, .. }
3717 | Self::Out { reg, .. }
3718 | Self::InOut { reg, .. }
3719 | Self::SplitInOut { reg, .. } => Some(reg),
3720 Self::Const { .. }
3721 | Self::SymFn { .. }
3722 | Self::SymStatic { .. }
3723 | Self::Label { .. } => None,
3724 }
3725 }
3726
3727 pub fn is_clobber(&self) -> bool {
3728 matches!(
3729 self,
3730 InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3731 )
3732 }
3733}
3734
3735#[derive(Debug, Clone, Copy, HashStable_Generic)]
3736pub struct InlineAsm<'hir> {
3737 pub asm_macro: ast::AsmMacro,
3738 pub template: &'hir [InlineAsmTemplatePiece],
3739 pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3740 pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3741 pub options: InlineAsmOptions,
3742 pub line_spans: &'hir [Span],
3743}
3744
3745impl InlineAsm<'_> {
3746 pub fn contains_label(&self) -> bool {
3747 self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3748 }
3749}
3750
3751#[derive(Debug, Clone, Copy, HashStable_Generic)]
3753pub struct Param<'hir> {
3754 #[stable_hasher(ignore)]
3755 pub hir_id: HirId,
3756 pub pat: &'hir Pat<'hir>,
3757 pub ty_span: Span,
3758 pub span: Span,
3759}
3760
3761#[derive(Debug, Clone, Copy, HashStable_Generic)]
3763pub struct FnDecl<'hir> {
3764 pub inputs: &'hir [Ty<'hir>],
3768 pub output: FnRetTy<'hir>,
3769 pub c_variadic: bool,
3770 pub implicit_self: ImplicitSelfKind,
3772 pub lifetime_elision_allowed: bool,
3774}
3775
3776impl<'hir> FnDecl<'hir> {
3777 pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3778 if let FnRetTy::Return(ty) = self.output
3779 && let TyKind::InferDelegation(sig_id, _) = ty.kind
3780 {
3781 return Some(sig_id);
3782 }
3783 None
3784 }
3785}
3786
3787#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3789pub enum ImplicitSelfKind {
3790 Imm,
3792 Mut,
3794 RefImm,
3796 RefMut,
3798 None,
3801}
3802
3803impl ImplicitSelfKind {
3804 pub fn has_implicit_self(&self) -> bool {
3806 !matches!(*self, ImplicitSelfKind::None)
3807 }
3808}
3809
3810#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3811pub enum IsAsync {
3812 Async(Span),
3813 NotAsync,
3814}
3815
3816impl IsAsync {
3817 pub fn is_async(self) -> bool {
3818 matches!(self, IsAsync::Async(_))
3819 }
3820}
3821
3822#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3823pub enum Defaultness {
3824 Default { has_value: bool },
3825 Final,
3826}
3827
3828impl Defaultness {
3829 pub fn has_value(&self) -> bool {
3830 match *self {
3831 Defaultness::Default { has_value } => has_value,
3832 Defaultness::Final => true,
3833 }
3834 }
3835
3836 pub fn is_final(&self) -> bool {
3837 *self == Defaultness::Final
3838 }
3839
3840 pub fn is_default(&self) -> bool {
3841 matches!(*self, Defaultness::Default { .. })
3842 }
3843}
3844
3845#[derive(Debug, Clone, Copy, HashStable_Generic)]
3846pub enum FnRetTy<'hir> {
3847 DefaultReturn(Span),
3853 Return(&'hir Ty<'hir>),
3855}
3856
3857impl<'hir> FnRetTy<'hir> {
3858 #[inline]
3859 pub fn span(&self) -> Span {
3860 match *self {
3861 Self::DefaultReturn(span) => span,
3862 Self::Return(ref ty) => ty.span,
3863 }
3864 }
3865
3866 pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3867 if let Self::Return(ty) = self
3868 && ty.is_suggestable_infer_ty()
3869 {
3870 return Some(*ty);
3871 }
3872 None
3873 }
3874}
3875
3876#[derive(Copy, Clone, Debug, HashStable_Generic)]
3878pub enum ClosureBinder {
3879 Default,
3881 For { span: Span },
3885}
3886
3887#[derive(Debug, Clone, Copy, HashStable_Generic)]
3888pub struct Mod<'hir> {
3889 pub spans: ModSpans,
3890 pub item_ids: &'hir [ItemId],
3891}
3892
3893#[derive(Copy, Clone, Debug, HashStable_Generic)]
3894pub struct ModSpans {
3895 pub inner_span: Span,
3899 pub inject_use_span: Span,
3900}
3901
3902#[derive(Debug, Clone, Copy, HashStable_Generic)]
3903pub struct EnumDef<'hir> {
3904 pub variants: &'hir [Variant<'hir>],
3905}
3906
3907#[derive(Debug, Clone, Copy, HashStable_Generic)]
3908pub struct Variant<'hir> {
3909 pub ident: Ident,
3911 #[stable_hasher(ignore)]
3913 pub hir_id: HirId,
3914 pub def_id: LocalDefId,
3915 pub data: VariantData<'hir>,
3917 pub disr_expr: Option<&'hir AnonConst>,
3919 pub span: Span,
3921}
3922
3923#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3924pub enum UseKind {
3925 Single(Ident),
3932
3933 Glob,
3935
3936 ListStem,
3940}
3941
3942#[derive(Clone, Debug, Copy, HashStable_Generic)]
3949pub struct TraitRef<'hir> {
3950 pub path: &'hir Path<'hir>,
3951 #[stable_hasher(ignore)]
3953 pub hir_ref_id: HirId,
3954}
3955
3956impl TraitRef<'_> {
3957 pub fn trait_def_id(&self) -> Option<DefId> {
3959 match self.path.res {
3960 Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
3961 Res::Err => None,
3962 res => panic!("{res:?} did not resolve to a trait or trait alias"),
3963 }
3964 }
3965}
3966
3967#[derive(Clone, Debug, Copy, HashStable_Generic)]
3968pub struct PolyTraitRef<'hir> {
3969 pub bound_generic_params: &'hir [GenericParam<'hir>],
3971
3972 pub modifiers: TraitBoundModifiers,
3976
3977 pub trait_ref: TraitRef<'hir>,
3979
3980 pub span: Span,
3981}
3982
3983#[derive(Debug, Clone, Copy, HashStable_Generic)]
3984pub struct FieldDef<'hir> {
3985 pub span: Span,
3986 pub vis_span: Span,
3987 pub ident: Ident,
3988 #[stable_hasher(ignore)]
3989 pub hir_id: HirId,
3990 pub def_id: LocalDefId,
3991 pub ty: &'hir Ty<'hir>,
3992 pub safety: Safety,
3993 pub default: Option<&'hir AnonConst>,
3994}
3995
3996impl FieldDef<'_> {
3997 pub fn is_positional(&self) -> bool {
3999 self.ident.as_str().as_bytes()[0].is_ascii_digit()
4000 }
4001}
4002
4003#[derive(Debug, Clone, Copy, HashStable_Generic)]
4005pub enum VariantData<'hir> {
4006 Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
4010 Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
4014 Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
4018}
4019
4020impl<'hir> VariantData<'hir> {
4021 pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
4023 match *self {
4024 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
4025 _ => &[],
4026 }
4027 }
4028
4029 pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
4030 match *self {
4031 VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
4032 VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
4033 VariantData::Struct { .. } => None,
4034 }
4035 }
4036
4037 #[inline]
4038 pub fn ctor_kind(&self) -> Option<CtorKind> {
4039 self.ctor().map(|(kind, ..)| kind)
4040 }
4041
4042 #[inline]
4044 pub fn ctor_hir_id(&self) -> Option<HirId> {
4045 self.ctor().map(|(_, hir_id, _)| hir_id)
4046 }
4047
4048 #[inline]
4050 pub fn ctor_def_id(&self) -> Option<LocalDefId> {
4051 self.ctor().map(|(.., def_id)| def_id)
4052 }
4053}
4054
4055#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
4059pub struct ItemId {
4060 pub owner_id: OwnerId,
4061}
4062
4063impl ItemId {
4064 #[inline]
4065 pub fn hir_id(&self) -> HirId {
4066 HirId::make_owner(self.owner_id.def_id)
4068 }
4069}
4070
4071#[derive(Debug, Clone, Copy, HashStable_Generic)]
4080pub struct Item<'hir> {
4081 pub owner_id: OwnerId,
4082 pub kind: ItemKind<'hir>,
4083 pub span: Span,
4084 pub vis_span: Span,
4085}
4086
4087impl<'hir> Item<'hir> {
4088 #[inline]
4089 pub fn hir_id(&self) -> HirId {
4090 HirId::make_owner(self.owner_id.def_id)
4092 }
4093
4094 pub fn item_id(&self) -> ItemId {
4095 ItemId { owner_id: self.owner_id }
4096 }
4097
4098 pub fn is_adt(&self) -> bool {
4101 matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
4102 }
4103
4104 pub fn is_struct_or_union(&self) -> bool {
4106 matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
4107 }
4108
4109 expect_methods_self_kind! {
4110 expect_extern_crate, (Option<Symbol>, Ident),
4111 ItemKind::ExternCrate(s, ident), (*s, *ident);
4112
4113 expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
4114
4115 expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId),
4116 ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body);
4117
4118 expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4119 ItemKind::Const(ident, generics, ty, body), (*ident, generics, ty, *body);
4120
4121 expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
4122 ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
4123
4124 expect_macro, (Ident, &ast::MacroDef, MacroKind),
4125 ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
4126
4127 expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
4128
4129 expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
4130 ItemKind::ForeignMod { abi, items }, (*abi, items);
4131
4132 expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
4133
4134 expect_ty_alias, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4135 ItemKind::TyAlias(ident, generics, ty), (*ident, generics, ty);
4136
4137 expect_enum, (Ident, &'hir Generics<'hir>, &EnumDef<'hir>),
4138 ItemKind::Enum(ident, generics, def), (*ident, generics, def);
4139
4140 expect_struct, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4141 ItemKind::Struct(ident, generics, data), (*ident, generics, data);
4142
4143 expect_union, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
4144 ItemKind::Union(ident, generics, data), (*ident, generics, data);
4145
4146 expect_trait,
4147 (
4148 IsAuto,
4149 Safety,
4150 Ident,
4151 &'hir Generics<'hir>,
4152 GenericBounds<'hir>,
4153 &'hir [TraitItemRef]
4154 ),
4155 ItemKind::Trait(is_auto, safety, ident, generics, bounds, items),
4156 (*is_auto, *safety, *ident, generics, bounds, items);
4157
4158 expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4159 ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
4160
4161 expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
4162 }
4163}
4164
4165#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4166#[derive(Encodable, Decodable, HashStable_Generic)]
4167pub enum Safety {
4168 Unsafe,
4169 Safe,
4170}
4171
4172impl Safety {
4173 pub fn prefix_str(self) -> &'static str {
4174 match self {
4175 Self::Unsafe => "unsafe ",
4176 Self::Safe => "",
4177 }
4178 }
4179
4180 #[inline]
4181 pub fn is_unsafe(self) -> bool {
4182 !self.is_safe()
4183 }
4184
4185 #[inline]
4186 pub fn is_safe(self) -> bool {
4187 match self {
4188 Self::Unsafe => false,
4189 Self::Safe => true,
4190 }
4191 }
4192}
4193
4194impl fmt::Display for Safety {
4195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4196 f.write_str(match *self {
4197 Self::Unsafe => "unsafe",
4198 Self::Safe => "safe",
4199 })
4200 }
4201}
4202
4203#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
4204pub enum Constness {
4205 Const,
4206 NotConst,
4207}
4208
4209impl fmt::Display for Constness {
4210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4211 f.write_str(match *self {
4212 Self::Const => "const",
4213 Self::NotConst => "non-const",
4214 })
4215 }
4216}
4217
4218#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
4223pub enum HeaderSafety {
4224 SafeTargetFeatures,
4230 Normal(Safety),
4231}
4232
4233impl From<Safety> for HeaderSafety {
4234 fn from(v: Safety) -> Self {
4235 Self::Normal(v)
4236 }
4237}
4238
4239#[derive(Copy, Clone, Debug, HashStable_Generic)]
4240pub struct FnHeader {
4241 pub safety: HeaderSafety,
4242 pub constness: Constness,
4243 pub asyncness: IsAsync,
4244 pub abi: ExternAbi,
4245}
4246
4247impl FnHeader {
4248 pub fn is_async(&self) -> bool {
4249 matches!(self.asyncness, IsAsync::Async(_))
4250 }
4251
4252 pub fn is_const(&self) -> bool {
4253 matches!(self.constness, Constness::Const)
4254 }
4255
4256 pub fn is_unsafe(&self) -> bool {
4257 self.safety().is_unsafe()
4258 }
4259
4260 pub fn is_safe(&self) -> bool {
4261 self.safety().is_safe()
4262 }
4263
4264 pub fn safety(&self) -> Safety {
4265 match self.safety {
4266 HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
4267 HeaderSafety::Normal(safety) => safety,
4268 }
4269 }
4270}
4271
4272#[derive(Debug, Clone, Copy, HashStable_Generic)]
4273pub enum ItemKind<'hir> {
4274 ExternCrate(Option<Symbol>, Ident),
4278
4279 Use(&'hir UsePath<'hir>, UseKind),
4285
4286 Static(Mutability, Ident, &'hir Ty<'hir>, BodyId),
4288 Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, BodyId),
4290 Fn {
4292 sig: FnSig<'hir>,
4293 ident: Ident,
4294 generics: &'hir Generics<'hir>,
4295 body: BodyId,
4296 has_body: bool,
4300 },
4301 Macro(Ident, &'hir ast::MacroDef, MacroKind),
4303 Mod(Ident, &'hir Mod<'hir>),
4305 ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
4307 GlobalAsm {
4309 asm: &'hir InlineAsm<'hir>,
4310 fake_body: BodyId,
4316 },
4317 TyAlias(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
4319 Enum(Ident, &'hir Generics<'hir>, EnumDef<'hir>),
4321 Struct(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4323 Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
4325 Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
4327 TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4329
4330 Impl(&'hir Impl<'hir>),
4332}
4333
4334#[derive(Debug, Clone, Copy, HashStable_Generic)]
4339pub struct Impl<'hir> {
4340 pub constness: Constness,
4341 pub safety: Safety,
4342 pub polarity: ImplPolarity,
4343 pub defaultness: Defaultness,
4344 pub defaultness_span: Option<Span>,
4347 pub generics: &'hir Generics<'hir>,
4348
4349 pub of_trait: Option<TraitRef<'hir>>,
4351
4352 pub self_ty: &'hir Ty<'hir>,
4353 pub items: &'hir [ImplItemRef],
4354}
4355
4356impl ItemKind<'_> {
4357 pub fn ident(&self) -> Option<Ident> {
4358 match *self {
4359 ItemKind::ExternCrate(_, ident)
4360 | ItemKind::Use(_, UseKind::Single(ident))
4361 | ItemKind::Static(_, ident, ..)
4362 | ItemKind::Const(ident, ..)
4363 | ItemKind::Fn { ident, .. }
4364 | ItemKind::Macro(ident, ..)
4365 | ItemKind::Mod(ident, ..)
4366 | ItemKind::TyAlias(ident, ..)
4367 | ItemKind::Enum(ident, ..)
4368 | ItemKind::Struct(ident, ..)
4369 | ItemKind::Union(ident, ..)
4370 | ItemKind::Trait(_, _, ident, ..)
4371 | ItemKind::TraitAlias(ident, ..) => Some(ident),
4372
4373 ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
4374 | ItemKind::ForeignMod { .. }
4375 | ItemKind::GlobalAsm { .. }
4376 | ItemKind::Impl(_) => None,
4377 }
4378 }
4379
4380 pub fn generics(&self) -> Option<&Generics<'_>> {
4381 Some(match self {
4382 ItemKind::Fn { generics, .. }
4383 | ItemKind::TyAlias(_, generics, _)
4384 | ItemKind::Const(_, generics, _, _)
4385 | ItemKind::Enum(_, generics, _)
4386 | ItemKind::Struct(_, generics, _)
4387 | ItemKind::Union(_, generics, _)
4388 | ItemKind::Trait(_, _, _, generics, _, _)
4389 | ItemKind::TraitAlias(_, generics, _)
4390 | ItemKind::Impl(Impl { generics, .. }) => generics,
4391 _ => return None,
4392 })
4393 }
4394
4395 pub fn descr(&self) -> &'static str {
4396 match self {
4397 ItemKind::ExternCrate(..) => "extern crate",
4398 ItemKind::Use(..) => "`use` import",
4399 ItemKind::Static(..) => "static item",
4400 ItemKind::Const(..) => "constant item",
4401 ItemKind::Fn { .. } => "function",
4402 ItemKind::Macro(..) => "macro",
4403 ItemKind::Mod(..) => "module",
4404 ItemKind::ForeignMod { .. } => "extern block",
4405 ItemKind::GlobalAsm { .. } => "global asm item",
4406 ItemKind::TyAlias(..) => "type alias",
4407 ItemKind::Enum(..) => "enum",
4408 ItemKind::Struct(..) => "struct",
4409 ItemKind::Union(..) => "union",
4410 ItemKind::Trait(..) => "trait",
4411 ItemKind::TraitAlias(..) => "trait alias",
4412 ItemKind::Impl(..) => "implementation",
4413 }
4414 }
4415}
4416
4417#[derive(Debug, Clone, Copy, HashStable_Generic)]
4424pub struct TraitItemRef {
4425 pub id: TraitItemId,
4426 pub ident: Ident,
4427 pub kind: AssocItemKind,
4428 pub span: Span,
4429}
4430
4431#[derive(Debug, Clone, Copy, HashStable_Generic)]
4438pub struct ImplItemRef {
4439 pub id: ImplItemId,
4440 pub ident: Ident,
4441 pub kind: AssocItemKind,
4442 pub span: Span,
4443 pub trait_item_def_id: Option<DefId>,
4445}
4446
4447#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4448pub enum AssocItemKind {
4449 Const,
4450 Fn { has_self: bool },
4451 Type,
4452}
4453
4454#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4458pub struct ForeignItemId {
4459 pub owner_id: OwnerId,
4460}
4461
4462impl ForeignItemId {
4463 #[inline]
4464 pub fn hir_id(&self) -> HirId {
4465 HirId::make_owner(self.owner_id.def_id)
4467 }
4468}
4469
4470#[derive(Debug, Clone, Copy, HashStable_Generic)]
4477pub struct ForeignItemRef {
4478 pub id: ForeignItemId,
4479 pub ident: Ident,
4480 pub span: Span,
4481}
4482
4483#[derive(Debug, Clone, Copy, HashStable_Generic)]
4484pub struct ForeignItem<'hir> {
4485 pub ident: Ident,
4486 pub kind: ForeignItemKind<'hir>,
4487 pub owner_id: OwnerId,
4488 pub span: Span,
4489 pub vis_span: Span,
4490}
4491
4492impl ForeignItem<'_> {
4493 #[inline]
4494 pub fn hir_id(&self) -> HirId {
4495 HirId::make_owner(self.owner_id.def_id)
4497 }
4498
4499 pub fn foreign_item_id(&self) -> ForeignItemId {
4500 ForeignItemId { owner_id: self.owner_id }
4501 }
4502}
4503
4504#[derive(Debug, Clone, Copy, HashStable_Generic)]
4506pub enum ForeignItemKind<'hir> {
4507 Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
4514 Static(&'hir Ty<'hir>, Mutability, Safety),
4516 Type,
4518}
4519
4520#[derive(Debug, Copy, Clone, HashStable_Generic)]
4522pub struct Upvar {
4523 pub span: Span,
4525}
4526
4527#[derive(Debug, Clone, HashStable_Generic)]
4531pub struct TraitCandidate {
4532 pub def_id: DefId,
4533 pub import_ids: SmallVec<[LocalDefId; 1]>,
4534}
4535
4536#[derive(Copy, Clone, Debug, HashStable_Generic)]
4537pub enum OwnerNode<'hir> {
4538 Item(&'hir Item<'hir>),
4539 ForeignItem(&'hir ForeignItem<'hir>),
4540 TraitItem(&'hir TraitItem<'hir>),
4541 ImplItem(&'hir ImplItem<'hir>),
4542 Crate(&'hir Mod<'hir>),
4543 Synthetic,
4544}
4545
4546impl<'hir> OwnerNode<'hir> {
4547 pub fn span(&self) -> Span {
4548 match self {
4549 OwnerNode::Item(Item { span, .. })
4550 | OwnerNode::ForeignItem(ForeignItem { span, .. })
4551 | OwnerNode::ImplItem(ImplItem { span, .. })
4552 | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4553 OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4554 OwnerNode::Synthetic => unreachable!(),
4555 }
4556 }
4557
4558 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4559 match self {
4560 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4561 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4562 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4563 | OwnerNode::ForeignItem(ForeignItem {
4564 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4565 }) => Some(fn_sig),
4566 _ => None,
4567 }
4568 }
4569
4570 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4571 match self {
4572 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4573 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4574 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4575 | OwnerNode::ForeignItem(ForeignItem {
4576 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4577 }) => Some(fn_sig.decl),
4578 _ => None,
4579 }
4580 }
4581
4582 pub fn body_id(&self) -> Option<BodyId> {
4583 match self {
4584 OwnerNode::Item(Item {
4585 kind:
4586 ItemKind::Static(_, _, _, body)
4587 | ItemKind::Const(_, _, _, body)
4588 | ItemKind::Fn { body, .. },
4589 ..
4590 })
4591 | OwnerNode::TraitItem(TraitItem {
4592 kind:
4593 TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4594 ..
4595 })
4596 | OwnerNode::ImplItem(ImplItem {
4597 kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4598 ..
4599 }) => Some(*body),
4600 _ => None,
4601 }
4602 }
4603
4604 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4605 Node::generics(self.into())
4606 }
4607
4608 pub fn def_id(self) -> OwnerId {
4609 match self {
4610 OwnerNode::Item(Item { owner_id, .. })
4611 | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4612 | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4613 | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4614 OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4615 OwnerNode::Synthetic => unreachable!(),
4616 }
4617 }
4618
4619 pub fn is_impl_block(&self) -> bool {
4621 matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4622 }
4623
4624 expect_methods_self! {
4625 expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
4626 expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4627 expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n;
4628 expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n;
4629 }
4630}
4631
4632impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4633 fn from(val: &'hir Item<'hir>) -> Self {
4634 OwnerNode::Item(val)
4635 }
4636}
4637
4638impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4639 fn from(val: &'hir ForeignItem<'hir>) -> Self {
4640 OwnerNode::ForeignItem(val)
4641 }
4642}
4643
4644impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4645 fn from(val: &'hir ImplItem<'hir>) -> Self {
4646 OwnerNode::ImplItem(val)
4647 }
4648}
4649
4650impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4651 fn from(val: &'hir TraitItem<'hir>) -> Self {
4652 OwnerNode::TraitItem(val)
4653 }
4654}
4655
4656impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4657 fn from(val: OwnerNode<'hir>) -> Self {
4658 match val {
4659 OwnerNode::Item(n) => Node::Item(n),
4660 OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4661 OwnerNode::ImplItem(n) => Node::ImplItem(n),
4662 OwnerNode::TraitItem(n) => Node::TraitItem(n),
4663 OwnerNode::Crate(n) => Node::Crate(n),
4664 OwnerNode::Synthetic => Node::Synthetic,
4665 }
4666 }
4667}
4668
4669#[derive(Copy, Clone, Debug, HashStable_Generic)]
4670pub enum Node<'hir> {
4671 Param(&'hir Param<'hir>),
4672 Item(&'hir Item<'hir>),
4673 ForeignItem(&'hir ForeignItem<'hir>),
4674 TraitItem(&'hir TraitItem<'hir>),
4675 ImplItem(&'hir ImplItem<'hir>),
4676 Variant(&'hir Variant<'hir>),
4677 Field(&'hir FieldDef<'hir>),
4678 AnonConst(&'hir AnonConst),
4679 ConstBlock(&'hir ConstBlock),
4680 ConstArg(&'hir ConstArg<'hir>),
4681 Expr(&'hir Expr<'hir>),
4682 ExprField(&'hir ExprField<'hir>),
4683 Stmt(&'hir Stmt<'hir>),
4684 PathSegment(&'hir PathSegment<'hir>),
4685 Ty(&'hir Ty<'hir>),
4686 AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4687 TraitRef(&'hir TraitRef<'hir>),
4688 OpaqueTy(&'hir OpaqueTy<'hir>),
4689 TyPat(&'hir TyPat<'hir>),
4690 Pat(&'hir Pat<'hir>),
4691 PatField(&'hir PatField<'hir>),
4692 PatExpr(&'hir PatExpr<'hir>),
4696 Arm(&'hir Arm<'hir>),
4697 Block(&'hir Block<'hir>),
4698 LetStmt(&'hir LetStmt<'hir>),
4699 Ctor(&'hir VariantData<'hir>),
4702 Lifetime(&'hir Lifetime),
4703 GenericParam(&'hir GenericParam<'hir>),
4704 Crate(&'hir Mod<'hir>),
4705 Infer(&'hir InferArg),
4706 WherePredicate(&'hir WherePredicate<'hir>),
4707 PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4708 Synthetic,
4710 Err(Span),
4711}
4712
4713impl<'hir> Node<'hir> {
4714 pub fn ident(&self) -> Option<Ident> {
4729 match self {
4730 Node::Item(item) => item.kind.ident(),
4731 Node::TraitItem(TraitItem { ident, .. })
4732 | Node::ImplItem(ImplItem { ident, .. })
4733 | Node::ForeignItem(ForeignItem { ident, .. })
4734 | Node::Field(FieldDef { ident, .. })
4735 | Node::Variant(Variant { ident, .. })
4736 | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4737 Node::Lifetime(lt) => Some(lt.ident),
4738 Node::GenericParam(p) => Some(p.name.ident()),
4739 Node::AssocItemConstraint(c) => Some(c.ident),
4740 Node::PatField(f) => Some(f.ident),
4741 Node::ExprField(f) => Some(f.ident),
4742 Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4743 Node::Param(..)
4744 | Node::AnonConst(..)
4745 | Node::ConstBlock(..)
4746 | Node::ConstArg(..)
4747 | Node::Expr(..)
4748 | Node::Stmt(..)
4749 | Node::Block(..)
4750 | Node::Ctor(..)
4751 | Node::Pat(..)
4752 | Node::TyPat(..)
4753 | Node::PatExpr(..)
4754 | Node::Arm(..)
4755 | Node::LetStmt(..)
4756 | Node::Crate(..)
4757 | Node::Ty(..)
4758 | Node::TraitRef(..)
4759 | Node::OpaqueTy(..)
4760 | Node::Infer(..)
4761 | Node::WherePredicate(..)
4762 | Node::Synthetic
4763 | Node::Err(..) => None,
4764 }
4765 }
4766
4767 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4768 match self {
4769 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4770 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4771 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4772 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4773 Some(fn_sig.decl)
4774 }
4775 Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4776 Some(fn_decl)
4777 }
4778 _ => None,
4779 }
4780 }
4781
4782 pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4784 if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4785 && let Some(trait_ref) = impl_block.of_trait
4786 && let Some(trait_id) = trait_ref.trait_def_id()
4787 && trait_id == trait_def_id
4788 {
4789 Some(impl_block)
4790 } else {
4791 None
4792 }
4793 }
4794
4795 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4796 match self {
4797 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4798 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4799 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4800 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4801 Some(fn_sig)
4802 }
4803 _ => None,
4804 }
4805 }
4806
4807 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4809 match self {
4810 Node::Item(it) => match it.kind {
4811 ItemKind::TyAlias(_, _, ty)
4812 | ItemKind::Static(_, _, ty, _)
4813 | ItemKind::Const(_, _, ty, _) => Some(ty),
4814 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4815 _ => None,
4816 },
4817 Node::TraitItem(it) => match it.kind {
4818 TraitItemKind::Const(ty, _) => Some(ty),
4819 TraitItemKind::Type(_, ty) => ty,
4820 _ => None,
4821 },
4822 Node::ImplItem(it) => match it.kind {
4823 ImplItemKind::Const(ty, _) => Some(ty),
4824 ImplItemKind::Type(ty) => Some(ty),
4825 _ => None,
4826 },
4827 _ => None,
4828 }
4829 }
4830
4831 pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4832 match self {
4833 Node::Item(Item { kind: ItemKind::TyAlias(_, _, ty), .. }) => Some(ty),
4834 _ => None,
4835 }
4836 }
4837
4838 #[inline]
4839 pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4840 match self {
4841 Node::Item(Item {
4842 owner_id,
4843 kind:
4844 ItemKind::Const(_, _, _, body)
4845 | ItemKind::Static(.., body)
4846 | ItemKind::Fn { body, .. },
4847 ..
4848 })
4849 | Node::TraitItem(TraitItem {
4850 owner_id,
4851 kind:
4852 TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4853 ..
4854 })
4855 | Node::ImplItem(ImplItem {
4856 owner_id,
4857 kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4858 ..
4859 }) => Some((owner_id.def_id, *body)),
4860
4861 Node::Item(Item {
4862 owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4863 }) => Some((owner_id.def_id, *fake_body)),
4864
4865 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4866 Some((*def_id, *body))
4867 }
4868
4869 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4870 Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4871
4872 _ => None,
4873 }
4874 }
4875
4876 pub fn body_id(&self) -> Option<BodyId> {
4877 Some(self.associated_body()?.1)
4878 }
4879
4880 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4881 match self {
4882 Node::ForeignItem(ForeignItem {
4883 kind: ForeignItemKind::Fn(_, _, generics), ..
4884 })
4885 | Node::TraitItem(TraitItem { generics, .. })
4886 | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4887 Node::Item(item) => item.kind.generics(),
4888 _ => None,
4889 }
4890 }
4891
4892 pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4893 match self {
4894 Node::Item(i) => Some(OwnerNode::Item(i)),
4895 Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4896 Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4897 Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4898 Node::Crate(i) => Some(OwnerNode::Crate(i)),
4899 Node::Synthetic => Some(OwnerNode::Synthetic),
4900 _ => None,
4901 }
4902 }
4903
4904 pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4905 match self {
4906 Node::Item(i) => match i.kind {
4907 ItemKind::Fn { ident, sig, generics, .. } => {
4908 Some(FnKind::ItemFn(ident, generics, sig.header))
4909 }
4910 _ => None,
4911 },
4912 Node::TraitItem(ti) => match ti.kind {
4913 TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4914 _ => None,
4915 },
4916 Node::ImplItem(ii) => match ii.kind {
4917 ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4918 _ => None,
4919 },
4920 Node::Expr(e) => match e.kind {
4921 ExprKind::Closure { .. } => Some(FnKind::Closure),
4922 _ => None,
4923 },
4924 _ => None,
4925 }
4926 }
4927
4928 expect_methods_self! {
4929 expect_param, &'hir Param<'hir>, Node::Param(n), n;
4930 expect_item, &'hir Item<'hir>, Node::Item(n), n;
4931 expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n;
4932 expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n;
4933 expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n;
4934 expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
4935 expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
4936 expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
4937 expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
4938 expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
4939 expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
4940 expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
4941 expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
4942 expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
4943 expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
4944 expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4945 expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
4946 expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
4947 expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
4948 expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
4949 expect_block, &'hir Block<'hir>, Node::Block(n), n;
4950 expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
4951 expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
4952 expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
4953 expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
4954 expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
4955 expect_infer, &'hir InferArg, Node::Infer(n), n;
4956 expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
4957 }
4958}
4959
4960#[cfg(target_pointer_width = "64")]
4962mod size_asserts {
4963 use rustc_data_structures::static_assert_size;
4964
4965 use super::*;
4966 static_assert_size!(Block<'_>, 48);
4968 static_assert_size!(Body<'_>, 24);
4969 static_assert_size!(Expr<'_>, 64);
4970 static_assert_size!(ExprKind<'_>, 48);
4971 static_assert_size!(FnDecl<'_>, 40);
4972 static_assert_size!(ForeignItem<'_>, 88);
4973 static_assert_size!(ForeignItemKind<'_>, 56);
4974 static_assert_size!(GenericArg<'_>, 16);
4975 static_assert_size!(GenericBound<'_>, 64);
4976 static_assert_size!(Generics<'_>, 56);
4977 static_assert_size!(Impl<'_>, 80);
4978 static_assert_size!(ImplItem<'_>, 88);
4979 static_assert_size!(ImplItemKind<'_>, 40);
4980 static_assert_size!(Item<'_>, 88);
4981 static_assert_size!(ItemKind<'_>, 64);
4982 static_assert_size!(LetStmt<'_>, 72);
4983 static_assert_size!(Param<'_>, 32);
4984 static_assert_size!(Pat<'_>, 72);
4985 static_assert_size!(Path<'_>, 40);
4986 static_assert_size!(PathSegment<'_>, 48);
4987 static_assert_size!(PatKind<'_>, 48);
4988 static_assert_size!(QPath<'_>, 24);
4989 static_assert_size!(Res, 12);
4990 static_assert_size!(Stmt<'_>, 32);
4991 static_assert_size!(StmtKind<'_>, 16);
4992 static_assert_size!(TraitItem<'_>, 88);
4993 static_assert_size!(TraitItemKind<'_>, 48);
4994 static_assert_size!(Ty<'_>, 48);
4995 static_assert_size!(TyKind<'_>, 32);
4996 }
4998
4999#[cfg(test)]
5000mod tests;