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