Skip to content

Commit 63fb0de

Browse files
committed
added pretty_print_const_expr
1 parent aaef5fe commit 63fb0de

File tree

4 files changed

+166
-9
lines changed

4 files changed

+166
-9
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::query::Providers;
44
use crate::traits::util::supertraits_for_pretty_printing;
55
use crate::ty::GenericArgKind;
66
use crate::ty::{
7-
ConstInt, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
7+
ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
88
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
99
};
1010
use rustc_apfloat::ieee::{Double, Single};
@@ -262,6 +262,31 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
262262
Ok(())
263263
}
264264

265+
/// Prints `(...)` around what `f` prints.
266+
fn parenthesized(
267+
&mut self,
268+
f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
269+
) -> Result<(), PrintError> {
270+
self.write_str("(")?;
271+
f(self)?;
272+
self.write_str(")")?;
273+
Ok(())
274+
}
275+
276+
/// Prints `(...)` around what `f` prints if `parenthesized` is true, otherwise just prints `f`.
277+
fn maybe_parenthesized(
278+
&mut self,
279+
f: impl FnOnce(&mut Self) -> Result<(), PrintError>,
280+
parenthesized: bool,
281+
) -> Result<(), PrintError> {
282+
if parenthesized {
283+
self.parenthesized(f)?;
284+
} else {
285+
f(self)?;
286+
}
287+
Ok(())
288+
}
289+
265290
/// Prints `<...>` around what `f` prints.
266291
fn generic_delimiters(
267292
&mut self,
@@ -1382,12 +1407,137 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
13821407
ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
13831408
// FIXME(generic_const_exprs):
13841409
// write out some legible representation of an abstract const?
1385-
ty::ConstKind::Expr(_) => p!("{{const expr}}"),
1410+
ty::ConstKind::Expr(expr) => self.pretty_print_const_expr(expr, print_ty)?,
13861411
ty::ConstKind::Error(_) => p!("{{const error}}"),
13871412
};
13881413
Ok(())
13891414
}
13901415

1416+
fn pretty_print_const_expr(
1417+
&mut self,
1418+
expr: Expr<'tcx>,
1419+
print_ty: bool,
1420+
) -> Result<(), PrintError> {
1421+
define_scoped_cx!(self);
1422+
match expr {
1423+
Expr::Binop(op, c1, c2) => {
1424+
let precedence = |binop: rustc_middle::mir::BinOp| {
1425+
use rustc_ast::util::parser::AssocOp;
1426+
AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
1427+
};
1428+
let op_precedence = precedence(op);
1429+
let formatted_op = op.to_hir_binop().as_str();
1430+
let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) {
1431+
(
1432+
ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)),
1433+
ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)),
1434+
) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence),
1435+
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => {
1436+
(precedence(lhs_op) < op_precedence, true)
1437+
}
1438+
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
1439+
(true, precedence(rhs_op) < op_precedence)
1440+
}
1441+
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true),
1442+
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => {
1443+
(precedence(lhs_op) < op_precedence, false)
1444+
}
1445+
(_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
1446+
(false, precedence(rhs_op) < op_precedence)
1447+
}
1448+
(ty::ConstKind::Expr(_), _) => (true, false),
1449+
(_, ty::ConstKind::Expr(_)) => (false, true),
1450+
_ => (false, false),
1451+
};
1452+
1453+
self.maybe_parenthesized(
1454+
|this| this.pretty_print_const(c1, print_ty),
1455+
lhs_parenthesized,
1456+
)?;
1457+
p!(write(" {formatted_op} "));
1458+
self.maybe_parenthesized(
1459+
|this| this.pretty_print_const(c2, print_ty),
1460+
rhs_parenthesized,
1461+
)?;
1462+
}
1463+
Expr::UnOp(op, ct) => {
1464+
use rustc_middle::mir::UnOp;
1465+
let formatted_op = match op {
1466+
UnOp::Not => "!",
1467+
UnOp::Neg => "-",
1468+
};
1469+
let parenthesized = match ct.kind() {
1470+
ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op,
1471+
ty::ConstKind::Expr(_) => true,
1472+
_ => false,
1473+
};
1474+
p!(write("{formatted_op}"));
1475+
self.maybe_parenthesized(
1476+
|this| this.pretty_print_const(ct, print_ty),
1477+
parenthesized,
1478+
)?
1479+
}
1480+
Expr::FunctionCall(fn_def, fn_args) => {
1481+
use ty::TyKind;
1482+
match fn_def.ty().kind() {
1483+
TyKind::FnDef(def_id, gen_args) => {
1484+
p!(print_value_path(*def_id, gen_args), "(");
1485+
if print_ty {
1486+
let tcx = self.tcx();
1487+
let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder();
1488+
1489+
let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty()));
1490+
let output_ty = sig.output();
1491+
1492+
if let Some((ct, ty)) = args_with_ty.next() {
1493+
self.typed_value(
1494+
|this| this.pretty_print_const(ct, print_ty),
1495+
|this| this.pretty_print_type(ty),
1496+
": ",
1497+
)?;
1498+
for (ct, ty) in args_with_ty {
1499+
p!(", ");
1500+
self.typed_value(
1501+
|this| this.pretty_print_const(ct, print_ty),
1502+
|this| this.pretty_print_type(ty),
1503+
": ",
1504+
)?;
1505+
}
1506+
}
1507+
p!(write(") -> {output_ty}"));
1508+
} else {
1509+
p!(comma_sep(fn_args.iter()), ")");
1510+
}
1511+
}
1512+
_ => bug!("unexpected type of fn def"),
1513+
}
1514+
}
1515+
Expr::Cast(kind, ct, ty) => {
1516+
use ty::abstract_const::CastKind;
1517+
if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) {
1518+
let parenthesized = match ct.kind() {
1519+
ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false,
1520+
ty::ConstKind::Expr(_) => true,
1521+
_ => false,
1522+
};
1523+
self.maybe_parenthesized(
1524+
|this| {
1525+
this.typed_value(
1526+
|this| this.pretty_print_const(ct, print_ty),
1527+
|this| this.pretty_print_type(ty),
1528+
" as ",
1529+
)
1530+
},
1531+
parenthesized,
1532+
)?;
1533+
} else {
1534+
self.pretty_print_const(ct, print_ty)?
1535+
}
1536+
}
1537+
}
1538+
Ok(())
1539+
}
1540+
13911541
fn pretty_print_const_scalar(
13921542
&mut self,
13931543
scalar: Scalar,

tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ where
1919
//~^^ ERROR: unconstrained generic constant
2020
//~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied
2121
//~^^^^ ERROR: unconstrained generic constant
22-
//~^^^^^ ERROR: unconstrained generic constant `{const expr}`
22+
//~^^^^^ ERROR: unconstrained generic constant `L + 1 + L`
23+
//~^^^^^ ERROR: unconstrained generic constant `L + 1`
2324
}
2425

