1use std::ops::ControlFlow;
11
12use rustc_data_structures::stack::ensure_sufficient_stack;
13use rustc_hir::lang_items::LangItem;
14use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
15use rustc_infer::traits::ObligationCauseCode;
16use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
17use rustc_middle::ty::{
18 self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate,
19};
20use rustc_middle::{bug, span_bug};
21use rustc_span::def_id::DefId;
22use thin_vec::thin_vec;
23use tracing::{debug, instrument};
24
25use super::SelectionCandidate::{self, *};
26use super::{BuiltinImplConditions, PredicateObligations, SelectionContext};
27use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
28use crate::traits::util::{self, closure_trait_ref_and_return_type};
29use crate::traits::{
30 ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
31 PolyTraitObligation, PredicateObligation, Selection, SelectionError, SignatureMismatch,
32 TraitDynIncompatible, TraitObligation, Unimplemented,
33};
34
35impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
36 #[instrument(level = "debug", skip(self))]
37 pub(super) fn confirm_candidate(
38 &mut self,
39 obligation: &PolyTraitObligation<'tcx>,
40 candidate: SelectionCandidate<'tcx>,
41 ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
42 Ok(match candidate {
43 SizedCandidate { has_nested } => {
44 let data = self.confirm_builtin_candidate(obligation, has_nested);
45 ImplSource::Builtin(BuiltinImplSource::Misc, data)
46 }
47
48 BuiltinCandidate { has_nested } => {
49 let data = self.confirm_builtin_candidate(obligation, has_nested);
50 ImplSource::Builtin(BuiltinImplSource::Misc, data)
51 }
52
53 TransmutabilityCandidate => {
54 let data = self.confirm_transmutability_candidate(obligation)?;
55 ImplSource::Builtin(BuiltinImplSource::Misc, data)
56 }
57
58 ParamCandidate(param) => {
59 let obligations =
60 self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
61 ImplSource::Param(obligations)
62 }
63
64 ImplCandidate(impl_def_id) => {
65 ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))
66 }
67
68 AutoImplCandidate => {
69 let data = self.confirm_auto_impl_candidate(obligation)?;
70 ImplSource::Builtin(BuiltinImplSource::Misc, data)
71 }
72
73 ProjectionCandidate(idx) => {
74 let obligations = self.confirm_projection_candidate(obligation, idx)?;
75 ImplSource::Param(obligations)
76 }
77
78 ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?,
79
80 ClosureCandidate { .. } => {
81 let vtable_closure = self.confirm_closure_candidate(obligation)?;
82 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
83 }
84
85 AsyncClosureCandidate => {
86 let vtable_closure = self.confirm_async_closure_candidate(obligation)?;
87 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
88 }
89
90 AsyncFnKindHelperCandidate => {
93 ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
94 }
95
96 CoroutineCandidate => {
97 let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?;
98 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_coroutine)
99 }
100
101 FutureCandidate => {
102 let vtable_future = self.confirm_future_candidate(obligation)?;
103 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_future)
104 }
105
106 IteratorCandidate => {
107 let vtable_iterator = self.confirm_iterator_candidate(obligation)?;
108 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
109 }
110
111 AsyncIteratorCandidate => {
112 let vtable_iterator = self.confirm_async_iterator_candidate(obligation)?;
113 ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
114 }
115
116 FnPointerCandidate => {
117 let data = self.confirm_fn_pointer_candidate(obligation)?;
118 ImplSource::Builtin(BuiltinImplSource::Misc, data)
119 }
120
121 TraitAliasCandidate => {
122 let data = self.confirm_trait_alias_candidate(obligation);
123 ImplSource::Builtin(BuiltinImplSource::Misc, data)
124 }
125
126 BuiltinObjectCandidate => {
127 ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
131 }
132
133 BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?,
134
135 TraitUpcastingUnsizeCandidate(idx) => {
136 self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?
137 }
138
139 BikeshedGuaranteedNoDropCandidate => {
140 self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
141 }
142 })
143 }
144
145 fn confirm_projection_candidate(
146 &mut self,
147 obligation: &PolyTraitObligation<'tcx>,
148 idx: usize,
149 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
150 let tcx = self.tcx();
151
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 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(|_| Unimplemented)?,
198 );
199
200 if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
202 let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
203 for (predicate, _) in predicates {
204 let normalized = normalize_with_depth_to(
205 self,
206 obligation.param_env,
207 obligation.cause.clone(),
208 obligation.recursion_depth + 1,
209 predicate,
210 &mut obligations,
211 );
212 obligations.push(Obligation::with_depth(
213 self.tcx(),
214 obligation.cause.clone(),
215 obligation.recursion_depth + 1,
216 obligation.param_env,
217 normalized,
218 ));
219 }
220 }
221
222 Ok(obligations)
223 }
224
225 fn confirm_param_candidate(
226 &mut self,
227 obligation: &PolyTraitObligation<'tcx>,
228 param: ty::PolyTraitRef<'tcx>,
229 ) -> PredicateObligations<'tcx> {
230 debug!(?obligation, ?param, "confirm_param_candidate");
231
232 let param = util::lazily_elaborate_sizedness_candidate(
233 self.infcx,
234 obligation,
235 param.upcast(self.infcx.tcx),
236 )
237 .map_bound(|p| p.trait_ref);
238
239 match self.match_where_clause_trait_ref(obligation, param) {
244 Ok(obligations) => obligations,
245 Err(()) => {
246 bug!(
247 "Where clause `{:?}` was applicable to `{:?}` but now is not",
248 param,
249 obligation
250 );
251 }
252 }
253 }
254
255 fn confirm_builtin_candidate(
256 &mut self,
257 obligation: &PolyTraitObligation<'tcx>,
258 has_nested: bool,
259 ) -> PredicateObligations<'tcx> {
260 debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
261
262 let tcx = self.tcx();
263 let obligations = if has_nested {
264 let trait_def = obligation.predicate.def_id();
265 let conditions = match tcx.as_lang_item(trait_def) {
266 Some(LangItem::Sized) => {
267 self.sizedness_conditions(obligation, SizedTraitKind::Sized)
268 }
269 Some(LangItem::MetaSized) => {
270 self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
271 }
272 Some(LangItem::PointeeSized) => {
273 bug!("`PointeeSized` is removing during lowering");
274 }
275 Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
276 Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
277 other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
278 };
279 let BuiltinImplConditions::Where(types) = conditions else {
280 bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
281 };
282 let types = self.infcx.enter_forall_and_leak_universe(types);
283
284 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
285 self.collect_predicates_for_types(
286 obligation.param_env,
287 cause,
288 obligation.recursion_depth + 1,
289 trait_def,
290 types,
291 )
292 } else {
293 PredicateObligations::new()
294 };
295
296 debug!(?obligations);
297
298 obligations
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(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(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
413 let types = self.constituent_types_for_ty(self_ty)?;
414 let types = self.infcx.enter_forall_and_leak_universe(types);
415
416 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
417 let obligations = self.collect_predicates_for_types(
418 obligation.param_env,
419 cause,
420 obligation.recursion_depth + 1,
421 obligation.predicate.def_id(),
422 types,
423 );
424
425 Ok(obligations)
426 })
427 }
428
429 fn confirm_impl_candidate(
430 &mut self,
431 obligation: &PolyTraitObligation<'tcx>,
432 impl_def_id: DefId,
433 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
434 debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
435
436 let args = self.rematch_impl(impl_def_id, obligation);
439 debug!(?args, "impl args");
440 ensure_sufficient_stack(|| {
441 self.vtable_impl(
442 impl_def_id,
443 args,
444 &obligation.cause,
445 obligation.recursion_depth + 1,
446 obligation.param_env,
447 obligation.predicate,
448 )
449 })
450 }
451
452 fn vtable_impl(
453 &mut self,
454 impl_def_id: DefId,
455 args: Normalized<'tcx, GenericArgsRef<'tcx>>,
456 cause: &ObligationCause<'tcx>,
457 recursion_depth: usize,
458 param_env: ty::ParamEnv<'tcx>,
459 parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
460 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
461 debug!(?impl_def_id, ?args, ?recursion_depth, "vtable_impl");
462
463 let mut impl_obligations = self.impl_or_trait_obligations(
464 cause,
465 recursion_depth,
466 param_env,
467 impl_def_id,
468 args.value,
469 parent_trait_pred,
470 );
471
472 debug!(?impl_obligations, "vtable_impl");
473
474 impl_obligations.extend(args.obligations);
480
481 ImplSourceUserDefinedData { impl_def_id, args: args.value, nested: impl_obligations }
482 }
483
484 fn confirm_object_candidate(
485 &mut self,
486 obligation: &PolyTraitObligation<'tcx>,
487 index: usize,
488 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
489 let tcx = self.tcx();
490 debug!(?obligation, ?index, "confirm_object_candidate");
491
492 let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
493 let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
494 let ty::Dynamic(data, ..) = *self_ty.kind() else {
495 span_bug!(obligation.cause.span, "object candidate with non-object");
496 };
497
498 let object_trait_ref = data.principal().unwrap_or_else(|| {
499 span_bug!(obligation.cause.span, "object candidate with no principal")
500 });
501 let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
502 obligation.cause.span,
503 HigherRankedType,
504 object_trait_ref,
505 );
506 let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty);
507
508 let mut nested = PredicateObligations::new();
509
510 let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref));
511 let unnormalized_upcast_trait_ref =
512 supertraits.nth(index).expect("supertraits iterator no longer has as many elements");
513
514 let upcast_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
515 obligation.cause.span,
516 HigherRankedType,
517 unnormalized_upcast_trait_ref,
518 );
519 let upcast_trait_ref = normalize_with_depth_to(
520 self,
521 obligation.param_env,
522 obligation.cause.clone(),
523 obligation.recursion_depth + 1,
524 upcast_trait_ref,
525 &mut nested,
526 );
527
528 nested.extend(
529 self.infcx
530 .at(&obligation.cause, obligation.param_env)
531 .eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref)
532 .map(|InferOk { obligations, .. }| obligations)
533 .map_err(|_| Unimplemented)?,
534 );
535
536 for (supertrait, _) in tcx
539 .explicit_super_predicates_of(trait_predicate.def_id())
540 .iter_instantiated_copied(tcx, trait_predicate.trait_ref.args)
541 {
542 let normalized_supertrait = normalize_with_depth_to(
543 self,
544 obligation.param_env,
545 obligation.cause.clone(),
546 obligation.recursion_depth + 1,
547 supertrait,
548 &mut nested,
549 );
550 nested.push(obligation.with(tcx, normalized_supertrait));
551 }
552
553 let assoc_types: Vec<_> = tcx
554 .associated_items(trait_predicate.def_id())
555 .in_definition_order()
556 .filter(|item| !tcx.generics_require_sized_self(item.def_id))
559 .filter_map(|item| if item.is_type() { Some(item.def_id) } else { None })
560 .collect();
561
562 for assoc_type in assoc_types {
563 let defs: &ty::Generics = tcx.generics_of(assoc_type);
564
565 if !defs.own_params.is_empty() {
566 tcx.dcx().span_delayed_bug(
567 obligation.cause.span,
568 "GATs in trait object shouldn't have been considered",
569 );
570 return Err(SelectionError::TraitDynIncompatible(trait_predicate.trait_ref.def_id));
571 }
572
573 for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
577 let normalized_bound = normalize_with_depth_to(
578 self,
579 obligation.param_env,
580 obligation.cause.clone(),
581 obligation.recursion_depth + 1,
582 bound.instantiate(tcx, trait_predicate.trait_ref.args),
583 &mut nested,
584 );
585 nested.push(obligation.with(tcx, normalized_bound));
586 }
587 }
588
589 debug!(?nested, "object nested obligations");
590
591 Ok(ImplSource::Builtin(BuiltinImplSource::Object(index), nested))
592 }
593
594 fn confirm_fn_pointer_candidate(
595 &mut self,
596 obligation: &PolyTraitObligation<'tcx>,
597 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
598 debug!(?obligation, "confirm_fn_pointer_candidate");
599 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
600 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
601
602 let tcx = self.tcx();
603 let sig = self_ty.fn_sig(tcx);
604 let trait_ref = closure_trait_ref_and_return_type(
605 tcx,
606 obligation.predicate.def_id(),
607 self_ty,
608 sig,
609 util::TupleArgumentsFlag::Yes,
610 )
611 .map_bound(|(trait_ref, _)| trait_ref);
612
613 let mut nested =
614 self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?;
615 let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
616
617 let output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
619 let output_ty = normalize_with_depth_to(
620 self,
621 obligation.param_env,
622 cause.clone(),
623 obligation.recursion_depth,
624 output_ty,
625 &mut nested,
626 );
627 let tr = ty::TraitRef::new(
628 self.tcx(),
629 self.tcx().require_lang_item(LangItem::Sized, cause.span),
630 [output_ty],
631 );
632 nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
633
634 Ok(nested)
635 }
636
637 fn confirm_trait_alias_candidate(
638 &mut self,
639 obligation: &PolyTraitObligation<'tcx>,
640 ) -> PredicateObligations<'tcx> {
641 debug!(?obligation, "confirm_trait_alias_candidate");
642
643 let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
644 let trait_ref = predicate.trait_ref;
645 let trait_def_id = trait_ref.def_id;
646 let args = trait_ref.args;
647
648 let trait_obligations = self.impl_or_trait_obligations(
649 &obligation.cause,
650 obligation.recursion_depth,
651 obligation.param_env,
652 trait_def_id,
653 args,
654 obligation.predicate,
655 );
656
657 debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
658
659 trait_obligations
660 }
661
662 fn confirm_coroutine_candidate(
663 &mut self,
664 obligation: &PolyTraitObligation<'tcx>,
665 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
666 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
667 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
668 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
669 bug!("closure candidate for non-closure {:?}", obligation);
670 };
671
672 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_coroutine_candidate");
673
674 let coroutine_sig = args.as_coroutine().sig();
675
676 let (trait_ref, _, _) = super::util::coroutine_trait_ref_and_outputs(
677 self.tcx(),
678 obligation.predicate.def_id(),
679 self_ty,
680 coroutine_sig,
681 );
682
683 let nested = self.equate_trait_refs(
684 obligation.with(self.tcx(), placeholder_predicate),
685 ty::Binder::dummy(trait_ref),
686 )?;
687 debug!(?trait_ref, ?nested, "coroutine candidate obligations");
688
689 Ok(nested)
690 }
691
692 fn confirm_future_candidate(
693 &mut self,
694 obligation: &PolyTraitObligation<'tcx>,
695 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
696 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
697 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
698 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
699 bug!("closure candidate for non-closure {:?}", obligation);
700 };
701
702 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_future_candidate");
703
704 let coroutine_sig = args.as_coroutine().sig();
705
706 let (trait_ref, _) = super::util::future_trait_ref_and_outputs(
707 self.tcx(),
708 obligation.predicate.def_id(),
709 self_ty,
710 coroutine_sig,
711 );
712
713 let nested = self.equate_trait_refs(
714 obligation.with(self.tcx(), placeholder_predicate),
715 ty::Binder::dummy(trait_ref),
716 )?;
717 debug!(?trait_ref, ?nested, "future candidate obligations");
718
719 Ok(nested)
720 }
721
722 fn confirm_iterator_candidate(
723 &mut self,
724 obligation: &PolyTraitObligation<'tcx>,
725 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
726 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
727 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
728 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
729 bug!("closure candidate for non-closure {:?}", obligation);
730 };
731
732 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_iterator_candidate");
733
734 let gen_sig = args.as_coroutine().sig();
735
736 let (trait_ref, _) = super::util::iterator_trait_ref_and_outputs(
737 self.tcx(),
738 obligation.predicate.def_id(),
739 self_ty,
740 gen_sig,
741 );
742
743 let nested = self.equate_trait_refs(
744 obligation.with(self.tcx(), placeholder_predicate),
745 ty::Binder::dummy(trait_ref),
746 )?;
747 debug!(?trait_ref, ?nested, "iterator candidate obligations");
748
749 Ok(nested)
750 }
751
752 fn confirm_async_iterator_candidate(
753 &mut self,
754 obligation: &PolyTraitObligation<'tcx>,
755 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
756 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
757 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
758 let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
759 bug!("closure candidate for non-closure {:?}", obligation);
760 };
761
762 debug!(?obligation, ?coroutine_def_id, ?args, "confirm_async_iterator_candidate");
763
764 let gen_sig = args.as_coroutine().sig();
765
766 let (trait_ref, _) = super::util::async_iterator_trait_ref_and_outputs(
767 self.tcx(),
768 obligation.predicate.def_id(),
769 self_ty,
770 gen_sig,
771 );
772
773 let nested = self.equate_trait_refs(
774 obligation.with(self.tcx(), placeholder_predicate),
775 ty::Binder::dummy(trait_ref),
776 )?;
777 debug!(?trait_ref, ?nested, "iterator candidate obligations");
778
779 Ok(nested)
780 }
781
782 #[instrument(skip(self), level = "debug")]
783 fn confirm_closure_candidate(
784 &mut self,
785 obligation: &PolyTraitObligation<'tcx>,
786 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
787 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
788 let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
789
790 let trait_ref = match *self_ty.kind() {
791 ty::Closure(..) => {
792 self.closure_trait_ref_unnormalized(self_ty, obligation.predicate.def_id())
793 }
794 ty::CoroutineClosure(_, args) => {
795 args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
796 ty::TraitRef::new(
797 self.tcx(),
798 obligation.predicate.def_id(),
799 [self_ty, sig.tupled_inputs_ty],
800 )
801 })
802 }
803 _ => {
804 bug!("closure candidate for non-closure {:?}", obligation);
805 }
806 };
807
808 self.equate_trait_refs(obligation.with(self.tcx(), placeholder_predicate), trait_ref)
809 }
810
811 #[instrument(skip(self), level = "debug")]
812 fn confirm_async_closure_candidate(
813 &mut self,
814 obligation: &PolyTraitObligation<'tcx>,
815 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
816 let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
817 let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
818
819 let tcx = self.tcx();
820
821 let mut nested = PredicateObligations::new();
822 let (trait_ref, kind_ty) = match *self_ty.kind() {
823 ty::CoroutineClosure(_, args) => {
824 let args = args.as_coroutine_closure();
825 let trait_ref = args.coroutine_closure_sig().map_bound(|sig| {
826 ty::TraitRef::new(
827 self.tcx(),
828 obligation.predicate.def_id(),
829 [self_ty, sig.tupled_inputs_ty],
830 )
831 });
832
833 (trait_ref, args.kind_ty())
837 }
838 ty::FnDef(..) | ty::FnPtr(..) => {
839 let sig = self_ty.fn_sig(tcx);
840 let trait_ref = sig.map_bound(|sig| {
841 ty::TraitRef::new(
842 self.tcx(),
843 obligation.predicate.def_id(),
844 [self_ty, Ty::new_tup(tcx, sig.inputs())],
845 )
846 });
847
848 let future_trait_def_id =
850 tcx.require_lang_item(LangItem::Future, obligation.cause.span);
851 nested.push(obligation.with(
852 tcx,
853 sig.output().map_bound(|output_ty| {
854 ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
855 }),
856 ));
857 let sized_trait_def_id =
858 tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
859 nested.push(obligation.with(
860 tcx,
861 sig.output().map_bound(|output_ty| {
862 ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
863 }),
864 ));
865
866 (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
867 }
868 ty::Closure(_, args) => {
869 let args = args.as_closure();
870 let sig = args.sig();
871 let trait_ref = sig.map_bound(|sig| {
872 ty::TraitRef::new(
873 self.tcx(),
874 obligation.predicate.def_id(),
875 [self_ty, sig.inputs()[0]],
876 )
877 });
878
879 let future_trait_def_id =
881 tcx.require_lang_item(LangItem::Future, obligation.cause.span);
882 let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
883 nested.push(obligation.with(
884 tcx,
885 ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
886 ));
887 let sized_trait_def_id =
888 tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
889 nested.push(obligation.with(
890 tcx,
891 sig.output().map_bound(|output_ty| {
892 ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
893 }),
894 ));
895
896 (trait_ref, args.kind_ty())
897 }
898 _ => bug!("expected callable type for AsyncFn candidate"),
899 };
900
901 nested.extend(
902 self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?,
903 );
904
905 let goal_kind =
906 self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
907
908 if let Some(closure_kind) = self.infcx.shallow_resolve(kind_ty).to_opt_closure_kind() {
912 if !closure_kind.extends(goal_kind) {
913 return Err(SelectionError::Unimplemented);
914 }
915 } else {
916 nested.push(Obligation::new(
917 self.tcx(),
918 obligation.derived_cause(ObligationCauseCode::BuiltinDerived),
919 obligation.param_env,
920 ty::TraitRef::new(
921 self.tcx(),
922 self.tcx()
923 .require_lang_item(LangItem::AsyncFnKindHelper, obligation.cause.span),
924 [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
925 ),
926 ));
927 }
928
929 Ok(nested)
930 }
931
932 #[instrument(skip(self), level = "trace")]
958 fn equate_trait_refs(
959 &mut self,
960 obligation: TraitObligation<'tcx>,
961 found_trait_ref: ty::PolyTraitRef<'tcx>,
962 ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
963 let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
964 obligation.cause.span,
965 HigherRankedType,
966 found_trait_ref,
967 );
968 let Normalized { obligations: nested, value: (obligation_trait_ref, found_trait_ref) } =
970 ensure_sufficient_stack(|| {
971 normalize_with_depth(
972 self,
973 obligation.param_env,
974 obligation.cause.clone(),
975 obligation.recursion_depth + 1,
976 (obligation.predicate.trait_ref, found_trait_ref),
977 )
978 });
979
980 self.infcx
982 .at(&obligation.cause, obligation.param_env)
983 .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
984 .map(|InferOk { mut obligations, .. }| {
985 obligations.extend(nested);
986 obligations
987 })
988 .map_err(|terr| {
989 SignatureMismatch(Box::new(SignatureMismatchData {
990 expected_trait_ref: obligation_trait_ref,
991 found_trait_ref,
992 terr,
993 }))
994 })
995 }
996
997 fn confirm_trait_upcasting_unsize_candidate(
998 &mut self,
999 obligation: &PolyTraitObligation<'tcx>,
1000 idx: usize,
1001 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1002 let tcx = self.tcx();
1003
1004 let predicate = obligation.predicate.no_bound_vars().unwrap();
1007 let a_ty = self.infcx.shallow_resolve(predicate.self_ty());
1008 let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1));
1009
1010 let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
1011 bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1012 };
1013 let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
1014 bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1015 };
1016
1017 let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty);
1018 let unnormalized_upcast_principal =
1019 util::supertraits(tcx, source_principal).nth(idx).unwrap();
1020
1021 let nested = self
1022 .match_upcast_principal(
1023 obligation,
1024 unnormalized_upcast_principal,
1025 a_data,
1026 b_data,
1027 a_region,
1028 b_region,
1029 )?
1030 .expect("did not expect ambiguity during confirmation");
1031
1032 Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting(idx), nested))
1033 }
1034
1035 fn confirm_builtin_unsize_candidate(
1036 &mut self,
1037 obligation: &PolyTraitObligation<'tcx>,
1038 ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1039 let tcx = self.tcx();
1040
1041 let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
1044 let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
1045 let target = self.infcx.shallow_resolve(target);
1046 debug!(?source, ?target, "confirm_builtin_unsize_candidate");
1047
1048 Ok(match (source.kind(), target.kind()) {
1049 (&ty::Dynamic(data_a, r_a, dyn_a), &ty::Dynamic(data_b, r_b, dyn_b))
1051 if dyn_a == dyn_b =>
1052 {
1053 let existential_predicates = if data_b.principal().is_some() {
1056 tcx.mk_poly_existential_predicates_from_iter(
1057 data_a
1058 .principal()
1059 .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
1060 .into_iter()
1061 .chain(
1062 data_a
1063 .projection_bounds()
1064 .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
1065 )
1066 .chain(
1067 data_b
1068 .auto_traits()
1069 .map(ty::ExistentialPredicate::AutoTrait)
1070 .map(ty::Binder::dummy),
1071 ),
1072 )
1073 } else {
1074 tcx.mk_poly_existential_predicates_from_iter(
1079 data_b
1080 .auto_traits()
1081 .map(ty::ExistentialPredicate::AutoTrait)
1082 .map(ty::Binder::dummy),
1083 )
1084 };
1085 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
1086
1087 let InferOk { mut obligations, .. } = self
1090 .infcx
1091 .at(&obligation.cause, obligation.param_env)
1092 .sup(DefineOpaqueTypes::Yes, target, source_trait)
1093 .map_err(|_| Unimplemented)?;
1094
1095 let outlives = ty::OutlivesPredicate(r_a, r_b);
1097 obligations.push(Obligation::with_depth(
1098 tcx,
1099 obligation.cause.clone(),
1100 obligation.recursion_depth + 1,
1101 obligation.param_env,
1102 obligation.predicate.rebind(outlives),
1103 ));
1104
1105 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1106 }
1107
1108 (_, &ty::Dynamic(data, r, ty::Dyn)) => {
1110 let mut object_dids = data.auto_traits().chain(data.principal_def_id());
1111 if let Some(did) = object_dids.find(|did| !tcx.is_dyn_compatible(*did)) {
1112 return Err(TraitDynIncompatible(did));
1113 }
1114
1115 let predicate_to_obligation = |predicate| {
1116 Obligation::with_depth(
1117 tcx,
1118 obligation.cause.clone(),
1119 obligation.recursion_depth + 1,
1120 obligation.param_env,
1121 predicate,
1122 )
1123 };
1124
1125 let mut nested: PredicateObligations<'_> = data
1132 .iter()
1133 .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source)))
1134 .collect();
1135
1136 let tr = ty::TraitRef::new(
1138 tcx,
1139 tcx.require_lang_item(LangItem::Sized, obligation.cause.span),
1140 [source],
1141 );
1142 nested.push(predicate_to_obligation(tr.upcast(tcx)));
1143
1144 let outlives = ty::OutlivesPredicate(source, r);
1147 nested.push(predicate_to_obligation(
1148 ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
1149 ));
1150
1151 if let Some(principal) = data.principal() {
1154 for supertrait in
1155 elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
1156 {
1157 if tcx.is_trait_alias(supertrait.def_id()) {
1158 continue;
1159 }
1160
1161 for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
1162 if !tcx.is_impl_trait_in_trait(assoc_item) {
1163 continue;
1164 }
1165
1166 if tcx.generics_require_sized_self(assoc_item) {
1168 continue;
1169 }
1170
1171 let pointer_like_goal = pointer_like_goal_for_rpitit(
1172 tcx,
1173 supertrait,
1174 assoc_item,
1175 &obligation.cause,
1176 );
1177
1178 nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
1179 }
1180 }
1181 }
1182
1183 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1184 }
1185
1186 (&ty::Array(a, _), &ty::Slice(b)) => {
1188 let InferOk { obligations, .. } = self
1189 .infcx
1190 .at(&obligation.cause, obligation.param_env)
1191 .eq(DefineOpaqueTypes::Yes, b, a)
1192 .map_err(|_| Unimplemented)?;
1193
1194 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1195 }
1196
1197 (&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => {
1199 let unsizing_params = tcx.unsizing_params_for_adt(def.did());
1200 if unsizing_params.is_empty() {
1201 return Err(Unimplemented);
1202 }
1203
1204 let tail_field = def.non_enum_variant().tail();
1205 let tail_field_ty = tcx.type_of(tail_field.did);
1206
1207 let mut nested = PredicateObligations::new();
1208
1209 let source_tail = normalize_with_depth_to(
1213 self,
1214 obligation.param_env,
1215 obligation.cause.clone(),
1216 obligation.recursion_depth + 1,
1217 tail_field_ty.instantiate(tcx, args_a),
1218 &mut nested,
1219 );
1220 let target_tail = normalize_with_depth_to(
1221 self,
1222 obligation.param_env,
1223 obligation.cause.clone(),
1224 obligation.recursion_depth + 1,
1225 tail_field_ty.instantiate(tcx, args_b),
1226 &mut nested,
1227 );
1228
1229 let args =
1232 tcx.mk_args_from_iter(args_a.iter().enumerate().map(|(i, k)| {
1233 if unsizing_params.contains(i as u32) { args_b[i] } else { k }
1234 }));
1235 let new_struct = Ty::new_adt(tcx, def, args);
1236 let InferOk { obligations, .. } = self
1237 .infcx
1238 .at(&obligation.cause, obligation.param_env)
1239 .eq(DefineOpaqueTypes::Yes, target, new_struct)
1240 .map_err(|_| Unimplemented)?;
1241 nested.extend(obligations);
1242
1243 let tail_unsize_obligation = obligation.with(
1245 tcx,
1246 ty::TraitRef::new(
1247 tcx,
1248 obligation.predicate.def_id(),
1249 [source_tail, target_tail],
1250 ),
1251 );
1252 nested.push(tail_unsize_obligation);
1253
1254 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1255 }
1256
1257 _ => bug!("source: {source}, target: {target}"),
1258 })
1259 }
1260
1261 fn confirm_bikeshed_guaranteed_no_drop_candidate(
1262 &mut self,
1263 obligation: &PolyTraitObligation<'tcx>,
1264 ) -> ImplSource<'tcx, PredicateObligation<'tcx>> {
1265 let mut obligations = thin_vec![];
1266
1267 let tcx = self.tcx();
1268 let self_ty = obligation.predicate.self_ty();
1269 match *self_ty.skip_binder().kind() {
1270 ty::Ref(..) => {}
1272 ty::Adt(def, _) if def.is_manually_drop() => {}
1274 ty::Tuple(tys) => {
1277 obligations.extend(tys.iter().map(|elem_ty| {
1278 obligation.with(
1279 tcx,
1280 self_ty.rebind(ty::TraitRef::new(
1281 tcx,
1282 obligation.predicate.def_id(),
1283 [elem_ty],
1284 )),
1285 )
1286 }));
1287 }
1288 ty::Array(elem_ty, _) => {
1289 obligations.push(obligation.with(
1290 tcx,
1291 self_ty.rebind(ty::TraitRef::new(
1292 tcx,
1293 obligation.predicate.def_id(),
1294 [elem_ty],
1295 )),
1296 ));
1297 }
1298
1299 ty::FnDef(..)
1303 | ty::FnPtr(..)
1304 | ty::Error(_)
1305 | ty::Uint(_)
1306 | ty::Int(_)
1307 | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1308 | ty::Bool
1309 | ty::Float(_)
1310 | ty::Char
1311 | ty::RawPtr(..)
1312 | ty::Never
1313 | ty::Pat(..)
1314 | ty::Dynamic(..)
1315 | ty::Str
1316 | ty::Slice(_)
1317 | ty::Foreign(..)
1318 | ty::Adt(..)
1319 | ty::Alias(..)
1320 | ty::Param(_)
1321 | ty::Placeholder(..)
1322 | ty::Closure(..)
1323 | ty::CoroutineClosure(..)
1324 | ty::Coroutine(..)
1325 | ty::UnsafeBinder(_)
1326 | ty::CoroutineWitness(..)
1327 | ty::Bound(..) => {
1328 obligations.push(obligation.with(
1329 tcx,
1330 self_ty.map_bound(|ty| {
1331 ty::TraitRef::new(
1332 tcx,
1333 tcx.require_lang_item(LangItem::Copy, obligation.cause.span),
1334 [ty],
1335 )
1336 }),
1337 ));
1338 }
1339
1340 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1341 panic!("unexpected type `{self_ty:?}`")
1342 }
1343 }
1344
1345 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1346 }
1347}
1348
1349fn pointer_like_goal_for_rpitit<'tcx>(
1359 tcx: TyCtxt<'tcx>,
1360 supertrait: ty::PolyTraitRef<'tcx>,
1361 rpitit_item: DefId,
1362 cause: &ObligationCause<'tcx>,
1363) -> ty::PolyTraitRef<'tcx> {
1364 let mut bound_vars = supertrait.bound_vars().to_vec();
1365
1366 let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
1367 ty::GenericParamDefKind::Lifetime => {
1368 let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
1369 bound_vars.push(ty::BoundVariableKind::Region(kind));
1370 ty::Region::new_bound(
1371 tcx,
1372 ty::INNERMOST,
1373 ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1374 )
1375 .into()
1376 }
1377 ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
1378 unreachable!()
1379 }
1380 });
1381
1382 ty::Binder::bind_with_vars(
1383 ty::TraitRef::new(
1384 tcx,
1385 tcx.require_lang_item(LangItem::PointerLike, cause.span),
1386 [Ty::new_projection_from_args(tcx, rpitit_item, args)],
1387 ),
1388 tcx.mk_bound_variable_kinds(&bound_vars),
1389 )
1390}