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 }
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_hir_errors: self.reported_hir_errors.clone(),
112 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
113 tainted_by_errors: self.tainted_by_errors.clone(),
114 universe: self.universe.clone(),
115 placeholder_assumptions_for_next_solver: self
116 .placeholder_assumptions_for_next_solver
117 .clone(),
118 next_trait_solver: self.next_trait_solver,
119 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw.clone(),
120 obligation_inspector: self.obligation_inspector.clone(),
121 };
122 forked.inner.borrow_mut().projection_cache().clear();
123 forked
124 }
125
126 pub fn sup_raw<T>(
134 &self,
135 cause: &ObligationCause<'tcx>,
136 param_env: ParamEnv<'tcx>,
137 define_opaque_types: DefineOpaqueTypes,
138 expected: T,
139 actual: T,
140 ) -> InferResult<'tcx, ()>
141 where
142 T: ToTrace<'tcx>,
143 {
144 if self.next_trait_solver {
145 NextSolverRelate::relate(
146 self,
147 param_env,
148 expected,
149 ty::Contravariant,
150 actual,
151 cause.span,
152 )
153 .map(|goals| self.goals_to_obligations(cause, goals))
154 } else {
155 let mut op = TypeRelating::new(
156 &self,
157 ToTrace::to_trace(cause, expected, actual),
158 param_env,
159 define_opaque_types,
160 ty::Contravariant,
161 );
162 op.relate(expected, actual)?;
163 Ok(InferOk { value: (), obligations: op.into_obligations() })
164 }
165 }
166
167 pub fn sub_raw<T>(
172 &self,
173 cause: &ObligationCause<'tcx>,
174 param_env: ParamEnv<'tcx>,
175 define_opaque_types: DefineOpaqueTypes,
176 expected: T,
177 actual: T,
178 ) -> InferResult<'tcx, ()>
179 where
180 T: ToTrace<'tcx>,
181 {
182 if self.next_trait_solver {
183 NextSolverRelate::relate(self, param_env, expected, ty::Covariant, actual, cause.span)
184 .map(|goals| self.goals_to_obligations(cause, goals))
185 } else {
186 let mut op = TypeRelating::new(
187 self,
188 ToTrace::to_trace(cause, expected, actual),
189 param_env,
190 define_opaque_types,
191 ty::Covariant,
192 );
193 op.relate(expected, actual)?;
194 Ok(InferOk { value: (), obligations: op.into_obligations() })
195 }
196 }
197
198 pub fn eq_raw<T>(
203 self,
204 cause: &ObligationCause<'tcx>,
205 param_env: ParamEnv<'tcx>,
206 define_opaque_types: DefineOpaqueTypes,
207 expected: T,
208 actual: T,
209 ) -> InferResult<'tcx, ()>
210 where
211 T: ToTrace<'tcx>,
212 {
213 self.eq_trace_raw(
214 cause,
215 param_env,
216 define_opaque_types,
217 ToTrace::to_trace(cause, expected, actual),
218 expected,
219 actual,
220 )
221 }
222
223 pub fn eq_trace_raw<T>(
228 self,
229 cause: &ObligationCause<'tcx>,
230 param_env: ParamEnv<'tcx>,
231 define_opaque_types: DefineOpaqueTypes,
232 trace: TypeTrace<'tcx>,
233 expected: T,
234 actual: T,
235 ) -> InferResult<'tcx, ()>
236 where
237 T: Relate<TyCtxt<'tcx>>,
238 {
239 self.at(cause, param_env).eq_trace(define_opaque_types, trace, expected, actual)
240 }
241
242 pub fn relate_raw<T>(
245 self,
246 cause: &ObligationCause<'tcx>,
247 param_env: ParamEnv<'tcx>,
248 define_opaque_types: DefineOpaqueTypes,
249 expected: T,
250 variance: ty::Variance,
251 actual: T,
252 ) -> InferResult<'tcx, ()>
253 where
254 T: ToTrace<'tcx>,
255 {
256 self.at(cause, param_env).relate(define_opaque_types, expected, variance, actual)
257 }
258
259 pub fn lub_raw<T>(
268 self,
269 cause: &ObligationCause<'tcx>,
270 param_env: ParamEnv<'tcx>,
271 expected: T,
272 actual: T,
273 ) -> InferResult<'tcx, T>
274 where
275 T: ToTrace<'tcx>,
276 {
277 self.at(cause, param_env).lub(expected, actual)
278 }
279
280 pub fn goals_to_obligations(
281 &self,
282 cause: &ObligationCause<'tcx>,
283 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
284 ) -> InferOk<'tcx, ()> {
285 InferOk {
286 value: (),
287 obligations: goals
288 .into_iter()
289 .map(|goal| {
290 Obligation::new(self.tcx, cause.clone(), goal.param_env, goal.predicate)
291 })
292 .collect(),
293 }
294 }
295}
296
297pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
298 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
299}
300
301impl<'a, 'tcx> At<'a, 'tcx> {
302 pub fn eq<T>(
306 self,
307 define_opaque_types: DefineOpaqueTypes,
308 expected: T,
309 actual: T,
310 ) -> InferResult<'tcx, ()>
311 where
312 T: ToTrace<'tcx>,
313 {
314 self.eq_trace(
315 define_opaque_types,
316 ToTrace::to_trace(self.cause, expected, actual),
317 expected,
318 actual,
319 )
320 }
321
322 pub fn eq_trace<T>(
326 self,
327 define_opaque_types: DefineOpaqueTypes,
328 trace: TypeTrace<'tcx>,
329 expected: T,
330 actual: T,
331 ) -> InferResult<'tcx, ()>
332 where
333 T: Relate<TyCtxt<'tcx>>,
334 {
335 if self.infcx.next_trait_solver {
336 NextSolverRelate::relate(
337 self.infcx,
338 self.param_env,
339 expected,
340 ty::Invariant,
341 actual,
342 self.cause.span,
343 )
344 .map(|goals| self.goals_to_obligations(goals))
345 } else {
346 let mut op = TypeRelating::new(
347 self.infcx,
348 trace,
349 self.param_env,
350 define_opaque_types,
351 ty::Invariant,
352 );
353 op.relate(expected, actual)?;
354 Ok(InferOk { value: (), obligations: op.into_obligations() })
355 }
356 }
357
358 pub fn relate<T>(
360 self,
361 define_opaque_types: DefineOpaqueTypes,
362 expected: T,
363 variance: ty::Variance,
364 actual: T,
365 ) -> InferResult<'tcx, ()>
366 where
367 T: ToTrace<'tcx>,
368 {
369 match variance {
370 ty::Covariant => self.infcx.sub_raw(
371 self.cause,
372 self.param_env,
373 define_opaque_types,
374 expected,
375 actual,
376 ),
377 ty::Invariant => self.eq(define_opaque_types, expected, actual),
378 ty::Contravariant => self.infcx.sup_raw(
379 self.cause,
380 self.param_env,
381 define_opaque_types,
382 expected,
383 actual,
384 ),
385
386 ty::Bivariant => {
::core::panicking::panic_fmt(format_args!("Bivariant given to `relate()`"));
}panic!("Bivariant given to `relate()`"),
392 }
393 }
394
395 pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
403 where
404 T: ToTrace<'tcx>,
405 {
406 let mut op = LatticeOp::new(
407 self.infcx,
408 ToTrace::to_trace(self.cause, expected, actual),
409 self.param_env,
410 LatticeOpKind::Lub,
411 );
412 let value = op.relate(expected, actual)?;
413 Ok(InferOk { value, obligations: op.into_obligations() })
414 }
415
416 fn goals_to_obligations(
418 &self,
419 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
420 ) -> InferOk<'tcx, ()> {
421 InferOk {
422 value: (),
423 obligations: goals
424 .into_iter()
425 .map(|goal| {
426 Obligation::new(
427 self.infcx.tcx,
428 self.cause.clone(),
429 goal.param_env,
430 goal.predicate,
431 )
432 })
433 .collect(),
434 }
435 }
436}
437
438impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
439 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
440 TypeTrace {
441 cause: cause.clone(),
442 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
443 }
444 }
445}
446
447impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
448 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
449 TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) }
450 }
451}
452
453impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
454 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
455 TypeTrace {
456 cause: cause.clone(),
457 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
458 }
459 }
460}
461
462impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
463 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
464 TypeTrace {
465 cause: cause.clone(),
466 values: match (a.kind(), b.kind()) {
467 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
468 ValuePairs::Regions(ExpectedFound::new(a, b))
469 }
470 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
471 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
472 }
473 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
474 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
475 }
476 _ => ::rustc_span::macros::bug_impl(None,
format_args!("relating different kinds: {0:?} {1:?}", a, b),
Location::caller())bug!("relating different kinds: {a:?} {b:?}"),
477 },
478 }
479 }
480}
481
482impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
483 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
484 TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) }
485 }
486}
487
488impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
489 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
490 TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
491 }
492}
493
494impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
495 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
496 TypeTrace {
497 cause: cause.clone(),
498 values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())),
499 }
500 }
501}
502
503impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
504 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
505 TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) }
506 }
507}
508
509impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
510 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
511 TypeTrace {
512 cause: cause.clone(),
513 values: ValuePairs::PolySigs(ExpectedFound::new(
514 ty::Binder::dummy(a),
515 ty::Binder::dummy(b),
516 )),
517 }
518 }
519}
520
521impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
522 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
523 TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) }
524 }
525}
526
527impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
528 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
529 TypeTrace {
530 cause: cause.clone(),
531 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)),
532 }
533 }
534}
535
536impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> {
537 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
538 TypeTrace {
539 cause: cause.clone(),
540 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(
541 ty::Binder::dummy(a),
542 ty::Binder::dummy(b),
543 )),
544 }
545 }
546}
547
548impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
549 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
550 TypeTrace {
551 cause: cause.clone(),
552 values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)),
553 }
554 }
555}
556
557impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> {
558 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
559 TypeTrace {
560 cause: cause.clone(),
561 values: ValuePairs::ExistentialProjection(ExpectedFound::new(
562 ty::Binder::dummy(a),
563 ty::Binder::dummy(b),
564 )),
565 }
566 }
567}