1pub mod inspect;
2
3use std::fmt;
4use std::hash::Hash;
5
6use derive_where::derive_where;
7#[cfg(feature = "nightly")]
8use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
9use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
10
11use crate::lang_items::TraitSolverLangItem;
12use crate::search_graph::PathKind;
13use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
14
15pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
16 ty::CanonicalQueryInput<I, QueryInput<I, T>>;
17pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
18pub type QueryResult<I> = Result<CanonicalResponse<I>, NoSolution>;
25
26#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
27#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
28pub struct NoSolution;
29
30#[derive_where(Clone; I: Interner, P: Clone)]
36#[derive_where(Copy; I: Interner, P: Copy)]
37#[derive_where(Hash; I: Interner, P: Hash)]
38#[derive_where(PartialEq; I: Interner, P: PartialEq)]
39#[derive_where(Eq; I: Interner, P: Eq)]
40#[derive_where(Debug; I: Interner, P: fmt::Debug)]
41#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
42#[cfg_attr(
43 feature = "nightly",
44 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
45)]
46pub struct Goal<I: Interner, P> {
47 pub param_env: I::ParamEnv,
48 pub predicate: P,
49}
50
51impl<I: Interner, P> Goal<I, P> {
52 pub fn new(cx: I, param_env: I::ParamEnv, predicate: impl Upcast<I, P>) -> Goal<I, P> {
53 Goal { param_env, predicate: predicate.upcast(cx) }
54 }
55
56 pub fn with<Q>(self, cx: I, predicate: impl Upcast<I, Q>) -> Goal<I, Q> {
58 Goal { param_env: self.param_env, predicate: predicate.upcast(cx) }
59 }
60}
61
62#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
71#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
72pub enum GoalSource {
73 Misc,
74 TypeRelating,
80 ImplWhereBound,
82 AliasBoundConstCondition,
84 InstantiateHigherRanked,
86 AliasWellFormed,
93 NormalizeGoal(PathKind),
99}
100
101#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
102#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
103#[derive_where(Hash; I: Interner, Goal<I, P>: Hash)]
104#[derive_where(PartialEq; I: Interner, Goal<I, P>: PartialEq)]
105#[derive_where(Eq; I: Interner, Goal<I, P>: Eq)]
106#[derive_where(Debug; I: Interner, Goal<I, P>: fmt::Debug)]
107#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
108#[cfg_attr(
109 feature = "nightly",
110 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
111)]
112pub struct QueryInput<I: Interner, P> {
113 pub goal: Goal<I, P>,
114 pub predefined_opaques_in_body: I::PredefinedOpaques,
115}
116
117#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
119#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
120#[cfg_attr(
121 feature = "nightly",
122 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
123)]
124pub struct PredefinedOpaquesData<I: Interner> {
125 pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
126}
127
128#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
130pub enum CandidateSource<I: Interner> {
131 Impl(I::DefId),
143 BuiltinImpl(BuiltinImplSource),
151 ParamEnv(ParamEnvSource),
164 AliasBound,
185 CoherenceUnknowable,
190}
191
192#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
193pub enum ParamEnvSource {
194 NonGlobal,
196 Global,
198}
199
200#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
201#[cfg_attr(
202 feature = "nightly",
203 derive(HashStable_NoContext, Encodable_NoContext, Decodable_NoContext)
204)]
205pub enum BuiltinImplSource {
206 Trivial,
209 Misc,
212 Object(usize),
214 TraitUpcasting(usize),
218}
219
220#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
221#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
222#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
223pub struct Response<I: Interner> {
224 pub certainty: Certainty,
225 pub var_values: CanonicalVarValues<I>,
226 pub external_constraints: I::ExternalConstraints,
228}
229
230#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
232#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
233#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
234pub struct ExternalConstraintsData<I: Interner> {
235 pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>,
236 pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
237 pub normalization_nested_goals: NestedNormalizationGoals<I>,
238}
239
240impl<I: Interner> ExternalConstraintsData<I> {
241 pub fn is_empty(&self) -> bool {
242 self.region_constraints.is_empty()
243 && self.opaque_types.is_empty()
244 && self.normalization_nested_goals.is_empty()
245 }
246}
247
248#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
249#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
250#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
251pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
252
253impl<I: Interner> NestedNormalizationGoals<I> {
254 pub fn empty() -> Self {
255 NestedNormalizationGoals(vec![])
256 }
257
258 pub fn is_empty(&self) -> bool {
259 self.0.is_empty()
260 }
261}
262
263#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
264#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
265pub enum Certainty {
266 Yes,
267 Maybe(MaybeCause),
268}
269
270impl Certainty {
271 pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
272
273 pub fn and(self, other: Certainty) -> Certainty {
286 match (self, other) {
287 (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
288 (Certainty::Yes, Certainty::Maybe(_)) => other,
289 (Certainty::Maybe(_), Certainty::Yes) => self,
290 (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)),
291 }
292 }
293
294 pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
295 Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false })
296 }
297}
298
299#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
301#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
302pub enum MaybeCause {
303 Ambiguity,
307 Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
309}
310
311impl MaybeCause {
312 fn and(self, other: MaybeCause) -> MaybeCause {
313 match (self, other) {
314 (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
315 (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
316 (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
317 (
318 MaybeCause::Overflow {
319 suggest_increasing_limit: limit_a,
320 keep_constraints: keep_a,
321 },
322 MaybeCause::Overflow {
323 suggest_increasing_limit: limit_b,
324 keep_constraints: keep_b,
325 },
326 ) => MaybeCause::Overflow {
327 suggest_increasing_limit: limit_a && limit_b,
328 keep_constraints: keep_a && keep_b,
329 },
330 }
331 }
332
333 pub fn or(self, other: MaybeCause) -> MaybeCause {
334 match (self, other) {
335 (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
336
337 (
339 MaybeCause::Ambiguity,
340 MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
341 ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
342 (
343 MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
344 MaybeCause::Ambiguity,
345 ) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
346
347 (
348 MaybeCause::Overflow {
349 suggest_increasing_limit: limit_a,
350 keep_constraints: keep_a,
351 },
352 MaybeCause::Overflow {
353 suggest_increasing_limit: limit_b,
354 keep_constraints: keep_b,
355 },
356 ) => MaybeCause::Overflow {
357 suggest_increasing_limit: limit_a || limit_b,
358 keep_constraints: keep_a || keep_b,
359 },
360 }
361 }
362}
363
364#[derive(Debug)]
366pub enum AdtDestructorKind {
367 NotConst,
368 Const,
369}
370
371#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
374#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
375pub enum SizedTraitKind {
376 Sized,
378 MetaSized,
380}
381
382impl SizedTraitKind {
383 pub fn require_lang_item<I: Interner>(self, cx: I) -> I::DefId {
385 cx.require_lang_item(match self {
386 SizedTraitKind::Sized => TraitSolverLangItem::Sized,
387 SizedTraitKind::MetaSized => TraitSolverLangItem::MetaSized,
388 })
389 }
390}