Skip to content

Commit bb33e03

Browse files
committed
Auto merge of rust-lang#112718 - oli-obk:SIMD-destructure_mir_const, r=cjgillot
Make simd_shuffle_indices use valtrees This removes the second-to-last user of the `destructure_mir_constant` query. So in a follow-up we can remove the query and just move the query provider function directly into pretty printing (which is the last user). cc `@rust-lang/clippy` there's a small functional change, but I think it is correct?
2 parents 2ac2dc1 + 7bd8ab7 commit bb33e03

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

clippy_lints/src/non_copy_const.rs

+50-14
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ use rustc_hir::{
1515
};
1616
use rustc_hir_analysis::hir_ty_to_ty;
1717
use rustc_lint::{LateContext, LateLintPass, Lint};
18-
use rustc_middle::mir;
19-
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
18+
use rustc_middle::mir::interpret::ErrorHandled;
2019
use rustc_middle::ty::adjustment::Adjust;
21-
use rustc_middle::ty::{self, Ty};
20+
use rustc_middle::ty::{self, Ty, TyCtxt};
2221
use rustc_session::{declare_lint_pass, declare_tool_lint};
2322
use rustc_span::{sym, InnerSpan, Span};
23+
use rustc_target::abi::VariantIdx;
24+
use rustc_middle::mir::interpret::EvalToValTreeResult;
25+
use rustc_middle::mir::interpret::GlobalId;
2426

2527
// FIXME: this is a correctness problem but there's no suitable
2628
// warn-by-default category.
@@ -141,21 +143,35 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
141143

142144
fn is_value_unfrozen_raw<'tcx>(
143145
cx: &LateContext<'tcx>,
144-
result: Result<ConstValue<'tcx>, ErrorHandled>,
146+
result: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
145147
ty: Ty<'tcx>,
146148
) -> bool {
147-
fn inner<'tcx>(cx: &LateContext<'tcx>, val: mir::ConstantKind<'tcx>) -> bool {
148-
match val.ty().kind() {
149+
fn inner<'tcx>(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
150+
match *ty.kind() {
149151
// the fact that we have to dig into every structs to search enums
150152
// leads us to the point checking `UnsafeCell` directly is the only option.
151153
ty::Adt(ty_def, ..) if ty_def.is_unsafe_cell() => true,
152154
// As of 2022-09-08 miri doesn't track which union field is active so there's no safe way to check the
153155
// contained value.
154156
ty::Adt(def, ..) if def.is_union() => false,
155-
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
156-
let val = cx.tcx.destructure_mir_constant(cx.param_env, val);
157-
val.fields.iter().any(|field| inner(cx, *field))
157+
ty::Array(ty, _) => {
158+
val.unwrap_branch().iter().any(|field| inner(cx, *field, ty))
158159
},
160+
ty::Adt(def, _) if def.is_union() => false,
161+
ty::Adt(def, substs) if def.is_enum() => {
162+
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
163+
let variant_index =
164+
VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
165+
fields.iter().copied().zip(
166+
def.variants()[variant_index]
167+
.fields
168+
.iter()
169+
.map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, field, ty))
170+
}
171+
ty::Adt(def, substs) => {
172+
val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, *field, ty))
173+
}
174+
ty::Tuple(tys) => val.unwrap_branch().iter().zip(tys).any(|(field, ty)| inner(cx, *field, ty)),
159175
_ => false,
160176
}
161177
}
@@ -184,24 +200,44 @@ fn is_value_unfrozen_raw<'tcx>(
184200
// I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none).
185201
err == ErrorHandled::TooGeneric
186202
},
187-
|val| inner(cx, mir::ConstantKind::from_value(val, ty)),
203+
|val| val.map_or(true, |val| inner(cx, val, ty)),
188204
)
189205
}
190206

191207
fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
192-
let result = cx.tcx.const_eval_poly(body_id.hir_id.owner.to_def_id());
208+
let def_id = body_id.hir_id.owner.to_def_id();
209+
let substs = ty::InternalSubsts::identity_for_item(cx.tcx, def_id);
210+
let instance = ty::Instance::new(def_id, substs);
211+
let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
212+
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
213+
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None);
193214
is_value_unfrozen_raw(cx, result, ty)
194215
}
195216

196217
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
197218
let substs = cx.typeck_results().node_substs(hir_id);
198219

199-
let result = cx
200-
.tcx
201-
.const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None);
220+
let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, substs), None);
202221
is_value_unfrozen_raw(cx, result, ty)
203222
}
204223

224+
225+
pub fn const_eval_resolve<'tcx>(
226+
tcx: TyCtxt<'tcx>,
227+
param_env: ty::ParamEnv<'tcx>,
228+
ct: ty::UnevaluatedConst<'tcx>,
229+
span: Option<Span>,
230+
) -> EvalToValTreeResult<'tcx> {
231+
match ty::Instance::resolve(tcx, param_env, ct.def, ct.substs) {
232+
Ok(Some(instance)) => {
233+
let cid = GlobalId { instance, promoted: None };
234+
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
235+
}
236+
Ok(None) => Err(ErrorHandled::TooGeneric),
237+
Err(err) => Err(ErrorHandled::Reported(err.into())),
238+
}
239+
}
240+
205241
#[derive(Copy, Clone)]
206242
enum Source {
207243
Item { item: Span },

tests/ui/crashes/ice-9445.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: a `const` item should never be interior mutable
2+
--> $DIR/ice-9445.rs:1:1
3+
|
4+
LL | const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core::mem::MaybeUninit::uninit();
5+
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| make this a static item (maybe with lazy_static)
8+
|
9+
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
10+
11+
error: aborting due to previous error
12+

0 commit comments

Comments
 (0)