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