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