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