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