1 use super::callee
::DeferredCallResolution
;
2 use super::MaybeInProgressTables
;
4 use rustc_data_structures
::fx
::FxHashMap
;
6 use rustc_hir
::def_id
::{DefIdMap, LocalDefId}
;
7 use rustc_hir
::HirIdMap
;
8 use rustc_infer
::infer
;
9 use rustc_infer
::infer
::{InferCtxt, InferOk, TyCtxtInferExt}
;
10 use rustc_middle
::ty
::fold
::TypeFoldable
;
11 use rustc_middle
::ty
::{self, Ty, TyCtxt}
;
12 use rustc_span
::{self, Span}
;
13 use rustc_trait_selection
::infer
::InferCtxtExt
as _
;
14 use rustc_trait_selection
::opaque_types
::OpaqueTypeDecl
;
15 use rustc_trait_selection
::traits
::{self, TraitEngine, TraitEngineExt}
;
17 use std
::cell
::RefCell
;
20 /// Closures defined within the function. For example:
23 /// bar(move|| { ... })
26 /// Here, the function `foo()` and the closure passed to
27 /// `bar()` will each have their own `FnCtxt`, but they will
28 /// share the inherited fields.
29 pub struct Inherited
<'a
, 'tcx
> {
30 pub(super) infcx
: InferCtxt
<'a
, 'tcx
>,
32 pub(super) typeck_results
: super::MaybeInProgressTables
<'a
, 'tcx
>,
34 pub(super) locals
: RefCell
<HirIdMap
<super::LocalTy
<'tcx
>>>,
36 pub(super) fulfillment_cx
: RefCell
<Box
<dyn TraitEngine
<'tcx
>>>,
38 // Some additional `Sized` obligations badly affect type inference.
39 // These obligations are added in a later stage of typeck.
40 pub(super) deferred_sized_obligations
:
41 RefCell
<Vec
<(Ty
<'tcx
>, Span
, traits
::ObligationCauseCode
<'tcx
>)>>,
43 // When we process a call like `c()` where `c` is a closure type,
44 // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
45 // `FnOnce` closure. In that case, we defer full resolution of the
46 // call until upvar inference can kick in and make the
47 // decision. We keep these deferred resolutions grouped by the
48 // def-id of the closure, so that once we decide, we can easily go
49 // back and process them.
50 pub(super) deferred_call_resolutions
: RefCell
<DefIdMap
<Vec
<DeferredCallResolution
<'tcx
>>>>,
52 pub(super) deferred_cast_checks
: RefCell
<Vec
<super::cast
::CastCheck
<'tcx
>>>,
54 pub(super) deferred_generator_interiors
:
55 RefCell
<Vec
<(hir
::BodyId
, Ty
<'tcx
>, hir
::GeneratorKind
)>>,
57 // Opaque types found in explicit return types and their
58 // associated fresh inference variable. Writeback resolves these
59 // variables to get the concrete type, which can be used to
60 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
61 pub(super) opaque_types
: RefCell
<DefIdMap
<OpaqueTypeDecl
<'tcx
>>>,
63 /// A map from inference variables created from opaque
64 /// type instantiations (`ty::Infer`) to the actual opaque
65 /// type (`ty::Opaque`). Used during fallback to map unconstrained
66 /// opaque type inference variables to their corresponding
68 pub(super) opaque_types_vars
: RefCell
<FxHashMap
<Ty
<'tcx
>, Ty
<'tcx
>>>,
70 pub(super) body_id
: Option
<hir
::BodyId
>,
73 impl<'a
, 'tcx
> Deref
for Inherited
<'a
, 'tcx
> {
74 type Target
= InferCtxt
<'a
, 'tcx
>;
75 fn deref(&self) -> &Self::Target
{
80 /// Helper type of a temporary returned by `Inherited::build(...)`.
81 /// Necessary because we can't write the following bound:
82 /// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
83 pub struct InheritedBuilder
<'tcx
> {
84 infcx
: infer
::InferCtxtBuilder
<'tcx
>,
88 impl Inherited
<'_
, 'tcx
> {
89 pub fn build(tcx
: TyCtxt
<'tcx
>, def_id
: LocalDefId
) -> InheritedBuilder
<'tcx
> {
90 let hir_owner
= tcx
.hir().local_def_id_to_hir_id(def_id
).owner
;
93 infcx
: tcx
.infer_ctxt().with_fresh_in_progress_typeck_results(hir_owner
),
99 impl<'tcx
> InheritedBuilder
<'tcx
> {
100 pub fn enter
<F
, R
>(&mut self, f
: F
) -> R
102 F
: for<'a
> FnOnce(Inherited
<'a
, 'tcx
>) -> R
,
104 let def_id
= self.def_id
;
105 self.infcx
.enter(|infcx
| f(Inherited
::new(infcx
, def_id
)))
109 impl Inherited
<'a
, 'tcx
> {
110 pub(super) fn new(infcx
: InferCtxt
<'a
, 'tcx
>, def_id
: LocalDefId
) -> Self {
112 let item_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
113 let body_id
= tcx
.hir().maybe_body_owned_by(item_id
);
116 typeck_results
: MaybeInProgressTables
{
117 maybe_typeck_results
: infcx
.in_progress_typeck_results
,
120 fulfillment_cx
: RefCell
::new(TraitEngine
::new(tcx
)),
121 locals
: RefCell
::new(Default
::default()),
122 deferred_sized_obligations
: RefCell
::new(Vec
::new()),
123 deferred_call_resolutions
: RefCell
::new(Default
::default()),
124 deferred_cast_checks
: RefCell
::new(Vec
::new()),
125 deferred_generator_interiors
: RefCell
::new(Vec
::new()),
126 opaque_types
: RefCell
::new(Default
::default()),
127 opaque_types_vars
: RefCell
::new(Default
::default()),
132 pub(super) fn register_predicate(&self, obligation
: traits
::PredicateObligation
<'tcx
>) {
133 debug
!("register_predicate({:?})", obligation
);
134 if obligation
.has_escaping_bound_vars() {
135 span_bug
!(obligation
.cause
.span
, "escaping bound vars in predicate {:?}", obligation
);
137 self.fulfillment_cx
.borrow_mut().register_predicate_obligation(self, obligation
);
140 pub(super) fn register_predicates
<I
>(&self, obligations
: I
)
142 I
: IntoIterator
<Item
= traits
::PredicateObligation
<'tcx
>>,
144 for obligation
in obligations
{
145 self.register_predicate(obligation
);
149 pub(super) fn register_infer_ok_obligations
<T
>(&self, infer_ok
: InferOk
<'tcx
, T
>) -> T
{
150 self.register_predicates(infer_ok
.obligations
);
154 pub(super) fn normalize_associated_types_in
<T
>(
158 param_env
: ty
::ParamEnv
<'tcx
>,
162 T
: TypeFoldable
<'tcx
>,
164 let ok
= self.partially_normalize_associated_types_in(span
, body_id
, param_env
, value
);
165 self.register_infer_ok_obligations(ok
)