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