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