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 crate::hir::place::Place as HirPlace;
21use crate::infer::canonical::Canonical;
22use crate::mir::FakeReadCause;
23use crate::thir::DerefPatBorrowMode;
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::adjustment::PatAdjustment<'tcx>>>,
103
104 skipped_ref_pats: ItemLocalSet,
107
108 closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
111
112 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
147
148 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
153
154 coercion_casts: ItemLocalSet,
157
158 pub used_trait_imports: UnordSet<LocalDefId>,
161
162 pub tainted_by_errors: Option<ErrorGuaranteed>,
165
166 pub hidden_types: FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
171
172 pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
175
176 pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, HirId)>>,
199
200 pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
203
204 pub potentially_region_dependent_goals:
212 FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
213
214 pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
217
218 pub transmutes_to_check: Vec<(Ty<'tcx>, Ty<'tcx>, HirId)>,
222
223 offset_of_data: ItemLocalMap<Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>>,
225}
226
227impl<'tcx> TypeckResults<'tcx> {
228 pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
229 TypeckResults {
230 hir_owner,
231 type_dependent_defs: Default::default(),
232 field_indices: Default::default(),
233 user_provided_types: Default::default(),
234 user_provided_sigs: Default::default(),
235 node_types: Default::default(),
236 node_args: Default::default(),
237 adjustments: Default::default(),
238 pat_binding_modes: Default::default(),
239 pat_adjustments: Default::default(),
240 rust_2024_migration_desugared_pats: Default::default(),
241 skipped_ref_pats: Default::default(),
242 closure_kind_origins: Default::default(),
243 liberated_fn_sigs: Default::default(),
244 fru_field_types: Default::default(),
245 coercion_casts: Default::default(),
246 used_trait_imports: Default::default(),
247 tainted_by_errors: None,
248 hidden_types: Default::default(),
249 closure_min_captures: Default::default(),
250 closure_fake_reads: Default::default(),
251 coroutine_stalled_predicates: Default::default(),
252 potentially_region_dependent_goals: Default::default(),
253 closure_size_eval: Default::default(),
254 transmutes_to_check: Default::default(),
255 offset_of_data: Default::default(),
256 }
257 }
258
259 pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res {
261 match *qpath {
262 hir::QPath::Resolved(_, path) => path.res,
263 hir::QPath::TypeRelative(..) => self
264 .type_dependent_def(id)
265 .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
266 }
267 }
268
269 pub fn type_dependent_defs(
270 &self,
271 ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
272 LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
273 }
274
275 pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
276 validate_hir_id_for_typeck_results(self.hir_owner, id);
277 self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
278 }
279
280 pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
281 self.type_dependent_def(id).map(|(_, def_id)| def_id)
282 }
283
284 pub fn type_dependent_defs_mut(
285 &mut self,
286 ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
287 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
288 }
289
290 pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> {
291 LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
292 }
293
294 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> {
295 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
296 }
297
298 pub fn field_index(&self, id: HirId) -> FieldIdx {
299 self.field_indices().get(id).cloned().expect("no index for a field")
300 }
301
302 pub fn opt_field_index(&self, id: HirId) -> Option<FieldIdx> {
303 self.field_indices().get(id).cloned()
304 }
305
306 pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
307 LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
308 }
309
310 pub fn user_provided_types_mut(
311 &mut self,
312 ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
313 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
314 }
315
316 pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
317 LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
318 }
319
320 pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
321 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
322 }
323
324 pub fn node_type(&self, id: HirId) -> Ty<'tcx> {
325 self.node_type_opt(id).unwrap_or_else(|| {
326 bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id)))
327 })
328 }
329
330 pub fn node_type_opt(&self, id: HirId) -> Option<Ty<'tcx>> {
331 validate_hir_id_for_typeck_results(self.hir_owner, id);
332 self.node_types.get(&id.local_id).cloned()
333 }
334
335 pub fn node_args_mut(&mut self) -> LocalTableInContextMut<'_, GenericArgsRef<'tcx>> {
336 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args }
337 }
338
339 pub fn node_args(&self, id: HirId) -> GenericArgsRef<'tcx> {
340 validate_hir_id_for_typeck_results(self.hir_owner, id);
341 self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty())
342 }
343
344 pub fn node_args_opt(&self, id: HirId) -> Option<GenericArgsRef<'tcx>> {
345 validate_hir_id_for_typeck_results(self.hir_owner, id);
346 self.node_args.get(&id.local_id).cloned()
347 }
348
349 pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
354 self.node_type(pat.hir_id)
355 }
356
357 pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
368 self.node_type(expr.hir_id)
369 }
370
371 pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
372 self.node_type_opt(expr.hir_id)
373 }
374
375 pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
376 LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
377 }
378
379 pub fn adjustments_mut(
380 &mut self,
381 ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
382 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
383 }
384
385 pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
386 validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
387 self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
388 }
389
390 pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
393 self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
394 }
395
396 pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
397 self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
398 }
399
400 pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
401 if let hir::ExprKind::Path(_) = expr.kind {
404 return false;
405 }
406
407 matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
408 }
409
410 pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode {
413 self.pat_binding_modes().get(id).copied().unwrap_or_else(|| {
414 s.dcx().span_bug(sp, "missing binding mode");
415 })
416 }
417
418 pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
419 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
420 }
421
422 pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
423 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
424 }
425
426 pub fn pat_adjustments(
427 &self,
428 ) -> LocalTableInContext<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> {
429 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
430 }
431
432 pub fn pat_adjustments_mut(
433 &mut self,
434 ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::PatAdjustment<'tcx>>> {
435 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
436 }
437
438 pub fn rust_2024_migration_desugared_pats(
439 &self,
440 ) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
441 LocalTableInContext {
442 hir_owner: self.hir_owner,
443 data: &self.rust_2024_migration_desugared_pats,
444 }
445 }
446
447 pub fn rust_2024_migration_desugared_pats_mut(
448 &mut self,
449 ) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
450 LocalTableInContextMut {
451 hir_owner: self.hir_owner,
452 data: &mut self.rust_2024_migration_desugared_pats,
453 }
454 }
455
456 pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
457 LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
458 }
459
460 pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
461 LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
462 }
463
464 pub fn pat_has_ref_mut_binding(&self, pat: &hir::Pat<'_>) -> bool {
473 let mut has_ref_mut = false;
474 pat.walk(|pat| {
475 if let hir::PatKind::Binding(_, id, _, _) = pat.kind
476 && let Some(BindingMode(ByRef::Yes(_, Mutability::Mut), _)) =
477 self.pat_binding_modes().get(id)
478 {
479 has_ref_mut = true;
480 false
482 } else {
483 true
484 }
485 });
486 has_ref_mut
487 }
488
489 pub fn deref_pat_borrow_mode(
496 &self,
497 pointer_ty: Ty<'_>,
498 inner: &hir::Pat<'_>,
499 ) -> DerefPatBorrowMode {
500 if pointer_ty.is_box() {
501 DerefPatBorrowMode::Box
502 } else {
503 let mutability =
504 if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
505 DerefPatBorrowMode::Borrow(mutability)
506 }
507 }
508
509 pub fn closure_min_captures_flattened(
512 &self,
513 closure_def_id: LocalDefId,
514 ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
515 self.closure_min_captures
516 .get(&closure_def_id)
517 .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
518 .into_iter()
519 .flatten()
520 }
521
522 pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
523 LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
524 }
525
526 pub fn closure_kind_origins_mut(
527 &mut self,
528 ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
529 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
530 }
531
532 pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
533 LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
534 }
535
536 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
537 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
538 }
539
540 pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
541 LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
542 }
543
544 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
545 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
546 }
547
548 pub fn is_coercion_cast(&self, hir_id: HirId) -> bool {
549 validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
550 self.coercion_casts.contains(&hir_id.local_id)
551 }
552
553 pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
554 self.coercion_casts.insert(id);
555 }
556
557 pub fn coercion_casts(&self) -> &ItemLocalSet {
558 &self.coercion_casts
559 }
560
561 pub fn offset_of_data(&self) -> LocalTableInContext<'_, Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>> {
562 LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data }
563 }
564
565 pub fn offset_of_data_mut(
566 &mut self,
567 ) -> LocalTableInContextMut<'_, Vec<(Ty<'tcx>, VariantIdx, FieldIdx)>> {
568 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data }
569 }
570}
571
572#[inline]
580fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
581 if hir_id.owner != hir_owner {
582 invalid_hir_id_for_typeck_results(hir_owner, hir_id);
583 }
584}
585
586#[cold]
587#[inline(never)]
588fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
589 ty::tls::with(|tcx| {
590 bug!(
591 "node {} cannot be placed in TypeckResults with hir_owner {:?}",
592 tcx.hir_id_to_string(hir_id),
593 hir_owner
594 )
595 });
596}
597
598pub struct LocalTableInContext<'a, V> {
599 hir_owner: OwnerId,
600 data: &'a ItemLocalMap<V>,
601}
602
603impl<'a, V> LocalTableInContext<'a, V> {
604 pub fn contains_key(&self, id: HirId) -> bool {
605 validate_hir_id_for_typeck_results(self.hir_owner, id);
606 self.data.contains_key(&id.local_id)
607 }
608
609 pub fn get(&self, id: HirId) -> Option<&'a V> {
610 validate_hir_id_for_typeck_results(self.hir_owner, id);
611 self.data.get(&id.local_id)
612 }
613
614 pub fn items(
615 &self,
616 ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator<Item = (hir::ItemLocalId, &'a V)>>
617 {
618 self.data.items().map(|(id, value)| (*id, value))
619 }
620
621 pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
622 self.data.items().map(|(&k, v)| (k, v)).into_sorted_stable_ord_by_key(|(k, _)| k)
623 }
624}
625
626impl<'a, V> ::std::ops::Index<HirId> for LocalTableInContext<'a, V> {
627 type Output = V;
628
629 fn index(&self, key: HirId) -> &V {
630 self.get(key).unwrap_or_else(|| {
631 bug!("LocalTableInContext({:?}): key {:?} not found", self.hir_owner, key)
632 })
633 }
634}
635
636pub struct LocalTableInContextMut<'a, V> {
637 hir_owner: OwnerId,
638 data: &'a mut ItemLocalMap<V>,
639}
640
641impl<'a, V> LocalTableInContextMut<'a, V> {
642 pub fn get_mut(&mut self, id: HirId) -> Option<&mut V> {
643 validate_hir_id_for_typeck_results(self.hir_owner, id);
644 self.data.get_mut(&id.local_id)
645 }
646
647 pub fn get(&mut self, id: HirId) -> Option<&V> {
648 validate_hir_id_for_typeck_results(self.hir_owner, id);
649 self.data.get(&id.local_id)
650 }
651
652 pub fn entry(&mut self, id: HirId) -> Entry<'_, hir::ItemLocalId, V> {
653 validate_hir_id_for_typeck_results(self.hir_owner, id);
654 self.data.entry(id.local_id)
655 }
656
657 pub fn insert(&mut self, id: HirId, val: V) -> Option<V> {
658 validate_hir_id_for_typeck_results(self.hir_owner, id);
659 self.data.insert(id.local_id, val)
660 }
661
662 pub fn remove(&mut self, id: HirId) -> Option<V> {
663 validate_hir_id_for_typeck_results(self.hir_owner, id);
664 self.data.remove(&id.local_id)
665 }
666
667 pub fn extend(&mut self, items: UnordItems<(HirId, V), impl Iterator<Item = (HirId, V)>>) {
668 self.data.extend_unord(items.map(|(id, value)| {
669 validate_hir_id_for_typeck_results(self.hir_owner, id);
670 (id.local_id, value)
671 }))
672 }
673}
674
675#[derive(Clone, Copy, Debug)]
676pub struct LocalSetInContext<'a> {
677 hir_owner: OwnerId,
678 data: &'a ItemLocalSet,
679}
680
681impl<'a> LocalSetInContext<'a> {
682 pub fn is_empty(&self) -> bool {
683 self.data.is_empty()
684 }
685
686 pub fn contains(&self, id: hir::HirId) -> bool {
687 validate_hir_id_for_typeck_results(self.hir_owner, id);
688 self.data.contains(&id.local_id)
689 }
690}
691
692#[derive(Debug)]
693pub struct LocalSetInContextMut<'a> {
694 hir_owner: OwnerId,
695 data: &'a mut ItemLocalSet,
696}
697
698impl<'a> LocalSetInContextMut<'a> {
699 pub fn is_empty(&self) -> bool {
700 self.data.is_empty()
701 }
702
703 pub fn contains(&self, id: hir::HirId) -> bool {
704 validate_hir_id_for_typeck_results(self.hir_owner, id);
705 self.data.contains(&id.local_id)
706 }
707 pub fn insert(&mut self, id: hir::HirId) -> bool {
708 validate_hir_id_for_typeck_results(self.hir_owner, id);
709 self.data.insert(id.local_id)
710 }
711
712 pub fn remove(&mut self, id: hir::HirId) -> bool {
713 validate_hir_id_for_typeck_results(self.hir_owner, id);
714 self.data.remove(&id.local_id)
715 }
716}
717
718rustc_index::newtype_index! {
719 #[derive(HashStable)]
720 #[encodable]
721 #[debug_format = "UserType({})"]
722 pub struct UserTypeAnnotationIndex {
723 const START_INDEX = 0;
724 }
725}
726
727pub type CanonicalUserTypeAnnotations<'tcx> =
729 IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
730
731#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
732pub struct CanonicalUserTypeAnnotation<'tcx> {
733 #[type_foldable(identity)]
734 #[type_visitable(ignore)]
735 pub user_ty: Box<CanonicalUserType<'tcx>>,
736 pub span: Span,
737 pub inferred_ty: Ty<'tcx>,
738}
739
740pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
742
743#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
744#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
745pub struct UserType<'tcx> {
746 pub kind: UserTypeKind<'tcx>,
747 pub bounds: ty::Clauses<'tcx>,
748}
749
750impl<'tcx> UserType<'tcx> {
751 pub fn new(kind: UserTypeKind<'tcx>) -> UserType<'tcx> {
752 UserType { kind, bounds: ty::ListWithCachedTypeInfo::empty() }
753 }
754
755 pub fn new_with_bounds(kind: UserTypeKind<'tcx>, bounds: ty::Clauses<'tcx>) -> UserType<'tcx> {
758 UserType { kind, bounds }
759 }
760}
761
762#[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
766#[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable)]
767pub enum UserTypeKind<'tcx> {
768 Ty(Ty<'tcx>),
769
770 TypeOf(DefId, UserArgs<'tcx>),
773}
774
775pub trait IsIdentity {
776 fn is_identity(&self) -> bool;
777}
778
779impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
780 fn is_identity(&self) -> bool {
783 if !self.value.bounds.is_empty() {
784 return false;
785 }
786
787 match self.value.kind {
788 UserTypeKind::Ty(_) => false,
789 UserTypeKind::TypeOf(_, user_args) => {
790 if user_args.user_self_ty.is_some() {
791 return false;
792 }
793
794 iter::zip(user_args.args, BoundVar::ZERO..).all(|(arg, cvar)| {
795 match arg.kind() {
796 GenericArgKind::Type(ty) => match ty.kind() {
797 ty::Bound(debruijn, b) => {
798 assert_eq!(*debruijn, ty::BoundVarIndexKind::Canonical);
800 cvar == b.var
801 }
802 _ => false,
803 },
804
805 GenericArgKind::Lifetime(r) => match r.kind() {
806 ty::ReBound(debruijn, b) => {
807 assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
809 cvar == b.var
810 }
811 _ => false,
812 },
813
814 GenericArgKind::Const(ct) => match ct.kind() {
815 ty::ConstKind::Bound(debruijn, b) => {
816 assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
818 cvar == b.var
819 }
820 _ => false,
821 },
822 }
823 })
824 }
825 }
826 }
827}
828
829impl<'tcx> std::fmt::Display for UserType<'tcx> {
830 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
831 if self.bounds.is_empty() {
832 self.kind.fmt(f)
833 } else {
834 self.kind.fmt(f)?;
835 write!(f, " + ")?;
836 std::fmt::Debug::fmt(&self.bounds, f)
837 }
838 }
839}
840
841impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
842 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
843 match self {
844 Self::Ty(arg0) => {
845 ty::print::with_no_trimmed_paths!(write!(f, "Ty({})", arg0))
846 }
847 Self::TypeOf(arg0, arg1) => write!(f, "TypeOf({:?}, {:?})", arg0, arg1),
848 }
849 }
850}
851
852#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
855pub struct Rust2024IncompatiblePatInfo {
856 pub primary_labels: Vec<(Span, String)>,
858 pub bad_mut_modifiers: bool,
860 pub bad_ref_modifiers: bool,
862 pub bad_ref_pats: bool,
864 pub suggest_eliding_modes: bool,
866}