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::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            let _ = 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_def(def_id).safety.is_unsafe()
806                        && self_ty.has_unsafe_fields()
807                    {
808                        return;
809                    }
810
811                    // Only consider auto impls if there are no manual impls for the root of `self_ty`.
812                    //
813                    // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
814                    // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
815                    // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
816                    //
817                    // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
818                    // which may define impls for that type is either the crate defining the type
819                    // or the trait. This should be guaranteed by the orphan check.
820                    let mut has_impl = false;
821                    self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
822                    if !has_impl {
823                        candidates.vec.push(AutoImplCandidate)
824                    }
825                }
826                ty::Error(_) => {
827                    candidates.vec.push(AutoImplCandidate);
828                }
829            }
830        }
831    }
832
833    /// Searches for impls that might apply to `obligation`.
834    fn assemble_candidates_from_object_ty(
835        &mut self,
836        obligation: &PolyTraitObligation<'tcx>,
837        candidates: &mut SelectionCandidateSet<'tcx>,
838    ) {
839        debug!(
840            self_ty = ?obligation.self_ty().skip_binder(),
841            "assemble_candidates_from_object_ty",
842        );
843
844        if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object {
845            return;
846        }
847
848        self.infcx.probe(|_snapshot| {
849            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
850            self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
851                let self_ty = placeholder_trait_predicate.self_ty();
852                let principal_trait_ref = match self_ty.kind() {
853                    ty::Dynamic(data, ..) => {
854                        if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
855                            debug!(
856                                "assemble_candidates_from_object_ty: matched builtin bound, \
857                             pushing candidate"
858                            );
859                            candidates.vec.push(BuiltinObjectCandidate);
860                            return;
861                        }
862
863                        if let Some(principal) = data.principal() {
864                            principal.with_self_ty(self.tcx(), self_ty)
865                        } else {
866                            // Only auto trait bounds exist.
867                            return;
868                        }
869                    }
870                    ty::Infer(ty::TyVar(_)) => {
871                        debug!("assemble_candidates_from_object_ty: ambiguous");
872                        candidates.ambiguous = true; // could wind up being an object type
873                        return;
874                    }
875                    _ => return,
876                };
877
878                debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
879
880                // Count only those upcast versions that match the trait-ref
881                // we are looking for. Specifically, do not only check for the
882                // correct trait, but also the correct type parameters.
883                // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
884                // but `Foo` is declared as `trait Foo: Bar<u32>`.
885                let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
886                    .enumerate()
887                    .filter(|&(_, upcast_trait_ref)| {
888                        self.infcx.probe(|_| {
889                            self.match_normalize_trait_ref(
890                                obligation,
891                                placeholder_trait_predicate.trait_ref,
892                                upcast_trait_ref,
893                            )
894                            .is_ok()
895                        })
896                    })
897                    .map(|(idx, _)| ObjectCandidate(idx));
898
899                candidates.vec.extend(candidate_supertraits);
900            })
901        })
902    }
903
904    /// Searches for unsizing that might apply to `obligation`.
905    fn assemble_candidates_for_unsizing(
906        &mut self,
907        obligation: &PolyTraitObligation<'tcx>,
908        candidates: &mut SelectionCandidateSet<'tcx>,
909    ) {
910        // We currently never consider higher-ranked obligations e.g.
911        // `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
912        // because they are a priori invalid, and we could potentially add support
913        // for them later, it's just that there isn't really a strong need for it.
914        // A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
915        // impl, and those are generally applied to concrete types.
916        //
917        // That said, one might try to write a fn with a where clause like
918        //     for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
919        // where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
920        // Still, you'd be more likely to write that where clause as
921        //     T: Trait
922        // so it seems ok if we (conservatively) fail to accept that `Unsize`
923        // obligation above. Should be possible to extend this in the future.
924        let Some(trait_pred) = obligation.predicate.no_bound_vars() else {
925            // Don't add any candidates if there are bound regions.
926            return;
927        };
928        let source = trait_pred.self_ty();
929        let target = trait_pred.trait_ref.args.type_at(1);
930
931        debug!(?source, ?target, "assemble_candidates_for_unsizing");
932
933        match (source.kind(), target.kind()) {
934            // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
935            (&ty::Dynamic(a_data, a_region, ty::Dyn), &ty::Dynamic(b_data, b_region, ty::Dyn)) => {
936                // Upcast coercions permit several things:
937                //
938                // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
939                // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
940                // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar`
941                //
942                // Note that neither of the first two of these changes requires any
943                // change at runtime. The third needs to change pointer metadata at runtime.
944                //
945                // We always perform upcasting coercions when we can because of reason
946                // #2 (region bounds).
947                let principal_def_id_a = a_data.principal_def_id();
948                let principal_def_id_b = b_data.principal_def_id();
949                if principal_def_id_a == principal_def_id_b || principal_def_id_b.is_none() {
950                    // We may upcast to auto traits that are either explicitly listed in
951                    // the object type's bounds, or implied by the principal trait ref's
952                    // supertraits.
953                    let a_auto_traits: FxIndexSet<DefId> = a_data
954                        .auto_traits()
955                        .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| {
956                            elaborate::supertrait_def_ids(self.tcx(), principal_def_id)
957                                .filter(|def_id| self.tcx().trait_is_auto(*def_id))
958                        }))
959                        .collect();
960                    let auto_traits_compatible = b_data
961                        .auto_traits()
962                        // All of a's auto traits need to be in b's auto traits.
963                        .all(|b| a_auto_traits.contains(&b));
964                    if auto_traits_compatible {
965                        candidates.vec.push(BuiltinUnsizeCandidate);
966                    }
967                } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
968                    // not casual unsizing, now check whether this is trait upcasting coercion.
969                    let principal_a = a_data.principal().unwrap();
970                    let target_trait_did = principal_def_id_b.unwrap();
971                    let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
972
973                    for (idx, upcast_trait_ref) in
974                        util::supertraits(self.tcx(), source_trait_ref).enumerate()
975                    {
976                        self.infcx.probe(|_| {
977                            if upcast_trait_ref.def_id() == target_trait_did
978                                && let Ok(nested) = self.match_upcast_principal(
979                                    obligation,
980                                    upcast_trait_ref,
981                                    a_data,
982                                    b_data,
983                                    a_region,
984                                    b_region,
985                                )
986                            {
987                                if nested.is_none() {
988                                    candidates.ambiguous = true;
989                                }
990                                candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
991                            }
992                        })
993                    }
994                }
995            }
996
997            // `T` -> `Trait`
998            (_, &ty::Dynamic(_, _, ty::Dyn)) => {
999                candidates.vec.push(BuiltinUnsizeCandidate);
1000            }
1001
1002            // Ambiguous handling is below `T` -> `Trait`, because inference
1003            // variables can still implement `Unsize<Trait>` and nested
1004            // obligations will have the final say (likely deferred).
1005            (&ty::Infer(ty::TyVar(_)), _) | (_, &ty::Infer(ty::TyVar(_))) => {
1006                debug!("assemble_candidates_for_unsizing: ambiguous");
1007                candidates.ambiguous = true;
1008            }
1009
1010            // `[T; n]` -> `[T]`
1011            (&ty::Array(..), &ty::Slice(_)) => {
1012                candidates.vec.push(BuiltinUnsizeCandidate);
1013            }
1014
1015            // `Struct<T>` -> `Struct<U>`
1016            (&ty::Adt(def_id_a, _), &ty::Adt(def_id_b, _)) if def_id_a.is_struct() => {
1017                if def_id_a == def_id_b {
1018                    candidates.vec.push(BuiltinUnsizeCandidate);
1019                }
1020            }
1021
1022            _ => {}
1023        };
1024    }
1025
1026    #[instrument(level = "debug", skip(self, obligation, candidates))]
1027    fn assemble_candidates_for_transmutability(
1028        &mut self,
1029        obligation: &PolyTraitObligation<'tcx>,
1030        candidates: &mut SelectionCandidateSet<'tcx>,
1031    ) {
1032        if obligation.predicate.has_non_region_param() {
1033            return;
1034        }
1035
1036        if obligation.has_non_region_infer() {
1037            candidates.ambiguous = true;
1038            return;
1039        }
1040
1041        candidates.vec.push(TransmutabilityCandidate);
1042    }
1043
1044    #[instrument(level = "debug", skip(self, obligation, candidates))]
1045    fn assemble_candidates_for_trait_alias(
1046        &mut self,
1047        obligation: &PolyTraitObligation<'tcx>,
1048        candidates: &mut SelectionCandidateSet<'tcx>,
1049    ) {
1050        // Okay to skip binder here because the tests we do below do not involve bound regions.
1051        let self_ty = obligation.self_ty().skip_binder();
1052        debug!(?self_ty);
1053
1054        let def_id = obligation.predicate.def_id();
1055
1056        if self.tcx().is_trait_alias(def_id) {
1057            candidates.vec.push(TraitAliasCandidate);
1058        }
1059    }
1060
1061    /// Assembles the trait which are built-in to the language itself:
1062    /// `Copy`, `Clone` and `Sized`.
1063    #[instrument(level = "debug", skip(self, candidates))]
1064    fn assemble_builtin_bound_candidates(
1065        &mut self,
1066        conditions: BuiltinImplConditions<'tcx>,
1067        candidates: &mut SelectionCandidateSet<'tcx>,
1068    ) {
1069        match conditions {
1070            BuiltinImplConditions::Where(nested) => {
1071                candidates
1072                    .vec
1073                    .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
1074            }
1075            BuiltinImplConditions::None => {}
1076            BuiltinImplConditions::Ambiguous => {
1077                candidates.ambiguous = true;
1078            }
1079        }
1080    }
1081
1082    fn assemble_const_destruct_candidates(
1083        &mut self,
1084        _obligation: &PolyTraitObligation<'tcx>,
1085        candidates: &mut SelectionCandidateSet<'tcx>,
1086    ) {
1087        candidates.vec.push(BuiltinCandidate { has_nested: false });
1088    }
1089
1090    fn assemble_candidate_for_tuple(
1091        &mut self,
1092        obligation: &PolyTraitObligation<'tcx>,
1093        candidates: &mut SelectionCandidateSet<'tcx>,
1094    ) {
1095        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
1096        match self_ty.kind() {
1097            ty::Tuple(_) => {
1098                candidates.vec.push(BuiltinCandidate { has_nested: false });
1099            }
1100            ty::Infer(ty::TyVar(_)) => {
1101                candidates.ambiguous = true;
1102            }
1103            ty::Bool
1104            | ty::Char
1105            | ty::Int(_)
1106            | ty::Uint(_)
1107            | ty::Float(_)
1108            | ty::Adt(_, _)
1109            | ty::Foreign(_)
1110            | ty::Str
1111            | ty::Array(_, _)
1112            | ty::Slice(_)
1113            | ty::RawPtr(_, _)
1114            | ty::Ref(_, _, _)
1115            | ty::FnDef(_, _)
1116            | ty::Pat(_, _)
1117            | ty::FnPtr(..)
1118            | ty::UnsafeBinder(_)
1119            | ty::Dynamic(_, _, _)
1120            | ty::Closure(..)
1121            | ty::CoroutineClosure(..)
1122            | ty::Coroutine(_, _)
1123            | ty::CoroutineWitness(..)
1124            | ty::Never
1125            | ty::Alias(..)
1126            | ty::Param(_)
1127            | ty::Bound(_, _)
1128            | ty::Error(_)
1129            | ty::Infer(_)
1130            | ty::Placeholder(_) => {}
1131        }
1132    }
1133
1134    fn assemble_candidates_for_fn_ptr_trait(
1135        &mut self,
1136        obligation: &PolyTraitObligation<'tcx>,
1137        candidates: &mut SelectionCandidateSet<'tcx>,
1138    ) {
1139        let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
1140
1141        match self_ty.skip_binder().kind() {
1142            ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
1143            ty::Bool
1144            | ty::Char
1145            | ty::Int(_)
1146            | ty::Uint(_)
1147            | ty::Float(_)
1148            | ty::Adt(..)
1149            | ty::Foreign(..)
1150            | ty::Str
1151            | ty::Array(..)
1152            | ty::Pat(..)
1153            | ty::Slice(_)
1154            | ty::RawPtr(_, _)
1155            | ty::Ref(..)
1156            | ty::FnDef(..)
1157            | ty::Placeholder(..)
1158            | ty::Dynamic(..)
1159            | ty::Closure(..)
1160            | ty::CoroutineClosure(..)
1161            | ty::Coroutine(..)
1162            | ty::CoroutineWitness(..)
1163            | ty::UnsafeBinder(_)
1164            | ty::Never
1165            | ty::Tuple(..)
1166            | ty::Alias(..)
1167            | ty::Param(..)
1168            | ty::Bound(..)
1169            | ty::Error(_)
1170            | ty::Infer(
1171                ty::InferTy::IntVar(_)
1172                | ty::InferTy::FloatVar(_)
1173                | ty::InferTy::FreshIntTy(_)
1174                | ty::InferTy::FreshFloatTy(_),
1175            ) => {}
1176            ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => {
1177                candidates.ambiguous = true;
1178            }
1179        }
1180    }
1181
1182    fn assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
1183        &mut self,
1184        obligation: &PolyTraitObligation<'tcx>,
1185        candidates: &mut SelectionCandidateSet<'tcx>,
1186    ) {
1187        match obligation.predicate.self_ty().skip_binder().kind() {
1188            ty::Ref(..)
1189            | ty::Adt(..)
1190            | ty::Tuple(_)
1191            | ty::Array(..)
1192            | ty::FnDef(..)
1193            | ty::FnPtr(..)
1194            | ty::Error(_)
1195            | ty::Uint(_)
1196            | ty::Int(_)
1197            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1198            | ty::Bool
1199            | ty::Float(_)
1200            | ty::Char
1201            | ty::RawPtr(..)
1202            | ty::Never
1203            | ty::Pat(..)
1204            | ty::Dynamic(..)
1205            | ty::Str
1206            | ty::Slice(_)
1207            | ty::Foreign(..)
1208            | ty::Alias(..)
1209            | ty::Param(_)
1210            | ty::Placeholder(..)
1211            | ty::Closure(..)
1212            | ty::CoroutineClosure(..)
1213            | ty::Coroutine(..)
1214            | ty::UnsafeBinder(_)
1215            | ty::CoroutineWitness(..)
1216            | ty::Bound(..) => {
1217                candidates.vec.push(BikeshedGuaranteedNoDropCandidate);
1218            }
1219
1220            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1221                candidates.ambiguous = true;
1222            }
1223        }
1224    }
1225}