1use std::fmt::Debug;
2use std::hash::Hash;
3use std::ops::Deref;
4
5use rustc_ast_ir::Movability;
6use rustc_index::bit_set::DenseBitSet;
7use smallvec::SmallVec;
8
9use crate::fold::TypeFoldable;
10use crate::inherent::*;
11use crate::ir_print::IrPrint;
12use crate::lang_items::TraitSolverLangItem;
13use crate::relate::Relate;
14use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult};
15use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
16use crate::{self as ty, search_graph};
17
18#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_interner")]
19pub trait Interner:
20 Sized
21 + Copy
22 + IrPrint<ty::AliasTy<Self>>
23 + IrPrint<ty::AliasTerm<Self>>
24 + IrPrint<ty::TraitRef<Self>>
25 + IrPrint<ty::TraitPredicate<Self>>
26 + IrPrint<ty::HostEffectPredicate<Self>>
27 + IrPrint<ty::ExistentialTraitRef<Self>>
28 + IrPrint<ty::ExistentialProjection<Self>>
29 + IrPrint<ty::ProjectionPredicate<Self>>
30 + IrPrint<ty::NormalizesTo<Self>>
31 + IrPrint<ty::SubtypePredicate<Self>>
32 + IrPrint<ty::CoercePredicate<Self>>
33 + IrPrint<ty::FnSig<Self>>
34{
35 type DefId: DefId<Self>;
36 type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
37 type Span: Span<Self>;
38
39 type GenericArgs: GenericArgs<Self>;
40 type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>;
41 type GenericArg: GenericArg<Self>;
42 type Term: Term<Self>;
43
44 type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike<Item = Self::BoundVarKind> + Default;
45 type BoundVarKind: Copy + Debug + Hash + Eq;
46
47 type PredefinedOpaques: Copy
48 + Debug
49 + Hash
50 + Eq
51 + TypeFoldable<Self>
52 + Deref<Target = PredefinedOpaquesData<Self>>;
53 fn mk_predefined_opaques_in_body(
54 self,
55 data: PredefinedOpaquesData<Self>,
56 ) -> Self::PredefinedOpaques;
57
58 type DefiningOpaqueTypes: Copy
59 + Debug
60 + Hash
61 + Default
62 + Eq
63 + TypeVisitable<Self>
64 + SliceLike<Item = Self::LocalDefId>;
65
66 type CanonicalVars: Copy
67 + Debug
68 + Hash
69 + Eq
70 + SliceLike<Item = ty::CanonicalVarInfo<Self>>
71 + Default;
72 fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
73
74 type ExternalConstraints: Copy
75 + Debug
76 + Hash
77 + Eq
78 + TypeFoldable<Self>
79 + Deref<Target = ExternalConstraintsData<Self>>;
80 fn mk_external_constraints(
81 self,
82 data: ExternalConstraintsData<Self>,
83 ) -> Self::ExternalConstraints;
84
85 type DepNodeIndex;
86 type Tracked<T: Debug + Clone>: Debug;
87 fn mk_tracked<T: Debug + Clone>(
88 self,
89 data: T,
90 dep_node: Self::DepNodeIndex,
91 ) -> Self::Tracked<T>;
92 fn get_tracked<T: Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T;
93 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, Self::DepNodeIndex);
94
95 type Ty: Ty<Self>;
97 type Tys: Tys<Self>;
98 type FnInputTys: Copy + Debug + Hash + Eq + SliceLike<Item = Self::Ty> + TypeVisitable<Self>;
99 type ParamTy: Copy + Debug + Hash + Eq + ParamLike;
100 type BoundTy: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
101 type PlaceholderTy: PlaceholderLike;
102
103 type ErrorGuaranteed: Copy + Debug + Hash + Eq;
105 type BoundExistentialPredicates: BoundExistentialPredicates<Self>;
106 type AllocId: Copy + Debug + Hash + Eq;
107 type Pat: Copy + Debug + Hash + Eq + Debug + Relate<Self>;
108 type Safety: Safety<Self>;
109 type Abi: Abi<Self>;
110
111 type Const: Const<Self>;
113 type PlaceholderConst: PlaceholderLike;
114 type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
115 type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
116 type ValueConst: ValueConst<Self>;
117 type ExprConst: ExprConst<Self>;
118 type ValTree: Copy + Debug + Hash + Eq;
119
120 type Region: Region<Self>;
122 type EarlyParamRegion: Copy + Debug + Hash + Eq + ParamLike;
123 type LateParamRegion: Copy + Debug + Hash + Eq;
124 type BoundRegion: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
125 type PlaceholderRegion: PlaceholderLike;
126
127 type ParamEnv: ParamEnv<Self>;
129 type Predicate: Predicate<Self>;
130 type Clause: Clause<Self>;
131 type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
132
133 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R;
134
135 fn evaluation_is_concurrent(&self) -> bool;
136
137 fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
138
139 type GenericsOf: GenericsOf<Self>;
140 fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
141
142 type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
143 fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
144
145 fn opt_alias_variances(
146 self,
147 kind: impl Into<ty::AliasTermKind>,
148 def_id: Self::DefId,
149 ) -> Option<Self::VariancesOf>;
150
151 fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
152
153 type AdtDef: AdtDef<Self>;
154 fn adt_def(self, adt_def_id: Self::DefId) -> Self::AdtDef;
155
156 fn alias_ty_kind(self, alias: ty::AliasTy<Self>) -> ty::AliasTyKind;
157
158 fn alias_term_kind(self, alias: ty::AliasTerm<Self>) -> ty::AliasTermKind;
159
160 fn trait_ref_and_own_args_for_alias(
161 self,
162 def_id: Self::DefId,
163 args: Self::GenericArgs,
164 ) -> (ty::TraitRef<Self>, Self::GenericArgsSlice);
165
166 fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
167
168 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
169 where
170 I: Iterator<Item = T>,
171 T: CollectAndApply<Self::GenericArg, Self::GenericArgs>;
172
173 fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool;
174
175 fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
176
177 fn debug_assert_existential_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
180
181 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
182 where
183 I: Iterator<Item = T>,
184 T: CollectAndApply<Self::Ty, Self::Tys>;
185
186 fn parent(self, def_id: Self::DefId) -> Self::DefId;
187
188 fn recursion_limit(self) -> usize;
189
190 type Features: Features<Self>;
191 fn features(self) -> Self::Features;
192
193 fn coroutine_hidden_types(
194 self,
195 def_id: Self::DefId,
196 ) -> ty::EarlyBinder<Self, ty::Binder<Self, Self::Tys>>;
197
198 fn fn_sig(
199 self,
200 def_id: Self::DefId,
201 ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::FnSig<Self>>>;
202
203 fn coroutine_movability(self, def_id: Self::DefId) -> Movability;
204
205 fn coroutine_for_closure(self, def_id: Self::DefId) -> Self::DefId;
206
207 fn generics_require_sized_self(self, def_id: Self::DefId) -> bool;
208
209 fn item_bounds(
210 self,
211 def_id: Self::DefId,
212 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
213
214 fn item_self_bounds(
215 self,
216 def_id: Self::DefId,
217 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
218
219 fn item_non_self_bounds(
220 self,
221 def_id: Self::DefId,
222 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
223
224 fn predicates_of(
225 self,
226 def_id: Self::DefId,
227 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
228
229 fn own_predicates_of(
230 self,
231 def_id: Self::DefId,
232 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
233
234 fn explicit_super_predicates_of(
235 self,
236 def_id: Self::DefId,
237 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
238
239 fn explicit_implied_predicates_of(
240 self,
241 def_id: Self::DefId,
242 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
243
244 fn impl_is_const(self, def_id: Self::DefId) -> bool;
245 fn fn_is_const(self, def_id: Self::DefId) -> bool;
246 fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;
247 fn const_conditions(
248 self,
249 def_id: Self::DefId,
250 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
251 fn explicit_implied_const_bounds(
252 self,
253 def_id: Self::DefId,
254 ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
255
256 fn has_target_features(self, def_id: Self::DefId) -> bool;
257
258 fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
259
260 fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool;
261
262 fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
263
264 fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;
265
266 fn for_each_relevant_impl(
267 self,
268 trait_def_id: Self::DefId,
269 self_ty: Self::Ty,
270 f: impl FnMut(Self::DefId),
271 );
272
273 fn has_item_definition(self, def_id: Self::DefId) -> bool;
274
275 fn impl_is_default(self, impl_def_id: Self::DefId) -> bool;
276
277 fn impl_trait_ref(self, impl_def_id: Self::DefId) -> ty::EarlyBinder<Self, ty::TraitRef<Self>>;
278
279 fn impl_polarity(self, impl_def_id: Self::DefId) -> ty::ImplPolarity;
280
281 fn trait_is_auto(self, trait_def_id: Self::DefId) -> bool;
282
283 fn trait_is_coinductive(self, trait_def_id: Self::DefId) -> bool;
284
285 fn trait_is_alias(self, trait_def_id: Self::DefId) -> bool;
286
287 fn trait_is_dyn_compatible(self, trait_def_id: Self::DefId) -> bool;
288
289 fn trait_is_fundamental(self, def_id: Self::DefId) -> bool;
290
291 fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;
292
293 fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool;
295
296 fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;
297
298 fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
299
300 fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool;
301 fn coroutine_is_async(self, coroutine_def_id: Self::DefId) -> bool;
302 fn coroutine_is_gen(self, coroutine_def_id: Self::DefId) -> bool;
303 fn coroutine_is_async_gen(self, coroutine_def_id: Self::DefId) -> bool;
304
305 type UnsizingParams: Deref<Target = DenseBitSet<u32>>;
306 fn unsizing_params_for_adt(self, adt_def_id: Self::DefId) -> Self::UnsizingParams;
307
308 fn find_const_ty_from_env(
309 self,
310 param_env: Self::ParamEnv,
311 placeholder: Self::PlaceholderConst,
312 ) -> Self::Ty;
313
314 fn anonymize_bound_vars<T: TypeFoldable<Self>>(
315 self,
316 binder: ty::Binder<Self, T>,
317 ) -> ty::Binder<Self, T>;
318
319 fn opaque_types_defined_by(
320 self,
321 defining_anchor: Self::LocalDefId,
322 ) -> Self::DefiningOpaqueTypes;
323}
324
325pub trait CollectAndApply<T, R>: Sized {
334 type Output;
335
336 fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
341 where
342 I: Iterator<Item = Self>,
343 F: FnOnce(&[T]) -> R;
344}
345
346impl<T, R> CollectAndApply<T, R> for T {
348 type Output = R;
349
350 fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
352 where
353 I: Iterator<Item = T>,
354 F: FnOnce(&[T]) -> R,
355 {
356 match iter.size_hint() {
362 (0, Some(0)) => {
363 assert!(iter.next().is_none());
364 f(&[])
365 }
366 (1, Some(1)) => {
367 let t0 = iter.next().unwrap();
368 assert!(iter.next().is_none());
369 f(&[t0])
370 }
371 (2, Some(2)) => {
372 let t0 = iter.next().unwrap();
373 let t1 = iter.next().unwrap();
374 assert!(iter.next().is_none());
375 f(&[t0, t1])
376 }
377 _ => f(&iter.collect::<SmallVec<[_; 8]>>()),
378 }
379 }
380}
381
382impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
385 type Output = Result<R, E>;
386
387 fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
389 where
390 I: Iterator<Item = Result<T, E>>,
391 F: FnOnce(&[T]) -> R,
392 {
393 Ok(match iter.size_hint() {
400 (0, Some(0)) => {
401 assert!(iter.next().is_none());
402 f(&[])
403 }
404 (1, Some(1)) => {
405 let t0 = iter.next().unwrap()?;
406 assert!(iter.next().is_none());
407 f(&[t0])
408 }
409 (2, Some(2)) => {
410 let t0 = iter.next().unwrap()?;
411 let t1 = iter.next().unwrap()?;
412 assert!(iter.next().is_none());
413 f(&[t0, t1])
414 }
415 _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
416 })
417 }
418}
419
420impl<I: Interner> search_graph::Cx for I {
421 type Input = CanonicalInput<I>;
422 type Result = QueryResult<I>;
423
424 type DepNodeIndex = I::DepNodeIndex;
425 type Tracked<T: Debug + Clone> = I::Tracked<T>;
426 fn mk_tracked<T: Debug + Clone>(
427 self,
428 data: T,
429 dep_node_index: I::DepNodeIndex,
430 ) -> I::Tracked<T> {
431 I::mk_tracked(self, data, dep_node_index)
432 }
433 fn get_tracked<T: Debug + Clone>(self, tracked: &I::Tracked<T>) -> T {
434 I::get_tracked(self, tracked)
435 }
436 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, I::DepNodeIndex) {
437 I::with_cached_task(self, task)
438 }
439 fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
440 I::with_global_cache(self, f)
441 }
442 fn evaluation_is_concurrent(&self) -> bool {
443 self.evaluation_is_concurrent()
444 }
445}