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