2526
fn main() {}

tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,19 @@ LL | | }
5252
LL | | }],
5353
| |_____^ required by this bound in `foo`
5454

55-
error: unconstrained generic constant `{const expr}`
55+
error: unconstrained generic constant `L + 1 + L`
5656
--> $DIR/issue_114151.rs:17:5
5757
|
5858
LL | foo::<_, L>([(); L + 1 + L]);
5959
| ^^^^^^^^^^^
6060

61-
error: aborting due to 5 previous errors
61+
error: unconstrained generic constant `L + 1`
62+
--> $DIR/issue_114151.rs:17:5
63+
|
64+
LL | foo::<_, L>([(); L + 1 + L]);
65+
| ^^^^^^^^^^^
66+
|
67+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
6268

6369
Some errors have detailed explanations: E0107, E0308.
6470
For more information about an error, try `rustc --explain E0107`.

tests/ui/const-generics/transmute-fail.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
44
LL | std::mem::transmute(v)
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: source type: `[[u32; H+1]; W]` (generic size {const expr})
8-
= note: target type: `[[u32; W+1]; H]` (generic size {const expr})
7+
= note: source type: `[[u32; H+1]; W]` (generic size (H + 1) * 4 * W)
8+
= note: target type: `[[u32; W+1]; H]` (generic size (W + 1) * 4 * H)
99

1010
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
1111
--> $DIR/transmute-fail.rs:16:5
@@ -22,8 +22,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
2222
LL | std::mem::transmute(v)
2323
| ^^^^^^^^^^^^^^^^^^^
2424
|
25-
= note: source type: `[[u32; H]; W]` (generic size {const expr})
26-
= note: target type: `[u32; W * H * H]` (generic size {const expr})
25+
= note: source type: `[[u32; H]; W]` (generic size 4 * H * W)
26+
= note: target type: `[u32; W * H * H]` (generic size 4 * H * H * W)
2727

2828
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
2929
--> $DIR/transmute-fail.rs:30:5

0 commit comments

Comments
 (0)