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