1use relate::lattice::{LatticeOp, LatticeOpKind};
29use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate;
30use rustc_middle::ty::{Const, ParamEnv, TypingMode};
31use rustc_span::bug;
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::marker::StructuralPartialEq for DefineOpaqueTypes { }
#[automatically_derived]
impl ::core::cmp::PartialEq for DefineOpaqueTypes {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DefineOpaqueTypes { }Eq, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DefineOpaqueTypes { }
#[automatically_derived]
impl ::core::clone::Clone for DefineOpaqueTypes {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DefineOpaqueTypes { }Copy)]
44pub enum DefineOpaqueTypes {
45 Yes,
46 No,
47}
48
49#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'a, 'tcx> ::core::clone::TrivialClone for At<'a, 'tcx> { }
#[automatically_derived]
impl<'a, 'tcx> ::core::clone::Clone for At<'a, 'tcx> {
#[inline]
fn clone(&self) -> Self {
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_hir_errors: self.reported_hir_errors.clone(),
82 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
83 tainted_by_errors: self.tainted_by_errors.clone(),
84 universe: self.universe.clone(),
85 placeholder_assumptions_for_next_solver: self
86 .placeholder_assumptions_for_next_solver
87 .clone(),
88 next_trait_solver: self.next_trait_solver,
89 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw.clone(),
90 obligation_inspector: self.obligation_inspector.clone(),
91 canonicalizer_state: Default::default(),
92 }
93 }
94
95 pub fn fork_with_typing_mode(&self, typing_mode: TypingMode<'tcx>) -> Self {
99 let forked = Self {
102 tcx: self.tcx,
103 typing_mode,
104 considering_regions: self.considering_regions,
105 in_hir_typeck: self.in_hir_typeck,
106 skip_leak_check: self.skip_leak_check,
107 inner: self.inner.clone(),
108 lexical_region_resolutions: self.lexical_region_resolutions.clone(),
109 selection_cache: Default::default(),
110 evaluation_cache: Default::default(),
111 reported_trait_errors: self.reported_trait_errors.clone(),
112 reported_hir_errors: self.reported_hir_errors.clone(),
113 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
114 tainted_by_errors: self.tainted_by_errors.clone(),
115 universe: self.universe.clone(),
116 placeholder_assumptions_for_next_solver: self
117 .placeholder_assumptions_for_next_solver
118 .clone(),
119 next_trait_solver: self.next_trait_solver,
120 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw.clone(),
121 obligation_inspector: self.obligation_inspector.clone(),
122 canonicalizer_state: Default::default(),
123 };
124 forked.inner.borrow_mut().projection_cache().clear();
125 forked
126 }
127
128 pub fn sup_raw<T>(
136 &self,
137 cause: &ObligationCause<'tcx>,
138 param_env: ParamEnv<'tcx>,
139 define_opaque_types: DefineOpaqueTypes,
140 expected: T,
141 actual: T,
142 ) -> InferResult<'tcx, ()>
143 where
144 T: ToTrace<'tcx>,
145 {
146 if self.next_trait_solver {
147 NextSolverRelate::relate(
148 self,
149 param_env,
150 expected,
151 ty::Contravariant,
152 actual,
153 cause.span,
154 )
155 .map(|goals| self.goals_to_obligations(cause, goals))
156 } else {
157 let mut op = TypeRelating::new(
158 &self,
159 ToTrace::to_trace(cause, expected, actual),
160 param_env,
161 define_opaque_types,
162 ty::Contravariant,
163 );
164 op.relate(expected, actual)?;
165 Ok(InferOk { value: (), obligations: op.into_obligations() })
166 }
167 }
168
169 pub fn sub_raw<T>(
174 self,
175 cause: &ObligationCause<'tcx>,
176 param_env: ParamEnv<'tcx>,
177 define_opaque_types: DefineOpaqueTypes,
178 expected: T,
179 actual: T,
180 ) -> InferResult<'tcx, ()>
181 where
182 T: ToTrace<'tcx>,
183 {
184 self.at(cause, param_env).sub(define_opaque_types, expected, actual)
185 }
186
187 pub fn eq_raw<T>(
192 self,
193 cause: &ObligationCause<'tcx>,
194 param_env: ParamEnv<'tcx>,
195 define_opaque_types: DefineOpaqueTypes,
196 expected: T,
197 actual: T,
198 ) -> InferResult<'tcx, ()>
199 where
200 T: ToTrace<'tcx>,
201 {
202 self.eq_trace_raw(
203 cause,
204 param_env,
205 define_opaque_types,
206 ToTrace::to_trace(cause, expected, actual),
207 expected,
208 actual,
209 )
210 }
211
212 pub fn eq_trace_raw<T>(
217 self,
218 cause: &ObligationCause<'tcx>,
219 param_env: ParamEnv<'tcx>,
220 define_opaque_types: DefineOpaqueTypes,
221 trace: TypeTrace<'tcx>,
222 expected: T,
223 actual: T,
224 ) -> InferResult<'tcx, ()>
225 where
226 T: Relate<TyCtxt<'tcx>>,
227 {
228 self.at(cause, param_env).eq_trace(define_opaque_types, trace, expected, actual)
229 }
230
231 pub fn relate_raw<T>(
234 self,
235 cause: &ObligationCause<'tcx>,
236 param_env: ParamEnv<'tcx>,
237 define_opaque_types: DefineOpaqueTypes,
238 expected: T,
239 variance: ty::Variance,
240 actual: T,
241 ) -> InferResult<'tcx, ()>
242 where
243 T: ToTrace<'tcx>,
244 {
245 self.at(cause, param_env).relate(define_opaque_types, expected, variance, actual)
246 }
247
248 pub fn lub_raw<T>(
257 self,
258 cause: &ObligationCause<'tcx>,
259 param_env: ParamEnv<'tcx>,
260 expected: T,
261 actual: T,
262 ) -> InferResult<'tcx, T>
263 where
264 T: ToTrace<'tcx>,
265 {
266 self.at(cause, param_env).lub(expected, actual)
267 }
268
269 pub fn goals_to_obligations(
270 &self,
271 cause: &ObligationCause<'tcx>,
272 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
273 ) -> InferOk<'tcx, ()> {
274 InferOk {
275 value: (),
276 obligations: goals
277 .into_iter()
278 .map(|goal| {
279 Obligation::new(self.tcx, cause.clone(), goal.param_env, goal.predicate)
280 })
281 .collect(),
282 }
283 }
284}
285
286pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
287 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
288}
289
290impl<'a, 'tcx> At<'a, 'tcx> {
291 pub fn sub<T>(
295 self,
296 define_opaque_types: DefineOpaqueTypes,
297 expected: T,
298 actual: T,
299 ) -> InferResult<'tcx, ()>
300 where
301 T: ToTrace<'tcx>,
302 {
303 if self.infcx.next_trait_solver {
304 NextSolverRelate::relate(
305 self.infcx,
306 self.param_env,
307 expected,
308 ty::Covariant,
309 actual,
310 self.cause.span,
311 )
312 .map(|goals| self.goals_to_obligations(goals))
313 } else {
314 let mut op = TypeRelating::new(
315 self.infcx,
316 ToTrace::to_trace(self.cause, expected, actual),
317 self.param_env,
318 define_opaque_types,
319 ty::Covariant,
320 );
321 op.relate(expected, actual)?;
322 Ok(InferOk { value: (), obligations: op.into_obligations() })
323 }
324 }
325
326 pub fn eq<T>(
330 self,
331 define_opaque_types: DefineOpaqueTypes,
332 expected: T,
333 actual: T,
334 ) -> InferResult<'tcx, ()>
335 where
336 T: ToTrace<'tcx>,
337 {
338 self.eq_trace(
339 define_opaque_types,
340 ToTrace::to_trace(self.cause, expected, actual),
341 expected,
342 actual,
343 )
344 }
345
346 pub fn eq_trace<T>(
350 self,
351 define_opaque_types: DefineOpaqueTypes,
352 trace: TypeTrace<'tcx>,
353 expected: T,
354 actual: T,
355 ) -> InferResult<'tcx, ()>
356 where
357 T: Relate<TyCtxt<'tcx>>,
358 {
359 if self.infcx.next_trait_solver {
360 NextSolverRelate::relate(
361 self.infcx,
362 self.param_env,
363 expected,
364 ty::Invariant,
365 actual,
366 self.cause.span,
367 )
368 .map(|goals| self.goals_to_obligations(goals))
369 } else {
370 let mut op = TypeRelating::new(
371 self.infcx,
372 trace,
373 self.param_env,
374 define_opaque_types,
375 ty::Invariant,
376 );
377 op.relate(expected, actual)?;
378 Ok(InferOk { value: (), obligations: op.into_obligations() })
379 }
380 }
381
382 pub fn relate<T>(
384 self,
385 define_opaque_types: DefineOpaqueTypes,
386 expected: T,
387 variance: ty::Variance,
388 actual: T,
389 ) -> InferResult<'tcx, ()>
390 where
391 T: ToTrace<'tcx>,
392 {
393 match variance {
394 ty::Covariant => self.sub(define_opaque_types, expected, actual),
395 ty::Invariant => self.eq(define_opaque_types, expected, actual),
396 ty::Contravariant => self.infcx.sup_raw(
397 self.cause,
398 self.param_env,
399 define_opaque_types,
400 expected,
401 actual,
402 ),
403
404 ty::Bivariant => {
::core::panicking::panic_fmt(format_args!("Bivariant given to `relate()`"));
}panic!("Bivariant given to `relate()`"),
410 }
411 }
412
413 pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
421 where
422 T: ToTrace<'tcx>,
423 {
424 let mut op = LatticeOp::new(
425 self.infcx,
426 ToTrace::to_trace(self.cause, expected, actual),
427 self.param_env,
428 LatticeOpKind::Lub,
429 );
430 let value = op.relate(expected, actual)?;
431 Ok(InferOk { value, obligations: op.into_obligations() })
432 }
433
434 fn goals_to_obligations(
436 &self,
437 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
438 ) -> InferOk<'tcx, ()> {
439 InferOk {
440 value: (),
441 obligations: goals
442 .into_iter()
443 .map(|goal| {
444 Obligation::new(
445 self.infcx.tcx,
446 self.cause.clone(),
447 goal.param_env,
448 goal.predicate,
449 )
450 })
451 .collect(),
452 }
453 }
454}
455
456impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
457 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
458 TypeTrace {
459 cause: cause.clone(),
460 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
461 }
462 }
463}
464
465impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
466 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
467 TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) }
468 }
469}
470
471impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
472 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
473 TypeTrace {
474 cause: cause.clone(),
475 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
476 }
477 }
478}
479
480impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
481 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
482 TypeTrace {
483 cause: cause.clone(),
484 values: match (a.kind(), b.kind()) {
485 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
486 ValuePairs::Regions(ExpectedFound::new(a, b))
487 }
488 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
489 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
490 }
491 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
492 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
493 }
494 _ => ::rustc_span::macros::bug_impl(None,
format_args!("relating different kinds: {0:?} {1:?}", a, b),
Location::caller())bug!("relating different kinds: {a:?} {b:?}"),
495 },
496 }
497 }
498}
499
500impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
501 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
502 TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) }
503 }
504}
505
506impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
507 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
508 TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
509 }
510}
511
512impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
513 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
514 TypeTrace {
515 cause: cause.clone(),
516 values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())),
517 }
518 }
519}
520
521impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
522 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
523 TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) }
524 }
525}
526
527impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
528 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
529 TypeTrace {
530 cause: cause.clone(),
531 values: ValuePairs::PolySigs(ExpectedFound::new(
532 ty::Binder::dummy(a),
533 ty::Binder::dummy(b),
534 )),
535 }
536 }
537}
538
539impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
540 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
541 TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) }
542 }
543}
544
545impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
546 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
547 TypeTrace {
548 cause: cause.clone(),
549 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)),
550 }
551 }
552}
553
554impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> {
555 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
556 TypeTrace {
557 cause: cause.clone(),
558 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(
559 ty::Binder::dummy(a),
560 ty::Binder::dummy(b),
561 )),
562 }
563 }
564}
565
566impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
567 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
568 TypeTrace {
569 cause: cause.clone(),
570 values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)),
571 }
572 }
573}
574
575impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> {
576 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
577 TypeTrace {
578 cause: cause.clone(),
579 values: ValuePairs::ExistentialProjection(ExpectedFound::new(
580 ty::Binder::dummy(a),
581 ty::Binder::dummy(b),
582 )),
583 }
584 }
585}