1use derive_where::derive_where;
2#[cfg(feature = "nightly")]
3use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
4use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
5
6use crate::fold::TypeFoldable;
7use crate::inherent::*;
8use crate::relate::RelateResult;
9use crate::relate::combine::PredicateEmittingRelation;
10use crate::{self as ty, Interner};
11
12#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
23#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
24#[cfg_attr(
25 feature = "nightly",
26 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
27)]
28pub enum TypingMode<I: Interner> {
29 Coherence,
41 Analysis { defining_opaque_types_and_generators: I::LocalDefIds },
70 Borrowck { defining_opaque_types: I::LocalDefIds },
78 PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
84 PostAnalysis,
93}
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 in_hir_typeck(&self) -> bool {
152 false
153 }
154
155 fn typing_mode(&self) -> TypingMode<Self::Interner>;
156
157 fn universe(&self) -> ty::UniverseIndex;
158 fn create_next_universe(&self) -> ty::UniverseIndex;
159
160 fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
161 fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
162 fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
163
164 fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
165 fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
166
167 fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
168 fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
169 fn opportunistic_resolve_float_var(
170 &self,
171 vid: ty::FloatVid,
172 ) -> <Self::Interner as Interner>::Ty;
173 fn opportunistic_resolve_ct_var(
174 &self,
175 vid: ty::ConstVid,
176 ) -> <Self::Interner as Interner>::Const;
177 fn opportunistic_resolve_lt_var(
178 &self,
179 vid: ty::RegionVid,
180 ) -> <Self::Interner as Interner>::Region;
181
182 fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool;
183
184 fn next_region_infer(&self) -> <Self::Interner as Interner>::Region;
185 fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
186 fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
187 fn fresh_args_for_item(
188 &self,
189 def_id: <Self::Interner as Interner>::DefId,
190 ) -> <Self::Interner as Interner>::GenericArgs;
191
192 fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
193 &self,
194 value: ty::Binder<Self::Interner, T>,
195 ) -> T;
196
197 fn enter_forall<T: TypeFoldable<Self::Interner>, U>(
198 &self,
199 value: ty::Binder<Self::Interner, T>,
200 f: impl FnOnce(T) -> U,
201 ) -> U;
202
203 fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
204 fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid);
205 fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid);
206 fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid);
207
208 fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
209 &self,
210 relation: &mut R,
211 target_is_expected: bool,
212 target_vid: ty::TyVid,
213 instantiation_variance: ty::Variance,
214 source_ty: <Self::Interner as Interner>::Ty,
215 ) -> RelateResult<Self::Interner, ()>;
216 fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue);
217 fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue);
218 fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
219 &self,
220 relation: &mut R,
221 target_is_expected: bool,
222 target_vid: ty::ConstVid,
223 source_ct: <Self::Interner as Interner>::Const,
224 ) -> RelateResult<Self::Interner, ()>;
225
226 fn set_tainted_by_errors(&self, e: <Self::Interner as Interner>::ErrorGuaranteed);
227
228 fn shallow_resolve(
229 &self,
230 ty: <Self::Interner as Interner>::Ty,
231 ) -> <Self::Interner as Interner>::Ty;
232 fn shallow_resolve_const(
233 &self,
234 ty: <Self::Interner as Interner>::Const,
235 ) -> <Self::Interner as Interner>::Const;
236
237 fn resolve_vars_if_possible<T>(&self, value: T) -> T
238 where
239 T: TypeFoldable<Self::Interner>;
240
241 fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
242
243 fn sub_regions(
244 &self,
245 sub: <Self::Interner as Interner>::Region,
246 sup: <Self::Interner as Interner>::Region,
247 span: <Self::Interner as Interner>::Span,
248 );
249
250 fn equate_regions(
251 &self,
252 a: <Self::Interner as Interner>::Region,
253 b: <Self::Interner as Interner>::Region,
254 span: <Self::Interner as Interner>::Span,
255 );
256
257 fn register_ty_outlives(
258 &self,
259 ty: <Self::Interner as Interner>::Ty,
260 r: <Self::Interner as Interner>::Region,
261 span: <Self::Interner as Interner>::Span,
262 );
263
264 type OpaqueTypeStorageEntries: OpaqueTypeStorageEntries;
265 fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
266 fn clone_opaque_types_lookup_table(
267 &self,
268 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
269 fn clone_duplicate_opaque_types(
270 &self,
271 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
272 fn clone_opaque_types_added_since(
273 &self,
274 prev_entries: Self::OpaqueTypeStorageEntries,
275 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
276
277 fn register_hidden_type_in_storage(
278 &self,
279 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
280 hidden_ty: <Self::Interner as Interner>::Ty,
281 span: <Self::Interner as Interner>::Span,
282 ) -> Option<<Self::Interner as Interner>::Ty>;
283 fn add_duplicate_opaque_type(
284 &self,
285 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
286 hidden_ty: <Self::Interner as Interner>::Ty,
287 span: <Self::Interner as Interner>::Span,
288 );
289
290 fn reset_opaque_types(&self);
291}
292
293pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
294 infcx: &'a Infcx,
295 param_env: I::ParamEnv,
296 symbol: I::Symbol,
297) -> bool
298where
299 Infcx: InferCtxtLike<Interner = I>,
300{
301 for pred in param_env.caller_bounds().iter() {
303 if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
304 if sym == symbol {
305 return true;
306 }
307 }
308 }
309
310 (infcx.typing_mode() == TypingMode::PostAnalysis)
327 || infcx.cx().features().feature_bound_holds_in_crate(symbol)
328}