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