1use std::iter;
11use std::ops::ControlFlow;
12
13use rustc_ast::Mutability;
14use rustc_data_structures::stack::ensure_sufficient_stack;
15use rustc_hir::lang_items::LangItem;
16use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
17use rustc_infer::traits::ObligationCauseCode;
18use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
19use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast};
20use rustc_middle::{bug, span_bug};
21use rustc_span::def_id::DefId;
22use rustc_type_ir::elaborate;
23use thin_vec::thin_vec;
24use tracing::{debug, instrument};
25
26use super::SelectionCandidate::{self, *};
27use super::{BuiltinImplConditions, PredicateObligations, SelectionContext};
28use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
29use crate::traits::util::{self, closure_trait_ref_and_return_type};
30use crate::traits::{
31 ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
32 PolyTraitObligation, PredicateObligation, Selection, SelectionError, SignatureMismatch,
33 TraitDynIncompatible, TraitObligation, Unimplemented,
34};
35
36impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
37 #[instrument(level = "debug", skip(self))]
38 pub(super) fn confirm_candidate(
39 &mut self,
40 obligation: &PolyTraitObligation<'tcx>,
41 candidate: SelectionCandidate<'tcx>,
42 ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
43 let mut impl_src = match candidate {
44 BuiltinCandidate { has_nested } => {
45 let data = self.confirm_builtin_candidate(obligation, has_nested);
46 ImplSource::Builtin(BuiltinImplSource::Misc, data)
47 }
48
49 TransmutabilityCandidate => {
50 let data = self.confirm_transmutability_candidate(obligation)?;
51 ImplSource::Builtin(BuiltinImplSource::Misc, data)
52 }
53
54 ParamCandidate(param) => {
55 let obligations =
56 self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
57 ImplSource::Param(obligations)
58 }
59
60 ImplCandidate(impl_def_id) => {
61 ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))
62 }
63
64 AutoImplCandidate => {
65 let data = self.confirm_auto_impl_candidate(obligation)?;
66 ImplSource::Builtin(BuiltinImplSource::Misc, data)
67 }
68
69 ProjectionCandidate(idx) => {
70 let obligations = self.confirm_projection_candidate(obligation, idx)?;
71 ImplSource::Param(obligations)
72 }
73
74 ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?,
75
76 ClosureCandidate { .. } => {
77 let vtable_closure = self.confirm_closure_candidate(obligation)?;
78 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
79 }
80
81 AsyncClosureCandidate => {
82 let vtable_closure = self.confirm_async_closure_candidate(obligation)?;
83 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
84 }
85
86 AsyncFnKindHelperCandidate => {
89 ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
90 }
91
92 CoroutineCandidate => {
93 let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?;
94 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_coroutine)
95 }
96
97 FutureCandidate => {
98 let vtable_future = self.confirm_future_candidate(obligation)?;
99 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_future)
100 }
101
102 IteratorCandidate => {
103 let vtable_iterator = self.confirm_iterator_candidate(obligation)?;
104 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
105 }
106
107 AsyncIteratorCandidate => {
108 let vtable_iterator = self.confirm_async_iterator_candidate(obligation)?;
109 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
110 }
111
112 FnPointerCandidate => {
113 let data = self.confirm_fn_pointer_candidate(obligation)?;
114 ImplSource::Builtin(BuiltinImplSource::Misc, data)
115 }
116
117 TraitAliasCandidate => {
118 let data = self.confirm_trait_alias_candidate(obligation);
119 ImplSource::Builtin(BuiltinImplSource::Misc, data)
120 }
121
122 BuiltinObjectCandidate => {
123 ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
127 }
128
129 BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?,
130
131 TraitUpcastingUnsizeCandidate(idx) => {
132 self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?
133 }
134
135 BikeshedGuaranteedNoDropCandidate => {
136 self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
137 }
138 };
139
140 for subobligation in impl_src.borrow_nested_obligations_mut() {
143 subobligation.set_depth_from_parent(obligation.recursion_depth);
144 }
145
146 Ok(impl_src)
147 }
148
149 fn confirm_projection_candidate(
150 &mut self,
151 obligation: &PolyTraitObligation<'tcx>,
152 idx: usize,
153 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
154 let tcx = self.tcx();
155
156 let placeholder_trait_predicate =
157 self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref;
158 let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty());
159 let candidate_predicate = self
160 .for_each_item_bound(
161 placeholder_self_ty,
162 |_, clause, clause_idx| {
163 if clause_idx == idx {
164 ControlFlow::Break(clause)
165 } else {
166 ControlFlow::Continue(())
167 }
168 },
169 || unreachable!(),
170 )
171 .break_value()
172 .expect("expected to index into clause that exists");
173 let candidate = candidate_predicate
174 .as_trait_clause()
175 .expect("projection candidate is not a trait predicate")
176 .map_bound(|t| t.trait_ref);
177
178 let candidate = self.infcx.instantiate_binder_with_fresh_vars(
179 obligation.cause.span,
180 HigherRankedType,
181 candidate,
182 );
183 let mut obligations = PredicateObligations::new();
184 let candidate = normalize_with_depth_to(
185 self,
186 obligation.param_env,
187 obligation.cause.clone(),
188 obligation.recursion_depth + 1,
189 candidate,
190 &mut obligations,
191 );
192
193 obligations.extend(
194 self.infcx
195 .at(&obligation.cause, obligation.param_env)
196 .eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
197 .map(|InferOk { obligations, .. }| obligations)
198 .map_err(|_| Unimplemented)?,
199 );
200
201 if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
203 let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
204 for (predicate, _) in predicates {
205 let normalized = normalize_with_depth_to(
206 self,
207 obligation.param_env,
208 obligation.cause.clone(),
209 obligation.recursion_depth + 1,
210 predicate,
211 &mut obligations,
212 );
213 obligations.push(Obligation::with_depth(
214 self.tcx(),
215 obligation.cause.clone(),
216 obligation.recursion_depth + 1,
217 obligation.param_env,
218 normalized,
219 ));
220 }
221 }
222
223 Ok(obligations)
224 }
225
226 fn confirm_param_candidate(
227 &mut self,
228 obligation: &PolyTraitObligation<'tcx>,
229 param: ty::PolyTraitRef<'tcx>,
230 ) -> PredicateObligations<'tcx> {
231 debug!(?obligation, ?param, "confirm_param_candidate");
232
233 match self.match_where_clause_trait_ref(obligation, param) {
238 Ok(obligations) => obligations,
239 Err(()) => {
240 bug!(
241 "Where clause `{:?}` was applicable to `{:?}` but now is not",
242 param,
243 obligation
244 );
245 }
246 }
247 }
248
249 fn confirm_builtin_candidate(
250 &mut self,
251 obligation: &PolyTraitObligation<'tcx>,
252 has_nested: bool,
253 ) -> PredicateObligations<'tcx> {
254 debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
255
256 let tcx = self.tcx();
257 let obligations = if has_nested {
258 let trait_def = obligation.predicate.def_id();
259 let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) {
260 self.sized_conditions(obligation)
261 } else if tcx.is_lang_item(trait_def, LangItem::Copy) {
262 self.copy_clone_conditions(obligation)
263 } else if tcx.is_lang_item(trait_def, LangItem::Clone) {
264 self.copy_clone_conditions(obligation)
265 } else if tcx.is_lang_item(trait_def, LangItem::FusedIterator) {
266 self.fused_iterator_conditions(obligation)
267 } else {
268 bug!("unexpected builtin trait {:?}", trait_def)
269 };
270 let BuiltinImplConditions::Where(nested) = conditions else {
271 bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
272 };
273
274 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
275 self.collect_predicates_for_types(
276 obligation.param_env,
277 cause,
278 obligation.recursion_depth + 1,
279 trait_def,
280 nested,
281 )
282 } else {
283 PredicateObligations::new()
284 };
285
286 debug!(?obligations);
287
288 obligations
289 }
290
291 #[instrument(level = "debug", skip(self))]
292 fn confirm_transmutability_candidate(
293 &mut self,
294 obligation: &PolyTraitObligation<'tcx>,
295 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
296 use rustc_transmute::{Answer, Assume, Condition};
297
298 fn reference_obligations<'tcx>(
300 tcx: TyCtxt<'tcx>,
301 obligation: &PolyTraitObligation<'tcx>,
302 (src_lifetime, src_ty, src_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability),
303 (dst_lifetime, dst_ty, dst_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability),
304 assume: Assume,
305 ) -> PredicateObligations<'tcx> {
306 let make_transmute_obl = |src, dst| {
307 let transmute_trait = obligation.predicate.def_id();
308 let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2);
309 let trait_ref = ty::TraitRef::new(
310 tcx,
311 transmute_trait,
312 [
313 ty::GenericArg::from(dst),
314 ty::GenericArg::from(src),
315 ty::GenericArg::from(assume),
316 ],
317 );
318 Obligation::with_depth(
319 tcx,
320 obligation.cause.clone(),
321 obligation.recursion_depth + 1,
322 obligation.param_env,
323 obligation.predicate.rebind(trait_ref),
324 )
325 };
326
327 let make_freeze_obl = |ty| {
328 let trait_ref = ty::TraitRef::new(
329 tcx,
330 tcx.require_lang_item(LangItem::Freeze, None),
331 [ty::GenericArg::from(ty)],
332 );
333 Obligation::with_depth(
334 tcx,
335 obligation.cause.clone(),
336 obligation.recursion_depth + 1,
337 obligation.param_env,
338 trait_ref,
339 )
340 };
341
342 let make_outlives_obl = |target, region| {
343 let outlives = ty::OutlivesPredicate(target, region);
344 Obligation::with_depth(
345 tcx,
346 obligation.cause.clone(),
347 obligation.recursion_depth + 1,
348 obligation.param_env,
349 obligation.predicate.rebind(outlives),
350 )
351 };
352
353 let mut obls = PredicateObligations::with_capacity(1);
357 obls.push(make_transmute_obl(src_ty, dst_ty));
358 if !assume.lifetimes {
359 obls.push(make_outlives_obl(src_lifetime, dst_lifetime));
360 }
361
362 if src_mut == Mutability::Not {
366 obls.extend([make_freeze_obl(src_ty), make_freeze_obl(dst_ty)])
367 }
368
369 if dst_mut == Mutability::Mut {
376 obls.push(make_transmute_obl(dst_ty, src_ty));
377 if !assume.lifetimes {
378 obls.push(make_outlives_obl(dst_lifetime, src_lifetime));
379 }
380 }
381
382 obls
383 }
384
385 #[instrument(level = "debug", skip(tcx, obligation))]
387 fn flatten_answer_tree<'tcx>(
388 tcx: TyCtxt<'tcx>,
389 obligation: &PolyTraitObligation<'tcx>,
390 cond: Condition<rustc_transmute::layout::rustc::Ref<'tcx>>,
391 assume: Assume,
392 ) -> PredicateObligations<'tcx> {
393 match cond {
394 Condition::IfAll(conds) | Condition::IfAny(conds) => conds
397 .into_iter()
398 .flat_map(|cond| flatten_answer_tree(tcx, obligation, cond, assume))
399 .collect(),
400 Condition::IfTransmutable { src, dst } => reference_obligations(
401 tcx,
402 obligation,
403 (src.lifetime, src.ty, src.mutability),
404 (dst.lifetime, dst.ty, dst.mutability),
405 assume,
406 ),
407 }
408 }
409
410 let predicate = obligation.predicate.skip_binder();
411
412 let mut assume = predicate.trait_ref.args.const_at(2);
413 if self.tcx().features().generic_const_exprs() {
415 assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env)
416 }
417 let Some(assume) =
418 rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume)
419 else {
420 return Err(Unimplemented);
421 };
422
423 let dst = predicate.trait_ref.args.type_at(0);
424 let src = predicate.trait_ref.args.type_at(1);
425
426 debug!(?src, ?dst);
427 let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx);
428 let maybe_transmutable = transmute_env.is_transmutable(
429 obligation.cause.clone(),
430 rustc_transmute::Types { dst, src },
431 assume,
432 );
433
434 let fully_flattened = match maybe_transmutable {
435 Answer::No(_) => Err(Unimplemented)?,
436 Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, cond, assume),
437 Answer::Yes => PredicateObligations::new(),
438 };
439
440 debug!(?fully_flattened);
441 Ok(fully_flattened)
442 }
443
444 fn confirm_auto_impl_candidate(
450 &mut self,
451 obligation: &PolyTraitObligation<'tcx>,
452 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
453 debug!(?obligation, "confirm_auto_impl_candidate");
454
455 let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
456 let types = self.constituent_types_for_ty(self_ty)?;
457 Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types))
458 }
459
460 fn vtable_auto_impl(
462 &mut self,
463 obligation: &PolyTraitObligation<'tcx>,
464 trait_def_id: DefId,
465 nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
466 ) -> PredicateObligations<'tcx> {
467 debug!(?nested, "vtable_auto_impl");
468 ensure_sufficient_stack(|| {
469 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
470
471 assert_eq!(obligation.predicate.polarity(), ty::PredicatePolarity::Positive);
472 let trait_ref =
473 self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref;
474 let trait_obligations = self.impl_or_trait_obligations(
475 &cause,
476 obligation.recursion_depth + 1,
477 obligation.param_env,
478 trait_def_id,
479 trait_ref.args,
480 obligation.predicate,
481 );
482
483 let mut obligations = self.collect_predicates_for_types(
484 obligation.param_env,
485 cause,
486 obligation.recursion_depth + 1,
487 trait_def_id,
488 nested,
489 );
490
491 obligations.extend(trait_obligations);
494
495 debug!(?obligations, "vtable_auto_impl");
496
497 obligations
498 })
499 }
500
501 fn confirm_impl_candidate(
502 &mut self,
503 obligation: &PolyTraitObligation<'tcx>,
504 impl_def_id: DefId,
505 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
506 debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
507
508 let args = self.rematch_impl(impl_def_id, obligation);
511 debug!(?args, "impl args");
512 ensure_sufficient_stack(|| {
513 self.vtable_impl(
514 impl_def_id,
515 args,
516 &obligation.cause,
517 obligation.recursion_depth + 1,
518 obligation.param_env,
519 obligation.predicate,
520 )
521 })
522 }
523
524 fn vtable_impl(
525 &mut self,
526 impl_def_id: DefId,
527 args: Normalized<'tcx, GenericArgsRef<'tcx>>,
528 cause: &ObligationCause<'tcx>,
529 recursion_depth: usize,
530 param_env: ty::ParamEnv<'tcx>,
531 parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
532 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
533 debug!(?impl_def_id, ?args, ?recursion_depth, "vtable_impl");
534
535 let mut impl_obligations = self.impl_or_trait_obligations(
536 cause,
537 recursion_depth,
538 param_env,
539 impl_def_id,
540 args.value,
541 parent_trait_pred,
542 );
543
544 debug!(?impl_obligations, "vtable_impl");
545
546 impl_obligations.extend(args.obligations);
552
553 ImplSourceUserDefinedData { impl_def_id, args: args.value, nested: impl_obligations }
554 }
555
556 fn confirm_object_candidate(
557 &mut self,
558 obligation: &PolyTraitObligation<'tcx>,
559 index: usize,
560 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
561 let tcx = self.tcx();
562 debug!(?obligation, ?index, "confirm_object_candidate");
563
564 let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
565 let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
566 let ty::Dynamic(data, ..) = *self_ty.kind() else {
567 span_bug!(obligation.cause.span, "object candidate with non-object");
568 };
569
570 let object_trait_ref = data.principal().unwrap_or_else(|| {
571 span_bug!(obligation.cause.span, "object candidate with no principal")
572 });
573 let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
574 obligation.cause.span,
575 HigherRankedType,
576 object_trait_ref,
577 );
578 let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty);
579
580 let mut nested = PredicateObligations::new();
581
582 let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref));
583 let unnormalized_upcast_trait_ref =
584 supertraits.nth(index).expect("supertraits iterator no longer has as many elements");
585
586 let upcast_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
587 obligation.cause.span,
588 HigherRankedType,
589 unnormalized_upcast_trait_ref,
590 );
591 let upcast_trait_ref = normalize_with_depth_to(
592 self,
593 obligation.param_env,
594 obligation.cause.clone(),
595 obligation.recursion_depth + 1,
596 upcast_trait_ref,
597 &mut nested,
598 );
599
600 nested.extend(
601 self.infcx
602 .at(&obligation.cause, obligation.param_env)
603 .eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref)
604 .map(|InferOk { obligations, .. }| obligations)
605 .map_err(|_| Unimplemented)?,
606 );
607
608 for (supertrait, _) in tcx
611 .explicit_super_predicates_of(trait_predicate.def_id())
612 .iter_instantiated_copied(tcx, trait_predicate.trait_ref.args)
613 {
614 let normalized_supertrait = normalize_with_depth_to(
615 self,
616 obligation.param_env,
617 obligation.cause.clone(),
618 obligation.recursion_depth + 1,
619 supertrait,
620 &mut nested,
621 );
622 nested.push(obligation.with(tcx, normalized_supertrait));
623 }
624
625 let assoc_types: Vec<_> = tcx
626 .associated_items(trait_predicate.def_id())
627 .in_definition_order()
628 .filter(|item| !tcx.generics_require_sized_self(item.def_id))
631 .filter_map(
632 |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
633 )
634 .collect();
635
636 for assoc_type in assoc_types {
637 let defs: &ty::Generics = tcx.generics_of(assoc_type);
638
639 if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) {
642 continue;
643 }
644
645 if !defs.own_params.is_empty() {
646 tcx.dcx().span_delayed_bug(
647 obligation.cause.span,
648 "GATs in trait object shouldn't have been considered",
649 );
650 return Err(SelectionError::TraitDynIncompatible(trait_predicate.trait_ref.def_id));
651 }
652
653 for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
657 let normalized_bound = normalize_with_depth_to(
658 self,
659 obligation.param_env,
660 obligation.cause.clone(),
661 obligation.recursion_depth + 1,
662 bound.instantiate(tcx, trait_predicate.trait_ref.args),
663 &mut nested,
664 );
665 nested.push(obligation.with(tcx, normalized_bound));
666 }
667 }
668
669 debug!(?nested, "object nested obligations");
670
671 Ok(ImplSource::Builtin(BuiltinImplSource::Object(index), nested))
672 }
673
674 fn confirm_fn_pointer_candidate(
675 &mut self,
676 obligation: &PolyTraitObligation<'tcx>,
677 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
678 debug!(?obligation, "confirm_fn_pointer_candidate");
679 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
680 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
681
682 let tcx = self.tcx();
683 let sig = self_ty.fn_sig(tcx);
684 let trait_ref = closure_trait_ref_and_return_type(
685 tcx,
686 obligation.predicate.def_id(),
687 self_ty,
688 sig,
689 util::TupleArgumentsFlag::Yes,
690 )
691 .map_bound(|(trait_ref, _)| trait_ref);
692
693 let mut nested =
694 self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?;
695 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
696
697 let output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
699 let output_ty = normalize_with_depth_to(
700 self,
701 obligation.param_env,
702 cause.clone(),
703 obligation.recursion_depth,
704 output_ty,
705 &mut nested,
706 );
707 let tr = ty::TraitRef::new(
708 self.tcx(),
709 self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
710 [output_ty],
711 );
712 nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
713
714 Ok(nested)
715 }
716
717 fn confirm_trait_alias_candidate(
718 &mut self,
719 obligation: &PolyTraitObligation<'tcx>,
720 ) -> PredicateObligations<'tcx> {
721 debug!(?obligation, "confirm_trait_alias_candidate");
722
723 let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
724 let trait_ref = predicate.trait_ref;
725 let trait_def_id = trait_ref.def_id;
726 let args = trait_ref.args;
727
728 let trait_obligations = self.impl_or_trait_obligations(
729 &obligation.cause,
730 obligation.recursion_depth,
731 obligation.param_env,
732 trait_def_id,
733 args,
734 obligation.predicate,
735 );
736
737 debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
738
739 trait_obligations
740 }
741
742 fn confirm_coroutine_candidate(
743 &mut self,
744 obligation: &PolyTraitObligation<'tcx>,
745 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
746 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
747 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
748 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
749 bug!("closure candidate for non-closure {:?}", obligation);
750 };
751
752 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_coroutine_candidate");
753
754 let coroutine_sig = args.as_coroutine().sig();
755
756 let (trait_ref, _, _) = super::util::coroutine_trait_ref_and_outputs(
757 self.tcx(),
758 obligation.predicate.def_id(),
759 self_ty,
760 coroutine_sig,
761 );
762
763 let nested = self.equate_trait_refs(
764 obligation.with(self.tcx(), placeholder_predicate),
765 ty::Binder::dummy(trait_ref),
766 )?;
767 debug!(?trait_ref, ?nested, "coroutine candidate obligations");
768
769 Ok(nested)
770 }
771
772 fn confirm_future_candidate(
773 &mut self,
774 obligation: &PolyTraitObligation<'tcx>,
775 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
776 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
777 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
778 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
779 bug!("closure candidate for non-closure {:?}", obligation);
780 };
781
782 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_future_candidate");
783
784 let coroutine_sig = args.as_coroutine().sig();
785
786 let (trait_ref, _) = super::util::future_trait_ref_and_outputs(
787 self.tcx(),
788 obligation.predicate.def_id(),
789 self_ty,
790 coroutine_sig,
791 );
792
793 let nested = self.equate_trait_refs(
794 obligation.with(self.tcx(), placeholder_predicate),
795 ty::Binder::dummy(trait_ref),
796 )?;
797 debug!(?trait_ref, ?nested, "future candidate obligations");
798
799 Ok(nested)
800 }
801
802 fn confirm_iterator_candidate(
803 &mut self,
804 obligation: &PolyTraitObligation<'tcx>,
805 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
806 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
807 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
808 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
809 bug!("closure candidate for non-closure {:?}", obligation);
810 };
811
812 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_iterator_candidate");
813
814 let gen_sig = args.as_coroutine().sig();
815
816 let (trait_ref, _) = super::util::iterator_trait_ref_and_outputs(
817 self.tcx(),
818 obligation.predicate.def_id(),
819 self_ty,
820 gen_sig,
821 );
822
823 let nested = self.equate_trait_refs(
824 obligation.with(self.tcx(), placeholder_predicate),
825 ty::Binder::dummy(trait_ref),
826 )?;
827 debug!(?trait_ref, ?nested, "iterator candidate obligations");
828
829 Ok(nested)
830 }
831
832 fn confirm_async_iterator_candidate(
833 &mut self,
834 obligation: &PolyTraitObligation<'tcx>,
835 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
836 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
837 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
838 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
839 bug!("closure candidate for non-closure {:?}", obligation);
840 };
841
842 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_async_iterator_candidate");
843
844 let gen_sig = args.as_coroutine().sig();
845
846 let (trait_ref, _) = super::util::async_iterator_trait_ref_and_outputs(
847 self.tcx(),
848 obligation.predicate.def_id(),
849 self_ty,
850 gen_sig,
851 );
852
853 let nested = self.equate_trait_refs(
854 obligation.with(self.tcx(), placeholder_predicate),
855 ty::Binder::dummy(trait_ref),
856 )?;
857 debug!(?trait_ref, ?nested, "iterator candidate obligations");
858
859 Ok(nested)
860 }
861
862 #[instrument(skip(self), level = "debug")]
863 fn confirm_closure_candidate(
864 &mut self,
865 obligation: &PolyTraitObligation<'tcx>,
866 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
867 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
868 let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
869
870 let trait_ref = match *self_ty.kind() {
871 ty::Closure(..) => {
872 self.closure_trait_ref_unnormalized(self_ty, obligation.predicate.def_id())
873 }
874 ty::CoroutineClosure(_, args) => {
875 args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
876 ty::TraitRef::new(
877 self.tcx(),
878 obligation.predicate.def_id(),
879 [self_ty, sig.tupled_inputs_ty],
880 )
881 })
882 }
883 _ => {
884 bug!("closure candidate for non-closure {:?}", obligation);
885 }
886 };
887
888 self.equate_trait_refs(obligation.with(self.tcx(), placeholder_predicate), trait_ref)
889 }
890
891 #[instrument(skip(self), level = "debug")]
892 fn confirm_async_closure_candidate(
893 &mut self,
894 obligation: &PolyTraitObligation<'tcx>,
895 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
896 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
897 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
898
899 let tcx = self.tcx();
900
901 let mut nested = PredicateObligations::new();
902 let (trait_ref, kind_ty) = match *self_ty.kind() {
903 ty::CoroutineClosure(_, args) => {
904 let args = args.as_coroutine_closure();
905 let trait_ref = args.coroutine_closure_sig().map_bound(|sig| {
906 ty::TraitRef::new(
907 self.tcx(),
908 obligation.predicate.def_id(),
909 [self_ty, sig.tupled_inputs_ty],
910 )
911 });
912
913 (trait_ref, args.kind_ty())
917 }
918 ty::FnDef(..) | ty::FnPtr(..) => {
919 let sig = self_ty.fn_sig(tcx);
920 let trait_ref = sig.map_bound(|sig| {
921 ty::TraitRef::new(
922 self.tcx(),
923 obligation.predicate.def_id(),
924 [self_ty, Ty::new_tup(tcx, sig.inputs())],
925 )
926 });
927
928 let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
930 nested.push(obligation.with(
931 tcx,
932 sig.output().map_bound(|output_ty| {
933 ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
934 }),
935 ));
936 let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
937 nested.push(obligation.with(
938 tcx,
939 sig.output().map_bound(|output_ty| {
940 ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
941 }),
942 ));
943
944 (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
945 }
946 ty::Closure(_, args) => {
947 let args = args.as_closure();
948 let sig = args.sig();
949 let trait_ref = sig.map_bound(|sig| {
950 ty::TraitRef::new(
951 self.tcx(),
952 obligation.predicate.def_id(),
953 [self_ty, sig.inputs()[0]],
954 )
955 });
956
957 let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
959 let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
960 nested.push(obligation.with(
961 tcx,
962 ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
963 ));
964 let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
965 nested.push(obligation.with(
966 tcx,
967 sig.output().map_bound(|output_ty| {
968 ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
969 }),
970 ));
971
972 (trait_ref, args.kind_ty())
973 }
974 _ => bug!("expected callable type for AsyncFn candidate"),
975 };
976
977 nested.extend(
978 self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?,
979 );
980
981 let goal_kind =
982 self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
983
984 if let Some(closure_kind) = self.infcx.shallow_resolve(kind_ty).to_opt_closure_kind() {
988 if !closure_kind.extends(goal_kind) {
989 return Err(SelectionError::Unimplemented);
990 }
991 } else {
992 nested.push(obligation.with(
993 self.tcx(),
994 ty::TraitRef::new(
995 self.tcx(),
996 self.tcx().require_lang_item(
997 LangItem::AsyncFnKindHelper,
998 Some(obligation.cause.span),
999 ),
1000 [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
1001 ),
1002 ));
1003 }
1004
1005 Ok(nested)
1006 }
1007
1008 #[instrument(skip(self), level = "trace")]
1034 fn equate_trait_refs(
1035 &mut self,
1036 obligation: TraitObligation<'tcx>,
1037 found_trait_ref: ty::PolyTraitRef<'tcx>,
1038 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
1039 let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
1040 obligation.cause.span,
1041 HigherRankedType,
1042 found_trait_ref,
1043 );
1044 let Normalized { obligations: nested, value: (obligation_trait_ref, found_trait_ref) } =
1046 ensure_sufficient_stack(|| {
1047 normalize_with_depth(
1048 self,
1049 obligation.param_env,
1050 obligation.cause.clone(),
1051 obligation.recursion_depth + 1,
1052 (obligation.predicate.trait_ref, found_trait_ref),
1053 )
1054 });
1055
1056 self.infcx
1058 .at(&obligation.cause, obligation.param_env)
1059 .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
1060 .map(|InferOk { mut obligations, .. }| {
1061 obligations.extend(nested);
1062 obligations
1063 })
1064 .map_err(|terr| {
1065 SignatureMismatch(Box::new(SignatureMismatchData {
1066 expected_trait_ref: obligation_trait_ref,
1067 found_trait_ref,
1068 terr,
1069 }))
1070 })
1071 }
1072
1073 fn confirm_trait_upcasting_unsize_candidate(
1074 &mut self,
1075 obligation: &PolyTraitObligation<'tcx>,
1076 idx: usize,
1077 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1078 let tcx = self.tcx();
1079
1080 let predicate = obligation.predicate.no_bound_vars().unwrap();
1083 let a_ty = self.infcx.shallow_resolve(predicate.self_ty());
1084 let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1));
1085
1086 let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
1087 bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1088 };
1089 let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
1090 bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1091 };
1092
1093 let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty);
1094 let unnormalized_upcast_principal =
1095 util::supertraits(tcx, source_principal).nth(idx).unwrap();
1096
1097 let nested = self
1098 .match_upcast_principal(
1099 obligation,
1100 unnormalized_upcast_principal,
1101 a_data,
1102 b_data,
1103 a_region,
1104 b_region,
1105 )?
1106 .expect("did not expect ambiguity during confirmation");
1107
1108 Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting(idx), nested))
1109 }
1110
1111 fn confirm_builtin_unsize_candidate(
1112 &mut self,
1113 obligation: &PolyTraitObligation<'tcx>,
1114 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1115 let tcx = self.tcx();
1116
1117 let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
1120 let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
1121 let target = self.infcx.shallow_resolve(target);
1122 debug!(?source, ?target, "confirm_builtin_unsize_candidate");
1123
1124 Ok(match (source.kind(), target.kind()) {
1125 (&ty::Dynamic(data_a, r_a, dyn_a), &ty::Dynamic(data_b, r_b, dyn_b))
1127 if dyn_a == dyn_b =>
1128 {
1129 let iter = data_a
1132 .principal()
1133 .filter(|_| {
1134 data_b.principal().is_some()
1136 })
1137 .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
1138 .into_iter()
1139 .chain(
1140 data_a
1141 .projection_bounds()
1142 .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
1143 )
1144 .chain(
1145 data_b
1146 .auto_traits()
1147 .map(ty::ExistentialPredicate::AutoTrait)
1148 .map(ty::Binder::dummy),
1149 );
1150 let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
1151 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
1152
1153 let InferOk { mut obligations, .. } = self
1156 .infcx
1157 .at(&obligation.cause, obligation.param_env)
1158 .sup(DefineOpaqueTypes::Yes, target, source_trait)
1159 .map_err(|_| Unimplemented)?;
1160
1161 let outlives = ty::OutlivesPredicate(r_a, r_b);
1163 obligations.push(Obligation::with_depth(
1164 tcx,
1165 obligation.cause.clone(),
1166 obligation.recursion_depth + 1,
1167 obligation.param_env,
1168 obligation.predicate.rebind(outlives),
1169 ));
1170
1171 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1172 }
1173
1174 (_, &ty::Dynamic(data, r, ty::Dyn)) => {
1176 let mut object_dids = data.auto_traits().chain(data.principal_def_id());
1177 if let Some(did) = object_dids.find(|did| !tcx.is_dyn_compatible(*did)) {
1178 return Err(TraitDynIncompatible(did));
1179 }
1180
1181 let predicate_to_obligation = |predicate| {
1182 Obligation::with_depth(
1183 tcx,
1184 obligation.cause.clone(),
1185 obligation.recursion_depth + 1,
1186 obligation.param_env,
1187 predicate,
1188 )
1189 };
1190
1191 let mut nested: PredicateObligations<'_> = data
1198 .iter()
1199 .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source)))
1200 .collect();
1201
1202 let tr = ty::TraitRef::new(
1204 tcx,
1205 tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
1206 [source],
1207 );
1208 nested.push(predicate_to_obligation(tr.upcast(tcx)));
1209
1210 let outlives = ty::OutlivesPredicate(source, r);
1213 nested.push(predicate_to_obligation(
1214 ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
1215 ));
1216
1217 if let Some(principal) = data.principal() {
1220 for supertrait in
1221 elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
1222 {
1223 if tcx.is_trait_alias(supertrait.def_id()) {
1224 continue;
1225 }
1226
1227 for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
1228 if !tcx.is_impl_trait_in_trait(assoc_item) {
1229 continue;
1230 }
1231
1232 if tcx.generics_require_sized_self(assoc_item) {
1234 continue;
1235 }
1236
1237 let pointer_like_goal = pointer_like_goal_for_rpitit(
1238 tcx,
1239 supertrait,
1240 assoc_item,
1241 &obligation.cause,
1242 );
1243
1244 nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
1245 }
1246 }
1247 }
1248
1249 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1250 }
1251
1252 (&ty::Array(a, _), &ty::Slice(b)) => {
1254 let InferOk { obligations, .. } = self
1255 .infcx
1256 .at(&obligation.cause, obligation.param_env)
1257 .eq(DefineOpaqueTypes::Yes, b, a)
1258 .map_err(|_| Unimplemented)?;
1259
1260 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1261 }
1262
1263 (&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => {
1265 let unsizing_params = tcx.unsizing_params_for_adt(def.did());
1266 if unsizing_params.is_empty() {
1267 return Err(Unimplemented);
1268 }
1269
1270 let tail_field = def.non_enum_variant().tail();
1271 let tail_field_ty = tcx.type_of(tail_field.did);
1272
1273 let mut nested = PredicateObligations::new();
1274
1275 let source_tail = normalize_with_depth_to(
1279 self,
1280 obligation.param_env,
1281 obligation.cause.clone(),
1282 obligation.recursion_depth + 1,
1283 tail_field_ty.instantiate(tcx, args_a),
1284 &mut nested,
1285 );
1286 let target_tail = normalize_with_depth_to(
1287 self,
1288 obligation.param_env,
1289 obligation.cause.clone(),
1290 obligation.recursion_depth + 1,
1291 tail_field_ty.instantiate(tcx, args_b),
1292 &mut nested,
1293 );
1294
1295 let args =
1298 tcx.mk_args_from_iter(args_a.iter().enumerate().map(|(i, k)| {
1299 if unsizing_params.contains(i as u32) { args_b[i] } else { k }
1300 }));
1301 let new_struct = Ty::new_adt(tcx, def, args);
1302 let InferOk { obligations, .. } = self
1303 .infcx
1304 .at(&obligation.cause, obligation.param_env)
1305 .eq(DefineOpaqueTypes::Yes, target, new_struct)
1306 .map_err(|_| Unimplemented)?;
1307 nested.extend(obligations);
1308
1309 let tail_unsize_obligation = obligation.with(
1311 tcx,
1312 ty::TraitRef::new(
1313 tcx,
1314 obligation.predicate.def_id(),
1315 [source_tail, target_tail],
1316 ),
1317 );
1318 nested.push(tail_unsize_obligation);
1319
1320 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1321 }
1322
1323 (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
1325 assert_eq!(tys_a.len(), tys_b.len());
1326
1327 let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
1329 let &b_last = tys_b.last().unwrap();
1330
1331 let new_tuple =
1334 Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last)));
1335 let InferOk { mut obligations, .. } = self
1336 .infcx
1337 .at(&obligation.cause, obligation.param_env)
1338 .eq(DefineOpaqueTypes::Yes, target, new_tuple)
1339 .map_err(|_| Unimplemented)?;
1340
1341 let last_unsize_obligation = obligation.with(
1343 tcx,
1344 ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
1345 );
1346 obligations.push(last_unsize_obligation);
1347
1348 ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, obligations)
1349 }
1350
1351 _ => bug!("source: {source}, target: {target}"),
1352 })
1353 }
1354
1355 fn confirm_bikeshed_guaranteed_no_drop_candidate(
1356 &mut self,
1357 obligation: &PolyTraitObligation<'tcx>,
1358 ) -> ImplSource<'tcx, PredicateObligation<'tcx>> {
1359 let mut obligations = thin_vec![];
1360
1361 let tcx = self.tcx();
1362 let self_ty = obligation.predicate.self_ty();
1363 match *self_ty.skip_binder().kind() {
1364 ty::Ref(..) => {}
1366 ty::Adt(def, _) if def.is_manually_drop() => {}
1368 ty::Tuple(tys) => {
1371 obligations.extend(tys.iter().map(|elem_ty| {
1372 obligation.with(
1373 tcx,
1374 self_ty.rebind(ty::TraitRef::new(
1375 tcx,
1376 obligation.predicate.def_id(),
1377 [elem_ty],
1378 )),
1379 )
1380 }));
1381 }
1382 ty::Array(elem_ty, _) => {
1383 obligations.push(obligation.with(
1384 tcx,
1385 self_ty.rebind(ty::TraitRef::new(
1386 tcx,
1387 obligation.predicate.def_id(),
1388 [elem_ty],
1389 )),
1390 ));
1391 }
1392
1393 ty::FnDef(..)
1397 | ty::FnPtr(..)
1398 | ty::Error(_)
1399 | ty::Uint(_)
1400 | ty::Int(_)
1401 | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1402 | ty::Bool
1403 | ty::Float(_)
1404 | ty::Char
1405 | ty::RawPtr(..)
1406 | ty::Never
1407 | ty::Pat(..)
1408 | ty::Dynamic(..)
1409 | ty::Str
1410 | ty::Slice(_)
1411 | ty::Foreign(..)
1412 | ty::Adt(..)
1413 | ty::Alias(..)
1414 | ty::Param(_)
1415 | ty::Placeholder(..)
1416 | ty::Closure(..)
1417 | ty::CoroutineClosure(..)
1418 | ty::Coroutine(..)
1419 | ty::UnsafeBinder(_)
1420 | ty::CoroutineWitness(..)
1421 | ty::Bound(..) => {
1422 obligations.push(obligation.with(
1423 tcx,
1424 self_ty.map_bound(|ty| {
1425 ty::TraitRef::new(
1426 tcx,
1427 tcx.require_lang_item(LangItem::Copy, Some(obligation.cause.span)),
1428 [ty],
1429 )
1430 }),
1431 ));
1432 }
1433
1434 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1435 panic!("unexpected type `{self_ty:?}`")
1436 }
1437 }
1438
1439 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1440 }
1441}
1442
1443fn pointer_like_goal_for_rpitit<'tcx>(
1453 tcx: TyCtxt<'tcx>,
1454 supertrait: ty::PolyTraitRef<'tcx>,
1455 rpitit_item: DefId,
1456 cause: &ObligationCause<'tcx>,
1457) -> ty::PolyTraitRef<'tcx> {
1458 let mut bound_vars = supertrait.bound_vars().to_vec();
1459
1460 let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
1461 ty::GenericParamDefKind::Lifetime => {
1462 let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
1463 bound_vars.push(ty::BoundVariableKind::Region(kind));
1464 ty::Region::new_bound(
1465 tcx,
1466 ty::INNERMOST,
1467 ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1468 )
1469 .into()
1470 }
1471 ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
1472 unreachable!()
1473 }
1474 });
1475
1476 ty::Binder::bind_with_vars(
1477 ty::TraitRef::new(
1478 tcx,
1479 tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)),
1480 [Ty::new_projection_from_args(tcx, rpitit_item, args)],
1481 ),
1482 tcx.mk_bound_variable_kinds(&bound_vars),
1483 )
1484}