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