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