Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Debug representation in const value pretty print #66451

Closed
iwikal opened this issue Nov 15, 2019 · 2 comments · Fixed by #98643
Closed

Replace Debug representation in const value pretty print #66451

iwikal opened this issue Nov 15, 2019 · 2 comments · Fixed by #98643
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-const-generics Area: const generics (parameters and arguments) C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. F-adt_const_params `#![feature(adt_const_params)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@iwikal
Copy link

iwikal commented Nov 15, 2019

As discussed in #65859, we shouldn't be using Debug for user facing output.

@jonas-schievink jonas-schievink added A-const-eval Area: constant evaluation (mir interpretation) C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 15, 2019
@varkor varkor added F-const_generics `#![feature(const_generics)]` A-const-generics Area: const generics (parameters and arguments) labels Nov 18, 2019
@varkor
Copy link
Member

varkor commented Sep 13, 2020

I think this only affects pointers, so this ought not to be a problem for min_const_generics.

@lcnr lcnr added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Jun 28, 2022
@lcnr
Copy link
Contributor

lcnr commented Jun 28, 2022

this issue isn't really relevant anymore, as we now use fn pretty_print_const_valtree for this:

fn pretty_print_const_valtree(
mut self,
valtree: ty::ValTree<'tcx>,
ty: Ty<'tcx>,
print_ty: bool,
) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self);
if self.tcx().sess.verbose() {
p!(write("ValTree({:?}: ", valtree), print(ty), ")");
return Ok(self);
}
let u8_type = self.tcx().types.u8;
match (valtree, ty.kind()) {
(ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() {
ty::Slice(t) if *t == u8_type => {
let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
bug!(
"expected to convert valtree {:?} to raw bytes for type {:?}",
valtree,
t
)
});
return self.pretty_print_byte_str(bytes);
}
ty::Str => {
let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
bug!("expected to convert valtree to raw bytes for type {:?}", ty)
});
p!(write("{:?}", String::from_utf8_lossy(bytes)));
return Ok(self);
}
_ => {}
},
(ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => {
let bytes = valtree.try_to_raw_bytes(self.tcx(), *t).unwrap_or_else(|| {
bug!("expected to convert valtree to raw bytes for type {:?}", t)
});
p!("*");
p!(pretty_print_byte_str(bytes));
return Ok(self);
}
// Aggregates, printed as array/tuple/struct/variant construction syntax.
(ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
let Some(contents) = self.tcx().try_destructure_const(
ty::Const::from_value(self.tcx(), valtree, ty)
) else {
// Fall back to debug pretty printing for invalid constants.
p!(write("{:?}", valtree));
if print_ty {
p!(": ", print(ty));
}
return Ok(self);
};
let fields = contents.fields.iter().copied();
match *ty.kind() {
ty::Array(..) => {
p!("[", comma_sep(fields), "]");
}
ty::Tuple(..) => {
p!("(", comma_sep(fields));
if contents.fields.len() == 1 {
p!(",");
}
p!(")");
}
ty::Adt(def, _) if def.variants().is_empty() => {
self = self.typed_value(
|mut this| {
write!(this, "unreachable()")?;
Ok(this)
},
|this| this.print_type(ty),
": ",
)?;
}
ty::Adt(def, substs) => {
let variant_idx =
contents.variant.expect("destructed const of adt without variant idx");
let variant_def = &def.variant(variant_idx);
p!(print_value_path(variant_def.def_id, substs));
match variant_def.ctor_kind {
CtorKind::Const => {}
CtorKind::Fn => {
p!("(", comma_sep(fields), ")");
}
CtorKind::Fictive => {
p!(" {{ ");
let mut first = true;
for (field_def, field) in iter::zip(&variant_def.fields, fields) {
if !first {
p!(", ");
}
p!(write("{}: ", field_def.name), print(field));
first = false;
}
p!(" }}");
}
}
}
_ => unreachable!(),
}
return Ok(self);
}
(ty::ValTree::Leaf(leaf), _) => {
return self.pretty_print_const_scalar_int(leaf, ty, print_ty);
}
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
// their fields instead of just dumping the memory.
_ => {}
}
// fallback
if valtree == ty::ValTree::zst() {
p!(write("<ZST>"));
} else {
p!(write("{:?}", valtree));
}
if print_ty {
p!(": ", print(ty));
}
Ok(self)
}
}

This should also deal with references by printing a & and then calling pretty_print_const_valtree recursively.

as a test case, consider https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=cf3ef9d61a8bd2f727db22dd6b755863

while that's getting fixed, also change the try_destructure_const to just return a DestructredConst, ICE in cases where it currently returns None, and rename it to destructure_const. Destructuring a valtree should be infallible.

Finally, move the implementation of that query to a new module rustc_ty_utils::consts.

@lcnr lcnr added F-adt_const_params `#![feature(adt_const_params)]` and removed F-const_generics `#![feature(const_generics)]` labels Jun 28, 2022
@bors bors closed this as completed in 921e311 Jun 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-const-generics Area: const generics (parameters and arguments) C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. F-adt_const_params `#![feature(adt_const_params)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants