]>
Commit | Line | Data |
---|---|---|
9fa01778 | 1 | //! A nice interface for working with the infcx. The basic idea is to |
7cac9316 | 2 | //! do `infcx.at(cause, param_env)`, which sets the "cause" of the |
9fa01778 | 3 | //! operation as well as the surrounding parameter environment. Then |
7cac9316 XL |
4 | //! you can do something like `.sub(a, b)` or `.eq(a, b)` to create a |
5 | //! subtype or equality relationship respectively. The first argument | |
6 | //! is always the "expected" output from the POV of diagnostics. | |
7 | //! | |
8 | //! Examples: | |
04454e1e | 9 | //! ```ignore (fragment) |
7cac9316 XL |
10 | //! infcx.at(cause, param_env).sub(a, b) |
11 | //! // requires that `a <: b`, with `a` considered the "expected" type | |
12 | //! | |
13 | //! infcx.at(cause, param_env).sup(a, b) | |
14 | //! // requires that `b <: a`, with `a` considered the "expected" type | |
15 | //! | |
16 | //! infcx.at(cause, param_env).eq(a, b) | |
17 | //! // requires that `a == b`, with `a` considered the "expected" type | |
04454e1e | 18 | //! ``` |
7cac9316 | 19 | //! For finer-grained control, you can also do use `trace`: |
04454e1e | 20 | //! ```ignore (fragment) |
7cac9316 | 21 | //! infcx.at(...).trace(a, b).sub(&c, &d) |
04454e1e | 22 | //! ``` |
7cac9316 XL |
23 | //! This will set `a` and `b` as the "root" values for |
24 | //! error-reporting, but actually operate on `c` and `d`. This is | |
25 | //! sometimes useful when the types of `c` and `d` are not traceable | |
26 | //! things. (That system should probably be refactored.) | |
27 | ||
28 | use super::*; | |
29 | ||
ba9703b0 | 30 | use rustc_middle::ty::relate::{Relate, TypeRelation}; |
5e7ed085 | 31 | use rustc_middle::ty::{Const, ImplSubject}; |
7cac9316 | 32 | |
353b0b11 FG |
33 | use std::cell::Cell; |
34 | ||
35 | /// Whether we should define opaque types or just treat them opaquely. | |
36 | /// | |
37 | /// Currently only used to prevent predicate matching from matching anything | |
38 | /// against opaque types. | |
39 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | |
40 | pub enum DefineOpaqueTypes { | |
41 | Yes, | |
42 | No, | |
43 | } | |
44 | ||
dc9dc135 | 45 | pub struct At<'a, 'tcx> { |
2b03887a | 46 | pub infcx: &'a InferCtxt<'tcx>, |
0531ce1d XL |
47 | pub cause: &'a ObligationCause<'tcx>, |
48 | pub param_env: ty::ParamEnv<'tcx>, | |
7cac9316 XL |
49 | } |
50 | ||
dc9dc135 XL |
51 | pub struct Trace<'a, 'tcx> { |
52 | at: At<'a, 'tcx>, | |
7cac9316 XL |
53 | a_is_expected: bool, |
54 | trace: TypeTrace<'tcx>, | |
55 | } | |
56 | ||
2b03887a | 57 | impl<'tcx> InferCtxt<'tcx> { |
a1dfa0c6 | 58 | #[inline] |
2b03887a | 59 | pub fn at<'a>( |
dc9dc135 XL |
60 | &'a self, |
61 | cause: &'a ObligationCause<'tcx>, | |
62 | param_env: ty::ParamEnv<'tcx>, | |
63 | ) -> At<'a, 'tcx> { | |
353b0b11 | 64 | At { infcx: self, cause, param_env } |
7cac9316 | 65 | } |
5099ac24 FG |
66 | |
67 | /// Forks the inference context, creating a new inference context with the same inference | |
68 | /// variables in the same state. This can be used to "branch off" many tests from the same | |
69 | /// common state. Used in coherence. | |
70 | pub fn fork(&self) -> Self { | |
71 | Self { | |
04454e1e FG |
72 | tcx: self.tcx, |
73 | defining_use_anchor: self.defining_use_anchor, | |
064997fb | 74 | considering_regions: self.considering_regions, |
5099ac24 FG |
75 | inner: self.inner.clone(), |
76 | skip_leak_check: self.skip_leak_check.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_closure_mismatch: self.reported_closure_mismatch.clone(), | |
f2b60f7d | 82 | tainted_by_errors: self.tainted_by_errors.clone(), |
5099ac24 FG |
83 | err_count_on_creation: self.err_count_on_creation, |
84 | in_snapshot: self.in_snapshot.clone(), | |
85 | universe: self.universe.clone(), | |
487cf647 | 86 | intercrate: self.intercrate, |
353b0b11 | 87 | inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()), |
5099ac24 FG |
88 | } |
89 | } | |
7cac9316 XL |
90 | } |
91 | ||
92 | pub trait ToTrace<'tcx>: Relate<'tcx> + Copy { | |
dfeec247 XL |
93 | fn to_trace( |
94 | cause: &ObligationCause<'tcx>, | |
95 | a_is_expected: bool, | |
96 | a: Self, | |
97 | b: Self, | |
98 | ) -> TypeTrace<'tcx>; | |
7cac9316 XL |
99 | } |
100 | ||
dc9dc135 | 101 | impl<'a, 'tcx> At<'a, 'tcx> { |
9fa01778 | 102 | /// Makes `a <: b`, where `a` may or may not be expected. |
923072b8 FG |
103 | /// |
104 | /// See [`At::trace_exp`] and [`Trace::sub`] for a version of | |
105 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
106 | pub fn sub_exp<T>( |
107 | self, | |
108 | define_opaque_types: DefineOpaqueTypes, | |
109 | a_is_expected: bool, | |
110 | a: T, | |
111 | b: T, | |
112 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
113 | where |
114 | T: ToTrace<'tcx>, | |
7cac9316 | 115 | { |
353b0b11 | 116 | self.trace_exp(a_is_expected, a, b).sub(define_opaque_types, a, b) |
7cac9316 XL |
117 | } |
118 | ||
9fa01778 | 119 | /// Makes `actual <: expected`. For example, if type-checking a |
7cac9316 XL |
120 | /// call like `foo(x)`, where `foo: fn(i32)`, you might have |
121 | /// `sup(i32, x)`, since the "expected" type is the type that | |
122 | /// appears in the signature. | |
923072b8 FG |
123 | /// |
124 | /// See [`At::trace`] and [`Trace::sub`] for a version of | |
125 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
126 | pub fn sup<T>( |
127 | self, | |
128 | define_opaque_types: DefineOpaqueTypes, | |
129 | expected: T, | |
130 | actual: T, | |
131 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
132 | where |
133 | T: ToTrace<'tcx>, | |
7cac9316 | 134 | { |
353b0b11 | 135 | self.sub_exp(define_opaque_types, false, actual, expected) |
7cac9316 XL |
136 | } |
137 | ||
9fa01778 | 138 | /// Makes `expected <: actual`. |
923072b8 FG |
139 | /// |
140 | /// See [`At::trace`] and [`Trace::sub`] for a version of | |
141 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
142 | pub fn sub<T>( |
143 | self, | |
144 | define_opaque_types: DefineOpaqueTypes, | |
145 | expected: T, | |
146 | actual: T, | |
147 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
148 | where |
149 | T: ToTrace<'tcx>, | |
7cac9316 | 150 | { |
353b0b11 | 151 | self.sub_exp(define_opaque_types, true, expected, actual) |
7cac9316 XL |
152 | } |
153 | ||
9fa01778 | 154 | /// Makes `expected <: actual`. |
923072b8 FG |
155 | /// |
156 | /// See [`At::trace_exp`] and [`Trace::eq`] for a version of | |
157 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
158 | pub fn eq_exp<T>( |
159 | self, | |
160 | define_opaque_types: DefineOpaqueTypes, | |
161 | a_is_expected: bool, | |
162 | a: T, | |
163 | b: T, | |
164 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
165 | where |
166 | T: ToTrace<'tcx>, | |
7cac9316 | 167 | { |
353b0b11 | 168 | self.trace_exp(a_is_expected, a, b).eq(define_opaque_types, a, b) |
7cac9316 XL |
169 | } |
170 | ||
9fa01778 | 171 | /// Makes `expected <: actual`. |
923072b8 FG |
172 | /// |
173 | /// See [`At::trace`] and [`Trace::eq`] for a version of | |
174 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
175 | pub fn eq<T>( |
176 | self, | |
177 | define_opaque_types: DefineOpaqueTypes, | |
178 | expected: T, | |
179 | actual: T, | |
180 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
181 | where |
182 | T: ToTrace<'tcx>, | |
7cac9316 | 183 | { |
353b0b11 | 184 | self.trace(expected, actual).eq(define_opaque_types, expected, actual) |
7cac9316 XL |
185 | } |
186 | ||
353b0b11 FG |
187 | pub fn relate<T>( |
188 | self, | |
189 | define_opaque_types: DefineOpaqueTypes, | |
190 | expected: T, | |
191 | variance: ty::Variance, | |
192 | actual: T, | |
193 | ) -> InferResult<'tcx, ()> | |
dfeec247 XL |
194 | where |
195 | T: ToTrace<'tcx>, | |
0bf4aa26 XL |
196 | { |
197 | match variance { | |
353b0b11 FG |
198 | ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual), |
199 | ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual), | |
200 | ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual), | |
0bf4aa26 XL |
201 | |
202 | // We could make this make sense but it's not readily | |
203 | // exposed and I don't feel like dealing with it. Note | |
204 | // that bivariance in general does a bit more than just | |
205 | // *nothing*, it checks that the types are the same | |
206 | // "modulo variance" basically. | |
207 | ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"), | |
208 | } | |
209 | } | |
210 | ||
9fa01778 | 211 | /// Computes the least-upper-bound, or mutual supertype, of two |
7cac9316 XL |
212 | /// values. The order of the arguments doesn't matter, but since |
213 | /// this can result in an error (e.g., if asked to compute LUB of | |
214 | /// u32 and i32), it is meaningful to call one of them the | |
215 | /// "expected type". | |
923072b8 FG |
216 | /// |
217 | /// See [`At::trace`] and [`Trace::lub`] for a version of | |
218 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
219 | pub fn lub<T>( |
220 | self, | |
221 | define_opaque_types: DefineOpaqueTypes, | |
222 | expected: T, | |
223 | actual: T, | |
224 | ) -> InferResult<'tcx, T> | |
dfeec247 XL |
225 | where |
226 | T: ToTrace<'tcx>, | |
7cac9316 | 227 | { |
353b0b11 | 228 | self.trace(expected, actual).lub(define_opaque_types, expected, actual) |
7cac9316 XL |
229 | } |
230 | ||
9fa01778 | 231 | /// Computes the greatest-lower-bound, or mutual subtype, of two |
7cac9316 XL |
232 | /// values. As with `lub` order doesn't matter, except for error |
233 | /// cases. | |
923072b8 FG |
234 | /// |
235 | /// See [`At::trace`] and [`Trace::glb`] for a version of | |
236 | /// this method that only requires `T: Relate<'tcx>` | |
353b0b11 FG |
237 | pub fn glb<T>( |
238 | self, | |
239 | define_opaque_types: DefineOpaqueTypes, | |
240 | expected: T, | |
241 | actual: T, | |
242 | ) -> InferResult<'tcx, T> | |
dfeec247 XL |
243 | where |
244 | T: ToTrace<'tcx>, | |
7cac9316 | 245 | { |
353b0b11 | 246 | self.trace(expected, actual).glb(define_opaque_types, expected, actual) |
7cac9316 XL |
247 | } |
248 | ||
249 | /// Sets the "trace" values that will be used for | |
3b2f2976 | 250 | /// error-reporting, but doesn't actually perform any operation |
7cac9316 XL |
251 | /// yet (this is useful when you want to set the trace using |
252 | /// distinct values from those you wish to operate upon). | |
dc9dc135 XL |
253 | pub fn trace<T>(self, expected: T, actual: T) -> Trace<'a, 'tcx> |
254 | where | |
255 | T: ToTrace<'tcx>, | |
7cac9316 XL |
256 | { |
257 | self.trace_exp(true, expected, actual) | |
258 | } | |
259 | ||
260 | /// Like `trace`, but the expected value is determined by the | |
261 | /// boolean argument (if true, then the first argument `a` is the | |
262 | /// "expected" value). | |
dc9dc135 XL |
263 | pub fn trace_exp<T>(self, a_is_expected: bool, a: T, b: T) -> Trace<'a, 'tcx> |
264 | where | |
265 | T: ToTrace<'tcx>, | |
7cac9316 | 266 | { |
353b0b11 | 267 | let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b); |
74b04a01 | 268 | Trace { at: self, trace, a_is_expected } |
7cac9316 XL |
269 | } |
270 | } | |
271 | ||
dc9dc135 | 272 | impl<'a, 'tcx> Trace<'a, 'tcx> { |
9fa01778 | 273 | /// Makes `a <: b` where `a` may or may not be expected (if |
7cac9316 | 274 | /// `a_is_expected` is true, then `a` is expected). |
c295e0f8 | 275 | #[instrument(skip(self), level = "debug")] |
353b0b11 | 276 | pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()> |
dfeec247 XL |
277 | where |
278 | T: Relate<'tcx>, | |
7cac9316 | 279 | { |
7cac9316 XL |
280 | let Trace { at, trace, a_is_expected } = self; |
281 | at.infcx.commit_if_ok(|_| { | |
353b0b11 | 282 | let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); |
dfeec247 XL |
283 | fields |
284 | .sub(a_is_expected) | |
285 | .relate(a, b) | |
286 | .map(move |_| InferOk { value: (), obligations: fields.obligations }) | |
7cac9316 XL |
287 | }) |
288 | } | |
289 | ||
9fa01778 | 290 | /// Makes `a == b`; the expectation is set by the call to |
7cac9316 | 291 | /// `trace()`. |
c295e0f8 | 292 | #[instrument(skip(self), level = "debug")] |
353b0b11 | 293 | pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()> |
dfeec247 XL |
294 | where |
295 | T: Relate<'tcx>, | |
7cac9316 | 296 | { |
7cac9316 XL |
297 | let Trace { at, trace, a_is_expected } = self; |
298 | at.infcx.commit_if_ok(|_| { | |
353b0b11 | 299 | let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); |
dfeec247 XL |
300 | fields |
301 | .equate(a_is_expected) | |
302 | .relate(a, b) | |
303 | .map(move |_| InferOk { value: (), obligations: fields.obligations }) | |
7cac9316 XL |
304 | }) |
305 | } | |
306 | ||
c295e0f8 | 307 | #[instrument(skip(self), level = "debug")] |
353b0b11 | 308 | pub fn lub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T> |
dfeec247 XL |
309 | where |
310 | T: Relate<'tcx>, | |
7cac9316 | 311 | { |
7cac9316 XL |
312 | let Trace { at, trace, a_is_expected } = self; |
313 | at.infcx.commit_if_ok(|_| { | |
353b0b11 | 314 | let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); |
dfeec247 XL |
315 | fields |
316 | .lub(a_is_expected) | |
317 | .relate(a, b) | |
318 | .map(move |t| InferOk { value: t, obligations: fields.obligations }) | |
7cac9316 XL |
319 | }) |
320 | } | |
321 | ||
c295e0f8 | 322 | #[instrument(skip(self), level = "debug")] |
353b0b11 | 323 | pub fn glb<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T> |
dfeec247 XL |
324 | where |
325 | T: Relate<'tcx>, | |
7cac9316 | 326 | { |
7cac9316 XL |
327 | let Trace { at, trace, a_is_expected } = self; |
328 | at.infcx.commit_if_ok(|_| { | |
353b0b11 | 329 | let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types); |
dfeec247 XL |
330 | fields |
331 | .glb(a_is_expected) | |
332 | .relate(a, b) | |
333 | .map(move |t| InferOk { value: t, obligations: fields.obligations }) | |
7cac9316 XL |
334 | }) |
335 | } | |
336 | } | |
337 | ||
5e7ed085 FG |
338 | impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { |
339 | fn to_trace( | |
5e7ed085 FG |
340 | cause: &ObligationCause<'tcx>, |
341 | a_is_expected: bool, | |
342 | a: Self, | |
343 | b: Self, | |
344 | ) -> TypeTrace<'tcx> { | |
345 | match (a, b) { | |
346 | (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => { | |
353b0b11 | 347 | ToTrace::to_trace(cause, a_is_expected, trait_ref_a, trait_ref_b) |
5e7ed085 FG |
348 | } |
349 | (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => { | |
353b0b11 | 350 | ToTrace::to_trace(cause, a_is_expected, ty_a, ty_b) |
5e7ed085 FG |
351 | } |
352 | (ImplSubject::Trait(_), ImplSubject::Inherent(_)) | |
353 | | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { | |
354 | bug!("can not trace TraitRef and Ty"); | |
355 | } | |
356 | } | |
357 | } | |
358 | } | |
359 | ||
7cac9316 | 360 | impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { |
dfeec247 XL |
361 | fn to_trace( |
362 | cause: &ObligationCause<'tcx>, | |
363 | a_is_expected: bool, | |
364 | a: Self, | |
365 | b: Self, | |
366 | ) -> TypeTrace<'tcx> { | |
5099ac24 FG |
367 | TypeTrace { |
368 | cause: cause.clone(), | |
369 | values: Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), | |
370 | } | |
7cac9316 XL |
371 | } |
372 | } | |
373 | ||
0531ce1d | 374 | impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { |
dfeec247 XL |
375 | fn to_trace( |
376 | cause: &ObligationCause<'tcx>, | |
377 | a_is_expected: bool, | |
378 | a: Self, | |
379 | b: Self, | |
380 | ) -> TypeTrace<'tcx> { | |
381 | TypeTrace { cause: cause.clone(), values: Regions(ExpectedFound::new(a_is_expected, a, b)) } | |
0531ce1d XL |
382 | } |
383 | } | |
384 | ||
5099ac24 FG |
385 | impl<'tcx> ToTrace<'tcx> for Const<'tcx> { |
386 | fn to_trace( | |
5099ac24 FG |
387 | cause: &ObligationCause<'tcx>, |
388 | a_is_expected: bool, | |
389 | a: Self, | |
390 | b: Self, | |
391 | ) -> TypeTrace<'tcx> { | |
392 | TypeTrace { | |
393 | cause: cause.clone(), | |
394 | values: Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), | |
395 | } | |
396 | } | |
397 | } | |
398 | ||
9ffffee4 FG |
399 | impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { |
400 | fn to_trace( | |
9ffffee4 FG |
401 | cause: &ObligationCause<'tcx>, |
402 | a_is_expected: bool, | |
403 | a: Self, | |
404 | b: Self, | |
405 | ) -> TypeTrace<'tcx> { | |
406 | use GenericArgKind::*; | |
407 | TypeTrace { | |
408 | cause: cause.clone(), | |
409 | values: match (a.unpack(), b.unpack()) { | |
410 | (Lifetime(a), Lifetime(b)) => Regions(ExpectedFound::new(a_is_expected, a, b)), | |
411 | (Type(a), Type(b)) => Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), | |
412 | (Const(a), Const(b)) => { | |
413 | Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())) | |
414 | } | |
415 | ||
416 | (Lifetime(_), Type(_) | Const(_)) | |
417 | | (Type(_), Lifetime(_) | Const(_)) | |
418 | | (Const(_), Lifetime(_) | Type(_)) => { | |
419 | bug!("relating different kinds: {a:?} {b:?}") | |
420 | } | |
421 | }, | |
422 | } | |
423 | } | |
424 | } | |
425 | ||
5099ac24 | 426 | impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> { |
dfeec247 XL |
427 | fn to_trace( |
428 | cause: &ObligationCause<'tcx>, | |
429 | a_is_expected: bool, | |
430 | a: Self, | |
431 | b: Self, | |
432 | ) -> TypeTrace<'tcx> { | |
5099ac24 | 433 | TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) } |
48663c56 XL |
434 | } |
435 | } | |
436 | ||
7cac9316 | 437 | impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { |
dfeec247 XL |
438 | fn to_trace( |
439 | cause: &ObligationCause<'tcx>, | |
440 | a_is_expected: bool, | |
441 | a: Self, | |
442 | b: Self, | |
443 | ) -> TypeTrace<'tcx> { | |
7cac9316 XL |
444 | TypeTrace { |
445 | cause: cause.clone(), | |
dfeec247 | 446 | values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)), |
7cac9316 XL |
447 | } |
448 | } | |
449 | } | |
450 | ||
451 | impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> { | |
dfeec247 XL |
452 | fn to_trace( |
453 | cause: &ObligationCause<'tcx>, | |
454 | a_is_expected: bool, | |
455 | a: Self, | |
456 | b: Self, | |
457 | ) -> TypeTrace<'tcx> { | |
7cac9316 XL |
458 | TypeTrace { |
459 | cause: cause.clone(), | |
dfeec247 | 460 | values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b)), |
7cac9316 XL |
461 | } |
462 | } | |
463 | } | |
6a06907d | 464 | |
9c376795 | 465 | impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { |
6a06907d | 466 | fn to_trace( |
6a06907d XL |
467 | cause: &ObligationCause<'tcx>, |
468 | a_is_expected: bool, | |
469 | a: Self, | |
470 | b: Self, | |
471 | ) -> TypeTrace<'tcx> { | |
353b0b11 | 472 | TypeTrace { cause: cause.clone(), values: Aliases(ExpectedFound::new(a_is_expected, a, b)) } |
6a06907d XL |
473 | } |
474 | } | |
9c376795 FG |
475 | |
476 | impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { | |
477 | fn to_trace( | |
9c376795 FG |
478 | cause: &ObligationCause<'tcx>, |
479 | a_is_expected: bool, | |
480 | a: Self, | |
481 | b: Self, | |
482 | ) -> TypeTrace<'tcx> { | |
483 | TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) } | |
484 | } | |
485 | } |