1use std::ops::ControlFlow;
4
5use rustc_data_structures::sso::SsoHashSet;
6use rustc_data_structures::stack::ensure_sufficient_stack;
7use rustc_errors::ErrorGuaranteed;
8use rustc_hir::def_id::DefId;
9use rustc_hir::lang_items::LangItem;
10use rustc_infer::infer::DefineOpaqueTypes;
11use rustc_infer::infer::resolve::OpportunisticRegionResolver;
12use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
13use rustc_middle::traits::select::OverflowError;
14use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
15use rustc_middle::ty::fast_reject::DeepRejectCtxt;
16use rustc_middle::ty::{
17 self, FieldInfo, Term, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Unnormalized,
18 Upcast,
19};
20use rustc_middle::{bug, span_bug};
21use rustc_span::sym;
22use tracing::{debug, instrument};
23
24use super::{
25 MismatchedProjectionTypes, Normalized, NormalizedTerm, Obligation, ObligationCause,
26 PredicateObligation, ProjectionCacheEntry, ProjectionCacheKey, Selection, SelectionContext,
27 SelectionError, specialization_graph, translate_args, util,
28};
29use crate::diagnostics::InherentProjectionNormalizationOverflow;
30use crate::infer::{BoundRegionConversionTime, InferOk};
31use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
32use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
33use crate::traits::select::ProjectionMatchesProjection;
34
35pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>;
36
37pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
38
39pub type ProjectionTermObligation<'tcx> = Obligation<'tcx, ty::AliasTerm<'tcx>>;
40
41pub(super) struct InProgress;
42
43#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ProjectionError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ProjectionError::TooManyCandidates =>
::core::fmt::Formatter::write_str(f, "TooManyCandidates"),
ProjectionError::TraitSelectionError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"TraitSelectionError", &__self_0),
}
}
}Debug)]
45pub enum ProjectionError<'tcx> {
46 TooManyCandidates,
48
49 TraitSelectionError(SelectionError<'tcx>),
51}
52
53#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for ProjectionCandidate<'tcx> {
#[inline]
fn eq(&self, other: &ProjectionCandidate<'tcx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ProjectionCandidate::ParamEnv(__self_0),
ProjectionCandidate::ParamEnv(__arg1_0)) =>
__self_0 == __arg1_0,
(ProjectionCandidate::TraitDef(__self_0),
ProjectionCandidate::TraitDef(__arg1_0)) =>
__self_0 == __arg1_0,
(ProjectionCandidate::Object(__self_0),
ProjectionCandidate::Object(__arg1_0)) =>
__self_0 == __arg1_0,
(ProjectionCandidate::Select(__self_0),
ProjectionCandidate::Select(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for ProjectionCandidate<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _:
::core::cmp::AssertParamIsEq<ty::PolyProjectionPredicate<'tcx>>;
let _:
::core::cmp::AssertParamIsEq<ty::PolyProjectionPredicate<'tcx>>;
let _:
::core::cmp::AssertParamIsEq<ty::PolyProjectionPredicate<'tcx>>;
let _: ::core::cmp::AssertParamIsEq<Selection<'tcx>>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ProjectionCandidate<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ProjectionCandidate::ParamEnv(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ParamEnv", &__self_0),
ProjectionCandidate::TraitDef(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"TraitDef", &__self_0),
ProjectionCandidate::Object(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Object",
&__self_0),
ProjectionCandidate::Select(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Select",
&__self_0),
}
}
}Debug)]
54enum ProjectionCandidate<'tcx> {
55 ParamEnv(ty::PolyProjectionPredicate<'tcx>),
57
58 TraitDef(ty::PolyProjectionPredicate<'tcx>),
61
62 Object(ty::PolyProjectionPredicate<'tcx>),
64
65 Select(Selection<'tcx>),
67}
68
69enum ProjectionCandidateSet<'tcx> {
70 None,
71 Single(ProjectionCandidate<'tcx>),
72 Ambiguous,
73 Error(SelectionError<'tcx>),
74}
75
76impl<'tcx> ProjectionCandidateSet<'tcx> {
77 fn mark_ambiguous(&mut self) {
78 *self = ProjectionCandidateSet::Ambiguous;
79 }
80
81 fn mark_error(&mut self, err: SelectionError<'tcx>) {
82 *self = ProjectionCandidateSet::Error(err);
83 }
84
85 fn push_candidate(&mut self, candidate: ProjectionCandidate<'tcx>) -> bool {
89 let convert_to_ambiguous;
98
99 match self {
100 ProjectionCandidateSet::None => {
101 *self = ProjectionCandidateSet::Single(candidate);
102 return true;
103 }
104
105 ProjectionCandidateSet::Single(current) => {
106 if current == &candidate {
109 return false;
110 }
111
112 match (current, candidate) {
120 (ProjectionCandidate::ParamEnv(..), ProjectionCandidate::ParamEnv(..)) => {
121 convert_to_ambiguous = ()
122 }
123 (ProjectionCandidate::ParamEnv(..), _) => return false,
124 (_, ProjectionCandidate::ParamEnv(..)) => ::rustc_middle::util::bug::bug_fmt(format_args!("should never prefer non-param-env candidates over param-env candidates"))bug!(
125 "should never prefer non-param-env candidates over param-env candidates"
126 ),
127 (_, _) => convert_to_ambiguous = (),
128 }
129 }
130
131 ProjectionCandidateSet::Ambiguous | ProjectionCandidateSet::Error(..) => {
132 return false;
133 }
134 }
135
136 let () = convert_to_ambiguous;
139 *self = ProjectionCandidateSet::Ambiguous;
140 false
141 }
142}
143
144pub(super) enum ProjectAndUnifyResult<'tcx> {
153 Holds(PredicateObligations<'tcx>),
158 FailedNormalization,
161 Recursive,
164 MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
167}
168
169#[allow(clippy :: suspicious_else_formatting)]
{
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("poly_project_and_unify_term",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(176u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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(&obligation)
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: ProjectAndUnifyResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let infcx = selcx.infcx;
let r =
infcx.commit_if_ok(|_snapshot|
{
let placeholder_predicate =
infcx.enter_forall_and_leak_universe(obligation.predicate);
let placeholder_obligation =
obligation.with(infcx.tcx, placeholder_predicate);
match project_and_unify_term(selcx, &placeholder_obligation)
{
ProjectAndUnifyResult::MismatchedProjectionTypes(e) =>
Err(e),
other => Ok(other),
}
});
match r {
Ok(inner) => inner,
Err(err) =>
ProjectAndUnifyResult::MismatchedProjectionTypes(err),
}
}
}
}#[instrument(level = "debug", skip(selcx))]
177pub(super) fn poly_project_and_unify_term<'cx, 'tcx>(
178 selcx: &mut SelectionContext<'cx, 'tcx>,
179 obligation: &PolyProjectionObligation<'tcx>,
180) -> ProjectAndUnifyResult<'tcx> {
181 let infcx = selcx.infcx;
182 let r = infcx.commit_if_ok(|_snapshot| {
183 let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate);
184
185 let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
186 match project_and_unify_term(selcx, &placeholder_obligation) {
187 ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
188 other => Ok(other),
189 }
190 });
191
192 match r {
193 Ok(inner) => inner,
194 Err(err) => ProjectAndUnifyResult::MismatchedProjectionTypes(err),
195 }
196}
197
198#[allow(clippy :: suspicious_else_formatting)]
{
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("project_and_unify_term",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(206u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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(&obligation)
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: ProjectAndUnifyResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let mut obligations = PredicateObligations::new();
let infcx = selcx.infcx;
let normalized =
match opt_normalize_projection_term(selcx,
obligation.param_env, obligation.predicate.projection_term,
obligation.cause.clone(), obligation.recursion_depth,
&mut obligations) {
Ok(Some(n)) => n,
Ok(None) =>
return ProjectAndUnifyResult::FailedNormalization,
Err(InProgress) => return ProjectAndUnifyResult::Recursive,
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:226",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(226u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("normalized")
}> =
::tracing::__macro_support::FieldName::new("normalized");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("project_and_unify_type result")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&normalized)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let actual = obligation.predicate.term;
let InferOk { value: actual, obligations: new } =
selcx.infcx.replace_opaque_types_with_inference_vars(actual,
obligation.cause.body_def_id, obligation.cause.span,
obligation.param_env);
obligations.extend(new);
match infcx.at(&obligation.cause,
obligation.param_env).eq(DefineOpaqueTypes::Yes, normalized,
actual) {
Ok(InferOk { obligations: inferred_obligations, value: () })
=> {
obligations.extend(inferred_obligations);
ProjectAndUnifyResult::Holds(obligations)
}
Err(err) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:251",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(251u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("equating types encountered error {0:?}",
err) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
ProjectAndUnifyResult::MismatchedProjectionTypes(MismatchedProjectionTypes {
err,
})
}
}
}
}
}#[instrument(level = "debug", skip(selcx))]
207fn project_and_unify_term<'cx, 'tcx>(
208 selcx: &mut SelectionContext<'cx, 'tcx>,
209 obligation: &ProjectionObligation<'tcx>,
210) -> ProjectAndUnifyResult<'tcx> {
211 let mut obligations = PredicateObligations::new();
212
213 let infcx = selcx.infcx;
214 let normalized = match opt_normalize_projection_term(
215 selcx,
216 obligation.param_env,
217 obligation.predicate.projection_term,
218 obligation.cause.clone(),
219 obligation.recursion_depth,
220 &mut obligations,
221 ) {
222 Ok(Some(n)) => n,
223 Ok(None) => return ProjectAndUnifyResult::FailedNormalization,
224 Err(InProgress) => return ProjectAndUnifyResult::Recursive,
225 };
226 debug!(?normalized, ?obligations, "project_and_unify_type result");
227 let actual = obligation.predicate.term;
228 let InferOk { value: actual, obligations: new } =
232 selcx.infcx.replace_opaque_types_with_inference_vars(
233 actual,
234 obligation.cause.body_def_id,
235 obligation.cause.span,
236 obligation.param_env,
237 );
238 obligations.extend(new);
239
240 match infcx.at(&obligation.cause, obligation.param_env).eq(
242 DefineOpaqueTypes::Yes,
243 normalized,
244 actual,
245 ) {
246 Ok(InferOk { obligations: inferred_obligations, value: () }) => {
247 obligations.extend(inferred_obligations);
248 ProjectAndUnifyResult::Holds(obligations)
249 }
250 Err(err) => {
251 debug!("equating types encountered error {:?}", err);
252 ProjectAndUnifyResult::MismatchedProjectionTypes(MismatchedProjectionTypes { err })
253 }
254 }
255}
256
257pub fn normalize_projection_term<'a, 'b, 'tcx>(
265 selcx: &'a mut SelectionContext<'b, 'tcx>,
266 param_env: ty::ParamEnv<'tcx>,
267 alias_term: ty::AliasTerm<'tcx>,
268 cause: ObligationCause<'tcx>,
269 depth: usize,
270 obligations: &mut PredicateObligations<'tcx>,
271) -> Term<'tcx> {
272 opt_normalize_projection_term(selcx, param_env, alias_term, cause.clone(), depth, obligations)
273 .ok()
274 .flatten()
275 .unwrap_or_else(move || {
276 selcx.infcx.projection_term_to_infer(
281 param_env,
282 alias_term,
283 cause,
284 depth + 1,
285 obligations,
286 )
287 })
288}
289
290#[allow(clippy :: suspicious_else_formatting)]
{
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("opt_normalize_projection_term",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(301u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("projection_term")
}> =
::tracing::__macro_support::FieldName::new("projection_term");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("depth")
}> =
::tracing::__macro_support::FieldName::new("depth");
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(&projection_term)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&depth 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<Option<Term<'tcx>>, InProgress> = loop {};
return __tracing_attr_fake_return;
}
{
let infcx = selcx.infcx;
if true {
if !!selcx.infcx.next_trait_solver() {
::core::panicking::panic("assertion failed: !selcx.infcx.next_trait_solver()")
};
};
let projection_term =
infcx.resolve_vars_if_possible(projection_term);
let cache_key =
ProjectionCacheKey::new(projection_term, param_env);
let cache_entry =
infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
match cache_entry {
Ok(()) => {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:324",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(324u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("no cache")
as &dyn ::tracing::field::Value))])
});
} else { ; }
}
Err(ProjectionCacheEntry::Ambiguous) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:329",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(329u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("found cache entry: ambiguous")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
return Ok(None);
}
Err(ProjectionCacheEntry::InProgress) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:341",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(341u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("found cache entry: in-progress")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
infcx.inner.borrow_mut().projection_cache().recur(cache_key);
return Err(InProgress);
}
Err(ProjectionCacheEntry::Recur) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:350",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(350u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("recur cache")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
return Err(InProgress);
}
Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ })
=> {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:365",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(365u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("ty")
}> =
::tracing::__macro_support::FieldName::new("ty");
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!("found normalized ty")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
obligations.extend(ty.obligations);
return Ok(Some(ty.value));
}
Err(ProjectionCacheEntry::Error) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:370",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(370u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("opt_normalize_projection_type: found error")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let result =
normalize_to_error(selcx, param_env, projection_term, cause,
depth);
obligations.extend(result.obligations);
return Ok(Some(result.value));
}
}
let obligation =
Obligation::with_depth(selcx.tcx(), cause.clone(), depth,
param_env, projection_term);
match project(selcx, &obligation) {
Ok(Projected::Progress(Progress {
term: projected_term, obligations: mut projected_obligations
})) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:385",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(385u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("opt_normalize_projection_type: progress")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let projected_term =
selcx.infcx.resolve_vars_if_possible(projected_term);
let mut result =
if projected_term.has_aliases() {
let normalized_ty =
normalize_with_depth_to(selcx, param_env, cause, depth + 1,
projected_term, &mut projected_obligations);
Normalized {
value: normalized_ty,
obligations: projected_obligations,
}
} else {
Normalized {
value: projected_term.skip_normalization(),
obligations: projected_obligations,
}
};
let mut deduped =
SsoHashSet::with_capacity(result.obligations.len());
result.obligations.retain(|obligation|
deduped.insert(obligation.clone()));
infcx.inner.borrow_mut().projection_cache().insert_term(cache_key,
result.clone());
obligations.extend(result.obligations);
Ok(Some(result.value))
}
Ok(Projected::NoProgress(projected_ty)) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:419",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(419u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("opt_normalize_projection_type: no progress")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let result =
Normalized {
value: projected_ty,
obligations: PredicateObligations::new(),
};
infcx.inner.borrow_mut().projection_cache().insert_term(cache_key,
result.clone());
Ok(Some(result.value))
}
Err(ProjectionError::TooManyCandidates) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:427",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(427u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("opt_normalize_projection_type: too many candidates")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
Ok(None)
}
Err(ProjectionError::TraitSelectionError(_)) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:432",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(432u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("opt_normalize_projection_type: ERROR")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
infcx.inner.borrow_mut().projection_cache().error(cache_key);
let result =
normalize_to_error(selcx, param_env, projection_term, cause,
depth);
obligations.extend(result.obligations);
Ok(Some(result.value))
}
}
}
}
}#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
302pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
303 selcx: &'a mut SelectionContext<'b, 'tcx>,
304 param_env: ty::ParamEnv<'tcx>,
305 projection_term: ty::AliasTerm<'tcx>,
306 cause: ObligationCause<'tcx>,
307 depth: usize,
308 obligations: &mut PredicateObligations<'tcx>,
309) -> Result<Option<Term<'tcx>>, InProgress> {
310 let infcx = selcx.infcx;
311 debug_assert!(!selcx.infcx.next_trait_solver());
312 let projection_term = infcx.resolve_vars_if_possible(projection_term);
313 let cache_key = ProjectionCacheKey::new(projection_term, param_env);
314
315 let cache_entry = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
323 match cache_entry {
324 Ok(()) => debug!("no cache"),
325 Err(ProjectionCacheEntry::Ambiguous) => {
326 debug!("found cache entry: ambiguous");
330 return Ok(None);
331 }
332 Err(ProjectionCacheEntry::InProgress) => {
333 debug!("found cache entry: in-progress");
342
343 infcx.inner.borrow_mut().projection_cache().recur(cache_key);
347 return Err(InProgress);
348 }
349 Err(ProjectionCacheEntry::Recur) => {
350 debug!("recur cache");
351 return Err(InProgress);
352 }
353 Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => {
354 debug!(?ty, "found normalized ty");
366 obligations.extend(ty.obligations);
367 return Ok(Some(ty.value));
368 }
369 Err(ProjectionCacheEntry::Error) => {
370 debug!("opt_normalize_projection_type: found error");
371 let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
372 obligations.extend(result.obligations);
373 return Ok(Some(result.value));
374 }
375 }
376
377 let obligation =
378 Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_term);
379
380 match project(selcx, &obligation) {
381 Ok(Projected::Progress(Progress {
382 term: projected_term,
383 obligations: mut projected_obligations,
384 })) => {
385 debug!("opt_normalize_projection_type: progress");
386 let projected_term = selcx.infcx.resolve_vars_if_possible(projected_term);
392
393 let mut result = if projected_term.has_aliases() {
394 let normalized_ty = normalize_with_depth_to(
395 selcx,
396 param_env,
397 cause,
398 depth + 1,
399 projected_term,
400 &mut projected_obligations,
401 );
402
403 Normalized { value: normalized_ty, obligations: projected_obligations }
404 } else {
405 Normalized {
406 value: projected_term.skip_normalization(),
407 obligations: projected_obligations,
408 }
409 };
410
411 let mut deduped = SsoHashSet::with_capacity(result.obligations.len());
412 result.obligations.retain(|obligation| deduped.insert(obligation.clone()));
413
414 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
415 obligations.extend(result.obligations);
416 Ok(Some(result.value))
417 }
418 Ok(Projected::NoProgress(projected_ty)) => {
419 debug!("opt_normalize_projection_type: no progress");
420 let result =
421 Normalized { value: projected_ty, obligations: PredicateObligations::new() };
422 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
423 Ok(Some(result.value))
425 }
426 Err(ProjectionError::TooManyCandidates) => {
427 debug!("opt_normalize_projection_type: too many candidates");
428 infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
429 Ok(None)
430 }
431 Err(ProjectionError::TraitSelectionError(_)) => {
432 debug!("opt_normalize_projection_type: ERROR");
433 infcx.inner.borrow_mut().projection_cache().error(cache_key);
438 let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
439 obligations.extend(result.obligations);
440 Ok(Some(result.value))
441 }
442 }
443}
444
445fn normalize_to_error<'a, 'tcx>(
466 selcx: &SelectionContext<'a, 'tcx>,
467 param_env: ty::ParamEnv<'tcx>,
468 projection_term: ty::AliasTerm<'tcx>,
469 cause: ObligationCause<'tcx>,
470 depth: usize,
471) -> NormalizedTerm<'tcx> {
472 let trait_ref = ty::Binder::dummy(projection_term.trait_ref(selcx.tcx()));
473 let new_value = match projection_term.kind {
474 ty::AliasTermKind::ProjectionTy { .. }
475 | ty::AliasTermKind::InherentTy { .. }
476 | ty::AliasTermKind::OpaqueTy { .. }
477 | ty::AliasTermKind::FreeTy { .. } => selcx.infcx.next_ty_var(cause.span).into(),
478 ty::AliasTermKind::FreeConst { .. }
479 | ty::AliasTermKind::InherentConst { .. }
480 | ty::AliasTermKind::AnonConst { .. }
481 | ty::AliasTermKind::ProjectionConst { .. } => {
482 selcx.infcx.next_const_var(cause.span).into()
483 }
484 };
485 let mut obligations = PredicateObligations::new();
486 obligations.push(Obligation {
487 cause,
488 recursion_depth: depth,
489 param_env,
490 predicate: trait_ref.upcast(selcx.tcx()),
491 });
492 Normalized { value: new_value, obligations }
493}
494
495fn push_const_arg_has_type_obligation<'tcx>(
498 tcx: TyCtxt<'tcx>,
499 obligations: &mut PredicateObligations<'tcx>,
500 cause: &ObligationCause<'tcx>,
501 depth: usize,
502 param_env: ty::ParamEnv<'tcx>,
503 term: Term<'tcx>,
504 def_id: DefId,
505 args: ty::GenericArgsRef<'tcx>,
506) {
507 if let Some(ct) = term.as_const() {
508 let expected_ty = tcx.type_of(def_id).instantiate(tcx, args).skip_norm_wip();
509 obligations.push(Obligation::with_depth(
510 tcx,
511 cause.clone(),
512 depth,
513 param_env,
514 ty::ClauseKind::ConstArgHasType(ct, expected_ty),
515 ));
516 }
517}
518
519#[allow(clippy :: suspicious_else_formatting)]
{
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("normalize_inherent_projection",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(521u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("alias_term")
}> =
::tracing::__macro_support::FieldName::new("alias_term");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("depth")
}> =
::tracing::__macro_support::FieldName::new("depth");
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(&alias_term)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&depth 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: ty::Term<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
if true {
if !!selcx.infcx.next_trait_solver() {
::core::panicking::panic("assertion failed: !selcx.infcx.next_trait_solver()")
};
};
let tcx = selcx.tcx();
if !tcx.recursion_limit().value_within_limit(depth) {
tcx.dcx().emit_fatal(InherentProjectionNormalizationOverflow {
span: cause.span,
ty: alias_term.to_string(),
});
}
let args =
compute_inherent_assoc_term_args(selcx, param_env, alias_term,
cause.clone(), depth, obligations);
let def_id = alias_term.expect_inherent_def_id();
let clauses = tcx.clauses_of(def_id).instantiate(tcx, args);
for (clause, span) in clauses {
let clause =
normalize_with_depth_to(selcx, param_env, cause.clone(),
depth + 1, clause, obligations);
let nested_cause =
ObligationCause::new(cause.span, cause.body_def_id,
ObligationCauseCode::WhereClause(def_id, span));
obligations.push(Obligation::with_depth(tcx, nested_cause,
depth + 1, param_env, clause));
}
let term =
if alias_term.kind.is_type() {
tcx.type_of(def_id).instantiate(tcx, args).map(Into::into)
} else {
tcx.const_of_item(def_id).instantiate(tcx,
args).map(Into::into)
};
let term = selcx.infcx.resolve_vars_if_possible(term);
let term =
normalize_with_depth_to(selcx, param_env, cause.clone(),
depth + 1, term, obligations);
push_const_arg_has_type_obligation(tcx, obligations, &cause,
depth + 1, param_env, term, def_id, args);
term
}
}
}#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
522pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
523 selcx: &'a mut SelectionContext<'b, 'tcx>,
524 param_env: ty::ParamEnv<'tcx>,
525 alias_term: ty::AliasTerm<'tcx>,
526 cause: ObligationCause<'tcx>,
527 depth: usize,
528 obligations: &mut PredicateObligations<'tcx>,
529) -> ty::Term<'tcx> {
530 debug_assert!(!selcx.infcx.next_trait_solver());
531 let tcx = selcx.tcx();
532
533 if !tcx.recursion_limit().value_within_limit(depth) {
534 tcx.dcx().emit_fatal(InherentProjectionNormalizationOverflow {
536 span: cause.span,
537 ty: alias_term.to_string(),
538 });
539 }
540
541 let args = compute_inherent_assoc_term_args(
542 selcx,
543 param_env,
544 alias_term,
545 cause.clone(),
546 depth,
547 obligations,
548 );
549
550 let def_id = alias_term.expect_inherent_def_id();
552 let clauses = tcx.clauses_of(def_id).instantiate(tcx, args);
553 for (clause, span) in clauses {
554 let clause = normalize_with_depth_to(
555 selcx,
556 param_env,
557 cause.clone(),
558 depth + 1,
559 clause,
560 obligations,
561 );
562
563 let nested_cause = ObligationCause::new(
564 cause.span,
565 cause.body_def_id,
566 ObligationCauseCode::WhereClause(def_id, span),
571 );
572
573 obligations.push(Obligation::with_depth(tcx, nested_cause, depth + 1, param_env, clause));
574 }
575
576 let term = if alias_term.kind.is_type() {
577 tcx.type_of(def_id).instantiate(tcx, args).map(Into::into)
578 } else {
579 tcx.const_of_item(def_id).instantiate(tcx, args).map(Into::into)
580 };
581
582 let term = selcx.infcx.resolve_vars_if_possible(term);
583 let term =
584 normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, term, obligations);
585
586 push_const_arg_has_type_obligation(
587 tcx,
588 obligations,
589 &cause,
590 depth + 1,
591 param_env,
592 term,
593 def_id,
594 args,
595 );
596
597 term
598}
599
600pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>(
602 selcx: &'a mut SelectionContext<'b, 'tcx>,
603 param_env: ty::ParamEnv<'tcx>,
604 alias_term: ty::AliasTerm<'tcx>,
605 cause: ObligationCause<'tcx>,
606 depth: usize,
607 obligations: &mut PredicateObligations<'tcx>,
608) -> ty::GenericArgsRef<'tcx> {
609 let tcx = selcx.tcx();
610
611 let alias_def_id = alias_term.expect_inherent_def_id();
612 let impl_def_id = tcx.parent(alias_def_id);
613 let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id);
614
615 let impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
616 let impl_ty = if !selcx.infcx.next_trait_solver() {
617 normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations)
618 } else {
619 impl_ty.skip_norm_wip()
620 };
621
622 let self_ty = ty::Unnormalized::new_wip(alias_term.self_ty());
625 let self_ty = if !selcx.infcx.next_trait_solver() {
626 normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, self_ty, obligations)
627 } else {
628 self_ty.skip_normalization()
629 };
630
631 match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::Yes, impl_ty, self_ty) {
632 Ok(mut ok) => obligations.append(&mut ok.obligations),
633 Err(_) => {
634 tcx.dcx().span_bug(
635 cause.span,
636 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?} was equal to {1:?} during selection but now it is not",
self_ty, impl_ty))
})format!("{self_ty:?} was equal to {impl_ty:?} during selection but now it is not"),
637 );
638 }
639 }
640
641 alias_term.rebase_inherent_args_onto_impl(impl_args, tcx)
642}
643
644enum Projected<'tcx> {
645 Progress(Progress<'tcx>),
646 NoProgress(ty::Term<'tcx>),
647}
648
649struct Progress<'tcx> {
650 term: ty::Unnormalized<'tcx, ty::Term<'tcx>>,
651 obligations: PredicateObligations<'tcx>,
652}
653
654impl<'tcx> Progress<'tcx> {
655 fn error_for_term(
656 tcx: TyCtxt<'tcx>,
657 alias_term: ty::AliasTerm<'tcx>,
658 guar: ErrorGuaranteed,
659 ) -> Self {
660 let err_term = if alias_term.kind.is_type() {
661 Ty::new_error(tcx, guar).into()
662 } else {
663 ty::Const::new_error(tcx, guar).into()
664 };
665 Progress {
666 term: ty::Unnormalized::dummy(err_term),
667 obligations: PredicateObligations::new(),
668 }
669 }
670
671 fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self {
672 self.obligations.append(&mut obligations);
673 self
674 }
675}
676
677#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::INFO <=
::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("project",
"rustc_trait_selection::traits::project",
::tracing::Level::INFO,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(682u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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::INFO <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::INFO <=
::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(&obligation)
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<Projected<'tcx>, ProjectionError<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth)
{
return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow(OverflowError::Canonical)));
}
if let Err(guar) =
obligation.predicate.non_region_error_reported() {
return Ok(Projected::Progress(Progress::error_for_term(selcx.tcx(),
obligation.predicate, guar)));
}
let mut candidates = ProjectionCandidateSet::None;
assemble_candidates_from_param_env(selcx, obligation,
&mut candidates);
assemble_candidates_from_trait_def(selcx, obligation,
&mut candidates);
assemble_candidates_from_object_ty(selcx, obligation,
&mut candidates);
if let ProjectionCandidateSet::Single(ProjectionCandidate::Object(_))
= candidates
{} else {
assemble_candidates_from_impls(selcx, obligation,
&mut candidates);
};
match candidates {
ProjectionCandidateSet::Single(candidate) => {
confirm_candidate(selcx, obligation, candidate)
}
ProjectionCandidateSet::None => {
let tcx = selcx.tcx();
let term =
obligation.predicate.to_term(tcx, ty::IsRigid::No);
Ok(Projected::NoProgress(term))
}
ProjectionCandidateSet::Error(e) =>
Err(ProjectionError::TraitSelectionError(e)),
ProjectionCandidateSet::Ambiguous =>
Err(ProjectionError::TooManyCandidates),
}
}
}
}#[instrument(level = "info", skip(selcx))]
683fn project<'cx, 'tcx>(
684 selcx: &mut SelectionContext<'cx, 'tcx>,
685 obligation: &ProjectionTermObligation<'tcx>,
686) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
687 if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
688 return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow(
691 OverflowError::Canonical,
692 )));
693 }
694
695 if let Err(guar) = obligation.predicate.non_region_error_reported() {
698 return Ok(Projected::Progress(Progress::error_for_term(
699 selcx.tcx(),
700 obligation.predicate,
701 guar,
702 )));
703 }
704
705 let mut candidates = ProjectionCandidateSet::None;
706
707 assemble_candidates_from_param_env(selcx, obligation, &mut candidates);
711
712 assemble_candidates_from_trait_def(selcx, obligation, &mut candidates);
713
714 assemble_candidates_from_object_ty(selcx, obligation, &mut candidates);
715
716 if let ProjectionCandidateSet::Single(ProjectionCandidate::Object(_)) = candidates {
717 } else {
722 assemble_candidates_from_impls(selcx, obligation, &mut candidates);
723 };
724
725 match candidates {
726 ProjectionCandidateSet::Single(candidate) => {
727 confirm_candidate(selcx, obligation, candidate)
728 }
729 ProjectionCandidateSet::None => {
730 let tcx = selcx.tcx();
731 let term = obligation.predicate.to_term(tcx, ty::IsRigid::No);
732 Ok(Projected::NoProgress(term))
733 }
734 ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)),
736 ProjectionCandidateSet::Ambiguous => Err(ProjectionError::TooManyCandidates),
739 }
740}
741
742fn assemble_candidates_from_param_env<'cx, 'tcx>(
746 selcx: &mut SelectionContext<'cx, 'tcx>,
747 obligation: &ProjectionTermObligation<'tcx>,
748 candidate_set: &mut ProjectionCandidateSet<'tcx>,
749) {
750 assemble_candidates_from_clauses(
751 selcx,
752 obligation,
753 candidate_set,
754 ProjectionCandidate::ParamEnv,
755 obligation.param_env.caller_bounds().iter(),
756 false,
757 );
758}
759
760fn assemble_candidates_from_trait_def<'cx, 'tcx>(
771 selcx: &mut SelectionContext<'cx, 'tcx>,
772 obligation: &ProjectionTermObligation<'tcx>,
773 candidate_set: &mut ProjectionCandidateSet<'tcx>,
774) {
775 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:775",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(775u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("assemble_candidates_from_trait_def(..)")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("assemble_candidates_from_trait_def(..)");
776 let mut ambiguous = false;
777 let _ = selcx.for_each_item_bound(
778 obligation.predicate.self_ty(),
779 |selcx, clause, _, _| {
780 let Some(clause) = clause.as_projection_clause() else {
781 return ControlFlow::Continue(());
782 };
783 if clause.item_def_id() != obligation.predicate.expect_projection_def_id() {
784 return ControlFlow::Continue(());
785 }
786
787 let is_match =
788 selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));
789
790 match is_match {
791 ProjectionMatchesProjection::Yes => {
792 candidate_set.push_candidate(ProjectionCandidate::TraitDef(clause));
793
794 if !obligation.predicate.has_non_region_infer() {
795 return ControlFlow::Break(());
799 }
800 }
801 ProjectionMatchesProjection::Ambiguous => {
802 candidate_set.mark_ambiguous();
803 }
804 ProjectionMatchesProjection::No => {}
805 }
806
807 ControlFlow::Continue(())
808 },
809 || ambiguous = true,
812 );
813
814 if ambiguous {
815 candidate_set.mark_ambiguous();
816 }
817}
818
819fn assemble_candidates_from_object_ty<'cx, 'tcx>(
829 selcx: &mut SelectionContext<'cx, 'tcx>,
830 obligation: &ProjectionTermObligation<'tcx>,
831 candidate_set: &mut ProjectionCandidateSet<'tcx>,
832) {
833 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:833",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(833u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("assemble_candidates_from_object_ty(..)")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("assemble_candidates_from_object_ty(..)");
834
835 let tcx = selcx.tcx();
836
837 let self_ty = obligation.predicate.self_ty();
838 let object_ty = selcx.infcx.shallow_resolve(self_ty);
839 let data = match object_ty.kind() {
840 ty::Dynamic(data, ..) => data,
841 ty::Infer(ty::TyVar(_)) => {
842 candidate_set.mark_ambiguous();
845 return;
846 }
847 _ => return,
848 };
849 let env_clauses = data
850 .projection_bounds()
851 .filter(|bound| bound.item_def_id() == obligation.predicate.expect_projection_def_id())
852 .map(|p| p.with_self_ty(tcx, object_ty).upcast(tcx));
853
854 assemble_candidates_from_clauses(
855 selcx,
856 obligation,
857 candidate_set,
858 ProjectionCandidate::Object,
859 env_clauses,
860 false,
861 );
862}
863
864#[allow(clippy :: suspicious_else_formatting)]
{
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("assemble_candidates_from_clauses",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(864u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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(&obligation)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
let infcx = selcx.infcx;
let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
for clause in env_clauses {
let bound_clause = clause.kind();
if let ty::ClauseKind::Projection(data) =
clause.kind().skip_binder() {
let data = bound_clause.rebind(data);
if data.item_def_id() !=
obligation.predicate.expect_projection_def_id() {
continue;
}
if !drcx.args_may_unify(obligation.predicate.args,
data.skip_binder().projection_term.args) {
continue;
}
let is_match =
infcx.probe(|_|
{
selcx.match_projection_projections(obligation, data,
potentially_unnormalized_candidates)
});
match is_match {
ProjectionMatchesProjection::Yes => {
candidate_set.push_candidate(ctor(data));
if potentially_unnormalized_candidates &&
!obligation.predicate.has_non_region_infer() {
return;
}
}
ProjectionMatchesProjection::Ambiguous => {
candidate_set.mark_ambiguous();
}
ProjectionMatchesProjection::No => {}
}
}
}
}
}
}#[instrument(
865 level = "debug",
866 skip(selcx, candidate_set, ctor, env_clauses, potentially_unnormalized_candidates)
867)]
868fn assemble_candidates_from_clauses<'cx, 'tcx>(
869 selcx: &mut SelectionContext<'cx, 'tcx>,
870 obligation: &ProjectionTermObligation<'tcx>,
871 candidate_set: &mut ProjectionCandidateSet<'tcx>,
872 ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>,
873 env_clauses: impl Iterator<Item = ty::Clause<'tcx>>,
874 potentially_unnormalized_candidates: bool,
875) {
876 let infcx = selcx.infcx;
877 let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
878 for clause in env_clauses {
879 let bound_clause = clause.kind();
880 if let ty::ClauseKind::Projection(data) = clause.kind().skip_binder() {
881 let data = bound_clause.rebind(data);
882 if data.item_def_id() != obligation.predicate.expect_projection_def_id() {
883 continue;
884 }
885
886 if !drcx
887 .args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args)
888 {
889 continue;
890 }
891
892 let is_match = infcx.probe(|_| {
893 selcx.match_projection_projections(
894 obligation,
895 data,
896 potentially_unnormalized_candidates,
897 )
898 });
899
900 match is_match {
901 ProjectionMatchesProjection::Yes => {
902 candidate_set.push_candidate(ctor(data));
903
904 if potentially_unnormalized_candidates
905 && !obligation.predicate.has_non_region_infer()
906 {
907 return;
911 }
912 }
913 ProjectionMatchesProjection::Ambiguous => {
914 candidate_set.mark_ambiguous();
915 }
916 ProjectionMatchesProjection::No => {}
917 }
918 }
919 }
920}
921
922#[allow(clippy :: suspicious_else_formatting)]
{
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("assemble_candidates_from_impls",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(922u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[],
::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,
&{ meta.fields().value_set_all(&[]) })
} 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: () = loop {};
return __tracing_attr_fake_return;
}
{
let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
let trait_obligation = obligation.with(selcx.tcx(), trait_ref);
let _ =
selcx.infcx.commit_if_ok(|_|
{
let impl_source =
match selcx.select(&trait_obligation) {
Ok(Some(impl_source)) => impl_source,
Ok(None) => {
candidate_set.mark_ambiguous();
return Err(());
}
Err(e) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:940",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(940u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("error")
}> =
::tracing::__macro_support::FieldName::new("error");
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!("selection error")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&e)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
candidate_set.mark_error(e);
return Err(());
}
};
let eligible =
match &impl_source {
ImplSource::UserDefined(impl_data) => {
match specialization_graph::assoc_def(selcx.tcx(),
impl_data.impl_def_id,
obligation.predicate.expect_projection_def_id()) {
Ok(node_item) => {
if node_item.is_final() {
true
} else {
match selcx.typing_mode() {
TypingMode::Coherence | TypingMode::Typeck { .. } |
TypingMode::PostTypeckUntilBorrowck { .. } |
TypingMode::Reflection | TypingMode::PostBorrowck { .. } =>
{
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:990",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(990u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("assoc_ty")
}> =
::tracing::__macro_support::FieldName::new("assoc_ty");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation.predicate")
}> =
::tracing::__macro_support::FieldName::new("obligation.predicate");
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!("not eligible due to default")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&selcx.tcx().def_path_str(node_item.item.def_id))
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation.predicate)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
false
}
TypingMode::PostAnalysis | TypingMode::Codegen => {
let poly_trait_ref =
selcx.infcx.resolve_vars_if_possible(trait_ref);
!poly_trait_ref.still_further_specializable()
}
}
}
}
Err(ErrorGuaranteed { .. }) => true,
}
}
ImplSource::Builtin(BuiltinImplSource::Misc |
BuiltinImplSource::Trivial, _) => {
let self_ty =
selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
let tcx = selcx.tcx();
match selcx.tcx().as_lang_item(trait_ref.def_id) {
Some(LangItem::Coroutine | LangItem::Future |
LangItem::Iterator | LangItem::AsyncIterator |
LangItem::Field | LangItem::Fn | LangItem::FnMut |
LangItem::FnOnce | LangItem::AsyncFn | LangItem::AsyncFnMut
| LangItem::AsyncFnOnce) => true,
Some(LangItem::AsyncFnKindHelper) => {
if obligation.predicate.args.type_at(0).is_ty_var() ||
obligation.predicate.args.type_at(4).is_ty_var() ||
obligation.predicate.args.type_at(5).is_ty_var() {
candidate_set.mark_ambiguous();
true
} else {
obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some()
&&
obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
}
}
Some(LangItem::DiscriminantKind) =>
match self_ty.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) |
ty::Float(_) | ty::Adt(..) | ty::Foreign(_) | ty::Str |
ty::Array(..) | ty::Pat(..) | ty::Slice(_) | ty::RawPtr(..)
| ty::Ref(..) | ty::FnDef(..) | ty::FnPtr(..) |
ty::Dynamic(..) | ty::Closure(..) | ty::CoroutineClosure(..)
| ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Never |
ty::Tuple(..) |
ty::Infer(ty::InferTy::IntVar(_) |
ty::InferTy::FloatVar(..)) => true,
ty::UnsafeBinder(_) => {
::core::panicking::panic_fmt(format_args!("not implemented: {0}",
format_args!("FIXME(unsafe_binder)")));
}
ty::Param(_) | ty::Alias(..) | ty::Bound(..) |
ty::Placeholder(..) | ty::Infer(..) | ty::Error(_) => false,
},
Some(LangItem::PointeeTrait) => {
let tail =
selcx.tcx().struct_tail_raw(self_ty, &obligation.cause,
|ty|
{
normalize_with_depth(selcx, obligation.param_env,
obligation.cause.clone(), obligation.recursion_depth + 1,
ty).value
}, || {});
match tail.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) |
ty::Float(_) | ty::Str | ty::Array(..) | ty::Pat(..) |
ty::Slice(_) | ty::RawPtr(..) | ty::Ref(..) | ty::FnDef(..)
| ty::FnPtr(..) | ty::Dynamic(..) | ty::Closure(..) |
ty::CoroutineClosure(..) | ty::Coroutine(..) |
ty::CoroutineWitness(..) | ty::Never | ty::Foreign(_) |
ty::Adt(..) | ty::Tuple(..) |
ty::Infer(ty::InferTy::IntVar(_) |
ty::InferTy::FloatVar(..)) | ty::Error(..) => true,
ty::Param(_) | ty::Alias(..) if
self_ty != tail ||
selcx.infcx.predicate_must_hold_modulo_regions(&obligation.with(selcx.tcx(),
ty::TraitRef::new(selcx.tcx(),
selcx.tcx().require_lang_item(LangItem::Sized,
obligation.cause.span), [self_ty]))) => {
true
}
ty::UnsafeBinder(_) => {
::core::panicking::panic_fmt(format_args!("not implemented: {0}",
format_args!("FIXME(unsafe_binder)")));
}
ty::Param(_) | ty::Alias(..) | ty::Bound(..) |
ty::Placeholder(..) | ty::Infer(..) => {
if tail.has_infer_types() {
candidate_set.mark_ambiguous();
}
false
}
}
}
_ if tcx.trait_is_auto(trait_ref.def_id) => {
tcx.dcx().span_delayed_bug(tcx.def_span(obligation.predicate.expect_projection_def_id()),
"associated types not allowed on auto traits");
false
}
_ => {
::rustc_middle::util::bug::bug_fmt(format_args!("unexpected builtin trait with associated type: {0:?}",
trait_ref))
}
}
}
ImplSource::Param(..) => { false }
ImplSource::Builtin(BuiltinImplSource::Object { .. }, _) =>
{
false
}
ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { ..
}, _) => {
selcx.tcx().dcx().span_delayed_bug(obligation.cause.span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Cannot project an associated type from `{0:?}`",
impl_source))
}));
return Err(());
}
};
if eligible {
if candidate_set.push_candidate(ProjectionCandidate::Select(impl_source))
{
Ok(())
} else { Err(()) }
} else { Err(()) }
});
}
}
}#[instrument(level = "debug", skip(selcx, obligation, candidate_set))]
923fn assemble_candidates_from_impls<'cx, 'tcx>(
924 selcx: &mut SelectionContext<'cx, 'tcx>,
925 obligation: &ProjectionTermObligation<'tcx>,
926 candidate_set: &mut ProjectionCandidateSet<'tcx>,
927) {
928 let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
931 let trait_obligation = obligation.with(selcx.tcx(), trait_ref);
932 let _ = selcx.infcx.commit_if_ok(|_| {
933 let impl_source = match selcx.select(&trait_obligation) {
934 Ok(Some(impl_source)) => impl_source,
935 Ok(None) => {
936 candidate_set.mark_ambiguous();
937 return Err(());
938 }
939 Err(e) => {
940 debug!(error = ?e, "selection error");
941 candidate_set.mark_error(e);
942 return Err(());
943 }
944 };
945
946 let eligible = match &impl_source {
947 ImplSource::UserDefined(impl_data) => {
948 match specialization_graph::assoc_def(
971 selcx.tcx(),
972 impl_data.impl_def_id,
973 obligation.predicate.expect_projection_def_id(),
974 ) {
975 Ok(node_item) => {
976 if node_item.is_final() {
977 true
979 } else {
980 match selcx.typing_mode() {
985 TypingMode::Coherence
986 | TypingMode::Typeck { .. }
987 | TypingMode::PostTypeckUntilBorrowck { .. }
988 | TypingMode::Reflection
989 | TypingMode::PostBorrowck { .. } => {
990 debug!(
991 assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
992 ?obligation.predicate,
993 "not eligible due to default",
994 );
995 false
996 }
997 TypingMode::PostAnalysis | TypingMode::Codegen => {
998 let poly_trait_ref =
1001 selcx.infcx.resolve_vars_if_possible(trait_ref);
1002 !poly_trait_ref.still_further_specializable()
1003 }
1004 }
1005 }
1006 }
1007 Err(ErrorGuaranteed { .. }) => true,
1011 }
1012 }
1013 ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, _) => {
1014 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1018
1019 let tcx = selcx.tcx();
1020 match selcx.tcx().as_lang_item(trait_ref.def_id) {
1021 Some(
1022 LangItem::Coroutine
1023 | LangItem::Future
1024 | LangItem::Iterator
1025 | LangItem::AsyncIterator
1026 | LangItem::Field
1027 | LangItem::Fn
1028 | LangItem::FnMut
1029 | LangItem::FnOnce
1030 | LangItem::AsyncFn
1031 | LangItem::AsyncFnMut
1032 | LangItem::AsyncFnOnce,
1033 ) => true,
1034 Some(LangItem::AsyncFnKindHelper) => {
1035 if obligation.predicate.args.type_at(0).is_ty_var()
1037 || obligation.predicate.args.type_at(4).is_ty_var()
1038 || obligation.predicate.args.type_at(5).is_ty_var()
1039 {
1040 candidate_set.mark_ambiguous();
1041 true
1042 } else {
1043 obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some()
1044 && obligation
1045 .predicate
1046 .args
1047 .type_at(1)
1048 .to_opt_closure_kind()
1049 .is_some()
1050 }
1051 }
1052 Some(LangItem::DiscriminantKind) => match self_ty.kind() {
1053 ty::Bool
1054 | ty::Char
1055 | ty::Int(_)
1056 | ty::Uint(_)
1057 | ty::Float(_)
1058 | ty::Adt(..)
1059 | ty::Foreign(_)
1060 | ty::Str
1061 | ty::Array(..)
1062 | ty::Pat(..)
1063 | ty::Slice(_)
1064 | ty::RawPtr(..)
1065 | ty::Ref(..)
1066 | ty::FnDef(..)
1067 | ty::FnPtr(..)
1068 | ty::Dynamic(..)
1069 | ty::Closure(..)
1070 | ty::CoroutineClosure(..)
1071 | ty::Coroutine(..)
1072 | ty::CoroutineWitness(..)
1073 | ty::Never
1074 | ty::Tuple(..)
1075 | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1077
1078 ty::UnsafeBinder(_) => unimplemented!("FIXME(unsafe_binder)"),
1079
1080 ty::Param(_)
1084 | ty::Alias(..)
1085 | ty::Bound(..)
1086 | ty::Placeholder(..)
1087 | ty::Infer(..)
1088 | ty::Error(_) => false,
1089 },
1090 Some(LangItem::PointeeTrait) => {
1091 let tail = selcx.tcx().struct_tail_raw(
1092 self_ty,
1093 &obligation.cause,
1094 |ty| {
1095 normalize_with_depth(
1098 selcx,
1099 obligation.param_env,
1100 obligation.cause.clone(),
1101 obligation.recursion_depth + 1,
1102 ty,
1103 )
1104 .value
1105 },
1106 || {},
1107 );
1108
1109 match tail.kind() {
1110 ty::Bool
1111 | ty::Char
1112 | ty::Int(_)
1113 | ty::Uint(_)
1114 | ty::Float(_)
1115 | ty::Str
1116 | ty::Array(..)
1117 | ty::Pat(..)
1118 | ty::Slice(_)
1119 | ty::RawPtr(..)
1120 | ty::Ref(..)
1121 | ty::FnDef(..)
1122 | ty::FnPtr(..)
1123 | ty::Dynamic(..)
1124 | ty::Closure(..)
1125 | ty::CoroutineClosure(..)
1126 | ty::Coroutine(..)
1127 | ty::CoroutineWitness(..)
1128 | ty::Never
1129 | ty::Foreign(_)
1131 | ty::Adt(..)
1134 | ty::Tuple(..)
1136 | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..))
1138 | ty::Error(..) => true,
1140
1141 ty::Param(_) | ty::Alias(..)
1145 if self_ty != tail
1146 || selcx.infcx.predicate_must_hold_modulo_regions(
1147 &obligation.with(
1148 selcx.tcx(),
1149 ty::TraitRef::new(
1150 selcx.tcx(),
1151 selcx.tcx().require_lang_item(
1152 LangItem::Sized,
1153 obligation.cause.span,
1154 ),
1155 [self_ty],
1156 ),
1157 ),
1158 ) =>
1159 {
1160 true
1161 }
1162
1163 ty::UnsafeBinder(_) => unimplemented!("FIXME(unsafe_binder)"),
1164
1165 ty::Param(_)
1167 | ty::Alias(..)
1168 | ty::Bound(..)
1169 | ty::Placeholder(..)
1170 | ty::Infer(..) => {
1171 if tail.has_infer_types() {
1172 candidate_set.mark_ambiguous();
1173 }
1174 false
1175 }
1176 }
1177 }
1178 _ if tcx.trait_is_auto(trait_ref.def_id) => {
1179 tcx.dcx().span_delayed_bug(
1180 tcx.def_span(obligation.predicate.expect_projection_def_id()),
1181 "associated types not allowed on auto traits",
1182 );
1183 false
1184 }
1185 _ => {
1186 bug!("unexpected builtin trait with associated type: {trait_ref:?}")
1187 }
1188 }
1189 }
1190 ImplSource::Param(..) => {
1191 false
1217 }
1218 ImplSource::Builtin(BuiltinImplSource::Object { .. }, _) => {
1219 false
1223 }
1224 ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
1225 selcx.tcx().dcx().span_delayed_bug(
1227 obligation.cause.span,
1228 format!("Cannot project an associated type from `{impl_source:?}`"),
1229 );
1230 return Err(());
1231 }
1232 };
1233
1234 if eligible {
1235 if candidate_set.push_candidate(ProjectionCandidate::Select(impl_source)) {
1236 Ok(())
1237 } else {
1238 Err(())
1239 }
1240 } else {
1241 Err(())
1242 }
1243 });
1244}
1245
1246fn confirm_candidate<'cx, 'tcx>(
1248 selcx: &mut SelectionContext<'cx, 'tcx>,
1249 obligation: &ProjectionTermObligation<'tcx>,
1250 candidate: ProjectionCandidate<'tcx>,
1251) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
1252 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1252",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1252u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("candidate")
}> =
::tracing::__macro_support::FieldName::new("candidate");
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!("confirm_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&candidate)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?candidate, "confirm_candidate");
1253 let mut result = match candidate {
1254 ProjectionCandidate::ParamEnv(poly_projection)
1255 | ProjectionCandidate::Object(poly_projection) => Ok(Projected::Progress(
1256 confirm_param_env_candidate(selcx, obligation, poly_projection, false),
1257 )),
1258 ProjectionCandidate::TraitDef(poly_projection) => Ok(Projected::Progress(
1259 confirm_param_env_candidate(selcx, obligation, poly_projection, true),
1260 )),
1261 ProjectionCandidate::Select(impl_source) => {
1262 confirm_select_candidate(selcx, obligation, impl_source)
1263 }
1264 };
1265
1266 if let Ok(Projected::Progress(progress)) = &mut result
1272 && progress.term.has_infer_regions()
1273 {
1274 progress.term = progress.term.fold_with(&mut OpportunisticRegionResolver::new(selcx.infcx));
1275 }
1276
1277 result
1278}
1279
1280fn confirm_select_candidate<'cx, 'tcx>(
1282 selcx: &mut SelectionContext<'cx, 'tcx>,
1283 obligation: &ProjectionTermObligation<'tcx>,
1284 impl_source: Selection<'tcx>,
1285) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
1286 match impl_source {
1287 ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
1288 ImplSource::Builtin(BuiltinImplSource::Misc | BuiltinImplSource::Trivial, data) => {
1289 let tcx = selcx.tcx();
1290 let trait_def_id = obligation.predicate.trait_def_id(tcx);
1291 let progress = if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) {
1292 confirm_coroutine_candidate(selcx, obligation, data)
1293 } else if tcx.is_lang_item(trait_def_id, LangItem::Future) {
1294 confirm_future_candidate(selcx, obligation, data)
1295 } else if tcx.is_lang_item(trait_def_id, LangItem::Iterator) {
1296 confirm_iterator_candidate(selcx, obligation, data)
1297 } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncIterator) {
1298 confirm_async_iterator_candidate(selcx, obligation, data)
1299 } else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
1300 if obligation.predicate.self_ty().is_closure()
1301 || obligation.predicate.self_ty().is_coroutine_closure()
1302 {
1303 confirm_closure_candidate(selcx, obligation, data)
1304 } else {
1305 confirm_fn_pointer_candidate(selcx, obligation, data)
1306 }
1307 } else if selcx.tcx().async_fn_trait_kind_from_def_id(trait_def_id).is_some() {
1308 confirm_async_closure_candidate(selcx, obligation, data)
1309 } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncFnKindHelper) {
1310 confirm_async_fn_kind_helper_candidate(selcx, obligation, data)
1311 } else {
1312 confirm_builtin_candidate(selcx, obligation, data)
1313 };
1314 Ok(Projected::Progress(progress))
1315 }
1316 ImplSource::Builtin(BuiltinImplSource::Object { .. }, _)
1317 | ImplSource::Param(..)
1318 | ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
1319 ::rustc_middle::util::bug::span_bug_fmt(obligation.cause.span,
format_args!("Cannot project an associated type from `{0:?}`",
impl_source))span_bug!(
1321 obligation.cause.span,
1322 "Cannot project an associated type from `{:?}`",
1323 impl_source
1324 )
1325 }
1326 }
1327}
1328
1329fn confirm_coroutine_candidate<'cx, 'tcx>(
1330 selcx: &mut SelectionContext<'cx, 'tcx>,
1331 obligation: &ProjectionTermObligation<'tcx>,
1332 nested: PredicateObligations<'tcx>,
1333) -> Progress<'tcx> {
1334 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1335 let ty::Coroutine(_, args) = self_ty.kind() else {
1336 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("expected coroutine self type for built-in coroutine candidate, found {0}",
self_ty)));
}unreachable!(
1337 "expected coroutine self type for built-in coroutine candidate, found {self_ty}"
1338 )
1339 };
1340 let coroutine_sig = Unnormalized::new_wip(args.as_coroutine().sig());
1341 let Normalized { value: coroutine_sig, obligations } = normalize_with_depth(
1342 selcx,
1343 obligation.param_env,
1344 obligation.cause.clone(),
1345 obligation.recursion_depth + 1,
1346 coroutine_sig,
1347 );
1348
1349 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1349",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1349u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("coroutine_sig")
}> =
::tracing::__macro_support::FieldName::new("coroutine_sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("confirm_coroutine_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&coroutine_sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?coroutine_sig, ?obligations, "confirm_coroutine_candidate");
1350
1351 let tcx = selcx.tcx();
1352
1353 let coroutine_def_id = tcx.require_lang_item(LangItem::Coroutine, obligation.cause.span);
1354
1355 let (trait_ref, yield_ty, return_ty) = super::util::coroutine_trait_ref_and_outputs(
1356 tcx,
1357 coroutine_def_id,
1358 obligation.predicate.self_ty(),
1359 coroutine_sig,
1360 );
1361
1362 let def_id = obligation.predicate.expect_projection_def_id();
1363 let ty = if tcx.is_lang_item(def_id, LangItem::CoroutineReturn) {
1364 return_ty
1365 } else if tcx.is_lang_item(def_id, LangItem::CoroutineYield) {
1366 yield_ty
1367 } else {
1368 ::rustc_middle::util::bug::span_bug_fmt(tcx.def_span(def_id),
format_args!("unexpected associated type: `Coroutine::{0}`",
tcx.item_name(def_id)));span_bug!(
1369 tcx.def_span(def_id),
1370 "unexpected associated type: `Coroutine::{}`",
1371 tcx.item_name(def_id),
1372 );
1373 };
1374
1375 let predicate = ty::ProjectionPredicate {
1376 projection_term: obligation.predicate.with_args(tcx, trait_ref.args),
1377 term: ty.into(),
1378 };
1379
1380 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1381 .with_addl_obligations(nested)
1382 .with_addl_obligations(obligations)
1383}
1384
1385fn confirm_future_candidate<'cx, 'tcx>(
1386 selcx: &mut SelectionContext<'cx, 'tcx>,
1387 obligation: &ProjectionTermObligation<'tcx>,
1388 nested: PredicateObligations<'tcx>,
1389) -> Progress<'tcx> {
1390 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1391 let ty::Coroutine(_, args) = self_ty.kind() else {
1392 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("expected coroutine self type for built-in async future candidate, found {0}",
self_ty)));
}unreachable!(
1393 "expected coroutine self type for built-in async future candidate, found {self_ty}"
1394 )
1395 };
1396 let coroutine_sig = Unnormalized::new_wip(args.as_coroutine().sig());
1397 let Normalized { value: coroutine_sig, obligations } = normalize_with_depth(
1398 selcx,
1399 obligation.param_env,
1400 obligation.cause.clone(),
1401 obligation.recursion_depth + 1,
1402 coroutine_sig,
1403 );
1404
1405 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1405",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1405u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("coroutine_sig")
}> =
::tracing::__macro_support::FieldName::new("coroutine_sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("confirm_future_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&coroutine_sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?coroutine_sig, ?obligations, "confirm_future_candidate");
1406
1407 let tcx = selcx.tcx();
1408 let fut_def_id = tcx.require_lang_item(LangItem::Future, obligation.cause.span);
1409
1410 let (trait_ref, return_ty) = super::util::future_trait_ref_and_outputs(
1411 tcx,
1412 fut_def_id,
1413 obligation.predicate.self_ty(),
1414 coroutine_sig,
1415 );
1416
1417 if true {
{
match (&tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
&sym::Output) {
(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);
}
}
}
};
};debug_assert_eq!(
1418 tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
1419 sym::Output
1420 );
1421
1422 let predicate = ty::ProjectionPredicate {
1423 projection_term: obligation.predicate.with_args(tcx, trait_ref.args),
1424 term: return_ty.into(),
1425 };
1426
1427 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1428 .with_addl_obligations(nested)
1429 .with_addl_obligations(obligations)
1430}
1431
1432fn confirm_iterator_candidate<'cx, 'tcx>(
1433 selcx: &mut SelectionContext<'cx, 'tcx>,
1434 obligation: &ProjectionTermObligation<'tcx>,
1435 nested: PredicateObligations<'tcx>,
1436) -> Progress<'tcx> {
1437 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1438 let ty::Coroutine(_, args) = self_ty.kind() else {
1439 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("expected coroutine self type for built-in gen candidate, found {0}",
self_ty)));
}unreachable!("expected coroutine self type for built-in gen candidate, found {self_ty}")
1440 };
1441 let gen_sig = Unnormalized::new_wip(args.as_coroutine().sig());
1442 let Normalized { value: gen_sig, obligations } = normalize_with_depth(
1443 selcx,
1444 obligation.param_env,
1445 obligation.cause.clone(),
1446 obligation.recursion_depth + 1,
1447 gen_sig,
1448 );
1449
1450 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1450",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1450u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("gen_sig")
}> =
::tracing::__macro_support::FieldName::new("gen_sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("confirm_iterator_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&gen_sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?gen_sig, ?obligations, "confirm_iterator_candidate");
1451
1452 let tcx = selcx.tcx();
1453 let iter_def_id = tcx.require_lang_item(LangItem::Iterator, obligation.cause.span);
1454
1455 let (trait_ref, yield_ty) = super::util::iterator_trait_ref_and_outputs(
1456 tcx,
1457 iter_def_id,
1458 obligation.predicate.self_ty(),
1459 gen_sig,
1460 );
1461
1462 if true {
{
match (&tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
&sym::Item) {
(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);
}
}
}
};
};debug_assert_eq!(
1463 tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
1464 sym::Item
1465 );
1466
1467 let predicate = ty::ProjectionPredicate {
1468 projection_term: obligation.predicate.with_args(tcx, trait_ref.args),
1469 term: yield_ty.into(),
1470 };
1471
1472 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1473 .with_addl_obligations(nested)
1474 .with_addl_obligations(obligations)
1475}
1476
1477fn confirm_async_iterator_candidate<'cx, 'tcx>(
1478 selcx: &mut SelectionContext<'cx, 'tcx>,
1479 obligation: &ProjectionTermObligation<'tcx>,
1480 nested: PredicateObligations<'tcx>,
1481) -> Progress<'tcx> {
1482 let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
1483 else {
1484 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1485 };
1486 let gen_sig = Unnormalized::new_wip(args.as_coroutine().sig());
1487 let Normalized { value: gen_sig, obligations } = normalize_with_depth(
1488 selcx,
1489 obligation.param_env,
1490 obligation.cause.clone(),
1491 obligation.recursion_depth + 1,
1492 gen_sig,
1493 );
1494
1495 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1495",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1495u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("gen_sig")
}> =
::tracing::__macro_support::FieldName::new("gen_sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("confirm_async_iterator_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&gen_sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?gen_sig, ?obligations, "confirm_async_iterator_candidate");
1496
1497 let tcx = selcx.tcx();
1498 let iter_def_id = tcx.require_lang_item(LangItem::AsyncIterator, obligation.cause.span);
1499
1500 let (trait_ref, yield_ty) = super::util::async_iterator_trait_ref_and_outputs(
1501 tcx,
1502 iter_def_id,
1503 obligation.predicate.self_ty(),
1504 gen_sig,
1505 );
1506
1507 if true {
{
match (&tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
&sym::Item) {
(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);
}
}
}
};
};debug_assert_eq!(
1508 tcx.associated_item(obligation.predicate.expect_projection_def_id()).name(),
1509 sym::Item
1510 );
1511
1512 let ty::Adt(_poll_adt, args) = *yield_ty.kind() else {
1513 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"));bug!();
1514 };
1515 let ty::Adt(_option_adt, args) = *args.type_at(0).kind() else {
1516 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"));bug!();
1517 };
1518 let item_ty = args.type_at(0);
1519
1520 let predicate = ty::ProjectionPredicate {
1521 projection_term: obligation.predicate.with_args(tcx, trait_ref.args),
1522 term: item_ty.into(),
1523 };
1524
1525 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1526 .with_addl_obligations(nested)
1527 .with_addl_obligations(obligations)
1528}
1529
1530fn confirm_builtin_candidate<'cx, 'tcx>(
1531 selcx: &mut SelectionContext<'cx, 'tcx>,
1532 obligation: &ProjectionTermObligation<'tcx>,
1533 data: PredicateObligations<'tcx>,
1534) -> Progress<'tcx> {
1535 let tcx = selcx.tcx();
1536 let self_ty = obligation.predicate.self_ty();
1537 let item_def_id = obligation.predicate.expect_projection_def_id();
1538 let trait_def_id = tcx.parent(item_def_id);
1539 let args = tcx.mk_args(&[self_ty.into()]);
1540 let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) {
1541 let discriminant_def_id =
1542 tcx.require_lang_item(LangItem::Discriminant, obligation.cause.span);
1543 {
match (&discriminant_def_id, &item_def_id) {
(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!(discriminant_def_id, item_def_id);
1544
1545 (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new())
1546 } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) {
1547 let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, obligation.cause.span);
1548 {
match (&metadata_def_id, &item_def_id) {
(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!(metadata_def_id, item_def_id);
1549
1550 let mut obligations = PredicateObligations::new();
1551 let normalize = |ty: ty::Unnormalized<'tcx, Ty<'tcx>>| {
1552 normalize_with_depth_to(
1553 selcx,
1554 obligation.param_env,
1555 obligation.cause.clone(),
1556 obligation.recursion_depth + 1,
1557 ty,
1558 &mut obligations,
1559 )
1560 };
1561 let metadata_ty = self_ty.ptr_metadata_ty_or_tail(tcx, normalize).unwrap_or_else(|tail| {
1562 if tail == self_ty {
1563 let sized_predicate = ty::TraitRef::new(
1568 tcx,
1569 tcx.require_lang_item(LangItem::Sized, obligation.cause.span),
1570 [self_ty],
1571 );
1572 obligations.push(obligation.with(tcx, sized_predicate));
1573 tcx.types.unit
1574 } else {
1575 Ty::new_projection(tcx, ty::IsRigid::No, metadata_def_id, [tail])
1578 }
1579 });
1580 (metadata_ty.into(), obligations)
1581 } else if tcx.is_lang_item(trait_def_id, LangItem::Field) {
1582 let ty::Adt(def, args) = self_ty.kind() else {
1583 ::rustc_middle::util::bug::bug_fmt(format_args!("only field representing types can implement `Field`"))bug!("only field representing types can implement `Field`")
1584 };
1585 let Some(FieldInfo { base, ty, .. }) = def.field_representing_type_info(tcx, args) else {
1586 ::rustc_middle::util::bug::bug_fmt(format_args!("only field representing types can implement `Field`"))bug!("only field representing types can implement `Field`")
1587 };
1588 if tcx.is_lang_item(item_def_id, LangItem::FieldBase) {
1589 (base.into(), PredicateObligations::new())
1590 } else if tcx.is_lang_item(item_def_id, LangItem::FieldType) {
1591 (ty.into(), PredicateObligations::new())
1592 } else {
1593 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected associated type {0:?} in `Field`",
obligation.predicate));bug!("unexpected associated type {:?} in `Field`", obligation.predicate);
1594 }
1595 } else {
1596 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected builtin trait with associated type: {0:?}",
obligation.predicate));bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
1597 };
1598
1599 let predicate = ty::ProjectionPredicate {
1600 projection_term: ty::AliasTerm::new_from_args(
1601 tcx,
1602 ty::AliasTermKind::ProjectionTy { def_id: item_def_id },
1603 args,
1604 ),
1605 term,
1606 };
1607
1608 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1609 .with_addl_obligations(obligations)
1610 .with_addl_obligations(data)
1611}
1612
1613fn confirm_fn_pointer_candidate<'cx, 'tcx>(
1614 selcx: &mut SelectionContext<'cx, 'tcx>,
1615 obligation: &ProjectionTermObligation<'tcx>,
1616 nested: PredicateObligations<'tcx>,
1617) -> Progress<'tcx> {
1618 let tcx = selcx.tcx();
1619 let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1620 let sig = fn_type.unnormalized_fn_sig(tcx);
1621 let Normalized { value: sig, obligations } = normalize_with_depth(
1622 selcx,
1623 obligation.param_env,
1624 obligation.cause.clone(),
1625 obligation.recursion_depth + 1,
1626 sig,
1627 );
1628
1629 confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
1630 .with_addl_obligations(nested)
1631 .with_addl_obligations(obligations)
1632}
1633
1634fn confirm_closure_candidate<'cx, 'tcx>(
1635 selcx: &mut SelectionContext<'cx, 'tcx>,
1636 obligation: &ProjectionTermObligation<'tcx>,
1637 nested: PredicateObligations<'tcx>,
1638) -> Progress<'tcx> {
1639 let tcx = selcx.tcx();
1640 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1641 let closure_sig = match *self_ty.kind() {
1642 ty::Closure(_, args) => Unnormalized::new_wip(args.as_closure().sig()),
1643
1644 ty::CoroutineClosure(def_id, args) => {
1648 let args = args.as_coroutine_closure();
1649 Unnormalized::new_wip(args.coroutine_closure_sig().map_bound(|sig| {
1650 let output_ty = coroutine_closure_output_coroutine(
1651 tcx,
1652 obligation,
1653 ty::ClosureKind::FnOnce,
1654 tcx.lifetimes.re_static,
1655 def_id,
1656 args,
1657 );
1658 tcx.mk_fn_sig([sig.tupled_inputs_ty], output_ty, sig.fn_sig_kind)
1659 }))
1660 }
1661
1662 _ => {
1663 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("expected closure self type for closure candidate, found {0}",
self_ty)));
};unreachable!("expected closure self type for closure candidate, found {self_ty}");
1664 }
1665 };
1666
1667 let Normalized { value: closure_sig, obligations } = normalize_with_depth(
1668 selcx,
1669 obligation.param_env,
1670 obligation.cause.clone(),
1671 obligation.recursion_depth + 1,
1672 closure_sig,
1673 );
1674
1675 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1675",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1675u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("closure_sig")
}> =
::tracing::__macro_support::FieldName::new("closure_sig");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligations")
}> =
::tracing::__macro_support::FieldName::new("obligations");
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!("confirm_closure_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_sig)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligations)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
1676
1677 confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
1678 .with_addl_obligations(nested)
1679 .with_addl_obligations(obligations)
1680}
1681
1682fn confirm_callable_candidate<'cx, 'tcx>(
1683 selcx: &mut SelectionContext<'cx, 'tcx>,
1684 obligation: &ProjectionTermObligation<'tcx>,
1685 fn_sig: ty::PolyFnSig<'tcx>,
1686 flag: util::TupleArgumentsFlag,
1687) -> Progress<'tcx> {
1688 let tcx = selcx.tcx();
1689
1690 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1690",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1690u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("fn_sig")
}> =
::tracing::__macro_support::FieldName::new("fn_sig");
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!("confirm_callable_candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_sig)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, ?fn_sig, "confirm_callable_candidate");
1691
1692 let fn_once_def_id = tcx.require_lang_item(LangItem::FnOnce, obligation.cause.span);
1693 let fn_once_output_def_id =
1694 tcx.require_lang_item(LangItem::FnOnceOutput, obligation.cause.span);
1695
1696 let predicate = super::util::closure_trait_ref_and_return_type(
1697 tcx,
1698 fn_once_def_id,
1699 obligation.predicate.self_ty(),
1700 fn_sig,
1701 flag,
1702 )
1703 .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
1704 projection_term: ty::AliasTerm::new_from_args(
1705 tcx,
1706 ty::AliasTermKind::ProjectionTy { def_id: fn_once_output_def_id },
1707 trait_ref.args,
1708 ),
1709 term: ret_type.into(),
1710 });
1711
1712 confirm_param_env_candidate(selcx, obligation, predicate, true)
1713}
1714
1715fn confirm_async_closure_candidate<'cx, 'tcx>(
1716 selcx: &mut SelectionContext<'cx, 'tcx>,
1717 obligation: &ProjectionTermObligation<'tcx>,
1718 nested: PredicateObligations<'tcx>,
1719) -> Progress<'tcx> {
1720 let tcx = selcx.tcx();
1721 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
1722
1723 let goal_kind =
1724 tcx.async_fn_trait_kind_from_def_id(obligation.predicate.trait_def_id(tcx)).unwrap();
1725 let env_region = match goal_kind {
1726 ty::ClosureKind::Fn | ty::ClosureKind::FnMut => obligation.predicate.args.region_at(2),
1727 ty::ClosureKind::FnOnce => tcx.lifetimes.re_static,
1728 };
1729 let item_name = tcx.item_name(obligation.predicate.expect_projection_def_id());
1730
1731 let poly_cache_entry = match *self_ty.kind() {
1732 ty::CoroutineClosure(def_id, args) => {
1733 let args = args.as_coroutine_closure();
1734 let sig = args.coroutine_closure_sig().skip_binder();
1735
1736 let term = match item_name {
1737 sym::CallOnceFuture | sym::CallRefFuture => coroutine_closure_output_coroutine(
1738 tcx, obligation, goal_kind, env_region, def_id, args,
1739 ),
1740 sym::Output => sig.return_ty,
1741 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1742 };
1743 let projection_term = match item_name {
1744 sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
1745 tcx,
1746 obligation.predicate.kind,
1747 [self_ty, sig.tupled_inputs_ty],
1748 ),
1749 sym::CallRefFuture => ty::AliasTerm::new(
1750 tcx,
1751 obligation.predicate.kind,
1752 [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()],
1753 ),
1754 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1755 };
1756
1757 args.coroutine_closure_sig()
1758 .rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
1759 }
1760 ty::FnDef(..) | ty::FnPtr(..) => {
1761 let bound_sig = self_ty.fn_sig(tcx);
1762 let sig = bound_sig.skip_binder();
1763
1764 let term = match item_name {
1765 sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
1766 sym::Output => {
1767 let future_output_def_id =
1768 tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span);
1769 Ty::new_projection(tcx, ty::IsRigid::No, future_output_def_id, [sig.output()])
1770 }
1771 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1772 };
1773 let projection_term = match item_name {
1774 sym::CallOnceFuture | sym::Output => ty::AliasTerm::new(
1775 tcx,
1776 obligation.predicate.kind,
1777 [self_ty, Ty::new_tup(tcx, sig.inputs())],
1778 ),
1779 sym::CallRefFuture => ty::AliasTerm::new(
1780 tcx,
1781 obligation.predicate.kind,
1782 [
1783 ty::GenericArg::from(self_ty),
1784 Ty::new_tup(tcx, sig.inputs()).into(),
1785 env_region.into(),
1786 ],
1787 ),
1788 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1789 };
1790
1791 bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
1792 }
1793 ty::Closure(_, args) => {
1794 let args = args.as_closure();
1795 let bound_sig = args.sig();
1796 let sig = bound_sig.skip_binder();
1797
1798 let term = match item_name {
1799 sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
1800 sym::Output => {
1801 let future_output_def_id =
1802 tcx.require_lang_item(LangItem::FutureOutput, obligation.cause.span);
1803 Ty::new_projection(tcx, ty::IsRigid::No, future_output_def_id, [sig.output()])
1804 }
1805 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1806 };
1807 let projection_term = match item_name {
1808 sym::CallOnceFuture | sym::Output => {
1809 ty::AliasTerm::new(tcx, obligation.predicate.kind, [self_ty, sig.inputs()[0]])
1810 }
1811 sym::CallRefFuture => ty::AliasTerm::new(
1812 tcx,
1813 obligation.predicate.kind,
1814 [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()],
1815 ),
1816 name => ::rustc_middle::util::bug::bug_fmt(format_args!("no such associated type: {0}",
name))bug!("no such associated type: {name}"),
1817 };
1818
1819 bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() })
1820 }
1821 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("expected callable type for AsyncFn candidate"))bug!("expected callable type for AsyncFn candidate"),
1822 };
1823
1824 confirm_param_env_candidate(selcx, obligation, poly_cache_entry, true)
1825 .with_addl_obligations(nested)
1826}
1827
1828fn coroutine_closure_output_coroutine<'tcx>(
1831 tcx: TyCtxt<'tcx>,
1832 obligation: &ProjectionTermObligation<'tcx>,
1833 goal_kind: ty::ClosureKind,
1834 env_region: ty::Region<'tcx>,
1835 def_id: DefId,
1836 args: ty::CoroutineClosureArgs<TyCtxt<'tcx>>,
1837) -> Ty<'tcx> {
1838 let kind_ty = args.kind_ty();
1839 let sig = args.coroutine_closure_sig().skip_binder();
1840
1841 if let Some(closure_kind) = kind_ty.to_opt_closure_kind()
1845 && !args.tupled_upvars_ty().is_ty_var()
1847 {
1848 if !closure_kind.extends(goal_kind) {
1849 ::rustc_middle::util::bug::bug_fmt(format_args!("we should not be confirming if the closure kind is not met"));bug!("we should not be confirming if the closure kind is not met");
1850 }
1851 sig.to_coroutine_given_kind_and_upvars(
1852 tcx,
1853 args.parent_args(),
1854 tcx.coroutine_for_closure(def_id),
1855 goal_kind,
1856 env_region,
1857 args.tupled_upvars_ty(),
1858 args.coroutine_captures_by_ref_ty(),
1859 )
1860 } else {
1861 let upvars_projection_def_id =
1862 tcx.require_lang_item(LangItem::AsyncFnKindUpvars, obligation.cause.span);
1863 let tupled_upvars_ty = Ty::new_projection(
1872 tcx,
1873 ty::IsRigid::No,
1874 upvars_projection_def_id,
1875 [
1876 ty::GenericArg::from(kind_ty),
1877 Ty::from_closure_kind(tcx, goal_kind).into(),
1878 env_region.into(),
1879 sig.tupled_inputs_ty.into(),
1880 args.tupled_upvars_ty().into(),
1881 args.coroutine_captures_by_ref_ty().into(),
1882 ],
1883 );
1884 sig.to_coroutine(
1885 tcx,
1886 args.parent_args(),
1887 Ty::from_closure_kind(tcx, goal_kind),
1888 tcx.coroutine_for_closure(def_id),
1889 tupled_upvars_ty,
1890 )
1891 }
1892}
1893
1894fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
1895 selcx: &mut SelectionContext<'cx, 'tcx>,
1896 obligation: &ProjectionTermObligation<'tcx>,
1897 nested: PredicateObligations<'tcx>,
1898) -> Progress<'tcx> {
1899 let [
1900 _closure_kind_ty,
1902 goal_kind_ty,
1903 borrow_region,
1904 tupled_inputs_ty,
1905 tupled_upvars_ty,
1906 coroutine_captures_by_ref_ty,
1907 ] = **obligation.predicate.args
1908 else {
1909 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"));bug!();
1910 };
1911
1912 let predicate = ty::ProjectionPredicate {
1913 projection_term: obligation.predicate.with_args(selcx.tcx(), obligation.predicate.args),
1914 term: ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind(
1915 selcx.tcx(),
1916 goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap(),
1917 tupled_inputs_ty.expect_ty(),
1918 tupled_upvars_ty.expect_ty(),
1919 coroutine_captures_by_ref_ty.expect_ty(),
1920 borrow_region.expect_region(),
1921 )
1922 .into(),
1923 };
1924
1925 confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
1926 .with_addl_obligations(nested)
1927}
1928
1929fn confirm_param_env_candidate<'cx, 'tcx>(
1931 selcx: &mut SelectionContext<'cx, 'tcx>,
1932 obligation: &ProjectionTermObligation<'tcx>,
1933 poly_cache_entry: ty::PolyProjectionPredicate<'tcx>,
1934 potentially_unnormalized_candidate: bool,
1935) -> Progress<'tcx> {
1936 let infcx = selcx.infcx;
1937 let cause = &obligation.cause;
1938 let param_env = obligation.param_env;
1939
1940 let cache_entry = infcx.instantiate_binder_with_fresh_vars(
1941 cause.span,
1942 BoundRegionConversionTime::HigherRankedType,
1943 poly_cache_entry,
1944 );
1945
1946 let mut cache_projection = cache_entry.projection_term;
1947 let mut nested_obligations = PredicateObligations::new();
1948 let obligation_projection = obligation.predicate;
1949 let obligation_projection = ensure_sufficient_stack(|| {
1950 normalize_with_depth_to(
1951 selcx,
1952 obligation.param_env,
1953 obligation.cause.clone(),
1954 obligation.recursion_depth + 1,
1955 ty::Unnormalized::new_wip(obligation_projection),
1956 &mut nested_obligations,
1957 )
1958 });
1959 if potentially_unnormalized_candidate {
1960 cache_projection = ensure_sufficient_stack(|| {
1961 normalize_with_depth_to(
1962 selcx,
1963 obligation.param_env,
1964 obligation.cause.clone(),
1965 obligation.recursion_depth + 1,
1966 ty::Unnormalized::new_wip(cache_projection),
1967 &mut nested_obligations,
1968 )
1969 });
1970 }
1971
1972 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1972",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1972u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("cache_projection")
}> =
::tracing::__macro_support::FieldName::new("cache_projection");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation_projection")
}> =
::tracing::__macro_support::FieldName::new("obligation_projection");
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(&cache_projection)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation_projection)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?cache_projection, ?obligation_projection);
1973
1974 match infcx.at(cause, param_env).eq(
1975 DefineOpaqueTypes::Yes,
1976 cache_projection,
1977 obligation_projection,
1978 ) {
1979 Ok(InferOk { value: _, obligations }) => {
1980 nested_obligations.extend(obligations);
1981 assoc_term_own_obligations(selcx, obligation, &mut nested_obligations);
1982 Progress {
1983 term: ty::Unnormalized::new(cache_entry.term),
1984 obligations: nested_obligations,
1985 }
1986 }
1987 Err(e) => {
1988 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Failed to unify obligation `{0:?}` with poly_projection `{1:?}`: {2:?}",
obligation, poly_cache_entry, e))
})format!(
1989 "Failed to unify obligation `{obligation:?}` with poly_projection `{poly_cache_entry:?}`: {e:?}",
1990 );
1991 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:1991",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(1991u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("confirm_param_env_candidate: {0}",
msg) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("confirm_param_env_candidate: {}", msg);
1992 let err = Ty::new_error_with_message(infcx.tcx, obligation.cause.span, msg);
1993 Progress {
1994 term: ty::Unnormalized::dummy(err.into()),
1995 obligations: PredicateObligations::new(),
1996 }
1997 }
1998 }
1999}
2000
2001fn confirm_impl_candidate<'cx, 'tcx>(
2003 selcx: &mut SelectionContext<'cx, 'tcx>,
2004 obligation: &ProjectionTermObligation<'tcx>,
2005 impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
2006) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
2007 let tcx = selcx.tcx();
2008
2009 let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
2010
2011 let assoc_item_id = obligation.predicate.expect_projection_def_id();
2012 let trait_def_id = tcx.impl_trait_id(impl_def_id);
2013
2014 let param_env = obligation.param_env;
2015 let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
2016 Ok(assoc_term) => assoc_term,
2017 Err(guar) => {
2018 return Ok(Projected::Progress(Progress::error_for_term(
2019 tcx,
2020 obligation.predicate,
2021 guar,
2022 )));
2023 }
2024 };
2025
2026 if !assoc_term.item.defaultness(tcx).has_value() {
2032 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/project.rs:2032",
"rustc_trait_selection::traits::project",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/project.rs"),
::tracing_core::__macro_support::Option::Some(2032u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::project"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("confirm_impl_candidate: no associated type {0:?} for {1:?}",
assoc_term.item.name(), obligation.predicate) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
2033 "confirm_impl_candidate: no associated type {:?} for {:?}",
2034 assoc_term.item.name(),
2035 obligation.predicate
2036 );
2037 if tcx.impl_self_is_guaranteed_unsized(impl_def_id) {
2038 return Ok(Projected::NoProgress(obligation.predicate.to_term(tcx, ty::IsRigid::No)));
2043 } else {
2044 return Ok(Projected::Progress(Progress {
2045 term: ty::Unnormalized::dummy(if obligation.predicate.kind.is_type() {
2046 Ty::new_misc_error(tcx).into()
2047 } else {
2048 ty::Const::new_misc_error(tcx).into()
2049 }),
2050 obligations: nested,
2051 }));
2052 }
2053 }
2054
2055 let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args);
2062 let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_term.defining_node);
2063
2064 let term = if obligation.predicate.kind.is_type() {
2065 tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into())
2066 } else {
2067 tcx.const_of_item(assoc_term.item.def_id).map_bound(|ct| ct.into())
2068 };
2069
2070 let progress = if !tcx.check_args_compatible(assoc_term.item.def_id, args) {
2071 let msg = "impl item and trait item have different parameters";
2072 let span = obligation.cause.span;
2073 let err = if obligation.predicate.kind.is_type() {
2074 Ty::new_error_with_message(tcx, span, msg).into()
2075 } else {
2076 ty::Const::new_error_with_message(tcx, span, msg).into()
2077 };
2078 Progress { term: ty::Unnormalized::dummy(err), obligations: nested }
2079 } else {
2080 assoc_term_own_obligations(selcx, obligation, &mut nested);
2081 let instantiated_term = term.instantiate(tcx, args);
2082 let term_for_obligation = instantiated_term.skip_norm_wip();
2083 push_const_arg_has_type_obligation(
2084 tcx,
2085 &mut nested,
2086 &obligation.cause,
2087 obligation.recursion_depth + 1,
2088 obligation.param_env,
2089 term_for_obligation,
2090 assoc_term.item.def_id,
2091 args,
2092 );
2093 Progress { term: instantiated_term, obligations: nested }
2094 };
2095 Ok(Projected::Progress(progress))
2096}
2097
2098fn assoc_term_own_obligations<'cx, 'tcx>(
2105 selcx: &mut SelectionContext<'cx, 'tcx>,
2106 obligation: &ProjectionTermObligation<'tcx>,
2107 nested: &mut PredicateObligations<'tcx>,
2108) {
2109 let tcx = selcx.tcx();
2110 let def_id = obligation.predicate.expect_projection_def_id();
2111 let clauses = tcx.clauses_of(def_id).instantiate_own(tcx, obligation.predicate.args);
2112 for (clause, span) in clauses {
2113 let normalized = normalize_with_depth_to(
2114 selcx,
2115 obligation.param_env,
2116 obligation.cause.clone(),
2117 obligation.recursion_depth + 1,
2118 clause,
2119 nested,
2120 );
2121
2122 let nested_cause = if #[allow(non_exhaustive_omitted_patterns)] match obligation.cause.code() {
ObligationCauseCode::CompareImplItem { .. } |
ObligationCauseCode::CheckAssociatedTypeBounds { .. } |
ObligationCauseCode::AscribeUserTypeProvePredicate(..) => true,
_ => false,
}matches!(
2123 obligation.cause.code(),
2124 ObligationCauseCode::CompareImplItem { .. }
2125 | ObligationCauseCode::CheckAssociatedTypeBounds { .. }
2126 | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
2127 ) {
2128 obligation.cause.clone()
2129 } else {
2130 ObligationCause::new(
2131 obligation.cause.span,
2132 obligation.cause.body_def_id,
2133 ObligationCauseCode::WhereClause(def_id, span),
2134 )
2135 };
2136 nested.push(Obligation::with_depth(
2137 tcx,
2138 nested_cause,
2139 obligation.recursion_depth + 1,
2140 obligation.param_env,
2141 normalized,
2142 ));
2143 }
2144}
2145
2146pub(crate) trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
2147 fn from_poly_projection_obligation(
2148 selcx: &mut SelectionContext<'cx, 'tcx>,
2149 obligation: &PolyProjectionObligation<'tcx>,
2150 ) -> Option<Self>;
2151}
2152
2153impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> {
2154 fn from_poly_projection_obligation(
2155 selcx: &mut SelectionContext<'cx, 'tcx>,
2156 obligation: &PolyProjectionObligation<'tcx>,
2157 ) -> Option<Self> {
2158 let infcx = selcx.infcx;
2159 obligation.predicate.no_bound_vars().map(|predicate| {
2162 ProjectionCacheKey::new(
2163 infcx.resolve_vars_if_possible(predicate.projection_term),
2168 obligation.param_env,
2169 )
2170 })
2171 }
2172}