1use relate::lattice::{LatticeOp, LatticeOpKind};
29use rustc_middle::bug;
30use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate;
31use rustc_middle::ty::{Const, TypingMode};
32
33use super::*;
34use crate::infer::relate::type_relating::TypeRelating;
35use crate::infer::relate::{Relate, TypeRelation};
36use crate::traits::Obligation;
37use crate::traits::solve::Goal;
38
39#[derive(#[automatically_derived]
impl ::core::fmt::Debug for DefineOpaqueTypes {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
DefineOpaqueTypes::Yes => "Yes",
DefineOpaqueTypes::No => "No",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DefineOpaqueTypes {
#[inline]
fn eq(&self, other: &DefineOpaqueTypes) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DefineOpaqueTypes {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::clone::Clone for DefineOpaqueTypes {
#[inline]
fn clone(&self) -> DefineOpaqueTypes { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DefineOpaqueTypes { }Copy)]
44pub enum DefineOpaqueTypes {
45 Yes,
46 No,
47}
48
49#[derive(#[automatically_derived]
impl<'a, 'tcx> ::core::clone::Clone for At<'a, 'tcx> {
#[inline]
fn clone(&self) -> At<'a, 'tcx> {
let _: ::core::clone::AssertParamIsClone<&'a InferCtxt<'tcx>>;
let _: ::core::clone::AssertParamIsClone<&'a ObligationCause<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ty::ParamEnv<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'a, 'tcx> ::core::marker::Copy for At<'a, 'tcx> { }Copy)]
50pub struct At<'a, 'tcx> {
51 pub infcx: &'a InferCtxt<'tcx>,
52 pub cause: &'a ObligationCause<'tcx>,
53 pub param_env: ty::ParamEnv<'tcx>,
54}
55
56impl<'tcx> InferCtxt<'tcx> {
57 #[inline]
58 pub fn at<'a>(
59 &'a self,
60 cause: &'a ObligationCause<'tcx>,
61 param_env: ty::ParamEnv<'tcx>,
62 ) -> At<'a, 'tcx> {
63 At { infcx: self, cause, param_env }
64 }
65
66 pub fn fork(&self) -> Self {
70 Self {
71 tcx: self.tcx,
72 typing_mode: self.typing_mode,
73 considering_regions: self.considering_regions,
74 in_hir_typeck: self.in_hir_typeck,
75 skip_leak_check: self.skip_leak_check,
76 inner: self.inner.clone(),
77 lexical_region_resolutions: self.lexical_region_resolutions.clone(),
78 selection_cache: self.selection_cache.clone(),
79 evaluation_cache: self.evaluation_cache.clone(),
80 reported_trait_errors: self.reported_trait_errors.clone(),
81 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
82 tainted_by_errors: self.tainted_by_errors.clone(),
83 universe: self.universe.clone(),
84 placeholder_assumptions_for_next_solver: self
85 .placeholder_assumptions_for_next_solver
86 .clone(),
87 next_trait_solver: self.next_trait_solver,
88 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw,
89 obligation_inspector: self.obligation_inspector.clone(),
90 canonicalizer_state: Default::default(),
91 }
92 }
93
94 pub fn fork_with_typing_mode(&self, typing_mode: TypingMode<'tcx>) -> Self {
98 let forked = Self {
101 tcx: self.tcx,
102 typing_mode,
103 considering_regions: self.considering_regions,
104 in_hir_typeck: self.in_hir_typeck,
105 skip_leak_check: self.skip_leak_check,
106 inner: self.inner.clone(),
107 lexical_region_resolutions: self.lexical_region_resolutions.clone(),
108 selection_cache: Default::default(),
109 evaluation_cache: Default::default(),
110 reported_trait_errors: self.reported_trait_errors.clone(),
111 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
112 tainted_by_errors: self.tainted_by_errors.clone(),
113 universe: self.universe.clone(),
114 placeholder_assumptions_for_next_solver: self
115 .placeholder_assumptions_for_next_solver
116 .clone(),
117 next_trait_solver: self.next_trait_solver,
118 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw,
119 obligation_inspector: self.obligation_inspector.clone(),
120 canonicalizer_state: Default::default(),
121 };
122 forked.inner.borrow_mut().projection_cache().clear();
123 forked
124 }
125}
126
127pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
128 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
129}
130
131impl<'a, 'tcx> At<'a, 'tcx> {
132 pub fn sup<T>(
137 self,
138 define_opaque_types: DefineOpaqueTypes,
139 expected: T,
140 actual: T,
141 ) -> InferResult<'tcx, ()>
142 where
143 T: ToTrace<'tcx>,
144 {
145 if self.infcx.next_trait_solver {
146 NextSolverRelate::relate(
147 self.infcx,
148 self.param_env,
149 expected,
150 ty::Contravariant,
151 actual,
152 self.cause.span,
153 )
154 .map(|goals| self.goals_to_obligations(goals))
155 } else {
156 let mut op = TypeRelating::new(
157 self.infcx,
158 ToTrace::to_trace(self.cause, expected, actual),
159 self.param_env,
160 define_opaque_types,
161 ty::Contravariant,
162 );
163 op.relate(expected, actual)?;
164 Ok(InferOk { value: (), obligations: op.into_obligations() })
165 }
166 }
167
168 pub fn sub<T>(
170 self,
171 define_opaque_types: DefineOpaqueTypes,
172 expected: T,
173 actual: T,
174 ) -> InferResult<'tcx, ()>
175 where
176 T: ToTrace<'tcx>,
177 {
178 if self.infcx.next_trait_solver {
179 NextSolverRelate::relate(
180 self.infcx,
181 self.param_env,
182 expected,
183 ty::Covariant,
184 actual,
185 self.cause.span,
186 )
187 .map(|goals| self.goals_to_obligations(goals))
188 } else {
189 let mut op = TypeRelating::new(
190 self.infcx,
191 ToTrace::to_trace(self.cause, expected, actual),
192 self.param_env,
193 define_opaque_types,
194 ty::Covariant,
195 );
196 op.relate(expected, actual)?;
197 Ok(InferOk { value: (), obligations: op.into_obligations() })
198 }
199 }
200
201 pub fn eq<T>(
203 self,
204 define_opaque_types: DefineOpaqueTypes,
205 expected: T,
206 actual: T,
207 ) -> InferResult<'tcx, ()>
208 where
209 T: ToTrace<'tcx>,
210 {
211 self.eq_trace(
212 define_opaque_types,
213 ToTrace::to_trace(self.cause, expected, actual),
214 expected,
215 actual,
216 )
217 }
218
219 pub fn eq_trace<T>(
221 self,
222 define_opaque_types: DefineOpaqueTypes,
223 trace: TypeTrace<'tcx>,
224 expected: T,
225 actual: T,
226 ) -> InferResult<'tcx, ()>
227 where
228 T: Relate<TyCtxt<'tcx>>,
229 {
230 if self.infcx.next_trait_solver {
231 NextSolverRelate::relate(
232 self.infcx,
233 self.param_env,
234 expected,
235 ty::Invariant,
236 actual,
237 self.cause.span,
238 )
239 .map(|goals| self.goals_to_obligations(goals))
240 } else {
241 let mut op = TypeRelating::new(
242 self.infcx,
243 trace,
244 self.param_env,
245 define_opaque_types,
246 ty::Invariant,
247 );
248 op.relate(expected, actual)?;
249 Ok(InferOk { value: (), obligations: op.into_obligations() })
250 }
251 }
252
253 pub fn relate<T>(
254 self,
255 define_opaque_types: DefineOpaqueTypes,
256 expected: T,
257 variance: ty::Variance,
258 actual: T,
259 ) -> InferResult<'tcx, ()>
260 where
261 T: ToTrace<'tcx>,
262 {
263 match variance {
264 ty::Covariant => self.sub(define_opaque_types, expected, actual),
265 ty::Invariant => self.eq(define_opaque_types, expected, actual),
266 ty::Contravariant => self.sup(define_opaque_types, expected, actual),
267
268 ty::Bivariant => {
::core::panicking::panic_fmt(format_args!("Bivariant given to `relate()`"));
}panic!("Bivariant given to `relate()`"),
274 }
275 }
276
277 pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
283 where
284 T: ToTrace<'tcx>,
285 {
286 let mut op = LatticeOp::new(
287 self.infcx,
288 ToTrace::to_trace(self.cause, expected, actual),
289 self.param_env,
290 LatticeOpKind::Lub,
291 );
292 let value = op.relate(expected, actual)?;
293 Ok(InferOk { value, obligations: op.into_obligations() })
294 }
295
296 fn goals_to_obligations(
297 &self,
298 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
299 ) -> InferOk<'tcx, ()> {
300 InferOk {
301 value: (),
302 obligations: goals
303 .into_iter()
304 .map(|goal| {
305 Obligation::new(
306 self.infcx.tcx,
307 self.cause.clone(),
308 goal.param_env,
309 goal.predicate,
310 )
311 })
312 .collect(),
313 }
314 }
315}
316
317impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
318 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
319 TypeTrace {
320 cause: cause.clone(),
321 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
322 }
323 }
324}
325
326impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
327 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
328 TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) }
329 }
330}
331
332impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
333 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
334 TypeTrace {
335 cause: cause.clone(),
336 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
337 }
338 }
339}
340
341impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
342 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
343 TypeTrace {
344 cause: cause.clone(),
345 values: match (a.kind(), b.kind()) {
346 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
347 ValuePairs::Regions(ExpectedFound::new(a, b))
348 }
349 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
350 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
351 }
352 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
353 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
354 }
355 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("relating different kinds: {0:?} {1:?}",
a, b))bug!("relating different kinds: {a:?} {b:?}"),
356 },
357 }
358 }
359}
360
361impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
362 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
363 TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) }
364 }
365}
366
367impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
368 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
369 TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
370 }
371}
372
373impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
374 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
375 TypeTrace {
376 cause: cause.clone(),
377 values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())),
378 }
379 }
380}
381
382impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
383 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
384 TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) }
385 }
386}
387
388impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
389 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
390 TypeTrace {
391 cause: cause.clone(),
392 values: ValuePairs::PolySigs(ExpectedFound::new(
393 ty::Binder::dummy(a),
394 ty::Binder::dummy(b),
395 )),
396 }
397 }
398}
399
400impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
401 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
402 TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) }
403 }
404}
405
406impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
407 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
408 TypeTrace {
409 cause: cause.clone(),
410 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)),
411 }
412 }
413}
414
415impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> {
416 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
417 TypeTrace {
418 cause: cause.clone(),
419 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(
420 ty::Binder::dummy(a),
421 ty::Binder::dummy(b),
422 )),
423 }
424 }
425}
426
427impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
428 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
429 TypeTrace {
430 cause: cause.clone(),
431 values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)),
432 }
433 }
434}
435
436impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> {
437 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
438 TypeTrace {
439 cause: cause.clone(),
440 values: ValuePairs::ExistentialProjection(ExpectedFound::new(
441 ty::Binder::dummy(a),
442 ty::Binder::dummy(b),
443 )),
444 }
445 }
446}