Rollup merge of #45784 - harpocrates:fix/print-parens-cast-lt, r=kennytm
Pretty print parens around casts on the LHS of `<`/`<<` When pretty printing a cast expression occuring on the LHS of a `<` or `<<` expression, we should add parens around the cast. Otherwise, the `<`/`<<` gets interpreted as the beginning of the generics for the type on the RHS of the cast. Consider: $ cat parens_cast.rs macro_rules! negative { ($e:expr) => { $e < 0 } } fn main() { negative!(1 as i32); } Before this PR, the output of the following is not valid Rust: $ rustc -Z unstable-options --pretty=expanded parens_cast.rs #![feature(prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*; #[macro_use] extern crate std as std; macro_rules! negative(( $ e : expr ) => { $ e < 0 }); fn main() { 1 as i32 < 0; } After this PR, the output of the following is valid Rust: $ rustc -Z unstable-options --pretty=expanded parens_cast.rs #![feature(prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*; #[macro_use] extern crate std as std; macro_rules! negative(( $ e : expr ) => { $ e < 0 }); fn main() { (1 as i32) < 0; } I've gone through several README/wiki style documents but I'm still not sure where to test this though. I'm not even sure if this sort of thing is tested...
This commit is contained in:
commit
0d53ecd0c7
@ -1254,6 +1254,15 @@ impl<'a> State<'a> {
|
||||
Fixity::None => (prec + 1, prec + 1),
|
||||
};
|
||||
|
||||
let left_prec = match (&lhs.node, op.node) {
|
||||
// These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
|
||||
// the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
|
||||
// of `(x as i32) < ...`. We need to convince it _not_ to do that.
|
||||
(&hir::ExprCast { .. }, hir::BinOp_::BiLt) |
|
||||
(&hir::ExprCast { .. }, hir::BinOp_::BiShl) => parser::PREC_FORCE_PAREN,
|
||||
_ => left_prec,
|
||||
};
|
||||
|
||||
self.print_expr_maybe_paren(lhs, left_prec)?;
|
||||
self.s.space()?;
|
||||
self.word_space(op.node.as_str())?;
|
||||
|
@ -1987,6 +1987,15 @@ impl<'a> State<'a> {
|
||||
Fixity::None => (prec + 1, prec + 1),
|
||||
};
|
||||
|
||||
let left_prec = match (&lhs.node, op.node) {
|
||||
// These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
|
||||
// the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
|
||||
// of `(x as i32) < ...`. We need to convince it _not_ to do that.
|
||||
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Lt) |
|
||||
(&ast::ExprKind::Cast { .. }, ast::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
|
||||
_ => left_prec,
|
||||
};
|
||||
|
||||
self.print_expr_maybe_paren(lhs, left_prec)?;
|
||||
self.s.space()?;
|
||||
self.word_space(op.node.to_string())?;
|
||||
|
24
src/test/pretty/cast-lt.pp
Normal file
24
src/test/pretty/cast-lt.pp
Normal file
@ -0,0 +1,24 @@
|
||||
#![feature(prelude_import)]
|
||||
#![no_std]
|
||||
#[prelude_import]
|
||||
use std::prelude::v1::*;
|
||||
#[macro_use]
|
||||
extern crate std as std;
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// pretty-compare-only
|
||||
// pretty-mode:expanded
|
||||
// pp-exact:cast-lt.pp
|
||||
|
||||
macro_rules! negative(( $ e : expr ) => { $ e < 0 });
|
||||
|
||||
fn main() { (1 as i32) < 0; }
|
||||
|
22
src/test/pretty/cast-lt.rs
Normal file
22
src/test/pretty/cast-lt.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// pretty-compare-only
|
||||
// pretty-mode:expanded
|
||||
// pp-exact:cast-lt.pp
|
||||
|
||||
macro_rules! negative {
|
||||
($e:expr) => { $e < 0 }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
negative!(1 as i32);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user