1use std::collections::hash_map::Entry;
2use std::hash::Hash;
3use std::iter;
4
5use rustc_abi::{FieldIdx, VariantIdx};
6use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
7use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet};
8use rustc_errors::ErrorGuaranteed;
9use rustc_hir::def::{DefKind, Res};
10use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
11use rustc_hir::hir_id::OwnerId;
12use rustc_hir::{
13 self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
14};
15use rustc_index::IndexVec;
16use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
17use rustc_session::Session;
18use rustc_span::Span;
19
20use super::RvalueScopes;
21use crate::hir::place::Place as HirPlace;
22use crate::infer::canonical::Canonical;
23use crate::mir::FakeReadCause;
24use crate::traits::ObligationCause;
25use crate::ty::{
26 self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs,
27 GenericArgsRef, Ty, UserArgs, tls,
28};
29
30#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
31pub struct TypeckResults<'tcx> {
32 pub hir_owner: OwnerId,
34
35 type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
38
39 field_indices: ItemLocalMap<FieldIdx>,
44
45 node_types: ItemLocalMap<Ty<'tcx>>,
49
50 node_args: ItemLocalMap<GenericArgsRef<'tcx>>,
55
56 user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
66
67 pub user_provided_sigs: LocalDefIdMap<CanonicalPolyFnSig<'tcx>>,
70
71 adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
72
73 pat_binding_modes: ItemLocalMap<BindingMode>,
75
76 rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>,
79
80 pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
94
95 skipped_ref_pats: ItemLocalSet,
98
99 closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
102
103 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
138
139 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
144
145 coercion_casts: ItemLocalSet,
148
149 pub used_trait_imports: UnordSet<LocalDefId>,
152
153 pub tainted_by_errors: Option<ErrorGuaranteed>,
156
157 pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
162
163 pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
166
167 pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, HirId)>>,
190
191 pub rvalue_scopes: RvalueScopes,
195
196 pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
199
200 pub treat_byte_string_as_slice: ItemLocalSet,
205
206 pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
209
210 offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>,
212}
213
214impl<'tcx> TypeckResults<'tcx> {
215 pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
216 TypeckResults {
217 hir_owner,
218 type_dependent_defs: Default::default(),
219 field_indices: Default::default(),
220 user_provided_types: Default::default(),
221 user_provided_sigs: Default::default(),
222 node_types: Default::default(),
223 node_args: Default::default(),
224 adjustments: Default::default(),
225 pat_binding_modes: Default::default(),
226 pat_adjustments: Default::default(),
227 rust_2024_migration_desugared_pats: Default::default(),
228 skipped_ref_pats: Default::default(),
229 closure_kind_origins: Default::default(),
230 liberated_fn_sigs: Default::default(),
231 fru_field_types: Default::default(),
232 coercion_casts: Default::default(),
233 used_trait_imports: Default::default(),
234 tainted_by_errors: None,
235 concrete_opaque_types: Default::default(),
236 closure_min_captures: Default::default(),
237 closure_fake_reads: Default::default(),
238 rvalue_scopes: Default::default(),
239 coroutine_stalled_predicates: Default::default(),
240 treat_byte_string_as_slice: Default::default(),
241 closure_size_eval: Default::default(),
242 offset_of_data: Default::default(),
243 }
244 }
245
246 pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res {
248 match *qpath {
249 hir::QPath::Resolved(_, path) => path.res,
250 hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
251 .type_dependent_def(id)
252 .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
253 }
254 }
255
256 pub fn type_dependent_defs(
257 &self,
258 ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
259 LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
260 }
261
262 pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
263 validate_hir_id_for_typeck_results(self.hir_owner, id);
264 self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
265 }
266
267 pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
268 self.type_dependent_def(id).map(|(_, def_id)| def_id)
269 }
270
271 pub fn type_dependent_defs_mut(
272 &mut self,
273 ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
274 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
275 }
276
277 pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> {
278 LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
279 }
280
281 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> {
282 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
283 }
284
285 pub fn field_index(&self, id: HirId) -> FieldIdx {
286 self.field_indices().get(id).cloned().expect("no index for a field")
287 }
288
289 pub fn opt_field_index(&self, id: HirId) -> Option<FieldIdx> {
290 self.field_indices().get(id).cloned()
291 }
292
293 pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
294 LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
295 }
296
297 pub fn user_provided_types_mut(
298 &mut self,
299 ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
300 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
301 }
302
303 pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
304 LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
305 }
306
307 pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
308 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
309 }
310
311 pub fn node_type(&self, id: HirId) -> Ty<'tcx> {
312 self.node_type_opt(id).unwrap_or_else(|| {
313 bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id)))
314 })
315 }
316
317 pub fn node_type_opt(&self, id: HirId) -> Option<Ty<'tcx>> {
318 validate_hir_id_for_typeck_results(self.hir_owner, id);
319 self.node_types.get(&id.local_id).cloned()
320 }
321
322 pub fn node_args_mut(&mut self) -> LocalTableInContextMut<'_, GenericArgsRef<'tcx>> {
323 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args }
324 }
325
326 pub fn node_args(&self, id: HirId) -> GenericArgsRef<'tcx> {
327 validate_hir_id_for_typeck_results(self.hir_owner, id);
328 self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty())
329 }
330
331 pub fn node_args_opt(&self, id: HirId) -> Option<GenericArgsRef<'tcx>> {
332 validate_hir_id_for_typeck_results(self.hir_owner, id);
333 self.node_args.get(&id.local_id).cloned()
334 }
335
336 pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
341 self.node_type(pat.hir_id)
342 }
343
344 pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
355 self.node_type(expr.hir_id)
356 }
357
358 pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
359 self.node_type_opt(expr.hir_id)
360 }
361
362 pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
363 LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
364 }
365
366 pub fn adjustments_mut(
367 &mut self,
368 ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
369 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
370 }
371
372 pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
373 validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
374 self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
375 }
376
377 pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
380 self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
381 }
382
383 pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
384 self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
385 }
386
387 pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
388 if let hir::ExprKind::Path(_) = expr.kind {
391 return false;
392 }
393
394 matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
395 }
396
397 pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode {
400 self.pat_binding_modes().get(id).copied().unwrap_or_else(|| {
401 s.dcx().span_bug(sp, "missing binding mode");
402 })
403 }
404
405 pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
406 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
407 }
408
409 pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
410 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
411 }
412
413 pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
414 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
415 }
416
417 pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
418 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
419 }
420
421 pub fn rust_2024_migration_desugared_pats(
422 &self,
423 ) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
424 LocalTableInContext {
425 hir_owner: self.hir_owner,
426 data: &self.rust_2024_migration_desugared_pats,
427 }
428 }
429
430 pub fn rust_2024_migration_desugared_pats_mut(
431 &mut self,
432 ) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
433 LocalTableInContextMut {
434 hir_owner: self.hir_owner,
435 data: &mut self.rust_2024_migration_desugared_pats,
436 }
437 }
438
439 pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
440 LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
441 }
442
443 pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
444 LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
445 }
446
447 pub fn pat_has_ref_mut_binding(&self, pat: &hir::Pat<'_>) -> bool {
456 let mut has_ref_mut = false;
457 pat.walk(|pat| {
458 if let hir::PatKind::Binding(_, id, _, _) = pat.kind
459 && let Some(BindingMode(ByRef::Yes(Mutability::Mut), _)) =
460 self.pat_binding_modes().get(id)
461 {
462 has_ref_mut = true;
463 false
465 } else {
466 true
467 }
468 });
469 has_ref_mut
470 }
471
472 pub fn closure_min_captures_flattened(
475 &self,
476 closure_def_id: LocalDefId,
477 ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
478 self.closure_min_captures
479 .get(&closure_def_id)
480 .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
481 .into_iter()
482 .flatten()
483 }
484
485 pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
486 LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
487 }
488
489 pub fn closure_kind_origins_mut(
490 &mut self,
491 ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
492 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
493 }
494
495 pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
496 LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
497 }
498
499 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
500 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
501 }
502
503 pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
504 LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
505 }
506
507 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
508 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
509 }
510
511 pub fn is_coercion_cast(&self, hir_id: HirId) -> bool {
512 validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
513 self.coercion_casts.contains(&hir_id.local_id)
514 }
515
516 pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
517 self.coercion_casts.insert(id);
518 }
519
520 pub fn coercion_casts(&self) -> &ItemLocalSet {
521 &self.coercion_casts
522 }
523
524 pub fn offset_of_data(
525 &self,
526 ) -> LocalTableInContext<'_, (Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)> {
527 LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data }
528 }
529
530 pub fn offset_of_data_mut(
531 &mut self,
532 ) -> LocalTableInContextMut<'_, (Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)> {
533 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data }
534 }
535}
536
537#[inline]
545fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
546 if hir_id.owner != hir_owner {
547 invalid_hir_id_for_typeck_results(hir_owner, hir_id);
548 }
549}
550
551#[cold]
552#[inline(never)]
553fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
554 ty::tls::with(|tcx| {
555 bug!(
556 "node {} cannot be placed in TypeckResults with hir_owner {:?}",
557 tcx.hir_id_to_string(hir_id),
558 hir_owner
559 )
560 });
561}
562
563pub struct LocalTableInContext<'a, V> {
564 hir_owner: OwnerId,
565 data: &'a ItemLocalMap<V>,
566}
567
568impl<'a, V> LocalTableInContext<'a, V> {
569 pub fn contains_key(&self, id: HirId) -> bool {
570 validate_hir_id_for_typeck_results(self.hir_owner, id);
571 self.data.contains_key(&id.local_id)
572 }
573
574 pub fn get(&self, id: HirId) -> Option<&'a V> {
575 validate_hir_id_for_typeck_results(self.hir_owner, id);
576 self.data.get(&id.local_id)
577 }
578
579 pub fn items(
580 &self,
581 ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator<Item = (hir::ItemLocalId, &'a V)>>
582 {
583 self.data.items().map(|(id, value)| (*id, value))
584 }
585
586 pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
587 self.data.items().map(|(&k, v)| (k, v)).into_sorted_stable_ord_by_key(|(k, _)| k)
588 }
589}
590
591impl<'a, V> ::std::ops::Index<HirId> for LocalTableInContext<'a, V> {
592 type Output = V;
593
594 fn index(&self, key: HirId) -> &V {
595 self.get(key).unwrap_or_else(|| {
596 bug!("LocalTableInContext({:?}): key {:?} not found", self.hir_owner, key)
597 })
598 }
599}
600
601pub struct LocalTableInContextMut<'a, V> {
602 hir_owner: OwnerId,
603 data: &'a mut ItemLocalMap<V>,
604}
605
606impl<'a, V> LocalTableInContextMut<'a, V> {
607 pub fn get_mut(&mut self, id: HirId) -> Option<&mut V> {
608 validate_hir_id_for_typeck_results(self.hir_owner, id);
609 self.data.get_mut(&id.local_id)
610 }
611
612 pub fn get(&mut self, id: HirId) -> Option<&V> {
613 validate_hir_id_for_typeck_results(self.hir_owner, id);
614 self.data.get(&id.local_id)
615 }
616
617 pub fn entry(&mut self, id: HirId) -> Entry<'_, hir::ItemLocalId, V> {
618 validate_hir_id_for_typeck_results(self.hir_owner, id);
619 self.data.entry(id.local_id)
620 }
621
622 pub fn insert(&mut self, id: HirId, val: V) -> Option<V> {
623 validate_hir_id_for_typeck_results(self.hir_owner, id);
624 self.data.insert(id.local_id, val)
625 }
626
627 pub fn remove(&mut self, id: HirId) -> Option<V> {
628 validate_hir_id_for_typeck_results(self.hir_owner, id);
629 self.data.remove(&id.local_id)
630 }
631
632 pub fn extend(&mut self, items: UnordItems<(HirId, V), impl Iterator<Item = (HirId, V)>>) {
633 self.data.extend_unord(items.map(|(id, value)| {
634 validate_hir_id_for_typeck_results(self.hir_owner, id);
635 (id.local_id, value)
636 }))
637 }
638}
639
640#[derive(Clone, Copy, Debug)]
641pub struct LocalSetInContext<'a> {
642 hir_owner: OwnerId,
643 data: &'a ItemLocalSet,
644}
645
646impl<'a> LocalSetInContext<'a> {
647 pub fn is_empty(&self) -> bool {
648 self.data.is_empty()
649 }
650
651 pub fn contains(&self, id: hir::HirId) -> bool {
652 validate_hir_id_for_typeck_results(self.hir_owner, id);
653 self.data.contains(&id.local_id)
654 }
655}
656
657#[derive(Debug)]
658pub struct LocalSetInContextMut<'a> {
659 hir_owner: OwnerId,
660 data: &'a mut ItemLocalSet,
661}
662
663impl<'a> LocalSetInContextMut<'a> {
664 pub fn is_empty(&self) -> bool {
665 self.data.is_empty()
666 }
667
668 pub fn contains(&self, id: hir::HirId) -> bool {
669 validate_hir_id_for_typeck_results(self.hir_owner, id);
670 self.data.contains(&id.local_id)
671 }
672 pub fn insert(&mut self, id: hir::HirId) -> bool {
673 validate_hir_id_for_typeck_results(self.hir_owner, id);
674 self.data.insert(id.local_id)
675 }
676
677 pub fn remove(&mut self, id: hir::HirId) -> bool {
678 validate_hir_id_for_typeck_results(self.hir_owner, id);
679 self.data.remove(&id.local_id)
680 }
681}
682
683rustc_index::newtype_index! {
684 #[derive(HashStable)]
685 #[encodable]
686 #[debug_format = "UserType({})"]
687 pub struct UserTypeAnnotationIndex {
688 const START_INDEX = 0;
689 }
690}
691
692pub type CanonicalUserTypeAnnotations<'tcx> =
694 IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
695
696#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
697pub struct CanonicalUserTypeAnnotation<'tcx> {
698 pub user_ty: Box<CanonicalUserType<'tcx>>,
699 pub span: Span,
700 pub inferred_ty: Ty<'tcx>,
701}
702
703pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
705
706#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
707#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
708pub struct UserType<'tcx> {
709 pub kind: UserTypeKind<'tcx>,
710 pub bounds: ty::Clauses<'tcx>,
711}
712
713impl<'tcx> UserType<'tcx> {
714 pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
715 UserType { kind, bounds: ty::ListWithCachedTypeInfo::empty() }
716 }
717
718 pub fn new_with_bounds(kind: UserTypeKind<'tcx>, bounds: ty::Clauses<'tcx>) -> UserType<'tcx> {
721 UserType { kind, bounds }
722 }
723}
724
725#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
729#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
730pub enum UserTypeKind<'tcx> {
731 Ty(Ty<'tcx>),
732
733 TypeOf(DefId, UserArgs<'tcx>),
736}
737
738pub trait IsIdentity {
739 fn is_identity(&self) -> bool;
740}
741
742impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
743 fn is_identity(&self) -> bool {
746 if !self.value.bounds.is_empty() {
747 return false;
748 }
749
750 match self.value.kind {
751 UserTypeKind::Ty(_) => false,
752 UserTypeKind::TypeOf(_, user_args) => {
753 if user_args.user_self_ty.is_some() {
754 return false;
755 }
756
757 iter::zip(user_args.args, BoundVar::ZERO..).all(|(kind, cvar)| {
758 match kind.unpack() {
759 GenericArgKind::Type(ty) => match ty.kind() {
760 ty::Bound(debruijn, b) => {
761 assert_eq!(*debruijn, ty::INNERMOST);
763 cvar == b.var
764 }
765 _ => false,
766 },
767
768 GenericArgKind::Lifetime(r) => match *r {
769 ty::ReBound(debruijn, br) => {
770 assert_eq!(debruijn, ty::INNERMOST);
772 cvar == br.var
773 }
774 _ => false,
775 },
776
777 GenericArgKind::Const(ct) => match ct.kind() {
778 ty::ConstKind::Bound(debruijn, b) => {
779 assert_eq!(debruijn, ty::INNERMOST);
781 cvar == b
782 }
783 _ => false,
784 },
785 }
786 })
787 }
788 }
789 }
790}
791
792impl<'tcx> std::fmt::Display for UserType<'tcx> {
793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
794 if self.bounds.is_empty() {
795 self.kind.fmt(f)
796 } else {
797 self.kind.fmt(f)?;
798 write!(f, " + ")?;
799 std::fmt::Debug::fmt(&self.bounds, f)
800 }
801 }
802}
803
804impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
805 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
806 match self {
807 Self::Ty(arg0) => {
808 ty::print::with_no_trimmed_paths!(write!(f, "Ty({})", arg0))
809 }
810 Self::TypeOf(arg0, arg1) => write!(f, "TypeOf({:?}, {:?})", arg0, arg1),
811 }
812 }
813}
814
815#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
818pub struct Rust2024IncompatiblePatInfo {
819 pub primary_labels: Vec<(Span, String)>,
821 pub bad_modifiers: bool,
823 pub bad_ref_pats: bool,
825 pub suggest_eliding_modes: bool,
827}