Skip to content

Commit 7bf3dc1

Browse files
committed
allow AbstractConsts to be printed for diagnostics
1 parent 2569e59 commit 7bf3dc1

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def::DefKind;
1313
use rustc_index::vec::IndexVec;
1414
use rustc_infer::infer::InferCtxt;
1515
use rustc_middle::mir;
16-
use rustc_middle::mir::interpret::ErrorHandled;
16+
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
1717
use rustc_middle::thir;
1818
use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
1919
use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -33,7 +33,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
3333
param_env: ty::ParamEnv<'tcx>,
3434
span: Span,
3535
) -> Result<(), NotConstEvaluatable> {
36-
debug!("is_const_evaluatable({:?})", uv);
36+
debug!("param_env: {:#?}", param_env);
37+
3738
if infcx.tcx.features().generic_const_exprs {
3839
let tcx = infcx.tcx;
3940
match AbstractConst::new(tcx, uv)? {
@@ -225,6 +226,61 @@ impl<'tcx> AbstractConst<'tcx> {
225226
Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => node,
226227
}
227228
}
229+
230+
/// Used for diagnostics only.
231+
/// Tries to create a String of an `AbstractConst` while recursively applying substs. This
232+
/// will fail for `AbstractConst`s that contain `Leaf`s including inference variables or errors,
233+
/// and any non-Leaf `Node`s other than `BinOp` and `UnOp`.
234+
pub(crate) fn try_print_with_replacing_substs(mut self, tcx: TyCtxt<'tcx>) -> Option<String> {
235+
// try to replace substs
236+
while let abstract_const::Node::Leaf(ct) = self.root(tcx) {
237+
match AbstractConst::from_const(tcx, ct) {
238+
Ok(Some(act)) => self = act,
239+
Ok(None) => break,
240+
Err(_) => bug!("should be able to create AbstractConst here"),
241+
}
242+
}
243+
244+
match self.root(tcx) {
245+
abstract_const::Node::Leaf(ct) => match ct.val {
246+
ty::ConstKind::Error(_) | ty::ConstKind::Infer(_) => return None,
247+
ty::ConstKind::Param(c) => return Some(format!("{}", c)),
248+
ty::ConstKind::Value(ConstValue::Scalar(scalar)) => match scalar.to_i64() {
249+
Ok(s) => return Some(format!("{}", s)),
250+
Err(_) => return None,
251+
},
252+
_ => return None,
253+
},
254+
abstract_const::Node::Binop(op, l, r) => {
255+
let op = match op.try_as_string() {
256+
Some(o) => o,
257+
None => return None,
258+
};
259+
260+
let left = self.subtree(l).try_print_with_replacing_substs(tcx);
261+
debug!(?left);
262+
263+
let right = self.subtree(r).try_print_with_replacing_substs(tcx);
264+
debug!(?right);
265+
266+
match (left, right) {
267+
(Some(l), Some(r)) => {
268+
return Some(format!("{} {} {}", l, op, r));
269+
}
270+
_ => return None,
271+
}
272+
}
273+
abstract_const::Node::UnaryOp(op, v) => {
274+
match self.subtree(v).try_print_with_replacing_substs(tcx) {
275+
Some(operand) => {
276+
return Some(format!("{}{}", op, operand));
277+
}
278+
None => return None,
279+
}
280+
}
281+
_ => return None,
282+
}
283+
}
228284
}
229285

230286
struct AbstractConstBuilder<'a, 'tcx> {

0 commit comments

Comments
 (0)