@@ -4,7 +4,7 @@ use crate::query::Providers;
44use crate :: traits:: util:: { super_predicates_for_pretty_printing, supertraits_for_pretty_printing} ;
55use crate :: ty:: GenericArgKind ;
66use crate :: ty:: {
7- ConstInt , ParamConst , ScalarInt , Term , TermKind , TypeFoldable , TypeSuperFoldable ,
7+ ConstInt , Expr , ParamConst , ScalarInt , Term , TermKind , TypeFoldable , TypeSuperFoldable ,
88 TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
99} ;
1010use rustc_apfloat:: ieee:: { Double , Single } ;
@@ -270,6 +270,31 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
270270 Ok ( ( ) )
271271 }
272272
273+ /// Prints `(...)` around what `f` prints.
274+ fn parenthesized (
275+ & mut self ,
276+ f : impl FnOnce ( & mut Self ) -> Result < ( ) , PrintError > ,
277+ ) -> Result < ( ) , PrintError > {
278+ self . write_str ( "(" ) ?;
279+ f ( self ) ?;
280+ self . write_str ( ")" ) ?;
281+ Ok ( ( ) )
282+ }
283+
284+ /// Prints `(...)` around what `f` prints if `parenthesized` is true, otherwise just prints `f`.
285+ fn maybe_parenthesized (
286+ & mut self ,
287+ f : impl FnOnce ( & mut Self ) -> Result < ( ) , PrintError > ,
288+ parenthesized : bool ,
289+ ) -> Result < ( ) , PrintError > {
290+ if parenthesized {
291+ self . parenthesized ( f) ?;
292+ } else {
293+ f ( self ) ?;
294+ }
295+ Ok ( ( ) )
296+ }
297+
273298 /// Prints `<...>` around what `f` prints.
274299 fn generic_delimiters (
275300 & mut self ,
@@ -1490,12 +1515,137 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
14901515 ty:: ConstKind :: Placeholder ( placeholder) => p ! ( write( "{placeholder:?}" ) ) ,
14911516 // FIXME(generic_const_exprs):
14921517 // write out some legible representation of an abstract const?
1493- ty:: ConstKind :: Expr ( _ ) => p ! ( "{{const expr}}" ) ,
1518+ ty:: ConstKind :: Expr ( expr ) => self . pretty_print_const_expr ( expr, print_ty ) ? ,
14941519 ty:: ConstKind :: Error ( _) => p ! ( "{{const error}}" ) ,
14951520 } ;
14961521 Ok ( ( ) )
14971522 }
14981523
1524+ fn pretty_print_const_expr (
1525+ & mut self ,
1526+ expr : Expr < ' tcx > ,
1527+ print_ty : bool ,
1528+ ) -> Result < ( ) , PrintError > {
1529+ define_scoped_cx ! ( self ) ;
1530+ match expr {
1531+ Expr :: Binop ( op, c1, c2) => {
1532+ let precedence = |binop : rustc_middle:: mir:: BinOp | {
1533+ use rustc_ast:: util:: parser:: AssocOp ;
1534+ AssocOp :: from_ast_binop ( binop. to_hir_binop ( ) . into ( ) ) . precedence ( )
1535+ } ;
1536+ let op_precedence = precedence ( op) ;
1537+ let formatted_op = op. to_hir_binop ( ) . as_str ( ) ;
1538+ let ( lhs_parenthesized, rhs_parenthesized) = match ( c1. kind ( ) , c2. kind ( ) ) {
1539+ (
1540+ ty:: ConstKind :: Expr ( Expr :: Binop ( lhs_op, _, _) ) ,
1541+ ty:: ConstKind :: Expr ( Expr :: Binop ( rhs_op, _, _) ) ,
1542+ ) => ( precedence ( lhs_op) < op_precedence, precedence ( rhs_op) < op_precedence) ,
1543+ ( ty:: ConstKind :: Expr ( Expr :: Binop ( lhs_op, ..) ) , ty:: ConstKind :: Expr ( _) ) => {
1544+ ( precedence ( lhs_op) < op_precedence, true )
1545+ }
1546+ ( ty:: ConstKind :: Expr ( _) , ty:: ConstKind :: Expr ( Expr :: Binop ( rhs_op, ..) ) ) => {
1547+ ( true , precedence ( rhs_op) < op_precedence)
1548+ }
1549+ ( ty:: ConstKind :: Expr ( _) , ty:: ConstKind :: Expr ( _) ) => ( true , true ) ,
1550+ ( ty:: ConstKind :: Expr ( Expr :: Binop ( lhs_op, ..) ) , _) => {
1551+ ( precedence ( lhs_op) < op_precedence, false )
1552+ }
1553+ ( _, ty:: ConstKind :: Expr ( Expr :: Binop ( rhs_op, ..) ) ) => {
1554+ ( false , precedence ( rhs_op) < op_precedence)
1555+ }
1556+ ( ty:: ConstKind :: Expr ( _) , _) => ( true , false ) ,
1557+ ( _, ty:: ConstKind :: Expr ( _) ) => ( false , true ) ,
1558+ _ => ( false , false ) ,
1559+ } ;
1560+
1561+ self . maybe_parenthesized (
1562+ |this| this. pretty_print_const ( c1, print_ty) ,
1563+ lhs_parenthesized,
1564+ ) ?;
1565+ p ! ( write( " {formatted_op} " ) ) ;
1566+ self . maybe_parenthesized (
1567+ |this| this. pretty_print_const ( c2, print_ty) ,
1568+ rhs_parenthesized,
1569+ ) ?;
1570+ }
1571+ Expr :: UnOp ( op, ct) => {
1572+ use rustc_middle:: mir:: UnOp ;
1573+ let formatted_op = match op {
1574+ UnOp :: Not => "!" ,
1575+ UnOp :: Neg => "-" ,
1576+ } ;
1577+ let parenthesized = match ct. kind ( ) {
1578+ ty:: ConstKind :: Expr ( Expr :: UnOp ( c_op, ..) ) => c_op != op,
1579+ ty:: ConstKind :: Expr ( _) => true ,
1580+ _ => false ,
1581+ } ;
1582+ p ! ( write( "{formatted_op}" ) ) ;
1583+ self . maybe_parenthesized (
1584+ |this| this. pretty_print_const ( ct, print_ty) ,
1585+ parenthesized,
1586+ ) ?
1587+ }
1588+ Expr :: FunctionCall ( fn_def, fn_args) => {
1589+ use ty:: TyKind ;
1590+ match fn_def. ty ( ) . kind ( ) {
1591+ TyKind :: FnDef ( def_id, gen_args) => {
1592+ p ! ( print_value_path( * def_id, gen_args) , "(" ) ;
1593+ if print_ty {
1594+ let tcx = self . tcx ( ) ;
1595+ let sig = tcx. fn_sig ( def_id) . instantiate ( tcx, gen_args) . skip_binder ( ) ;
1596+
1597+ let mut args_with_ty = fn_args. iter ( ) . map ( |ct| ( ct, ct. ty ( ) ) ) ;
1598+ let output_ty = sig. output ( ) ;
1599+
1600+ if let Some ( ( ct, ty) ) = args_with_ty. next ( ) {
1601+ self . typed_value (
1602+ |this| this. pretty_print_const ( ct, print_ty) ,
1603+ |this| this. pretty_print_type ( ty) ,
1604+ ": " ,
1605+ ) ?;
1606+ for ( ct, ty) in args_with_ty {
1607+ p ! ( ", " ) ;
1608+ self . typed_value (
1609+ |this| this. pretty_print_const ( ct, print_ty) ,
1610+ |this| this. pretty_print_type ( ty) ,
1611+ ": " ,
1612+ ) ?;
1613+ }
1614+ }
1615+ p ! ( write( ") -> {output_ty}" ) ) ;
1616+ } else {
1617+ p ! ( comma_sep( fn_args. iter( ) ) , ")" ) ;
1618+ }
1619+ }
1620+ _ => bug ! ( "unexpected type of fn def" ) ,
1621+ }
1622+ }
1623+ Expr :: Cast ( kind, ct, ty) => {
1624+ use ty:: abstract_const:: CastKind ;
1625+ if kind == CastKind :: As || ( kind == CastKind :: Use && self . should_print_verbose ( ) ) {
1626+ let parenthesized = match ct. kind ( ) {
1627+ ty:: ConstKind :: Expr ( Expr :: Cast ( _, _, _) ) => false ,
1628+ ty:: ConstKind :: Expr ( _) => true ,
1629+ _ => false ,
1630+ } ;
1631+ self . maybe_parenthesized (
1632+ |this| {
1633+ this. typed_value (
1634+ |this| this. pretty_print_const ( ct, print_ty) ,
1635+ |this| this. pretty_print_type ( ty) ,
1636+ " as " ,
1637+ )
1638+ } ,
1639+ parenthesized,
1640+ ) ?;
1641+ } else {
1642+ self . pretty_print_const ( ct, print_ty) ?
1643+ }
1644+ }
1645+ }
1646+ Ok ( ( ) )
1647+ }
1648+
14991649 fn pretty_print_const_scalar (
15001650 & mut self ,
15011651 scalar : Scalar ,
0 commit comments