1use rustc_data_structures::sso::SsoHashMap;
6use rustc_data_structures::stack::ensure_sufficient_stack;
7use rustc_hir::def::DefKind;
8use rustc_infer::traits::PredicateObligations;
9use rustc_macros::extension;
10pub use rustc_middle::traits::query::NormalizationResult;
11use rustc_middle::ty::{
12 self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
13 TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
14};
15use rustc_span::DUMMY_SP;
16use tracing::{debug, info, instrument};
17
18use super::NoSolution;
19use crate::error_reporting::InferCtxtErrorExt;
20use crate::error_reporting::traits::OverflowCause;
21use crate::infer::at::At;
22use crate::infer::canonical::OriginalQueryValues;
23use crate::infer::{InferCtxt, InferOk};
24use crate::traits::normalize::needs_normalization;
25use crate::traits::{
26 BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError,
27};
28
29impl<'a, 'tcx> QueryNormalizeExt<'tcx> for At<'a, 'tcx> {
#[doc = " Normalize `value` in the context of the inference context,"]
#[doc = " yielding a resulting type, or an error if `value` cannot be"]
#[doc =
" normalized. If you don\'t care about regions, you should prefer"]
#[doc = " `normalize_erasing_regions`, which is more efficient."]
#[doc = ""]
#[doc = " If the normalization succeeds, returns back the normalized"]
#[doc = " value along with various outlives relations (in the form of"]
#[doc = " obligations that must be discharged)."]
#[doc = ""]
#[doc =
" This normalization should *only* be used when the projection is well-formed and"]
#[doc =
" does not have possible ambiguity (contains inference variables)."]
#[doc = ""]
#[doc =
" After codegen, when lifetimes do not matter, it is preferable to instead"]
#[doc =
" use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure."]
#[doc = ""]
#[doc =
" N.B. Once the new solver is stabilized this method of normalization will"]
#[doc =
" likely be removed as trait solver operations are already cached by the query"]
#[doc = " system making this redundant."]
fn query_normalize<T>(self, value: T)
-> Result<Normalized<'tcx, T>, NoSolution> where
T: TypeFoldable<TyCtxt<'tcx>> {
{
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/query/normalize.rs:53",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(53u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("normalize::<{0}>(value={1:?}, param_env={2:?}, cause={3:?})",
std::any::type_name::<T>(), value, self.param_env,
self.cause) as &dyn Value))])
});
} else { ; }
};
let universes =
if value.has_escaping_bound_vars() {
let mut max_visitor =
MaxEscapingBoundVarVisitor {
outer_index: ty::INNERMOST,
escaping: 0,
};
value.visit_with(&mut max_visitor);
::alloc::vec::from_elem(None, max_visitor.escaping)
} else { ::alloc::vec::Vec::new() };
if self.infcx.next_trait_solver() {
match crate::solve::deeply_normalize_with_skipped_universes::<_,
ScrubbedTraitError<'tcx>>(self, value, universes) {
Ok(value) => {
return Ok(Normalized {
value,
obligations: PredicateObligations::new(),
});
}
Err(_errors) => { return Err(NoSolution); }
}
}
if !needs_normalization(self.infcx, &value) {
return Ok(Normalized {
value,
obligations: PredicateObligations::new(),
});
}
let mut normalizer =
QueryNormalizer {
infcx: self.infcx,
cause: self.cause,
param_env: self.param_env,
obligations: PredicateObligations::new(),
cache: SsoHashMap::new(),
anon_depth: 0,
universes,
};
let result = value.try_fold_with(&mut normalizer);
{
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/query/normalize.rs:108",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::INFO,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(108u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::INFO <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::INFO <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("normalize::<{0}>: result={1:?} with {2} obligations",
std::any::type_name::<T>(), result,
normalizer.obligations.len()) as &dyn Value))])
});
} else { ; }
};
{
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/query/normalize.rs:114",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(114u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("normalize::<{0}>: obligations={1:?}",
std::any::type_name::<T>(), normalizer.obligations) as
&dyn Value))])
});
} else { ; }
};
result.map(|value|
Normalized { value, obligations: normalizer.obligations })
}
}#[extension(pub trait QueryNormalizeExt<'tcx>)]
30impl<'a, 'tcx> At<'a, 'tcx> {
31 fn query_normalize<T>(self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
50 where
51 T: TypeFoldable<TyCtxt<'tcx>>,
52 {
53 debug!(
54 "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})",
55 std::any::type_name::<T>(),
56 value,
57 self.param_env,
58 self.cause,
59 );
60
61 let universes = if value.has_escaping_bound_vars() {
72 let mut max_visitor =
73 MaxEscapingBoundVarVisitor { outer_index: ty::INNERMOST, escaping: 0 };
74 value.visit_with(&mut max_visitor);
75 vec![None; max_visitor.escaping]
76 } else {
77 vec![]
78 };
79
80 if self.infcx.next_trait_solver() {
81 match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>(
82 self, value, universes,
83 ) {
84 Ok(value) => {
85 return Ok(Normalized { value, obligations: PredicateObligations::new() });
86 }
87 Err(_errors) => {
88 return Err(NoSolution);
89 }
90 }
91 }
92
93 if !needs_normalization(self.infcx, &value) {
94 return Ok(Normalized { value, obligations: PredicateObligations::new() });
95 }
96
97 let mut normalizer = QueryNormalizer {
98 infcx: self.infcx,
99 cause: self.cause,
100 param_env: self.param_env,
101 obligations: PredicateObligations::new(),
102 cache: SsoHashMap::new(),
103 anon_depth: 0,
104 universes,
105 };
106
107 let result = value.try_fold_with(&mut normalizer);
108 info!(
109 "normalize::<{}>: result={:?} with {} obligations",
110 std::any::type_name::<T>(),
111 result,
112 normalizer.obligations.len(),
113 );
114 debug!(
115 "normalize::<{}>: obligations={:?}",
116 std::any::type_name::<T>(),
117 normalizer.obligations,
118 );
119 result.map(|value| Normalized { value, obligations: normalizer.obligations })
120 }
121}
122
123struct MaxEscapingBoundVarVisitor {
125 outer_index: ty::DebruijnIndex,
127 escaping: usize,
128}
129
130impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
131 fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
132 self.outer_index.shift_in(1);
133 t.super_visit_with(self);
134 self.outer_index.shift_out(1);
135 }
136
137 #[inline]
138 fn visit_ty(&mut self, t: Ty<'tcx>) {
139 if t.outer_exclusive_binder() > self.outer_index {
140 self.escaping = self
141 .escaping
142 .max(t.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
143 }
144 }
145
146 #[inline]
147 fn visit_region(&mut self, r: ty::Region<'tcx>) {
148 match r.kind() {
149 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
150 if debruijn > self.outer_index =>
151 {
152 self.escaping =
153 self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
154 }
155 _ => {}
156 }
157 }
158
159 fn visit_const(&mut self, ct: ty::Const<'tcx>) {
160 if ct.outer_exclusive_binder() > self.outer_index {
161 self.escaping = self
162 .escaping
163 .max(ct.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
164 }
165 }
166}
167
168struct QueryNormalizer<'a, 'tcx> {
169 infcx: &'a InferCtxt<'tcx>,
170 cause: &'a ObligationCause<'tcx>,
171 param_env: ty::ParamEnv<'tcx>,
172 obligations: PredicateObligations<'tcx>,
173 cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
174 anon_depth: usize,
175 universes: Vec<Option<ty::UniverseIndex>>,
176}
177
178impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
179 type Error = NoSolution;
180
181 fn cx(&self) -> TyCtxt<'tcx> {
182 self.infcx.tcx
183 }
184
185 fn try_fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
186 &mut self,
187 t: ty::Binder<'tcx, T>,
188 ) -> Result<ty::Binder<'tcx, T>, Self::Error> {
189 self.universes.push(None);
190 let t = t.try_super_fold_with(self);
191 self.universes.pop();
192 t
193 }
194
195 #[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("try_fold_ty",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(195u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["ty"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<Ty<'tcx>, Self::Error> =
loop {};
return __tracing_attr_fake_return;
}
{
if !needs_normalization(self.infcx, &ty) { return Ok(ty); }
if let Some(ty) = self.cache.get(&ty) { return Ok(*ty); }
let (kind, data) =
match *ty.kind() {
ty::Alias(kind, data) => (kind, data),
_ => {
let res = ty.try_super_fold_with(self)?;
self.cache.insert(ty, res);
return Ok(res);
}
};
let res =
match kind {
ty::Opaque => {
match self.infcx.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { .. } |
TypingMode::Borrowck { .. } |
TypingMode::PostBorrowckAnalysis { .. } =>
ty.try_super_fold_with(self)?,
TypingMode::PostAnalysis => {
let args = data.args.try_fold_with(self)?;
let recursion_limit = self.cx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {
let guar =
self.infcx.err_ctxt().build_overflow_error(OverflowCause::DeeplyNormalize(data.into()),
self.cause.span, true).delay_as_bug();
return Ok(Ty::new_error(self.cx(), guar));
}
let generic_ty = self.cx().type_of(data.def_id);
let mut concrete_ty =
generic_ty.instantiate(self.cx(), args);
self.anon_depth += 1;
if concrete_ty == ty {
concrete_ty =
Ty::new_error_with_message(self.cx(), DUMMY_SP,
"recursive opaque type");
}
let folded_ty =
ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
self.anon_depth -= 1;
folded_ty?
}
}
}
ty::Projection | ty::Inherent | ty::Free =>
self.try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(),
data.def_id, data.args))?.expect_type(),
};
self.cache.insert(ty, res);
Ok(res)
}
}
}#[instrument(level = "debug", skip(self))]
196 fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
197 if !needs_normalization(self.infcx, &ty) {
198 return Ok(ty);
199 }
200
201 if let Some(ty) = self.cache.get(&ty) {
202 return Ok(*ty);
203 }
204
205 let (kind, data) = match *ty.kind() {
206 ty::Alias(kind, data) => (kind, data),
207 _ => {
208 let res = ty.try_super_fold_with(self)?;
209 self.cache.insert(ty, res);
210 return Ok(res);
211 }
212 };
213
214 let res = match kind {
217 ty::Opaque => {
218 match self.infcx.typing_mode() {
220 TypingMode::Coherence
221 | TypingMode::Analysis { .. }
222 | TypingMode::Borrowck { .. }
223 | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?,
224
225 TypingMode::PostAnalysis => {
226 let args = data.args.try_fold_with(self)?;
227 let recursion_limit = self.cx().recursion_limit();
228
229 if !recursion_limit.value_within_limit(self.anon_depth) {
230 let guar = self
231 .infcx
232 .err_ctxt()
233 .build_overflow_error(
234 OverflowCause::DeeplyNormalize(data.into()),
235 self.cause.span,
236 true,
237 )
238 .delay_as_bug();
239 return Ok(Ty::new_error(self.cx(), guar));
240 }
241
242 let generic_ty = self.cx().type_of(data.def_id);
243 let mut concrete_ty = generic_ty.instantiate(self.cx(), args);
244 self.anon_depth += 1;
245 if concrete_ty == ty {
246 concrete_ty = Ty::new_error_with_message(
247 self.cx(),
248 DUMMY_SP,
249 "recursive opaque type",
250 );
251 }
252 let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
253 self.anon_depth -= 1;
254 folded_ty?
255 }
256 }
257 }
258
259 ty::Projection | ty::Inherent | ty::Free => self
260 .try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), data.def_id, data.args))?
261 .expect_type(),
262 };
263
264 self.cache.insert(ty, res);
265 Ok(res)
266 }
267
268 fn try_fold_const(
269 &mut self,
270 constant: ty::Const<'tcx>,
271 ) -> Result<ty::Const<'tcx>, Self::Error> {
272 if !needs_normalization(self.infcx, &constant) {
273 return Ok(constant);
274 }
275
276 let uv = match constant.kind() {
277 ty::ConstKind::Unevaluated(uv) => uv,
278 _ => return constant.try_super_fold_with(self),
279 };
280
281 let constant = match self.cx().def_kind(uv.def) {
282 DefKind::AnonConst => crate::traits::with_replaced_escaping_bound_vars(
283 self.infcx,
284 &mut self.universes,
285 constant,
286 |constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env),
287 ),
288 _ => self
289 .try_fold_free_or_assoc(ty::AliasTerm::new(self.cx(), uv.def, uv.args))?
290 .expect_const(),
291 };
292 {
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/query/normalize.rs:292",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(292u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["constant",
"self.param_env"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&constant)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&self.param_env)
as &dyn Value))])
});
} else { ; }
};debug!(?constant, ?self.param_env);
293 constant.try_super_fold_with(self)
294 }
295
296 #[inline]
297 fn try_fold_predicate(
298 &mut self,
299 p: ty::Predicate<'tcx>,
300 ) -> Result<ty::Predicate<'tcx>, Self::Error> {
301 if p.allow_normalization() && needs_normalization(self.infcx, &p) {
302 p.try_super_fold_with(self)
303 } else {
304 Ok(p)
305 }
306 }
307}
308
309impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> {
310 fn try_fold_free_or_assoc(
311 &mut self,
312 term: ty::AliasTerm<'tcx>,
313 ) -> Result<ty::Term<'tcx>, NoSolution> {
314 let infcx = self.infcx;
315 let tcx = infcx.tcx;
316 let (term, maps) = if term.has_escaping_bound_vars() {
319 let (term, mapped_regions, mapped_types, mapped_consts) =
320 BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, term);
321 (term, Some((mapped_regions, mapped_types, mapped_consts)))
322 } else {
323 (term, None)
324 };
325 let term = term.try_fold_with(self)?;
326
327 let mut orig_values = OriginalQueryValues::default();
328 let c_term = infcx.canonicalize_query(self.param_env.and(term), &mut orig_values);
329 {
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/query/normalize.rs:329",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(329u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("QueryNormalizer: c_term = {0:#?}",
c_term) as &dyn Value))])
});
} else { ; }
};debug!("QueryNormalizer: c_term = {:#?}", c_term);
330 {
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/query/normalize.rs:330",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(330u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("QueryNormalizer: orig_values = {0:#?}",
orig_values) as &dyn Value))])
});
} else { ; }
};debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
331 let result = match term.kind(tcx) {
332 ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
333 tcx.normalize_canonicalized_projection(c_term)
334 }
335 ty::AliasTermKind::FreeTy | ty::AliasTermKind::FreeConst => {
336 tcx.normalize_canonicalized_free_alias(c_term)
337 }
338 ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => {
339 tcx.normalize_canonicalized_inherent_projection(c_term)
340 }
341 kind @ (ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::UnevaluatedConst) => {
342 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("did not expect {0:?} due to match arm above",
kind)));
}unreachable!("did not expect {kind:?} due to match arm above")
343 }
344 }?;
345 if !result.value.is_proven() {
347 if !tcx.sess.opts.actually_rustdoc {
350 tcx.dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unexpected ambiguity: {0:?} {1:?}",
c_term, result))
})format!("unexpected ambiguity: {c_term:?} {result:?}"));
351 }
352 return Err(NoSolution);
353 }
354 let InferOk { value: result, obligations } = infcx
355 .instantiate_query_response_and_region_obligations(
356 self.cause,
357 self.param_env,
358 &orig_values,
359 result,
360 )?;
361 {
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/query/normalize.rs:361",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(361u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("QueryNormalizer: result = {0:#?}",
result) as &dyn Value))])
});
} else { ; }
};debug!("QueryNormalizer: result = {:#?}", result);
362 {
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/query/normalize.rs:362",
"rustc_trait_selection::traits::query::normalize",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/normalize.rs"),
::tracing_core::__macro_support::Option::Some(362u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::normalize"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("QueryNormalizer: obligations = {0:#?}",
obligations) as &dyn Value))])
});
} else { ; }
};debug!("QueryNormalizer: obligations = {:#?}", obligations);
363 self.obligations.extend(obligations);
364 let res = if let Some((mapped_regions, mapped_types, mapped_consts)) = maps {
365 PlaceholderReplacer::replace_placeholders(
366 infcx,
367 mapped_regions,
368 mapped_types,
369 mapped_consts,
370 &self.universes,
371 result.normalized_term,
372 )
373 } else {
374 result.normalized_term
375 };
376 if res != term.to_term(tcx)
381 && (res.as_type().map_or(false, |t| t.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION))
382 || term.kind(tcx) == ty::AliasTermKind::FreeTy)
383 {
384 res.try_fold_with(self)
385 } else {
386 Ok(res)
387 }
388 }
389}