Skip to content

Fix representation when printing abstract consts #119212

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

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 152 additions & 2 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::query::Providers;
use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
use crate::ty::GenericArgKind;
use crate::ty::{
ConstInt, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_apfloat::ieee::{Double, Single};
Expand Down Expand Up @@ -270,6 +270,31 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
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.
fn generic_delimiters(
&mut self,
Expand Down Expand Up @@ -1490,12 +1515,137 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
// FIXME(generic_const_exprs):
// 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}}"),
};
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(
&mut self,
scalar: Scalar,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ where
//~^^ ERROR: unconstrained generic constant
//~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied
//~^^^^ ERROR: unconstrained generic constant
//~^^^^^ ERROR: unconstrained generic constant `{const expr}`
//~^^^^^^ ERROR: unconstrained generic constant `{const expr}`
//~^^^^^ ERROR: unconstrained generic constant `L + 1 + L`
//~^^^^^^ ERROR: unconstrained generic constant `L + 1`
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,17 @@ LL | | }
LL | | }],
| |_____^ 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
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^^^

error: unconstrained generic constant `{const expr}`
error: unconstrained generic constant `L + 1`
--> $DIR/issue_114151.rs:17:5
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 6 previous errors

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/const-generics/transmute-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
LL | std::mem::transmute(v)
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[[u32; H+1]; W]` (generic size {const expr})
= note: target type: `[[u32; W+1]; H]` (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 (W + 1) * 4 * H)

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/transmute-fail.rs:16:5
Expand All @@ -22,8 +22,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
LL | std::mem::transmute(v)
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[[u32; H]; W]` (generic size {const expr})
= note: target type: `[u32; W * H * H]` (generic size {const expr})
= note: source type: `[[u32; H]; W]` (generic size 4 * H * W)
= 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
--> $DIR/transmute-fail.rs:30:5
Expand Down