} } } else { <del> if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs { let hir_id = tcx.local_def_id_to_hir_id(def_id); let parent_def_id = tcx.hir().get_parent_item(hir_id); if let Some(defaulted_param_def_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) { // In `generics_of` we set the generics' parent to be our parent's parent which means that // we lose out on the predicates of our actual parent if we dont return those predicates here. // (See comment in `generics_of` for more information on why the parent shenanigans is necessary) // // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait; //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling //        ^^^                                             explicit_predicates_of on //        parent item we dont have set as the //        parent of generics returned by `generics_of` // // In the above code we want the anon const to have predicates in its param env for `T: Trait` // and we would be calling `explicit_predicates_of(Foo)` here let parent_preds = tcx.explicit_predicates_of(parent_def_id); // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution // to #106994 is implemented. let filtered_predicates = parent_preds .predicates .into_iter() .filter(|(pred, _)| { if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() { match ct.kind() { ty::ConstKind::Param(param_const) => { let defaulted_param_idx = tcx .generics_of(parent_def_id) .param_def_id_to_index[&defaulted_param_def_id.to_def_id()]; param_const.index < defaulted_param_idx } _ => bug!( "`ConstArgHasType` in `predicates_of` that isn't a `Param` const" ), </del> <ins> if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs && let Some(defaulted_param_def_id) = tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id)) { // In `generics_of` we set the generics' parent to be our parent's parent which means that // we lose out on the predicates of our actual parent if we dont return those predicates here. // (See comment in `generics_of` for more information on why the parent shenanigans is necessary) // // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait; //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling //        ^^^                                             explicit_predicates_of on //        parent item we dont have set as the //        parent of generics returned by `generics_of` // // In the above code we want the anon const to have predicates in its param env for `T: Trait` // and we would be calling `explicit_predicates_of(Foo)` here let parent_def_id = tcx.local_parent(def_id); let parent_preds = tcx.explicit_predicates_of(parent_def_id); // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution // to #106994 is implemented. let filtered_predicates = parent_preds .predicates .into_iter() .filter(|(pred, _)| { if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() { match ct.kind() { ty::ConstKind::Param(param_const) => { let defaulted_param_idx = tcx .generics_of(parent_def_id) .param_def_id_to_index[&defaulted_param_def_id.to_def_id()]; param_const.index < defaulted_param_idx </ins> } <del> } else { true </del> <ins> _ => bug!( "`ConstArgHasType` in `predicates_of` that isn't a `Param` const" ), </ins> } <del> }) .cloned(); return GenericPredicates { parent: parent_preds.parent, predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, }; } let parent_def_kind = tcx.def_kind(parent_def_id); if matches!(parent_def_kind, DefKind::OpaqueTy) { // In `instantiate_identity` we inherit the predicates of our parent. // However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means // that we lose out on the predicates of our actual parent if we dont return those predicates here. // // // fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() } //                                                        ^^^^^^^^^^^^^^^^^^^ the def id we are calling //                                                                            explicit_predicates_of on // // In the above code we want the anon const to have predicates in its param env for `T: Trait`. // However, the anon const cannot inherit predicates from its parent since it's opaque. // // To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent. // In the above example this is `foo::{opaque#0}` or `impl Iterator` let parent_hir_id = tcx.local_def_id_to_hir_id(parent_def_id.def_id); // In the above example this is the function `foo` let item_def_id = tcx.hir().get_parent_item(parent_hir_id); // In the above code example we would be calling `explicit_predicates_of(foo)` here return tcx.explicit_predicates_of(item_def_id); } </del> <ins> } else { true } }) .cloned(); return GenericPredicates { parent: parent_preds.parent, predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, }; </ins> } gather_explicit_predicates_of(tcx, def_id) }