]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/method/confirm.rs
split ty::util and ty::adjustment
[rust.git] / src / librustc_typeck / check / method / confirm.rs
1 // Copyright 2014 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 use super::probe;
12
13 use check::{self, FnCtxt, callee, demand};
14 use check::UnresolvedTypeAction;
15 use middle::def_id::DefId;
16 use middle::subst::{self};
17 use middle::traits;
18 use middle::ty::{self, NoPreference, PreferMutLvalue, Ty};
19 use middle::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
20 use middle::ty::fold::TypeFoldable;
21 use middle::infer;
22 use middle::infer::InferCtxt;
23 use syntax::codemap::Span;
24 use rustc_front::hir;
25
26 struct ConfirmContext<'a, 'tcx:'a> {
27     fcx: &'a FnCtxt<'a, 'tcx>,
28     span: Span,
29     self_expr: &'tcx hir::Expr,
30     call_expr: &'tcx hir::Expr,
31 }
32
33 struct InstantiatedMethodSig<'tcx> {
34     /// Function signature of the method being invoked. The 0th
35     /// argument is the receiver.
36     method_sig: ty::FnSig<'tcx>,
37
38     /// Substitutions for all types/early-bound-regions declared on
39     /// the method.
40     all_substs: subst::Substs<'tcx>,
41
42     /// Generic bounds on the method's parameters which must be added
43     /// as pending obligations.
44     method_predicates: ty::InstantiatedPredicates<'tcx>,
45 }
46
47 pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
48                          span: Span,
49                          self_expr: &'tcx hir::Expr,
50                          call_expr: &'tcx hir::Expr,
51                          unadjusted_self_ty: Ty<'tcx>,
52                          pick: probe::Pick<'tcx>,
53                          supplied_method_types: Vec<Ty<'tcx>>)
54                          -> ty::MethodCallee<'tcx>
55 {
56     debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, supplied_method_types={:?})",
57            unadjusted_self_ty,
58            pick,
59            supplied_method_types);
60
61     let mut confirm_cx = ConfirmContext::new(fcx, span, self_expr, call_expr);
62     confirm_cx.confirm(unadjusted_self_ty, pick, supplied_method_types)
63 }
64
65 impl<'a,'tcx> ConfirmContext<'a,'tcx> {
66     fn new(fcx: &'a FnCtxt<'a, 'tcx>,
67            span: Span,
68            self_expr: &'tcx hir::Expr,
69            call_expr: &'tcx hir::Expr)
70            -> ConfirmContext<'a, 'tcx>
71     {
72         ConfirmContext { fcx: fcx, span: span, self_expr: self_expr, call_expr: call_expr }
73     }
74
75     fn confirm(&mut self,
76                unadjusted_self_ty: Ty<'tcx>,
77                pick: probe::Pick<'tcx>,
78                supplied_method_types: Vec<Ty<'tcx>>)
79                -> ty::MethodCallee<'tcx>
80     {
81         // Adjust the self expression the user provided and obtain the adjusted type.
82         let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick);
83
84         // Make sure nobody calls `drop()` explicitly.
85         self.enforce_illegal_method_limitations(&pick);
86
87         // Create substitutions for the method's type parameters.
88         let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick);
89         let all_substs =
90             self.instantiate_method_substs(
91                 &pick,
92                 supplied_method_types,
93                 rcvr_substs);
94
95         debug!("all_substs={:?}", all_substs);
96
97         // Create the final signature for the method, replacing late-bound regions.
98         let InstantiatedMethodSig {
99             method_sig, all_substs, method_predicates
100         } = self.instantiate_method_sig(&pick, all_substs);
101         let method_self_ty = method_sig.inputs[0];
102
103         // Unify the (adjusted) self type with what the method expects.
104         self.unify_receivers(self_ty, method_self_ty);
105
106         // Add any trait/regions obligations specified on the method's type parameters.
107         self.add_obligations(&pick, &all_substs, &method_predicates);
108
109         // Create the final `MethodCallee`.
110         let method_ty = pick.item.as_opt_method().unwrap();
111         let fty = self.tcx().mk_fn(None, self.tcx().mk_bare_fn(ty::BareFnTy {
112             sig: ty::Binder(method_sig),
113             unsafety: method_ty.fty.unsafety,
114             abi: method_ty.fty.abi.clone(),
115         }));
116         let callee = ty::MethodCallee {
117             def_id: pick.item.def_id(),
118             ty: fty,
119             substs: self.tcx().mk_substs(all_substs)
120         };
121
122         // If this is an `&mut self` method, bias the receiver
123         // expression towards mutability (this will switch
124         // e.g. `Deref` to `DerefMut` in overloaded derefs and so on).
125         self.fixup_derefs_on_method_receiver_if_necessary(&callee);
126
127         callee
128     }
129
130     ///////////////////////////////////////////////////////////////////////////
131     // ADJUSTMENTS
132
133     fn adjust_self_ty(&mut self,
134                       unadjusted_self_ty: Ty<'tcx>,
135                       pick: &probe::Pick<'tcx>)
136                       -> Ty<'tcx>
137     {
138         let (autoref, unsize) = if let Some(mutbl) = pick.autoref {
139             let region = self.infcx().next_region_var(infer::Autoref(self.span));
140             let autoref = AutoPtr(self.tcx().mk_region(region), mutbl);
141             (Some(autoref), pick.unsize.map(|target| {
142                 target.adjust_for_autoref(self.tcx(), Some(autoref))
143             }))
144         } else {
145             // No unsizing should be performed without autoref (at
146             // least during method dispach). This is because we
147             // currently only unsize `[T;N]` to `[T]`, and naturally
148             // that must occur being a reference.
149             assert!(pick.unsize.is_none());
150             (None, None)
151         };
152
153         // Commit the autoderefs by calling `autoderef again, but this
154         // time writing the results into the various tables.
155         let (autoderefd_ty, n, result) = check::autoderef(self.fcx,
156                                                           self.span,
157                                                           unadjusted_self_ty,
158                                                           Some(self.self_expr),
159                                                           UnresolvedTypeAction::Error,
160                                                           NoPreference,
161                                                           |_, n| {
162             if n == pick.autoderefs {
163                 Some(())
164             } else {
165                 None
166             }
167         });
168         assert_eq!(n, pick.autoderefs);
169         assert_eq!(result, Some(()));
170
171         // Write out the final adjustment.
172         self.fcx.write_adjustment(self.self_expr.id,
173                                   AdjustDerefRef(AutoDerefRef {
174             autoderefs: pick.autoderefs,
175             autoref: autoref,
176             unsize: unsize
177         }));
178
179         if let Some(target) = unsize {
180             target
181         } else {
182             autoderefd_ty.adjust_for_autoref(self.tcx(), autoref)
183         }
184     }
185
186     ///////////////////////////////////////////////////////////////////////////
187     //
188
189     /// Returns a set of substitutions for the method *receiver* where all type and region
190     /// parameters are instantiated with fresh variables. This substitution does not include any
191     /// parameters declared on the method itself.
192     ///
193     /// Note that this substitution may include late-bound regions from the impl level. If so,
194     /// these are instantiated later in the `instantiate_method_sig` routine.
195     fn fresh_receiver_substs(&mut self,
196                              self_ty: Ty<'tcx>,
197                              pick: &probe::Pick<'tcx>)
198                              -> subst::Substs<'tcx>
199     {
200         match pick.kind {
201             probe::InherentImplPick => {
202                 let impl_def_id = pick.item.container().id();
203                 assert!(self.tcx().impl_trait_ref(impl_def_id).is_none(),
204                         "impl {:?} is not an inherent impl", impl_def_id);
205                 check::impl_self_ty(self.fcx, self.span, impl_def_id).substs
206             }
207
208             probe::ObjectPick => {
209                 let trait_def_id = pick.item.container().id();
210                 self.extract_trait_ref(self_ty, |this, object_ty, data| {
211                     // The object data has no entry for the Self
212                     // Type. For the purposes of this method call, we
213                     // substitute the object type itself. This
214                     // wouldn't be a sound substitution in all cases,
215                     // since each instance of the object type is a
216                     // different existential and hence could match
217                     // distinct types (e.g., if `Self` appeared as an
218                     // argument type), but those cases have already
219                     // been ruled out when we deemed the trait to be
220                     // "object safe".
221                     let original_poly_trait_ref =
222                         data.principal_trait_ref_with_self_ty(this.tcx(), object_ty);
223                     let upcast_poly_trait_ref =
224                         this.upcast(original_poly_trait_ref.clone(), trait_def_id);
225                     let upcast_trait_ref =
226                         this.replace_late_bound_regions_with_fresh_var(&upcast_poly_trait_ref);
227                     debug!("original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}",
228                            original_poly_trait_ref,
229                            upcast_trait_ref,
230                            trait_def_id);
231                     upcast_trait_ref.substs.clone()
232                 })
233             }
234
235             probe::ExtensionImplPick(impl_def_id) => {
236                 // The method being invoked is the method as defined on the trait,
237                 // so return the substitutions from the trait. Consider:
238                 //
239                 //     impl<A,B,C> Trait<A,B> for Foo<C> { ... }
240                 //
241                 // If we instantiate A, B, and C with $A, $B, and $C
242                 // respectively, then we want to return the type
243                 // parameters from the trait ([$A,$B]), not those from
244                 // the impl ([$A,$B,$C]) not the receiver type ([$C]).
245                 let impl_polytype = check::impl_self_ty(self.fcx, self.span, impl_def_id);
246                 let impl_trait_ref =
247                     self.fcx.instantiate_type_scheme(
248                         self.span,
249                         &impl_polytype.substs,
250                         &self.tcx().impl_trait_ref(impl_def_id).unwrap());
251                 impl_trait_ref.substs.clone()
252             }
253
254             probe::TraitPick => {
255                 let trait_def_id = pick.item.container().id();
256                 let trait_def = self.tcx().lookup_trait_def(trait_def_id);
257
258                 // Make a trait reference `$0 : Trait<$1...$n>`
259                 // consisting entirely of type variables. Later on in
260                 // the process we will unify the transformed-self-type
261                 // of the method with the actual type in order to
262                 // unify some of these variables.
263                 self.infcx().fresh_substs_for_trait(self.span,
264                                                     &trait_def.generics,
265                                                     self.infcx().next_ty_var())
266             }
267
268             probe::WhereClausePick(ref poly_trait_ref) => {
269                 // Where clauses can have bound regions in them. We need to instantiate
270                 // those to convert from a poly-trait-ref to a trait-ref.
271                 self.replace_late_bound_regions_with_fresh_var(&*poly_trait_ref).substs.clone()
272             }
273         }
274     }
275
276     fn extract_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where
277         F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, &ty::TraitTy<'tcx>) -> R,
278     {
279         // If we specified that this is an object method, then the
280         // self-type ought to be something that can be dereferenced to
281         // yield an object-type (e.g., `&Object` or `Box<Object>`
282         // etc).
283
284         let (_, _, result) = check::autoderef(self.fcx,
285                                               self.span,
286                                               self_ty,
287                                               None,
288                                               UnresolvedTypeAction::Error,
289                                               NoPreference,
290                                               |ty, _| {
291             match ty.sty {
292                 ty::TyTrait(ref data) => Some(closure(self, ty, &**data)),
293                 _ => None,
294             }
295         });
296
297         match result {
298             Some(r) => r,
299             None => {
300                 self.tcx().sess.span_bug(
301                     self.span,
302                     &format!("self-type `{}` for ObjectPick never dereferenced to an object",
303                             self_ty))
304             }
305         }
306     }
307
308     fn instantiate_method_substs(&mut self,
309                                  pick: &probe::Pick<'tcx>,
310                                  supplied_method_types: Vec<Ty<'tcx>>,
311                                  substs: subst::Substs<'tcx>)
312                                  -> subst::Substs<'tcx>
313     {
314         // Determine the values for the generic parameters of the method.
315         // If they were not explicitly supplied, just construct fresh
316         // variables.
317         let num_supplied_types = supplied_method_types.len();
318         let method = pick.item.as_opt_method().unwrap();
319         let method_types = method.generics.types.get_slice(subst::FnSpace);
320         let num_method_types = method_types.len();
321
322
323         // Create subst for early-bound lifetime parameters, combining
324         // parameters from the type and those from the method.
325         //
326         // FIXME -- permit users to manually specify lifetimes
327         let method_regions =
328             self.fcx.infcx().region_vars_for_defs(
329                 self.span,
330                 pick.item.as_opt_method().unwrap()
331                     .generics.regions.get_slice(subst::FnSpace));
332
333         let subst::Substs { types, regions } = substs;
334         let regions = regions.map(|r| r.with_vec(subst::FnSpace, method_regions));
335         let mut final_substs = subst::Substs { types: types, regions: regions };
336
337         if num_supplied_types == 0 {
338             self.fcx.infcx().type_vars_for_defs(
339                 self.span,
340                 subst::FnSpace,
341                 &mut final_substs,
342                 method_types);
343         } else if num_method_types == 0 {
344             span_err!(self.tcx().sess, self.span, E0035,
345                 "does not take type parameters");
346             self.fcx.infcx().type_vars_for_defs(
347                 self.span,
348                 subst::FnSpace,
349                 &mut final_substs,
350                 method_types);
351         } else if num_supplied_types != num_method_types {
352             span_err!(self.tcx().sess, self.span, E0036,
353                 "incorrect number of type parameters given for this method");
354             final_substs.types.replace(
355                 subst::FnSpace,
356                 vec![self.tcx().types.err; num_method_types]);
357         } else {
358             final_substs.types.replace(subst::FnSpace, supplied_method_types);
359         }
360
361         return final_substs;
362     }
363
364     fn unify_receivers(&mut self,
365                        self_ty: Ty<'tcx>,
366                        method_self_ty: Ty<'tcx>)
367     {
368         match self.fcx.mk_subty(false, infer::Misc(self.span), self_ty, method_self_ty) {
369             Ok(_) => {}
370             Err(_) => {
371                 self.tcx().sess.span_bug(
372                     self.span,
373                     &format!("{} was a subtype of {} but now is not?",
374                              self_ty, method_self_ty));
375             }
376         }
377     }
378
379     ///////////////////////////////////////////////////////////////////////////
380     //
381
382     fn instantiate_method_sig(&mut self,
383                               pick: &probe::Pick<'tcx>,
384                               all_substs: subst::Substs<'tcx>)
385                               -> InstantiatedMethodSig<'tcx>
386     {
387         debug!("instantiate_method_sig(pick={:?}, all_substs={:?})",
388                pick,
389                all_substs);
390
391         // Instantiate the bounds on the method with the
392         // type/early-bound-regions substitutions performed. There can
393         // be no late-bound regions appearing here.
394         let method_predicates = pick.item.as_opt_method().unwrap()
395                                     .predicates.instantiate(self.tcx(), &all_substs);
396         let method_predicates = self.fcx.normalize_associated_types_in(self.span,
397                                                                        &method_predicates);
398
399         debug!("method_predicates after subst = {:?}",
400                method_predicates);
401
402         // Instantiate late-bound regions and substitute the trait
403         // parameters into the method type to get the actual method type.
404         //
405         // NB: Instantiate late-bound regions first so that
406         // `instantiate_type_scheme` can normalize associated types that
407         // may reference those regions.
408         let method_sig = self.replace_late_bound_regions_with_fresh_var(
409             &pick.item.as_opt_method().unwrap().fty.sig);
410         debug!("late-bound lifetimes from method instantiated, method_sig={:?}",
411                method_sig);
412
413         let method_sig = self.fcx.instantiate_type_scheme(self.span, &all_substs, &method_sig);
414         debug!("type scheme substituted, method_sig={:?}",
415                method_sig);
416
417         InstantiatedMethodSig {
418             method_sig: method_sig,
419             all_substs: all_substs,
420             method_predicates: method_predicates,
421         }
422     }
423
424     fn add_obligations(&mut self,
425                        pick: &probe::Pick<'tcx>,
426                        all_substs: &subst::Substs<'tcx>,
427                        method_predicates: &ty::InstantiatedPredicates<'tcx>) {
428         debug!("add_obligations: pick={:?} all_substs={:?} method_predicates={:?}",
429                pick,
430                all_substs,
431                method_predicates);
432
433         self.fcx.add_obligations_for_parameters(
434             traits::ObligationCause::misc(self.span, self.fcx.body_id),
435             method_predicates);
436
437         // this is a projection from a trait reference, so we have to
438         // make sure that the trait reference inputs are well-formed.
439         self.fcx.add_wf_bounds(
440             all_substs,
441             self.call_expr);
442     }
443
444     ///////////////////////////////////////////////////////////////////////////
445     // RECONCILIATION
446
447     /// When we select a method with an `&mut self` receiver, we have to go convert any
448     /// auto-derefs, indices, etc from `Deref` and `Index` into `DerefMut` and `IndexMut`
449     /// respectively.
450     fn fixup_derefs_on_method_receiver_if_necessary(&self,
451                                                     method_callee: &ty::MethodCallee) {
452         let sig = match method_callee.ty.sty {
453             ty::TyBareFn(_, ref f) => f.sig.clone(),
454             _ => return,
455         };
456
457         match sig.0.inputs[0].sty {
458             ty::TyRef(_, ty::TypeAndMut {
459                 ty: _,
460                 mutbl: hir::MutMutable,
461             }) => {}
462             _ => return,
463         }
464
465         // Gather up expressions we want to munge.
466         let mut exprs = Vec::new();
467         exprs.push(self.self_expr);
468         loop {
469             let last = exprs[exprs.len() - 1];
470             match last.node {
471                 hir::ExprParen(ref expr) |
472                 hir::ExprField(ref expr, _) |
473                 hir::ExprTupField(ref expr, _) |
474                 hir::ExprIndex(ref expr, _) |
475                 hir::ExprUnary(hir::UnDeref, ref expr) => exprs.push(&**expr),
476                 _ => break,
477             }
478         }
479
480         debug!("fixup_derefs_on_method_receiver_if_necessary: exprs={:?}",
481                exprs);
482
483         // Fix up autoderefs and derefs.
484         for (i, &expr) in exprs.iter().rev().enumerate() {
485             // Count autoderefs.
486             let autoderef_count = match self.fcx
487                                             .inh
488                                             .tables
489                                             .borrow()
490                                             .adjustments
491                                             .get(&expr.id) {
492                 Some(&AdjustDerefRef(ref adj)) => adj.autoderefs,
493                 Some(_) | None => 0,
494             };
495
496             debug!("fixup_derefs_on_method_receiver_if_necessary: i={} expr={:?} \
497                                                                   autoderef_count={}",
498                    i, expr, autoderef_count);
499
500             if autoderef_count > 0 {
501                 check::autoderef(self.fcx,
502                                  expr.span,
503                                  self.fcx.expr_ty(expr),
504                                  Some(expr),
505                                  UnresolvedTypeAction::Error,
506                                  PreferMutLvalue,
507                                  |_, autoderefs| {
508                                      if autoderefs == autoderef_count + 1 {
509                                          Some(())
510                                      } else {
511                                          None
512                                      }
513                                  });
514             }
515
516             // Don't retry the first one or we might infinite loop!
517             if i != 0 {
518                 match expr.node {
519                     hir::ExprIndex(ref base_expr, ref index_expr) => {
520                         // If this is an overloaded index, the
521                         // adjustment will include an extra layer of
522                         // autoref because the method is an &self/&mut
523                         // self method. We have to peel it off to get
524                         // the raw adjustment that `try_index_step`
525                         // expects. This is annoying and horrible. We
526                         // ought to recode this routine so it doesn't
527                         // (ab)use the normal type checking paths.
528                         let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id)
529                                                                           .cloned();
530                         let (autoderefs, unsize) = match adj {
531                             Some(AdjustDerefRef(adr)) => match adr.autoref {
532                                 None => {
533                                     assert!(adr.unsize.is_none());
534                                     (adr.autoderefs, None)
535                                 }
536                                 Some(AutoPtr(_, _)) => {
537                                     (adr.autoderefs, adr.unsize.map(|target| {
538                                         target.builtin_deref(false, NoPreference)
539                                               .expect("fixup: AutoPtr is not &T").ty
540                                     }))
541                                 }
542                                 Some(_) => {
543                                     self.tcx().sess.span_bug(
544                                         base_expr.span,
545                                         &format!("unexpected adjustment autoref {:?}",
546                                                 adr));
547                                 }
548                             },
549                             None => (0, None),
550                             Some(_) => {
551                                 self.tcx().sess.span_bug(
552                                     base_expr.span,
553                                     "unexpected adjustment type");
554                             }
555                         };
556
557                         let (adjusted_base_ty, unsize) = if let Some(target) = unsize {
558                             (target, true)
559                         } else {
560                             (self.fcx.adjust_expr_ty(base_expr,
561                                 Some(&AdjustDerefRef(AutoDerefRef {
562                                     autoderefs: autoderefs,
563                                     autoref: None,
564                                     unsize: None
565                                 }))), false)
566                         };
567                         let index_expr_ty = self.fcx.expr_ty(&**index_expr);
568
569                         let result = check::try_index_step(
570                             self.fcx,
571                             ty::MethodCall::expr(expr.id),
572                             expr,
573                             &**base_expr,
574                             adjusted_base_ty,
575                             autoderefs,
576                             unsize,
577                             PreferMutLvalue,
578                             index_expr_ty);
579
580                         if let Some((input_ty, return_ty)) = result {
581                             demand::suptype(self.fcx, index_expr.span, input_ty, index_expr_ty);
582
583                             let expr_ty = self.fcx.expr_ty(&*expr);
584                             demand::suptype(self.fcx, expr.span, expr_ty, return_ty);
585                         }
586                     }
587                     hir::ExprUnary(hir::UnDeref, ref base_expr) => {
588                         // if this is an overloaded deref, then re-evaluate with
589                         // a preference for mut
590                         let method_call = ty::MethodCall::expr(expr.id);
591                         if self.fcx.inh.tables.borrow().method_map.contains_key(&method_call) {
592                             check::try_overloaded_deref(
593                                 self.fcx,
594                                 expr.span,
595                                 Some(method_call),
596                                 Some(&**base_expr),
597                                 self.fcx.expr_ty(&**base_expr),
598                                 PreferMutLvalue);
599                         }
600                     }
601                     _ => {}
602                 }
603             }
604         }
605     }
606
607     ///////////////////////////////////////////////////////////////////////////
608     // MISCELLANY
609
610     fn tcx(&self) -> &'a ty::ctxt<'tcx> {
611         self.fcx.tcx()
612     }
613
614     fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
615         self.fcx.infcx()
616     }
617
618     fn enforce_illegal_method_limitations(&self, pick: &probe::Pick) {
619         // Disallow calls to the method `drop` defined in the `Drop` trait.
620         match pick.item.container() {
621             ty::TraitContainer(trait_def_id) => {
622                 callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
623             }
624             ty::ImplContainer(..) => {
625                 // Since `drop` is a trait method, we expect that any
626                 // potential calls to it will wind up in the other
627                 // arm. But just to be sure, check that the method id
628                 // does not appear in the list of destructors.
629                 assert!(!self.tcx().destructors.borrow().contains(&pick.item.def_id()));
630             }
631         }
632     }
633
634     fn upcast(&mut self,
635               source_trait_ref: ty::PolyTraitRef<'tcx>,
636               target_trait_def_id: DefId)
637               -> ty::PolyTraitRef<'tcx>
638     {
639         let upcast_trait_refs = traits::upcast(self.tcx(),
640                                                source_trait_ref.clone(),
641                                                target_trait_def_id);
642
643         // must be exactly one trait ref or we'd get an ambig error etc
644         if upcast_trait_refs.len() != 1 {
645             self.tcx().sess.span_bug(
646                 self.span,
647                 &format!("cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`",
648                          source_trait_ref,
649                          target_trait_def_id,
650                          upcast_trait_refs));
651         }
652
653         upcast_trait_refs.into_iter().next().unwrap()
654     }
655
656     fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
657         where T : TypeFoldable<'tcx>
658     {
659         self.infcx().replace_late_bound_regions_with_fresh_var(
660             self.span, infer::FnCall, value).0
661     }
662 }