1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // ______________________________________________________________________
12 // Type combining
13 //
14 // There are three type combiners: sub, lub, and glb. Each implements
15 // the trait `Combine` and contains methods for combining two
16 // instances of various things and yielding a new instance. These
17 // combiner methods always yield a `result<T>`---failure is propagated
18 // upward using `and_then()` methods. There is a lot of common code for
19 // these operations, implemented as default methods on the `Combine`
20 // trait.
21 //
22 // In reality, the sub operation is rather different from lub/glb, but
23 // they are combined into one trait to avoid duplication (they used to
24 // be separate but there were many bugs because there were two copies
25 // of most routines).
26 //
27 // The differences are:
28 //
29 // - when making two things have a sub relationship, the order of the
30 // arguments is significant (a <: b) and the return value of the
31 // combine functions is largely irrelevant. The important thing is
32 // whether the action succeeds or fails. If it succeeds, then side
33 // effects have been committed into the type variables.
34 //
35 // - for GLB/LUB, the order of arguments is not significant (GLB(a,b) ==
36 // GLB(b,a)) and the return value is important (it is the GLB). Of
37 // course GLB/LUB may also have side effects.
38 //
39 // Contravariance
40 //
41 // When you are relating two things which have a contravariant
42 // relationship, you should use `contratys()` or `contraregions()`,
43 // rather than inversing the order of arguments! This is necessary
44 // because the order of arguments is not relevant for LUB and GLB. It
45 // is also useful to track which value is the "expected" value in
46 // terms of error reporting, although we do not do that properly right
47 // now.
48
49
50 use middle::ty::{FloatVar, FnSig, IntVar, TyVar};
51 use middle::ty::{IntType, UintType, substs};
52 use middle::ty::{BuiltinBounds};
53 use middle::ty;
54 use middle::typeck::infer::{then, ToUres};
55 use middle::typeck::infer::glb::Glb;
56 use middle::typeck::infer::lub::Lub;
57 use middle::typeck::infer::sub::Sub;
58 use middle::typeck::infer::to_str::InferStr;
59 use middle::typeck::infer::unify::InferCtxtMethods;
60 use middle::typeck::infer::{InferCtxt, cres, ures};
61 use middle::typeck::infer::{TypeTrace};
62 use util::common::indent;
63 use util::ppaux::Repr;
64
65 use std::result;
66
67 use syntax::ast::{Onceness, FnStyle};
68 use syntax::ast;
69 use syntax::owned_slice::OwnedSlice;
70 use syntax::abi;
71
72 pub trait Combine {
73 fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>;
74 fn tag(&self) -> ~str;
75 fn a_is_expected(&self) -> bool;
76 fn trace(&self) -> TypeTrace;
77
78 fn sub<'a>(&'a self) -> Sub<'a>;
79 fn lub<'a>(&'a self) -> Lub<'a>;
80 fn glb<'a>(&'a self) -> Glb<'a>;
81
82 fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt>;
83 fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t>;
84 fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t>;
85
86 fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<Vec<ty::t> > {
87
88 // Note: type parameters are always treated as *invariant*
89 // (otherwise the type system would be unsound). In the
90 // future we could allow type parameters to declare a
91 // variance.
92
93 if as_.len() == bs.len() {
94 result::fold_(as_.iter().zip(bs.iter())
95 .map(|(a, b)| eq_tys(self, *a, *b)))
96 .then(|| Ok(Vec::from_slice(as_)))
97 } else {
98 Err(ty::terr_ty_param_size(expected_found(self,
99 as_.len(),
100 bs.len())))
101 }
102 }
103
104 fn self_tys(&self, a: Option<ty::t>, b: Option<ty::t>)
105 -> cres<Option<ty::t>> {
106
107 match (a, b) {
108 (None, None) => {
109 Ok(None)
110 }
111 (Some(a), Some(b)) => {
112 // FIXME(#5781) this should be eq_tys
113 // eq_tys(self, a, b).then(|| Ok(Some(a)) )
114 self.contratys(a, b).and_then(|t| Ok(Some(t)))
115 }
116 (None, Some(_)) |
117 (Some(_), None) => {
118 // I think it should never happen that we unify two
119 // substs and one of them has a self_ty and one
120 // doesn't...? I could be wrong about this.
121 self.infcx().tcx.sess.bug(
122 format!("substitution a had a self_ty \
123 and substitution b didn't, \
124 or vice versa"));
125 }
126 }
127 }
128
129 fn substs(&self,
130 item_def_id: ast::DefId,
131 as_: &ty::substs,
132 bs: &ty::substs) -> cres<ty::substs> {
133
134 fn relate_region_params<C:Combine>(this: &C,
135 item_def_id: ast::DefId,
136 a: &ty::RegionSubsts,
137 b: &ty::RegionSubsts)
138 -> cres<ty::RegionSubsts> {
139 let tcx = this.infcx().tcx;
140 match (a, b) {
141 (&ty::ErasedRegions, _) | (_, &ty::ErasedRegions) => {
142 Ok(ty::ErasedRegions)
143 }
144
145 (&ty::NonerasedRegions(ref a_rs),
146 &ty::NonerasedRegions(ref b_rs)) => {
147 let variances = ty::item_variances(tcx, item_def_id);
148 let region_params = &variances.region_params;
149 let num_region_params = region_params.len();
150
151 debug!("relate_region_params(\
152 item_def_id={}, \
153 a_rs={}, \
154 b_rs={},
155 region_params={})",
156 item_def_id.repr(tcx),
157 a_rs.repr(tcx),
158 b_rs.repr(tcx),
159 region_params.repr(tcx));
160
161 assert_eq!(num_region_params, a_rs.len());
162 assert_eq!(num_region_params, b_rs.len());
163 let mut rs = vec!();
164 for i in range(0, num_region_params) {
165 let a_r = *a_rs.get(i);
166 let b_r = *b_rs.get(i);
167 let variance = *region_params.get(i);
168 let r = match variance {
169 ty::Invariant => {
170 eq_regions(this, a_r, b_r)
171 .and_then(|()| Ok(a_r))
172 }
173 ty::Covariant => this.regions(a_r, b_r),
174 ty::Contravariant => this.contraregions(a_r, b_r),
175 ty::Bivariant => Ok(a_r),
176 };
177 rs.push(if_ok!(r));
178 }
179 Ok(ty::NonerasedRegions(OwnedSlice::from_vec(rs)))
180 }
181 }
182 }
183
184 let tps = if_ok!(self.tps(as_.tps.as_slice(), bs.tps.as_slice()));
185 let self_ty = if_ok!(self.self_tys(as_.self_ty, bs.self_ty));
186 let regions = if_ok!(relate_region_params(self,
187 item_def_id,
188 &as_.regions,
189 &bs.regions));
190 Ok(substs { regions: regions,
191 self_ty: self_ty,
192 tps: tps.clone() })
193 }
194
195 fn bare_fn_tys(&self, a: &ty::BareFnTy,
196 b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
197 let fn_style = if_ok!(self.fn_styles(a.fn_style, b.fn_style));
198 let abi = if_ok!(self.abi(a.abi, b.abi));
199 let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
200 Ok(ty::BareFnTy {fn_style: fn_style,
201 abi: abi,
202 sig: sig})
203 }
204
205 fn closure_tys(&self, a: &ty::ClosureTy,
206 b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
207
208 let store = match (a.store, b.store) {
209 (ty::RegionTraitStore(a_r, a_m),
210 ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => {
211 let r = if_ok!(self.contraregions(a_r, b_r));
212 ty::RegionTraitStore(r, a_m)
213 }
214
215 _ if a.store == b.store => {
216 a.store
217 }
218
219 _ => {
220 return Err(ty::terr_sigil_mismatch(expected_found(self, a.store, b.store)))
221 }
222 };
223 let fn_style = if_ok!(self.fn_styles(a.fn_style, b.fn_style));
224 let onceness = if_ok!(self.oncenesses(a.onceness, b.onceness));
225 let bounds = if_ok!(self.bounds(a.bounds, b.bounds));
226 let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
227 Ok(ty::ClosureTy {
228 fn_style: fn_style,
229 onceness: onceness,
230 store: store,
231 bounds: bounds,
232 sig: sig
233 })
234 }
235
236 fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
237
238 fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
239 self.contratys(a, b).and_then(|t| Ok(t))
240 }
241
242 fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle>;
243
244 fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<abi::Abi> {
245 if a == b {
246 Ok(a)
247 } else {
248 Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
249 }
250 }
251
252 fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<Onceness>;
253 fn bounds(&self, a: BuiltinBounds, b: BuiltinBounds) -> cres<BuiltinBounds>;
254 fn contraregions(&self, a: ty::Region, b: ty::Region)
255 -> cres<ty::Region>;
256 fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
257
258 fn trait_stores(&self,
259 vk: ty::terr_vstore_kind,
260 a: ty::TraitStore,
261 b: ty::TraitStore)
262 -> cres<ty::TraitStore> {
263 debug!("{}.trait_stores(a={:?}, b={:?})", self.tag(), a, b);
264
265 match (a, b) {
266 (ty::RegionTraitStore(a_r, a_m),
267 ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => {
268 self.contraregions(a_r, b_r).and_then(|r| {
269 Ok(ty::RegionTraitStore(r, a_m))
270 })
271 }
272
273 _ if a == b => {
274 Ok(a)
275 }
276
277 _ => {
278 Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
279 }
280 }
281
282 }
283
284 fn trait_refs(&self,
285 a: &ty::TraitRef,
286 b: &ty::TraitRef)
287 -> cres<ty::TraitRef> {
288 // Different traits cannot be related
289
290 // - NOTE in the future, expand out subtraits!
291
292 if a.def_id != b.def_id {
293 Err(ty::terr_traits(
294 expected_found(self, a.def_id, b.def_id)))
295 } else {
296 let substs = if_ok!(self.substs(a.def_id, &a.substs, &b.substs));
297 Ok(ty::TraitRef { def_id: a.def_id,
298 substs: substs })
299 }
300 }
301 }
302
303 #[deriving(Clone)]
304 pub struct CombineFields<'a> {
305 pub infcx: &'a InferCtxt<'a>,
306 pub a_is_expected: bool,
307 pub trace: TypeTrace,
308 }
309
310 pub fn expected_found<C:Combine,T>(
311 this: &C, a: T, b: T) -> ty::expected_found<T> {
312 if this.a_is_expected() {
313 ty::expected_found {expected: a, found: b}
314 } else {
315 ty::expected_found {expected: b, found: a}
316 }
317 }
318
319 pub fn eq_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> ures {
320 let suber = this.sub();
321 this.infcx().try(|| {
322 suber.tys(a, b).and_then(|_ok| suber.contratys(a, b)).to_ures()
323 })
324 }
325
326 pub fn eq_regions<C:Combine>(this: &C, a: ty::Region, b: ty::Region)
327 -> ures {
328 debug!("eq_regions({}, {})",
329 a.repr(this.infcx().tcx),
330 b.repr(this.infcx().tcx));
331 let sub = this.sub();
332 indent(|| {
333 this.infcx().try(|| {
334 sub.regions(a, b).and_then(|_r| sub.contraregions(a, b))
335 }).or_else(|e| {
336 // substitute a better error, but use the regions
337 // found in the original error
338 match e {
339 ty::terr_regions_does_not_outlive(a1, b1) =>
340 Err(ty::terr_regions_not_same(a1, b1)),
341 _ => Err(e)
342 }
343 }).to_ures()
344 })
345 }
346
347 pub fn super_fn_sigs<C:Combine>(this: &C, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
348
349 fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<Vec<ty::t> > {
350 if a_args.len() == b_args.len() {
351 result::collect(a_args.iter().zip(b_args.iter())
352 .map(|(a, b)| this.args(*a, *b)))
353 } else {
354 Err(ty::terr_arg_count)
355 }
356 }
357
358 if a.variadic != b.variadic {
359 return Err(ty::terr_variadic_mismatch(expected_found(this, a.variadic, b.variadic)));
360 }
361
362 let inputs = if_ok!(argvecs(this,
363 a.inputs.as_slice(),
364 b.inputs.as_slice()));
365 let output = if_ok!(this.tys(a.output, b.output));
366 Ok(FnSig {binder_id: a.binder_id,
367 inputs: inputs,
368 output: output,
369 variadic: a.variadic})
370 }
371
372 pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
373
374 // This is a horible hack - historically, [T] was not treated as a type,
375 // so, for example, &T and &[U] should not unify. In fact the only thing
376 // &[U] should unify with is &[T]. We preserve that behaviour with this
377 // check.
378 fn check_ptr_to_vec<C:Combine>(this: &C,
379 a: ty::t,
380 b: ty::t,
381 a_inner: ty::t,
382 b_inner: ty::t,
383 result: ty::t) -> cres<ty::t> {
384 match (&ty::get(a_inner).sty, &ty::get(b_inner).sty) {
385 (&ty::ty_vec(_, None), &ty::ty_vec(_, None)) |
386 (&ty::ty_str, &ty::ty_str) => Ok(result),
387 (&ty::ty_vec(_, None), _) | (_, &ty::ty_vec(_, None)) |
388 (&ty::ty_str, _) | (_, &ty::ty_str)
389 => Err(ty::terr_sorts(expected_found(this, a, b))),
390 _ => Ok(result),
391 }
392 }
393
394 let tcx = this.infcx().tcx;
395 let a_sty = &ty::get(a).sty;
396 let b_sty = &ty::get(b).sty;
397 debug!("super_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty);
398 return match (a_sty, b_sty) {
399 // The "subtype" ought to be handling cases involving bot or var:
400 (&ty::ty_bot, _) |
401 (_, &ty::ty_bot) |
402 (&ty::ty_infer(TyVar(_)), _) |
403 (_, &ty::ty_infer(TyVar(_))) => {
404 tcx.sess.bug(
405 format!("{}: bot and var types should have been handled ({},{})",
406 this.tag(),
407 a.inf_str(this.infcx()),
408 b.inf_str(this.infcx())));
409 }
410
411 // Relate integral variables to other types
412 (&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => {
413 if_ok!(this.infcx().simple_vars(this.a_is_expected(),
414 a_id, b_id));
415 Ok(a)
416 }
417 (&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => {
418 unify_integral_variable(this, this.a_is_expected(),
419 v_id, IntType(v))
420 }
421 (&ty::ty_int(v), &ty::ty_infer(IntVar(v_id))) => {
422 unify_integral_variable(this, !this.a_is_expected(),
423 v_id, IntType(v))
424 }
425 (&ty::ty_infer(IntVar(v_id)), &ty::ty_uint(v)) => {
426 unify_integral_variable(this, this.a_is_expected(),
427 v_id, UintType(v))
428 }
429 (&ty::ty_uint(v), &ty::ty_infer(IntVar(v_id))) => {
430 unify_integral_variable(this, !this.a_is_expected(),
431 v_id, UintType(v))
432 }
433
434 // Relate floating-point variables to other types
435 (&ty::ty_infer(FloatVar(a_id)), &ty::ty_infer(FloatVar(b_id))) => {
436 if_ok!(this.infcx().simple_vars(this.a_is_expected(),
437 a_id, b_id));
438 Ok(a)
439 }
440 (&ty::ty_infer(FloatVar(v_id)), &ty::ty_float(v)) => {
441 unify_float_variable(this, this.a_is_expected(), v_id, v)
442 }
443 (&ty::ty_float(v), &ty::ty_infer(FloatVar(v_id))) => {
444 unify_float_variable(this, !this.a_is_expected(), v_id, v)
445 }
446
447 (&ty::ty_char, _) |
448 (&ty::ty_nil, _) |
449 (&ty::ty_bool, _) |
450 (&ty::ty_int(_), _) |
451 (&ty::ty_uint(_), _) |
452 (&ty::ty_float(_), _) => {
453 if ty::get(a).sty == ty::get(b).sty {
454 Ok(a)
455 } else {
456 Err(ty::terr_sorts(expected_found(this, a, b)))
457 }
458 }
459
460 (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if a_p.idx == b_p.idx => {
461 Ok(a)
462 }
463
464 (&ty::ty_enum(a_id, ref a_substs),
465 &ty::ty_enum(b_id, ref b_substs))
466 if a_id == b_id => {
467 let substs = if_ok!(this.substs(a_id,
468 a_substs,
469 b_substs));
470 Ok(ty::mk_enum(tcx, a_id, substs))
471 }
472
473 (&ty::ty_trait(ref a_),
474 &ty::ty_trait(ref b_))
475 if a_.def_id == b_.def_id => {
476 debug!("Trying to match traits {:?} and {:?}", a, b);
477 let substs = if_ok!(this.substs(a_.def_id, &a_.substs, &b_.substs));
478 let s = if_ok!(this.trait_stores(ty::terr_trait, a_.store, b_.store));
479 let bounds = if_ok!(this.bounds(a_.bounds, b_.bounds));
480 Ok(ty::mk_trait(tcx,
481 a_.def_id,
482 substs.clone(),
483 s,
484 bounds))
485 }
486
487 (&ty::ty_struct(a_id, ref a_substs), &ty::ty_struct(b_id, ref b_substs))
488 if a_id == b_id => {
489 let substs = if_ok!(this.substs(a_id, a_substs, b_substs));
490 Ok(ty::mk_struct(tcx, a_id, substs))
491 }
492
493 (&ty::ty_box(a_inner), &ty::ty_box(b_inner)) => {
494 this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_box(tcx, typ)))
495 }
496
497 (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
498 let typ = if_ok!(this.tys(a_inner, b_inner));
499 check_ptr_to_vec(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
500 }
501
502 (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {
503 let mt = if_ok!(this.mts(a_mt, b_mt));
504 check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
505 }
506
507 (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
508 let r = if_ok!(this.contraregions(a_r, b_r));
509 let mt = if_ok!(this.mts(a_mt, b_mt));
510 check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
511 }
512
513 (&ty::ty_vec(ref a_mt, sz_a), &ty::ty_vec(ref b_mt, sz_b)) => {
514 this.mts(a_mt, b_mt).and_then(|mt| {
515 if sz_a == sz_b {
516 Ok(ty::mk_vec(tcx, mt, sz_a))
517 } else {
518 Err(ty::terr_sorts(expected_found(this, a, b)))
519 }
520 })
521 }
522
523 (&ty::ty_str, &ty::ty_str) => {
524 Ok(ty::mk_str(tcx))
525 }
526
527 (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => {
528 if as_.len() == bs.len() {
529 result::collect(as_.iter().zip(bs.iter())
530 .map(|(a, b)| this.tys(*a, *b)))
531 .and_then(|ts| Ok(ty::mk_tup(tcx, ts)) )
532 } else {
533 Err(ty::terr_tuple_size(
534 expected_found(this, as_.len(), bs.len())))
535 }
536 }
537
538 (&ty::ty_bare_fn(ref a_fty), &ty::ty_bare_fn(ref b_fty)) => {
539 this.bare_fn_tys(a_fty, b_fty).and_then(|fty| {
540 Ok(ty::mk_bare_fn(tcx, fty))
541 })
542 }
543
544 (&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
545 this.closure_tys(*a_fty, *b_fty).and_then(|fty| {
546 Ok(ty::mk_closure(tcx, fty))
547 })
548 }
549
550 _ => Err(ty::terr_sorts(expected_found(this, a, b)))
551 };
552
553 fn unify_integral_variable<C:Combine>(
554 this: &C,
555 vid_is_expected: bool,
556 vid: ty::IntVid,
557 val: ty::IntVarValue) -> cres<ty::t>
558 {
559 if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
560 match val {
561 IntType(v) => Ok(ty::mk_mach_int(v)),
562 UintType(v) => Ok(ty::mk_mach_uint(v))
563 }
564 }
565
566 fn unify_float_variable<C:Combine>(
567 this: &C,
568 vid_is_expected: bool,
569 vid: ty::FloatVid,
570 val: ast::FloatTy) -> cres<ty::t>
571 {
572 if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
573 Ok(ty::mk_mach_float(val))
574 }
575 }
librustc/middle/typeck/infer/combine.rs:378:4-378:4 -fn- definition:
fn check_ptr_to_vec<C:Combine>(this: &C,
a: ty::t,
b: ty::t,
references:- 3498: let typ = if_ok!(this.tys(a_inner, b_inner));
499: check_ptr_to_vec(this, a, b, a_inner, b_inner, ty::mk_uniq(tcx, typ))
500: }
--
503: let mt = if_ok!(this.mts(a_mt, b_mt));
504: check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_ptr(tcx, mt))
505: }
--
509: let mt = if_ok!(this.mts(a_mt, b_mt));
510: check_ptr_to_vec(this, a, b, a_mt.ty, b_mt.ty, ty::mk_rptr(tcx, r, mt))
511: }
librustc/middle/typeck/infer/combine.rs:371:1-371:1 -fn- definition:
pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
// This is a horible hack - historically, [T] was not treated as a type,
// so, for example, &T and &[U] should not unify. In fact the only thing
references:- 2librustc/middle/typeck/infer/sub.rs:
144: _ => {
145: super_tys(self, a, b)
146: }
librustc/middle/typeck/infer/lattice.rs:
404: _ => {
405: return super_tys(this, a, b);
406: }
librustc/middle/typeck/infer/combine.rs:71:1-71:1 -trait- definition:
pub trait Combine {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>;
fn tag(&self) -> ~str;
references:- 17553: fn unify_integral_variable<C:Combine>(
554: this: &C,
--
566: fn unify_float_variable<C:Combine>(
567: this: &C,
librustc/middle/typeck/infer/glb.rs:
37: impl<'f> Combine for Glb<'f> {
38: fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
librustc/middle/typeck/infer/lattice.rs:
432: * return. */
433: pub fn lattice_vars<L:LatticeDir + Combine,
434: T:Clone + InferStr + LatticeValue,
--
479: pub fn lattice_var_and_t<L:LatticeDir + Combine,
480: T:Clone + InferStr + LatticeValue,
--
524: pub fn var_ids<T:Combine>(this: &T,
525: map: &HashMap<ty::BoundRegion, ty::Region>)
librustc/middle/typeck/infer/lub.rs:
36: impl<'f> Combine for Lub<'f> {
37: fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
librustc/middle/typeck/infer/sub.rs:
36: impl<'f> Combine for Sub<'f> {
37: fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
librustc/middle/typeck/infer/combine.rs:
377: // check.
378: fn check_ptr_to_vec<C:Combine>(this: &C,
379: a: ty::t,
librustc/middle/typeck/infer/combine.rs:566:4-566:4 -fn- definition:
fn unify_float_variable<C:Combine>(
this: &C,
vid_is_expected: bool,
references:- 2443: (&ty::ty_float(v), &ty::ty_infer(FloatVar(v_id))) => {
444: unify_float_variable(this, !this.a_is_expected(), v_id, v)
445: }
librustc/middle/typeck/infer/combine.rs:553:4-553:4 -fn- definition:
fn unify_integral_variable<C:Combine>(
this: &C,
vid_is_expected: bool,
references:- 4417: (&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => {
418: unify_integral_variable(this, this.a_is_expected(),
419: v_id, IntType(v))
--
429: (&ty::ty_uint(v), &ty::ty_infer(IntVar(v_id))) => {
430: unify_integral_variable(this, !this.a_is_expected(),
431: v_id, UintType(v))
librustc/middle/typeck/infer/combine.rs:303:19-303:19 -struct- definition:
pub struct CombineFields<'a> {
pub infcx: &'a InferCtxt<'a>,
pub a_is_expected: bool,
references:- 27304: pub struct CombineFields<'a> {
librustc/middle/typeck/infer/sub.rs:
55: -> cres<ty::Region> {
56: let opp = CombineFields {
57: a_is_expected: !self.get_ref().a_is_expected,
librustc/middle/typeck/infer/combine.rs:
304: pub struct CombineFields<'a> {
librustc/middle/typeck/infer/mod.rs:
501: -> CombineFields<'a> {
502: CombineFields {infcx: self,
503: a_is_expected: a_is_expected,
librustc/middle/typeck/infer/combine.rs:
304: pub struct CombineFields<'a> {
librustc/middle/typeck/infer/glb.rs:
31: pub struct Glb<'f>(pub CombineFields<'f>); // "greatest lower bound" (common subtype)
--
33: impl<'f> Glb<'f> {
34: pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Glb(ref v) = *self; v }
35: }
librustc/middle/typeck/infer/lattice.rs:
50: trait LatticeValue {
51: fn sub(cf: CombineFields, a: &Self, b: &Self) -> ures;
52: fn lub(cf: CombineFields, a: &Self, b: &Self) -> cres<Self>;
--
56: pub type LatticeOp<'a, T> =
57: |cf: CombineFields, a: &T, b: &T|: 'a -> cres<T>;
--
113: impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> {
114: fn var_sub_var<T:Clone + InferStr + LatticeValue,
--
339: impl<'f> LatticeDir for Lub<'f> {
340: fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() }
341: fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.ub.clone() }
--
353: impl<'f> LatticeDir for Glb<'f> {
354: fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() }
355: fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.lb.clone() }
librustc/middle/typeck/infer/lub.rs:
32: impl<'f> Lub<'f> {
33: pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Lub(ref v) = *self; v }
34: }
librustc/middle/typeck/infer/sub.rs:
30: pub struct Sub<'f>(pub CombineFields<'f>); // "subtype", "subregion" etc
--
32: impl<'f> Sub<'f> {
33: pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Sub(ref v) = *self; v }
34: }
librustc/middle/typeck/infer/coercion.rs:
87: impl<'f> Coerce<'f> {
88: pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> {
89: let Coerce(ref v) = *self; v
librustc/middle/typeck/infer/mod.rs:
500: pub fn combine_fields<'a>(&'a self, a_is_expected: bool, trace: TypeTrace)
501: -> CombineFields<'a> {
502: CombineFields {infcx: self,
librustc/middle/typeck/infer/lattice.rs:
329: pub trait LatticeDir {
330: fn combine_fields<'a>(&'a self) -> CombineFields<'a>;
331: fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T>;
librustc/middle/typeck/infer/combine.rs:309:1-309:1 -fn- definition:
pub fn expected_found<C:Combine,T>(
this: &C, a: T, b: T) -> ty::expected_found<T> {
if this.a_is_expected() {
references:- 1597: } else {
98: Err(ty::terr_ty_param_size(expected_found(self,
99: as_.len(),
--
533: Err(ty::terr_tuple_size(
534: expected_found(this, as_.len(), bs.len())))
535: }
--
550: _ => Err(ty::terr_sorts(expected_found(this, a, b)))
551: };
librustc/middle/typeck/infer/sub.rs:
99: self.lub().oncenesses(a, b).compare(b, || {
100: ty::terr_onceness_mismatch(expected_found(self, a, b))
101: })
--
112: } else {
113: Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
114: }
--
140: (_, &ty::ty_bot) => {
141: Err(ty::terr_sorts(expected_found(self, a, b)))
142: }
librustc/middle/typeck/infer/combine.rs:
247: } else {
248: Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
249: }
librustc/middle/typeck/infer/combine.rs:346:1-346:1 -fn- definition:
pub fn super_fn_sigs<C:Combine>(this: &C, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<Vec<ty::t> > {
if a_args.len() == b_args.len() {
references:- 3librustc/middle/typeck/infer/glb.rs:
146: // Collect constraints.
147: let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh));
148: debug!("sig0 = {}", sig0.inf_str(self.get_ref().infcx));
librustc/middle/typeck/infer/sub.rs:
189: // Compare types now that bound regions have been replaced.
190: let sig = if_ok!(super_fn_sigs(self, &a_sig, &b_sig));
librustc/middle/typeck/infer/lub.rs:
130: // Collect constraints.
131: let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh));
132: debug!("sig0 = {}", sig0.inf_str(self.get_ref().infcx));
librustc/middle/typeck/infer/combine.rs:318:1-318:1 -fn- definition:
pub fn eq_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> ures {
let suber = this.sub();
this.infcx().try(|| {
references:- 594: result::fold_(as_.iter().zip(bs.iter())
95: .map(|(a, b)| eq_tys(self, *a, *b)))
96: .then(|| Ok(Vec::from_slice(as_)))
librustc/middle/typeck/infer/glb.rs:
58: (MutMutable, MutMutable) => {
59: eq_tys(self, a.ty, b.ty).then(|| {
60: Ok(ty::mt {ty: a.ty, mutbl: MutMutable})
librustc/middle/typeck/infer/lub.rs:
65: self.get_ref().infcx.try(|| {
66: eq_tys(self, a.ty, b.ty).then(|| {
67: Ok(ty::mt {ty: a.ty, mutbl: m})
librustc/middle/typeck/infer/mod.rs:
369: let suber = cx.sub(a_is_expected, trace);
370: eq_tys(&suber, a, b)
371: })
librustc/middle/typeck/infer/sub.rs:
82: // (i.e., invariant if mut):
83: eq_tys(self, a.ty, b.ty).then(|| Ok(*a))
84: }