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 }
91 }
92
93 pub fn fork_with_typing_mode(&self, typing_mode: TypingMode<'tcx>) -> Self {
97 let forked = Self {
100 tcx: self.tcx,
101 typing_mode,
102 considering_regions: self.considering_regions,
103 in_hir_typeck: self.in_hir_typeck,
104 skip_leak_check: self.skip_leak_check,
105 inner: self.inner.clone(),
106 lexical_region_resolutions: self.lexical_region_resolutions.clone(),
107 selection_cache: Default::default(),
108 evaluation_cache: Default::default(),
109 reported_trait_errors: self.reported_trait_errors.clone(),
110 reported_signature_mismatch: self.reported_signature_mismatch.clone(),
111 tainted_by_errors: self.tainted_by_errors.clone(),
112 universe: self.universe.clone(),
113 placeholder_assumptions_for_next_solver: self
114 .placeholder_assumptions_for_next_solver
115 .clone(),
116 next_trait_solver: self.next_trait_solver,
117 enable_next_solver_overflow_fcw: self.enable_next_solver_overflow_fcw,
118 obligation_inspector: self.obligation_inspector.clone(),
119 };
120 forked.inner.borrow_mut().projection_cache().clear();
121 forked
122 }
123}
124
125pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
126 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
127}
128
129impl<'a, 'tcx> At<'a, 'tcx> {
130 pub fn sup<T>(
135 self,
136 define_opaque_types: DefineOpaqueTypes,
137 expected: T,
138 actual: T,
139 ) -> InferResult<'tcx, ()>
140 where
141 T: ToTrace<'tcx>,
142 {
143 if self.infcx.next_trait_solver {
144 NextSolverRelate::relate(
145 self.infcx,
146 self.param_env,
147 expected,
148 ty::Contravariant,
149 actual,
150 self.cause.span,
151 )
152 .map(|goals| self.goals_to_obligations(goals))
153 } else {
154 let mut op = TypeRelating::new(
155 self.infcx,
156 ToTrace::to_trace(self.cause, expected, actual),
157 self.param_env,
158 define_opaque_types,
159 ty::Contravariant,
160 );
161 op.relate(expected, actual)?;
162 Ok(InferOk { value: (), obligations: op.into_obligations() })
163 }
164 }
165
166 pub fn sub<T>(
168 self,
169 define_opaque_types: DefineOpaqueTypes,
170 expected: T,
171 actual: T,
172 ) -> InferResult<'tcx, ()>
173 where
174 T: ToTrace<'tcx>,
175 {
176 if self.infcx.next_trait_solver {
177 NextSolverRelate::relate(
178 self.infcx,
179 self.param_env,
180 expected,
181 ty::Covariant,
182 actual,
183 self.cause.span,
184 )
185 .map(|goals| self.goals_to_obligations(goals))
186 } else {
187 let mut op = TypeRelating::new(
188 self.infcx,
189 ToTrace::to_trace(self.cause, expected, actual),
190 self.param_env,
191 define_opaque_types,
192 ty::Covariant,
193 );
194 op.relate(expected, actual)?;
195 Ok(InferOk { value: (), obligations: op.into_obligations() })
196 }
197 }
198
199 pub fn eq<T>(
201 self,
202 define_opaque_types: DefineOpaqueTypes,
203 expected: T,
204 actual: T,
205 ) -> InferResult<'tcx, ()>
206 where
207 T: ToTrace<'tcx>,
208 {
209 self.eq_trace(
210 define_opaque_types,
211 ToTrace::to_trace(self.cause, expected, actual),
212 expected,
213 actual,
214 )
215 }
216
217 pub fn eq_trace<T>(
219 self,
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 if self.infcx.next_trait_solver {
229 NextSolverRelate::relate(
230 self.infcx,
231 self.param_env,
232 expected,
233 ty::Invariant,
234 actual,
235 self.cause.span,
236 )
237 .map(|goals| self.goals_to_obligations(goals))
238 } else {
239 let mut op = TypeRelating::new(
240 self.infcx,
241 trace,
242 self.param_env,
243 define_opaque_types,
244 ty::Invariant,
245 );
246 op.relate(expected, actual)?;
247 Ok(InferOk { value: (), obligations: op.into_obligations() })
248 }
249 }
250
251 pub fn relate<T>(
252 self,
253 define_opaque_types: DefineOpaqueTypes,
254 expected: T,
255 variance: ty::Variance,
256 actual: T,
257 ) -> InferResult<'tcx, ()>
258 where
259 T: ToTrace<'tcx>,
260 {
261 match variance {
262 ty::Covariant => self.sub(define_opaque_types, expected, actual),
263 ty::Invariant => self.eq(define_opaque_types, expected, actual),
264 ty::Contravariant => self.sup(define_opaque_types, expected, actual),
265
266 ty::Bivariant => {
::core::panicking::panic_fmt(format_args!("Bivariant given to `relate()`"));
}panic!("Bivariant given to `relate()`"),
272 }
273 }
274
275 pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
281 where
282 T: ToTrace<'tcx>,
283 {
284 let mut op = LatticeOp::new(
285 self.infcx,
286 ToTrace::to_trace(self.cause, expected, actual),
287 self.param_env,
288 LatticeOpKind::Lub,
289 );
290 let value = op.relate(expected, actual)?;
291 Ok(InferOk { value, obligations: op.into_obligations() })
292 }
293
294 fn goals_to_obligations(
295 &self,
296 goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
297 ) -> InferOk<'tcx, ()> {
298 InferOk {
299 value: (),
300 obligations: goals
301 .into_iter()
302 .map(|goal| {
303 Obligation::new(
304 self.infcx.tcx,
305 self.cause.clone(),
306 goal.param_env,
307 goal.predicate,
308 )
309 })
310 .collect(),
311 }
312 }
313}
314
315impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
316 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
317 TypeTrace {
318 cause: cause.clone(),
319 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
320 }
321 }
322}
323
324impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
325 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
326 TypeTrace { cause: cause.clone(), values: ValuePairs::Regions(ExpectedFound::new(a, b)) }
327 }
328}
329
330impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
331 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
332 TypeTrace {
333 cause: cause.clone(),
334 values: ValuePairs::Terms(ExpectedFound::new(a.into(), b.into())),
335 }
336 }
337}
338
339impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
340 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
341 TypeTrace {
342 cause: cause.clone(),
343 values: match (a.kind(), b.kind()) {
344 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
345 ValuePairs::Regions(ExpectedFound::new(a, b))
346 }
347 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
348 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
349 }
350 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
351 ValuePairs::Terms(ExpectedFound::new(a.into(), b.into()))
352 }
353 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("relating different kinds: {0:?} {1:?}",
a, b))bug!("relating different kinds: {a:?} {b:?}"),
354 },
355 }
356 }
357}
358
359impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
360 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
361 TypeTrace { cause: cause.clone(), values: ValuePairs::Terms(ExpectedFound::new(a, b)) }
362 }
363}
364
365impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
366 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
367 TypeTrace { cause: cause.clone(), values: ValuePairs::TraitRefs(ExpectedFound::new(a, b)) }
368 }
369}
370
371impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
372 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
373 TypeTrace {
374 cause: cause.clone(),
375 values: ValuePairs::Aliases(ExpectedFound::new(a.into(), b.into())),
376 }
377 }
378}
379
380impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
381 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
382 TypeTrace { cause: cause.clone(), values: ValuePairs::Aliases(ExpectedFound::new(a, b)) }
383 }
384}
385
386impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
387 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
388 TypeTrace {
389 cause: cause.clone(),
390 values: ValuePairs::PolySigs(ExpectedFound::new(
391 ty::Binder::dummy(a),
392 ty::Binder::dummy(b),
393 )),
394 }
395 }
396}
397
398impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
399 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
400 TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new(a, b)) }
401 }
402}
403
404impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
405 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
406 TypeTrace {
407 cause: cause.clone(),
408 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a, b)),
409 }
410 }
411}
412
413impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> {
414 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
415 TypeTrace {
416 cause: cause.clone(),
417 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(
418 ty::Binder::dummy(a),
419 ty::Binder::dummy(b),
420 )),
421 }
422 }
423}
424
425impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
426 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
427 TypeTrace {
428 cause: cause.clone(),
429 values: ValuePairs::ExistentialProjection(ExpectedFound::new(a, b)),
430 }
431 }
432}
433
434impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> {
435 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
436 TypeTrace {
437 cause: cause.clone(),
438 values: ValuePairs::ExistentialProjection(ExpectedFound::new(
439 ty::Binder::dummy(a),
440 ty::Binder::dummy(b),
441 )),
442 }
443 }
444}