]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/typeck_results.rs
Rollup merge of #107189 - cjgillot:meta-adt, r=compiler-errors
[rust.git] / compiler / rustc_middle / src / ty / typeck_results.rs
1 use crate::{
2     hir::place::Place as HirPlace,
3     infer::canonical::Canonical,
4     ty::{
5         self, tls, BindingMode, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData,
6         GenericArgKind, InternalSubsts, SubstsRef, Ty, UserSubsts,
7     },
8 };
9 use rustc_data_structures::{
10     fx::FxHashMap,
11     sync::Lrc,
12     unord::{UnordItems, UnordSet},
13     vec_map::VecMap,
14 };
15 use rustc_errors::ErrorGuaranteed;
16 use rustc_hir as hir;
17 use rustc_hir::{
18     def::{DefKind, Res},
19     def_id::{DefId, LocalDefId, LocalDefIdMap},
20     hir_id::OwnerId,
21     HirId, ItemLocalId, ItemLocalMap, ItemLocalSet,
22 };
23 use rustc_index::vec::{Idx, IndexVec};
24 use rustc_macros::HashStable;
25 use rustc_middle::mir::FakeReadCause;
26 use rustc_session::Session;
27 use rustc_span::Span;
28 use std::{collections::hash_map::Entry, hash::Hash, iter};
29
30 use super::RvalueScopes;
31
32 #[derive(TyEncodable, TyDecodable, Debug, HashStable)]
33 pub struct TypeckResults<'tcx> {
34     /// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
35     pub hir_owner: OwnerId,
36
37     /// Resolved definitions for `<T>::X` associated paths and
38     /// method calls, including those of overloaded operators.
39     type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>,
40
41     /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
42     /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
43     /// about the field you also need definition of the variant to which the field
44     /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
45     field_indices: ItemLocalMap<usize>,
46
47     /// Stores the types for various nodes in the AST. Note that this table
48     /// is not guaranteed to be populated outside inference. See
49     /// typeck::check::fn_ctxt for details.
50     node_types: ItemLocalMap<Ty<'tcx>>,
51
52     /// Stores the type parameters which were substituted to obtain the type
53     /// of this node. This only applies to nodes that refer to entities
54     /// parameterized by type parameters, such as generic fns, types, or
55     /// other items.
56     node_substs: ItemLocalMap<SubstsRef<'tcx>>,
57
58     /// This will either store the canonicalized types provided by the user
59     /// or the substitutions that the user explicitly gave (if any) attached
60     /// to `id`. These will not include any inferred values. The canonical form
61     /// is used to capture things like `_` or other unspecified values.
62     ///
63     /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
64     /// canonical substitutions would include only `for<X> { Vec<X> }`.
65     ///
66     /// See also `AscribeUserType` statement in MIR.
67     user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
68
69     /// Stores the canonicalized types provided by the user. See also
70     /// `AscribeUserType` statement in MIR.
71     pub user_provided_sigs: LocalDefIdMap<CanonicalPolyFnSig<'tcx>>,
72
73     adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
74
75     /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
76     pat_binding_modes: ItemLocalMap<BindingMode>,
77
78     /// Stores the types which were implicitly dereferenced in pattern binding modes
79     /// for later usage in THIR lowering. For example,
80     ///
81     /// ```
82     /// match &&Some(5i32) {
83     ///     Some(n) => {},
84     ///     _ => {},
85     /// }
86     /// ```
87     /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
88     ///
89     /// See:
90     /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
91     pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
92
93     /// Records the reasons that we picked the kind of each closure;
94     /// not all closures are present in the map.
95     closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
96
97     /// For each fn, records the "liberated" types of its arguments
98     /// and return type. Liberated means that all bound regions
99     /// (including late-bound regions) are replaced with free
100     /// equivalents. This table is not used in codegen (since regions
101     /// are erased there) and hence is not serialized to metadata.
102     ///
103     /// This table also contains the "revealed" values for any `impl Trait`
104     /// that appear in the signature and whose values are being inferred
105     /// by this function.
106     ///
107     /// # Example
108     ///
109     /// ```rust
110     /// # use std::fmt::Debug;
111     /// fn foo(x: &u32) -> impl Debug { *x }
112     /// ```
113     ///
114     /// The function signature here would be:
115     ///
116     /// ```ignore (illustrative)
117     /// for<'a> fn(&'a u32) -> Foo
118     /// ```
119     ///
120     /// where `Foo` is an opaque type created for this function.
121     ///
122     ///
123     /// The *liberated* form of this would be
124     ///
125     /// ```ignore (illustrative)
126     /// fn(&'a u32) -> u32
127     /// ```
128     ///
129     /// Note that `'a` is not bound (it would be an `ReFree`) and
130     /// that the `Foo` opaque type is replaced by its hidden type.
131     liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
132
133     /// For each FRU expression, record the normalized types of the fields
134     /// of the struct - this is needed because it is non-trivial to
135     /// normalize while preserving regions. This table is used only in
136     /// MIR construction and hence is not serialized to metadata.
137     fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
138
139     /// For every coercion cast we add the HIR node ID of the cast
140     /// expression to this set.
141     coercion_casts: ItemLocalSet,
142
143     /// Set of trait imports actually used in the method resolution.
144     /// This is used for warning unused imports. During type
145     /// checking, this `Lrc` should not be cloned: it must have a ref-count
146     /// of 1 so that we can insert things into the set mutably.
147     pub used_trait_imports: Lrc<UnordSet<LocalDefId>>,
148
149     /// If any errors occurred while type-checking this body,
150     /// this field will be set to `Some(ErrorGuaranteed)`.
151     pub tainted_by_errors: Option<ErrorGuaranteed>,
152
153     /// All the opaque types that have hidden types set
154     /// by this function. We also store the
155     /// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
156     /// even if they are only set in dead code (which doesn't show up in MIR).
157     pub concrete_opaque_types: VecMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
158
159     /// Tracks the minimum captures required for a closure;
160     /// see `MinCaptureInformationMap` for more details.
161     pub closure_min_captures: ty::MinCaptureInformationMap<'tcx>,
162
163     /// Tracks the fake reads required for a closure and the reason for the fake read.
164     /// When performing pattern matching for closures, there are times we don't end up
165     /// reading places that are mentioned in a closure (because of _ patterns). However,
166     /// to ensure the places are initialized, we introduce fake reads.
167     /// Consider these two examples:
168     /// ``` (discriminant matching with only wildcard arm)
169     /// let x: u8;
170     /// let c = || match x { _ => () };
171     /// ```
172     /// In this example, we don't need to actually read/borrow `x` in `c`, and so we don't
173     /// want to capture it. However, we do still want an error here, because `x` should have
174     /// to be initialized at the point where c is created. Therefore, we add a "fake read"
175     /// instead.
176     /// ``` (destructured assignments)
177     /// let c = || {
178     ///     let (t1, t2) = t;
179     /// }
180     /// ```
181     /// In the second example, we capture the disjoint fields of `t` (`t.0` & `t.1`), but
182     /// we never capture `t`. This becomes an issue when we build MIR as we require
183     /// information on `t` in order to create place `t.0` and `t.1`. We can solve this
184     /// issue by fake reading `t`.
185     pub closure_fake_reads: FxHashMap<LocalDefId, Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
186
187     /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
188     /// by applying extended parameter rules.
189     /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
190     pub rvalue_scopes: RvalueScopes,
191
192     /// Stores the type, expression, span and optional scope span of all types
193     /// that are live across the yield of this generator (if a generator).
194     pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
195
196     /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
197     /// as `&[u8]`, depending on the pattern in which they are used.
198     /// This hashset records all instances where we behave
199     /// like this to allow `const_to_pat` to reliably handle this situation.
200     pub treat_byte_string_as_slice: ItemLocalSet,
201
202     /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
203     /// on closure size.
204     pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>,
205 }
206
207 /// Whenever a value may be live across a generator yield, the type of that value winds up in the
208 /// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
209 /// captured types that can be useful for diagnostics. In particular, it stores the span that
210 /// caused a given type to be recorded, along with the scope that enclosed the value (which can
211 /// be used to find the await that the value is live across).
212 ///
213 /// For example:
214 ///
215 /// ```ignore (pseudo-Rust)
216 /// async move {
217 ///     let x: T = expr;
218 ///     foo.await
219 ///     ...
220 /// }
221 /// ```
222 ///
223 /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
224 /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
225 #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
226 #[derive(TypeFoldable, TypeVisitable)]
227 pub struct GeneratorInteriorTypeCause<'tcx> {
228     /// Type of the captured binding.
229     pub ty: Ty<'tcx>,
230     /// Span of the binding that was captured.
231     pub span: Span,
232     /// Span of the scope of the captured binding.
233     pub scope_span: Option<Span>,
234     /// Span of `.await` or `yield` expression.
235     pub yield_span: Span,
236     /// Expr which the type evaluated from.
237     pub expr: Option<hir::HirId>,
238 }
239
240 // This type holds diagnostic information on generators and async functions across crate boundaries
241 // and is used to provide better error messages
242 #[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
243 pub struct GeneratorDiagnosticData<'tcx> {
244     pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
245     pub hir_owner: DefId,
246     pub nodes_types: ItemLocalMap<Ty<'tcx>>,
247     pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
248 }
249
250 impl<'tcx> TypeckResults<'tcx> {
251     pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
252         TypeckResults {
253             hir_owner,
254             type_dependent_defs: Default::default(),
255             field_indices: Default::default(),
256             user_provided_types: Default::default(),
257             user_provided_sigs: Default::default(),
258             node_types: Default::default(),
259             node_substs: Default::default(),
260             adjustments: Default::default(),
261             pat_binding_modes: Default::default(),
262             pat_adjustments: Default::default(),
263             closure_kind_origins: Default::default(),
264             liberated_fn_sigs: Default::default(),
265             fru_field_types: Default::default(),
266             coercion_casts: Default::default(),
267             used_trait_imports: Lrc::new(Default::default()),
268             tainted_by_errors: None,
269             concrete_opaque_types: Default::default(),
270             closure_min_captures: Default::default(),
271             closure_fake_reads: Default::default(),
272             rvalue_scopes: Default::default(),
273             generator_interior_types: ty::Binder::dummy(Default::default()),
274             treat_byte_string_as_slice: Default::default(),
275             closure_size_eval: Default::default(),
276         }
277     }
278
279     /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
280     pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
281         match *qpath {
282             hir::QPath::Resolved(_, ref path) => path.res,
283             hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
284                 .type_dependent_def(id)
285                 .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
286         }
287     }
288
289     pub fn type_dependent_defs(
290         &self,
291     ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
292         LocalTableInContext { hir_owner: self.hir_owner, data: &self.type_dependent_defs }
293     }
294
295     pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
296         validate_hir_id_for_typeck_results(self.hir_owner, id);
297         self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
298     }
299
300     pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
301         self.type_dependent_def(id).map(|(_, def_id)| def_id)
302     }
303
304     pub fn type_dependent_defs_mut(
305         &mut self,
306     ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorGuaranteed>> {
307         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs }
308     }
309
310     pub fn field_indices(&self) -> LocalTableInContext<'_, usize> {
311         LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices }
312     }
313
314     pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> {
315         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
316     }
317
318     pub fn field_index(&self, id: hir::HirId) -> usize {
319         self.field_indices().get(id).cloned().expect("no index for a field")
320     }
321
322     pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> {
323         self.field_indices().get(id).cloned()
324     }
325
326     pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
327         LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
328     }
329
330     pub fn user_provided_types_mut(
331         &mut self,
332     ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
333         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.user_provided_types }
334     }
335
336     pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
337         LocalTableInContext { hir_owner: self.hir_owner, data: &self.node_types }
338     }
339
340     pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
341         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
342     }
343
344     pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
345         let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
346             vec.iter()
347                 .map(|item| {
348                     GeneratorInteriorTypeCause {
349                         ty: item.ty,
350                         span: item.span,
351                         scope_span: item.scope_span,
352                         yield_span: item.yield_span,
353                         expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
354                     }
355                 })
356                 .collect::<Vec<_>>()
357         });
358         GeneratorDiagnosticData {
359             generator_interior_types: generator_interior_type,
360             hir_owner: self.hir_owner.to_def_id(),
361             nodes_types: self.node_types.clone(),
362             adjustments: self.adjustments.clone(),
363         }
364     }
365
366     pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
367         self.node_type_opt(id).unwrap_or_else(|| {
368             bug!("node_type: no type for node `{}`", tls::with(|tcx| tcx.hir().node_to_string(id)))
369         })
370     }
371
372     pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
373         validate_hir_id_for_typeck_results(self.hir_owner, id);
374         self.node_types.get(&id.local_id).cloned()
375     }
376
377     pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<'_, SubstsRef<'tcx>> {
378         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_substs }
379     }
380
381     pub fn node_substs(&self, id: hir::HirId) -> SubstsRef<'tcx> {
382         validate_hir_id_for_typeck_results(self.hir_owner, id);
383         self.node_substs.get(&id.local_id).cloned().unwrap_or_else(|| InternalSubsts::empty())
384     }
385
386     pub fn node_substs_opt(&self, id: hir::HirId) -> Option<SubstsRef<'tcx>> {
387         validate_hir_id_for_typeck_results(self.hir_owner, id);
388         self.node_substs.get(&id.local_id).cloned()
389     }
390
391     /// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function
392     /// doesn't provide type parameter substitutions.
393     ///
394     /// [`expr_ty`]: TypeckResults::expr_ty
395     pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
396         self.node_type(pat.hir_id)
397     }
398
399     /// Returns the type of an expression as a monotype.
400     ///
401     /// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
402     /// some cases, we insert `Adjustment` annotations such as auto-deref or
403     /// auto-ref. The type returned by this function does not consider such
404     /// adjustments. See `expr_ty_adjusted()` instead.
405     ///
406     /// NB (2): This type doesn't provide type parameter substitutions; e.g., if you
407     /// ask for the type of `id` in `id(3)`, it will return `fn(&isize) -> isize`
408     /// instead of `fn(ty) -> T with T = isize`.
409     pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
410         self.node_type(expr.hir_id)
411     }
412
413     pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
414         self.node_type_opt(expr.hir_id)
415     }
416
417     pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
418         LocalTableInContext { hir_owner: self.hir_owner, data: &self.adjustments }
419     }
420
421     pub fn adjustments_mut(
422         &mut self,
423     ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
424         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.adjustments }
425     }
426
427     pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
428         validate_hir_id_for_typeck_results(self.hir_owner, expr.hir_id);
429         self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
430     }
431
432     /// Returns the type of `expr`, considering any `Adjustment`
433     /// entry recorded for that expression.
434     pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
435         self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
436     }
437
438     pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
439         self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
440     }
441
442     pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
443         // Only paths and method calls/overloaded operators have
444         // entries in type_dependent_defs, ignore the former here.
445         if let hir::ExprKind::Path(_) = expr.kind {
446             return false;
447         }
448
449         matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
450     }
451
452     pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
453         self.pat_binding_modes().get(id).copied().or_else(|| {
454             s.delay_span_bug(sp, "missing binding mode");
455             None
456         })
457     }
458
459     pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
460         LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
461     }
462
463     pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
464         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
465     }
466
467     pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
468         LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_adjustments }
469     }
470
471     pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
472         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
473     }
474
475     /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
476     /// by the closure.
477     pub fn closure_min_captures_flattened(
478         &self,
479         closure_def_id: LocalDefId,
480     ) -> impl Iterator<Item = &ty::CapturedPlace<'tcx>> {
481         self.closure_min_captures
482             .get(&closure_def_id)
483             .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter()))
484             .into_iter()
485             .flatten()
486     }
487
488     pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
489         LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
490     }
491
492     pub fn closure_kind_origins_mut(
493         &mut self,
494     ) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
495         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
496     }
497
498     pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
499         LocalTableInContext { hir_owner: self.hir_owner, data: &self.liberated_fn_sigs }
500     }
501
502     pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
503         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.liberated_fn_sigs }
504     }
505
506     pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
507         LocalTableInContext { hir_owner: self.hir_owner, data: &self.fru_field_types }
508     }
509
510     pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
511         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types }
512     }
513
514     pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool {
515         validate_hir_id_for_typeck_results(self.hir_owner, hir_id);
516         self.coercion_casts.contains(&hir_id.local_id)
517     }
518
519     pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
520         self.coercion_casts.insert(id);
521     }
522
523     pub fn coercion_casts(&self) -> &ItemLocalSet {
524         &self.coercion_casts
525     }
526 }
527
528 /// Validate that the given HirId (respectively its `local_id` part) can be
529 /// safely used as a key in the maps of a TypeckResults. For that to be
530 /// the case, the HirId must have the same `owner` as all the other IDs in
531 /// this table (signified by `hir_owner`). Otherwise the HirId
532 /// would be in a different frame of reference and using its `local_id`
533 /// would result in lookup errors, or worse, in silently wrong data being
534 /// stored/returned.
535 #[inline]
536 fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
537     if hir_id.owner != hir_owner {
538         invalid_hir_id_for_typeck_results(hir_owner, hir_id);
539     }
540 }
541
542 #[cold]
543 #[inline(never)]
544 fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) {
545     ty::tls::with(|tcx| {
546         bug!(
547             "node {} with HirId::owner {:?} cannot be placed in TypeckResults with hir_owner {:?}",
548             tcx.hir().node_to_string(hir_id),
549             hir_id.owner,
550             hir_owner
551         )
552     });
553 }
554
555 pub struct LocalTableInContext<'a, V> {
556     hir_owner: OwnerId,
557     data: &'a ItemLocalMap<V>,
558 }
559
560 impl<'a, V> LocalTableInContext<'a, V> {
561     pub fn contains_key(&self, id: hir::HirId) -> bool {
562         validate_hir_id_for_typeck_results(self.hir_owner, id);
563         self.data.contains_key(&id.local_id)
564     }
565
566     pub fn get(&self, id: hir::HirId) -> Option<&V> {
567         validate_hir_id_for_typeck_results(self.hir_owner, id);
568         self.data.get(&id.local_id)
569     }
570
571     pub fn items(
572         &'a self,
573     ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator<Item = (hir::ItemLocalId, &'a V)>>
574     {
575         self.data.items().map(|(id, value)| (*id, value))
576     }
577
578     pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
579         self.data.to_sorted_stable_ord()
580     }
581 }
582
583 impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
584     type Output = V;
585
586     fn index(&self, key: hir::HirId) -> &V {
587         self.get(key).expect("LocalTableInContext: key not found")
588     }
589 }
590
591 pub struct LocalTableInContextMut<'a, V> {
592     hir_owner: OwnerId,
593     data: &'a mut ItemLocalMap<V>,
594 }
595
596 impl<'a, V> LocalTableInContextMut<'a, V> {
597     pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
598         validate_hir_id_for_typeck_results(self.hir_owner, id);
599         self.data.get_mut(&id.local_id)
600     }
601
602     pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> {
603         validate_hir_id_for_typeck_results(self.hir_owner, id);
604         self.data.entry(id.local_id)
605     }
606
607     pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
608         validate_hir_id_for_typeck_results(self.hir_owner, id);
609         self.data.insert(id.local_id, val)
610     }
611
612     pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
613         validate_hir_id_for_typeck_results(self.hir_owner, id);
614         self.data.remove(&id.local_id)
615     }
616
617     pub fn extend(
618         &mut self,
619         items: UnordItems<(hir::HirId, V), impl Iterator<Item = (hir::HirId, V)>>,
620     ) {
621         self.data.extend(items.map(|(id, value)| {
622             validate_hir_id_for_typeck_results(self.hir_owner, id);
623             (id.local_id, value)
624         }))
625     }
626 }
627
628 rustc_index::newtype_index! {
629     #[derive(HashStable)]
630     #[debug_format = "UserType({})"]
631     pub struct UserTypeAnnotationIndex {
632         const START_INDEX = 0;
633     }
634 }
635
636 /// Mapping of type annotation indices to canonical user type annotations.
637 pub type CanonicalUserTypeAnnotations<'tcx> =
638     IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
639
640 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
641 pub struct CanonicalUserTypeAnnotation<'tcx> {
642     pub user_ty: Box<CanonicalUserType<'tcx>>,
643     pub span: Span,
644     pub inferred_ty: Ty<'tcx>,
645 }
646
647 /// Canonical user type annotation.
648 pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
649
650 impl<'tcx> CanonicalUserType<'tcx> {
651     /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
652     /// i.e., each thing is mapped to a canonical variable with the same index.
653     pub fn is_identity(&self) -> bool {
654         match self.value {
655             UserType::Ty(_) => false,
656             UserType::TypeOf(_, user_substs) => {
657                 if user_substs.user_self_ty.is_some() {
658                     return false;
659                 }
660
661                 iter::zip(user_substs.substs, BoundVar::new(0)..).all(|(kind, cvar)| {
662                     match kind.unpack() {
663                         GenericArgKind::Type(ty) => match ty.kind() {
664                             ty::Bound(debruijn, b) => {
665                                 // We only allow a `ty::INNERMOST` index in substitutions.
666                                 assert_eq!(*debruijn, ty::INNERMOST);
667                                 cvar == b.var
668                             }
669                             _ => false,
670                         },
671
672                         GenericArgKind::Lifetime(r) => match *r {
673                             ty::ReLateBound(debruijn, br) => {
674                                 // We only allow a `ty::INNERMOST` index in substitutions.
675                                 assert_eq!(debruijn, ty::INNERMOST);
676                                 cvar == br.var
677                             }
678                             _ => false,
679                         },
680
681                         GenericArgKind::Const(ct) => match ct.kind() {
682                             ty::ConstKind::Bound(debruijn, b) => {
683                                 // We only allow a `ty::INNERMOST` index in substitutions.
684                                 assert_eq!(debruijn, ty::INNERMOST);
685                                 cvar == b
686                             }
687                             _ => false,
688                         },
689                     }
690                 })
691             }
692         }
693     }
694 }
695
696 /// A user-given type annotation attached to a constant. These arise
697 /// from constants that are named via paths, like `Foo::<A>::new` and
698 /// so forth.
699 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable)]
700 #[derive(Eq, Hash, HashStable, TypeFoldable, TypeVisitable, Lift)]
701 pub enum UserType<'tcx> {
702     Ty(Ty<'tcx>),
703
704     /// The canonical type is the result of `type_of(def_id)` with the
705     /// given substitutions applied.
706     TypeOf(DefId, UserSubsts<'tcx>),
707 }