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