2 hir::place::Place as HirPlace,
3 infer::canonical::Canonical,
4 traits::ObligationCause,
6 self, tls, BindingMode, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData,
7 GenericArgKind, InternalSubsts, SubstsRef, Ty, UserSubsts,
10 use rustc_data_structures::{
13 unord::{UnordItems, UnordSet},
16 use rustc_errors::ErrorGuaranteed;
20 def_id::{DefId, LocalDefId, LocalDefIdMap},
22 HirId, ItemLocalId, ItemLocalMap, ItemLocalSet,
24 use rustc_index::vec::{Idx, IndexVec};
25 use rustc_macros::HashStable;
26 use rustc_middle::mir::FakeReadCause;
27 use rustc_session::Session;
29 use std::{collections::hash_map::Entry, hash::Hash, iter};
31 use super::RvalueScopes;
33 #[derive(TyEncodable, TyDecodable, Debug, HashStable)]
34 pub struct TypeckResults<'tcx> {
35 /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
36 pub hir_owner: OwnerId,
38 /// Resolved definitions for `<T>::X` associated paths and
39 /// method calls, including those of overloaded operators.
40 type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
42 /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
43 /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
44 /// about the field you also need definition of the variant to which the field
45 /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
46 field_indices: ItemLocalMap<usize>,
48 /// Stores the types for various nodes in the AST. Note that this table
49 /// is not guaranteed to be populated outside inference. See
50 /// typeck::check::fn_ctxt for details.
51 node_types: ItemLocalMap<Ty<'tcx>>,
53 /// Stores the type parameters which were substituted to obtain the type
54 /// of this node. This only applies to nodes that refer to entities
55 /// parameterized by type parameters, such as generic fns, types, or
57 node_substs: ItemLocalMap<SubstsRef<'tcx>>,
59 /// This will either store the canonicalized types provided by the user
60 /// or the substitutions that the user explicitly gave (if any) attached
61 /// to `id`. These will not include any inferred values. The canonical form
62 /// is used to capture things like `_` or other unspecified values.
64 /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
65 /// canonical substitutions would include only `for<X> { Vec<X> }`.
67 /// See also `AscribeUserType` statement in MIR.
68 user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
70 /// Stores the canonicalized types provided by the user. See also
71 /// `AscribeUserType` statement in MIR.
72 pub user_provided_sigs: LocalDefIdMap<CanonicalPolyFnSig<'tcx>>,
74 adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
76 /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
77 pat_binding_modes: ItemLocalMap<BindingMode>,
79 /// Stores the types which were implicitly dereferenced in pattern binding modes
80 /// for later usage in THIR lowering. For example,
83 /// match &&Some(5i32) {
88 /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
91 /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
92 pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
94 /// Records the reasons that we picked the kind of each closure;
95 /// not all closures are present in the map.
96 closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
98 /// For each fn, records the "liberated" types of its arguments
99 /// and return type. Liberated means that all bound regions
100 /// (including late-bound regions) are replaced with free
101 /// equivalents. This table is not used in codegen (since regions
102 /// are erased there) and hence is not serialized to metadata.
104 /// This table also contains the "revealed" values for any `impl Trait`
105 /// that appear in the signature and whose values are being inferred
106 /// by this function.
111 /// # use std::fmt::Debug;
112 /// fn foo(x: &u32) -> impl Debug { *x }
115 /// The function signature here would be:
117 /// ```ignore (illustrative)
118 /// for<'a> fn(&'a u32) -> Foo
121 /// where `Foo` is an opaque type created for this function.
124 /// The *liberated* form of this would be
126 /// ```ignore (illustrative)
127 /// fn(&'a u32) -> u32
130 /// Note that `'a` is not bound (it would be an `ReFree`) and
131 /// that the `Foo` opaque type is replaced by its hidden type.
132 liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
134 /// For each FRU expression, record the normalized types of the fields
135 /// of the struct - this is needed because it is non-trivial to
136 /// normalize while preserving regions. This table is used only in
137 /// MIR construction and hence is not serialized to metadata.
138 fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
140 /// For every coercion cast we add the HIR node ID of the cast
141 /// expression to this set.
142 coercion_casts: ItemLocalSet,
144 /// Set of trait imports actually used in the method resolution.
145 /// This is used for warning unused imports. During type
146 /// checking, this `Lrc` should not be cloned: it must have a ref-count
147 /// of 1 so that we can insert things into the set mutably.
148 pub used_trait_imports: Lrc<UnordSet<LocalDefId>>,
150 /// If any errors occurred while type-checking this body,
151 /// this field will be set to `Some(ErrorGuaranteed)`.
152 pub tainted_by_errors: Option<ErrorGuaranteed>,
154 /// All the opaque types that have hidden types set
155 /// by this function. We also store the
156 /// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
157 /// even if they are only set in dead code (which doesn't show up in MIR).
158 pub concrete_opaque_types: VecMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
160 /// Tracks the minimum captures required for a closure;
161 /// see `MinCaptureInformationMap` for more details.
162 pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
164 /// Tracks the fake reads required for a closure and the reason for the fake read.
165 /// When performing pattern matching for closures, there are times we don't end up
166 /// reading places that are mentioned in a closure (because of _ patterns). However,
167 /// to ensure the places are initialized, we introduce fake reads.
168 /// Consider these two examples:
169 /// ``` (discriminant matching with only wildcard arm)
171 /// let c = || match x { _ => () };
173 /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
174 /// want to capture it. However, we do still want an error here, because `x` should have
175 /// to be initialized at the point where c is created. Therefore, we add a "fake read"
177 /// ``` (destructured assignments)
179 /// let (t1, t2) = t;
182 /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
183 /// we never capture `t`. This becomes an issue when we build MIR as we require
184 /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
185 /// issue by fake reading `t`.
186 pub closure_fake_reads: FxHashMap<LocalDefId, Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
188 /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
189 /// by applying extended parameter rules.
190 /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
191 pub rvalue_scopes: RvalueScopes,
193 /// Stores the type, expression, span and optional scope span of all types
194 /// that are live across the yield of this generator (if a generator).
195 pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
197 /// Stores the predicates that apply on generator witness types.
198 /// formatting modified file tests/ui/generator/retain-resume-ref.rs
199 pub generator_interior_predicates:
200 FxHashMap<LocalDefId, Vec<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>>,
202 /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
203 /// as `&[u8]`, depending on the pattern in which they are used.
204 /// This hashset records all instances where we behave
205 /// like this to allow `const_to_pat` to reliably handle this situation.
206 pub treat_byte_string_as_slice: ItemLocalSet,
208 /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
210 pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>,
213 /// Whenever a value may be live across a generator yield, the type of that value winds up in the
214 /// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
215 /// captured types that can be useful for diagnostics. In particular, it stores the span that
216 /// caused a given type to be recorded, along with the scope that enclosed the value (which can
217 /// be used to find the await that the value is live across).
221 /// ```ignore (pseudo-Rust)
229 /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
230 /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
231 #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
232 #[derive(TypeFoldable, TypeVisitable)]
233 pub struct GeneratorInteriorTypeCause<'tcx> {
234 /// Type of the captured binding.
236 /// Span of the binding that was captured.
238 /// Span of the scope of the captured binding.
239 pub scope_span: Option<Span>,
240 /// Span of `.await` or `yield` expression.
241 pub yield_span: Span,
242 /// Expr which the type evaluated from.
243 pub expr: Option<hir::HirId>,
246 // This type holds diagnostic information on generators and async functions across crate boundaries
247 // and is used to provide better error messages
248 #[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
249 pub struct GeneratorDiagnosticData<'tcx> {
250 pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
251 pub hir_owner: DefId,
252 pub nodes_types: ItemLocalMap<Ty<'tcx>>,
253 pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
256 impl<'tcx> TypeckResults<'tcx> {
257 pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
260 type_dependent_defs: Default::default(),
261 field_indices: Default::default(),
262 user_provided_types: Default::default(),
263 user_provided_sigs: Default::default(),
264 node_types: Default::default(),
265 node_substs: Default::default(),
266 adjustments: Default::default(),
267 pat_binding_modes: Default::default(),
268 pat_adjustments: Default::default(),
269 closure_kind_origins: Default::default(),
270 liberated_fn_sigs: Default::default(),
271 fru_field_types: Default::default(),
272 coercion_casts: Default::default(),
273 used_trait_imports: Lrc::new(Default::default()),
274 tainted_by_errors: None,
275 concrete_opaque_types: Default::default(),
276 closure_min_captures: Default::default(),
277 closure_fake_reads: Default::default(),
278 rvalue_scopes: Default::default(),
279 generator_interior_types: ty::Binder::dummy(Default::default()),
280 generator_interior_predicates: Default::default(),
281 treat_byte_string_as_slice: Default::default(),
282 closure_size_eval: Default::default(),
286 /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
287 pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
289 hir::QPath::Resolved(_, ref path) => path.res,
290 hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
291 .type_dependent_def(id)
292 .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
296 pub fn type_dependent_defs(
298 ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
299 LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
302 pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
303 validate_hir_id_for_typeck_results(self.hir_owner, id);
304 self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
307 pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
308 self.type_dependent_def(id).map(|(_, def_id)| def_id)
311 pub fn type_dependent_defs_mut(
313 ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
314 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
317 pub fn field_indices(&self) -> LocalTableInContext<'_, usize> {
318 LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
321 pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> {
322 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
325 pub fn field_index(&self, id: hir::HirId) -> usize {
326 self.field_indices().get(id).cloned().expect("no index for a field")
329 pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> {
330 self.field_indices().get(id).cloned()
333 pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
334 LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
337 pub fn user_provided_types_mut(
339 ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
340 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
343 pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
344 LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
347 pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
348 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
351 pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
352 let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
355 GeneratorInteriorTypeCause {
358 scope_span: item.scope_span,
359 yield_span: item.yield_span,
360 expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
365 GeneratorDiagnosticData {
366 generator_interior_types: generator_interior_type,
367 hir_owner: self.hir_owner.to_def_id(),
368 nodes_types: self.node_types.clone(),
369 adjustments: self.adjustments.clone(),
373 pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
374 self.node_type_opt(id).unwrap_or_else(|| {
375 bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id)))
379 pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
380 validate_hir_id_for_typeck_results(self.hir_owner, id);
381 self.node_types.get(&id.local_id).cloned()
384 pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<'_, SubstsRef<'tcx>> {
385 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_substs }
388 pub fn node_substs(&self, id: hir::HirId) -> SubstsRef<'tcx> {
389 validate_hir_id_for_typeck_results(self.hir_owner, id);
390 self.node_substs.get(&id.local_id).cloned().unwrap_or_else(|| InternalSubsts::empty())
393 pub fn node_substs_opt(&self, id: hir::HirId) -> Option<SubstsRef<'tcx>> {
394 validate_hir_id_for_typeck_results(self.hir_owner, id);
395 self.node_substs.get(&id.local_id).cloned()
398 /// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function
399 /// doesn't provide type parameter substitutions.
401 /// [`expr_ty`]: TypeckResults::expr_ty
402 pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
403 self.node_type(pat.hir_id)
406 /// Returns the type of an expression as a monotype.
408 /// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
409 /// some cases, we insert `Adjustment` annotations such as auto-deref or
410 /// auto-ref. The type returned by this function does not consider such
411 /// adjustments. See `expr_ty_adjusted()` instead.
413 /// NB (2): This type doesn't provide type parameter substitutions; e.g., if you
414 /// ask for the type of `id` in `id(3)`, it will return `fn(&isize) -> isize`
415 /// instead of `fn(ty) -> T with T = isize`.
416 pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
417 self.node_type(expr.hir_id)
420 pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
421 self.node_type_opt(expr.hir_id)
424 pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
425 LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
428 pub fn adjustments_mut(
430 ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
431 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
434 pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
435 validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
436 self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
439 /// Returns the type of `expr`, considering any `Adjustment`
440 /// entry recorded for that expression.
441 pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
442 self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
445 pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
446 self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
449 pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
450 // Only paths and method calls/overloaded operators have
451 // entries in type_dependent_defs, ignore the former here.
452 if let hir::ExprKind::Path(_) = expr.kind {
456 matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
459 pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
460 self.pat_binding_modes().get(id).copied().or_else(|| {
461 s.delay_span_bug(sp, "missing binding mode");
466 pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
467 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
470 pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
471 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
474 pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
475 LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
478 pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
479 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
482 /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
484 pub fn closure_min_captures_flattened(
486 closure_def_id: LocalDefId,
487 ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
488 self.closure_min_captures
489 .get(&closure_def_id)
490 .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
495 pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
496 LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
499 pub fn closure_kind_origins_mut(
501 ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
502 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
505 pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
506 LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
509 pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
510 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
513 pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
514 LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
517 pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
518 LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
521 pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool {
522 validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
523 self.coercion_casts.contains(&hir_id.local_id)
526 pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
527 self.coercion_casts.insert(id);
530 pub fn coercion_casts(&self) -> &ItemLocalSet {
535 /// Validate that the given HirId (respectively its `local_id` part) can be
536 /// safely used as a key in the maps of a TypeckResults. For that to be
537 /// the case, the HirId must have the same `owner` as all the other IDs in
538 /// this table (signified by `hir_owner`). Otherwise the HirId
539 /// would be in a different frame of reference and using its `local_id`
540 /// would result in lookup errors, or worse, in silently wrong data being
543 fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
544 if hir_id.owner != hir_owner {
545 invalid_hir_id_for_typeck_results(hir_owner, hir_id);
551 fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
552 ty::tls::with(|tcx| {
554 "node {} cannot be placed in TypeckResults with hir_owner {:?}",
555 tcx.hir().node_to_string(hir_id),
561 pub struct LocalTableInContext<'a, V> {
563 data: &'a ItemLocalMap<V>,
566 impl<'a, V> LocalTableInContext<'a, V> {
567 pub fn contains_key(&self, id: hir::HirId) -> bool {
568 validate_hir_id_for_typeck_results(self.hir_owner, id);
569 self.data.contains_key(&id.local_id)
572 pub fn get(&self, id: hir::HirId) -> Option<&V> {
573 validate_hir_id_for_typeck_results(self.hir_owner, id);
574 self.data.get(&id.local_id)
579 ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator<Item = (hir::ItemLocalId, &'a V)>>
581 self.data.items().map(|(id, value)| (*id, value))
584 pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
585 self.data.to_sorted_stable_ord()
589 impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
592 fn index(&self, key: hir::HirId) -> &V {
593 self.get(key).expect("LocalTableInContext: key not found")
597 pub struct LocalTableInContextMut<'a, V> {
599 data: &'a mut ItemLocalMap<V>,
602 impl<'a, V> LocalTableInContextMut<'a, V> {
603 pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
604 validate_hir_id_for_typeck_results(self.hir_owner, id);
605 self.data.get_mut(&id.local_id)
608 pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> {
609 validate_hir_id_for_typeck_results(self.hir_owner, id);
610 self.data.entry(id.local_id)
613 pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
614 validate_hir_id_for_typeck_results(self.hir_owner, id);
615 self.data.insert(id.local_id, val)
618 pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
619 validate_hir_id_for_typeck_results(self.hir_owner, id);
620 self.data.remove(&id.local_id)
625 items: UnordItems<(hir::HirId, V), impl Iterator<Item = (hir::HirId, V)>>,
627 self.data.extend(items.map(|(id, value)| {
628 validate_hir_id_for_typeck_results(self.hir_owner, id);
634 rustc_index::newtype_index! {
635 #[derive(HashStable)]
636 #[debug_format = "UserType({})"]
637 pub struct UserTypeAnnotationIndex {
638 const START_INDEX = 0;
642 /// Mapping of type annotation indices to canonical user type annotations.
643 pub type CanonicalUserTypeAnnotations<'tcx> =
644 IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
646 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
647 pub struct CanonicalUserTypeAnnotation<'tcx> {
648 pub user_ty: Box<CanonicalUserType<'tcx>>,
650 pub inferred_ty: Ty<'tcx>,
653 /// Canonical user type annotation.
654 pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
656 impl<'tcx> CanonicalUserType<'tcx> {
657 /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
658 /// i.e., each thing is mapped to a canonical variable with the same index.
659 pub fn is_identity(&self) -> bool {
661 UserType::Ty(_) => false,
662 UserType::TypeOf(_, user_substs) => {
663 if user_substs.user_self_ty.is_some() {
667 iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| {
668 match kind.unpack() {
669 GenericArgKind::Type(ty) => match ty.kind() {
670 ty::Bound(debruijn, b) => {
671 // We only allow a `ty::INNERMOST` index in substitutions.
672 assert_eq!(*debruijn, ty::INNERMOST);
678 GenericArgKind::Lifetime(r) => match *r {
679 ty::ReLateBound(debruijn, br) => {
680 // We only allow a `ty::INNERMOST` index in substitutions.
681 assert_eq!(debruijn, ty::INNERMOST);
687 GenericArgKind::Const(ct) => match ct.kind() {
688 ty::ConstKind::Bound(debruijn, b) => {
689 // We only allow a `ty::INNERMOST` index in substitutions.
690 assert_eq!(debruijn, ty::INNERMOST);
702 /// A user-given type annotation attached to a constant. These arise
703 /// from constants that are named via paths, like `Foo::<A>::new` and
705 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
706 #[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable, Lift)]
707 pub enum UserType<'tcx> {
710 /// The canonical type is the result of `type_of(def_id)` with the
711 /// given substitutions applied.
712 TypeOf(DefId, UserSubsts<'tcx>),