borrow_interior_mutable_const ICE into FN (#13877)

This PR just makes sure that we exit the function before getting an ICE
and adds a regression test. Related to #12979. We would need to keep
researching the issue, but as the ICEing code isn't that complicated,
getting a hotfix into nightly is urgent.

changelog:[`borrow_interior_mutable_const`] Fix ICE #12979
This commit is contained in:
Fridtjof Stoldt 2024-12-29 15:52:35 +00:00 committed by GitHub
commit f5f1abd8fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 19 deletions

View file

@ -189,6 +189,8 @@ impl<'tcx> NonCopyConst<'tcx> {
}
fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
// No branch that we check (yet) should continue if val isn't a ValTree::Branch
let ty::ValTree::Branch(val) = val else { return false };
match *ty.kind() {
// the fact that we have to dig into every structs to search enums
// leads us to the point checking `UnsafeCell` directly is the only option.
@ -197,12 +199,13 @@ impl<'tcx> NonCopyConst<'tcx> {
// contained value.
ty::Adt(def, ..) if def.is_union() => false,
ty::Array(ty, _) => val
.unwrap_branch()
.iter()
.any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
ty::Adt(def, args) if def.is_enum() => {
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32());
let Some((&ty::ValTree::Leaf(variant_index), fields)) = val.split_first() else {
return false;
};
let variant_index = VariantIdx::from_u32(variant_index.to_u32());
fields
.iter()
.copied()
@ -215,12 +218,10 @@ impl<'tcx> NonCopyConst<'tcx> {
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, field, ty))
},
ty::Adt(def, args) => val
.unwrap_branch()
.iter()
.zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args)))
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
ty::Tuple(tys) => val
.unwrap_branch()
.iter()
.zip(tys)
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),