1use derive_where::derive_where;
2#[cfg(feature = "nightly")]
3use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
4
5use crate::fold::TypeFoldable;
6use crate::inherent::*;
7use crate::relate::RelateResult;
8use crate::relate::combine::PredicateEmittingRelation;
9use crate::{self as ty, Interner};
10
11#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
22#[cfg_attr(
23 feature = "nightly",
24 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
25)]
26pub enum TypingMode<I: Interner> {
27 Coherence,
39 Analysis { defining_opaque_types_and_generators: I::LocalDefIds },
68 Borrowck { defining_opaque_types: I::LocalDefIds },
76 PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
82 PostAnalysis,
91}
92
93impl<I: Interner> Eq for TypingMode<I> {}
94
95impl<I: Interner> TypingMode<I> {
96 pub fn non_body_analysis() -> TypingMode<I> {
98 TypingMode::Analysis { defining_opaque_types_and_generators: Default::default() }
99 }
100
101 pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
102 TypingMode::Analysis {
103 defining_opaque_types_and_generators: cx
104 .opaque_types_and_coroutines_defined_by(body_def_id),
105 }
106 }
107
108 pub fn analysis_in_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
114 TypingMode::Analysis {
115 defining_opaque_types_and_generators: cx.opaque_types_defined_by(body_def_id),
116 }
117 }
118
119 pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
120 let defining_opaque_types = cx.opaque_types_defined_by(body_def_id);
121 if defining_opaque_types.is_empty() {
122 TypingMode::non_body_analysis()
123 } else {
124 TypingMode::Borrowck { defining_opaque_types }
125 }
126 }
127
128 pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
129 let defined_opaque_types = cx.opaque_types_defined_by(body_def_id);
130 if defined_opaque_types.is_empty() {
131 TypingMode::non_body_analysis()
132 } else {
133 TypingMode::PostBorrowckAnalysis { defined_opaque_types }
134 }
135 }
136}
137
138#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_infer_ctxt_like")]
139pub trait InferCtxtLike: Sized {
140 type Interner: Interner;
141 fn cx(&self) -> Self::Interner;
142
143 fn next_trait_solver(&self) -> bool {
148 true
149 }
150
151 fn typing_mode(&self) -> TypingMode<Self::Interner>;
152
153 fn universe(&self) -> ty::UniverseIndex;
154 fn create_next_universe(&self) -> ty::UniverseIndex;
155
156 fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
157 fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
158 fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
159
160 fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
161 fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid;
162 fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
163
164 fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
165 fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
166 fn opportunistic_resolve_float_var(
167 &self,
168 vid: ty::FloatVid,
169 ) -> <Self::Interner as Interner>::Ty;
170 fn opportunistic_resolve_ct_var(
171 &self,
172 vid: ty::ConstVid,
173 ) -> <Self::Interner as Interner>::Const;
174 fn opportunistic_resolve_lt_var(
175 &self,
176 vid: ty::RegionVid,
177 ) -> <Self::Interner as Interner>::Region;
178
179 fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool;
180
181 fn next_region_infer(&self) -> <Self::Interner as Interner>::Region;
182 fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
183 fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
184 fn fresh_args_for_item(
185 &self,
186 def_id: <Self::Interner as Interner>::DefId,
187 ) -> <Self::Interner as Interner>::GenericArgs;
188
189 fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
190 &self,
191 value: ty::Binder<Self::Interner, T>,
192 ) -> T;
193
194 fn enter_forall<T: TypeFoldable<Self::Interner>, U>(
195 &self,
196 value: ty::Binder<Self::Interner, T>,
197 f: impl FnOnce(T) -> U,
198 ) -> U;
199
200 fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
201 fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
202 fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid);
203 fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid);
204 fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid);
205
206 fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
207 &self,
208 relation: &mut R,
209 target_is_expected: bool,
210 target_vid: ty::TyVid,
211 instantiation_variance: ty::Variance,
212 source_ty: <Self::Interner as Interner>::Ty,
213 ) -> RelateResult<Self::Interner, ()>;
214 fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue);
215 fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue);
216 fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
217 &self,
218 relation: &mut R,
219 target_is_expected: bool,
220 target_vid: ty::ConstVid,
221 source_ct: <Self::Interner as Interner>::Const,
222 ) -> RelateResult<Self::Interner, ()>;
223
224 fn set_tainted_by_errors(&self, e: <Self::Interner as Interner>::ErrorGuaranteed);
225
226 fn shallow_resolve(
227 &self,
228 ty: <Self::Interner as Interner>::Ty,
229 ) -> <Self::Interner as Interner>::Ty;
230 fn shallow_resolve_const(
231 &self,
232 ty: <Self::Interner as Interner>::Const,
233 ) -> <Self::Interner as Interner>::Const;
234
235 fn resolve_vars_if_possible<T>(&self, value: T) -> T
236 where
237 T: TypeFoldable<Self::Interner>;
238
239 fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
240
241 fn sub_regions(
242 &self,
243 sub: <Self::Interner as Interner>::Region,
244 sup: <Self::Interner as Interner>::Region,
245 span: <Self::Interner as Interner>::Span,
246 );
247
248 fn equate_regions(
249 &self,
250 a: <Self::Interner as Interner>::Region,
251 b: <Self::Interner as Interner>::Region,
252 span: <Self::Interner as Interner>::Span,
253 );
254
255 fn register_ty_outlives(
256 &self,
257 ty: <Self::Interner as Interner>::Ty,
258 r: <Self::Interner as Interner>::Region,
259 span: <Self::Interner as Interner>::Span,
260 );
261
262 type OpaqueTypeStorageEntries: OpaqueTypeStorageEntries;
263 fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
264 fn clone_opaque_types_lookup_table(
265 &self,
266 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
267 fn clone_duplicate_opaque_types(
268 &self,
269 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
270 fn clone_opaque_types_added_since(
271 &self,
272 prev_entries: Self::OpaqueTypeStorageEntries,
273 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
274
275 fn register_hidden_type_in_storage(
276 &self,
277 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
278 hidden_ty: <Self::Interner as Interner>::Ty,
279 span: <Self::Interner as Interner>::Span,
280 ) -> Option<<Self::Interner as Interner>::Ty>;
281 fn add_duplicate_opaque_type(
282 &self,
283 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
284 hidden_ty: <Self::Interner as Interner>::Ty,
285 span: <Self::Interner as Interner>::Span,
286 );
287
288 fn reset_opaque_types(&self);
289}
290
291pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
292 infcx: &'a Infcx,
293 param_env: I::ParamEnv,
294 symbol: I::Symbol,
295) -> bool
296where
297 Infcx: InferCtxtLike<Interner = I>,
298{
299 for pred in param_env.caller_bounds().iter() {
301 if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
302 if sym == symbol {
303 return true;
304 }
305 }
306 }
307
308 (infcx.typing_mode() == TypingMode::PostAnalysis)
325 || infcx.cx().features().feature_bound_holds_in_crate(symbol)
326}