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