1use rustc_type_ir::data_structures::IndexSet;
4use rustc_type_ir::fast_reject::DeepRejectCtxt;
5use rustc_type_ir::inherent::*;
6use rustc_type_ir::lang_items::SolverTraitLangItem;
7use rustc_type_ir::solve::{
8 AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, ExternalConstraintsData, MaybeInfo,
9 NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunNonErased,
10 RerunReason, RerunResultExt, SizedTraitKind,
11};
12use rustc_type_ir::{
13 self as ty, ClausePolarity, ExistentialPredicate, FieldInfo, Interner, MayBeErased, Movability,
14 Region, TraitClause, TraitRef, TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _,
15 elaborate,
16};
17use tracing::{debug, instrument, trace, warn};
18
19use crate::delegate::SolverDelegate;
20use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
21use crate::solve::assembly::{
22 self, AllowInferenceConstraints, AssembleCandidatesFrom, Candidate, FailedCandidateInfo,
23};
24use crate::solve::inspect::ProbeKind;
25use crate::solve::{
26 BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
27 MergeCandidateInfo, NoSolution, ParamEnvSource, StalledOnCoroutines,
28 has_only_region_constraints,
29};
30
31impl<D, I> assembly::GoalKind<D> for TraitClause<I>
32where
33 D: SolverDelegate<Interner = I>,
34 I: Interner,
35{
36 fn self_ty(self) -> I::Ty {
37 self.self_ty()
38 }
39
40 fn trait_ref(self, _: I) -> ty::TraitRef<I> {
41 self.trait_ref
42 }
43
44 fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
45 self.with_replaced_self_ty(cx, self_ty)
46 }
47
48 fn trait_def_id(self, _: I) -> I::TraitId {
49 self.def_id()
50 }
51
52 fn consider_additional_alias_assumptions(
53 _ecx: &mut EvalCtxt<'_, D>,
54 _goal: Goal<I, Self>,
55 _alias_ty: ty::AliasTy<I>,
56 ) -> Vec<Candidate<I>> {
57 ::alloc::vec::Vec::new()vec![]
58 }
59
60 fn consider_impl_candidate(
61 ecx: &mut EvalCtxt<'_, D>,
62 goal: Goal<I, TraitClause<I>>,
63 goal_trait_ref: TraitRef<I>,
64 impl_def_id: I::ImplId,
65 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
66 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
67 let cx = ecx.cx();
68
69 let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
70 if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
71 .args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args)
72 {
73 return Err(NoSolution.into());
74 }
75
76 if cx.impl_is_default(impl_def_id) {
80 return Err(NoSolution.into());
81 }
82
83 match (cx.impl_polarity(impl_def_id), goal.predicate.polarity) {
84 (ty::ImplPolarity::Positive, ty::ClausePolarity::Positive)
86 | (ty::ImplPolarity::Negative, ty::ClausePolarity::Negative) => {}
87
88 (ty::ImplPolarity::Positive, ty::ClausePolarity::Negative)
90 | (ty::ImplPolarity::Negative, ty::ClausePolarity::Positive) => {
91 return Err(NoSolution.into());
92 }
93 }
94
95 if ecx.typing_mode().is_reflection() && !cx.is_fully_generic_for_reflection(impl_def_id) {
96 return Err(NoSolution.into());
97 }
98
99 ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
100 let impl_args = ecx.fresh_args_for_item(impl_def_id.into());
101 ecx.record_impl_args(impl_args);
102 let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();
103
104 ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
105 let where_clause_bounds = cx
106 .clauses_of(impl_def_id.into())
107 .iter_instantiated(cx, impl_args)
108 .map(Unnormalized::skip_norm_wip)
109 .map(|clause| goal.with(cx, clause));
110 ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;
111
112 ecx.add_goals(
116 GoalSource::Misc,
117 cx.impl_super_outlives(impl_def_id)
118 .iter_instantiated(cx, impl_args)
119 .map(Unnormalized::skip_norm_wip)
120 .map(|pred| goal.with(cx, pred)),
121 )?;
122
123 then(ecx)
124 })
125 }
126
127 fn consider_error_guaranteed_candidate(
128 ecx: &mut EvalCtxt<'_, D>,
129 _goal: Goal<I, Self>,
130 _guar: I::ErrorGuaranteed,
131 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
132 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
133 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
134 }
135
136 fn fast_reject_assumption(
137 ecx: &mut EvalCtxt<'_, D>,
138 goal: Goal<I, Self>,
139 assumption: I::Clause,
140 ) -> Result<(), NoSolution> {
141 fn trait_def_id_matches<I: Interner>(
142 cx: I,
143 clause_def_id: I::TraitId,
144 goal_def_id: I::TraitId,
145 polarity: ClausePolarity,
146 ) -> bool {
147 clause_def_id == goal_def_id
148 || (polarity == ClausePolarity::Positive
153 && cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized)
154 && cx.is_trait_lang_item(goal_def_id, SolverTraitLangItem::MetaSized))
155 }
156
157 if let Some(trait_clause) = assumption.as_trait_clause()
158 && trait_clause.polarity() == goal.predicate.polarity
159 && trait_def_id_matches(
160 ecx.cx(),
161 trait_clause.def_id(),
162 goal.predicate.def_id(),
163 goal.predicate.polarity,
164 )
165 && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
166 goal.predicate.trait_ref.args,
167 trait_clause.skip_binder().trait_ref.args,
168 )
169 {
170 return Ok(());
171 } else {
172 Err(NoSolution)
173 }
174 }
175
176 fn match_assumption(
177 ecx: &mut EvalCtxt<'_, D>,
178 goal: Goal<I, Self>,
179 assumption: I::Clause,
180 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
181 ) -> QueryResultOrRerunNonErased<I> {
182 let trait_clause = assumption.as_trait_clause().unwrap();
183
184 if ecx.cx().is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::MetaSized)
190 && ecx.cx().is_trait_lang_item(trait_clause.def_id(), SolverTraitLangItem::Sized)
191 {
192 let meta_sized_clause =
193 trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
194 return Self::match_assumption(ecx, goal, meta_sized_clause, then);
195 }
196
197 let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
198 ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
199
200 then(ecx)
201 }
202
203 fn consider_auto_trait_candidate(
204 ecx: &mut EvalCtxt<'_, D>,
205 goal: Goal<I, Self>,
206 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
207 let cx = ecx.cx();
208 if goal.predicate.polarity != ty::ClausePolarity::Positive {
209 return Err(NoSolution.into());
210 }
211
212 if let Some(result) = ecx.disqualify_auto_trait_candidate_due_to_possible_impl(goal) {
213 return result;
214 }
215
216 if cx.trait_is_unsafe(goal.predicate.def_id())
219 && goal.predicate.self_ty().has_unsafe_fields()
220 {
221 return Err(NoSolution.into());
222 }
223
224 if let ty::Alias(is_rigid, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
240 goal.predicate.self_ty().kind()
241 {
242 if true {
if !(is_rigid == ty::IsRigid::Yes) {
::core::panicking::panic("assertion failed: is_rigid == ty::IsRigid::Yes")
};
};debug_assert!(is_rigid == ty::IsRigid::Yes);
243 return ecx.consider_auto_trait_candidate_for_opaque_ty(goal, def_id, args);
244 }
245
246 if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
248 return cand;
249 }
250
251 ecx.probe_and_evaluate_goal_for_constituent_tys(
252 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
253 goal,
254 structural_traits::instantiate_constituent_tys_for_auto_trait,
255 )
256 }
257
258 fn consider_trait_alias_candidate(
259 ecx: &mut EvalCtxt<'_, D>,
260 goal: Goal<I, Self>,
261 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
262 if goal.predicate.polarity != ty::ClausePolarity::Positive {
263 return Err(NoSolution.into());
264 }
265
266 let cx = ecx.cx();
267
268 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
269 let nested_obligations = cx
270 .clauses_of(goal.predicate.def_id().into())
271 .iter_instantiated(cx, goal.predicate.trait_ref.args)
272 .map(Unnormalized::skip_norm_wip)
273 .map(|c| goal.with(cx, c));
274 ecx.add_goals(GoalSource::Misc, nested_obligations)?;
280 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
281 })
282 }
283
284 fn consider_builtin_sizedness_candidates(
285 ecx: &mut EvalCtxt<'_, D>,
286 goal: Goal<I, Self>,
287 sizedness: SizedTraitKind,
288 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
289 if goal.predicate.polarity != ty::ClausePolarity::Positive {
290 return Err(NoSolution.into());
291 }
292
293 ecx.probe_and_evaluate_goal_for_constituent_tys(
294 CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial),
295 goal,
296 |ecx, ty| {
297 structural_traits::instantiate_constituent_tys_for_sizedness_trait(
298 ecx, sizedness, ty,
299 )
300 },
301 )
302 }
303
304 fn consider_builtin_copy_clone_candidate(
305 ecx: &mut EvalCtxt<'_, D>,
306 goal: Goal<I, Self>,
307 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
308 if goal.predicate.polarity != ty::ClausePolarity::Positive {
309 return Err(NoSolution.into());
310 }
311
312 if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
314 return cand;
315 }
316
317 ecx.probe_and_evaluate_goal_for_constituent_tys(
318 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
319 goal,
320 structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
321 )
322 }
323
324 fn consider_builtin_fn_ptr_trait_candidate(
325 ecx: &mut EvalCtxt<'_, D>,
326 goal: Goal<I, Self>,
327 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
328 let self_ty = goal.predicate.self_ty();
329 match goal.predicate.polarity {
330 ty::ClausePolarity::Positive => {
332 if self_ty.is_fn_ptr() {
333 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
334 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
335 })
336 } else {
337 Err(NoSolution.into())
338 }
339 }
340 ty::ClausePolarity::Negative => {
342 if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() {
345 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
346 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
347 })
348 } else {
349 Err(NoSolution.into())
350 }
351 }
352 }
353 }
354
355 fn consider_builtin_fn_trait_candidates(
356 ecx: &mut EvalCtxt<'_, D>,
357 goal: Goal<I, Self>,
358 goal_kind: ty::ClosureKind,
359 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
360 if goal.predicate.polarity != ty::ClausePolarity::Positive {
361 return Err(NoSolution.into());
362 }
363
364 let cx = ecx.cx();
365 let Some(tupled_inputs_and_output) =
366 structural_traits::extract_tupled_inputs_and_output_from_callable(
367 cx,
368 goal.predicate.self_ty(),
369 goal_kind,
370 )?
371 else {
372 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
373 };
374 let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
375
376 let output_is_sized_pred =
379 ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
380
381 let pred =
382 ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
383 .upcast(cx);
384 Self::probe_and_consider_implied_clause(
385 ecx,
386 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
387 goal,
388 pred,
389 [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))],
390 )
391 }
392
393 fn consider_builtin_async_fn_trait_candidates(
394 ecx: &mut EvalCtxt<'_, D>,
395 goal: Goal<I, Self>,
396 goal_kind: ty::ClosureKind,
397 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
398 if goal.predicate.polarity != ty::ClausePolarity::Positive {
399 return Err(NoSolution.into());
400 }
401
402 let cx = ecx.cx();
403 let (tupled_inputs_and_output_and_coroutine, nested_preds) =
404 structural_traits::extract_tupled_inputs_and_output_from_async_callable(
405 cx,
406 goal.predicate.self_ty(),
407 goal_kind,
408 Region::new_static(cx),
410 )?;
411 let AsyncCallableRelevantTypes {
412 tupled_inputs_ty,
413 output_coroutine_ty,
414 coroutine_return_ty: _,
415 } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
416
417 let output_is_sized_pred = ty::TraitRef::new(
420 cx,
421 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
422 [output_coroutine_ty],
423 );
424
425 let pred = ty::TraitRef::new(
426 cx,
427 goal.predicate.def_id(),
428 [goal.predicate.self_ty(), tupled_inputs_ty],
429 )
430 .upcast(cx);
431 Self::probe_and_consider_implied_clause(
432 ecx,
433 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
434 goal,
435 pred,
436 [goal.with(cx, output_is_sized_pred)]
437 .into_iter()
438 .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred)))
439 .map(|goal| (GoalSource::ImplWhereBound, goal)),
440 )
441 }
442
443 fn consider_builtin_async_fn_kind_helper_candidate(
444 ecx: &mut EvalCtxt<'_, D>,
445 goal: Goal<I, Self>,
446 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
447 let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
448 ::core::panicking::panic("explicit panic");panic!();
449 };
450
451 let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else {
452 return Err(NoSolution.into());
454 };
455 let goal_kind = goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap();
456 if closure_kind.extends(goal_kind) {
457 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
458 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
459 } else {
460 Err(NoSolution.into())
461 }
462 }
463
464 fn consider_builtin_tuple_candidate(
471 ecx: &mut EvalCtxt<'_, D>,
472 goal: Goal<I, Self>,
473 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
474 if goal.predicate.polarity != ty::ClausePolarity::Positive {
475 return Err(NoSolution.into());
476 }
477
478 if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
479 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
480 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
481 } else {
482 Err(NoSolution.into())
483 }
484 }
485
486 fn consider_builtin_pointee_candidate(
487 ecx: &mut EvalCtxt<'_, D>,
488 goal: Goal<I, Self>,
489 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
490 if goal.predicate.polarity != ty::ClausePolarity::Positive {
491 return Err(NoSolution.into());
492 }
493
494 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
495 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
496 }
497
498 fn consider_builtin_future_candidate(
499 ecx: &mut EvalCtxt<'_, D>,
500 goal: Goal<I, Self>,
501 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
502 if goal.predicate.polarity != ty::ClausePolarity::Positive {
503 return Err(NoSolution.into());
504 }
505
506 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
507 return Err(NoSolution.into());
508 };
509
510 let cx = ecx.cx();
512 if !cx.coroutine_is_async(def_id) {
513 return Err(NoSolution.into());
514 }
515
516 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
520 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
521 }
522
523 fn consider_builtin_iterator_candidate(
524 ecx: &mut EvalCtxt<'_, D>,
525 goal: Goal<I, Self>,
526 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
527 if goal.predicate.polarity != ty::ClausePolarity::Positive {
528 return Err(NoSolution.into());
529 }
530
531 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
532 return Err(NoSolution.into());
533 };
534
535 let cx = ecx.cx();
537 if !cx.coroutine_is_gen(def_id) {
538 return Err(NoSolution.into());
539 }
540
541 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
545 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
546 }
547
548 fn consider_builtin_fused_iterator_candidate(
549 ecx: &mut EvalCtxt<'_, D>,
550 goal: Goal<I, Self>,
551 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
552 if goal.predicate.polarity != ty::ClausePolarity::Positive {
553 return Err(NoSolution.into());
554 }
555
556 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
557 return Err(NoSolution.into());
558 };
559
560 let cx = ecx.cx();
562 if !cx.coroutine_is_gen(def_id) {
563 return Err(NoSolution.into());
564 }
565
566 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
568 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
569 }
570
571 fn consider_builtin_async_iterator_candidate(
572 ecx: &mut EvalCtxt<'_, D>,
573 goal: Goal<I, Self>,
574 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
575 if goal.predicate.polarity != ty::ClausePolarity::Positive {
576 return Err(NoSolution.into());
577 }
578
579 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
580 return Err(NoSolution.into());
581 };
582
583 let cx = ecx.cx();
585 if !cx.coroutine_is_async_gen(def_id) {
586 return Err(NoSolution.into());
587 }
588
589 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
593 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
594 }
595
596 fn consider_builtin_coroutine_candidate(
597 ecx: &mut EvalCtxt<'_, D>,
598 goal: Goal<I, Self>,
599 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
600 if goal.predicate.polarity != ty::ClausePolarity::Positive {
601 return Err(NoSolution.into());
602 }
603
604 let self_ty = goal.predicate.self_ty();
605 let ty::Coroutine(def_id, args) = self_ty.kind() else {
606 return Err(NoSolution.into());
607 };
608
609 let cx = ecx.cx();
611 if !cx.is_general_coroutine(def_id) {
612 return Err(NoSolution.into());
613 }
614
615 let coroutine = args.as_coroutine();
616 Self::probe_and_consider_implied_clause(
617 ecx,
618 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
619 goal,
620 ty::TraitRef::new(cx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()])
621 .upcast(cx),
622 [],
625 )
626 }
627
628 fn consider_builtin_discriminant_kind_candidate(
629 ecx: &mut EvalCtxt<'_, D>,
630 goal: Goal<I, Self>,
631 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
632 if goal.predicate.polarity != ty::ClausePolarity::Positive {
633 return Err(NoSolution.into());
634 }
635
636 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
638 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
639 }
640
641 fn consider_builtin_destruct_candidate(
642 ecx: &mut EvalCtxt<'_, D>,
643 goal: Goal<I, Self>,
644 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
645 if goal.predicate.polarity != ty::ClausePolarity::Positive {
646 return Err(NoSolution.into());
647 }
648
649 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
652 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
653 }
654
655 fn consider_builtin_transmute_candidate(
656 ecx: &mut EvalCtxt<'_, D>,
657 goal: Goal<I, Self>,
658 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
659 if goal.predicate.polarity != ty::ClausePolarity::Positive {
660 return Err(NoSolution.into());
661 }
662
663 if goal.predicate.has_non_region_placeholders() {
665 return Err(NoSolution.into());
666 }
667
668 if goal.has_non_region_infer() {
671 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
672 }
673
674 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(
675 |ecx| -> Result<_, NoSolutionOrRerunNonErased> {
676 let assume = ecx.structurally_normalize_const(
677 goal.param_env,
678 goal.predicate.trait_ref.args.const_at(2),
679 )?;
680
681 let certainty = ecx.is_transmutable(
682 goal.predicate.trait_ref.args.type_at(0),
683 goal.predicate.trait_ref.args.type_at(1),
684 assume,
685 )?;
686 ecx.evaluate_added_goals_and_make_canonical_response(certainty)
687 },
688 )
689 }
690
691 fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
704 ecx: &mut EvalCtxt<'_, D>,
705 goal: Goal<I, Self>,
706 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
707 if goal.predicate.polarity != ty::ClausePolarity::Positive {
708 return Err(NoSolution.into());
709 }
710
711 let cx = ecx.cx();
712 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
713 let ty = goal.predicate.self_ty();
714 match ty.kind() {
715 ty::Ref(..) => {}
717 ty::Adt(def, _) if def.is_manually_drop() => {}
719 ty::Tuple(tys) => {
722 ecx.add_goals(
723 GoalSource::ImplWhereBound,
724 tys.iter().map(|elem_ty| {
725 goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty]))
726 }),
727 )?;
728 }
729 ty::Array(elem_ty, _) => {
730 ecx.add_goal(
731 GoalSource::ImplWhereBound,
732 goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty])),
733 )?;
734 }
735
736 ty::FnDef(..)
740 | ty::FnPtr(..)
741 | ty::Error(_)
742 | ty::Uint(_)
743 | ty::Int(_)
744 | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
745 | ty::Bool
746 | ty::Float(_)
747 | ty::Char
748 | ty::RawPtr(..)
749 | ty::Never
750 | ty::Pat(..)
751 | ty::Dynamic(..)
752 | ty::Str
753 | ty::Slice(_)
754 | ty::Foreign(..)
755 | ty::Adt(..)
756 | ty::Alias(..)
757 | ty::Param(_)
758 | ty::Placeholder(..)
759 | ty::Closure(..)
760 | ty::CoroutineClosure(..)
761 | ty::Coroutine(..)
762 | ty::UnsafeBinder(_)
763 | ty::CoroutineWitness(..) => {
764 ecx.add_goal(
765 GoalSource::ImplWhereBound,
766 goal.with(
767 cx,
768 ty::TraitRef::new(
769 cx,
770 cx.require_trait_lang_item(SolverTraitLangItem::Copy),
771 [ty],
772 ),
773 ),
774 )?;
775 }
776
777 ty::Bound(..)
778 | ty::Infer(
779 ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
780 ) => {
781 { ::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`", ty)); }panic!("unexpected type `{ty:?}`")
782 }
783 }
784
785 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
786 })
787 }
788
789 fn consider_structural_builtin_unsize_candidates(
797 ecx: &mut EvalCtxt<'_, D>,
798 goal: Goal<I, Self>,
799 ) -> Result<Vec<Candidate<I>>, RerunNonErased> {
800 if goal.predicate.polarity != ty::ClausePolarity::Positive {
801 return Ok(::alloc::vec::Vec::new()vec![]);
802 }
803
804 let result = ecx.probe(|_| ProbeKind::UnsizeAssembly).enter(
805 |ecx| -> Result<Vec<Candidate<I>>, NoSolutionOrRerunNonErased> {
806 let a_ty = goal.predicate.self_ty();
807 let b_ty = ecx.structurally_normalize_ty(
810 goal.param_env,
811 goal.predicate.trait_ref.args.type_at(1),
812 )?;
813
814 let goal = goal.with(ecx.cx(), (a_ty, b_ty));
815 match (a_ty.kind(), b_ty.kind()) {
816 (ty::Infer(ty::TyVar(..)), ..) => {
::core::panicking::panic_fmt(format_args!("unexpected infer {0:?} {1:?}",
a_ty, b_ty));
}panic!("unexpected infer {a_ty:?} {b_ty:?}"),
817
818 (_, ty::Infer(ty::TyVar(..))) => {
819 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?]))vec![ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?])
820 }
821
822 (ty::Dynamic(a_data, a_region), ty::Dynamic(b_data, b_region)) => Ok(ecx
824 .consider_builtin_dyn_upcast_candidates(
825 goal, a_data, a_region, b_data, b_region,
826 )),
827
828 (_, ty::Dynamic(b_region, b_data)) => Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region,
b_data)?]))vec![
830 ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data)?,
831 ]),
832
833 (ty::Array(a_elem_ty, ..), ty::Slice(b_elem_ty)) => {
835 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?]))vec![ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?])
836 }
837
838 (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args))
840 if a_def.is_struct() && a_def == b_def =>
841 {
842 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?]))vec![ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?])
843 }
844
845 _ => Err(NoSolution.into()),
846 }
847 },
848 );
849
850 match result.map_err_to_rerun()? {
851 Ok(resp) => Ok(resp),
852 Err(NoSolution) => Ok(::alloc::vec::Vec::new()vec![]),
853 }
854 }
855
856 fn consider_builtin_try_as_dyn_candidate(
857 ecx: &mut EvalCtxt<'_, D>,
858 goal: Goal<I, Self>,
859 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
860 if goal.predicate.polarity != ty::ClausePolarity::Positive {
861 return Err(NoSolution.into());
862 }
863 let cx = ecx.cx();
864
865 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
866 let self_ty = goal.predicate.self_ty();
867 let ty_lifetime = goal.predicate.trait_ref.args.region_at(1);
868 match self_ty.kind() {
869 ty::Dynamic(bounds, lifetime) => {
870 for bound in bounds.iter() {
871 match bound.skip_binder() {
872 ExistentialPredicate::Trait(_) => {}
873 ExistentialPredicate::Projection(_) => return Err(NoSolution.into()),
875 ExistentialPredicate::AutoTrait(_) => {}
878 }
879 }
880 ecx.add_goal(
881 GoalSource::Misc,
882 goal.with(cx, ty::OutlivesClause(ty_lifetime, lifetime)),
883 )?;
884 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
885 }
886
887 ty::Bound(..)
888 | ty::Infer(
889 ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
890 ) => {
891 {
::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`",
self_ty));
}panic!("unexpected type `{self_ty:?}`")
892 }
893
894 _ => Err(NoSolution.into()),
895 }
896 })
897 }
898
899 fn consider_builtin_field_candidate(
900 ecx: &mut EvalCtxt<'_, D>,
901 goal: Goal<I, Self>,
902 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
903 if goal.predicate.polarity != ty::ClausePolarity::Positive {
904 return Err(NoSolution.into());
905 }
906 if let ty::Adt(def, args) = goal.predicate.self_ty().kind()
907 && let Some(FieldInfo { base, ty, .. }) =
908 def.field_representing_type_info(ecx.cx(), args)
909 && {
910 let sized_trait = ecx.cx().require_trait_lang_item(SolverTraitLangItem::Sized);
911 ecx.add_goal(
919 GoalSource::ImplWhereBound,
920 Goal {
921 param_env: goal.param_env,
922 predicate: TraitRef::new(ecx.cx(), sized_trait, [base]).upcast(ecx.cx()),
923 },
924 )?;
925 ecx.add_goal(
926 GoalSource::ImplWhereBound,
927 Goal {
928 param_env: goal.param_env,
929 predicate: TraitRef::new(ecx.cx(), sized_trait, [ty]).upcast(ecx.cx()),
930 },
931 )?;
932 ecx.try_evaluate_added_goals()? == Certainty::Yes
935 }
936 && match base.kind() {
937 ty::Adt(def, _) => def.is_struct() && !def.is_packed(),
938 ty::Tuple(..) => true,
939 _ => false,
940 }
941 {
942 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
943 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
944 } else {
945 Err(NoSolution.into())
946 }
947 }
948}
949
950#[inline(always)]
956fn trait_predicate_with_def_id<I: Interner>(
957 cx: I,
958 clause: ty::Binder<I, ty::TraitClause<I>>,
959 did: I::TraitId,
960) -> I::Clause {
961 clause
962 .map_bound(|c| TraitClause {
963 trait_ref: TraitRef::new_from_args(cx, did, c.trait_ref.args),
964 polarity: c.polarity,
965 })
966 .upcast(cx)
967}
968
969impl<D, I> EvalCtxt<'_, D>
970where
971 D: SolverDelegate<Interner = I>,
972 I: Interner,
973{
974 fn consider_builtin_dyn_upcast_candidates(
984 &mut self,
985 goal: Goal<I, (I::Ty, I::Ty)>,
986 a_data: I::BoundExistentialPredicates,
987 a_region: Region<I>,
988 b_data: I::BoundExistentialPredicates,
989 b_region: Region<I>,
990 ) -> Vec<Candidate<I>> {
991 let cx = self.cx();
992 let Goal { predicate: (a_ty, _b_ty), .. } = goal;
993
994 let mut responses = ::alloc::vec::Vec::new()vec![];
995 let b_principal_def_id = b_data.principal_def_id();
998 if a_data.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
999 responses.extend(self.consider_builtin_upcast_to_principal(
1000 goal,
1001 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
1002 a_data,
1003 a_region,
1004 b_data,
1005 b_region,
1006 a_data.principal(),
1007 ));
1008 } else if let Some(a_principal) = a_data.principal() {
1009 for (idx, new_a_principal) in
1010 elaborate::supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty))
1011 .enumerate()
1012 .skip(1)
1013 {
1014 responses.extend(self.consider_builtin_upcast_to_principal(
1015 goal,
1016 CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting(idx)),
1017 a_data,
1018 a_region,
1019 b_data,
1020 b_region,
1021 Some(new_a_principal.map_bound(|trait_ref| {
1022 ty::ExistentialTraitRef::erase_self_ty(cx, trait_ref)
1023 })),
1024 ));
1025 }
1026 }
1027
1028 responses
1029 }
1030
1031 fn consider_builtin_unsize_to_dyn_candidate(
1032 &mut self,
1033 goal: Goal<I, (I::Ty, I::Ty)>,
1034 b_data: I::BoundExistentialPredicates,
1035 b_region: Region<I>,
1036 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1037 let cx = self.cx();
1038 let Goal { predicate: (a_ty, _), .. } = goal;
1039
1040 if b_data.principal_def_id().is_some_and(|def_id| !cx.trait_is_dyn_compatible(def_id)) {
1042 return Err(NoSolution.into());
1043 }
1044
1045 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1046 ecx.add_goals(
1049 GoalSource::ImplWhereBound,
1050 b_data.iter().map(|pred| goal.with(cx, pred.with_self_ty(cx, a_ty))),
1051 )?;
1052
1053 ecx.add_goal(
1055 GoalSource::ImplWhereBound,
1056 goal.with(
1057 cx,
1058 ty::TraitRef::new(
1059 cx,
1060 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
1061 [a_ty],
1062 ),
1063 ),
1064 )?;
1065
1066 ecx.add_goal(GoalSource::Misc, goal.with(cx, ty::OutlivesClause(a_ty, b_region)))?;
1068 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1069 })
1070 }
1071
1072 fn consider_builtin_upcast_to_principal(
1073 &mut self,
1074 goal: Goal<I, (I::Ty, I::Ty)>,
1075 source: CandidateSource<I>,
1076 a_data: I::BoundExistentialPredicates,
1077 a_region: Region<I>,
1078 b_data: I::BoundExistentialPredicates,
1079 b_region: Region<I>,
1080 upcast_principal: Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>,
1081 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1082 let param_env = goal.param_env;
1083
1084 let a_auto_traits: IndexSet<I::TraitId> = a_data
1088 .auto_traits()
1089 .into_iter()
1090 .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
1091 self.cx()
1092 .supertrait_def_ids(principal_def_id)
1093 .filter(|def_id| self.cx().trait_is_auto(*def_id))
1094 }))
1095 .collect();
1096
1097 let projection_may_match =
1102 |ecx: &mut EvalCtxt<'_, D>,
1103 source_projection: ty::Binder<I, ty::ExistentialProjection<I>>,
1104 target_projection: ty::Binder<I, ty::ExistentialProjection<I>>|
1105 -> Result<bool, RerunNonErased> {
1106 if source_projection.item_def_id() != target_projection.item_def_id() {
1107 return Ok(false);
1108 }
1109 match ecx.probe(|_| ProbeKind::ProjectionCompatibility).enter(|ecx| {
1110 let target_projection = ecx.deeply_resolve_ignoring_regions(target_projection);
1111 ecx.enter_forall_with_assumptions(
1112 target_projection,
1113 param_env,
1114 |ecx, target_projection| {
1115 let source_projection =
1116 ecx.instantiate_binder_with_infer(source_projection);
1117 ecx.eq(param_env, source_projection, target_projection)?;
1118 ecx.try_evaluate_added_goals()
1119 },
1120 )
1121 }) {
1122 Ok(_) => Ok(true),
1123 Err(NoSolutionOrRerunNonErased::NoSolution(_)) => Ok(false),
1124 Err(NoSolutionOrRerunNonErased::RerunNonErased(rerun)) => Err(rerun),
1125 }
1126 };
1127
1128 self.probe_trait_candidate(source).enter(|ecx| {
1129 for bound in b_data.iter() {
1130 match bound.skip_binder() {
1131 ty::ExistentialPredicate::Trait(target_principal) => {
1134 let source_principal = upcast_principal.unwrap();
1135 let target_principal = bound.rebind(target_principal);
1136 let target_principal =
1138 ecx.deeply_resolve_ignoring_regions(target_principal);
1139 ecx.enter_forall_with_assumptions(
1140 target_principal,
1141 param_env,
1142 |ecx, target_principal| {
1143 let source_principal =
1144 ecx.instantiate_binder_with_infer(source_principal);
1145 ecx.eq(param_env, source_principal, target_principal)?;
1146 ecx.try_evaluate_added_goals()
1147 },
1148 )?;
1149 }
1150 ty::ExistentialPredicate::Projection(target_projection) => {
1156 let target_projection = bound.rebind(target_projection);
1157 let mut matching_projection = None;
1158 for source_projection in a_data.projection_bounds() {
1159 if projection_may_match(ecx, source_projection, target_projection)? {
1160 if matching_projection.is_some() {
1161 return ecx.evaluate_added_goals_and_make_canonical_response(
1162 Certainty::AMBIGUOUS,
1163 );
1164 }
1165 matching_projection = Some(source_projection);
1166 }
1167 }
1168 let Some(matching) = matching_projection else {
1169 return Err(NoSolution.into());
1170 };
1171
1172 let target_projection =
1174 ecx.deeply_resolve_ignoring_regions(target_projection);
1175 ecx.enter_forall_with_assumptions(
1176 target_projection,
1177 param_env,
1178 |ecx, target_projection| {
1179 let source_projection = ecx.instantiate_binder_with_infer(matching);
1180 ecx.eq(param_env, source_projection, target_projection)?;
1181 ecx.try_evaluate_added_goals()
1182 },
1183 )?;
1184 }
1185 ty::ExistentialPredicate::AutoTrait(def_id) => {
1187 if !a_auto_traits.contains(&def_id) {
1188 return Err(NoSolution.into());
1189 }
1190 }
1191 }
1192 }
1193
1194 ecx.add_goal(
1196 GoalSource::ImplWhereBound,
1197 Goal::new(ecx.cx(), param_env, ty::OutlivesClause(a_region, b_region)),
1198 )?;
1199
1200 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1201 })
1202 }
1203
1204 fn consider_builtin_array_unsize(
1213 &mut self,
1214 goal: Goal<I, (I::Ty, I::Ty)>,
1215 a_elem_ty: I::Ty,
1216 b_elem_ty: I::Ty,
1217 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1218 self.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
1219 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1220 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1221 }
1222
1223 fn consider_builtin_struct_unsize(
1237 &mut self,
1238 goal: Goal<I, (I::Ty, I::Ty)>,
1239 def: I::AdtDef,
1240 a_args: I::GenericArgs,
1241 b_args: I::GenericArgs,
1242 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1243 let cx = self.cx();
1244 let Goal { predicate: (_a_ty, b_ty), .. } = goal;
1245
1246 let unsizing_params = cx.unsizing_params_for_adt(def.def_id());
1247 if unsizing_params.is_empty() {
1250 return Err(NoSolution.into());
1251 }
1252
1253 let tail_field_ty = def.struct_tail_ty(cx).unwrap();
1254
1255 let a_tail_ty = tail_field_ty.instantiate(cx, a_args).skip_norm_wip();
1256 let b_tail_ty = tail_field_ty.instantiate(cx, b_args).skip_norm_wip();
1257
1258 let new_a_args = cx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
1262 if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
1263 }));
1264 let unsized_a_ty = Ty::new_adt(cx, def, new_a_args);
1265
1266 self.eq(goal.param_env, unsized_a_ty, b_ty)?;
1269 self.add_goal(
1270 GoalSource::ImplWhereBound,
1271 goal.with(
1272 cx,
1273 ty::TraitRef::new(
1274 cx,
1275 cx.require_trait_lang_item(SolverTraitLangItem::Unsize),
1276 [a_tail_ty, b_tail_ty],
1277 ),
1278 ),
1279 )?;
1280 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1281 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1282 }
1283
1284 fn consider_auto_trait_candidate_for_opaque_ty(
1285 &mut self,
1286 goal: Goal<I, TraitClause<I>>,
1287 def_id: I::OpaqueTyId,
1288 args: I::GenericArgs,
1289 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1290 let cx = self.cx();
1291 let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
1292
1293 for item_bound in cx.item_self_bounds(def_id.into()).skip_binder() {
1294 if item_bound.as_trait_clause().is_some_and(|b| b.def_id() == goal.predicate.def_id()) {
1295 return Err(NoSolution.into());
1296 }
1297 }
1298
1299 let candidate = self.probe_trait_candidate(source).enter(|ecx| {
1300 let hidden_ty = cx.type_of(def_id.into()).instantiate(cx, args).skip_norm_wip();
1301 ecx.add_goal(
1302 GoalSource::ImplWhereBound,
1303 goal.with(cx, goal.predicate.with_replaced_self_ty(cx, hidden_ty)),
1304 )?;
1305 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1306 })?;
1307
1308 if !candidate.result.value.var_values.is_identity_modulo_regions() {
1311 return self.forced_ambiguity(MaybeInfo::AMBIGUOUS);
1312 }
1313
1314 let ExternalConstraintsData {
1315 region_constraints: _,
1316 ref opaque_types,
1317 ref normalization_nested_goals,
1318 } = *candidate.result.value.external_constraints;
1319 if true {
if !normalization_nested_goals.is_empty() {
::core::panicking::panic("assertion failed: normalization_nested_goals.is_empty()")
};
};debug_assert!(normalization_nested_goals.is_empty());
1320
1321 if !opaque_types.is_empty() {
1326 let typing_mode = self.typing_mode();
1327
1328 match typing_mode {
1329 TypingMode::PostTypeckUntilBorrowck { .. } => {}
1333 TypingMode::Typeck { .. } => {
1336 return self.forced_ambiguity(MaybeInfo::AMBIGUOUS);
1337 }
1338 TypingMode::Coherence
1340 | TypingMode::PostBorrowck { .. }
1341 | TypingMode::Reflection
1342 | TypingMode::PostAnalysis
1343 | TypingMode::Codegen
1344 | TypingMode::ErasedNotCoherence(MayBeErased) => {
1345 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("we never add new uses to opaque types in typing mode {0:?}",
typing_mode)));
};unreachable!(
1346 "we never add new uses to opaque types in typing mode {typing_mode:?}"
1347 );
1348 }
1349 }
1350 }
1351
1352 Ok(candidate)
1353 }
1354
1355 fn disqualify_auto_trait_candidate_due_to_possible_impl(
1360 &mut self,
1361 goal: Goal<I, TraitClause<I>>,
1362 ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1363 let self_ty = goal.predicate.self_ty();
1364 let check_impls = || {
1365 let mut disqualifying_impl = None;
1366 self.cx().for_each_relevant_impl(goal.predicate.trait_ref, |impl_def_id| {
1367 disqualifying_impl = Some(impl_def_id);
1368 });
1369 if let Some(def_id) = disqualifying_impl {
1370 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1370",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1370u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("goal")
}> =
::tracing::__macro_support::FieldName::new("goal");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("disqualified auto-trait implementation")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};trace!(?def_id, ?goal, "disqualified auto-trait implementation");
1371 return Some(Err(NoSolution.into()));
1374 } else {
1375 None
1376 }
1377 };
1378
1379 match self_ty.kind() {
1380 ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
1386 Some(self.forced_ambiguity(MaybeInfo::AMBIGUOUS))
1387 }
1388
1389 ty::Foreign(..) if self.cx().is_default_trait(goal.predicate.def_id()) => check_impls(),
1392
1393 ty::Dynamic(..)
1396 | ty::Param(..)
1397 | ty::Foreign(..)
1398 | ty::Alias(
1399 ty::IsRigid::Yes,
1400 ty::AliasTy {
1401 kind: ty::Projection { .. } | ty::Free { .. } | ty::Inherent { .. },
1402 ..
1403 },
1404 )
1405 | ty::Placeholder(..) => Some(Err(NoSolution.into())),
1406
1407 ty::Coroutine(def_id, _)
1411 if self
1412 .cx()
1413 .is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::Unpin) =>
1414 {
1415 match self.cx().coroutine_movability(def_id) {
1416 Movability::Static => Some(Err(NoSolution.into())),
1417 Movability::Movable => Some(
1418 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1419 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1420 }),
1421 ),
1422 }
1423 }
1424
1425 ty::Alias(ty::IsRigid::Yes, ty::AliasTy { kind: ty::Opaque { .. }, .. }) => None,
1430
1431 ty::Bool
1438 | ty::Char
1439 | ty::Int(_)
1440 | ty::Uint(_)
1441 | ty::Float(_)
1442 | ty::Str
1443 | ty::Array(_, _)
1444 | ty::Pat(_, _)
1445 | ty::Slice(_)
1446 | ty::RawPtr(_, _)
1447 | ty::Ref(_, _, _)
1448 | ty::FnDef(_, _)
1449 | ty::FnPtr(..)
1450 | ty::Closure(..)
1451 | ty::CoroutineClosure(..)
1452 | ty::Coroutine(_, _)
1453 | ty::CoroutineWitness(..)
1454 | ty::Never
1455 | ty::Tuple(_)
1456 | ty::Adt(_, _)
1457 | ty::UnsafeBinder(_) => check_impls(),
1458 ty::Error(_) => None,
1459
1460 ty::Infer(_) | ty::Alias(ty::IsRigid::No, _) | ty::Bound(_, _) => {
1461 {
::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`",
self_ty));
}panic!("unexpected type `{self_ty:?}`")
1462 }
1463 }
1464 }
1465
1466 fn probe_and_evaluate_goal_for_constituent_tys(
1471 &mut self,
1472 source: CandidateSource<I>,
1473 goal: Goal<I, TraitClause<I>>,
1474 constituent_tys: impl Fn(
1475 &EvalCtxt<'_, D>,
1476 I::Ty,
1477 ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>,
1478 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1479 self.probe_trait_candidate(source).enter(|ecx| {
1480 let goals = ecx.enter_forall_with_assumptions(
1481 constituent_tys(ecx, goal.predicate.self_ty())?,
1482 goal.param_env,
1483 |ecx, tys| {
1484 tys.into_iter()
1485 .map(|ty| {
1486 goal.with(ecx.cx(), goal.predicate.with_replaced_self_ty(ecx.cx(), ty))
1487 })
1488 .collect::<Vec<_>>()
1489 },
1490 );
1491 ecx.add_goals(GoalSource::ImplWhereBound, goals)?;
1492 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1493 })
1494 }
1495}
1496
1497#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TraitGoalProvenVia {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
TraitGoalProvenVia::Misc => "Misc",
TraitGoalProvenVia::ParamEnv => "ParamEnv",
TraitGoalProvenVia::AliasBound => "AliasBound",
})
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TraitGoalProvenVia { }
#[automatically_derived]
impl ::core::clone::Clone for TraitGoalProvenVia {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TraitGoalProvenVia { }Copy)]
1508pub(super) enum TraitGoalProvenVia {
1509 Misc,
1515 ParamEnv,
1516 AliasBound,
1517}
1518
1519impl<D, I> EvalCtxt<'_, D>
1520where
1521 D: SolverDelegate<Interner = I>,
1522 I: Interner,
1523{
1524 pub(super) fn unsound_prefer_builtin_dyn_impl(&mut self, candidates: &mut Vec<Candidate<I>>) {
1537 if self.typing_mode().is_coherence() {
1538 return;
1539 }
1540
1541 if candidates
1542 .iter()
1543 .find(|c| {
1544 #[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)) => true,
_ => false,
}matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)))
1545 })
1546 .is_some_and(|c| has_only_region_constraints(c.result))
1547 {
1548 candidates.retain(|c| {
1549 if #[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::Impl(_) => true,
_ => false,
}matches!(c.source, CandidateSource::Impl(_)) {
1550 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1550",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1550u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("c")
}> =
::tracing::__macro_support::FieldName::new("c");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("unsoundly dropping impl in favor of builtin dyn-candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&c)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?c, "unsoundly dropping impl in favor of builtin dyn-candidate");
1551 false
1552 } else {
1553 true
1554 }
1555 });
1556 }
1557 }
1558
1559 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("merge_trait_candidates",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1559u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("candidate_preference_mode")
}> =
::tracing::__macro_support::FieldName::new("candidate_preference_mode");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("candidates")
}> =
::tracing::__macro_support::FieldName::new("candidates");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("failed_candidate_info")
}> =
::tracing::__macro_support::FieldName::new("failed_candidate_info");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&candidate_preference_mode)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&candidates)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&failed_candidate_info)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>),
NoSolution> = loop {};
return __tracing_attr_fake_return;
}
{
if self.typing_mode().is_coherence() {
return if let Some((response, _)) =
self.try_merge_candidates(&candidates) {
Ok((response, Some(TraitGoalProvenVia::Misc)))
} else { self.flounder(&candidates).map(|r| (r, None)) };
}
let mut trivial_builtin_impls =
candidates.iter().filter(|c|
{
#[allow(non_exhaustive_omitted_patterns)]
match c.source {
CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial) =>
true,
_ => false,
}
});
if let Some(candidate) = trivial_builtin_impls.next() {
if !trivial_builtin_impls.next().is_none() {
::core::panicking::panic("assertion failed: trivial_builtin_impls.next().is_none()")
};
return Ok((candidate.result,
Some(TraitGoalProvenVia::Misc)));
}
if #[allow(non_exhaustive_omitted_patterns)] match candidate_preference_mode
{
CandidatePreferenceMode::Marker => true,
_ => false,
} &&
candidates.iter().any(|c|
{
#[allow(non_exhaustive_omitted_patterns)]
match c.source {
CandidateSource::AliasBound(AliasBoundKind::SelfBounds) =>
true,
_ => false,
}
}) {
let alias_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(..) => true,
_ => false,
}).collect();
return if let Some((response, _)) =
self.try_merge_candidates(&alias_bounds) {
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
} else {
Ok((self.bail_with_ambiguity(&alias_bounds), None))
};
}
let has_non_global_where_bounds =
candidates.iter().any(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal) =>
true,
_ => false,
});
if has_non_global_where_bounds {
let where_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(_) => true,
_ => false,
}).collect();
let Some((response, info)) =
self.try_merge_candidates(&where_bounds) else {
return Ok((self.bail_with_ambiguity(&where_bounds), None));
};
match info {
MergeCandidateInfo::AlwaysApplicable(i) => {
for (j, c) in where_bounds.into_iter().enumerate() {
if i != j {
self.ignore_candidate_head_usages(c.head_usages)
}
}
self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages);
}
MergeCandidateInfo::EqualResponse => {}
}
return Ok((response, Some(TraitGoalProvenVia::ParamEnv)));
}
if candidates.iter().any(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(_) => true,
_ => false,
}) {
let alias_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(_) => true,
_ => false,
}).collect();
return if let Some((response, _)) =
self.try_merge_candidates(&alias_bounds) {
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
} else {
Ok((self.bail_with_ambiguity(&alias_bounds), None))
};
}
self.filter_specialized_impls(AllowInferenceConstraints::No,
&mut candidates);
self.unsound_prefer_builtin_dyn_impl(&mut candidates);
let proven_via =
if candidates.iter().all(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::Global) => true,
_ => false,
}) {
TraitGoalProvenVia::ParamEnv
} else {
candidates.retain(|c|
!#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::Global) => true,
_ => false,
});
TraitGoalProvenVia::Misc
};
if let Some((response, _)) =
self.try_merge_candidates(&candidates) {
Ok((response, Some(proven_via)))
} else { self.flounder(&candidates).map(|r| (r, None)) }
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1559",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1559u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(self), ret)]
1560 pub(super) fn merge_trait_candidates(
1561 &mut self,
1562 candidate_preference_mode: CandidatePreferenceMode,
1563 mut candidates: Vec<Candidate<I>>,
1564 failed_candidate_info: FailedCandidateInfo,
1565 ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
1566 if self.typing_mode().is_coherence() {
1567 return if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1568 Ok((response, Some(TraitGoalProvenVia::Misc)))
1569 } else {
1570 self.flounder(&candidates).map(|r| (r, None))
1571 };
1572 }
1573
1574 let mut trivial_builtin_impls = candidates.iter().filter(|c| {
1579 matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))
1580 });
1581 if let Some(candidate) = trivial_builtin_impls.next() {
1582 assert!(trivial_builtin_impls.next().is_none());
1585 return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
1586 }
1587
1588 if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
1591 && candidates.iter().any(|c| {
1592 matches!(c.source, CandidateSource::AliasBound(AliasBoundKind::SelfBounds))
1593 })
1594 {
1595 let alias_bounds: Vec<_> = candidates
1596 .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(..)))
1597 .collect();
1598 return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1599 Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1600 } else {
1601 Ok((self.bail_with_ambiguity(&alias_bounds), None))
1602 };
1603 }
1604
1605 let has_non_global_where_bounds = candidates
1608 .iter()
1609 .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
1610 if has_non_global_where_bounds {
1611 let where_bounds: Vec<_> = candidates
1612 .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_)))
1613 .collect();
1614 let Some((response, info)) = self.try_merge_candidates(&where_bounds) else {
1615 return Ok((self.bail_with_ambiguity(&where_bounds), None));
1616 };
1617 match info {
1618 MergeCandidateInfo::AlwaysApplicable(i) => {
1634 for (j, c) in where_bounds.into_iter().enumerate() {
1635 if i != j {
1636 self.ignore_candidate_head_usages(c.head_usages)
1637 }
1638 }
1639 self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages);
1643 }
1644 MergeCandidateInfo::EqualResponse => {}
1645 }
1646 return Ok((response, Some(TraitGoalProvenVia::ParamEnv)));
1647 }
1648
1649 if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound(_))) {
1651 let alias_bounds: Vec<_> = candidates
1652 .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(_)))
1653 .collect();
1654 return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1655 Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1656 } else {
1657 Ok((self.bail_with_ambiguity(&alias_bounds), None))
1658 };
1659 }
1660
1661 self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
1662 self.unsound_prefer_builtin_dyn_impl(&mut candidates);
1663
1664 let proven_via = if candidates
1669 .iter()
1670 .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
1671 {
1672 TraitGoalProvenVia::ParamEnv
1673 } else {
1674 candidates
1675 .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
1676 TraitGoalProvenVia::Misc
1677 };
1678
1679 if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1680 Ok((response, Some(proven_via)))
1681 } else {
1682 self.flounder(&candidates).map(|r| (r, None))
1683 }
1684 }
1685
1686 {}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("compute_trait_goal",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6eeff9a52c3e35c4c4cbf5651f342dcd2191866f/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1686u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("goal")
}> =
::tracing::__macro_support::FieldName::new("goal");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>),
NoSolutionOrRerunNonErased> = loop {};
return __tracing_attr_fake_return;
}
{
let (candidates, failed_candidate_info) =
self.assemble_and_evaluate_candidates(goal,
AssembleCandidatesFrom::All)?;
let candidate_preference_mode =
CandidatePreferenceMode::compute(self.cx(),
goal.predicate.def_id());
self.merge_trait_candidates(candidate_preference_mode, candidates,
failed_candidate_info).map_err(Into::into)
}
}
}#[instrument(level = "trace", skip(self))]
1687 pub(super) fn compute_trait_goal(
1688 &mut self,
1689 goal: Goal<I, TraitClause<I>>,
1690 ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolutionOrRerunNonErased>
1691 {
1692 let (candidates, failed_candidate_info) =
1693 self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All)?;
1694 let candidate_preference_mode =
1695 CandidatePreferenceMode::compute(self.cx(), goal.predicate.def_id());
1696 self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info)
1697 .map_err(Into::into)
1698 }
1699
1700 fn try_stall_coroutine(
1701 &mut self,
1702 self_ty: I::Ty,
1703 ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1704 if let ty::Coroutine(def_id, _) = self_ty.kind() {
1705 match self.typing_mode() {
1706 TypingMode::Typeck { defining_opaque_types_and_generators: stalled_generators } => {
1707 if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
1708 {
1709 return Some(self.forced_ambiguity(MaybeInfo {
1710 cause: MaybeCause::Ambiguity,
1711 opaque_types_jank: OpaqueTypesJank::AllGood,
1712 stalled_on_coroutines: StalledOnCoroutines::Yes,
1713 }));
1714 }
1715 }
1716 TypingMode::ErasedNotCoherence(MayBeErased) => {
1717 return Some(
1719 match self.opaque_accesses.rerun_always(RerunReason::TryStallCoroutine) {
1720 Err(e) => Err(e.into()),
1721 },
1722 );
1723 }
1724 TypingMode::Coherence
1725 | TypingMode::PostAnalysis
1726 | TypingMode::Reflection
1727 | TypingMode::Codegen
1728 | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ }
1729 | TypingMode::PostBorrowck { defined_opaque_types: _ } => {}
1730 }
1731 }
1732
1733 None
1734 }
1735}