]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/method/confirm.rs
Auto merge of #27230 - GuillaumeGomez:patch-1, r=brson
[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         self.fcx.add_default_region_param_bounds(
436             all_substs,
437             self.call_expr);
438     }
439
440     ///////////////////////////////////////////////////////////////////////////
441     // RECONCILIATION
442
443     /// When we select a method with an `&mut self` receiver, we have to go convert any
444     /// auto-derefs, indices, etc from `Deref` and `Index` into `DerefMut` and `IndexMut`
445     /// respectively.
446     fn fixup_derefs_on_method_receiver_if_necessary(&self,
447                                                     method_callee: &ty::MethodCallee) {
448         let sig = match method_callee.ty.sty {
449             ty::TyBareFn(_, ref f) => f.sig.clone(),
450             _ => return,
451         };
452
453         match sig.0.inputs[0].sty {
454             ty::TyRef(_, ty::TypeAndMut {
455                 ty: _,
456                 mutbl: ast::MutMutable,
457             }) => {}
458             _ => return,
459         }
460
461         // Gather up expressions we want to munge.
462         let mut exprs = Vec::new();
463         exprs.push(self.self_expr);
464         loop {
465             let last = exprs[exprs.len() - 1];
466             match last.node {
467                 ast::ExprParen(ref expr) |
468                 ast::ExprField(ref expr, _) |
469                 ast::ExprTupField(ref expr, _) |
470                 ast::ExprIndex(ref expr, _) |
471                 ast::ExprUnary(ast::UnDeref, ref expr) => exprs.push(&**expr),
472                 _ => break,
473             }
474         }
475
476         debug!("fixup_derefs_on_method_receiver_if_necessary: exprs={:?}",
477                exprs);
478
479         // Fix up autoderefs and derefs.
480         for (i, &expr) in exprs.iter().rev().enumerate() {
481             // Count autoderefs.
482             let autoderef_count = match self.fcx
483                                             .inh
484                                             .tables
485                                             .borrow()
486                                             .adjustments
487                                             .get(&expr.id) {
488                 Some(&ty::AdjustDerefRef(ref adj)) => adj.autoderefs,
489                 Some(_) | None => 0,
490             };
491
492             debug!("fixup_derefs_on_method_receiver_if_necessary: i={} expr={:?} \
493                                                                   autoderef_count={}",
494                    i, expr, autoderef_count);
495
496             if autoderef_count > 0 {
497                 check::autoderef(self.fcx,
498                                  expr.span,
499                                  self.fcx.expr_ty(expr),
500                                  Some(expr),
501                                  UnresolvedTypeAction::Error,
502                                  PreferMutLvalue,
503                                  |_, autoderefs| {
504                                      if autoderefs == autoderef_count + 1 {
505                                          Some(())
506                                      } else {
507                                          None
508                                      }
509                                  });
510             }
511
512             // Don't retry the first one or we might infinite loop!
513             if i != 0 {
514                 match expr.node {
515                     ast::ExprIndex(ref base_expr, ref index_expr) => {
516                         // If this is an overloaded index, the
517                         // adjustment will include an extra layer of
518                         // autoref because the method is an &self/&mut
519                         // self method. We have to peel it off to get
520                         // the raw adjustment that `try_index_step`
521                         // expects. This is annoying and horrible. We
522                         // ought to recode this routine so it doesn't
523                         // (ab)use the normal type checking paths.
524                         let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id)
525                                                                           .cloned();
526                         let (autoderefs, unsize) = match adj {
527                             Some(ty::AdjustDerefRef(adr)) => match adr.autoref {
528                                 None => {
529                                     assert!(adr.unsize.is_none());
530                                     (adr.autoderefs, None)
531                                 }
532                                 Some(ty::AutoPtr(_, _)) => {
533                                     (adr.autoderefs, adr.unsize.map(|target| {
534                                         target.builtin_deref(false)
535                                               .expect("fixup: AutoPtr is not &T").ty
536                                     }))
537                                 }
538                                 Some(_) => {
539                                     self.tcx().sess.span_bug(
540                                         base_expr.span,
541                                         &format!("unexpected adjustment autoref {:?}",
542                                                 adr));
543                                 }
544                             },
545                             None => (0, None),
546                             Some(_) => {
547                                 self.tcx().sess.span_bug(
548                                     base_expr.span,
549                                     "unexpected adjustment type");
550                             }
551                         };
552
553                         let (adjusted_base_ty, unsize) = if let Some(target) = unsize {
554                             (target, true)
555                         } else {
556                             (self.fcx.adjust_expr_ty(base_expr,
557                                 Some(&ty::AdjustDerefRef(ty::AutoDerefRef {
558                                     autoderefs: autoderefs,
559                                     autoref: None,
560                                     unsize: None
561                                 }))), false)
562                         };
563                         let index_expr_ty = self.fcx.expr_ty(&**index_expr);
564
565                         let result = check::try_index_step(
566                             self.fcx,
567                             ty::MethodCall::expr(expr.id),
568                             expr,
569                             &**base_expr,
570                             adjusted_base_ty,
571                             autoderefs,
572                             unsize,
573                             PreferMutLvalue,
574                             index_expr_ty);
575
576                         if let Some((input_ty, return_ty)) = result {
577                             demand::suptype(self.fcx, index_expr.span, input_ty, index_expr_ty);
578
579                             let expr_ty = self.fcx.expr_ty(&*expr);
580                             demand::suptype(self.fcx, expr.span, expr_ty, return_ty);
581                         }
582                     }
583                     ast::ExprUnary(ast::UnDeref, ref base_expr) => {
584                         // if this is an overloaded deref, then re-evaluate with
585                         // a preference for mut
586                         let method_call = ty::MethodCall::expr(expr.id);
587                         if self.fcx.inh.tables.borrow().method_map.contains_key(&method_call) {
588                             check::try_overloaded_deref(
589                                 self.fcx,
590                                 expr.span,
591                                 Some(method_call),
592                                 Some(&**base_expr),
593                                 self.fcx.expr_ty(&**base_expr),
594                                 PreferMutLvalue);
595                         }
596                     }
597                     _ => {}
598                 }
599             }
600         }
601     }
602
603     ///////////////////////////////////////////////////////////////////////////
604     // MISCELLANY
605
606     fn tcx(&self) -> &'a ty::ctxt<'tcx> {
607         self.fcx.tcx()
608     }
609
610     fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
611         self.fcx.infcx()
612     }
613
614     fn enforce_illegal_method_limitations(&self, pick: &probe::Pick) {
615         // Disallow calls to the method `drop` defined in the `Drop` trait.
616         match pick.item.container() {
617             ty::TraitContainer(trait_def_id) => {
618                 callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
619             }
620             ty::ImplContainer(..) => {
621                 // Since `drop` is a trait method, we expect that any
622                 // potential calls to it will wind up in the other
623                 // arm. But just to be sure, check that the method id
624                 // does not appear in the list of destructors.
625                 assert!(!self.tcx().destructors.borrow().contains(&pick.item.def_id()));
626             }
627         }
628     }
629
630     fn upcast(&mut self,
631               source_trait_ref: ty::PolyTraitRef<'tcx>,
632               target_trait_def_id: ast::DefId)
633               -> ty::PolyTraitRef<'tcx>
634     {
635         let upcast_trait_refs = traits::upcast(self.tcx(),
636                                                source_trait_ref.clone(),
637                                                target_trait_def_id);
638
639         // must be exactly one trait ref or we'd get an ambig error etc
640         if upcast_trait_refs.len() != 1 {
641             self.tcx().sess.span_bug(
642                 self.span,
643                 &format!("cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`",
644                          source_trait_ref,
645                          target_trait_def_id,
646                          upcast_trait_refs));
647         }
648
649         upcast_trait_refs.into_iter().next().unwrap()
650     }
651
652     fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
653         where T : TypeFoldable<'tcx>
654     {
655         self.infcx().replace_late_bound_regions_with_fresh_var(
656             self.span, infer::FnCall, value).0
657     }
658 }