1 use super::{probe, MethodCallee}; 2 3 use crate::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall}; 4 use crate::check::{callee, FnCtxt}; 5 use crate::hir::def_id::DefId; 6 use crate::hir::GenericArg; 7 use rustc_hir as hir; 8 use rustc_infer::infer::{self, InferOk}; 9 use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; 10 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; 11 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; 12 use rustc_middle::ty::fold::TypeFoldable; 13 use rustc_middle::ty::subst::{self, Subst, SubstsRef}; 14 use rustc_middle::ty::{self, GenericParamDefKind, Ty}; 15 use rustc_span::Span; 16 use rustc_trait_selection::traits; 17 18 use std::iter; 19 use std::ops::Deref; 20 21 struct ConfirmContext<'a, 'tcx> { 22 fcx: &'a FnCtxt<'a, 'tcx>, 23 span: Span, 24 self_expr: &'tcx hir::Expr<'tcx>, 25 call_expr: &'tcx hir::Expr<'tcx>, 26 } 27 28 impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> { 29 type Target = FnCtxt<'a, 'tcx>; deref(&self) -> &Self::Target30 fn deref(&self) -> &Self::Target { 31 self.fcx 32 } 33 } 34 35 #[derive(Debug)] 36 pub struct ConfirmResult<'tcx> { 37 pub callee: MethodCallee<'tcx>, 38 pub illegal_sized_bound: Option<Span>, 39 } 40 41 impl<'a, 'tcx> FnCtxt<'a, 'tcx> { confirm_method( &self, span: Span, self_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>, unadjusted_self_ty: Ty<'tcx>, pick: probe::Pick<'tcx>, segment: &hir::PathSegment<'_>, ) -> ConfirmResult<'tcx>42 pub fn confirm_method( 43 &self, 44 span: Span, 45 self_expr: &'tcx hir::Expr<'tcx>, 46 call_expr: &'tcx hir::Expr<'tcx>, 47 unadjusted_self_ty: Ty<'tcx>, 48 pick: probe::Pick<'tcx>, 49 segment: &hir::PathSegment<'_>, 50 ) -> ConfirmResult<'tcx> { 51 debug!( 52 "confirm(unadjusted_self_ty={:?}, pick={:?}, generic_args={:?})", 53 unadjusted_self_ty, pick, segment.args, 54 ); 55 56 let mut confirm_cx = ConfirmContext::new(self, span, self_expr, call_expr); 57 confirm_cx.confirm(unadjusted_self_ty, pick, segment) 58 } 59 } 60 61 impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { new( fcx: &'a FnCtxt<'a, 'tcx>, span: Span, self_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>, ) -> ConfirmContext<'a, 'tcx>62 fn new( 63 fcx: &'a FnCtxt<'a, 'tcx>, 64 span: Span, 65 self_expr: &'tcx hir::Expr<'tcx>, 66 call_expr: &'tcx hir::Expr<'tcx>, 67 ) -> ConfirmContext<'a, 'tcx> { 68 ConfirmContext { fcx, span, self_expr, call_expr } 69 } 70 confirm( &mut self, unadjusted_self_ty: Ty<'tcx>, pick: probe::Pick<'tcx>, segment: &hir::PathSegment<'_>, ) -> ConfirmResult<'tcx>71 fn confirm( 72 &mut self, 73 unadjusted_self_ty: Ty<'tcx>, 74 pick: probe::Pick<'tcx>, 75 segment: &hir::PathSegment<'_>, 76 ) -> ConfirmResult<'tcx> { 77 // Adjust the self expression the user provided and obtain the adjusted type. 78 let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick); 79 80 // Create substitutions for the method's type parameters. 81 let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick); 82 let all_substs = self.instantiate_method_substs(&pick, segment, rcvr_substs); 83 84 debug!("all_substs={:?}", all_substs); 85 86 // Create the final signature for the method, replacing late-bound regions. 87 let (method_sig, method_predicates) = self.instantiate_method_sig(&pick, all_substs); 88 89 // Unify the (adjusted) self type with what the method expects. 90 // 91 // SUBTLE: if we want good error messages, because of "guessing" while matching 92 // traits, no trait system method can be called before this point because they 93 // could alter our Self-type, except for normalizing the receiver from the 94 // signature (which is also done during probing). 95 let method_sig_rcvr = self.normalize_associated_types_in(self.span, method_sig.inputs()[0]); 96 debug!( 97 "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}", 98 self_ty, method_sig_rcvr, method_sig, method_predicates 99 ); 100 self.unify_receivers(self_ty, method_sig_rcvr, &pick, all_substs); 101 102 let (method_sig, method_predicates) = 103 self.normalize_associated_types_in(self.span, (method_sig, method_predicates)); 104 let method_sig = ty::Binder::dummy(method_sig); 105 106 // Make sure nobody calls `drop()` explicitly. 107 self.enforce_illegal_method_limitations(&pick); 108 109 // If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that 110 // something which derefs to `Self` actually implements the trait and the caller 111 // wanted to make a static dispatch on it but forgot to import the trait. 112 // See test `src/test/ui/issue-35976.rs`. 113 // 114 // In that case, we'll error anyway, but we'll also re-run the search with all traits 115 // in scope, and if we find another method which can be used, we'll output an 116 // appropriate hint suggesting to import the trait. 117 let illegal_sized_bound = self.predicates_require_illegal_sized_bound(&method_predicates); 118 119 // Add any trait/regions obligations specified on the method's type parameters. 120 // We won't add these if we encountered an illegal sized bound, so that we can use 121 // a custom error in that case. 122 if illegal_sized_bound.is_none() { 123 self.add_obligations( 124 self.tcx.mk_fn_ptr(method_sig), 125 all_substs, 126 method_predicates, 127 pick.item.def_id, 128 ); 129 } 130 131 // Create the final `MethodCallee`. 132 let callee = MethodCallee { 133 def_id: pick.item.def_id, 134 substs: all_substs, 135 sig: method_sig.skip_binder(), 136 }; 137 ConfirmResult { callee, illegal_sized_bound } 138 } 139 140 /////////////////////////////////////////////////////////////////////////// 141 // ADJUSTMENTS 142 adjust_self_ty( &mut self, unadjusted_self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>, ) -> Ty<'tcx>143 fn adjust_self_ty( 144 &mut self, 145 unadjusted_self_ty: Ty<'tcx>, 146 pick: &probe::Pick<'tcx>, 147 ) -> Ty<'tcx> { 148 // Commit the autoderefs by calling `autoderef` again, but this 149 // time writing the results into the various typeck results. 150 let mut autoderef = 151 self.autoderef_overloaded_span(self.span, unadjusted_self_ty, self.call_expr.span); 152 let (_, n) = match autoderef.nth(pick.autoderefs) { 153 Some(n) => n, 154 None => { 155 return self.tcx.ty_error_with_message( 156 rustc_span::DUMMY_SP, 157 &format!("failed autoderef {}", pick.autoderefs), 158 ); 159 } 160 }; 161 assert_eq!(n, pick.autoderefs); 162 163 let mut adjustments = self.adjust_steps(&autoderef); 164 165 let mut target = 166 self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false)); 167 168 match &pick.autoref_or_ptr_adjustment { 169 Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => { 170 let region = self.next_region_var(infer::Autoref(self.span)); 171 target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl: *mutbl, ty: target }); 172 let mutbl = match mutbl { 173 hir::Mutability::Not => AutoBorrowMutability::Not, 174 hir::Mutability::Mut => AutoBorrowMutability::Mut { 175 // Method call receivers are the primary use case 176 // for two-phase borrows. 177 allow_two_phase_borrow: AllowTwoPhase::Yes, 178 }, 179 }; 180 adjustments.push(Adjustment { 181 kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)), 182 target, 183 }); 184 185 if let Some(unsize_target) = unsize { 186 target = self 187 .tcx 188 .mk_ref(region, ty::TypeAndMut { mutbl: mutbl.into(), ty: unsize_target }); 189 adjustments 190 .push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target }); 191 } 192 } 193 Some(probe::AutorefOrPtrAdjustment::ToConstPtr) => { 194 target = match target.kind() { 195 ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => { 196 assert_eq!(*mutbl, hir::Mutability::Mut); 197 self.tcx.mk_ptr(ty::TypeAndMut { mutbl: hir::Mutability::Not, ty }) 198 } 199 other => panic!("Cannot adjust receiver type {:?} to const ptr", other), 200 }; 201 202 adjustments.push(Adjustment { 203 kind: Adjust::Pointer(PointerCast::MutToConstPointer), 204 target, 205 }); 206 } 207 None => {} 208 } 209 210 self.register_predicates(autoderef.into_obligations()); 211 212 // Write out the final adjustments. 213 self.apply_adjustments(self.self_expr, adjustments); 214 215 target 216 } 217 218 /// Returns a set of substitutions for the method *receiver* where all type and region 219 /// parameters are instantiated with fresh variables. This substitution does not include any 220 /// parameters declared on the method itself. 221 /// 222 /// Note that this substitution may include late-bound regions from the impl level. If so, 223 /// these are instantiated later in the `instantiate_method_sig` routine. fresh_receiver_substs( &mut self, self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>, ) -> SubstsRef<'tcx>224 fn fresh_receiver_substs( 225 &mut self, 226 self_ty: Ty<'tcx>, 227 pick: &probe::Pick<'tcx>, 228 ) -> SubstsRef<'tcx> { 229 match pick.kind { 230 probe::InherentImplPick => { 231 let impl_def_id = pick.item.container.id(); 232 assert!( 233 self.tcx.impl_trait_ref(impl_def_id).is_none(), 234 "impl {:?} is not an inherent impl", 235 impl_def_id 236 ); 237 self.fresh_substs_for_item(self.span, impl_def_id) 238 } 239 240 probe::ObjectPick => { 241 let trait_def_id = pick.item.container.id(); 242 self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| { 243 // The object data has no entry for the Self 244 // Type. For the purposes of this method call, we 245 // substitute the object type itself. This 246 // wouldn't be a sound substitution in all cases, 247 // since each instance of the object type is a 248 // different existential and hence could match 249 // distinct types (e.g., if `Self` appeared as an 250 // argument type), but those cases have already 251 // been ruled out when we deemed the trait to be 252 // "object safe". 253 let original_poly_trait_ref = principal.with_self_ty(this.tcx, object_ty); 254 let upcast_poly_trait_ref = this.upcast(original_poly_trait_ref, trait_def_id); 255 let upcast_trait_ref = 256 this.replace_bound_vars_with_fresh_vars(upcast_poly_trait_ref); 257 debug!( 258 "original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}", 259 original_poly_trait_ref, upcast_trait_ref, trait_def_id 260 ); 261 upcast_trait_ref.substs 262 }) 263 } 264 265 probe::TraitPick => { 266 let trait_def_id = pick.item.container.id(); 267 268 // Make a trait reference `$0 : Trait<$1...$n>` 269 // consisting entirely of type variables. Later on in 270 // the process we will unify the transformed-self-type 271 // of the method with the actual type in order to 272 // unify some of these variables. 273 self.fresh_substs_for_item(self.span, trait_def_id) 274 } 275 276 probe::WhereClausePick(poly_trait_ref) => { 277 // Where clauses can have bound regions in them. We need to instantiate 278 // those to convert from a poly-trait-ref to a trait-ref. 279 self.replace_bound_vars_with_fresh_vars(poly_trait_ref).substs 280 } 281 } 282 } 283 extract_existential_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>) -> R,284 fn extract_existential_trait_ref<R, F>(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R 285 where 286 F: FnMut(&mut ConfirmContext<'a, 'tcx>, Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>) -> R, 287 { 288 // If we specified that this is an object method, then the 289 // self-type ought to be something that can be dereferenced to 290 // yield an object-type (e.g., `&Object` or `Box<Object>` 291 // etc). 292 293 // FIXME: this feels, like, super dubious 294 self.fcx 295 .autoderef(self.span, self_ty) 296 .include_raw_pointers() 297 .find_map(|(ty, _)| match ty.kind() { 298 ty::Dynamic(data, ..) => Some(closure( 299 self, 300 ty, 301 data.principal().unwrap_or_else(|| { 302 span_bug!(self.span, "calling trait method on empty object?") 303 }), 304 )), 305 _ => None, 306 }) 307 .unwrap_or_else(|| { 308 span_bug!( 309 self.span, 310 "self-type `{}` for ObjectPick never dereferenced to an object", 311 self_ty 312 ) 313 }) 314 } 315 instantiate_method_substs( &mut self, pick: &probe::Pick<'tcx>, seg: &hir::PathSegment<'_>, parent_substs: SubstsRef<'tcx>, ) -> SubstsRef<'tcx>316 fn instantiate_method_substs( 317 &mut self, 318 pick: &probe::Pick<'tcx>, 319 seg: &hir::PathSegment<'_>, 320 parent_substs: SubstsRef<'tcx>, 321 ) -> SubstsRef<'tcx> { 322 // Determine the values for the generic parameters of the method. 323 // If they were not explicitly supplied, just construct fresh 324 // variables. 325 let generics = self.tcx.generics_of(pick.item.def_id); 326 327 let arg_count_correct = <dyn AstConv<'_>>::check_generic_arg_count_for_call( 328 self.tcx, 329 self.span, 330 pick.item.def_id, 331 generics, 332 seg, 333 IsMethodCall::Yes, 334 ); 335 336 // Create subst for early-bound lifetime parameters, combining 337 // parameters from the type and those from the method. 338 assert_eq!(generics.parent_count, parent_substs.len()); 339 340 struct MethodSubstsCtxt<'a, 'tcx> { 341 cfcx: &'a ConfirmContext<'a, 'tcx>, 342 pick: &'a probe::Pick<'tcx>, 343 seg: &'a hir::PathSegment<'a>, 344 } 345 impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for MethodSubstsCtxt<'a, 'tcx> { 346 fn args_for_def_id( 347 &mut self, 348 def_id: DefId, 349 ) -> (Option<&'a hir::GenericArgs<'a>>, bool) { 350 if def_id == self.pick.item.def_id { 351 if let Some(data) = self.seg.args { 352 return (Some(data), false); 353 } 354 } 355 (None, false) 356 } 357 358 fn provided_kind( 359 &mut self, 360 param: &ty::GenericParamDef, 361 arg: &GenericArg<'_>, 362 ) -> subst::GenericArg<'tcx> { 363 match (¶m.kind, arg) { 364 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => { 365 <dyn AstConv<'_>>::ast_region_to_region(self.cfcx.fcx, lt, Some(param)) 366 .into() 367 } 368 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { 369 self.cfcx.to_ty(ty).into() 370 } 371 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { 372 self.cfcx.const_arg_to_const(&ct.value, param.def_id).into() 373 } 374 (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { 375 self.cfcx.ty_infer(Some(param), inf.span).into() 376 } 377 (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { 378 let tcx = self.cfcx.tcx(); 379 self.cfcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into() 380 } 381 _ => unreachable!(), 382 } 383 } 384 385 fn inferred_kind( 386 &mut self, 387 _substs: Option<&[subst::GenericArg<'tcx>]>, 388 param: &ty::GenericParamDef, 389 _infer_args: bool, 390 ) -> subst::GenericArg<'tcx> { 391 self.cfcx.var_for_def(self.cfcx.span, param) 392 } 393 } 394 <dyn AstConv<'_>>::create_substs_for_generic_args( 395 self.tcx, 396 pick.item.def_id, 397 parent_substs, 398 false, 399 None, 400 &arg_count_correct, 401 &mut MethodSubstsCtxt { cfcx: self, pick, seg }, 402 ) 403 } 404 unify_receivers( &mut self, self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>, substs: SubstsRef<'tcx>, )405 fn unify_receivers( 406 &mut self, 407 self_ty: Ty<'tcx>, 408 method_self_ty: Ty<'tcx>, 409 pick: &probe::Pick<'tcx>, 410 substs: SubstsRef<'tcx>, 411 ) { 412 debug!( 413 "unify_receivers: self_ty={:?} method_self_ty={:?} span={:?} pick={:?}", 414 self_ty, method_self_ty, self.span, pick 415 ); 416 let cause = self.cause( 417 self.span, 418 ObligationCauseCode::UnifyReceiver(Box::new(UnifyReceiverContext { 419 assoc_item: pick.item, 420 param_env: self.param_env, 421 substs, 422 })), 423 ); 424 match self.at(&cause, self.param_env).sup(method_self_ty, self_ty) { 425 Ok(InferOk { obligations, value: () }) => { 426 self.register_predicates(obligations); 427 } 428 Err(_) => { 429 span_bug!( 430 self.span, 431 "{} was a subtype of {} but now is not?", 432 self_ty, 433 method_self_ty 434 ); 435 } 436 } 437 } 438 439 // NOTE: this returns the *unnormalized* predicates and method sig. Because of 440 // inference guessing, the predicates and method signature can't be normalized 441 // until we unify the `Self` type. instantiate_method_sig( &mut self, pick: &probe::Pick<'tcx>, all_substs: SubstsRef<'tcx>, ) -> (ty::FnSig<'tcx>, ty::InstantiatedPredicates<'tcx>)442 fn instantiate_method_sig( 443 &mut self, 444 pick: &probe::Pick<'tcx>, 445 all_substs: SubstsRef<'tcx>, 446 ) -> (ty::FnSig<'tcx>, ty::InstantiatedPredicates<'tcx>) { 447 debug!("instantiate_method_sig(pick={:?}, all_substs={:?})", pick, all_substs); 448 449 // Instantiate the bounds on the method with the 450 // type/early-bound-regions substitutions performed. There can 451 // be no late-bound regions appearing here. 452 let def_id = pick.item.def_id; 453 let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_substs); 454 455 debug!("method_predicates after subst = {:?}", method_predicates); 456 457 let sig = self.tcx.fn_sig(def_id); 458 459 // Instantiate late-bound regions and substitute the trait 460 // parameters into the method type to get the actual method type. 461 // 462 // N.B., instantiate late-bound regions first so that 463 // `instantiate_type_scheme` can normalize associated types that 464 // may reference those regions. 465 let method_sig = self.replace_bound_vars_with_fresh_vars(sig); 466 debug!("late-bound lifetimes from method instantiated, method_sig={:?}", method_sig); 467 468 let method_sig = method_sig.subst(self.tcx, all_substs); 469 debug!("type scheme substituted, method_sig={:?}", method_sig); 470 471 (method_sig, method_predicates) 472 } 473 add_obligations( &mut self, fty: Ty<'tcx>, all_substs: SubstsRef<'tcx>, method_predicates: ty::InstantiatedPredicates<'tcx>, def_id: DefId, )474 fn add_obligations( 475 &mut self, 476 fty: Ty<'tcx>, 477 all_substs: SubstsRef<'tcx>, 478 method_predicates: ty::InstantiatedPredicates<'tcx>, 479 def_id: DefId, 480 ) { 481 debug!( 482 "add_obligations: fty={:?} all_substs={:?} method_predicates={:?} def_id={:?}", 483 fty, all_substs, method_predicates, def_id 484 ); 485 486 // FIXME: could replace with the following, but we already calculated `method_predicates`, 487 // so we just call `predicates_for_generics` directly to avoid redoing work. 488 // `self.add_required_obligations(self.span, def_id, &all_substs);` 489 for obligation in traits::predicates_for_generics( 490 traits::ObligationCause::new(self.span, self.body_id, traits::ItemObligation(def_id)), 491 self.param_env, 492 method_predicates, 493 ) { 494 self.register_predicate(obligation); 495 } 496 497 // this is a projection from a trait reference, so we have to 498 // make sure that the trait reference inputs are well-formed. 499 self.add_wf_bounds(all_substs, self.call_expr); 500 501 // the function type must also be well-formed (this is not 502 // implied by the substs being well-formed because of inherent 503 // impls and late-bound regions - see issue #28609). 504 self.register_wf_obligation(fty.into(), self.span, traits::MiscObligation); 505 } 506 507 /////////////////////////////////////////////////////////////////////////// 508 // MISCELLANY 509 predicates_require_illegal_sized_bound( &self, predicates: &ty::InstantiatedPredicates<'tcx>, ) -> Option<Span>510 fn predicates_require_illegal_sized_bound( 511 &self, 512 predicates: &ty::InstantiatedPredicates<'tcx>, 513 ) -> Option<Span> { 514 let sized_def_id = match self.tcx.lang_items().sized_trait() { 515 Some(def_id) => def_id, 516 None => return None, 517 }; 518 519 traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied()) 520 // We don't care about regions here. 521 .filter_map(|obligation| match obligation.predicate.kind().skip_binder() { 522 ty::PredicateKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => { 523 let span = iter::zip(&predicates.predicates, &predicates.spans) 524 .find_map( 525 |(p, span)| { 526 if *p == obligation.predicate { Some(*span) } else { None } 527 }, 528 ) 529 .unwrap_or(rustc_span::DUMMY_SP); 530 Some((trait_pred, span)) 531 } 532 _ => None, 533 }) 534 .find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() { 535 ty::Dynamic(..) => Some(span), 536 _ => None, 537 }) 538 } 539 enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>)540 fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { 541 // Disallow calls to the method `drop` defined in the `Drop` trait. 542 match pick.item.container { 543 ty::TraitContainer(trait_def_id) => callee::check_legal_trait_for_method_call( 544 self.tcx, 545 self.span, 546 Some(self.self_expr.span), 547 self.call_expr.span, 548 trait_def_id, 549 ), 550 ty::ImplContainer(..) => {} 551 } 552 } 553 upcast( &mut self, source_trait_ref: ty::PolyTraitRef<'tcx>, target_trait_def_id: DefId, ) -> ty::PolyTraitRef<'tcx>554 fn upcast( 555 &mut self, 556 source_trait_ref: ty::PolyTraitRef<'tcx>, 557 target_trait_def_id: DefId, 558 ) -> ty::PolyTraitRef<'tcx> { 559 let upcast_trait_refs = 560 traits::upcast_choices(self.tcx, source_trait_ref, target_trait_def_id); 561 562 // must be exactly one trait ref or we'd get an ambig error etc 563 if upcast_trait_refs.len() != 1 { 564 span_bug!( 565 self.span, 566 "cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`", 567 source_trait_ref, 568 target_trait_def_id, 569 upcast_trait_refs 570 ); 571 } 572 573 upcast_trait_refs.into_iter().next().unwrap() 574 } 575 replace_bound_vars_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T where T: TypeFoldable<'tcx>,576 fn replace_bound_vars_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T 577 where 578 T: TypeFoldable<'tcx>, 579 { 580 self.fcx.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, value).0 581 } 582 } 583