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 AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity,
14 ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto, MetaItemInner, MetaItemLit, Movability,
15 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, 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 IsAnonInPath {
40 No,
41 Yes,
42}
43
44#[derive(Debug, Copy, Clone, HashStable_Generic)]
77pub struct Lifetime {
78 #[stable_hasher(ignore)]
79 pub hir_id: HirId,
80
81 pub ident: Ident,
85
86 pub res: LifetimeName,
88
89 pub is_anon_in_path: IsAnonInPath,
92}
93
94#[derive(Debug, Copy, Clone, HashStable_Generic)]
95pub enum ParamName {
96 Plain(Ident),
98
99 Error(Ident),
105
106 Fresh,
121}
122
123impl ParamName {
124 pub fn ident(&self) -> Ident {
125 match *self {
126 ParamName::Plain(ident) | ParamName::Error(ident) => ident,
127 ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
128 }
129 }
130}
131
132#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
133pub enum LifetimeName {
134 Param(LocalDefId),
136
137 ImplicitObjectLifetimeDefault,
149
150 Error,
153
154 Infer,
158
159 Static,
161}
162
163impl LifetimeName {
164 fn is_elided(&self) -> bool {
165 match self {
166 LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
167
168 LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
173 }
174 }
175}
176
177impl fmt::Display for Lifetime {
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 self.ident.name.fmt(f)
180 }
181}
182
183impl Lifetime {
184 pub fn new(
185 hir_id: HirId,
186 ident: Ident,
187 res: LifetimeName,
188 is_anon_in_path: IsAnonInPath,
189 ) -> Lifetime {
190 let lifetime = Lifetime { hir_id, ident, res, is_anon_in_path };
191
192 #[cfg(debug_assertions)]
194 match (lifetime.is_elided(), lifetime.is_anonymous()) {
195 (false, false) => {} (false, true) => {} (true, true) => {} (true, false) => panic!("bad Lifetime"),
199 }
200
201 lifetime
202 }
203
204 pub fn is_elided(&self) -> bool {
205 self.res.is_elided()
206 }
207
208 pub fn is_anonymous(&self) -> bool {
209 self.ident.name == kw::UnderscoreLifetime
210 }
211
212 pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
213 debug_assert!(new_lifetime.starts_with('\''));
214
215 match (self.is_anon_in_path, self.ident.span.is_empty()) {
216 (IsAnonInPath::Yes, true) => (self.ident.span, format!("{new_lifetime}, ")),
218
219 (IsAnonInPath::Yes, false) => {
221 (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
222 }
223
224 (IsAnonInPath::No, true) => (self.ident.span, format!("{new_lifetime} ")),
226
227 (IsAnonInPath::No, false) => (self.ident.span, format!("{new_lifetime}")),
229 }
230 }
231}
232
233#[derive(Debug, Clone, Copy, HashStable_Generic)]
237pub struct Path<'hir, R = Res> {
238 pub span: Span,
239 pub res: R,
241 pub segments: &'hir [PathSegment<'hir>],
243}
244
245pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
247
248impl Path<'_> {
249 pub fn is_global(&self) -> bool {
250 self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
251 }
252}
253
254#[derive(Debug, Clone, Copy, HashStable_Generic)]
257pub struct PathSegment<'hir> {
258 pub ident: Ident,
260 #[stable_hasher(ignore)]
261 pub hir_id: HirId,
262 pub res: Res,
263
264 pub args: Option<&'hir GenericArgs<'hir>>,
270
271 pub infer_args: bool,
276}
277
278impl<'hir> PathSegment<'hir> {
279 pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
281 PathSegment { ident, hir_id, res, infer_args: true, args: None }
282 }
283
284 pub fn invalid() -> Self {
285 Self::new(Ident::dummy(), HirId::INVALID, Res::Err)
286 }
287
288 pub fn args(&self) -> &GenericArgs<'hir> {
289 if let Some(ref args) = self.args {
290 args
291 } else {
292 const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
293 DUMMY
294 }
295 }
296}
297
298#[derive(Clone, Copy, Debug, HashStable_Generic)]
314#[repr(C)]
315pub struct ConstArg<'hir, Unambig = ()> {
316 #[stable_hasher(ignore)]
317 pub hir_id: HirId,
318 pub kind: ConstArgKind<'hir, Unambig>,
319}
320
321impl<'hir> ConstArg<'hir, AmbigArg> {
322 pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
333 let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
336 unsafe { &*ptr }
337 }
338}
339
340impl<'hir> ConstArg<'hir> {
341 pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
347 if let ConstArgKind::Infer(_, ()) = self.kind {
348 return None;
349 }
350
351 let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
355 Some(unsafe { &*ptr })
356 }
357}
358
359impl<'hir, Unambig> ConstArg<'hir, Unambig> {
360 pub fn anon_const_hir_id(&self) -> Option<HirId> {
361 match self.kind {
362 ConstArgKind::Anon(ac) => Some(ac.hir_id),
363 _ => None,
364 }
365 }
366
367 pub fn span(&self) -> Span {
368 match self.kind {
369 ConstArgKind::Path(path) => path.span(),
370 ConstArgKind::Anon(anon) => anon.span,
371 ConstArgKind::Infer(span, _) => span,
372 }
373 }
374}
375
376#[derive(Clone, Copy, Debug, HashStable_Generic)]
378#[repr(u8, C)]
379pub enum ConstArgKind<'hir, Unambig = ()> {
380 Path(QPath<'hir>),
386 Anon(&'hir AnonConst),
387 Infer(Span, Unambig),
390}
391
392#[derive(Clone, Copy, Debug, HashStable_Generic)]
393pub struct InferArg {
394 #[stable_hasher(ignore)]
395 pub hir_id: HirId,
396 pub span: Span,
397}
398
399impl InferArg {
400 pub fn to_ty(&self) -> Ty<'static> {
401 Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
402 }
403}
404
405#[derive(Debug, Clone, Copy, HashStable_Generic)]
406pub enum GenericArg<'hir> {
407 Lifetime(&'hir Lifetime),
408 Type(&'hir Ty<'hir, AmbigArg>),
409 Const(&'hir ConstArg<'hir, AmbigArg>),
410 Infer(InferArg),
420}
421
422impl GenericArg<'_> {
423 pub fn span(&self) -> Span {
424 match self {
425 GenericArg::Lifetime(l) => l.ident.span,
426 GenericArg::Type(t) => t.span,
427 GenericArg::Const(c) => c.span(),
428 GenericArg::Infer(i) => i.span,
429 }
430 }
431
432 pub fn hir_id(&self) -> HirId {
433 match self {
434 GenericArg::Lifetime(l) => l.hir_id,
435 GenericArg::Type(t) => t.hir_id,
436 GenericArg::Const(c) => c.hir_id,
437 GenericArg::Infer(i) => i.hir_id,
438 }
439 }
440
441 pub fn descr(&self) -> &'static str {
442 match self {
443 GenericArg::Lifetime(_) => "lifetime",
444 GenericArg::Type(_) => "type",
445 GenericArg::Const(_) => "constant",
446 GenericArg::Infer(_) => "placeholder",
447 }
448 }
449
450 pub fn to_ord(&self) -> ast::ParamKindOrd {
451 match self {
452 GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
453 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
454 ast::ParamKindOrd::TypeOrConst
455 }
456 }
457 }
458
459 pub fn is_ty_or_const(&self) -> bool {
460 match self {
461 GenericArg::Lifetime(_) => false,
462 GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
463 }
464 }
465}
466
467#[derive(Debug, Clone, Copy, HashStable_Generic)]
469pub struct GenericArgs<'hir> {
470 pub args: &'hir [GenericArg<'hir>],
472 pub constraints: &'hir [AssocItemConstraint<'hir>],
474 pub parenthesized: GenericArgsParentheses,
479 pub span_ext: Span,
492}
493
494impl<'hir> GenericArgs<'hir> {
495 pub const fn none() -> Self {
496 Self {
497 args: &[],
498 constraints: &[],
499 parenthesized: GenericArgsParentheses::No,
500 span_ext: DUMMY_SP,
501 }
502 }
503
504 pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
509 if self.parenthesized != GenericArgsParentheses::ParenSugar {
510 return None;
511 }
512
513 let inputs = self
514 .args
515 .iter()
516 .find_map(|arg| {
517 let GenericArg::Type(ty) = arg else { return None };
518 let TyKind::Tup(tys) = &ty.kind else { return None };
519 Some(tys)
520 })
521 .unwrap();
522
523 Some((inputs, self.paren_sugar_output_inner()))
524 }
525
526 pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
531 (self.parenthesized == GenericArgsParentheses::ParenSugar)
532 .then(|| self.paren_sugar_output_inner())
533 }
534
535 fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
536 let [constraint] = self.constraints.try_into().unwrap();
537 debug_assert_eq!(constraint.ident.name, sym::Output);
538 constraint.ty().unwrap()
539 }
540
541 pub fn has_err(&self) -> Option<ErrorGuaranteed> {
542 self.args
543 .iter()
544 .find_map(|arg| {
545 let GenericArg::Type(ty) = arg else { return None };
546 let TyKind::Err(guar) = ty.kind else { return None };
547 Some(guar)
548 })
549 .or_else(|| {
550 self.constraints.iter().find_map(|constraint| {
551 let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
552 Some(guar)
553 })
554 })
555 }
556
557 #[inline]
558 pub fn num_lifetime_params(&self) -> usize {
559 self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
560 }
561
562 #[inline]
563 pub fn has_lifetime_params(&self) -> bool {
564 self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
565 }
566
567 #[inline]
568 pub fn num_generic_params(&self) -> usize {
571 self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
572 }
573
574 pub fn span(&self) -> Option<Span> {
580 let span_ext = self.span_ext()?;
581 Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
582 }
583
584 pub fn span_ext(&self) -> Option<Span> {
586 Some(self.span_ext).filter(|span| !span.is_empty())
587 }
588
589 pub fn is_empty(&self) -> bool {
590 self.args.is_empty()
591 }
592}
593
594#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
595pub enum GenericArgsParentheses {
596 No,
597 ReturnTypeNotation,
600 ParenSugar,
602}
603
604#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
606pub struct TraitBoundModifiers {
607 pub constness: BoundConstness,
608 pub polarity: BoundPolarity,
609}
610
611impl TraitBoundModifiers {
612 pub const NONE: Self =
613 TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
614}
615
616#[derive(Clone, Copy, Debug, HashStable_Generic)]
617pub enum GenericBound<'hir> {
618 Trait(PolyTraitRef<'hir>),
619 Outlives(&'hir Lifetime),
620 Use(&'hir [PreciseCapturingArg<'hir>], Span),
621}
622
623impl GenericBound<'_> {
624 pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
625 match self {
626 GenericBound::Trait(data) => Some(&data.trait_ref),
627 _ => None,
628 }
629 }
630
631 pub fn span(&self) -> Span {
632 match self {
633 GenericBound::Trait(t, ..) => t.span,
634 GenericBound::Outlives(l) => l.ident.span,
635 GenericBound::Use(_, span) => *span,
636 }
637 }
638}
639
640pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];
641
642#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
643pub enum MissingLifetimeKind {
644 Underscore,
646 Ampersand,
648 Comma,
650 Brackets,
652}
653
654#[derive(Copy, Clone, Debug, HashStable_Generic)]
655pub enum LifetimeParamKind {
656 Explicit,
659
660 Elided(MissingLifetimeKind),
663
664 Error,
666}
667
668#[derive(Debug, Clone, Copy, HashStable_Generic)]
669pub enum GenericParamKind<'hir> {
670 Lifetime {
672 kind: LifetimeParamKind,
673 },
674 Type {
675 default: Option<&'hir Ty<'hir>>,
676 synthetic: bool,
677 },
678 Const {
679 ty: &'hir Ty<'hir>,
680 default: Option<&'hir ConstArg<'hir>>,
682 synthetic: bool,
683 },
684}
685
686#[derive(Debug, Clone, Copy, HashStable_Generic)]
687pub struct GenericParam<'hir> {
688 #[stable_hasher(ignore)]
689 pub hir_id: HirId,
690 pub def_id: LocalDefId,
691 pub name: ParamName,
692 pub span: Span,
693 pub pure_wrt_drop: bool,
694 pub kind: GenericParamKind<'hir>,
695 pub colon_span: Option<Span>,
696 pub source: GenericParamSource,
697}
698
699impl<'hir> GenericParam<'hir> {
700 pub fn is_impl_trait(&self) -> bool {
704 matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
705 }
706
707 pub fn is_elided_lifetime(&self) -> bool {
711 matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
712 }
713}
714
715#[derive(Debug, Clone, Copy, HashStable_Generic)]
722pub enum GenericParamSource {
723 Generics,
725 Binder,
727}
728
729#[derive(Default)]
730pub struct GenericParamCount {
731 pub lifetimes: usize,
732 pub types: usize,
733 pub consts: usize,
734 pub infer: usize,
735}
736
737#[derive(Debug, Clone, Copy, HashStable_Generic)]
740pub struct Generics<'hir> {
741 pub params: &'hir [GenericParam<'hir>],
742 pub predicates: &'hir [WherePredicate<'hir>],
743 pub has_where_clause_predicates: bool,
744 pub where_clause_span: Span,
745 pub span: Span,
746}
747
748impl<'hir> Generics<'hir> {
749 pub const fn empty() -> &'hir Generics<'hir> {
750 const NOPE: Generics<'_> = Generics {
751 params: &[],
752 predicates: &[],
753 has_where_clause_predicates: false,
754 where_clause_span: DUMMY_SP,
755 span: DUMMY_SP,
756 };
757 &NOPE
758 }
759
760 pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
761 self.params.iter().find(|¶m| name == param.name.ident().name)
762 }
763
764 pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
766 if let Some(first) = self.params.first()
767 && self.span.contains(first.span)
768 {
769 Some(first.span.shrink_to_lo())
772 } else {
773 None
774 }
775 }
776
777 pub fn span_for_param_suggestion(&self) -> Option<Span> {
779 self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
780 self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
783 })
784 }
785
786 pub fn tail_span_for_predicate_suggestion(&self) -> Span {
789 let end = self.where_clause_span.shrink_to_hi();
790 if self.has_where_clause_predicates {
791 self.predicates
792 .iter()
793 .rfind(|&p| p.kind.in_where_clause())
794 .map_or(end, |p| p.span)
795 .shrink_to_hi()
796 .to(end)
797 } else {
798 end
799 }
800 }
801
802 pub fn add_where_or_trailing_comma(&self) -> &'static str {
803 if self.has_where_clause_predicates {
804 ","
805 } else if self.where_clause_span.is_empty() {
806 " where"
807 } else {
808 ""
810 }
811 }
812
813 pub fn bounds_for_param(
814 &self,
815 param_def_id: LocalDefId,
816 ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
817 self.predicates.iter().filter_map(move |pred| match pred.kind {
818 WherePredicateKind::BoundPredicate(bp)
819 if bp.is_param_bound(param_def_id.to_def_id()) =>
820 {
821 Some(bp)
822 }
823 _ => None,
824 })
825 }
826
827 pub fn outlives_for_param(
828 &self,
829 param_def_id: LocalDefId,
830 ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
831 self.predicates.iter().filter_map(move |pred| match pred.kind {
832 WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
833 _ => None,
834 })
835 }
836
837 pub fn bounds_span_for_suggestions(
848 &self,
849 param_def_id: LocalDefId,
850 ) -> Option<(Span, Option<Span>)> {
851 self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
852 |bound| {
853 let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
854 && let [.., segment] = trait_ref.path.segments
855 && let Some(ret_ty) = segment.args().paren_sugar_output()
856 && let ret_ty = ret_ty.peel_refs()
857 && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
858 && let TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar = tagged_ptr.tag()
859 && ret_ty.span.can_be_used_for_suggestions()
860 {
861 Some(ret_ty.span)
862 } else {
863 None
864 };
865
866 span_for_parentheses.map_or_else(
867 || {
868 let bs = bound.span();
871 bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
872 },
873 |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
874 )
875 },
876 )
877 }
878
879 pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
880 let predicate = &self.predicates[pos];
881 let span = predicate.span;
882
883 if !predicate.kind.in_where_clause() {
884 return span;
887 }
888
889 if pos < self.predicates.len() - 1 {
891 let next_pred = &self.predicates[pos + 1];
892 if next_pred.kind.in_where_clause() {
893 return span.until(next_pred.span);
896 }
897 }
898
899 if pos > 0 {
900 let prev_pred = &self.predicates[pos - 1];
901 if prev_pred.kind.in_where_clause() {
902 return prev_pred.span.shrink_to_hi().to(span);
905 }
906 }
907
908 self.where_clause_span
912 }
913
914 pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
915 let predicate = &self.predicates[predicate_pos];
916 let bounds = predicate.kind.bounds();
917
918 if bounds.len() == 1 {
919 return self.span_for_predicate_removal(predicate_pos);
920 }
921
922 let bound_span = bounds[bound_pos].span();
923 if bound_pos < bounds.len() - 1 {
924 bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
930 } else {
931 bound_span.with_lo(bounds[bound_pos - 1].span().hi())
937 }
938 }
939}
940
941#[derive(Debug, Clone, Copy, HashStable_Generic)]
943pub struct WherePredicate<'hir> {
944 #[stable_hasher(ignore)]
945 pub hir_id: HirId,
946 pub span: Span,
947 pub kind: &'hir WherePredicateKind<'hir>,
948}
949
950#[derive(Debug, Clone, Copy, HashStable_Generic)]
952pub enum WherePredicateKind<'hir> {
953 BoundPredicate(WhereBoundPredicate<'hir>),
955 RegionPredicate(WhereRegionPredicate<'hir>),
957 EqPredicate(WhereEqPredicate<'hir>),
959}
960
961impl<'hir> WherePredicateKind<'hir> {
962 pub fn in_where_clause(&self) -> bool {
963 match self {
964 WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
965 WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
966 WherePredicateKind::EqPredicate(_) => false,
967 }
968 }
969
970 pub fn bounds(&self) -> GenericBounds<'hir> {
971 match self {
972 WherePredicateKind::BoundPredicate(p) => p.bounds,
973 WherePredicateKind::RegionPredicate(p) => p.bounds,
974 WherePredicateKind::EqPredicate(_) => &[],
975 }
976 }
977}
978
979#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
980pub enum PredicateOrigin {
981 WhereClause,
982 GenericParam,
983 ImplTrait,
984}
985
986#[derive(Debug, Clone, Copy, HashStable_Generic)]
988pub struct WhereBoundPredicate<'hir> {
989 pub origin: PredicateOrigin,
991 pub bound_generic_params: &'hir [GenericParam<'hir>],
993 pub bounded_ty: &'hir Ty<'hir>,
995 pub bounds: GenericBounds<'hir>,
997}
998
999impl<'hir> WhereBoundPredicate<'hir> {
1000 pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
1002 self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
1003 }
1004}
1005
1006#[derive(Debug, Clone, Copy, HashStable_Generic)]
1008pub struct WhereRegionPredicate<'hir> {
1009 pub in_where_clause: bool,
1010 pub lifetime: &'hir Lifetime,
1011 pub bounds: GenericBounds<'hir>,
1012}
1013
1014impl<'hir> WhereRegionPredicate<'hir> {
1015 fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
1017 self.lifetime.res == LifetimeName::Param(param_def_id)
1018 }
1019}
1020
1021#[derive(Debug, Clone, Copy, HashStable_Generic)]
1023pub struct WhereEqPredicate<'hir> {
1024 pub lhs_ty: &'hir Ty<'hir>,
1025 pub rhs_ty: &'hir Ty<'hir>,
1026}
1027
1028#[derive(Clone, Copy, Debug)]
1032pub struct ParentedNode<'tcx> {
1033 pub parent: ItemLocalId,
1034 pub node: Node<'tcx>,
1035}
1036
1037#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1039pub enum AttrArgs {
1040 Empty,
1042 Delimited(DelimArgs),
1044 Eq {
1046 eq_span: Span,
1048 expr: MetaItemLit,
1050 },
1051}
1052
1053#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1054pub struct AttrPath {
1055 pub segments: Box<[Ident]>,
1056 pub span: Span,
1057}
1058
1059impl AttrPath {
1060 pub fn from_ast(path: &ast::Path) -> Self {
1061 AttrPath {
1062 segments: path.segments.iter().map(|i| i.ident).collect::<Vec<_>>().into_boxed_slice(),
1063 span: path.span,
1064 }
1065 }
1066}
1067
1068impl fmt::Display for AttrPath {
1069 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1070 write!(f, "{}", self.segments.iter().map(|i| i.to_string()).collect::<Vec<_>>().join("::"))
1071 }
1072}
1073
1074#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
1075pub struct AttrItem {
1076 pub path: AttrPath,
1078 pub args: AttrArgs,
1079 pub id: HashIgnoredAttrId,
1080 pub style: AttrStyle,
1083 pub span: Span,
1085}
1086
1087#[derive(Copy, Debug, Encodable, Decodable, Clone)]
1090pub struct HashIgnoredAttrId {
1091 pub attr_id: AttrId,
1092}
1093
1094#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
1095pub enum Attribute {
1096 Parsed(AttributeKind),
1102
1103 Unparsed(Box<AttrItem>),
1106}
1107
1108impl Attribute {
1109 pub fn get_normal_item(&self) -> &AttrItem {
1110 match &self {
1111 Attribute::Unparsed(normal) => &normal,
1112 _ => panic!("unexpected parsed attribute"),
1113 }
1114 }
1115
1116 pub fn unwrap_normal_item(self) -> AttrItem {
1117 match self {
1118 Attribute::Unparsed(normal) => *normal,
1119 _ => panic!("unexpected parsed attribute"),
1120 }
1121 }
1122
1123 pub fn value_lit(&self) -> Option<&MetaItemLit> {
1124 match &self {
1125 Attribute::Unparsed(n) => match n.as_ref() {
1126 AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1127 _ => None,
1128 },
1129 _ => None,
1130 }
1131 }
1132}
1133
1134impl AttributeExt for Attribute {
1135 #[inline]
1136 fn id(&self) -> AttrId {
1137 match &self {
1138 Attribute::Unparsed(u) => u.id.attr_id,
1139 _ => panic!(),
1140 }
1141 }
1142
1143 #[inline]
1144 fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1145 match &self {
1146 Attribute::Unparsed(n) => match n.as_ref() {
1147 AttrItem { args: AttrArgs::Delimited(d), .. } => {
1148 ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1149 }
1150 _ => None,
1151 },
1152 _ => None,
1153 }
1154 }
1155
1156 #[inline]
1157 fn value_str(&self) -> Option<Symbol> {
1158 self.value_lit().and_then(|x| x.value_str())
1159 }
1160
1161 #[inline]
1162 fn value_span(&self) -> Option<Span> {
1163 self.value_lit().map(|i| i.span)
1164 }
1165
1166 #[inline]
1168 fn ident(&self) -> Option<Ident> {
1169 match &self {
1170 Attribute::Unparsed(n) => {
1171 if let [ident] = n.path.segments.as_ref() {
1172 Some(*ident)
1173 } else {
1174 None
1175 }
1176 }
1177 _ => None,
1178 }
1179 }
1180
1181 #[inline]
1182 fn path_matches(&self, name: &[Symbol]) -> bool {
1183 match &self {
1184 Attribute::Unparsed(n) => {
1185 n.path.segments.len() == name.len()
1186 && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
1187 }
1188 _ => false,
1189 }
1190 }
1191
1192 #[inline]
1193 fn is_doc_comment(&self) -> bool {
1194 matches!(self, Attribute::Parsed(AttributeKind::DocComment { .. }))
1195 }
1196
1197 #[inline]
1198 fn span(&self) -> Span {
1199 match &self {
1200 Attribute::Unparsed(u) => u.span,
1201 Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
1203 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
1204 a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
1205 }
1206 }
1207
1208 #[inline]
1209 fn is_word(&self) -> bool {
1210 match &self {
1211 Attribute::Unparsed(n) => {
1212 matches!(n.args, AttrArgs::Empty)
1213 }
1214 _ => false,
1215 }
1216 }
1217
1218 #[inline]
1219 fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1220 match &self {
1221 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
1222 _ => None,
1223 }
1224 }
1225
1226 #[inline]
1227 fn doc_str(&self) -> Option<Symbol> {
1228 match &self {
1229 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
1230 Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(),
1231 _ => None,
1232 }
1233 }
1234 #[inline]
1235 fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1236 match &self {
1237 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
1238 Some((*comment, *kind))
1239 }
1240 Attribute::Unparsed(_) if self.name_or_empty() == sym::doc => {
1241 self.value_str().map(|s| (s, CommentKind::Line))
1242 }
1243 _ => None,
1244 }
1245 }
1246
1247 #[inline]
1248 fn style(&self) -> AttrStyle {
1249 match &self {
1250 Attribute::Unparsed(u) => u.style,
1251 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => *style,
1252 _ => panic!(),
1253 }
1254 }
1255}
1256
1257impl Attribute {
1259 #[inline]
1260 pub fn id(&self) -> AttrId {
1261 AttributeExt::id(self)
1262 }
1263
1264 #[inline]
1265 pub fn name_or_empty(&self) -> Symbol {
1266 AttributeExt::name_or_empty(self)
1267 }
1268
1269 #[inline]
1270 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1271 AttributeExt::meta_item_list(self)
1272 }
1273
1274 #[inline]
1275 pub fn value_str(&self) -> Option<Symbol> {
1276 AttributeExt::value_str(self)
1277 }
1278
1279 #[inline]
1280 pub fn value_span(&self) -> Option<Span> {
1281 AttributeExt::value_span(self)
1282 }
1283
1284 #[inline]
1285 pub fn ident(&self) -> Option<Ident> {
1286 AttributeExt::ident(self)
1287 }
1288
1289 #[inline]
1290 pub fn path_matches(&self, name: &[Symbol]) -> bool {
1291 AttributeExt::path_matches(self, name)
1292 }
1293
1294 #[inline]
1295 pub fn is_doc_comment(&self) -> bool {
1296 AttributeExt::is_doc_comment(self)
1297 }
1298
1299 #[inline]
1300 pub fn has_name(&self, name: Symbol) -> bool {
1301 AttributeExt::has_name(self, name)
1302 }
1303
1304 #[inline]
1305 pub fn span(&self) -> Span {
1306 AttributeExt::span(self)
1307 }
1308
1309 #[inline]
1310 pub fn is_word(&self) -> bool {
1311 AttributeExt::is_word(self)
1312 }
1313
1314 #[inline]
1315 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1316 AttributeExt::path(self)
1317 }
1318
1319 #[inline]
1320 pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1321 AttributeExt::ident_path(self)
1322 }
1323
1324 #[inline]
1325 pub fn doc_str(&self) -> Option<Symbol> {
1326 AttributeExt::doc_str(self)
1327 }
1328
1329 #[inline]
1330 pub fn is_proc_macro_attr(&self) -> bool {
1331 AttributeExt::is_proc_macro_attr(self)
1332 }
1333
1334 #[inline]
1335 pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1336 AttributeExt::doc_str_and_comment_kind(self)
1337 }
1338
1339 #[inline]
1340 pub fn style(&self) -> AttrStyle {
1341 AttributeExt::style(self)
1342 }
1343}
1344
1345#[derive(Debug)]
1347pub struct AttributeMap<'tcx> {
1348 pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
1349 pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
1351 pub opt_hash: Option<Fingerprint>,
1353}
1354
1355impl<'tcx> AttributeMap<'tcx> {
1356 pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
1357 map: SortedMap::new(),
1358 opt_hash: Some(Fingerprint::ZERO),
1359 define_opaque: None,
1360 };
1361
1362 #[inline]
1363 pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
1364 self.map.get(&id).copied().unwrap_or(&[])
1365 }
1366}
1367
1368pub struct OwnerNodes<'tcx> {
1372 pub opt_hash_including_bodies: Option<Fingerprint>,
1375 pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
1380 pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
1382}
1383
1384impl<'tcx> OwnerNodes<'tcx> {
1385 pub fn node(&self) -> OwnerNode<'tcx> {
1386 self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
1388 }
1389}
1390
1391impl fmt::Debug for OwnerNodes<'_> {
1392 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393 f.debug_struct("OwnerNodes")
1394 .field("node", &self.nodes[ItemLocalId::ZERO])
1396 .field(
1397 "parents",
1398 &fmt::from_fn(|f| {
1399 f.debug_list()
1400 .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
1401 fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
1402 }))
1403 .finish()
1404 }),
1405 )
1406 .field("bodies", &self.bodies)
1407 .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
1408 .finish()
1409 }
1410}
1411
1412#[derive(Debug, HashStable_Generic)]
1414pub struct OwnerInfo<'hir> {
1415 pub nodes: OwnerNodes<'hir>,
1417 pub parenting: LocalDefIdMap<ItemLocalId>,
1419 pub attrs: AttributeMap<'hir>,
1421 pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
1424}
1425
1426impl<'tcx> OwnerInfo<'tcx> {
1427 #[inline]
1428 pub fn node(&self) -> OwnerNode<'tcx> {
1429 self.nodes.node()
1430 }
1431}
1432
1433#[derive(Copy, Clone, Debug, HashStable_Generic)]
1434pub enum MaybeOwner<'tcx> {
1435 Owner(&'tcx OwnerInfo<'tcx>),
1436 NonOwner(HirId),
1437 Phantom,
1439}
1440
1441impl<'tcx> MaybeOwner<'tcx> {
1442 pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
1443 match self {
1444 MaybeOwner::Owner(i) => Some(i),
1445 MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1446 }
1447 }
1448
1449 pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1450 self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1451 }
1452}
1453
1454#[derive(Debug)]
1461pub struct Crate<'hir> {
1462 pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
1463 pub opt_hir_hash: Option<Fingerprint>,
1465}
1466
1467#[derive(Debug, Clone, Copy, HashStable_Generic)]
1468pub struct Closure<'hir> {
1469 pub def_id: LocalDefId,
1470 pub binder: ClosureBinder,
1471 pub constness: Constness,
1472 pub capture_clause: CaptureBy,
1473 pub bound_generic_params: &'hir [GenericParam<'hir>],
1474 pub fn_decl: &'hir FnDecl<'hir>,
1475 pub body: BodyId,
1476 pub fn_decl_span: Span,
1478 pub fn_arg_span: Option<Span>,
1480 pub kind: ClosureKind,
1481}
1482
1483#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1484pub enum ClosureKind {
1485 Closure,
1487 Coroutine(CoroutineKind),
1492 CoroutineClosure(CoroutineDesugaring),
1497}
1498
1499#[derive(Debug, Clone, Copy, HashStable_Generic)]
1503pub struct Block<'hir> {
1504 pub stmts: &'hir [Stmt<'hir>],
1506 pub expr: Option<&'hir Expr<'hir>>,
1509 #[stable_hasher(ignore)]
1510 pub hir_id: HirId,
1511 pub rules: BlockCheckMode,
1513 pub span: Span,
1515 pub targeted_by_break: bool,
1519}
1520
1521impl<'hir> Block<'hir> {
1522 pub fn innermost_block(&self) -> &Block<'hir> {
1523 let mut block = self;
1524 while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
1525 block = inner_block;
1526 }
1527 block
1528 }
1529}
1530
1531#[derive(Debug, Clone, Copy, HashStable_Generic)]
1532pub struct TyPat<'hir> {
1533 #[stable_hasher(ignore)]
1534 pub hir_id: HirId,
1535 pub kind: TyPatKind<'hir>,
1536 pub span: Span,
1537}
1538
1539#[derive(Debug, Clone, Copy, HashStable_Generic)]
1540pub struct Pat<'hir> {
1541 #[stable_hasher(ignore)]
1542 pub hir_id: HirId,
1543 pub kind: PatKind<'hir>,
1544 pub span: Span,
1545 pub default_binding_modes: bool,
1548}
1549
1550impl<'hir> Pat<'hir> {
1551 fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
1552 if !it(self) {
1553 return false;
1554 }
1555
1556 use PatKind::*;
1557 match self.kind {
1558 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
1559 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
1560 Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1561 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1562 Slice(before, slice, after) => {
1563 before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1564 }
1565 }
1566 }
1567
1568 pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1575 self.walk_short_(&mut it)
1576 }
1577
1578 fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1579 if !it(self) {
1580 return;
1581 }
1582
1583 use PatKind::*;
1584 match self.kind {
1585 Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
1586 Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
1587 Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1588 TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1589 Slice(before, slice, after) => {
1590 before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1591 }
1592 }
1593 }
1594
1595 pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1599 self.walk_(&mut it)
1600 }
1601
1602 pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
1606 self.walk(|p| {
1607 it(p);
1608 true
1609 })
1610 }
1611
1612 pub fn is_never_pattern(&self) -> bool {
1614 let mut is_never_pattern = false;
1615 self.walk(|pat| match &pat.kind {
1616 PatKind::Never => {
1617 is_never_pattern = true;
1618 false
1619 }
1620 PatKind::Or(s) => {
1621 is_never_pattern = s.iter().all(|p| p.is_never_pattern());
1622 false
1623 }
1624 _ => true,
1625 });
1626 is_never_pattern
1627 }
1628}
1629
1630#[derive(Debug, Clone, Copy, HashStable_Generic)]
1636pub struct PatField<'hir> {
1637 #[stable_hasher(ignore)]
1638 pub hir_id: HirId,
1639 pub ident: Ident,
1641 pub pat: &'hir Pat<'hir>,
1643 pub is_shorthand: bool,
1644 pub span: Span,
1645}
1646
1647#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
1648pub enum RangeEnd {
1649 Included,
1650 Excluded,
1651}
1652
1653impl fmt::Display for RangeEnd {
1654 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1655 f.write_str(match self {
1656 RangeEnd::Included => "..=",
1657 RangeEnd::Excluded => "..",
1658 })
1659 }
1660}
1661
1662#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
1666pub struct DotDotPos(u32);
1667
1668impl DotDotPos {
1669 pub fn new(n: Option<usize>) -> Self {
1671 match n {
1672 Some(n) => {
1673 assert!(n < u32::MAX as usize);
1674 Self(n as u32)
1675 }
1676 None => Self(u32::MAX),
1677 }
1678 }
1679
1680 pub fn as_opt_usize(&self) -> Option<usize> {
1681 if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
1682 }
1683}
1684
1685impl fmt::Debug for DotDotPos {
1686 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1687 self.as_opt_usize().fmt(f)
1688 }
1689}
1690
1691#[derive(Debug, Clone, Copy, HashStable_Generic)]
1692pub struct PatExpr<'hir> {
1693 #[stable_hasher(ignore)]
1694 pub hir_id: HirId,
1695 pub span: Span,
1696 pub kind: PatExprKind<'hir>,
1697}
1698
1699#[derive(Debug, Clone, Copy, HashStable_Generic)]
1700pub enum PatExprKind<'hir> {
1701 Lit {
1702 lit: &'hir Lit,
1703 negated: bool,
1706 },
1707 ConstBlock(ConstBlock),
1708 Path(QPath<'hir>),
1710}
1711
1712#[derive(Debug, Clone, Copy, HashStable_Generic)]
1713pub enum TyPatKind<'hir> {
1714 Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
1716
1717 Err(ErrorGuaranteed),
1719}
1720
1721#[derive(Debug, Clone, Copy, HashStable_Generic)]
1722pub enum PatKind<'hir> {
1723 Wild,
1725
1726 Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
1737
1738 Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
1741
1742 TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
1746
1747 Or(&'hir [Pat<'hir>]),
1750
1751 Never,
1753
1754 Tuple(&'hir [Pat<'hir>], DotDotPos),
1758
1759 Box(&'hir Pat<'hir>),
1761
1762 Deref(&'hir Pat<'hir>),
1764
1765 Ref(&'hir Pat<'hir>, Mutability),
1767
1768 Expr(&'hir PatExpr<'hir>),
1770
1771 Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
1773
1774 Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
1776
1777 Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
1787
1788 Err(ErrorGuaranteed),
1790}
1791
1792#[derive(Debug, Clone, Copy, HashStable_Generic)]
1794pub struct Stmt<'hir> {
1795 #[stable_hasher(ignore)]
1796 pub hir_id: HirId,
1797 pub kind: StmtKind<'hir>,
1798 pub span: Span,
1799}
1800
1801#[derive(Debug, Clone, Copy, HashStable_Generic)]
1803pub enum StmtKind<'hir> {
1804 Let(&'hir LetStmt<'hir>),
1806
1807 Item(ItemId),
1809
1810 Expr(&'hir Expr<'hir>),
1812
1813 Semi(&'hir Expr<'hir>),
1815}
1816
1817#[derive(Debug, Clone, Copy, HashStable_Generic)]
1819pub struct LetStmt<'hir> {
1820 pub pat: &'hir Pat<'hir>,
1821 pub ty: Option<&'hir Ty<'hir>>,
1823 pub init: Option<&'hir Expr<'hir>>,
1825 pub els: Option<&'hir Block<'hir>>,
1827 #[stable_hasher(ignore)]
1828 pub hir_id: HirId,
1829 pub span: Span,
1830 pub source: LocalSource,
1834}
1835
1836#[derive(Debug, Clone, Copy, HashStable_Generic)]
1839pub struct Arm<'hir> {
1840 #[stable_hasher(ignore)]
1841 pub hir_id: HirId,
1842 pub span: Span,
1843 pub pat: &'hir Pat<'hir>,
1845 pub guard: Option<&'hir Expr<'hir>>,
1847 pub body: &'hir Expr<'hir>,
1849}
1850
1851#[derive(Debug, Clone, Copy, HashStable_Generic)]
1857pub struct LetExpr<'hir> {
1858 pub span: Span,
1859 pub pat: &'hir Pat<'hir>,
1860 pub ty: Option<&'hir Ty<'hir>>,
1861 pub init: &'hir Expr<'hir>,
1862 pub recovered: ast::Recovered,
1865}
1866
1867#[derive(Debug, Clone, Copy, HashStable_Generic)]
1868pub struct ExprField<'hir> {
1869 #[stable_hasher(ignore)]
1870 pub hir_id: HirId,
1871 pub ident: Ident,
1872 pub expr: &'hir Expr<'hir>,
1873 pub span: Span,
1874 pub is_shorthand: bool,
1875}
1876
1877#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1878pub enum BlockCheckMode {
1879 DefaultBlock,
1880 UnsafeBlock(UnsafeSource),
1881}
1882
1883#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
1884pub enum UnsafeSource {
1885 CompilerGenerated,
1886 UserProvided,
1887}
1888
1889#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
1890pub struct BodyId {
1891 pub hir_id: HirId,
1892}
1893
1894#[derive(Debug, Clone, Copy, HashStable_Generic)]
1916pub struct Body<'hir> {
1917 pub params: &'hir [Param<'hir>],
1918 pub value: &'hir Expr<'hir>,
1919}
1920
1921impl<'hir> Body<'hir> {
1922 pub fn id(&self) -> BodyId {
1923 BodyId { hir_id: self.value.hir_id }
1924 }
1925}
1926
1927#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1929pub enum CoroutineKind {
1930 Desugared(CoroutineDesugaring, CoroutineSource),
1932
1933 Coroutine(Movability),
1935}
1936
1937impl CoroutineKind {
1938 pub fn movability(self) -> Movability {
1939 match self {
1940 CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
1941 | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
1942 CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
1943 CoroutineKind::Coroutine(mov) => mov,
1944 }
1945 }
1946}
1947
1948impl CoroutineKind {
1949 pub fn is_fn_like(self) -> bool {
1950 matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
1951 }
1952}
1953
1954impl fmt::Display for CoroutineKind {
1955 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1956 match self {
1957 CoroutineKind::Desugared(d, k) => {
1958 d.fmt(f)?;
1959 k.fmt(f)
1960 }
1961 CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
1962 }
1963 }
1964}
1965
1966#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
1972pub enum CoroutineSource {
1973 Block,
1975
1976 Closure,
1978
1979 Fn,
1981}
1982
1983impl fmt::Display for CoroutineSource {
1984 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1985 match self {
1986 CoroutineSource::Block => "block",
1987 CoroutineSource::Closure => "closure body",
1988 CoroutineSource::Fn => "fn body",
1989 }
1990 .fmt(f)
1991 }
1992}
1993
1994#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
1995pub enum CoroutineDesugaring {
1996 Async,
1998
1999 Gen,
2001
2002 AsyncGen,
2005}
2006
2007impl fmt::Display for CoroutineDesugaring {
2008 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2009 match self {
2010 CoroutineDesugaring::Async => {
2011 if f.alternate() {
2012 f.write_str("`async` ")?;
2013 } else {
2014 f.write_str("async ")?
2015 }
2016 }
2017 CoroutineDesugaring::Gen => {
2018 if f.alternate() {
2019 f.write_str("`gen` ")?;
2020 } else {
2021 f.write_str("gen ")?
2022 }
2023 }
2024 CoroutineDesugaring::AsyncGen => {
2025 if f.alternate() {
2026 f.write_str("`async gen` ")?;
2027 } else {
2028 f.write_str("async gen ")?
2029 }
2030 }
2031 }
2032
2033 Ok(())
2034 }
2035}
2036
2037#[derive(Copy, Clone, Debug)]
2038pub enum BodyOwnerKind {
2039 Fn,
2041
2042 Closure,
2044
2045 Const { inline: bool },
2047
2048 Static(Mutability),
2050
2051 GlobalAsm,
2053}
2054
2055impl BodyOwnerKind {
2056 pub fn is_fn_or_closure(self) -> bool {
2057 match self {
2058 BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
2059 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
2060 false
2061 }
2062 }
2063 }
2064}
2065
2066#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2068pub enum ConstContext {
2069 ConstFn,
2071
2072 Static(Mutability),
2074
2075 Const { inline: bool },
2085}
2086
2087impl ConstContext {
2088 pub fn keyword_name(self) -> &'static str {
2092 match self {
2093 Self::Const { .. } => "const",
2094 Self::Static(Mutability::Not) => "static",
2095 Self::Static(Mutability::Mut) => "static mut",
2096 Self::ConstFn => "const fn",
2097 }
2098 }
2099}
2100
2101impl fmt::Display for ConstContext {
2104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2105 match *self {
2106 Self::Const { .. } => write!(f, "constant"),
2107 Self::Static(_) => write!(f, "static"),
2108 Self::ConstFn => write!(f, "constant function"),
2109 }
2110 }
2111}
2112
2113pub type Lit = Spanned<LitKind>;
2118
2119#[derive(Copy, Clone, Debug, HashStable_Generic)]
2128pub struct AnonConst {
2129 #[stable_hasher(ignore)]
2130 pub hir_id: HirId,
2131 pub def_id: LocalDefId,
2132 pub body: BodyId,
2133 pub span: Span,
2134}
2135
2136#[derive(Copy, Clone, Debug, HashStable_Generic)]
2138pub struct ConstBlock {
2139 #[stable_hasher(ignore)]
2140 pub hir_id: HirId,
2141 pub def_id: LocalDefId,
2142 pub body: BodyId,
2143}
2144
2145#[derive(Debug, Clone, Copy, HashStable_Generic)]
2154pub struct Expr<'hir> {
2155 #[stable_hasher(ignore)]
2156 pub hir_id: HirId,
2157 pub kind: ExprKind<'hir>,
2158 pub span: Span,
2159}
2160
2161impl Expr<'_> {
2162 pub fn precedence(&self) -> ExprPrecedence {
2163 match &self.kind {
2164 ExprKind::Closure(closure) => {
2165 match closure.fn_decl.output {
2166 FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
2167 FnRetTy::Return(_) => ExprPrecedence::Unambiguous,
2168 }
2169 }
2170
2171 ExprKind::Break(..)
2172 | ExprKind::Ret(..)
2173 | ExprKind::Yield(..)
2174 | ExprKind::Become(..) => ExprPrecedence::Jump,
2175
2176 ExprKind::Binary(op, ..) => op.node.precedence(),
2178 ExprKind::Cast(..) => ExprPrecedence::Cast,
2179
2180 ExprKind::Assign(..) |
2181 ExprKind::AssignOp(..) => ExprPrecedence::Assign,
2182
2183 ExprKind::AddrOf(..)
2185 | ExprKind::Let(..)
2190 | ExprKind::Unary(..) => ExprPrecedence::Prefix,
2191
2192 ExprKind::Array(_)
2194 | ExprKind::Block(..)
2195 | ExprKind::Call(..)
2196 | ExprKind::ConstBlock(_)
2197 | ExprKind::Continue(..)
2198 | ExprKind::Field(..)
2199 | ExprKind::If(..)
2200 | ExprKind::Index(..)
2201 | ExprKind::InlineAsm(..)
2202 | ExprKind::Lit(_)
2203 | ExprKind::Loop(..)
2204 | ExprKind::Match(..)
2205 | ExprKind::MethodCall(..)
2206 | ExprKind::OffsetOf(..)
2207 | ExprKind::Path(..)
2208 | ExprKind::Repeat(..)
2209 | ExprKind::Struct(..)
2210 | ExprKind::Tup(_)
2211 | ExprKind::Type(..)
2212 | ExprKind::UnsafeBinderCast(..)
2213 | ExprKind::Use(..)
2214 | ExprKind::Err(_) => ExprPrecedence::Unambiguous,
2215
2216 ExprKind::DropTemps(expr, ..) => expr.precedence(),
2217 }
2218 }
2219
2220 pub fn is_syntactic_place_expr(&self) -> bool {
2225 self.is_place_expr(|_| true)
2226 }
2227
2228 pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
2233 match self.kind {
2234 ExprKind::Path(QPath::Resolved(_, ref path)) => {
2235 matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
2236 }
2237
2238 ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),
2242
2243 ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),
2245
2246 ExprKind::Unary(UnOp::Deref, _) => true,
2247
2248 ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
2249 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
2250 }
2251
2252 ExprKind::Path(QPath::LangItem(..)) => false,
2254
2255 ExprKind::Path(QPath::TypeRelative(..))
2258 | ExprKind::Call(..)
2259 | ExprKind::MethodCall(..)
2260 | ExprKind::Use(..)
2261 | ExprKind::Struct(..)
2262 | ExprKind::Tup(..)
2263 | ExprKind::If(..)
2264 | ExprKind::Match(..)
2265 | ExprKind::Closure { .. }
2266 | ExprKind::Block(..)
2267 | ExprKind::Repeat(..)
2268 | ExprKind::Array(..)
2269 | ExprKind::Break(..)
2270 | ExprKind::Continue(..)
2271 | ExprKind::Ret(..)
2272 | ExprKind::Become(..)
2273 | ExprKind::Let(..)
2274 | ExprKind::Loop(..)
2275 | ExprKind::Assign(..)
2276 | ExprKind::InlineAsm(..)
2277 | ExprKind::OffsetOf(..)
2278 | ExprKind::AssignOp(..)
2279 | ExprKind::Lit(_)
2280 | ExprKind::ConstBlock(..)
2281 | ExprKind::Unary(..)
2282 | ExprKind::AddrOf(..)
2283 | ExprKind::Binary(..)
2284 | ExprKind::Yield(..)
2285 | ExprKind::Cast(..)
2286 | ExprKind::DropTemps(..)
2287 | ExprKind::Err(_) => false,
2288 }
2289 }
2290
2291 pub fn is_size_lit(&self) -> bool {
2294 matches!(
2295 self.kind,
2296 ExprKind::Lit(Lit {
2297 node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2298 ..
2299 })
2300 )
2301 }
2302
2303 pub fn peel_drop_temps(&self) -> &Self {
2309 let mut expr = self;
2310 while let ExprKind::DropTemps(inner) = &expr.kind {
2311 expr = inner;
2312 }
2313 expr
2314 }
2315
2316 pub fn peel_blocks(&self) -> &Self {
2317 let mut expr = self;
2318 while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
2319 expr = inner;
2320 }
2321 expr
2322 }
2323
2324 pub fn peel_borrows(&self) -> &Self {
2325 let mut expr = self;
2326 while let ExprKind::AddrOf(.., inner) = &expr.kind {
2327 expr = inner;
2328 }
2329 expr
2330 }
2331
2332 pub fn can_have_side_effects(&self) -> bool {
2333 match self.peel_drop_temps().kind {
2334 ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2335 false
2336 }
2337 ExprKind::Type(base, _)
2338 | ExprKind::Unary(_, base)
2339 | ExprKind::Field(base, _)
2340 | ExprKind::Index(base, _, _)
2341 | ExprKind::AddrOf(.., base)
2342 | ExprKind::Cast(base, _)
2343 | ExprKind::UnsafeBinderCast(_, base, _) => {
2344 base.can_have_side_effects()
2348 }
2349 ExprKind::Struct(_, fields, init) => {
2350 let init_side_effects = match init {
2351 StructTailExpr::Base(init) => init.can_have_side_effects(),
2352 StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
2353 };
2354 fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
2355 || init_side_effects
2356 }
2357
2358 ExprKind::Array(args)
2359 | ExprKind::Tup(args)
2360 | ExprKind::Call(
2361 Expr {
2362 kind:
2363 ExprKind::Path(QPath::Resolved(
2364 None,
2365 Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
2366 )),
2367 ..
2368 },
2369 args,
2370 ) => args.iter().any(|arg| arg.can_have_side_effects()),
2371 ExprKind::If(..)
2372 | ExprKind::Match(..)
2373 | ExprKind::MethodCall(..)
2374 | ExprKind::Call(..)
2375 | ExprKind::Closure { .. }
2376 | ExprKind::Block(..)
2377 | ExprKind::Repeat(..)
2378 | ExprKind::Break(..)
2379 | ExprKind::Continue(..)
2380 | ExprKind::Ret(..)
2381 | ExprKind::Become(..)
2382 | ExprKind::Let(..)
2383 | ExprKind::Loop(..)
2384 | ExprKind::Assign(..)
2385 | ExprKind::InlineAsm(..)
2386 | ExprKind::AssignOp(..)
2387 | ExprKind::ConstBlock(..)
2388 | ExprKind::Binary(..)
2389 | ExprKind::Yield(..)
2390 | ExprKind::DropTemps(..)
2391 | ExprKind::Err(_) => true,
2392 }
2393 }
2394
2395 pub fn is_approximately_pattern(&self) -> bool {
2397 match &self.kind {
2398 ExprKind::Array(_)
2399 | ExprKind::Call(..)
2400 | ExprKind::Tup(_)
2401 | ExprKind::Lit(_)
2402 | ExprKind::Path(_)
2403 | ExprKind::Struct(..) => true,
2404 _ => false,
2405 }
2406 }
2407
2408 pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
2413 match (self.kind, other.kind) {
2414 (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
2415 (
2416 ExprKind::Path(QPath::LangItem(item1, _)),
2417 ExprKind::Path(QPath::LangItem(item2, _)),
2418 ) => item1 == item2,
2419 (
2420 ExprKind::Path(QPath::Resolved(None, path1)),
2421 ExprKind::Path(QPath::Resolved(None, path2)),
2422 ) => path1.res == path2.res,
2423 (
2424 ExprKind::Struct(
2425 QPath::LangItem(LangItem::RangeTo, _),
2426 [val1],
2427 StructTailExpr::None,
2428 ),
2429 ExprKind::Struct(
2430 QPath::LangItem(LangItem::RangeTo, _),
2431 [val2],
2432 StructTailExpr::None,
2433 ),
2434 )
2435 | (
2436 ExprKind::Struct(
2437 QPath::LangItem(LangItem::RangeToInclusive, _),
2438 [val1],
2439 StructTailExpr::None,
2440 ),
2441 ExprKind::Struct(
2442 QPath::LangItem(LangItem::RangeToInclusive, _),
2443 [val2],
2444 StructTailExpr::None,
2445 ),
2446 )
2447 | (
2448 ExprKind::Struct(
2449 QPath::LangItem(LangItem::RangeFrom, _),
2450 [val1],
2451 StructTailExpr::None,
2452 ),
2453 ExprKind::Struct(
2454 QPath::LangItem(LangItem::RangeFrom, _),
2455 [val2],
2456 StructTailExpr::None,
2457 ),
2458 )
2459 | (
2460 ExprKind::Struct(
2461 QPath::LangItem(LangItem::RangeFromCopy, _),
2462 [val1],
2463 StructTailExpr::None,
2464 ),
2465 ExprKind::Struct(
2466 QPath::LangItem(LangItem::RangeFromCopy, _),
2467 [val2],
2468 StructTailExpr::None,
2469 ),
2470 ) => val1.expr.equivalent_for_indexing(val2.expr),
2471 (
2472 ExprKind::Struct(
2473 QPath::LangItem(LangItem::Range, _),
2474 [val1, val3],
2475 StructTailExpr::None,
2476 ),
2477 ExprKind::Struct(
2478 QPath::LangItem(LangItem::Range, _),
2479 [val2, val4],
2480 StructTailExpr::None,
2481 ),
2482 )
2483 | (
2484 ExprKind::Struct(
2485 QPath::LangItem(LangItem::RangeCopy, _),
2486 [val1, val3],
2487 StructTailExpr::None,
2488 ),
2489 ExprKind::Struct(
2490 QPath::LangItem(LangItem::RangeCopy, _),
2491 [val2, val4],
2492 StructTailExpr::None,
2493 ),
2494 )
2495 | (
2496 ExprKind::Struct(
2497 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2498 [val1, val3],
2499 StructTailExpr::None,
2500 ),
2501 ExprKind::Struct(
2502 QPath::LangItem(LangItem::RangeInclusiveCopy, _),
2503 [val2, val4],
2504 StructTailExpr::None,
2505 ),
2506 ) => {
2507 val1.expr.equivalent_for_indexing(val2.expr)
2508 && val3.expr.equivalent_for_indexing(val4.expr)
2509 }
2510 _ => false,
2511 }
2512 }
2513
2514 pub fn method_ident(&self) -> Option<Ident> {
2515 match self.kind {
2516 ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
2517 ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
2518 _ => None,
2519 }
2520 }
2521}
2522
2523pub fn is_range_literal(expr: &Expr<'_>) -> bool {
2526 match expr.kind {
2527 ExprKind::Struct(ref qpath, _, _) => matches!(
2529 **qpath,
2530 QPath::LangItem(
2531 LangItem::Range
2532 | LangItem::RangeTo
2533 | LangItem::RangeFrom
2534 | LangItem::RangeFull
2535 | LangItem::RangeToInclusive
2536 | LangItem::RangeCopy
2537 | LangItem::RangeFromCopy
2538 | LangItem::RangeInclusiveCopy,
2539 ..
2540 )
2541 ),
2542
2543 ExprKind::Call(ref func, _) => {
2545 matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
2546 }
2547
2548 _ => false,
2549 }
2550}
2551
2552pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
2559 match expr.kind {
2560 ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
2562 _ if is_range_literal(expr) => true,
2564 _ => false,
2565 }
2566}
2567
2568#[derive(Debug, Clone, Copy, HashStable_Generic)]
2569pub enum ExprKind<'hir> {
2570 ConstBlock(ConstBlock),
2572 Array(&'hir [Expr<'hir>]),
2574 Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
2581 MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
2598 Use(&'hir Expr<'hir>, Span),
2600 Tup(&'hir [Expr<'hir>]),
2602 Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2604 Unary(UnOp, &'hir Expr<'hir>),
2606 Lit(&'hir Lit),
2608 Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
2610 Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
2612 DropTemps(&'hir Expr<'hir>),
2618 Let(&'hir LetExpr<'hir>),
2623 If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
2627 Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
2633 Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
2636 Closure(&'hir Closure<'hir>),
2643 Block(&'hir Block<'hir>, Option<Label>),
2645
2646 Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2648 AssignOp(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
2652 Field(&'hir Expr<'hir>, Ident),
2654 Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
2658
2659 Path(QPath<'hir>),
2661
2662 AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
2664 Break(Destination, Option<&'hir Expr<'hir>>),
2666 Continue(Destination),
2668 Ret(Option<&'hir Expr<'hir>>),
2670 Become(&'hir Expr<'hir>),
2672
2673 InlineAsm(&'hir InlineAsm<'hir>),
2675
2676 OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
2678
2679 Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),
2684
2685 Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),
2690
2691 Yield(&'hir Expr<'hir>, YieldSource),
2693
2694 UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),
2697
2698 Err(rustc_span::ErrorGuaranteed),
2700}
2701
2702#[derive(Debug, Clone, Copy, HashStable_Generic)]
2703pub enum StructTailExpr<'hir> {
2704 None,
2706 Base(&'hir Expr<'hir>),
2709 DefaultFields(Span),
2713}
2714
2715#[derive(Debug, Clone, Copy, HashStable_Generic)]
2721pub enum QPath<'hir> {
2722 Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),
2729
2730 TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
2737
2738 LangItem(LangItem, Span),
2740}
2741
2742impl<'hir> QPath<'hir> {
2743 pub fn span(&self) -> Span {
2745 match *self {
2746 QPath::Resolved(_, path) => path.span,
2747 QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
2748 QPath::LangItem(_, span) => span,
2749 }
2750 }
2751
2752 pub fn qself_span(&self) -> Span {
2755 match *self {
2756 QPath::Resolved(_, path) => path.span,
2757 QPath::TypeRelative(qself, _) => qself.span,
2758 QPath::LangItem(_, span) => span,
2759 }
2760 }
2761}
2762
2763#[derive(Copy, Clone, Debug, HashStable_Generic)]
2765pub enum LocalSource {
2766 Normal,
2768 AsyncFn,
2779 AwaitDesugar,
2781 AssignDesugar(Span),
2784 Contract,
2786}
2787
2788#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
2790pub enum MatchSource {
2791 Normal,
2793 Postfix,
2795 ForLoopDesugar,
2797 TryDesugar(HirId),
2799 AwaitDesugar,
2801 FormatArgs,
2803}
2804
2805impl MatchSource {
2806 #[inline]
2807 pub const fn name(self) -> &'static str {
2808 use MatchSource::*;
2809 match self {
2810 Normal => "match",
2811 Postfix => ".match",
2812 ForLoopDesugar => "for",
2813 TryDesugar(_) => "?",
2814 AwaitDesugar => ".await",
2815 FormatArgs => "format_args!()",
2816 }
2817 }
2818}
2819
2820#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
2822pub enum LoopSource {
2823 Loop,
2825 While,
2827 ForLoop,
2829}
2830
2831impl LoopSource {
2832 pub fn name(self) -> &'static str {
2833 match self {
2834 LoopSource::Loop => "loop",
2835 LoopSource::While => "while",
2836 LoopSource::ForLoop => "for",
2837 }
2838 }
2839}
2840
2841#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
2842pub enum LoopIdError {
2843 OutsideLoopScope,
2844 UnlabeledCfInWhileCondition,
2845 UnresolvedLabel,
2846}
2847
2848impl fmt::Display for LoopIdError {
2849 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2850 f.write_str(match self {
2851 LoopIdError::OutsideLoopScope => "not inside loop scope",
2852 LoopIdError::UnlabeledCfInWhileCondition => {
2853 "unlabeled control flow (break or continue) in while condition"
2854 }
2855 LoopIdError::UnresolvedLabel => "label not found",
2856 })
2857 }
2858}
2859
2860#[derive(Copy, Clone, Debug, HashStable_Generic)]
2861pub struct Destination {
2862 pub label: Option<Label>,
2864
2865 pub target_id: Result<HirId, LoopIdError>,
2868}
2869
2870#[derive(Copy, Clone, Debug, HashStable_Generic)]
2872pub enum YieldSource {
2873 Await { expr: Option<HirId> },
2875 Yield,
2877}
2878
2879impl fmt::Display for YieldSource {
2880 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2881 f.write_str(match self {
2882 YieldSource::Await { .. } => "`await`",
2883 YieldSource::Yield => "`yield`",
2884 })
2885 }
2886}
2887
2888#[derive(Debug, Clone, Copy, HashStable_Generic)]
2891pub struct MutTy<'hir> {
2892 pub ty: &'hir Ty<'hir>,
2893 pub mutbl: Mutability,
2894}
2895
2896#[derive(Debug, Clone, Copy, HashStable_Generic)]
2899pub struct FnSig<'hir> {
2900 pub header: FnHeader,
2901 pub decl: &'hir FnDecl<'hir>,
2902 pub span: Span,
2903}
2904
2905#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
2909pub struct TraitItemId {
2910 pub owner_id: OwnerId,
2911}
2912
2913impl TraitItemId {
2914 #[inline]
2915 pub fn hir_id(&self) -> HirId {
2916 HirId::make_owner(self.owner_id.def_id)
2918 }
2919}
2920
2921#[derive(Debug, Clone, Copy, HashStable_Generic)]
2926pub struct TraitItem<'hir> {
2927 pub ident: Ident,
2928 pub owner_id: OwnerId,
2929 pub generics: &'hir Generics<'hir>,
2930 pub kind: TraitItemKind<'hir>,
2931 pub span: Span,
2932 pub defaultness: Defaultness,
2933}
2934
2935macro_rules! expect_methods_self_kind {
2936 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
2937 $(
2938 #[track_caller]
2939 pub fn $name(&self) -> $ret_ty {
2940 let $pat = &self.kind else { expect_failed(stringify!($ident), self) };
2941 $ret_val
2942 }
2943 )*
2944 }
2945}
2946
2947macro_rules! expect_methods_self {
2948 ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
2949 $(
2950 #[track_caller]
2951 pub fn $name(&self) -> $ret_ty {
2952 let $pat = self else { expect_failed(stringify!($ident), self) };
2953 $ret_val
2954 }
2955 )*
2956 }
2957}
2958
2959#[track_caller]
2960fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
2961 panic!("{ident}: found {found:?}")
2962}
2963
2964impl<'hir> TraitItem<'hir> {
2965 #[inline]
2966 pub fn hir_id(&self) -> HirId {
2967 HirId::make_owner(self.owner_id.def_id)
2969 }
2970
2971 pub fn trait_item_id(&self) -> TraitItemId {
2972 TraitItemId { owner_id: self.owner_id }
2973 }
2974
2975 expect_methods_self_kind! {
2976 expect_const, (&'hir Ty<'hir>, Option<BodyId>),
2977 TraitItemKind::Const(ty, body), (ty, *body);
2978
2979 expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
2980 TraitItemKind::Fn(ty, trfn), (ty, trfn);
2981
2982 expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
2983 TraitItemKind::Type(bounds, ty), (bounds, *ty);
2984 }
2985}
2986
2987#[derive(Debug, Clone, Copy, HashStable_Generic)]
2989pub enum TraitFn<'hir> {
2990 Required(&'hir [Option<Ident>]),
2992
2993 Provided(BodyId),
2995}
2996
2997#[derive(Debug, Clone, Copy, HashStable_Generic)]
2999pub enum TraitItemKind<'hir> {
3000 Const(&'hir Ty<'hir>, Option<BodyId>),
3002 Fn(FnSig<'hir>, TraitFn<'hir>),
3004 Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
3007}
3008
3009#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3013pub struct ImplItemId {
3014 pub owner_id: OwnerId,
3015}
3016
3017impl ImplItemId {
3018 #[inline]
3019 pub fn hir_id(&self) -> HirId {
3020 HirId::make_owner(self.owner_id.def_id)
3022 }
3023}
3024
3025#[derive(Debug, Clone, Copy, HashStable_Generic)]
3029pub struct ImplItem<'hir> {
3030 pub ident: Ident,
3031 pub owner_id: OwnerId,
3032 pub generics: &'hir Generics<'hir>,
3033 pub kind: ImplItemKind<'hir>,
3034 pub defaultness: Defaultness,
3035 pub span: Span,
3036 pub vis_span: Span,
3037}
3038
3039impl<'hir> ImplItem<'hir> {
3040 #[inline]
3041 pub fn hir_id(&self) -> HirId {
3042 HirId::make_owner(self.owner_id.def_id)
3044 }
3045
3046 pub fn impl_item_id(&self) -> ImplItemId {
3047 ImplItemId { owner_id: self.owner_id }
3048 }
3049
3050 expect_methods_self_kind! {
3051 expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
3052 expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3053 expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3054 }
3055}
3056
3057#[derive(Debug, Clone, Copy, HashStable_Generic)]
3059pub enum ImplItemKind<'hir> {
3060 Const(&'hir Ty<'hir>, BodyId),
3063 Fn(FnSig<'hir>, BodyId),
3065 Type(&'hir Ty<'hir>),
3067}
3068
3069#[derive(Debug, Clone, Copy, HashStable_Generic)]
3080pub struct AssocItemConstraint<'hir> {
3081 #[stable_hasher(ignore)]
3082 pub hir_id: HirId,
3083 pub ident: Ident,
3084 pub gen_args: &'hir GenericArgs<'hir>,
3085 pub kind: AssocItemConstraintKind<'hir>,
3086 pub span: Span,
3087}
3088
3089impl<'hir> AssocItemConstraint<'hir> {
3090 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
3092 match self.kind {
3093 AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
3094 _ => None,
3095 }
3096 }
3097
3098 pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
3100 match self.kind {
3101 AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
3102 _ => None,
3103 }
3104 }
3105}
3106
3107#[derive(Debug, Clone, Copy, HashStable_Generic)]
3108pub enum Term<'hir> {
3109 Ty(&'hir Ty<'hir>),
3110 Const(&'hir ConstArg<'hir>),
3111}
3112
3113impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
3114 fn from(ty: &'hir Ty<'hir>) -> Self {
3115 Term::Ty(ty)
3116 }
3117}
3118
3119impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
3120 fn from(c: &'hir ConstArg<'hir>) -> Self {
3121 Term::Const(c)
3122 }
3123}
3124
3125#[derive(Debug, Clone, Copy, HashStable_Generic)]
3127pub enum AssocItemConstraintKind<'hir> {
3128 Equality { term: Term<'hir> },
3135 Bound { bounds: &'hir [GenericBound<'hir>] },
3137}
3138
3139impl<'hir> AssocItemConstraintKind<'hir> {
3140 pub fn descr(&self) -> &'static str {
3141 match self {
3142 AssocItemConstraintKind::Equality { .. } => "binding",
3143 AssocItemConstraintKind::Bound { .. } => "constraint",
3144 }
3145 }
3146}
3147
3148#[derive(Debug, Clone, Copy, HashStable_Generic)]
3152pub enum AmbigArg {}
3153
3154#[derive(Debug, Clone, Copy, HashStable_Generic)]
3155#[repr(C)]
3156pub struct Ty<'hir, Unambig = ()> {
3163 #[stable_hasher(ignore)]
3164 pub hir_id: HirId,
3165 pub span: Span,
3166 pub kind: TyKind<'hir, Unambig>,
3167}
3168
3169impl<'hir> Ty<'hir, AmbigArg> {
3170 pub fn as_unambig_ty(&self) -> &Ty<'hir> {
3181 let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
3184 unsafe { &*ptr }
3185 }
3186}
3187
3188impl<'hir> Ty<'hir> {
3189 pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
3195 if let TyKind::Infer(()) = self.kind {
3196 return None;
3197 }
3198
3199 let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
3203 Some(unsafe { &*ptr })
3204 }
3205}
3206
3207impl<'hir> Ty<'hir, AmbigArg> {
3208 pub fn peel_refs(&self) -> &Ty<'hir> {
3209 let mut final_ty = self.as_unambig_ty();
3210 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3211 final_ty = ty;
3212 }
3213 final_ty
3214 }
3215}
3216
3217impl<'hir> Ty<'hir> {
3218 pub fn peel_refs(&self) -> &Self {
3219 let mut final_ty = self;
3220 while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
3221 final_ty = ty;
3222 }
3223 final_ty
3224 }
3225
3226 pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
3228 let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
3229 return None;
3230 };
3231 let [segment] = &path.segments else {
3232 return None;
3233 };
3234 match path.res {
3235 Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
3236 Some((def_id, segment.ident))
3237 }
3238 _ => None,
3239 }
3240 }
3241
3242 pub fn find_self_aliases(&self) -> Vec<Span> {
3243 use crate::intravisit::Visitor;
3244 struct MyVisitor(Vec<Span>);
3245 impl<'v> Visitor<'v> for MyVisitor {
3246 fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
3247 if matches!(
3248 &t.kind,
3249 TyKind::Path(QPath::Resolved(
3250 _,
3251 Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
3252 ))
3253 ) {
3254 self.0.push(t.span);
3255 return;
3256 }
3257 crate::intravisit::walk_ty(self, t);
3258 }
3259 }
3260
3261 let mut my_visitor = MyVisitor(vec![]);
3262 my_visitor.visit_ty_unambig(self);
3263 my_visitor.0
3264 }
3265
3266 pub fn is_suggestable_infer_ty(&self) -> bool {
3269 fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
3270 generic_args.iter().any(|arg| match arg {
3271 GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
3272 GenericArg::Infer(_) => true,
3273 _ => false,
3274 })
3275 }
3276 debug!(?self);
3277 match &self.kind {
3278 TyKind::Infer(()) => true,
3279 TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
3280 TyKind::Array(ty, length) => {
3281 ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
3282 }
3283 TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
3284 TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
3285 TyKind::Path(QPath::TypeRelative(ty, segment)) => {
3286 ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
3287 }
3288 TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
3289 ty_opt.is_some_and(Self::is_suggestable_infer_ty)
3290 || segments
3291 .iter()
3292 .any(|segment| are_suggestable_generic_args(segment.args().args))
3293 }
3294 _ => false,
3295 }
3296 }
3297}
3298
3299#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
3301pub enum PrimTy {
3302 Int(IntTy),
3303 Uint(UintTy),
3304 Float(FloatTy),
3305 Str,
3306 Bool,
3307 Char,
3308}
3309
3310impl PrimTy {
3311 pub const ALL: [Self; 19] = [
3313 Self::Int(IntTy::I8),
3315 Self::Int(IntTy::I16),
3316 Self::Int(IntTy::I32),
3317 Self::Int(IntTy::I64),
3318 Self::Int(IntTy::I128),
3319 Self::Int(IntTy::Isize),
3320 Self::Uint(UintTy::U8),
3321 Self::Uint(UintTy::U16),
3322 Self::Uint(UintTy::U32),
3323 Self::Uint(UintTy::U64),
3324 Self::Uint(UintTy::U128),
3325 Self::Uint(UintTy::Usize),
3326 Self::Float(FloatTy::F16),
3327 Self::Float(FloatTy::F32),
3328 Self::Float(FloatTy::F64),
3329 Self::Float(FloatTy::F128),
3330 Self::Bool,
3331 Self::Char,
3332 Self::Str,
3333 ];
3334
3335 pub fn name_str(self) -> &'static str {
3339 match self {
3340 PrimTy::Int(i) => i.name_str(),
3341 PrimTy::Uint(u) => u.name_str(),
3342 PrimTy::Float(f) => f.name_str(),
3343 PrimTy::Str => "str",
3344 PrimTy::Bool => "bool",
3345 PrimTy::Char => "char",
3346 }
3347 }
3348
3349 pub fn name(self) -> Symbol {
3350 match self {
3351 PrimTy::Int(i) => i.name(),
3352 PrimTy::Uint(u) => u.name(),
3353 PrimTy::Float(f) => f.name(),
3354 PrimTy::Str => sym::str,
3355 PrimTy::Bool => sym::bool,
3356 PrimTy::Char => sym::char,
3357 }
3358 }
3359
3360 pub fn from_name(name: Symbol) -> Option<Self> {
3363 let ty = match name {
3364 sym::i8 => Self::Int(IntTy::I8),
3366 sym::i16 => Self::Int(IntTy::I16),
3367 sym::i32 => Self::Int(IntTy::I32),
3368 sym::i64 => Self::Int(IntTy::I64),
3369 sym::i128 => Self::Int(IntTy::I128),
3370 sym::isize => Self::Int(IntTy::Isize),
3371 sym::u8 => Self::Uint(UintTy::U8),
3372 sym::u16 => Self::Uint(UintTy::U16),
3373 sym::u32 => Self::Uint(UintTy::U32),
3374 sym::u64 => Self::Uint(UintTy::U64),
3375 sym::u128 => Self::Uint(UintTy::U128),
3376 sym::usize => Self::Uint(UintTy::Usize),
3377 sym::f16 => Self::Float(FloatTy::F16),
3378 sym::f32 => Self::Float(FloatTy::F32),
3379 sym::f64 => Self::Float(FloatTy::F64),
3380 sym::f128 => Self::Float(FloatTy::F128),
3381 sym::bool => Self::Bool,
3382 sym::char => Self::Char,
3383 sym::str => Self::Str,
3384 _ => return None,
3385 };
3386 Some(ty)
3387 }
3388}
3389
3390#[derive(Debug, Clone, Copy, HashStable_Generic)]
3391pub struct BareFnTy<'hir> {
3392 pub safety: Safety,
3393 pub abi: ExternAbi,
3394 pub generic_params: &'hir [GenericParam<'hir>],
3395 pub decl: &'hir FnDecl<'hir>,
3396 pub param_names: &'hir [Option<Ident>],
3399}
3400
3401#[derive(Debug, Clone, Copy, HashStable_Generic)]
3402pub struct UnsafeBinderTy<'hir> {
3403 pub generic_params: &'hir [GenericParam<'hir>],
3404 pub inner_ty: &'hir Ty<'hir>,
3405}
3406
3407#[derive(Debug, Clone, Copy, HashStable_Generic)]
3408pub struct OpaqueTy<'hir> {
3409 #[stable_hasher(ignore)]
3410 pub hir_id: HirId,
3411 pub def_id: LocalDefId,
3412 pub bounds: GenericBounds<'hir>,
3413 pub origin: OpaqueTyOrigin<LocalDefId>,
3414 pub span: Span,
3415}
3416
3417#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
3418pub enum PreciseCapturingArgKind<T, U> {
3419 Lifetime(T),
3420 Param(U),
3422}
3423
3424pub type PreciseCapturingArg<'hir> =
3425 PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;
3426
3427impl PreciseCapturingArg<'_> {
3428 pub fn hir_id(self) -> HirId {
3429 match self {
3430 PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
3431 PreciseCapturingArg::Param(param) => param.hir_id,
3432 }
3433 }
3434
3435 pub fn name(self) -> Symbol {
3436 match self {
3437 PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
3438 PreciseCapturingArg::Param(param) => param.ident.name,
3439 }
3440 }
3441}
3442
3443#[derive(Debug, Clone, Copy, HashStable_Generic)]
3448pub struct PreciseCapturingNonLifetimeArg {
3449 #[stable_hasher(ignore)]
3450 pub hir_id: HirId,
3451 pub ident: Ident,
3452 pub res: Res,
3453}
3454
3455#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3456#[derive(HashStable_Generic, Encodable, Decodable)]
3457pub enum RpitContext {
3458 Trait,
3459 TraitImpl,
3460}
3461
3462#[derive(Copy, Clone, PartialEq, Eq, Debug)]
3464#[derive(HashStable_Generic, Encodable, Decodable)]
3465pub enum OpaqueTyOrigin<D> {
3466 FnReturn {
3468 parent: D,
3470 in_trait_or_impl: Option<RpitContext>,
3472 },
3473 AsyncFn {
3475 parent: D,
3477 in_trait_or_impl: Option<RpitContext>,
3479 },
3480 TyAlias {
3482 parent: D,
3484 in_assoc_ty: bool,
3486 },
3487}
3488
3489#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
3490pub enum InferDelegationKind {
3491 Input(usize),
3492 Output,
3493}
3494
3495#[derive(Debug, Clone, Copy, HashStable_Generic)]
3497#[repr(u8, C)]
3499pub enum TyKind<'hir, Unambig = ()> {
3500 InferDelegation(DefId, InferDelegationKind),
3502 Slice(&'hir Ty<'hir>),
3504 Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
3506 Ptr(MutTy<'hir>),
3508 Ref(&'hir Lifetime, MutTy<'hir>),
3510 BareFn(&'hir BareFnTy<'hir>),
3512 UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
3514 Never,
3516 Tup(&'hir [Ty<'hir>]),
3518 Path(QPath<'hir>),
3523 OpaqueDef(&'hir OpaqueTy<'hir>),
3525 TraitAscription(GenericBounds<'hir>),
3527 TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
3533 Typeof(&'hir AnonConst),
3535 Err(rustc_span::ErrorGuaranteed),
3537 Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
3539 Infer(Unambig),
3545}
3546
3547#[derive(Debug, Clone, Copy, HashStable_Generic)]
3548pub enum InlineAsmOperand<'hir> {
3549 In {
3550 reg: InlineAsmRegOrRegClass,
3551 expr: &'hir Expr<'hir>,
3552 },
3553 Out {
3554 reg: InlineAsmRegOrRegClass,
3555 late: bool,
3556 expr: Option<&'hir Expr<'hir>>,
3557 },
3558 InOut {
3559 reg: InlineAsmRegOrRegClass,
3560 late: bool,
3561 expr: &'hir Expr<'hir>,
3562 },
3563 SplitInOut {
3564 reg: InlineAsmRegOrRegClass,
3565 late: bool,
3566 in_expr: &'hir Expr<'hir>,
3567 out_expr: Option<&'hir Expr<'hir>>,
3568 },
3569 Const {
3570 anon_const: ConstBlock,
3571 },
3572 SymFn {
3573 expr: &'hir Expr<'hir>,
3574 },
3575 SymStatic {
3576 path: QPath<'hir>,
3577 def_id: DefId,
3578 },
3579 Label {
3580 block: &'hir Block<'hir>,
3581 },
3582}
3583
3584impl<'hir> InlineAsmOperand<'hir> {
3585 pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
3586 match *self {
3587 Self::In { reg, .. }
3588 | Self::Out { reg, .. }
3589 | Self::InOut { reg, .. }
3590 | Self::SplitInOut { reg, .. } => Some(reg),
3591 Self::Const { .. }
3592 | Self::SymFn { .. }
3593 | Self::SymStatic { .. }
3594 | Self::Label { .. } => None,
3595 }
3596 }
3597
3598 pub fn is_clobber(&self) -> bool {
3599 matches!(
3600 self,
3601 InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
3602 )
3603 }
3604}
3605
3606#[derive(Debug, Clone, Copy, HashStable_Generic)]
3607pub struct InlineAsm<'hir> {
3608 pub asm_macro: ast::AsmMacro,
3609 pub template: &'hir [InlineAsmTemplatePiece],
3610 pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
3611 pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
3612 pub options: InlineAsmOptions,
3613 pub line_spans: &'hir [Span],
3614}
3615
3616impl InlineAsm<'_> {
3617 pub fn contains_label(&self) -> bool {
3618 self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
3619 }
3620}
3621
3622#[derive(Debug, Clone, Copy, HashStable_Generic)]
3624pub struct Param<'hir> {
3625 #[stable_hasher(ignore)]
3626 pub hir_id: HirId,
3627 pub pat: &'hir Pat<'hir>,
3628 pub ty_span: Span,
3629 pub span: Span,
3630}
3631
3632#[derive(Debug, Clone, Copy, HashStable_Generic)]
3634pub struct FnDecl<'hir> {
3635 pub inputs: &'hir [Ty<'hir>],
3639 pub output: FnRetTy<'hir>,
3640 pub c_variadic: bool,
3641 pub implicit_self: ImplicitSelfKind,
3643 pub lifetime_elision_allowed: bool,
3645}
3646
3647impl<'hir> FnDecl<'hir> {
3648 pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
3649 if let FnRetTy::Return(ty) = self.output
3650 && let TyKind::InferDelegation(sig_id, _) = ty.kind
3651 {
3652 return Some(sig_id);
3653 }
3654 None
3655 }
3656}
3657
3658#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3660pub enum ImplicitSelfKind {
3661 Imm,
3663 Mut,
3665 RefImm,
3667 RefMut,
3669 None,
3672}
3673
3674impl ImplicitSelfKind {
3675 pub fn has_implicit_self(&self) -> bool {
3677 !matches!(*self, ImplicitSelfKind::None)
3678 }
3679}
3680
3681#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
3682pub enum IsAsync {
3683 Async(Span),
3684 NotAsync,
3685}
3686
3687impl IsAsync {
3688 pub fn is_async(self) -> bool {
3689 matches!(self, IsAsync::Async(_))
3690 }
3691}
3692
3693#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
3694pub enum Defaultness {
3695 Default { has_value: bool },
3696 Final,
3697}
3698
3699impl Defaultness {
3700 pub fn has_value(&self) -> bool {
3701 match *self {
3702 Defaultness::Default { has_value } => has_value,
3703 Defaultness::Final => true,
3704 }
3705 }
3706
3707 pub fn is_final(&self) -> bool {
3708 *self == Defaultness::Final
3709 }
3710
3711 pub fn is_default(&self) -> bool {
3712 matches!(*self, Defaultness::Default { .. })
3713 }
3714}
3715
3716#[derive(Debug, Clone, Copy, HashStable_Generic)]
3717pub enum FnRetTy<'hir> {
3718 DefaultReturn(Span),
3724 Return(&'hir Ty<'hir>),
3726}
3727
3728impl<'hir> FnRetTy<'hir> {
3729 #[inline]
3730 pub fn span(&self) -> Span {
3731 match *self {
3732 Self::DefaultReturn(span) => span,
3733 Self::Return(ref ty) => ty.span,
3734 }
3735 }
3736
3737 pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
3738 if let Self::Return(ty) = self
3739 && ty.is_suggestable_infer_ty()
3740 {
3741 return Some(*ty);
3742 }
3743 None
3744 }
3745}
3746
3747#[derive(Copy, Clone, Debug, HashStable_Generic)]
3749pub enum ClosureBinder {
3750 Default,
3752 For { span: Span },
3756}
3757
3758#[derive(Debug, Clone, Copy, HashStable_Generic)]
3759pub struct Mod<'hir> {
3760 pub spans: ModSpans,
3761 pub item_ids: &'hir [ItemId],
3762}
3763
3764#[derive(Copy, Clone, Debug, HashStable_Generic)]
3765pub struct ModSpans {
3766 pub inner_span: Span,
3770 pub inject_use_span: Span,
3771}
3772
3773#[derive(Debug, Clone, Copy, HashStable_Generic)]
3774pub struct EnumDef<'hir> {
3775 pub variants: &'hir [Variant<'hir>],
3776}
3777
3778#[derive(Debug, Clone, Copy, HashStable_Generic)]
3779pub struct Variant<'hir> {
3780 pub ident: Ident,
3782 #[stable_hasher(ignore)]
3784 pub hir_id: HirId,
3785 pub def_id: LocalDefId,
3786 pub data: VariantData<'hir>,
3788 pub disr_expr: Option<&'hir AnonConst>,
3790 pub span: Span,
3792}
3793
3794#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
3795pub enum UseKind {
3796 Single(Ident),
3803
3804 Glob,
3806
3807 ListStem,
3811}
3812
3813#[derive(Clone, Debug, Copy, HashStable_Generic)]
3820pub struct TraitRef<'hir> {
3821 pub path: &'hir Path<'hir>,
3822 #[stable_hasher(ignore)]
3824 pub hir_ref_id: HirId,
3825}
3826
3827impl TraitRef<'_> {
3828 pub fn trait_def_id(&self) -> Option<DefId> {
3830 match self.path.res {
3831 Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
3832 Res::Err => None,
3833 res => panic!("{res:?} did not resolve to a trait or trait alias"),
3834 }
3835 }
3836}
3837
3838#[derive(Clone, Debug, Copy, HashStable_Generic)]
3839pub struct PolyTraitRef<'hir> {
3840 pub bound_generic_params: &'hir [GenericParam<'hir>],
3842
3843 pub modifiers: TraitBoundModifiers,
3847
3848 pub trait_ref: TraitRef<'hir>,
3850
3851 pub span: Span,
3852}
3853
3854#[derive(Debug, Clone, Copy, HashStable_Generic)]
3855pub struct FieldDef<'hir> {
3856 pub span: Span,
3857 pub vis_span: Span,
3858 pub ident: Ident,
3859 #[stable_hasher(ignore)]
3860 pub hir_id: HirId,
3861 pub def_id: LocalDefId,
3862 pub ty: &'hir Ty<'hir>,
3863 pub safety: Safety,
3864 pub default: Option<&'hir AnonConst>,
3865}
3866
3867impl FieldDef<'_> {
3868 pub fn is_positional(&self) -> bool {
3870 self.ident.as_str().as_bytes()[0].is_ascii_digit()
3871 }
3872}
3873
3874#[derive(Debug, Clone, Copy, HashStable_Generic)]
3876pub enum VariantData<'hir> {
3877 Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
3881 Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
3885 Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
3889}
3890
3891impl<'hir> VariantData<'hir> {
3892 pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
3894 match *self {
3895 VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
3896 _ => &[],
3897 }
3898 }
3899
3900 pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
3901 match *self {
3902 VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
3903 VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
3904 VariantData::Struct { .. } => None,
3905 }
3906 }
3907
3908 #[inline]
3909 pub fn ctor_kind(&self) -> Option<CtorKind> {
3910 self.ctor().map(|(kind, ..)| kind)
3911 }
3912
3913 #[inline]
3915 pub fn ctor_hir_id(&self) -> Option<HirId> {
3916 self.ctor().map(|(_, hir_id, _)| hir_id)
3917 }
3918
3919 #[inline]
3921 pub fn ctor_def_id(&self) -> Option<LocalDefId> {
3922 self.ctor().map(|(.., def_id)| def_id)
3923 }
3924}
3925
3926#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
3930pub struct ItemId {
3931 pub owner_id: OwnerId,
3932}
3933
3934impl ItemId {
3935 #[inline]
3936 pub fn hir_id(&self) -> HirId {
3937 HirId::make_owner(self.owner_id.def_id)
3939 }
3940}
3941
3942#[derive(Debug, Clone, Copy, HashStable_Generic)]
3951pub struct Item<'hir> {
3952 pub owner_id: OwnerId,
3953 pub kind: ItemKind<'hir>,
3954 pub span: Span,
3955 pub vis_span: Span,
3956}
3957
3958impl<'hir> Item<'hir> {
3959 #[inline]
3960 pub fn hir_id(&self) -> HirId {
3961 HirId::make_owner(self.owner_id.def_id)
3963 }
3964
3965 pub fn item_id(&self) -> ItemId {
3966 ItemId { owner_id: self.owner_id }
3967 }
3968
3969 pub fn is_adt(&self) -> bool {
3972 matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
3973 }
3974
3975 pub fn is_struct_or_union(&self) -> bool {
3977 matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
3978 }
3979
3980 expect_methods_self_kind! {
3981 expect_extern_crate, (Option<Symbol>, Ident),
3982 ItemKind::ExternCrate(s, ident), (*s, *ident);
3983
3984 expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
3985
3986 expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId),
3987 ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body);
3988
3989 expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
3990 ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body);
3991
3992 expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
3993 ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
3994
3995 expect_macro, (Ident, &ast::MacroDef, MacroKind),
3996 ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
3997
3998 expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
3999
4000 expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
4001 ItemKind::ForeignMod { abi, items }, (*abi, items);
4002
4003 expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
4004
4005 expect_ty_alias, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
4006 ItemKind::TyAlias(ident, ty, generics), (*ident, ty, generics);
4007
4008 expect_enum, (Ident, &EnumDef<'hir>, &'hir Generics<'hir>),
4009 ItemKind::Enum(ident, def, generics), (*ident, def, generics);
4010
4011 expect_struct, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
4012 ItemKind::Struct(ident, data, generics), (*ident, data, generics);
4013
4014 expect_union, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
4015 ItemKind::Union(ident, data, generics), (*ident, data, generics);
4016
4017 expect_trait,
4018 (
4019 IsAuto,
4020 Safety,
4021 Ident,
4022 &'hir Generics<'hir>,
4023 GenericBounds<'hir>,
4024 &'hir [TraitItemRef]
4025 ),
4026 ItemKind::Trait(is_auto, safety, ident, generics, bounds, items),
4027 (*is_auto, *safety, *ident, generics, bounds, items);
4028
4029 expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4030 ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
4031
4032 expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
4033 }
4034}
4035
4036#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4037#[derive(Encodable, Decodable, HashStable_Generic)]
4038pub enum Safety {
4039 Unsafe,
4040 Safe,
4041}
4042
4043impl Safety {
4044 pub fn prefix_str(self) -> &'static str {
4045 match self {
4046 Self::Unsafe => "unsafe ",
4047 Self::Safe => "",
4048 }
4049 }
4050
4051 #[inline]
4052 pub fn is_unsafe(self) -> bool {
4053 !self.is_safe()
4054 }
4055
4056 #[inline]
4057 pub fn is_safe(self) -> bool {
4058 match self {
4059 Self::Unsafe => false,
4060 Self::Safe => true,
4061 }
4062 }
4063}
4064
4065impl fmt::Display for Safety {
4066 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4067 f.write_str(match *self {
4068 Self::Unsafe => "unsafe",
4069 Self::Safe => "safe",
4070 })
4071 }
4072}
4073
4074#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
4075pub enum Constness {
4076 Const,
4077 NotConst,
4078}
4079
4080impl fmt::Display for Constness {
4081 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4082 f.write_str(match *self {
4083 Self::Const => "const",
4084 Self::NotConst => "non-const",
4085 })
4086 }
4087}
4088
4089#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
4094pub enum HeaderSafety {
4095 SafeTargetFeatures,
4101 Normal(Safety),
4102}
4103
4104impl From<Safety> for HeaderSafety {
4105 fn from(v: Safety) -> Self {
4106 Self::Normal(v)
4107 }
4108}
4109
4110#[derive(Copy, Clone, Debug, HashStable_Generic)]
4111pub struct FnHeader {
4112 pub safety: HeaderSafety,
4113 pub constness: Constness,
4114 pub asyncness: IsAsync,
4115 pub abi: ExternAbi,
4116}
4117
4118impl FnHeader {
4119 pub fn is_async(&self) -> bool {
4120 matches!(self.asyncness, IsAsync::Async(_))
4121 }
4122
4123 pub fn is_const(&self) -> bool {
4124 matches!(self.constness, Constness::Const)
4125 }
4126
4127 pub fn is_unsafe(&self) -> bool {
4128 self.safety().is_unsafe()
4129 }
4130
4131 pub fn is_safe(&self) -> bool {
4132 self.safety().is_safe()
4133 }
4134
4135 pub fn safety(&self) -> Safety {
4136 match self.safety {
4137 HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
4138 HeaderSafety::Normal(safety) => safety,
4139 }
4140 }
4141}
4142
4143#[derive(Debug, Clone, Copy, HashStable_Generic)]
4144pub enum ItemKind<'hir> {
4145 ExternCrate(Option<Symbol>, Ident),
4149
4150 Use(&'hir UsePath<'hir>, UseKind),
4156
4157 Static(Ident, &'hir Ty<'hir>, Mutability, BodyId),
4159 Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
4161 Fn {
4163 ident: Ident,
4164 sig: FnSig<'hir>,
4165 generics: &'hir Generics<'hir>,
4166 body: BodyId,
4167 has_body: bool,
4171 },
4172 Macro(Ident, &'hir ast::MacroDef, MacroKind),
4174 Mod(Ident, &'hir Mod<'hir>),
4176 ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
4178 GlobalAsm {
4180 asm: &'hir InlineAsm<'hir>,
4181 fake_body: BodyId,
4187 },
4188 TyAlias(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
4190 Enum(Ident, EnumDef<'hir>, &'hir Generics<'hir>),
4192 Struct(Ident, VariantData<'hir>, &'hir Generics<'hir>),
4194 Union(Ident, VariantData<'hir>, &'hir Generics<'hir>),
4196 Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
4198 TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
4200
4201 Impl(&'hir Impl<'hir>),
4203}
4204
4205#[derive(Debug, Clone, Copy, HashStable_Generic)]
4210pub struct Impl<'hir> {
4211 pub constness: Constness,
4212 pub safety: Safety,
4213 pub polarity: ImplPolarity,
4214 pub defaultness: Defaultness,
4215 pub defaultness_span: Option<Span>,
4218 pub generics: &'hir Generics<'hir>,
4219
4220 pub of_trait: Option<TraitRef<'hir>>,
4222
4223 pub self_ty: &'hir Ty<'hir>,
4224 pub items: &'hir [ImplItemRef],
4225}
4226
4227impl ItemKind<'_> {
4228 pub fn ident(&self) -> Option<Ident> {
4229 match *self {
4230 ItemKind::ExternCrate(_, ident)
4231 | ItemKind::Use(_, UseKind::Single(ident))
4232 | ItemKind::Static(ident, ..)
4233 | ItemKind::Const(ident, ..)
4234 | ItemKind::Fn { ident, .. }
4235 | ItemKind::Macro(ident, ..)
4236 | ItemKind::Mod(ident, ..)
4237 | ItemKind::TyAlias(ident, ..)
4238 | ItemKind::Enum(ident, ..)
4239 | ItemKind::Struct(ident, ..)
4240 | ItemKind::Union(ident, ..)
4241 | ItemKind::Trait(_, _, ident, ..)
4242 | ItemKind::TraitAlias(ident, ..) => Some(ident),
4243
4244 ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
4245 | ItemKind::ForeignMod { .. }
4246 | ItemKind::GlobalAsm { .. }
4247 | ItemKind::Impl(_) => None,
4248 }
4249 }
4250
4251 pub fn generics(&self) -> Option<&Generics<'_>> {
4252 Some(match self {
4253 ItemKind::Fn { generics, .. }
4254 | ItemKind::TyAlias(_, _, generics)
4255 | ItemKind::Const(_, _, generics, _)
4256 | ItemKind::Enum(_, _, generics)
4257 | ItemKind::Struct(_, _, generics)
4258 | ItemKind::Union(_, _, generics)
4259 | ItemKind::Trait(_, _, _, generics, _, _)
4260 | ItemKind::TraitAlias(_, generics, _)
4261 | ItemKind::Impl(Impl { generics, .. }) => generics,
4262 _ => return None,
4263 })
4264 }
4265
4266 pub fn descr(&self) -> &'static str {
4267 match self {
4268 ItemKind::ExternCrate(..) => "extern crate",
4269 ItemKind::Use(..) => "`use` import",
4270 ItemKind::Static(..) => "static item",
4271 ItemKind::Const(..) => "constant item",
4272 ItemKind::Fn { .. } => "function",
4273 ItemKind::Macro(..) => "macro",
4274 ItemKind::Mod(..) => "module",
4275 ItemKind::ForeignMod { .. } => "extern block",
4276 ItemKind::GlobalAsm { .. } => "global asm item",
4277 ItemKind::TyAlias(..) => "type alias",
4278 ItemKind::Enum(..) => "enum",
4279 ItemKind::Struct(..) => "struct",
4280 ItemKind::Union(..) => "union",
4281 ItemKind::Trait(..) => "trait",
4282 ItemKind::TraitAlias(..) => "trait alias",
4283 ItemKind::Impl(..) => "implementation",
4284 }
4285 }
4286}
4287
4288#[derive(Debug, Clone, Copy, HashStable_Generic)]
4295pub struct TraitItemRef {
4296 pub id: TraitItemId,
4297 pub ident: Ident,
4298 pub kind: AssocItemKind,
4299 pub span: Span,
4300}
4301
4302#[derive(Debug, Clone, Copy, HashStable_Generic)]
4309pub struct ImplItemRef {
4310 pub id: ImplItemId,
4311 pub ident: Ident,
4312 pub kind: AssocItemKind,
4313 pub span: Span,
4314 pub trait_item_def_id: Option<DefId>,
4316}
4317
4318#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
4319pub enum AssocItemKind {
4320 Const,
4321 Fn { has_self: bool },
4322 Type,
4323}
4324
4325#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
4329pub struct ForeignItemId {
4330 pub owner_id: OwnerId,
4331}
4332
4333impl ForeignItemId {
4334 #[inline]
4335 pub fn hir_id(&self) -> HirId {
4336 HirId::make_owner(self.owner_id.def_id)
4338 }
4339}
4340
4341#[derive(Debug, Clone, Copy, HashStable_Generic)]
4348pub struct ForeignItemRef {
4349 pub id: ForeignItemId,
4350 pub ident: Ident,
4351 pub span: Span,
4352}
4353
4354#[derive(Debug, Clone, Copy, HashStable_Generic)]
4355pub struct ForeignItem<'hir> {
4356 pub ident: Ident,
4357 pub kind: ForeignItemKind<'hir>,
4358 pub owner_id: OwnerId,
4359 pub span: Span,
4360 pub vis_span: Span,
4361}
4362
4363impl ForeignItem<'_> {
4364 #[inline]
4365 pub fn hir_id(&self) -> HirId {
4366 HirId::make_owner(self.owner_id.def_id)
4368 }
4369
4370 pub fn foreign_item_id(&self) -> ForeignItemId {
4371 ForeignItemId { owner_id: self.owner_id }
4372 }
4373}
4374
4375#[derive(Debug, Clone, Copy, HashStable_Generic)]
4377pub enum ForeignItemKind<'hir> {
4378 Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
4385 Static(&'hir Ty<'hir>, Mutability, Safety),
4387 Type,
4389}
4390
4391#[derive(Debug, Copy, Clone, HashStable_Generic)]
4393pub struct Upvar {
4394 pub span: Span,
4396}
4397
4398#[derive(Debug, Clone, HashStable_Generic)]
4402pub struct TraitCandidate {
4403 pub def_id: DefId,
4404 pub import_ids: SmallVec<[LocalDefId; 1]>,
4405}
4406
4407#[derive(Copy, Clone, Debug, HashStable_Generic)]
4408pub enum OwnerNode<'hir> {
4409 Item(&'hir Item<'hir>),
4410 ForeignItem(&'hir ForeignItem<'hir>),
4411 TraitItem(&'hir TraitItem<'hir>),
4412 ImplItem(&'hir ImplItem<'hir>),
4413 Crate(&'hir Mod<'hir>),
4414 Synthetic,
4415}
4416
4417impl<'hir> OwnerNode<'hir> {
4418 pub fn span(&self) -> Span {
4419 match self {
4420 OwnerNode::Item(Item { span, .. })
4421 | OwnerNode::ForeignItem(ForeignItem { span, .. })
4422 | OwnerNode::ImplItem(ImplItem { span, .. })
4423 | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
4424 OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
4425 OwnerNode::Synthetic => unreachable!(),
4426 }
4427 }
4428
4429 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4430 match self {
4431 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4432 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4433 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4434 | OwnerNode::ForeignItem(ForeignItem {
4435 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4436 }) => Some(fn_sig),
4437 _ => None,
4438 }
4439 }
4440
4441 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4442 match self {
4443 OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4444 | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4445 | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4446 | OwnerNode::ForeignItem(ForeignItem {
4447 kind: ForeignItemKind::Fn(fn_sig, _, _), ..
4448 }) => Some(fn_sig.decl),
4449 _ => None,
4450 }
4451 }
4452
4453 pub fn body_id(&self) -> Option<BodyId> {
4454 match self {
4455 OwnerNode::Item(Item {
4456 kind:
4457 ItemKind::Static(_, _, _, body)
4458 | ItemKind::Const(_, _, _, body)
4459 | ItemKind::Fn { body, .. },
4460 ..
4461 })
4462 | OwnerNode::TraitItem(TraitItem {
4463 kind:
4464 TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4465 ..
4466 })
4467 | OwnerNode::ImplItem(ImplItem {
4468 kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4469 ..
4470 }) => Some(*body),
4471 _ => None,
4472 }
4473 }
4474
4475 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4476 Node::generics(self.into())
4477 }
4478
4479 pub fn def_id(self) -> OwnerId {
4480 match self {
4481 OwnerNode::Item(Item { owner_id, .. })
4482 | OwnerNode::TraitItem(TraitItem { owner_id, .. })
4483 | OwnerNode::ImplItem(ImplItem { owner_id, .. })
4484 | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
4485 OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
4486 OwnerNode::Synthetic => unreachable!(),
4487 }
4488 }
4489
4490 pub fn is_impl_block(&self) -> bool {
4492 matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
4493 }
4494
4495 expect_methods_self! {
4496 expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
4497 expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
4498 expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n;
4499 expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n;
4500 }
4501}
4502
4503impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
4504 fn from(val: &'hir Item<'hir>) -> Self {
4505 OwnerNode::Item(val)
4506 }
4507}
4508
4509impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
4510 fn from(val: &'hir ForeignItem<'hir>) -> Self {
4511 OwnerNode::ForeignItem(val)
4512 }
4513}
4514
4515impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
4516 fn from(val: &'hir ImplItem<'hir>) -> Self {
4517 OwnerNode::ImplItem(val)
4518 }
4519}
4520
4521impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
4522 fn from(val: &'hir TraitItem<'hir>) -> Self {
4523 OwnerNode::TraitItem(val)
4524 }
4525}
4526
4527impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
4528 fn from(val: OwnerNode<'hir>) -> Self {
4529 match val {
4530 OwnerNode::Item(n) => Node::Item(n),
4531 OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
4532 OwnerNode::ImplItem(n) => Node::ImplItem(n),
4533 OwnerNode::TraitItem(n) => Node::TraitItem(n),
4534 OwnerNode::Crate(n) => Node::Crate(n),
4535 OwnerNode::Synthetic => Node::Synthetic,
4536 }
4537 }
4538}
4539
4540#[derive(Copy, Clone, Debug, HashStable_Generic)]
4541pub enum Node<'hir> {
4542 Param(&'hir Param<'hir>),
4543 Item(&'hir Item<'hir>),
4544 ForeignItem(&'hir ForeignItem<'hir>),
4545 TraitItem(&'hir TraitItem<'hir>),
4546 ImplItem(&'hir ImplItem<'hir>),
4547 Variant(&'hir Variant<'hir>),
4548 Field(&'hir FieldDef<'hir>),
4549 AnonConst(&'hir AnonConst),
4550 ConstBlock(&'hir ConstBlock),
4551 ConstArg(&'hir ConstArg<'hir>),
4552 Expr(&'hir Expr<'hir>),
4553 ExprField(&'hir ExprField<'hir>),
4554 Stmt(&'hir Stmt<'hir>),
4555 PathSegment(&'hir PathSegment<'hir>),
4556 Ty(&'hir Ty<'hir>),
4557 AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
4558 TraitRef(&'hir TraitRef<'hir>),
4559 OpaqueTy(&'hir OpaqueTy<'hir>),
4560 TyPat(&'hir TyPat<'hir>),
4561 Pat(&'hir Pat<'hir>),
4562 PatField(&'hir PatField<'hir>),
4563 PatExpr(&'hir PatExpr<'hir>),
4567 Arm(&'hir Arm<'hir>),
4568 Block(&'hir Block<'hir>),
4569 LetStmt(&'hir LetStmt<'hir>),
4570 Ctor(&'hir VariantData<'hir>),
4573 Lifetime(&'hir Lifetime),
4574 GenericParam(&'hir GenericParam<'hir>),
4575 Crate(&'hir Mod<'hir>),
4576 Infer(&'hir InferArg),
4577 WherePredicate(&'hir WherePredicate<'hir>),
4578 PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
4579 Synthetic,
4581 Err(Span),
4582}
4583
4584impl<'hir> Node<'hir> {
4585 pub fn ident(&self) -> Option<Ident> {
4600 match self {
4601 Node::Item(item) => item.kind.ident(),
4602 Node::TraitItem(TraitItem { ident, .. })
4603 | Node::ImplItem(ImplItem { ident, .. })
4604 | Node::ForeignItem(ForeignItem { ident, .. })
4605 | Node::Field(FieldDef { ident, .. })
4606 | Node::Variant(Variant { ident, .. })
4607 | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
4608 Node::Lifetime(lt) => Some(lt.ident),
4609 Node::GenericParam(p) => Some(p.name.ident()),
4610 Node::AssocItemConstraint(c) => Some(c.ident),
4611 Node::PatField(f) => Some(f.ident),
4612 Node::ExprField(f) => Some(f.ident),
4613 Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
4614 Node::Param(..)
4615 | Node::AnonConst(..)
4616 | Node::ConstBlock(..)
4617 | Node::ConstArg(..)
4618 | Node::Expr(..)
4619 | Node::Stmt(..)
4620 | Node::Block(..)
4621 | Node::Ctor(..)
4622 | Node::Pat(..)
4623 | Node::TyPat(..)
4624 | Node::PatExpr(..)
4625 | Node::Arm(..)
4626 | Node::LetStmt(..)
4627 | Node::Crate(..)
4628 | Node::Ty(..)
4629 | Node::TraitRef(..)
4630 | Node::OpaqueTy(..)
4631 | Node::Infer(..)
4632 | Node::WherePredicate(..)
4633 | Node::Synthetic
4634 | Node::Err(..) => None,
4635 }
4636 }
4637
4638 pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
4639 match self {
4640 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4641 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4642 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4643 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4644 Some(fn_sig.decl)
4645 }
4646 Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
4647 Some(fn_decl)
4648 }
4649 _ => None,
4650 }
4651 }
4652
4653 pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
4655 if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4656 && let Some(trait_ref) = impl_block.of_trait
4657 && let Some(trait_id) = trait_ref.trait_def_id()
4658 && trait_id == trait_def_id
4659 {
4660 Some(impl_block)
4661 } else {
4662 None
4663 }
4664 }
4665
4666 pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
4667 match self {
4668 Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
4669 | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
4670 | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
4671 | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
4672 Some(fn_sig)
4673 }
4674 _ => None,
4675 }
4676 }
4677
4678 pub fn ty(self) -> Option<&'hir Ty<'hir>> {
4680 match self {
4681 Node::Item(it) => match it.kind {
4682 ItemKind::TyAlias(_, ty, _)
4683 | ItemKind::Static(_, ty, _, _)
4684 | ItemKind::Const(_, ty, _, _) => Some(ty),
4685 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
4686 _ => None,
4687 },
4688 Node::TraitItem(it) => match it.kind {
4689 TraitItemKind::Const(ty, _) => Some(ty),
4690 TraitItemKind::Type(_, ty) => ty,
4691 _ => None,
4692 },
4693 Node::ImplItem(it) => match it.kind {
4694 ImplItemKind::Const(ty, _) => Some(ty),
4695 ImplItemKind::Type(ty) => Some(ty),
4696 _ => None,
4697 },
4698 _ => None,
4699 }
4700 }
4701
4702 pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
4703 match self {
4704 Node::Item(Item { kind: ItemKind::TyAlias(_, ty, _), .. }) => Some(ty),
4705 _ => None,
4706 }
4707 }
4708
4709 #[inline]
4710 pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
4711 match self {
4712 Node::Item(Item {
4713 owner_id,
4714 kind:
4715 ItemKind::Const(_, _, _, body)
4716 | ItemKind::Static(.., body)
4717 | ItemKind::Fn { body, .. },
4718 ..
4719 })
4720 | Node::TraitItem(TraitItem {
4721 owner_id,
4722 kind:
4723 TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4724 ..
4725 })
4726 | Node::ImplItem(ImplItem {
4727 owner_id,
4728 kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4729 ..
4730 }) => Some((owner_id.def_id, *body)),
4731
4732 Node::Item(Item {
4733 owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4734 }) => Some((owner_id.def_id, *fake_body)),
4735
4736 Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
4737 Some((*def_id, *body))
4738 }
4739
4740 Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
4741 Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
4742
4743 _ => None,
4744 }
4745 }
4746
4747 pub fn body_id(&self) -> Option<BodyId> {
4748 Some(self.associated_body()?.1)
4749 }
4750
4751 pub fn generics(self) -> Option<&'hir Generics<'hir>> {
4752 match self {
4753 Node::ForeignItem(ForeignItem {
4754 kind: ForeignItemKind::Fn(_, _, generics), ..
4755 })
4756 | Node::TraitItem(TraitItem { generics, .. })
4757 | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
4758 Node::Item(item) => item.kind.generics(),
4759 _ => None,
4760 }
4761 }
4762
4763 pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
4764 match self {
4765 Node::Item(i) => Some(OwnerNode::Item(i)),
4766 Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
4767 Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
4768 Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
4769 Node::Crate(i) => Some(OwnerNode::Crate(i)),
4770 Node::Synthetic => Some(OwnerNode::Synthetic),
4771 _ => None,
4772 }
4773 }
4774
4775 pub fn fn_kind(self) -> Option<FnKind<'hir>> {
4776 match self {
4777 Node::Item(i) => match i.kind {
4778 ItemKind::Fn { ident, sig, generics, .. } => {
4779 Some(FnKind::ItemFn(ident, generics, sig.header))
4780 }
4781 _ => None,
4782 },
4783 Node::TraitItem(ti) => match ti.kind {
4784 TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
4785 _ => None,
4786 },
4787 Node::ImplItem(ii) => match ii.kind {
4788 ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
4789 _ => None,
4790 },
4791 Node::Expr(e) => match e.kind {
4792 ExprKind::Closure { .. } => Some(FnKind::Closure),
4793 _ => None,
4794 },
4795 _ => None,
4796 }
4797 }
4798
4799 expect_methods_self! {
4800 expect_param, &'hir Param<'hir>, Node::Param(n), n;
4801 expect_item, &'hir Item<'hir>, Node::Item(n), n;
4802 expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n;
4803 expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n;
4804 expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n;
4805 expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
4806 expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
4807 expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
4808 expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
4809 expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
4810 expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
4811 expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
4812 expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
4813 expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
4814 expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
4815 expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
4816 expect_opaque_ty, &'hir OpaqueTy<'hir>, Node::OpaqueTy(n), n;
4817 expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
4818 expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
4819 expect_arm, &'hir Arm<'hir>, Node::Arm(n), n;
4820 expect_block, &'hir Block<'hir>, Node::Block(n), n;
4821 expect_let_stmt, &'hir LetStmt<'hir>, Node::LetStmt(n), n;
4822 expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n;
4823 expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n;
4824 expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
4825 expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
4826 expect_infer, &'hir InferArg, Node::Infer(n), n;
4827 expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
4828 }
4829}
4830
4831#[cfg(target_pointer_width = "64")]
4833mod size_asserts {
4834 use rustc_data_structures::static_assert_size;
4835
4836 use super::*;
4837 static_assert_size!(Block<'_>, 48);
4839 static_assert_size!(Body<'_>, 24);
4840 static_assert_size!(Expr<'_>, 64);
4841 static_assert_size!(ExprKind<'_>, 48);
4842 static_assert_size!(FnDecl<'_>, 40);
4843 static_assert_size!(ForeignItem<'_>, 88);
4844 static_assert_size!(ForeignItemKind<'_>, 56);
4845 static_assert_size!(GenericArg<'_>, 16);
4846 static_assert_size!(GenericBound<'_>, 64);
4847 static_assert_size!(Generics<'_>, 56);
4848 static_assert_size!(Impl<'_>, 80);
4849 static_assert_size!(ImplItem<'_>, 88);
4850 static_assert_size!(ImplItemKind<'_>, 40);
4851 static_assert_size!(Item<'_>, 88);
4852 static_assert_size!(ItemKind<'_>, 64);
4853 static_assert_size!(LetStmt<'_>, 64);
4854 static_assert_size!(Param<'_>, 32);
4855 static_assert_size!(Pat<'_>, 72);
4856 static_assert_size!(Path<'_>, 40);
4857 static_assert_size!(PathSegment<'_>, 48);
4858 static_assert_size!(PatKind<'_>, 48);
4859 static_assert_size!(QPath<'_>, 24);
4860 static_assert_size!(Res, 12);
4861 static_assert_size!(Stmt<'_>, 32);
4862 static_assert_size!(StmtKind<'_>, 16);
4863 static_assert_size!(TraitItem<'_>, 88);
4864 static_assert_size!(TraitItemKind<'_>, 48);
4865 static_assert_size!(Ty<'_>, 48);
4866 static_assert_size!(TyKind<'_>, 32);
4867 }
4869
4870#[cfg(test)]
4871mod tests;