1use std::debug_assert_matches;
2
3use rustc_type_ir::fast_reject::DeepRejectCtxt;
4use rustc_type_ir::inherent::*;
5use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
6use rustc_type_ir::solve::{
7 FetchEligibleAssocItemResponse, NoSolutionOrRerunNonErased, QueryResultOrRerunNonErased,
8 RerunNonErased, RerunReason, RerunResultExt,
9};
10use rustc_type_ir::{
11 self as ty, Const, FieldInfo, Interner, NormalizesTo, PredicateKind, Region, Unnormalized,
12 Upcast as _,
13};
14use tracing::instrument;
15
16use crate::delegate::SolverDelegate;
17use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
18use crate::solve::assembly::{self, Candidate};
19use crate::solve::inspect::ProbeKind;
20use crate::solve::{
21 BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeInfo,
22 NoSolution, SizedTraitKind,
23};
24
25impl<D, I> EvalCtxt<'_, D>
26where
27 D: SolverDelegate<Interner = I>,
28 I: Interner,
29{
30 {}
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_normalizes_to_goal",
"rustc_next_trait_solver::solve::normalizes_to",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs"),
::tracing_core::__macro_support::Option::Some(30u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::normalizes_to"),
::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();
}
#[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:
QueryResultOrRerunNonErased<I> = loop {};
return __tracing_attr_fake_return;
}
{
if true {
if !self.term_is_fully_unconstrained(goal) {
::core::panicking::panic("assertion failed: self.term_is_fully_unconstrained(goal)")
};
};
if true {
{
match goal.predicate.alias.kind {
ty::AliasTermKind::ProjectionTy { .. } |
ty::AliasTermKind::ProjectionConst { .. } => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ty::AliasTermKind::ProjectionTy { .. } |\nty::AliasTermKind::ProjectionConst { .. }",
::core::option::Option::None);
}
}
};
};
let cx = self.cx();
let trait_ref = goal.predicate.alias.trait_ref(cx);
let (_, proven_via) =
self.probe(|_|
ProbeKind::ShadowedEnvProbing).enter(|ecx|
{
let trait_goal: Goal<I, ty::TraitClause<I>> =
goal.with(cx, trait_ref);
ecx.compute_trait_goal(trait_goal)
})?;
self.assemble_and_merge_candidates(proven_via, goal,
|ecx|
{
for arg in goal.predicate.alias.own_args(cx).iter() {
let Some(term) = arg.as_term() else { continue; };
match ecx.structurally_normalize_term(goal.param_env, term)
{
Ok(term) => {
if term.is_infer() {
return Some(ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS));
}
}
Err(e @
(NoSolutionOrRerunNonErased::NoSolution(NoSolution) |
NoSolutionOrRerunNonErased::RerunNonErased(_))) => {
return Some(Err(e));
}
}
}
None
},
|ecx|
{
ecx.probe(|&result|
ProbeKind::RigidAlias {
result,
}).enter(|this|
{
this.instantiate_normalizes_to_as_rigid(goal)?;
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
})
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs:30",
"rustc_next_trait_solver::solve::normalizes_to",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs"),
::tracing_core::__macro_support::Option::Some(30u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::normalizes_to"),
::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::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(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "trace", skip(self), ret)]
31 pub(super) fn compute_normalizes_to_goal(
32 &mut self,
33 goal: Goal<I, NormalizesTo<I>>,
34 ) -> QueryResultOrRerunNonErased<I> {
35 debug_assert!(self.term_is_fully_unconstrained(goal));
36 debug_assert_matches!(
37 goal.predicate.alias.kind,
38 ty::AliasTermKind::ProjectionTy { .. } | ty::AliasTermKind::ProjectionConst { .. }
39 );
40
41 let cx = self.cx();
42
43 let trait_ref = goal.predicate.alias.trait_ref(cx);
44 let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
45 let trait_goal: Goal<I, ty::TraitClause<I>> = goal.with(cx, trait_ref);
46 ecx.compute_trait_goal(trait_goal)
47 })?;
48 self.assemble_and_merge_candidates(
49 proven_via,
50 goal,
51 |ecx| {
52 for arg in goal.predicate.alias.own_args(cx).iter() {
62 let Some(term) = arg.as_term() else {
63 continue;
64 };
65 match ecx.structurally_normalize_term(goal.param_env, term) {
66 Ok(term) => {
67 if term.is_infer() {
68 return Some(ecx.evaluate_added_goals_and_make_canonical_response(
69 Certainty::AMBIGUOUS,
70 ));
71 }
72 }
73 Err(
74 e @ (NoSolutionOrRerunNonErased::NoSolution(NoSolution)
75 | NoSolutionOrRerunNonErased::RerunNonErased(_)),
76 ) => {
77 return Some(Err(e));
78 }
79 }
80 }
81
82 None
83 },
84 |ecx| {
85 ecx.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
86 this.instantiate_normalizes_to_as_rigid(goal)?;
87 this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
88 })
89 },
90 )
91 }
92
93 pub fn push_const_arg_has_type_goal(
96 &mut self,
97 param_env: I::ParamEnv,
98 alias: ty::AliasTerm<I>,
99 term: I::Term,
100 ) -> Result<(), NoSolutionOrRerunNonErased> {
101 if let Some(ct) = term.as_const() {
102 let cx = self.cx();
103 let expected_ty = alias.expect_ct().type_of(cx).skip_norm_wip();
104 self.add_goal(
105 GoalSource::Misc,
106 Goal {
107 param_env,
108 predicate: ty::ClauseKind::ConstArgHasType(ct, expected_ty).upcast(cx),
109 },
110 )?;
111 }
112 Ok(())
113 }
114
115 fn instantiate_normalizes_to_term(
138 &mut self,
139 goal: Goal<I, NormalizesTo<I>>,
140 value: I::Term,
141 ) -> Result<(), NoSolutionOrRerunNonErased> {
142 self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.alias, value)?;
143 self.eq(goal.param_env, goal.predicate.term, value)?;
147 Ok(())
148 }
149
150 fn instantiate_normalizes_to_as_rigid(
151 &mut self,
152 goal: Goal<I, NormalizesTo<I>>,
153 ) -> Result<(), NoSolutionOrRerunNonErased> {
154 self.eq(
155 goal.param_env,
156 goal.predicate.term,
157 goal.predicate.alias.to_term(self.cx(), ty::IsRigid::Yes),
158 )
159 }
160}
161
162impl<D, I> assembly::GoalKind<D> for NormalizesTo<I>
163where
164 D: SolverDelegate<Interner = I>,
165 I: Interner,
166{
167 fn self_ty(self) -> I::Ty {
168 self.self_ty()
169 }
170
171 fn trait_ref(self, cx: I) -> ty::TraitRef<I> {
172 self.alias.trait_ref(cx)
173 }
174
175 fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
176 self.with_replaced_self_ty(cx, self_ty)
177 }
178
179 fn trait_def_id(self, cx: I) -> I::TraitId {
180 self.trait_def_id(cx)
181 }
182
183 fn fast_reject_assumption(
184 ecx: &mut EvalCtxt<'_, D>,
185 goal: Goal<I, Self>,
186 assumption: I::Clause,
187 ) -> Result<(), NoSolution> {
188 let alias_def_id = match goal.predicate.alias.kind {
189 ty::AliasTermKind::ProjectionTy { def_id } => def_id.into(),
190 ty::AliasTermKind::ProjectionConst { def_id } => def_id.into(),
191 _ => return Err(NoSolution),
192 };
193 if let Some(projection_pred) = assumption.as_projection_clause()
194 && projection_pred.item_def_id() == alias_def_id
195 && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
196 goal.predicate.alias.args,
197 projection_pred.skip_binder().projection_term.args,
198 )
199 {
200 Ok(())
201 } else {
202 Err(NoSolution)
203 }
204 }
205
206 fn match_assumption(
207 ecx: &mut EvalCtxt<'_, D>,
208 goal: Goal<I, Self>,
209 assumption: I::Clause,
210 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
211 ) -> QueryResultOrRerunNonErased<I> {
212 let cx = ecx.cx();
213 let projection_pred = assumption.as_projection_clause().unwrap();
214 let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
215 ecx.eq(goal.param_env, goal.predicate.alias, assumption_projection_pred.projection_term)?;
216
217 ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term)?;
218
219 ecx.add_goals(
222 GoalSource::AliasWellFormed,
223 cx.own_clauses_of(goal.predicate.alias.expect_projection_def_id().into())
224 .iter_instantiated(cx, goal.predicate.alias.args)
225 .map(Unnormalized::skip_norm_wip)
226 .map(|clause| goal.with(cx, clause)),
227 )?;
228
229 then(ecx)
230 }
231
232 fn probe_and_consider_object_bound_candidate(
236 ecx: &mut EvalCtxt<'_, D>,
237 source: CandidateSource<I>,
238 goal: Goal<I, Self>,
239 assumption: I::Clause,
240 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
241 Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
242 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
243 })
244 }
245
246 fn consider_additional_alias_assumptions(
247 _ecx: &mut EvalCtxt<'_, D>,
248 _goal: Goal<I, Self>,
249 _alias_ty: ty::AliasTy<I>,
250 ) -> Vec<Candidate<I>> {
251 ::alloc::vec::Vec::new()vec![]
252 }
253
254 fn consider_impl_candidate(
255 ecx: &mut EvalCtxt<'_, D>,
256 goal: Goal<I, NormalizesTo<I>>,
257 goal_trait_ref: ty::TraitRef<I>,
258 impl_def_id: I::ImplId,
259 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
260 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
261 let cx = ecx.cx();
262
263 let alias_def_id = goal.predicate.alias.expect_projection_def_id();
264 let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
265 if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
266 .args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args)
267 {
268 return Err(NoSolution.into());
269 }
270
271 if cx.impl_is_default(impl_def_id) {
275 return Err(NoSolution.into());
276 }
277
278 let impl_polarity = cx.impl_polarity(impl_def_id);
280 match impl_polarity {
281 ty::ImplPolarity::Negative => return Err(NoSolution.into()),
282 ty::ImplPolarity::Positive => {}
283 };
284
285 ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
286 let impl_args = ecx.fresh_args_for_item(impl_def_id.into());
287 let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();
288
289 ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
290
291 let where_clause_bounds = cx
292 .clauses_of(impl_def_id.into())
293 .iter_instantiated(cx, impl_args)
294 .map(Unnormalized::skip_norm_wip)
295 .map(|clause| goal.with(cx, clause));
296 ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;
297
298 ecx.try_evaluate_added_goals()?;
303
304 ecx.add_goals(
308 GoalSource::AliasWellFormed,
309 cx.own_clauses_of(alias_def_id.into())
310 .iter_instantiated(cx, goal.predicate.alias.args)
311 .map(Unnormalized::skip_norm_wip)
312 .map(|clause| goal.with(cx, clause)),
313 )?;
314
315 let error_response = |ecx: &mut EvalCtxt<'_, D>, guar| {
316 let error_term = match goal.predicate.alias.kind {
317 ty::AliasTermKind::ProjectionTy { .. } => Ty::new_error(cx, guar).into(),
318 ty::AliasTermKind::ProjectionConst { .. } => Const::new_error(cx, guar).into(),
319 kind => {
::core::panicking::panic_fmt(format_args!("expected projection, found {0:?}",
kind));
}panic!("expected projection, found {kind:?}"),
320 };
321 ecx.instantiate_normalizes_to_term(goal, error_term)?;
322 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
323 };
324
325 let target_item_def_id =
326 match ecx.fetch_eligible_assoc_item(goal_trait_ref, alias_def_id, impl_def_id) {
327 FetchEligibleAssocItemResponse::Found(target_item_def_id) => target_item_def_id,
328 FetchEligibleAssocItemResponse::NotFound(tm) => {
329 match tm {
330 ty::TypingMode::Coherence => {
342 ecx.add_goal(
343 GoalSource::Misc,
344 goal.with(cx, PredicateKind::Ambiguous),
345 )?;
346 return ecx.evaluate_added_goals_and_make_canonical_response(
347 Certainty::Yes,
348 );
349 }
350 ty::TypingMode::Typeck { .. }
352 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
353 | ty::TypingMode::PostBorrowck { .. }
354 | ty::TypingMode::PostAnalysis
355 | ty::TypingMode::Reflection
356 | ty::TypingMode::Codegen => {
357 ecx.instantiate_normalizes_to_as_rigid(goal)?;
358 return ecx.evaluate_added_goals_and_make_canonical_response(
359 Certainty::Yes,
360 );
361 }
362 };
363 }
364 FetchEligibleAssocItemResponse::Err(guar) => return error_response(ecx, guar),
365 FetchEligibleAssocItemResponse::NotFoundBecauseErased => {
366 match ecx
367 .opaque_accesses
368 .rerun_always(RerunReason::FetchEligibleAssocItem)? {}
369 }
370 };
371
372 if !cx.has_item_definition(target_item_def_id) {
373 if cx.impl_self_is_guaranteed_unsized(impl_def_id) {
379 if ecx.typing_mode().is_coherence() {
380 ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous))?;
391 return then(ecx);
392 } else {
393 ecx.instantiate_normalizes_to_as_rigid(goal)?;
394 return then(ecx);
395 }
396 } else {
397 return error_response(ecx, cx.delay_bug("missing item"));
398 }
399 }
400
401 let target_container_def_id = cx.impl_or_trait_assoc_term_parent(target_item_def_id);
402
403 let target_args = ecx.translate_args(
414 goal,
415 impl_def_id,
416 impl_args,
417 impl_trait_ref,
418 target_container_def_id,
419 )?;
420
421 let target_item_def_id: I::DefId = target_item_def_id.into();
422
423 let target_item_kind = if goal.predicate.alias.kind.is_type() {
424 ty::AliasTermKind::ProjectionTy { def_id: target_item_def_id.try_into().unwrap() }
425 } else {
426 ty::AliasTermKind::ProjectionConst {
427 def_id: target_item_def_id.try_into().unwrap(),
428 }
429 };
430
431 if !cx.check_alias_term_args_compatible(target_item_kind, target_args) {
432 return error_response(
433 ecx,
434 cx.delay_bug("associated item has mismatched arguments"),
435 );
436 }
437
438 let term = match target_item_kind {
440 ty::AliasTermKind::ProjectionTy { .. } => {
441 let t = cx.type_of(target_item_def_id).instantiate(cx, target_args);
442 let t = ecx.normalize(goal.param_env, t)?;
443 t.into()
444 }
445 ty::AliasTermKind::ProjectionConst { def_id }
446 if let Some(c) =
447 cx.const_of_item(ty::AliasConstKind::Projection { def_id }) =>
448 {
449 let c = c.instantiate(cx, target_args);
450 let c = ecx.normalize(goal.param_env, c)?;
451 c.into()
452 }
453 ty::AliasTermKind::ProjectionConst { .. } => {
454 let alias_const = ty::AliasConst::new(
455 cx,
456 ty::AliasConstKind::Projection {
457 def_id: target_item_def_id.try_into().unwrap(),
458 },
459 target_args,
460 );
461 return ecx.evaluate_const_and_instantiate_projection_term(
462 goal.param_env,
463 goal.predicate.alias,
464 goal.predicate.term,
465 alias_const,
466 );
467 }
468 kind => {
::core::panicking::panic_fmt(format_args!("expected projection, found {0:?}",
kind));
}panic!("expected projection, found {kind:?}"),
469 };
470
471 ecx.instantiate_normalizes_to_term(goal, term)?;
472 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
473 })
474 }
475
476 fn consider_error_guaranteed_candidate(
479 ecx: &mut EvalCtxt<'_, D>,
480 goal: Goal<I, Self>,
481 guar: I::ErrorGuaranteed,
482 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
483 let cx = ecx.cx();
484 let error_term = match goal.predicate.alias.kind {
485 ty::AliasTermKind::ProjectionTy { .. } => Ty::new_error(cx, guar).into(),
486 ty::AliasTermKind::ProjectionConst { .. } => Const::new_error(cx, guar).into(),
487 kind => {
::core::panicking::panic_fmt(format_args!("expected projection, found {0:?}",
kind));
}panic!("expected projection, found {kind:?}"),
488 };
489
490 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
491 ecx.instantiate_normalizes_to_term(goal, error_term)?;
492 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
493 })
494 }
495
496 fn consider_auto_trait_candidate(
497 ecx: &mut EvalCtxt<'_, D>,
498 _goal: Goal<I, Self>,
499 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
500 ecx.cx().delay_bug("associated types not allowed on auto traits");
501 Err(NoSolution.into())
502 }
503
504 fn consider_trait_alias_candidate(
505 _ecx: &mut EvalCtxt<'_, D>,
506 goal: Goal<I, Self>,
507 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
508 {
::core::panicking::panic_fmt(format_args!("trait aliases do not have associated types: {0:?}",
goal));
};panic!("trait aliases do not have associated types: {:?}", goal);
509 }
510
511 fn consider_builtin_sizedness_candidates(
512 _ecx: &mut EvalCtxt<'_, D>,
513 goal: Goal<I, Self>,
514 _sizedness: SizedTraitKind,
515 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
516 {
::core::panicking::panic_fmt(format_args!("`Sized`/`MetaSized` does not have an associated type: {0:?}",
goal));
};panic!("`Sized`/`MetaSized` does not have an associated type: {:?}", goal);
517 }
518
519 fn consider_builtin_copy_clone_candidate(
520 _ecx: &mut EvalCtxt<'_, D>,
521 goal: Goal<I, Self>,
522 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
523 {
::core::panicking::panic_fmt(format_args!("`Copy`/`Clone` does not have an associated type: {0:?}",
goal));
};panic!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
524 }
525
526 fn consider_builtin_fn_ptr_trait_candidate(
527 _ecx: &mut EvalCtxt<'_, D>,
528 goal: Goal<I, Self>,
529 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
530 {
::core::panicking::panic_fmt(format_args!("`FnPtr` does not have an associated type: {0:?}",
goal));
};panic!("`FnPtr` does not have an associated type: {:?}", goal);
531 }
532
533 fn consider_builtin_fn_trait_candidates(
534 ecx: &mut EvalCtxt<'_, D>,
535 goal: Goal<I, Self>,
536 goal_kind: ty::ClosureKind,
537 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
538 let cx = ecx.cx();
539 let Some(tupled_inputs_and_output) =
540 structural_traits::extract_tupled_inputs_and_output_from_callable(
541 cx,
542 goal.predicate.self_ty(),
543 goal_kind,
544 )?
545 else {
546 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
547 };
548 let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
549
550 let output_is_sized_pred =
553 ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
554
555 let pred = ty::ProjectionClause {
556 projection_term: ty::AliasTerm::new(
557 cx,
558 goal.predicate.alias.kind,
559 [goal.predicate.self_ty(), inputs],
560 ),
561 term: output.into(),
562 }
563 .upcast(cx);
564
565 Self::probe_and_consider_implied_clause(
566 ecx,
567 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
568 goal,
569 pred,
570 [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))],
571 )
572 }
573
574 fn consider_builtin_async_fn_trait_candidates(
575 ecx: &mut EvalCtxt<'_, D>,
576 goal: Goal<I, Self>,
577 goal_kind: ty::ClosureKind,
578 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
579 let cx = ecx.cx();
580 let def_id = goal.predicate.alias.expect_projection_ty_def_id();
581
582 let env_region = match goal_kind {
583 ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2),
584 ty::ClosureKind::FnOnce => Region::new_static(cx),
586 };
587 let (tupled_inputs_and_output_and_coroutine, nested_preds) =
588 structural_traits::extract_tupled_inputs_and_output_from_async_callable(
589 cx,
590 goal.predicate.self_ty(),
591 goal_kind,
592 env_region,
593 )?;
594 let AsyncCallableRelevantTypes {
595 tupled_inputs_ty,
596 output_coroutine_ty,
597 coroutine_return_ty,
598 } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
599
600 let output_is_sized_pred = ty::TraitRef::new(
603 cx,
604 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
605 [output_coroutine_ty],
606 );
607
608 let (projection_term, term) = if cx
609 .is_projection_lang_item(def_id, SolverProjectionLangItem::CallOnceFuture)
610 {
611 (
612 ty::AliasTerm::new(
613 cx,
614 goal.predicate.alias.kind,
615 [goal.predicate.self_ty(), tupled_inputs_ty],
616 ),
617 output_coroutine_ty.into(),
618 )
619 } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CallRefFuture) {
620 (
621 ty::AliasTerm::new(
622 cx,
623 goal.predicate.alias.kind,
624 [
625 I::GenericArg::from(goal.predicate.self_ty()),
626 tupled_inputs_ty.into(),
627 env_region.into(),
628 ],
629 ),
630 output_coroutine_ty.into(),
631 )
632 } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::AsyncFnOnceOutput) {
633 (
634 ty::AliasTerm::new(
635 cx,
636 goal.predicate.alias.kind,
637 [goal.predicate.self_ty(), tupled_inputs_ty],
638 ),
639 coroutine_return_ty.into(),
640 )
641 } else {
642 {
::core::panicking::panic_fmt(format_args!("no such associated type in `AsyncFn*`: {0:?}",
def_id));
}panic!("no such associated type in `AsyncFn*`: {:?}", def_id)
643 };
644 let pred = ty::ProjectionClause { projection_term, term }.upcast(cx);
645
646 Self::probe_and_consider_implied_clause(
647 ecx,
648 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
649 goal,
650 pred,
651 [goal.with(cx, output_is_sized_pred)]
652 .into_iter()
653 .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred)))
654 .map(|goal| (GoalSource::ImplWhereBound, goal)),
655 )
656 }
657
658 fn consider_builtin_async_fn_kind_helper_candidate(
659 ecx: &mut EvalCtxt<'_, D>,
660 goal: Goal<I, Self>,
661 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
662 let [
663 closure_fn_kind_ty,
664 goal_kind_ty,
665 borrow_region,
666 tupled_inputs_ty,
667 tupled_upvars_ty,
668 coroutine_captures_by_ref_ty,
669 ] = *goal.predicate.alias.args.as_slice()
670 else {
671 ::core::panicking::panic("explicit panic");panic!();
672 };
673
674 if tupled_upvars_ty.expect_ty().is_ty_var() {
676 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
677 }
678
679 let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else {
680 return Err(NoSolution.into());
682 };
683 let Some(goal_kind) = goal_kind_ty.expect_ty().to_opt_closure_kind() else {
684 return Err(NoSolution.into());
685 };
686 if !closure_kind.extends(goal_kind) {
687 return Err(NoSolution.into());
688 }
689
690 let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind(
691 ecx.cx(),
692 goal_kind,
693 tupled_inputs_ty.expect_ty(),
694 tupled_upvars_ty.expect_ty(),
695 coroutine_captures_by_ref_ty.expect_ty(),
696 borrow_region.expect_region(),
697 );
698
699 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
700 ecx.instantiate_normalizes_to_term(goal, upvars_ty.into())?;
701 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
702 })
703 }
704
705 fn consider_builtin_tuple_candidate(
706 _ecx: &mut EvalCtxt<'_, D>,
707 goal: Goal<I, Self>,
708 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
709 {
::core::panicking::panic_fmt(format_args!("`Tuple` does not have an associated type: {0:?}",
goal));
};panic!("`Tuple` does not have an associated type: {:?}", goal);
710 }
711
712 fn consider_builtin_pointee_candidate(
713 ecx: &mut EvalCtxt<'_, D>,
714 goal: Goal<I, Self>,
715 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
716 let cx = ecx.cx();
717 let metadata_def_id = cx.require_projection_lang_item(SolverProjectionLangItem::Metadata);
718 {
match (&ty::AliasTermKind::ProjectionTy { def_id: metadata_def_id },
&goal.predicate.alias.kind) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(
719 ty::AliasTermKind::ProjectionTy { def_id: metadata_def_id },
720 goal.predicate.alias.kind
721 );
722 let metadata_ty = match goal.predicate.self_ty().kind() {
723 ty::Bool
724 | ty::Char
725 | ty::Int(..)
726 | ty::Uint(..)
727 | ty::Float(..)
728 | ty::Array(..)
729 | ty::Pat(..)
730 | ty::RawPtr(..)
731 | ty::Ref(..)
732 | ty::FnDef(..)
733 | ty::FnPtr(..)
734 | ty::Closure(..)
735 | ty::CoroutineClosure(..)
736 | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
737 | ty::Coroutine(..)
738 | ty::CoroutineWitness(..)
739 | ty::Never
740 | ty::Foreign(..) => Ty::new_unit(cx),
741
742 ty::Error(e) => Ty::new_error(cx, e),
743
744 ty::Str | ty::Slice(_) => Ty::new_usize(cx),
745
746 ty::Dynamic(_, _) => {
747 let dyn_metadata = cx.require_adt_lang_item(SolverAdtLangItem::DynMetadata);
748 cx.type_of(dyn_metadata.into())
749 .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())])
750 .skip_norm_wip()
751 }
752
753 ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) | ty::Placeholder(..) => {
754 let alias_bound_result = ecx
759 .probe_builtin_trait_candidate(BuiltinImplSource::Misc)
760 .enter(|ecx| {
761 let sized_predicate = ty::TraitRef::new(
762 cx,
763 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
764 [I::GenericArg::from(goal.predicate.self_ty())],
765 );
766 ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate))?;
767 ecx.instantiate_normalizes_to_term(goal, Ty::new_unit(cx).into())?;
768 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
769 })
770 .map_err_to_rerun()?;
771
772 return alias_bound_result.or_else(|NoSolution| {
775 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|this| {
776 this.instantiate_normalizes_to_as_rigid(goal)?;
777 this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
778 })
779 });
780 }
781
782 ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) {
783 None => Ty::new_unit(cx),
784 Some(tail_ty) => Ty::new_projection(
785 cx,
786 ty::IsRigid::No,
787 metadata_def_id,
788 [tail_ty.instantiate(cx, args).skip_norm_wip()],
789 ),
790 },
791 ty::Adt(_, _) => Ty::new_unit(cx),
792
793 ty::Tuple(elements) => match elements.last() {
794 None => Ty::new_unit(cx),
795 Some(tail_ty) => {
796 Ty::new_projection(cx, ty::IsRigid::No, metadata_def_id, [tail_ty])
797 }
798 },
799
800 ty::UnsafeBinder(_) => {
801 ::core::panicking::panic("not implemented")unimplemented!()
803 }
804
805 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
806 | ty::Alias(ty::IsRigid::No, _)
807 | ty::Bound(..) => {
::core::panicking::panic_fmt(format_args!("unexpected self ty `{0:?}` when normalizing `<T as Pointee>::Metadata`",
goal.predicate.self_ty()));
}panic!(
808 "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`",
809 goal.predicate.self_ty()
810 ),
811 };
812
813 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
814 ecx.instantiate_normalizes_to_term(goal, metadata_ty.into())?;
815 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
816 })
817 }
818
819 fn consider_builtin_future_candidate(
820 ecx: &mut EvalCtxt<'_, D>,
821 goal: Goal<I, Self>,
822 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
823 let self_ty = goal.predicate.self_ty();
824 let ty::Coroutine(def_id, args) = self_ty.kind() else {
825 return Err(NoSolution.into());
826 };
827
828 let cx = ecx.cx();
830 if !cx.coroutine_is_async(def_id) {
831 return Err(NoSolution.into());
832 }
833
834 let term = args.as_coroutine().return_ty().into();
835
836 Self::probe_and_consider_implied_clause(
837 ecx,
838 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
839 goal,
840 ty::ProjectionClause {
841 projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.alias.kind, [self_ty]),
842 term,
843 }
844 .upcast(cx),
845 [],
848 )
849 }
850
851 fn consider_builtin_iterator_candidate(
852 ecx: &mut EvalCtxt<'_, D>,
853 goal: Goal<I, Self>,
854 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
855 let self_ty = goal.predicate.self_ty();
856 let ty::Coroutine(def_id, args) = self_ty.kind() else {
857 return Err(NoSolution.into());
858 };
859
860 let cx = ecx.cx();
862 if !cx.coroutine_is_gen(def_id) {
863 return Err(NoSolution.into());
864 }
865
866 let term = args.as_coroutine().yield_ty().into();
867
868 Self::probe_and_consider_implied_clause(
869 ecx,
870 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
871 goal,
872 ty::ProjectionClause {
873 projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.alias.kind, [self_ty]),
874 term,
875 }
876 .upcast(cx),
877 [],
880 )
881 }
882
883 fn consider_builtin_fused_iterator_candidate(
884 _ecx: &mut EvalCtxt<'_, D>,
885 goal: Goal<I, Self>,
886 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
887 {
::core::panicking::panic_fmt(format_args!("`FusedIterator` does not have an associated type: {0:?}",
goal));
};panic!("`FusedIterator` does not have an associated type: {:?}", goal);
888 }
889
890 fn consider_builtin_async_iterator_candidate(
891 ecx: &mut EvalCtxt<'_, D>,
892 goal: Goal<I, Self>,
893 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
894 let self_ty = goal.predicate.self_ty();
895 let ty::Coroutine(def_id, args) = self_ty.kind() else {
896 return Err(NoSolution.into());
897 };
898
899 let cx = ecx.cx();
901 if !cx.coroutine_is_async_gen(def_id) {
902 return Err(NoSolution.into());
903 }
904
905 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
906 let expected_ty = ecx.next_ty_infer();
907 let wrapped_expected_ty = Ty::new_adt(
910 cx,
911 cx.adt_def(cx.require_adt_lang_item(SolverAdtLangItem::Poll)),
912 cx.mk_args(&[Ty::new_adt(
913 cx,
914 cx.adt_def(cx.require_adt_lang_item(SolverAdtLangItem::Option)),
915 cx.mk_args(&[expected_ty.into()]),
916 )
917 .into()]),
918 );
919 let yield_ty = args.as_coroutine().yield_ty();
920 ecx.eq(goal.param_env, wrapped_expected_ty, yield_ty)?;
921 ecx.instantiate_normalizes_to_term(goal, expected_ty.into())?;
922 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
923 })
924 }
925
926 fn consider_builtin_coroutine_candidate(
927 ecx: &mut EvalCtxt<'_, D>,
928 goal: Goal<I, Self>,
929 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
930 let self_ty = goal.predicate.self_ty();
931 let ty::Coroutine(def_id, args) = self_ty.kind() else {
932 return Err(NoSolution.into());
933 };
934
935 let cx = ecx.cx();
937 if !cx.is_general_coroutine(def_id) {
938 return Err(NoSolution.into());
939 }
940
941 let coroutine = args.as_coroutine();
942 let def_id = goal.predicate.alias.expect_projection_ty_def_id();
943
944 let term = if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineReturn)
945 {
946 coroutine.return_ty().into()
947 } else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineYield) {
948 coroutine.yield_ty().into()
949 } else {
950 {
::core::panicking::panic_fmt(format_args!("unexpected associated item `{0:?}` for `{1:?}`",
def_id, self_ty));
}panic!("unexpected associated item `{:?}` for `{self_ty:?}`", def_id)
951 };
952
953 Self::probe_and_consider_implied_clause(
954 ecx,
955 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
956 goal,
957 ty::ProjectionClause {
958 projection_term: ty::AliasTerm::new(
959 ecx.cx(),
960 goal.predicate.alias.kind,
961 [self_ty, coroutine.resume_ty()],
962 ),
963 term,
964 }
965 .upcast(cx),
966 [],
969 )
970 }
971
972 fn consider_structural_builtin_unsize_candidates(
973 _ecx: &mut EvalCtxt<'_, D>,
974 goal: Goal<I, Self>,
975 ) -> Result<Vec<Candidate<I>>, RerunNonErased> {
976 {
::core::panicking::panic_fmt(format_args!("`Unsize` does not have an associated type: {0:?}",
goal));
};panic!("`Unsize` does not have an associated type: {:?}", goal);
977 }
978
979 fn consider_builtin_discriminant_kind_candidate(
980 ecx: &mut EvalCtxt<'_, D>,
981 goal: Goal<I, Self>,
982 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
983 let self_ty = goal.predicate.self_ty();
984 let discriminant_ty = match self_ty.kind() {
985 ty::Bool
986 | ty::Char
987 | ty::Int(..)
988 | ty::Uint(..)
989 | ty::Float(..)
990 | ty::Array(..)
991 | ty::Pat(..)
992 | ty::RawPtr(..)
993 | ty::Ref(..)
994 | ty::FnDef(..)
995 | ty::FnPtr(..)
996 | ty::Closure(..)
997 | ty::CoroutineClosure(..)
998 | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
999 | ty::Coroutine(..)
1000 | ty::CoroutineWitness(..)
1001 | ty::Never
1002 | ty::Foreign(..)
1003 | ty::Adt(_, _)
1004 | ty::Str
1005 | ty::Slice(_)
1006 | ty::Dynamic(_, _)
1007 | ty::Tuple(_)
1008 | ty::Error(_) => self_ty.discriminant_ty(ecx.cx()),
1009
1010 ty::UnsafeBinder(_) => {
1011 {
::core::panicking::panic_fmt(format_args!("not implemented: {0}",
format_args!("discr subgoal...")));
}unimplemented!("discr subgoal...")
1013 }
1014
1015 ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) | ty::Placeholder(..) => {
1019 return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1020 ecx.instantiate_normalizes_to_as_rigid(goal)?;
1021 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1022 });
1023 }
1024
1025 ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
1026 | ty::Alias(ty::IsRigid::No, _)
1027 | ty::Bound(..) => {
::core::panicking::panic_fmt(format_args!("unexpected self ty `{0:?}` when normalizing `<T as DiscriminantKind>::Discriminant`",
goal.predicate.self_ty()));
}panic!(
1028 "unexpected self ty `{:?}` when normalizing `<T as DiscriminantKind>::Discriminant`",
1029 goal.predicate.self_ty()
1030 ),
1031 };
1032
1033 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1034 ecx.instantiate_normalizes_to_term(goal, discriminant_ty.into())?;
1035 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1036 })
1037 }
1038
1039 fn consider_builtin_destruct_candidate(
1040 _ecx: &mut EvalCtxt<'_, D>,
1041 goal: Goal<I, Self>,
1042 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1043 {
::core::panicking::panic_fmt(format_args!("`Destruct` does not have an associated type: {0:?}",
goal));
};panic!("`Destruct` does not have an associated type: {:?}", goal);
1044 }
1045
1046 fn consider_builtin_transmute_candidate(
1047 _ecx: &mut EvalCtxt<'_, D>,
1048 goal: Goal<I, Self>,
1049 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1050 {
::core::panicking::panic_fmt(format_args!("`TransmuteFrom` does not have an associated type: {0:?}",
goal));
}panic!("`TransmuteFrom` does not have an associated type: {:?}", goal)
1051 }
1052
1053 fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
1054 _ecx: &mut EvalCtxt<'_, D>,
1055 goal: Goal<I, Self>,
1056 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1057 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("`BikeshedGuaranteedNoDrop` does not have an associated type: {0:?}",
goal)));
}unreachable!("`BikeshedGuaranteedNoDrop` does not have an associated type: {:?}", goal)
1058 }
1059
1060 fn consider_builtin_field_candidate(
1061 ecx: &mut EvalCtxt<'_, D>,
1062 goal: Goal<I, Self>,
1063 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1064 let self_ty = goal.predicate.self_ty();
1065 let ty::Adt(def, args) = self_ty.kind() else {
1066 return Err(NoSolution.into());
1067 };
1068 let Some(FieldInfo { base, ty, .. }) = def.field_representing_type_info(ecx.cx(), args)
1069 else {
1070 return Err(NoSolution.into());
1071 };
1072 let def_id = goal.predicate.alias.expect_projection_ty_def_id();
1073 let ty = match ecx.cx().as_projection_lang_item(def_id) {
1074 Some(SolverProjectionLangItem::FieldBase) => base,
1075 Some(SolverProjectionLangItem::FieldType) => ty,
1076 _ => {
::core::panicking::panic_fmt(format_args!("unexpected associated type {0:?} in `Field`",
goal.predicate));
}panic!("unexpected associated type {:?} in `Field`", goal.predicate),
1077 };
1078 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1079 ecx.instantiate_normalizes_to_term(goal, ty.into())?;
1080 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1081 })
1082 }
1083
1084 fn consider_builtin_try_as_dyn_candidate(
1085 _ecx: &mut EvalCtxt<'_, D>,
1086 _goal: Goal<I, Self>,
1087 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1088 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("try_as_dyn helper trait doesn\'t have assoc types")));
}unreachable!("try_as_dyn helper trait doesn't have assoc types")
1089 }
1090}
1091
1092impl<D, I> EvalCtxt<'_, D>
1093where
1094 D: SolverDelegate<Interner = I>,
1095 I: Interner,
1096{
1097 fn translate_args(
1098 &mut self,
1099 goal: Goal<I, ty::NormalizesTo<I>>,
1100 impl_def_id: I::ImplId,
1101 impl_args: I::GenericArgs,
1102 impl_trait_ref: rustc_type_ir::TraitRef<I>,
1103 target_container_def_id: I::DefId,
1104 ) -> Result<I::GenericArgs, NoSolutionOrRerunNonErased> {
1105 let cx = self.cx();
1106 Ok(if target_container_def_id == impl_trait_ref.def_id.into() {
1107 goal.predicate.alias.args
1109 } else if target_container_def_id == impl_def_id.into() {
1110 goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id.into(), impl_args)
1113 } else {
1114 let target_args = self.fresh_args_for_item(target_container_def_id);
1115 let target_trait_ref = cx
1116 .impl_trait_ref(target_container_def_id.try_into().unwrap())
1117 .instantiate(cx, target_args)
1118 .skip_norm_wip();
1119 self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?;
1121 self.add_goals(
1124 GoalSource::Misc,
1125 cx.clauses_of(target_container_def_id)
1126 .iter_instantiated(cx, target_args)
1127 .map(Unnormalized::skip_norm_wip)
1128 .map(|clause| goal.with(cx, clause)),
1129 )?;
1130 goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id.into(), target_args)
1131 })
1132 }
1133}