rustc_trait_selection/traits/select/
candidate_assembly.rs

1//! Candidate assembly.
2//!
3//! The selection process begins by examining all in-scope impls,
4//! caller obligations, and so forth and assembling a list of
5//! candidates. See the [rustc dev guide] for more details.
6//!
7//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
8
9use std::ops::ControlFlow;
10
11use hir::LangItem;
12use hir::def_id::DefId;
13use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
14use rustc_hir as hir;
15use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
16use rustc_middle::ty::fast_reject::DeepRejectCtxt;
17use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate};
18use rustc_middle::{bug, span_bug};
19use tracing::{debug, instrument, trace};
20
21use super::SelectionCandidate::*;
22use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
23use crate::traits::util;
24
25impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
26    #[instrument(skip(self, stack), level = "debug")]
27    pub(super) fn assemble_candidates<'o>(
28        &mut self,
29        stack: &TraitObligationStack<'o, 'tcx>,
30    ) -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>> {
31        let TraitObligationStack { obligation, .. } = *stack;
32        let obligation = &Obligation {
33            param_env: obligation.param_env,
34            cause: obligation.cause.clone(),
35            recursion_depth: obligation.recursion_depth,
36            predicate: self.infcx.resolve_vars_if_possible(obligation.predicate),
37        };
38
39        if obligation.predicate.skip_binder().self_ty().is_ty_var() {
40            debug!(ty = ?obligation.predicate.skip_binder().self_ty(), "ambiguous inference var or opaque type");
41            // Self is a type variable (e.g., `_: AsRef<str>`).
42            //
43            // This is somewhat problematic, as the current scheme can't really
44            // handle it turning to be a projection. This does end up as truly
45            // ambiguous in most cases anyway.
46            //
47            // Take the fast path out - this also improves
48            // performance by preventing assemble_candidates_from_impls from
49            // matching every impl for this trait.
50            return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true });
51        }
52
53        let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
54
55        // Negative trait predicates have different rules than positive trait predicates.
56        if obligation.polarity() == ty::PredicatePolarity::Negative {
57            self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
58            self.assemble_candidates_from_impls(obligation, &mut candidates);
59            self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
60        } else {
61            self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
62
63            // Other bounds. Consider both in-scope bounds from fn decl
64            // and applicable impls. There is a certain set of precedence rules here.
65            let def_id = obligation.predicate.def_id();
66            let tcx = self.tcx();
67
68            let lang_item = tcx.as_lang_item(def_id);
69            match lang_item {
70                Some(LangItem::Copy | LangItem::Clone) => {
71                    debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
72
73                    // User-defined copy impls are permitted, but only for
74                    // structs and enums.
75                    self.assemble_candidates_from_impls(obligation, &mut candidates);
76
77                    // For other types, we'll use the builtin rules.
78                    let copy_conditions = self.copy_clone_conditions(obligation);
79                    self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
80                }
81                Some(LangItem::DiscriminantKind) => {
82                    // `DiscriminantKind` is automatically implemented for every type.
83                    candidates.vec.push(BuiltinCandidate { has_nested: false });
84                }
85                Some(LangItem::PointeeTrait) => {
86                    // `Pointee` is automatically implemented for every type.
87                    candidates.vec.push(BuiltinCandidate { has_nested: false });
88                }
89                Some(LangItem::Sized) => {
90                    self.assemble_builtin_sized_candidate(obligation, &mut candidates);
91                }
92                Some(LangItem::Unsize) => {
93                    self.assemble_candidates_for_unsizing(obligation, &mut candidates);
94                }
95                Some(LangItem::Destruct) => {
96                    self.assemble_const_destruct_candidates(obligation, &mut candidates);
97                }
98                Some(LangItem::TransmuteTrait) => {
99                    // User-defined transmutability impls are permitted.
100                    self.assemble_candidates_from_impls(obligation, &mut candidates);
101                    self.assemble_candidates_for_transmutability(obligation, &mut candidates);
102                }
103                Some(LangItem::Tuple) => {
104                    self.assemble_candidate_for_tuple(obligation, &mut candidates);
105                }
106                Some(LangItem::FnPtrTrait) => {
107                    self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
108                }
109                Some(LangItem::BikeshedGuaranteedNoDrop) => {
110                    self.assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
111                        obligation,
112                        &mut candidates,
113                    );
114                }
115                _ => {
116                    // We re-match here for traits that can have both builtin impls and user written impls.
117                    // After the builtin impls we need to also add user written impls, which we do not want to
118                    // do in general because just checking if there are any is expensive.
119                    match lang_item {
120                        Some(LangItem::Coroutine) => {
121                            self.assemble_coroutine_candidates(obligation, &mut candidates);
122                        }
123                        Some(LangItem::Future) => {
124                            self.assemble_future_candidates(obligation, &mut candidates);
125                        }
126                        Some(LangItem::Iterator) => {
127                            self.assemble_iterator_candidates(obligation, &mut candidates);
128                        }
129                        Some(LangItem::FusedIterator) => {
130                            self.assemble_fused_iterator_candidates(obligation, &mut candidates);
131                        }
132                        Some(LangItem::AsyncIterator) => {
133                            self.assemble_async_iterator_candidates(obligation, &mut candidates);
134                        }
135                        Some(LangItem::AsyncFnKindHelper) => {
136                            self.assemble_async_fn_kind_helper_candidates(
137                                obligation,
138                                &mut candidates,
139                            );
140                        }
141                        Some(LangItem::AsyncFn | LangItem::AsyncFnMut | LangItem::AsyncFnOnce) => {
142                            self.assemble_async_closure_candidates(obligation, &mut candidates);
143                        }
144                        Some(LangItem::Fn | LangItem::FnMut | LangItem::FnOnce) => {
145                            self.assemble_closure_candidates(obligation, &mut candidates);
146                            self.assemble_fn_pointer_candidates(obligation, &mut candidates);
147                        }
148                        _ => {}
149                    }
150
151                    self.assemble_candidates_from_impls(obligation, &mut candidates);
152                    self.assemble_candidates_from_object_ty(obligation, &mut candidates);
153                }
154            }
155
156            self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
157            self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
158            self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
159        }
160        debug!("candidate list size: {}", candidates.vec.len());
161        Ok(candidates)
162    }
163
164    #[instrument(level = "debug", skip(self, candidates))]
165    fn assemble_candidates_from_projected_tys(
166        &mut self,
167        obligation: &PolyTraitObligation<'tcx>,
168        candidates: &mut SelectionCandidateSet<'tcx>,
169    ) {
170        // Before we go into the whole placeholder thing, just
171        // quickly check if the self-type is a projection at all.
172        match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
173            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
174            ty::Alias(ty::Projection | ty::Opaque, _) => {}
175            ty::Infer(ty::TyVar(_)) => {
176                span_bug!(
177                    obligation.cause.span,
178                    "Self=_ should have been handled by assemble_candidates"
179                );
180            }
181            _ => return,
182        }
183
184        self.infcx.probe(|_| {
185            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
186            let placeholder_trait_predicate =
187                self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
188
189            // The bounds returned by `item_bounds` may contain duplicates after
190            // normalization, so try to deduplicate when possible to avoid
191            // unnecessary ambiguity.
192            let mut distinct_normalized_bounds = FxHashSet::default();
193            let _ = self.for_each_item_bound::<!>(
194                placeholder_trait_predicate.self_ty(),
195                |selcx, bound, idx| {
196                    let Some(bound) = bound.as_trait_clause() else {
197                        return ControlFlow::Continue(());
198                    };
199                    if bound.polarity() != placeholder_trait_predicate.polarity {
200                        return ControlFlow::Continue(());
201                    }
202
203                    selcx.infcx.probe(|_| {
204                        // We checked the polarity already
205                        match selcx.match_normalize_trait_ref(
206                            obligation,
207                            placeholder_trait_predicate.trait_ref,
208                            bound.map_bound(|pred| pred.trait_ref),
209                        ) {
210                            Ok(None) => {
211                                candidates.vec.push(ProjectionCandidate(idx));
212                            }
213                            Ok(Some(normalized_trait))
214                                if distinct_normalized_bounds.insert(normalized_trait) =>
215                            {
216                                candidates.vec.push(ProjectionCandidate(idx));
217                            }
218                            _ => {}
219                        }
220                    });
221
222                    ControlFlow::Continue(())
223                },
224                // On ambiguity.
225                || candidates.ambiguous = true,
226            );
227        });
228    }
229
230    /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
231    /// supplied to find out whether it is listed among them.
232    ///
233    /// Never affects the inference environment.
234    #[instrument(level = "debug", skip(self, stack, candidates))]
235    fn assemble_candidates_from_caller_bounds<'o>(
236        &mut self,
237        stack: &TraitObligationStack<'o, 'tcx>,
238        candidates: &mut SelectionCandidateSet<'tcx>,
239    ) -> Result<(), SelectionError<'tcx>> {
240        debug!(?stack.obligation);
241
242        let bounds = stack
243            .obligation
244            .param_env
245            .caller_bounds()
246            .iter()
247            .filter_map(|p| p.as_trait_clause())
248            // Micro-optimization: filter out predicates relating to different traits.
249            .filter(|p| p.def_id() == stack.obligation.predicate.def_id())
250            .filter(|p| p.polarity() == stack.obligation.predicate.polarity());
251
252        let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
253        let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
254        // Keep only those bounds which may apply, and propagate overflow if it occurs.
255        for bound in bounds {
256            let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
257            if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
258                continue;
259            }
260            let wc = self.where_clause_may_apply(stack, bound_trait_ref)?;
261            if wc.may_apply() {
262                candidates.vec.push(ParamCandidate(bound));
263            }
264        }
265
266        Ok(())
267    }
268
269    fn assemble_coroutine_candidates(
270        &mut self,
271        obligation: &PolyTraitObligation<'tcx>,
272        candidates: &mut SelectionCandidateSet<'tcx>,
273    ) {
274        // Okay to skip binder because the args on coroutine types never
275        // touch bound regions, they just capture the in-scope
276        // type/region parameters.
277        let self_ty = obligation.self_ty().skip_binder();
278        match self_ty.kind() {
279            // `async`/`gen` constructs get lowered to a special kind of coroutine that
280            // should *not* `impl Coroutine`.
281            ty::Coroutine(did, ..) if self.tcx().is_general_coroutine(*did) => {
282                debug!(?self_ty, ?obligation, "assemble_coroutine_candidates",);
283
284                candidates.vec.push(CoroutineCandidate);
285            }
286            ty::Infer(ty::TyVar(_)) => {
287                debug!("assemble_coroutine_candidates: ambiguous self-type");
288                candidates.ambiguous = true;
289            }
290            _ => {}
291        }
292    }
293
294    fn assemble_future_candidates(
295        &mut self,
296        obligation: &PolyTraitObligation<'tcx>,
297        candidates: &mut SelectionCandidateSet<'tcx>,
298    ) {
299        let self_ty = obligation.self_ty().skip_binder();
300        if let ty::Coroutine(did, ..) = self_ty.kind() {
301            // async constructs get lowered to a special kind of coroutine that
302            // should directly `impl Future`.
303            if self.tcx().coroutine_is_async(*did) {
304                debug!(?self_ty, ?obligation, "assemble_future_candidates",);
305
306                candidates.vec.push(FutureCandidate);
307            }
308        }
309    }
310
311    fn assemble_iterator_candidates(
312        &mut self,
313        obligation: &PolyTraitObligation<'tcx>,
314        candidates: &mut SelectionCandidateSet<'tcx>,
315    ) {
316        let self_ty = obligation.self_ty().skip_binder();
317        // gen constructs get lowered to a special kind of coroutine that
318        // should directly `impl Iterator`.
319        if let ty::Coroutine(did, ..) = self_ty.kind()
320            && self.tcx().coroutine_is_gen(*did)
321        {
322            debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
323
324            candidates.vec.push(IteratorCandidate);
325        }
326    }
327
328    fn assemble_fused_iterator_candidates(
329        &mut self,
330        obligation: &PolyTraitObligation<'tcx>,
331        candidates: &mut SelectionCandidateSet<'tcx>,
332    ) {
333        let self_ty = obligation.self_ty().skip_binder();
334        // gen constructs get lowered to a special kind of coroutine that
335        // should directly `impl FusedIterator`.
336        if let ty::Coroutine(did, ..) = self_ty.kind()
337            && self.tcx().coroutine_is_gen(*did)
338        {
339            debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
340
341            candidates.vec.push(BuiltinCandidate { has_nested: false });
342        }
343    }
344
345    fn assemble_async_iterator_candidates(
346        &mut self,
347        obligation: &PolyTraitObligation<'tcx>,
348        candidates: &mut SelectionCandidateSet<'tcx>,
349    ) {
350        let self_ty = obligation.self_ty().skip_binder();
351        if let ty::Coroutine(did, args) = *self_ty.kind() {
352            // gen constructs get lowered to a special kind of coroutine that
353            // should directly `impl AsyncIterator`.
354            if self.tcx().coroutine_is_async_gen(did) {
355                debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
356
357                // Can only confirm this candidate if we have constrained
358                // the `Yield` type to at least `Poll<Option<?0>>`..
359                let ty::Adt(_poll_def, args) = *args.as_coroutine().yield_ty().kind() else {
360                    candidates.ambiguous = true;
361                    return;
362                };
363                let ty::Adt(_option_def, _) = *args.type_at(0).kind() else {
364                    candidates.ambiguous = true;
365                    return;
366                };
367
368                candidates.vec.push(AsyncIteratorCandidate);
369            }
370        }
371    }
372
373    /// Checks for the artificial impl that the compiler will create for an obligation like `X :
374    /// FnMut<..>` where `X` is a closure type.
375    ///
376    /// Note: the type parameters on a closure candidate are modeled as *output* type
377    /// parameters and hence do not affect whether this trait is a match or not. They will be
378    /// unified during the confirmation step.
379    fn assemble_closure_candidates(
380        &mut self,
381        obligation: &PolyTraitObligation<'tcx>,
382        candidates: &mut SelectionCandidateSet<'tcx>,
383    ) {
384        let kind = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
385
386        // Okay to skip binder because the args on closure types never
387        // touch bound regions, they just capture the in-scope
388        // type/region parameters
389        let self_ty = obligation.self_ty().skip_binder();
390        match *self_ty.kind() {
391            ty::Closure(def_id, _) => {
392                let is_const = self.tcx().is_const_fn(def_id);
393                debug!(?kind, ?obligation, "assemble_unboxed_candidates");
394                match self.infcx.closure_kind(self_ty) {
395                    Some(closure_kind) => {
396                        debug!(?closure_kind, "assemble_unboxed_candidates");
397                        if closure_kind.extends(kind) {
398                            candidates.vec.push(ClosureCandidate { is_const });
399                        }
400                    }
401                    None => {
402                        if kind == ty::ClosureKind::FnOnce {
403                            candidates.vec.push(ClosureCandidate { is_const });
404                        } else {
405                            candidates.ambiguous = true;
406                        }
407                    }
408                }
409            }
410            ty::CoroutineClosure(def_id, args) => {
411                let args = args.as_coroutine_closure();
412                let is_const = self.tcx().is_const_fn(def_id);
413                if let Some(closure_kind) = self.infcx.closure_kind(self_ty)
414                    // Ambiguity if upvars haven't been constrained yet
415                    && !args.tupled_upvars_ty().is_ty_var()
416                {
417                    // A coroutine-closure implements `FnOnce` *always*, since it may
418                    // always be called once. It additionally implements `Fn`/`FnMut`
419                    // only if it has no upvars referencing the closure-env lifetime,
420                    // and if the closure kind permits it.
421                    if closure_kind.extends(kind) && !args.has_self_borrows() {
422                        candidates.vec.push(ClosureCandidate { is_const });
423                    } else if kind == ty::ClosureKind::FnOnce {
424                        candidates.vec.push(ClosureCandidate { is_const });
425                    }
426                } else if kind == ty::ClosureKind::FnOnce {
427                    candidates.vec.push(ClosureCandidate { is_const });
428                } else {
429                    // This stays ambiguous until kind+upvars are determined.
430                    candidates.ambiguous = true;
431                }
432            }
433            ty::Infer(ty::TyVar(_)) => {
434                debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
435                candidates.ambiguous = true;
436            }
437            _ => {}
438        }
439    }
440
441    fn assemble_async_closure_candidates(
442        &mut self,
443        obligation: &PolyTraitObligation<'tcx>,
444        candidates: &mut SelectionCandidateSet<'tcx>,
445    ) {
446        let goal_kind =
447            self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
448
449        match *obligation.self_ty().skip_binder().kind() {
450            ty::CoroutineClosure(_, args) => {
451                if let Some(closure_kind) =
452                    args.as_coroutine_closure().kind_ty().to_opt_closure_kind()
453                    && !closure_kind.extends(goal_kind)
454                {
455                    return;
456                }
457                candidates.vec.push(AsyncClosureCandidate);
458            }
459            // Closures and fn pointers implement `AsyncFn*` if their return types
460            // implement `Future`, which is checked later.
461            ty::Closure(_, args) => {
462                if let Some(closure_kind) = args.as_closure().kind_ty().to_opt_closure_kind()
463                    && !closure_kind.extends(goal_kind)
464                {
465                    return;
466                }
467                candidates.vec.push(AsyncClosureCandidate);
468            }
469            // Provide an impl, but only for suitable `fn` pointers.
470            ty::FnPtr(sig_tys, hdr) => {
471                if sig_tys.with(hdr).is_fn_trait_compatible() {
472                    candidates.vec.push(AsyncClosureCandidate);
473                }
474            }
475            // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
476            ty::FnDef(def_id, _) => {
477                let tcx = self.tcx();
478                if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
479                    && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
480                {
481                    candidates.vec.push(AsyncClosureCandidate);
482                }
483            }
484            _ => {}
485        }
486    }
487
488    fn assemble_async_fn_kind_helper_candidates(
489        &mut self,
490        obligation: &PolyTraitObligation<'tcx>,
491        candidates: &mut SelectionCandidateSet<'tcx>,
492    ) {
493        let self_ty = obligation.self_ty().skip_binder();
494        let target_kind_ty = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
495
496        // `to_opt_closure_kind` is kind of ICEy when it sees non-int types.
497        if !(self_ty.is_integral() || self_ty.is_ty_var()) {
498            return;
499        }
500        if !(target_kind_ty.is_integral() || self_ty.is_ty_var()) {
501            return;
502        }
503
504        // Check that the self kind extends the goal kind. If it does,
505        // then there's nothing else to check.
506        if let Some(closure_kind) = self_ty.to_opt_closure_kind()
507            && let Some(goal_kind) = target_kind_ty.to_opt_closure_kind()
508            && closure_kind.extends(goal_kind)
509        {
510            candidates.vec.push(AsyncFnKindHelperCandidate);
511        }
512    }
513
514    /// Implements one of the `Fn()` family for a fn pointer.
515    fn assemble_fn_pointer_candidates(
516        &mut self,
517        obligation: &PolyTraitObligation<'tcx>,
518        candidates: &mut SelectionCandidateSet<'tcx>,
519    ) {
520        // Keep this function in sync with extract_tupled_inputs_and_output_from_callable
521        // until the old solver (and thus this function) is removed.
522
523        // Okay to skip binder because what we are inspecting doesn't involve bound regions.
524        let self_ty = obligation.self_ty().skip_binder();
525        match *self_ty.kind() {
526            ty::Infer(ty::TyVar(_)) => {
527                debug!("assemble_fn_pointer_candidates: ambiguous self-type");
528                candidates.ambiguous = true; // Could wind up being a fn() type.
529            }
530            // Provide an impl, but only for suitable `fn` pointers.
531            ty::FnPtr(sig_tys, hdr) => {
532                if sig_tys.with(hdr).is_fn_trait_compatible() {
533                    candidates.vec.push(FnPointerCandidate);
534                }
535            }
536            // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
537            ty::FnDef(def_id, _) => {
538                let tcx = self.tcx();
539                if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
540                    && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
541                {
542                    candidates.vec.push(FnPointerCandidate);
543                }
544            }
545            _ => {}
546        }
547    }
548
549    /// Searches for impls that might apply to `obligation`.
550    #[instrument(level = "debug", skip(self, candidates))]
551    fn assemble_candidates_from_impls(
552        &mut self,
553        obligation: &PolyTraitObligation<'tcx>,
554        candidates: &mut SelectionCandidateSet<'tcx>,
555    ) {
556        let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
557        let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
558        self.tcx().for_each_relevant_impl(
559            obligation.predicate.def_id(),
560            obligation.predicate.skip_binder().trait_ref.self_ty(),
561            |impl_def_id| {
562                // Before we create the generic parameters and everything, first
563                // consider a "quick reject". This avoids creating more types
564                // and so forth that we need to.
565                let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap();
566                if !drcx
567                    .args_may_unify(obligation_args, impl_trait_header.trait_ref.skip_binder().args)
568                {
569                    return;
570                }
571
572                // For every `default impl`, there's always a non-default `impl`
573                // that will *also* apply. There's no reason to register a candidate
574                // for this impl, since it is *not* proof that the trait goal holds.
575                if self.tcx().defaultness(impl_def_id).is_default() {
576                    return;
577                }
578
579                if self.reject_fn_ptr_impls(
580                    impl_def_id,
581                    obligation,
582                    impl_trait_header.trait_ref.skip_binder().self_ty(),
583                ) {
584                    return;
585                }
586
587                self.infcx.probe(|_| {
588                    if let Ok(_args) = self.match_impl(impl_def_id, impl_trait_header, obligation) {
589                        candidates.vec.push(ImplCandidate(impl_def_id));
590                    }
591                });
592            },
593        );
594    }
595
596    /// The various `impl<T: FnPtr> Trait for T` in libcore are more like builtin impls for all function items
597    /// and function pointers and less like blanket impls. Rejecting them when they can't possibly apply (because
598    /// the obligation's self-type does not implement `FnPtr`) avoids reporting that the self type does not implement
599    /// `FnPtr`, when we wanted to report that it doesn't implement `Trait`.
600    #[instrument(level = "trace", skip(self), ret)]
601    fn reject_fn_ptr_impls(
602        &mut self,
603        impl_def_id: DefId,
604        obligation: &PolyTraitObligation<'tcx>,
605        impl_self_ty: Ty<'tcx>,
606    ) -> bool {
607        // Let `impl<T: FnPtr> Trait for Vec<T>` go through the normal rejection path.
608        if !matches!(impl_self_ty.kind(), ty::Param(..)) {
609            return false;
610        }
611        let Some(fn_ptr_trait) = self.tcx().lang_items().fn_ptr_trait() else {
612            return false;
613        };
614
615        for &(predicate, _) in self.tcx().predicates_of(impl_def_id).predicates {
616            let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder() else { continue };
617            if fn_ptr_trait != pred.trait_ref.def_id {
618                continue;
619            }
620            trace!(?pred);
621            // Not the bound we're looking for
622            if pred.self_ty() != impl_self_ty {
623                continue;
624            }
625
626            let self_ty = obligation.self_ty().skip_binder();
627            match self_ty.kind() {
628                // Fast path to avoid evaluating an obligation that trivially holds.
629                // There may be more bounds, but these are checked by the regular path.
630                ty::FnPtr(..) => return false,
631
632                // These may potentially implement `FnPtr`
633                ty::Placeholder(..)
634                | ty::Dynamic(_, _, _)
635                | ty::Alias(_, _)
636                | ty::Infer(_)
637                | ty::Param(..)
638                | ty::Bound(_, _) => {}
639
640                // These can't possibly implement `FnPtr` as they are concrete types
641                // and not `FnPtr`
642                ty::Bool
643                | ty::Char
644                | ty::Int(_)
645                | ty::Uint(_)
646                | ty::Float(_)
647                | ty::Adt(_, _)
648                | ty::Foreign(_)
649                | ty::Str
650                | ty::Array(_, _)
651                | ty::Pat(_, _)
652                | ty::Slice(_)
653                | ty::RawPtr(_, _)
654                | ty::Ref(_, _, _)
655                | ty::Closure(..)
656                | ty::CoroutineClosure(..)
657                | ty::Coroutine(_, _)
658                | ty::CoroutineWitness(..)
659                | ty::UnsafeBinder(_)
660                | ty::Never
661                | ty::Tuple(_)
662                | ty::Error(_) => return true,
663                // FIXME: Function definitions could actually implement `FnPtr` by
664                // casting the ZST function def to a function pointer.
665                ty::FnDef(_, _) => return true,
666            }
667
668            // Generic params can implement `FnPtr` if the predicate
669            // holds within its own environment.
670            let obligation = Obligation::new(
671                self.tcx(),
672                obligation.cause.clone(),
673                obligation.param_env,
674                self.tcx().mk_predicate(obligation.predicate.map_bound(|mut pred| {
675                    pred.trait_ref =
676                        ty::TraitRef::new(self.tcx(), fn_ptr_trait, [pred.trait_ref.self_ty()]);
677                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
678                })),
679            );
680            if let Ok(r) = self.evaluate_root_obligation(&obligation) {
681                if !r.may_apply() {
682                    return true;
683                }
684            }
685        }
686        false
687    }
688
689    fn assemble_candidates_from_auto_impls(
690        &mut self,
691        obligation: &PolyTraitObligation<'tcx>,
692        candidates: &mut SelectionCandidateSet<'tcx>,
693    ) {
694        // Okay to skip binder here because the tests we do below do not involve bound regions.
695        let self_ty = obligation.self_ty().skip_binder();
696        debug!(?self_ty, "assemble_candidates_from_auto_impls");
697
698        let def_id = obligation.predicate.def_id();
699
700        let mut check_impls = || {
701            // Only consider auto impls if there are no manual impls for the root of `self_ty`.
702            //
703            // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
704            // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
705            // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
706            //
707            // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
708            // which may define impls for that type is either the crate defining the type
709            // or the trait. This should be guaranteed by the orphan check.
710            let mut has_impl = false;
711            self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
712            if !has_impl {
713                candidates.vec.push(AutoImplCandidate)
714            }
715        };
716
717        if self.tcx().trait_is_auto(def_id) {
718            match *self_ty.kind() {
719                ty::Dynamic(..) => {
720                    // For object types, we don't know what the closed
721                    // over types are. This means we conservatively
722                    // say nothing; a candidate may be added by
723                    // `assemble_candidates_from_object_ty`.
724                }
725                ty::Foreign(..) => {
726                    // Since the contents of foreign types is unknown,
727                    // we don't add any `..` impl. Default traits could
728                    // still be provided by a manual implementation for
729                    // this trait and type.
730
731                    // Backward compatibility for default auto traits.
732                    // Test: ui/traits/default_auto_traits/extern-types.rs
733                    if self.tcx().is_default_trait(def_id) {
734                        check_impls()
735                    }
736                }
737                ty::Param(..)
738                | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
739                | ty::Placeholder(..)
740                | ty::Bound(..) => {
741                    // In these cases, we don't know what the actual
742                    // type is. Therefore, we cannot break it down
743                    // into its constituent types. So we don't
744                    // consider the `..` impl but instead just add no
745                    // candidates: this means that typeck will only
746                    // succeed if there is another reason to believe
747                    // that this obligation holds. That could be a
748                    // where-clause or, in the case of an object type,
749                    // it could be that the object type lists the
750                    // trait (e.g., `Foo+Send : Send`). See
751                    // `ui/typeck/typeck-default-trait-impl-send-param.rs`
752                    // for an example of a test case that exercises
753                    // this path.
754                }
755                ty::Infer(ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_)) => {
756                    // The auto impl might apply; we don't know.
757                    candidates.ambiguous = true;
758                }
759                ty::Coroutine(coroutine_def_id, _)
760                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
761                {
762                    match self.tcx().coroutine_movability(coroutine_def_id) {
763                        hir::Movability::Static => {
764                            // Immovable coroutines are never `Unpin`, so
765                            // suppress the normal auto-impl candidate for it.
766                        }
767                        hir::Movability::Movable => {
768                            // Movable coroutines are always `Unpin`, so add an
769                            // unconditional builtin candidate.
770                            candidates.vec.push(BuiltinCandidate { has_nested: false });
771                        }
772                    }
773                }
774
775                ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
776                    bug!(
777                        "asked to assemble auto trait candidates of unexpected type: {:?}",
778                        self_ty
779                    );
780                }
781
782                ty::Alias(ty::Opaque, alias) => {
783                    if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
784                        // We do not generate an auto impl candidate for `impl Trait`s which already
785                        // reference our auto trait.
786                        //
787                        // For example during candidate assembly for `impl Send: Send`, we don't have
788                        // to look at the constituent types for this opaque types to figure out that this
789                        // trivially holds.
790                        //
791                        // Note that this is only sound as projection candidates of opaque types
792                        // are always applicable for auto traits.
793                    } else if let TypingMode::Coherence = self.infcx.typing_mode() {
794                        // We do not emit auto trait candidates for opaque types in coherence.
795                        // Doing so can result in weird dependency cycles.
796                        candidates.ambiguous = true;
797                    } else if self.infcx.can_define_opaque_ty(alias.def_id) {
798                        // We do not emit auto trait candidates for opaque types in their defining scope, as
799                        // we need to know the hidden type first, which we can't reliably know within the defining
800                        // scope.
801                        candidates.ambiguous = true;
802                    } else {
803                        candidates.vec.push(AutoImplCandidate)
804                    }
805                }
806
807                ty::Bool
808                | ty::Char
809                | ty::Int(_)
810                | ty::Uint(_)
811                | ty::Float(_)
812                | ty::Str
813                | ty::Array(_, _)
814                | ty::Pat(_, _)
815                | ty::Slice(_)
816                | ty::Adt(..)
817                | ty::RawPtr(_, _)
818                | ty::Ref(..)
819                | ty::FnDef(..)
820                | ty::FnPtr(..)
821                | ty::Closure(..)
822                | ty::CoroutineClosure(..)
823                | ty::Coroutine(..)
824                | ty::Never
825                | ty::Tuple(_)
826                | ty::CoroutineWitness(..)
827                | ty::UnsafeBinder(_) => {
828                    // Only consider auto impls of unsafe traits when there are
829                    // no unsafe fields.
830                    if self.tcx().trait_def(def_id).safety.is_unsafe()
831                        && self_ty.has_unsafe_fields()
832                    {
833                        return;
834                    }
835
836                    check_impls();
837                }
838                ty::Error(_) => {
839                    candidates.vec.push(AutoImplCandidate);
840                }
841            }
842        }
843    }
844
845    /// Searches for impls that might apply to `obligation`.
846    fn assemble_candidates_from_object_ty(
847        &mut self,
848        obligation: &PolyTraitObligation<'tcx>,
849        candidates: &mut SelectionCandidateSet<'tcx>,
850    ) {
851        debug!(
852            self_ty = ?obligation.self_ty().skip_binder(),
853            "assemble_candidates_from_object_ty",
854        );
855
856        if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object {
857            return;
858        }
859
860        self.infcx.probe(|_snapshot| {
861            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
862            self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
863                let self_ty = placeholder_trait_predicate.self_ty();
864                let principal_trait_ref = match self_ty.kind() {
865                    ty::Dynamic(data, ..) => {
866                        if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
867                            debug!(
868                                "assemble_candidates_from_object_ty: matched builtin bound, \
869                             pushing candidate"
870                            );
871                            candidates.vec.push(BuiltinObjectCandidate);
872                            return;
873                        }
874
875                        if let Some(principal) = data.principal() {
876                            principal.with_self_ty(self.tcx(), self_ty)
877                        } else {
878                            // Only auto trait bounds exist.
879                            return;
880                        }
881                    }
882                    ty::Infer(ty::TyVar(_)) => {
883                        debug!("assemble_candidates_from_object_ty: ambiguous");
884                        candidates.ambiguous = true; // could wind up being an object type
885                        return;
886                    }
887                    _ => return,
888                };
889
890                debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
891
892                // Count only those upcast versions that match the trait-ref
893                // we are looking for. Specifically, do not only check for the
894                // correct trait, but also the correct type parameters.
895                // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
896                // but `Foo` is declared as `trait Foo: Bar<u32>`.
897                let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
898                    .enumerate()
899                    .filter(|&(_, upcast_trait_ref)| {
900                        self.infcx.probe(|_| {
901                            self.match_normalize_trait_ref(
902                                obligation,
903                                placeholder_trait_predicate.trait_ref,
904                                upcast_trait_ref,
905                            )
906                            .is_ok()
907                        })
908                    })
909                    .map(|(idx, _)| ObjectCandidate(idx));
910
911                candidates.vec.extend(candidate_supertraits);
912            })
913        })
914    }
915
916    /// Searches for unsizing that might apply to `obligation`.
917    fn assemble_candidates_for_unsizing(
918        &mut self,
919        obligation: &PolyTraitObligation<'tcx>,
920        candidates: &mut SelectionCandidateSet<'tcx>,
921    ) {
922        // We currently never consider higher-ranked obligations e.g.
923        // `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
924        // because they are a priori invalid, and we could potentially add support
925        // for them later, it's just that there isn't really a strong need for it.
926        // A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
927        // impl, and those are generally applied to concrete types.
928        //
929        // That said, one might try to write a fn with a where clause like
930        //     for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
931        // where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
932        // Still, you'd be more likely to write that where clause as
933        //     T: Trait
934        // so it seems ok if we (conservatively) fail to accept that `Unsize`
935        // obligation above. Should be possible to extend this in the future.
936        let Some(trait_pred) = obligation.predicate.no_bound_vars() else {
937            // Don't add any candidates if there are bound regions.
938            return;
939        };
940        let source = trait_pred.self_ty();
941        let target = trait_pred.trait_ref.args.type_at(1);
942
943        debug!(?source, ?target, "assemble_candidates_for_unsizing");
944
945        match (source.kind(), target.kind()) {
946            // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
947            (&ty::Dynamic(a_data, a_region, ty::Dyn), &ty::Dynamic(b_data, b_region, ty::Dyn)) => {
948                // Upcast coercions permit several things:
949                //
950                // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
951                // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
952                // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar`
953                //
954                // Note that neither of the first two of these changes requires any
955                // change at runtime. The third needs to change pointer metadata at runtime.
956                //
957                // We always perform upcasting coercions when we can because of reason
958                // #2 (region bounds).
959                let principal_def_id_a = a_data.principal_def_id();
960                let principal_def_id_b = b_data.principal_def_id();
961                if principal_def_id_a == principal_def_id_b || principal_def_id_b.is_none() {
962                    // We may upcast to auto traits that are either explicitly listed in
963                    // the object type's bounds, or implied by the principal trait ref's
964                    // supertraits.
965                    let a_auto_traits: FxIndexSet<DefId> = a_data
966                        .auto_traits()
967                        .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| {
968                            elaborate::supertrait_def_ids(self.tcx(), principal_def_id)
969                                .filter(|def_id| self.tcx().trait_is_auto(*def_id))
970                        }))
971                        .collect();
972                    let auto_traits_compatible = b_data
973                        .auto_traits()
974                        // All of a's auto traits need to be in b's auto traits.
975                        .all(|b| a_auto_traits.contains(&b));
976                    if auto_traits_compatible {
977                        candidates.vec.push(BuiltinUnsizeCandidate);
978                    }
979                } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
980                    // not casual unsizing, now check whether this is trait upcasting coercion.
981                    let principal_a = a_data.principal().unwrap();
982                    let target_trait_did = principal_def_id_b.unwrap();
983                    let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
984
985                    for (idx, upcast_trait_ref) in
986                        util::supertraits(self.tcx(), source_trait_ref).enumerate()
987                    {
988                        self.infcx.probe(|_| {
989                            if upcast_trait_ref.def_id() == target_trait_did
990                                && let Ok(nested) = self.match_upcast_principal(
991                                    obligation,
992                                    upcast_trait_ref,
993                                    a_data,
994                                    b_data,
995                                    a_region,
996                                    b_region,
997                                )
998                            {
999                                if nested.is_none() {
1000                                    candidates.ambiguous = true;
1001                                }
1002                                candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
1003                            }
1004                        })
1005                    }
1006                }
1007            }
1008
1009            // `T` -> `Trait`
1010            (_, &ty::Dynamic(_, _, ty::Dyn)) => {
1011                candidates.vec.push(BuiltinUnsizeCandidate);
1012            }
1013
1014            // Ambiguous handling is below `T` -> `Trait`, because inference
1015            // variables can still implement `Unsize<Trait>` and nested
1016            // obligations will have the final say (likely deferred).
1017            (&ty::Infer(ty::TyVar(_)), _) | (_, &ty::Infer(ty::TyVar(_))) => {
1018                debug!("assemble_candidates_for_unsizing: ambiguous");
1019                candidates.ambiguous = true;
1020            }
1021
1022            // `[T; n]` -> `[T]`
1023            (&ty::Array(..), &ty::Slice(_)) => {
1024                candidates.vec.push(BuiltinUnsizeCandidate);
1025            }
1026
1027            // `Struct<T>` -> `Struct<U>`
1028            (&ty::Adt(def_id_a, _), &ty::Adt(def_id_b, _)) if def_id_a.is_struct() => {
1029                if def_id_a == def_id_b {
1030                    candidates.vec.push(BuiltinUnsizeCandidate);
1031                }
1032            }
1033
1034            _ => {}
1035        };
1036    }
1037
1038    #[instrument(level = "debug", skip(self, obligation, candidates))]
1039    fn assemble_candidates_for_transmutability(
1040        &mut self,
1041        obligation: &PolyTraitObligation<'tcx>,
1042        candidates: &mut SelectionCandidateSet<'tcx>,
1043    ) {
1044        if obligation.predicate.has_non_region_param() {
1045            return;
1046        }
1047
1048        if obligation.has_non_region_infer() {
1049            candidates.ambiguous = true;
1050            return;
1051        }
1052
1053        candidates.vec.push(TransmutabilityCandidate);
1054    }
1055
1056    #[instrument(level = "debug", skip(self, obligation, candidates))]
1057    fn assemble_candidates_for_trait_alias(
1058        &mut self,
1059        obligation: &PolyTraitObligation<'tcx>,
1060        candidates: &mut SelectionCandidateSet<'tcx>,
1061    ) {
1062        // Okay to skip binder here because the tests we do below do not involve bound regions.
1063        let self_ty = obligation.self_ty().skip_binder();
1064        debug!(?self_ty);
1065
1066        let def_id = obligation.predicate.def_id();
1067
1068        if self.tcx().is_trait_alias(def_id) {
1069            candidates.vec.push(TraitAliasCandidate);
1070        }
1071    }
1072
1073    /// Assembles the trait which are built-in to the language itself:
1074    /// `Copy`, `Clone` and `Sized`.
1075    #[instrument(level = "debug", skip(self, candidates))]
1076    fn assemble_builtin_sized_candidate(
1077        &mut self,
1078        obligation: &PolyTraitObligation<'tcx>,
1079        candidates: &mut SelectionCandidateSet<'tcx>,
1080    ) {
1081        match self.sized_conditions(obligation) {
1082            BuiltinImplConditions::Where(nested) => {
1083                candidates
1084                    .vec
1085                    .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() });
1086            }
1087            BuiltinImplConditions::None => {}
1088            BuiltinImplConditions::Ambiguous => {
1089                candidates.ambiguous = true;
1090            }
1091        }
1092    }
1093
1094    /// Assembles the trait which are built-in to the language itself:
1095    /// e.g. `Copy` and `Clone`.
1096    #[instrument(level = "debug", skip(self, candidates))]
1097    fn assemble_builtin_bound_candidates(
1098        &mut self,
1099        conditions: BuiltinImplConditions<'tcx>,
1100        candidates: &mut SelectionCandidateSet<'tcx>,
1101    ) {
1102        match conditions {
1103            BuiltinImplConditions::Where(nested) => {
1104                candidates
1105                    .vec
1106                    .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
1107            }
1108            BuiltinImplConditions::None => {}
1109            BuiltinImplConditions::Ambiguous => {
1110                candidates.ambiguous = true;
1111            }
1112        }
1113    }
1114
1115    fn assemble_const_destruct_candidates(
1116        &mut self,
1117        _obligation: &PolyTraitObligation<'tcx>,
1118        candidates: &mut SelectionCandidateSet<'tcx>,
1119    ) {
1120        candidates.vec.push(BuiltinCandidate { has_nested: false });
1121    }
1122
1123    fn assemble_candidate_for_tuple(
1124        &mut self,
1125        obligation: &PolyTraitObligation<'tcx>,
1126        candidates: &mut SelectionCandidateSet<'tcx>,
1127    ) {
1128        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
1129        match self_ty.kind() {
1130            ty::Tuple(_) => {
1131                candidates.vec.push(BuiltinCandidate { has_nested: false });
1132            }
1133            ty::Infer(ty::TyVar(_)) => {
1134                candidates.ambiguous = true;
1135            }
1136            ty::Bool
1137            | ty::Char
1138            | ty::Int(_)
1139            | ty::Uint(_)
1140            | ty::Float(_)
1141            | ty::Adt(_, _)
1142            | ty::Foreign(_)
1143            | ty::Str
1144            | ty::Array(_, _)
1145            | ty::Slice(_)
1146            | ty::RawPtr(_, _)
1147            | ty::Ref(_, _, _)
1148            | ty::FnDef(_, _)
1149            | ty::Pat(_, _)
1150            | ty::FnPtr(..)
1151            | ty::UnsafeBinder(_)
1152            | ty::Dynamic(_, _, _)
1153            | ty::Closure(..)
1154            | ty::CoroutineClosure(..)
1155            | ty::Coroutine(_, _)
1156            | ty::CoroutineWitness(..)
1157            | ty::Never
1158            | ty::Alias(..)
1159            | ty::Param(_)
1160            | ty::Bound(_, _)
1161            | ty::Error(_)
1162            | ty::Infer(_)
1163            | ty::Placeholder(_) => {}
1164        }
1165    }
1166
1167    fn assemble_candidates_for_fn_ptr_trait(
1168        &mut self,
1169        obligation: &PolyTraitObligation<'tcx>,
1170        candidates: &mut SelectionCandidateSet<'tcx>,
1171    ) {
1172        let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
1173
1174        match self_ty.skip_binder().kind() {
1175            ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
1176            ty::Bool
1177            | ty::Char
1178            | ty::Int(_)
1179            | ty::Uint(_)
1180            | ty::Float(_)
1181            | ty::Adt(..)
1182            | ty::Foreign(..)
1183            | ty::Str
1184            | ty::Array(..)
1185            | ty::Pat(..)
1186            | ty::Slice(_)
1187            | ty::RawPtr(_, _)
1188            | ty::Ref(..)
1189            | ty::FnDef(..)
1190            | ty::Placeholder(..)
1191            | ty::Dynamic(..)
1192            | ty::Closure(..)
1193            | ty::CoroutineClosure(..)
1194            | ty::Coroutine(..)
1195            | ty::CoroutineWitness(..)
1196            | ty::UnsafeBinder(_)
1197            | ty::Never
1198            | ty::Tuple(..)
1199            | ty::Alias(..)
1200            | ty::Param(..)
1201            | ty::Bound(..)
1202            | ty::Error(_)
1203            | ty::Infer(
1204                ty::InferTy::IntVar(_)
1205                | ty::InferTy::FloatVar(_)
1206                | ty::InferTy::FreshIntTy(_)
1207                | ty::InferTy::FreshFloatTy(_),
1208            ) => {}
1209            ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => {
1210                candidates.ambiguous = true;
1211            }
1212        }
1213    }
1214
1215    fn assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
1216        &mut self,
1217        obligation: &PolyTraitObligation<'tcx>,
1218        candidates: &mut SelectionCandidateSet<'tcx>,
1219    ) {
1220        match obligation.predicate.self_ty().skip_binder().kind() {
1221            ty::Ref(..)
1222            | ty::Adt(..)
1223            | ty::Tuple(_)
1224            | ty::Array(..)
1225            | ty::FnDef(..)
1226            | ty::FnPtr(..)
1227            | ty::Error(_)
1228            | ty::Uint(_)
1229            | ty::Int(_)
1230            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1231            | ty::Bool
1232            | ty::Float(_)
1233            | ty::Char
1234            | ty::RawPtr(..)
1235            | ty::Never
1236            | ty::Pat(..)
1237            | ty::Dynamic(..)
1238            | ty::Str
1239            | ty::Slice(_)
1240            | ty::Foreign(..)
1241            | ty::Alias(..)
1242            | ty::Param(_)
1243            | ty::Placeholder(..)
1244            | ty::Closure(..)
1245            | ty::CoroutineClosure(..)
1246            | ty::Coroutine(..)
1247            | ty::UnsafeBinder(_)
1248            | ty::CoroutineWitness(..)
1249            | ty::Bound(..) => {
1250                candidates.vec.push(BikeshedGuaranteedNoDropCandidate);
1251            }
1252
1253            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1254                candidates.ambiguous = true;
1255            }
1256        }
1257    }
1258}