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