1use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
2use rustc_type_ir::inherent::*;
3use rustc_type_ir::solve::{Goal, QueryInput};
4use rustc_type_ir::{
5 self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalVarKind, Flags, InferCtxtLike,
6 Interner, PlaceholderConst, PlaceholderType, Region, TypeFlags, TypeFoldable, TypeFolder,
7 TypeSuperFoldable, TypeVisitableExt,
8};
9
10use crate::delegate::SolverDelegate;
11
12const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits(
14 TypeFlags::HAS_INFER.bits()
15 | TypeFlags::HAS_PLACEHOLDER.bits()
16 | TypeFlags::HAS_PARAM.bits()
17 | TypeFlags::HAS_FREE_REGIONS.bits()
18 | TypeFlags::HAS_RE_ERASED.bits(),
19)
20.unwrap();
21
22#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CanonicalizeInputKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CanonicalizeInputKind::ParamEnv => "ParamEnv",
CanonicalizeInputKind::Predicate => "Predicate",
})
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CanonicalizeInputKind {
#[inline]
fn clone(&self) -> CanonicalizeInputKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CanonicalizeInputKind { }Copy)]
23enum CanonicalizeInputKind {
24 ParamEnv,
28 Predicate,
30}
31
32#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CanonicalizeMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
CanonicalizeMode::Input(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Input",
&__self_0),
CanonicalizeMode::Response { max_input_universe: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Response", "max_input_universe", &__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CanonicalizeMode {
#[inline]
fn clone(&self) -> CanonicalizeMode {
let _: ::core::clone::AssertParamIsClone<CanonicalizeInputKind>;
let _: ::core::clone::AssertParamIsClone<ty::UniverseIndex>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CanonicalizeMode { }Copy)]
38enum CanonicalizeMode {
39 Input(CanonicalizeInputKind),
40 Response {
48 max_input_universe: ty::UniverseIndex,
58 },
59}
60
61pub(super) struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
62 delegate: &'a D,
63
64 canonicalize_mode: CanonicalizeMode,
66
67 variables: Vec<I::GenericArg>,
69 var_kinds: Vec<CanonicalVarKind<I>>,
70 variable_lookup_table: HashMap<I::GenericArg, usize>,
71 sub_root_lookup_table: HashMap<ty::TyVid, usize>,
78
79 cache: HashMap<I::Ty, I::Ty>,
82}
83
84impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
85 pub(super) fn canonicalize_response<T: TypeFoldable<I>>(
86 delegate: &'a D,
87 max_input_universe: ty::UniverseIndex,
88 value: T,
89 ) -> ty::Canonical<I, T> {
90 let mut canonicalizer = Canonicalizer {
91 delegate,
92 canonicalize_mode: CanonicalizeMode::Response { max_input_universe },
93
94 variables: Vec::new(),
95 variable_lookup_table: Default::default(),
96 sub_root_lookup_table: Default::default(),
97 var_kinds: Vec::new(),
98
99 cache: Default::default(),
100 };
101
102 let value = if value.has_type_flags(NEEDS_CANONICAL) {
103 value.fold_with(&mut canonicalizer)
104 } else {
105 value
106 };
107 if true {
if !!value.has_infer() {
{
::core::panicking::panic_fmt(format_args!("unexpected infer in {0:?}",
value));
}
};
};debug_assert!(!value.has_infer(), "unexpected infer in {value:?}");
108 if true {
if !!value.has_placeholders() {
{
::core::panicking::panic_fmt(format_args!("unexpected placeholders in {0:?}",
value));
}
};
};debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
109 let (max_universe, _variables, var_kinds) = canonicalizer.finalize();
110 Canonical { max_universe, var_kinds, value }
111 }
112
113 fn canonicalize_param_env(
114 delegate: &'a D,
115 param_env: I::ParamEnv,
116 ) -> (I::ParamEnv, Vec<I::GenericArg>, Vec<CanonicalVarKind<I>>, HashMap<I::GenericArg, usize>)
117 {
118 if !param_env.has_type_flags(NEEDS_CANONICAL) {
119 return (param_env, Vec::new(), Vec::new(), Default::default());
120 }
121
122 if !param_env.has_non_region_infer() {
130 delegate.cx().canonical_param_env_cache_get_or_insert(
131 param_env,
132 || {
133 let mut env_canonicalizer = Canonicalizer {
134 delegate,
135 canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv),
136
137 variables: Vec::new(),
138 variable_lookup_table: Default::default(),
139 sub_root_lookup_table: Default::default(),
140 var_kinds: Vec::new(),
141
142 cache: Default::default(),
143 };
144 let param_env = param_env.fold_with(&mut env_canonicalizer);
145 if true {
if !env_canonicalizer.sub_root_lookup_table.is_empty() {
::core::panicking::panic("assertion failed: env_canonicalizer.sub_root_lookup_table.is_empty()")
};
};debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
146 CanonicalParamEnvCacheEntry {
147 param_env,
148 variable_lookup_table: env_canonicalizer.variable_lookup_table,
149 var_kinds: env_canonicalizer.var_kinds,
150 variables: env_canonicalizer.variables,
151 }
152 },
153 |&CanonicalParamEnvCacheEntry {
154 param_env,
155 variables: ref cache_variables,
156 ref variable_lookup_table,
157 ref var_kinds,
158 }| {
159 let mut variables = Vec::new();
163 variables.extend(cache_variables.iter().copied());
164 (param_env, variables, var_kinds.clone(), variable_lookup_table.clone())
165 },
166 )
167 } else {
168 let mut env_canonicalizer = Canonicalizer {
169 delegate,
170 canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv),
171
172 variables: Vec::new(),
173 variable_lookup_table: Default::default(),
174 sub_root_lookup_table: Default::default(),
175 var_kinds: Vec::new(),
176
177 cache: Default::default(),
178 };
179 let param_env = param_env.fold_with(&mut env_canonicalizer);
180 if true {
if !env_canonicalizer.sub_root_lookup_table.is_empty() {
::core::panicking::panic("assertion failed: env_canonicalizer.sub_root_lookup_table.is_empty()")
};
};debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
181 (
182 param_env,
183 env_canonicalizer.variables,
184 env_canonicalizer.var_kinds,
185 env_canonicalizer.variable_lookup_table,
186 )
187 }
188 }
189
190 pub(super) fn canonicalize_input<P: TypeFoldable<I>>(
199 delegate: &'a D,
200 input: QueryInput<I, P>,
201 ) -> (Vec<I::GenericArg>, ty::Canonical<I, QueryInput<I, P>>) {
202 let (param_env, variables, var_kinds, variable_lookup_table) =
204 Canonicalizer::canonicalize_param_env(delegate, input.goal.param_env);
205 let mut rest_canonicalizer = Canonicalizer {
208 delegate,
209 canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::Predicate),
210
211 variables,
212 variable_lookup_table,
213 sub_root_lookup_table: Default::default(),
214 var_kinds,
215
216 cache: Default::default(),
222 };
223
224 let predicate = input.goal.predicate;
225 let predicate = predicate.fold_with(&mut rest_canonicalizer);
226 let goal = Goal { param_env, predicate };
227
228 let predefined_opaques_in_body = input.predefined_opaques_in_body;
229 let predefined_opaques_in_body =
230 if predefined_opaques_in_body.has_type_flags(NEEDS_CANONICAL) {
231 predefined_opaques_in_body.fold_with(&mut rest_canonicalizer)
232 } else {
233 predefined_opaques_in_body
234 };
235
236 let value = QueryInput { goal, predefined_opaques_in_body };
237
238 if true {
if !!value.has_infer() {
{
::core::panicking::panic_fmt(format_args!("unexpected infer in {0:?}",
value));
}
};
};debug_assert!(!value.has_infer(), "unexpected infer in {value:?}");
239 if true {
if !!value.has_placeholders() {
{
::core::panicking::panic_fmt(format_args!("unexpected placeholders in {0:?}",
value));
}
};
};debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
240 let (max_universe, variables, var_kinds) = rest_canonicalizer.finalize();
241 (variables, Canonical { max_universe, var_kinds, value })
242 }
243
244 fn get_or_insert_bound_var(
245 &mut self,
246 arg: impl Into<I::GenericArg>,
247 kind: CanonicalVarKind<I>,
248 ) -> ty::BoundVar {
249 let arg = arg.into();
253 let idx = if self.variables.len() > 16 {
254 if self.variable_lookup_table.is_empty() {
255 self.variable_lookup_table.extend(self.variables.iter().copied().zip(0..));
256 }
257
258 *self.variable_lookup_table.entry(arg).or_insert_with(|| {
259 let var = self.variables.len();
260 self.variables.push(arg);
261 self.var_kinds.push(kind);
262 var
263 })
264 } else {
265 self.variables.iter().position(|&v| v == arg).unwrap_or_else(|| {
266 let var = self.variables.len();
267 self.variables.push(arg);
268 self.var_kinds.push(kind);
269 var
270 })
271 };
272
273 ty::BoundVar::from(idx)
274 }
275
276 fn get_or_insert_sub_root(&mut self, vid: ty::TyVid) -> ty::BoundVar {
277 let root_vid = self.delegate.sub_unification_table_root_var(vid);
278 let idx =
279 *self.sub_root_lookup_table.entry(root_vid).or_insert_with(|| self.variables.len());
280 ty::BoundVar::from(idx)
281 }
282
283 fn finalize(self) -> (ty::UniverseIndex, Vec<I::GenericArg>, I::CanonicalVarKinds) {
284 let mut var_kinds = self.var_kinds;
285 let max_universe = match self.canonicalize_mode {
288 CanonicalizeMode::Input { .. } => {
290 if true {
if !var_kinds.iter().all(|var| var.universe() == ty::UniverseIndex::ROOT)
{
{
::core::panicking::panic_fmt(format_args!("expected all vars to be canonicalized in root universe: {0:#?}",
var_kinds));
}
};
};debug_assert!(
291 var_kinds.iter().all(|var| var.universe() == ty::UniverseIndex::ROOT),
292 "expected all vars to be canonicalized in root universe: {var_kinds:#?}"
293 );
294 ty::UniverseIndex::ROOT
295 }
296 CanonicalizeMode::Response { max_input_universe } => {
301 for var in var_kinds.iter_mut() {
302 let uv = var.universe();
303 let new_uv = ty::UniverseIndex::from(
304 uv.index().saturating_sub(max_input_universe.index()),
305 );
306 *var = var.with_updated_universe(new_uv);
307 }
308 var_kinds
309 .iter()
310 .map(|kind| kind.universe())
311 .max()
312 .unwrap_or(ty::UniverseIndex::ROOT)
313 }
314 };
315 let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds);
316 (max_universe, self.variables, var_kinds)
317 }
318
319 fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty {
320 let kind = match t.kind() {
321 ty::Infer(i) => match i {
322 ty::TyVar(vid) => {
323 if true {
{
match (&self.delegate.opportunistic_resolve_ty_var(vid), &t) {
(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::Some(format_args!("ty vid should have been resolved fully before canonicalization")));
}
}
}
};
};debug_assert_eq!(
324 self.delegate.opportunistic_resolve_ty_var(vid),
325 t,
326 "ty vid should have been resolved fully before canonicalization"
327 );
328
329 let sub_root = self.get_or_insert_sub_root(vid);
330 let ui = match self.canonicalize_mode {
331 CanonicalizeMode::Input { .. } => ty::UniverseIndex::ROOT,
332 CanonicalizeMode::Response { .. } => self
333 .delegate
334 .universe_of_ty(vid)
335 .unwrap_or_else(|| {
::core::panicking::panic_fmt(format_args!("ty var should have been resolved: {0:?}",
t));
}panic!("ty var should have been resolved: {t:?}")),
336 };
337 CanonicalVarKind::Ty { ui, sub_root }
338 }
339 ty::IntVar(vid) => {
340 if true {
{
match (&self.delegate.opportunistic_resolve_int_var(vid), &t) {
(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::Some(format_args!("ty vid should have been resolved fully before canonicalization")));
}
}
}
};
};debug_assert_eq!(
341 self.delegate.opportunistic_resolve_int_var(vid),
342 t,
343 "ty vid should have been resolved fully before canonicalization"
344 );
345 CanonicalVarKind::Int
346 }
347 ty::FloatVar(vid) => {
348 if true {
{
match (&self.delegate.opportunistic_resolve_float_var(vid), &t) {
(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::Some(format_args!("ty vid should have been resolved fully before canonicalization")));
}
}
}
};
};debug_assert_eq!(
349 self.delegate.opportunistic_resolve_float_var(vid),
350 t,
351 "ty vid should have been resolved fully before canonicalization"
352 );
353 CanonicalVarKind::Float
354 }
355 ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
356 {
::core::panicking::panic_fmt(format_args!("fresh vars not expected in canonicalization"));
}panic!("fresh vars not expected in canonicalization")
357 }
358 },
359 ty::Placeholder(placeholder) => match self.canonicalize_mode {
360 CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy(
361 PlaceholderType::new_anon(ty::UniverseIndex::ROOT, self.variables.len().into()),
362 ),
363 CanonicalizeMode::Response { .. } => CanonicalVarKind::PlaceholderTy(placeholder),
364 },
365 ty::Param(_) => match self.canonicalize_mode {
366 CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy(
367 PlaceholderType::new_anon(ty::UniverseIndex::ROOT, self.variables.len().into()),
368 ),
369 CanonicalizeMode::Response { .. } => {
::core::panicking::panic_fmt(format_args!("param ty in response: {0:?}",
t));
}panic!("param ty in response: {t:?}"),
370 },
371 ty::Bool
372 | ty::Char
373 | ty::Int(_)
374 | ty::Uint(_)
375 | ty::Float(_)
376 | ty::Adt(_, _)
377 | ty::Foreign(_)
378 | ty::Str
379 | ty::Array(_, _)
380 | ty::Slice(_)
381 | ty::RawPtr(_, _)
382 | ty::Ref(_, _, _)
383 | ty::Pat(_, _)
384 | ty::FnDef(_, _)
385 | ty::FnPtr(..)
386 | ty::UnsafeBinder(_)
387 | ty::Dynamic(_, _)
388 | ty::Closure(..)
389 | ty::CoroutineClosure(..)
390 | ty::Coroutine(_, _)
391 | ty::CoroutineWitness(..)
392 | ty::Never
393 | ty::Tuple(_)
394 | ty::Alias(_, _)
395 | ty::Bound(_, _)
396 | ty::Error(_) => {
397 return ensure_sufficient_stack(|| t.super_fold_with(self));
398 }
399 };
400
401 let var = self.get_or_insert_bound_var(t, kind);
402
403 Ty::new_canonical_bound(self.cx(), var)
404 }
405}
406
407impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicalizer<'_, D, I> {
408 fn cx(&self) -> I {
409 self.delegate.cx()
410 }
411
412 fn fold_region(&mut self, r: Region<I>) -> Region<I> {
413 let kind = match r.kind() {
419 ty::ReBound(..) => return r,
420
421 ty::ReStatic => match self.canonicalize_mode {
424 CanonicalizeMode::Input(CanonicalizeInputKind::Predicate) => {
425 CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion::new_anon(
426 ty::UniverseIndex::ROOT,
427 self.variables.len().into(),
428 ))
429 }
430 CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv)
431 | CanonicalizeMode::Response { .. } => return r,
432 },
433
434 ty::ReErased | ty::ReError(_) => match self.canonicalize_mode {
442 CanonicalizeMode::Input(_) => {
443 CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion::new_anon(
444 ty::UniverseIndex::ROOT,
445 self.variables.len().into(),
446 ))
447 }
448 CanonicalizeMode::Response { .. } => return r,
449 },
450
451 ty::ReEarlyParam(_) | ty::ReLateParam(_) => match self.canonicalize_mode {
452 CanonicalizeMode::Input(_) => {
453 CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion::new_anon(
454 ty::UniverseIndex::ROOT,
455 self.variables.len().into(),
456 ))
457 }
458 CanonicalizeMode::Response { .. } => {
459 {
::core::panicking::panic_fmt(format_args!("unexpected region in response: {0:?}",
r));
}panic!("unexpected region in response: {r:?}")
460 }
461 },
462
463 ty::RePlaceholder(placeholder) => match self.canonicalize_mode {
464 CanonicalizeMode::Input(_) => {
465 CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion::new_anon(
466 ty::UniverseIndex::ROOT,
467 self.variables.len().into(),
468 ))
469 }
470 CanonicalizeMode::Response { max_input_universe } => {
471 if placeholder.universe() != ty::UniverseIndex::ROOT
475 && max_input_universe.can_name(placeholder.universe())
476 {
477 {
::core::panicking::panic_fmt(format_args!("new placeholder in universe {0:?}: {1:?}",
max_input_universe, r));
};panic!("new placeholder in universe {max_input_universe:?}: {r:?}");
478 }
479 CanonicalVarKind::PlaceholderRegion(placeholder)
480 }
481 },
482
483 ty::ReVar(vid) => {
484 if true {
{
match (&self.delegate.opportunistic_resolve_lt_var(vid), &r) {
(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::Some(format_args!("region vid should have been resolved fully before canonicalization")));
}
}
}
};
};debug_assert_eq!(
485 self.delegate.opportunistic_resolve_lt_var(vid),
486 r,
487 "region vid should have been resolved fully before canonicalization"
488 );
489 match self.canonicalize_mode {
490 CanonicalizeMode::Input(_) => {
491 CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion::new_anon(
492 ty::UniverseIndex::ROOT,
493 self.variables.len().into(),
494 ))
495 }
496 CanonicalizeMode::Response { .. } => {
497 CanonicalVarKind::Region(self.delegate.universe_of_lt(vid).unwrap())
498 }
499 }
500 }
501 };
502
503 let var = self.get_or_insert_bound_var(r, kind);
504
505 Region::new_canonical_bound(self.cx(), var)
506 }
507
508 fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
509 if !t.flags().intersects(NEEDS_CANONICAL) {
510 t
511 } else if let Some(&ty) = self.cache.get(&t) {
512 ty
513 } else {
514 let res = self.inner_fold_ty(t);
515 let old = self.cache.insert(t, res);
516 {
match (&old, &None) {
(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!(old, None);
517 res
518 }
519 }
520
521 fn fold_const(&mut self, c: I::Const) -> I::Const {
522 if !c.flags().intersects(NEEDS_CANONICAL) {
523 return c;
524 }
525
526 let kind = match c.kind() {
527 ty::ConstKind::Infer(i) => match i {
528 ty::InferConst::Var(vid) => {
529 if true {
{
match (&self.delegate.opportunistic_resolve_ct_var(vid), &c) {
(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::Some(format_args!("const vid should have been resolved fully before canonicalization")));
}
}
}
};
};debug_assert_eq!(
530 self.delegate.opportunistic_resolve_ct_var(vid),
531 c,
532 "const vid should have been resolved fully before canonicalization"
533 );
534
535 match self.canonicalize_mode {
536 CanonicalizeMode::Input { .. } => {
537 CanonicalVarKind::Const(ty::UniverseIndex::ROOT)
538 }
539 CanonicalizeMode::Response { .. } => {
540 CanonicalVarKind::Const(self.delegate.universe_of_ct(vid).unwrap())
541 }
542 }
543 }
544 ty::InferConst::Fresh(_) => ::core::panicking::panic("not implemented")unimplemented!(),
545 },
546 ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
547 CanonicalizeMode::Input { .. } => {
548 CanonicalVarKind::PlaceholderConst(PlaceholderConst::new_anon(
549 ty::UniverseIndex::ROOT,
550 self.variables.len().into(),
551 ))
552 }
553 CanonicalizeMode::Response { .. } => {
554 CanonicalVarKind::PlaceholderConst(placeholder)
555 }
556 },
557 ty::ConstKind::Param(_) => match self.canonicalize_mode {
558 CanonicalizeMode::Input { .. } => {
559 CanonicalVarKind::PlaceholderConst(PlaceholderConst::new_anon(
560 ty::UniverseIndex::ROOT,
561 self.variables.len().into(),
562 ))
563 }
564 CanonicalizeMode::Response { .. } => {
::core::panicking::panic_fmt(format_args!("param ty in response: {0:?}",
c));
}panic!("param ty in response: {c:?}"),
565 },
566 ty::ConstKind::Bound(_, _)
568 | ty::ConstKind::Alias(_, _)
569 | ty::ConstKind::Value(_)
570 | ty::ConstKind::Error(_)
571 | ty::ConstKind::Expr(_) => return c.super_fold_with(self),
572 };
573
574 let var = self.get_or_insert_bound_var(c, kind);
575
576 Const::new_canonical_bound(self.cx(), var)
577 }
578
579 fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
580 if !p.flags().intersects(NEEDS_CANONICAL) { p } else { p.super_fold_with(self) }
581 }
582
583 fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses {
584 match self.canonicalize_mode {
585 CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv)
586 | CanonicalizeMode::Response { max_input_universe: _ } => {}
587 CanonicalizeMode::Input(CanonicalizeInputKind::Predicate) => {
588 { ::core::panicking::panic_fmt(format_args!("erasing \'static in env")); }panic!("erasing 'static in env")
589 }
590 }
591 if !c.flags().intersects(NEEDS_CANONICAL) { c } else { c.super_fold_with(self) }
592 }
593}