1pub mod inspect;
2
3use std::hash::Hash;
4
5use derive_where::derive_where;
6#[cfg(feature = "nightly")]
7use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
8use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
9
10use crate::lang_items::SolverTraitLangItem;
11use crate::search_graph::PathKind;
12use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
13
14pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
15 ty::CanonicalQueryInput<I, QueryInput<I, T>>;
16pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
17pub type QueryResult<I> = Result<CanonicalResponse<I>, NoSolution>;
24
25#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
26#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
27pub struct NoSolution;
28
29#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)]
35#[derive_where(Copy; I: Interner, P: Copy)]
36#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
37#[cfg_attr(
38 feature = "nightly",
39 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
40)]
41pub struct Goal<I: Interner, P> {
42 pub param_env: I::ParamEnv,
43 pub predicate: P,
44}
45
46impl<I: Interner, P: Eq> Eq for Goal<I, P> {}
47
48impl<I: Interner, P> Goal<I, P> {
49 pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> {
50 Goal { param_env, predicate: predicate.upcast(cx) }
51 }
52
53 pub fn with<Q>(self, cx: I, predicate: impl Upcast<I, Q>) -> Goal<I, Q> {
55 Goal { param_env: self.param_env, predicate: predicate.upcast(cx) }
56 }
57}
58
59#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
68#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
69pub enum GoalSource {
70 Misc,
71 TypeRelating,
77 ImplWhereBound,
79 AliasBoundConstCondition,
81 InstantiateHigherRanked,
83 AliasWellFormed,
90 NormalizeGoal(PathKind),
96}
97
98#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal<I, P>)]
99#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
100#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
101#[cfg_attr(
102 feature = "nightly",
103 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
104)]
105pub struct QueryInput<I: Interner, P> {
106 pub goal: Goal<I, P>,
107 pub predefined_opaques_in_body: I::PredefinedOpaques,
108}
109
110impl<I: Interner, P: Eq> Eq for QueryInput<I, P> {}
111
112#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
114#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
115#[cfg_attr(
116 feature = "nightly",
117 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
118)]
119pub struct PredefinedOpaquesData<I: Interner> {
120 pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
121}
122
123impl<I: Interner> Eq for PredefinedOpaquesData<I> {}
124
125#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
127pub enum CandidateSource<I: Interner> {
128 Impl(I::ImplId),
140 BuiltinImpl(BuiltinImplSource),
148 ParamEnv(ParamEnvSource),
161 AliasBound,
182 CoherenceUnknowable,
187}
188
189impl<I: Interner> Eq for CandidateSource<I> {}
190
191#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
192pub enum ParamEnvSource {
193 NonGlobal,
195 Global,
197}
198
199#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
200#[cfg_attr(
201 feature = "nightly",
202 derive(HashStable_NoContext, Encodable_NoContext, Decodable_NoContext)
203)]
204pub enum BuiltinImplSource {
205 Trivial,
208 Misc,
211 Object(usize),
213 TraitUpcasting(usize),
217}
218
219#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
220#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
221#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
222pub struct Response<I: Interner> {
223 pub certainty: Certainty,
224 pub var_values: CanonicalVarValues<I>,
225 pub external_constraints: I::ExternalConstraints,
227}
228
229impl<I: Interner> Eq for Response<I> {}
230
231#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
233#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
234#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
235pub struct ExternalConstraintsData<I: Interner> {
236 pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>,
237 pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
238 pub normalization_nested_goals: NestedNormalizationGoals<I>,
239}
240
241impl<I: Interner> Eq for ExternalConstraintsData<I> {}
242
243impl<I: Interner> ExternalConstraintsData<I> {
244 pub fn is_empty(&self) -> bool {
245 self.region_constraints.is_empty()
246 && self.opaque_types.is_empty()
247 && self.normalization_nested_goals.is_empty()
248 }
249}
250
251#[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)]
252#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
253#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
254pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
255
256impl<I: Interner> Eq for NestedNormalizationGoals<I> {}
257
258impl<I: Interner> NestedNormalizationGoals<I> {
259 pub fn empty() -> Self {
260 NestedNormalizationGoals(vec![])
261 }
262
263 pub fn is_empty(&self) -> bool {
264 self.0.is_empty()
265 }
266}
267
268#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
269#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
270pub enum Certainty {
271 Yes,
272 Maybe(MaybeCause),
273}
274
275impl Certainty {
276 pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
277
278 pub fn and(self, other: Certainty) -> Certainty {
291 match (self, other) {
292 (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
293 (Certainty::Yes, Certainty::Maybe(_)) => other,
294 (Certainty::Maybe(_), Certainty::Yes) => self,
295 (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)),
296 }
297 }
298
299 pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
300 Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false })
301 }
302}
303
304#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
306#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
307pub enum MaybeCause {
308 Ambiguity,
312 Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
314}
315
316impl MaybeCause {
317 fn and(self, other: MaybeCause) -> MaybeCause {
318 match (self, other) {
319 (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
320 (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
321 (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
322 (
323 MaybeCause::Overflow {
324 suggest_increasing_limit: limit_a,
325 keep_constraints: keep_a,
326 },
327 MaybeCause::Overflow {
328 suggest_increasing_limit: limit_b,
329 keep_constraints: keep_b,
330 },
331 ) => MaybeCause::Overflow {
332 suggest_increasing_limit: limit_a && limit_b,
333 keep_constraints: keep_a && keep_b,
334 },
335 }
336 }
337
338 pub fn or(self, other: MaybeCause) -> MaybeCause {
339 match (self, other) {
340 (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
341
342 (
344 MaybeCause::Ambiguity,
345 MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
346 ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
347 (
348 MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
349 MaybeCause::Ambiguity,
350 ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
351
352 (
353 MaybeCause::Overflow {
354 suggest_increasing_limit: limit_a,
355 keep_constraints: keep_a,
356 },
357 MaybeCause::Overflow {
358 suggest_increasing_limit: limit_b,
359 keep_constraints: keep_b,
360 },
361 ) => MaybeCause::Overflow {
362 suggest_increasing_limit: limit_a || limit_b,
363 keep_constraints: keep_a || keep_b,
364 },
365 }
366 }
367}
368
369#[derive(Debug)]
371pub enum AdtDestructorKind {
372 NotConst,
373 Const,
374}
375
376#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
379#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
380pub enum SizedTraitKind {
381 Sized,
383 MetaSized,
385}
386
387impl SizedTraitKind {
388 pub fn require_lang_item<I: Interner>(self, cx: I) -> I::TraitId {
390 cx.require_trait_lang_item(match self {
391 SizedTraitKind::Sized => SolverTraitLangItem::Sized,
392 SizedTraitKind::MetaSized => SolverTraitLangItem::MetaSized,
393 })
394 }
395}