1 use super::callee
::DeferredCallResolution
;
2 use super::MaybeInProgressTables
;
4 use rustc_data_structures
::fx
::FxHashMap
;
5 use rustc_data_structures
::vec_map
::VecMap
;
7 use rustc_hir
::def_id
::{DefIdMap, LocalDefId}
;
8 use rustc_hir
::HirIdMap
;
9 use rustc_infer
::infer
;
10 use rustc_infer
::infer
::{InferCtxt, InferOk, TyCtxtInferExt}
;
11 use rustc_middle
::ty
::fold
::TypeFoldable
;
12 use rustc_middle
::ty
::{self, OpaqueTypeKey, Ty, TyCtxt}
;
13 use rustc_span
::{self, Span}
;
14 use rustc_trait_selection
::infer
::InferCtxtExt
as _
;
15 use rustc_trait_selection
::opaque_types
::OpaqueTypeDecl
;
16 use rustc_trait_selection
::traits
::{self, ObligationCause, TraitEngine, TraitEngineExt}
;
18 use std
::cell
::RefCell
;
21 /// Closures defined within the function. For example:
24 /// bar(move|| { ... })
27 /// Here, the function `foo()` and the closure passed to
28 /// `bar()` will each have their own `FnCtxt`, but they will
29 /// share the inherited fields.
30 pub struct Inherited
<'a
, 'tcx
> {
31 pub(super) infcx
: InferCtxt
<'a
, 'tcx
>,
33 pub(super) typeck_results
: super::MaybeInProgressTables
<'a
, 'tcx
>,
35 pub(super) locals
: RefCell
<HirIdMap
<super::LocalTy
<'tcx
>>>,
37 pub(super) fulfillment_cx
: RefCell
<Box
<dyn TraitEngine
<'tcx
>>>,
39 // Some additional `Sized` obligations badly affect type inference.
40 // These obligations are added in a later stage of typeck.
41 pub(super) deferred_sized_obligations
:
42 RefCell
<Vec
<(Ty
<'tcx
>, Span
, traits
::ObligationCauseCode
<'tcx
>)>>,
44 // When we process a call like `c()` where `c` is a closure type,
45 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
46 // `FnOnce` closure. In that case, we defer full resolution of the
47 // call until upvar inference can kick in and make the
48 // decision. We keep these deferred resolutions grouped by the
49 // def-id of the closure, so that once we decide, we can easily go
50 // back and process them.
51 pub(super) deferred_call_resolutions
: RefCell
<DefIdMap
<Vec
<DeferredCallResolution
<'tcx
>>>>,
53 pub(super) deferred_cast_checks
: RefCell
<Vec
<super::cast
::CastCheck
<'tcx
>>>,
55 pub(super) deferred_generator_interiors
:
56 RefCell
<Vec
<(hir
::BodyId
, Ty
<'tcx
>, hir
::GeneratorKind
)>>,
58 // Opaque types found in explicit return types and their
59 // associated fresh inference variable. Writeback resolves these
60 // variables to get the concrete type, which can be used to
61 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
62 pub(super) opaque_types
: RefCell
<VecMap
<OpaqueTypeKey
<'tcx
>, OpaqueTypeDecl
<'tcx
>>>,
64 /// A map from inference variables created from opaque
65 /// type instantiations (`ty::Infer`) to the actual opaque
66 /// type (`ty::Opaque`). Used during fallback to map unconstrained
67 /// opaque type inference variables to their corresponding
69 pub(super) opaque_types_vars
: RefCell
<FxHashMap
<Ty
<'tcx
>, Ty
<'tcx
>>>,
71 pub(super) body_id
: Option
<hir
::BodyId
>,
74 impl<'a
, 'tcx
> Deref
for Inherited
<'a
, 'tcx
> {
75 type Target
= InferCtxt
<'a
, 'tcx
>;
76 fn deref(&self) -> &Self::Target
{
81 /// Helper type of a temporary returned by `Inherited::build(...)`.
82 /// Necessary because we can't write the following bound:
83 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
84 pub struct InheritedBuilder
<'tcx
> {
85 infcx
: infer
::InferCtxtBuilder
<'tcx
>,
89 impl Inherited
<'_
, 'tcx
> {
90 pub fn build(tcx
: TyCtxt
<'tcx
>, def_id
: LocalDefId
) -> InheritedBuilder
<'tcx
> {
91 let hir_owner
= tcx
.hir().local_def_id_to_hir_id(def_id
).owner
;
94 infcx
: tcx
.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner
),
100 impl<'tcx
> InheritedBuilder
<'tcx
> {
101 pub fn enter
<F
, R
>(&mut self, f
: F
) -> R
103 F
: for<'a
> FnOnce(Inherited
<'a
, 'tcx
>) -> R
,
105 let def_id
= self.def_id
;
106 self.infcx
.enter(|infcx
| f(Inherited
::new(infcx
, def_id
)))
110 impl Inherited
<'a
, 'tcx
> {
111 pub(super) fn new(infcx
: InferCtxt
<'a
, 'tcx
>, def_id
: LocalDefId
) -> Self {
113 let item_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
114 let body_id
= tcx
.hir().maybe_body_owned_by(item_id
);
117 typeck_results
: MaybeInProgressTables
{
118 maybe_typeck_results
: infcx
.in_progress_typeck_results
,
121 fulfillment_cx
: RefCell
::new(<dyn TraitEngine
<'_
>>::new(tcx
)),
122 locals
: RefCell
::new(Default
::default()),
123 deferred_sized_obligations
: RefCell
::new(Vec
::new()),
124 deferred_call_resolutions
: RefCell
::new(Default
::default()),
125 deferred_cast_checks
: RefCell
::new(Vec
::new()),
126 deferred_generator_interiors
: RefCell
::new(Vec
::new()),
127 opaque_types
: RefCell
::new(Default
::default()),
128 opaque_types_vars
: RefCell
::new(Default
::default()),
133 pub(super) fn register_predicate(&self, obligation
: traits
::PredicateObligation
<'tcx
>) {
134 debug
!("register_predicate({:?})", obligation
);
135 if obligation
.has_escaping_bound_vars() {
136 span_bug
!(obligation
.cause
.span
, "escaping bound vars in predicate {:?}", obligation
);
138 self.fulfillment_cx
.borrow_mut().register_predicate_obligation(self, obligation
);
141 pub(super) fn register_predicates
<I
>(&self, obligations
: I
)
143 I
: IntoIterator
<Item
= traits
::PredicateObligation
<'tcx
>>,
145 for obligation
in obligations
{
146 self.register_predicate(obligation
);
150 pub(super) fn register_infer_ok_obligations
<T
>(&self, infer_ok
: InferOk
<'tcx
, T
>) -> T
{
151 self.register_predicates(infer_ok
.obligations
);
155 pub(super) fn normalize_associated_types_in
<T
>(
159 param_env
: ty
::ParamEnv
<'tcx
>,
163 T
: TypeFoldable
<'tcx
>,
165 self.normalize_associated_types_in_with_cause(
166 ObligationCause
::misc(span
, body_id
),
172 pub(super) fn normalize_associated_types_in_with_cause
<T
>(
174 cause
: ObligationCause
<'tcx
>,
175 param_env
: ty
::ParamEnv
<'tcx
>,
179 T
: TypeFoldable
<'tcx
>,
181 let ok
= self.partially_normalize_associated_types_in(cause
, param_env
, value
);
183 self.register_infer_ok_obligations(ok
)