added pretty_print_const_expr
This commit is contained in:
parent
9023f908cf
commit
7c4b07d5e8
4 changed files with 160 additions and 12 deletions
|
@ -4,7 +4,7 @@ use crate::query::Providers;
|
||||||
use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
|
use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
|
||||||
use crate::ty::GenericArgKind;
|
use crate::ty::GenericArgKind;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
ConstInt, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
|
ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
|
||||||
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
use rustc_apfloat::ieee::{Double, Single};
|
use rustc_apfloat::ieee::{Double, Single};
|
||||||
|
@ -270,6 +270,31 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prints `(...)` around what `f` prints.
|
||||||
|
fn parenthesized(
|
||||||
|
&mut self,
|
||||||
|
f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||||
|
) -> Result<(), PrintError> {
|
||||||
|
self.write_str("(")?;
|
||||||
|
f(self)?;
|
||||||
|
self.write_str(")")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints `(...)` around what `f` prints if `parenthesized` is true, otherwise just prints `f`.
|
||||||
|
fn maybe_parenthesized(
|
||||||
|
&mut self,
|
||||||
|
f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||||
|
parenthesized: bool,
|
||||||
|
) -> Result<(), PrintError> {
|
||||||
|
if parenthesized {
|
||||||
|
self.parenthesized(f)?;
|
||||||
|
} else {
|
||||||
|
f(self)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Prints `<...>` around what `f` prints.
|
/// Prints `<...>` around what `f` prints.
|
||||||
fn generic_delimiters(
|
fn generic_delimiters(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1490,12 +1515,137 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
|
ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
|
||||||
// FIXME(generic_const_exprs):
|
// FIXME(generic_const_exprs):
|
||||||
// write out some legible representation of an abstract const?
|
// write out some legible representation of an abstract const?
|
||||||
ty::ConstKind::Expr(_) => p!("{{const expr}}"),
|
ty::ConstKind::Expr(expr) => self.pretty_print_const_expr(expr, print_ty)?,
|
||||||
ty::ConstKind::Error(_) => p!("{{const error}}"),
|
ty::ConstKind::Error(_) => p!("{{const error}}"),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pretty_print_const_expr(
|
||||||
|
&mut self,
|
||||||
|
expr: Expr<'tcx>,
|
||||||
|
print_ty: bool,
|
||||||
|
) -> Result<(), PrintError> {
|
||||||
|
define_scoped_cx!(self);
|
||||||
|
match expr {
|
||||||
|
Expr::Binop(op, c1, c2) => {
|
||||||
|
let precedence = |binop: rustc_middle::mir::BinOp| {
|
||||||
|
use rustc_ast::util::parser::AssocOp;
|
||||||
|
AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
|
||||||
|
};
|
||||||
|
let op_precedence = precedence(op);
|
||||||
|
let formatted_op = op.to_hir_binop().as_str();
|
||||||
|
let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) {
|
||||||
|
(
|
||||||
|
ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)),
|
||||||
|
ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)),
|
||||||
|
) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence),
|
||||||
|
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => {
|
||||||
|
(precedence(lhs_op) < op_precedence, true)
|
||||||
|
}
|
||||||
|
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
|
||||||
|
(true, precedence(rhs_op) < op_precedence)
|
||||||
|
}
|
||||||
|
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true),
|
||||||
|
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => {
|
||||||
|
(precedence(lhs_op) < op_precedence, false)
|
||||||
|
}
|
||||||
|
(_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
|
||||||
|
(false, precedence(rhs_op) < op_precedence)
|
||||||
|
}
|
||||||
|
(ty::ConstKind::Expr(_), _) => (true, false),
|
||||||
|
(_, ty::ConstKind::Expr(_)) => (false, true),
|
||||||
|
_ => (false, false),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.maybe_parenthesized(
|
||||||
|
|this| this.pretty_print_const(c1, print_ty),
|
||||||
|
lhs_parenthesized,
|
||||||
|
)?;
|
||||||
|
p!(write(" {formatted_op} "));
|
||||||
|
self.maybe_parenthesized(
|
||||||
|
|this| this.pretty_print_const(c2, print_ty),
|
||||||
|
rhs_parenthesized,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Expr::UnOp(op, ct) => {
|
||||||
|
use rustc_middle::mir::UnOp;
|
||||||
|
let formatted_op = match op {
|
||||||
|
UnOp::Not => "!",
|
||||||
|
UnOp::Neg => "-",
|
||||||
|
};
|
||||||
|
let parenthesized = match ct.kind() {
|
||||||
|
ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op,
|
||||||
|
ty::ConstKind::Expr(_) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
p!(write("{formatted_op}"));
|
||||||
|
self.maybe_parenthesized(
|
||||||
|
|this| this.pretty_print_const(ct, print_ty),
|
||||||
|
parenthesized,
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
Expr::FunctionCall(fn_def, fn_args) => {
|
||||||
|
use ty::TyKind;
|
||||||
|
match fn_def.ty().kind() {
|
||||||
|
TyKind::FnDef(def_id, gen_args) => {
|
||||||
|
p!(print_value_path(*def_id, gen_args), "(");
|
||||||
|
if print_ty {
|
||||||
|
let tcx = self.tcx();
|
||||||
|
let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder();
|
||||||
|
|
||||||
|
let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty()));
|
||||||
|
let output_ty = sig.output();
|
||||||
|
|
||||||
|
if let Some((ct, ty)) = args_with_ty.next() {
|
||||||
|
self.typed_value(
|
||||||
|
|this| this.pretty_print_const(ct, print_ty),
|
||||||
|
|this| this.pretty_print_type(ty),
|
||||||
|
": ",
|
||||||
|
)?;
|
||||||
|
for (ct, ty) in args_with_ty {
|
||||||
|
p!(", ");
|
||||||
|
self.typed_value(
|
||||||
|
|this| this.pretty_print_const(ct, print_ty),
|
||||||
|
|this| this.pretty_print_type(ty),
|
||||||
|
": ",
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p!(write(") -> {output_ty}"));
|
||||||
|
} else {
|
||||||
|
p!(comma_sep(fn_args.iter()), ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => bug!("unexpected type of fn def"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Cast(kind, ct, ty) => {
|
||||||
|
use ty::abstract_const::CastKind;
|
||||||
|
if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) {
|
||||||
|
let parenthesized = match ct.kind() {
|
||||||
|
ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false,
|
||||||
|
ty::ConstKind::Expr(_) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
self.maybe_parenthesized(
|
||||||
|
|this| {
|
||||||
|
this.typed_value(
|
||||||
|
|this| this.pretty_print_const(ct, print_ty),
|
||||||
|
|this| this.pretty_print_type(ty),
|
||||||
|
" as ",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
parenthesized,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
self.pretty_print_const(ct, print_ty)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn pretty_print_const_scalar(
|
fn pretty_print_const_scalar(
|
||||||
&mut self,
|
&mut self,
|
||||||
scalar: Scalar,
|
scalar: Scalar,
|
||||||
|
|
|
@ -19,8 +19,8 @@ where
|
||||||
//~^^ ERROR: unconstrained generic constant
|
//~^^ ERROR: unconstrained generic constant
|
||||||
//~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied
|
//~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied
|
||||||
//~^^^^ ERROR: unconstrained generic constant
|
//~^^^^ ERROR: unconstrained generic constant
|
||||||
//~^^^^^ ERROR: unconstrained generic constant `{const expr}`
|
//~^^^^^ ERROR: unconstrained generic constant `L + 1 + L`
|
||||||
//~^^^^^^ ERROR: unconstrained generic constant `{const expr}`
|
//~^^^^^^ ERROR: unconstrained generic constant `L + 1`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -52,19 +52,17 @@ LL | | }
|
||||||
LL | | }],
|
LL | | }],
|
||||||
| |_____^ required by this bound in `foo`
|
| |_____^ required by this bound in `foo`
|
||||||
|
|
||||||
error: unconstrained generic constant `{const expr}`
|
error: unconstrained generic constant `L + 1 + L`
|
||||||
--> $DIR/issue_114151.rs:17:5
|
--> $DIR/issue_114151.rs:17:5
|
||||||
|
|
|
|
||||||
LL | foo::<_, L>([(); L + 1 + L]);
|
LL | foo::<_, L>([(); L + 1 + L]);
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: unconstrained generic constant `{const expr}`
|
error: unconstrained generic constant `L + 1`
|
||||||
--> $DIR/issue_114151.rs:17:5
|
--> $DIR/issue_114151.rs:17:5
|
||||||
|
|
|
|
||||||
LL | foo::<_, L>([(); L + 1 + L]);
|
LL | foo::<_, L>([(); L + 1 + L]);
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `[[u32; H+1]; W]` (generic size {const expr})
|
= note: source type: `[[u32; H+1]; W]` (generic size (H + 1) * 4 * W)
|
||||||
= note: target type: `[[u32; W+1]; H]` (generic size {const expr})
|
= note: target type: `[[u32; W+1]; H]` (generic size (W + 1) * 4 * H)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:16:5
|
--> $DIR/transmute-fail.rs:16:5
|
||||||
|
@ -22,8 +22,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
|
||||||
LL | std::mem::transmute(v)
|
LL | std::mem::transmute(v)
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: source type: `[[u32; H]; W]` (generic size {const expr})
|
= note: source type: `[[u32; H]; W]` (generic size 4 * H * W)
|
||||||
= note: target type: `[u32; W * H * H]` (generic size {const expr})
|
= note: target type: `[u32; W * H * H]` (generic size 4 * H * H * W)
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||||
--> $DIR/transmute-fail.rs:30:5
|
--> $DIR/transmute-fail.rs:30:5
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue