From 45a0aa4b4d4fb124f8db4e8b037465b457e66147 Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Sun, 5 Nov 2017 09:28:00 -0800 Subject: [PATCH 1/4] 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. --- src/librustc/hir/print.rs | 9 +++++++++ src/libsyntax/print/pprust.rs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 24a0b5fcea9b8..54f66453db87d 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1253,6 +1253,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())?; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8a970fd409895..e6ffbb2cce9f3 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1986,6 +1986,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())?; From 005d14d5c810519517cc2507b5c304df7be9a6ed Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Sun, 5 Nov 2017 12:27:46 -0800 Subject: [PATCH 2/4] Added tests --- src/test/pretty/cast-lt.pp | 26 ++++++++++++++++++++++++++ src/test/pretty/cast-lt.rs | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/test/pretty/cast-lt.pp create mode 100644 src/test/pretty/cast-lt.rs diff --git a/src/test/pretty/cast-lt.pp b/src/test/pretty/cast-lt.pp new file mode 100644 index 0000000000000..1e611f5075f69 --- /dev/null +++ b/src/test/pretty/cast-lt.pp @@ -0,0 +1,26 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use std::prelude::v1::*; +#[macro_use] +extern crate std as std; +// Copyright 2014 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 or the MIT license +// , 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 + +// #4264 fixed-length vector types + +macro_rules! negative(( $ e : expr ) => { $ e < 0 }); + +fn main() { (1 as i32) < 0; } + diff --git a/src/test/pretty/cast-lt.rs b/src/test/pretty/cast-lt.rs new file mode 100644 index 0000000000000..c0ee62380ed00 --- /dev/null +++ b/src/test/pretty/cast-lt.rs @@ -0,0 +1,24 @@ +// Copyright 2014 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 or the MIT license +// , 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 + +// #4264 fixed-length vector types + +macro_rules! negative { + ($e:expr) => { $e < 0 } +} + +fn main() { + negative!(1 as i32); +} + From 3761c0d246f8deb9ebb83567991bbbc0c090d75d Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Sun, 5 Nov 2017 20:53:46 -0800 Subject: [PATCH 3/4] Fix comments --- src/test/pretty/cast-lt.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/pretty/cast-lt.rs b/src/test/pretty/cast-lt.rs index c0ee62380ed00..87b5274545f38 100644 --- a/src/test/pretty/cast-lt.rs +++ b/src/test/pretty/cast-lt.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -12,8 +12,6 @@ // pretty-mode:expanded // pp-exact:cast-lt.pp -// #4264 fixed-length vector types - macro_rules! negative { ($e:expr) => { $e < 0 } } From aa38a1ee5092fb81e23b0cbd215535de08ae7b28 Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Mon, 6 Nov 2017 22:18:14 -0800 Subject: [PATCH 4/4] Update comments in cast-lt.pp --- src/test/pretty/cast-lt.pp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/pretty/cast-lt.pp b/src/test/pretty/cast-lt.pp index 1e611f5075f69..b21158abfe551 100644 --- a/src/test/pretty/cast-lt.pp +++ b/src/test/pretty/cast-lt.pp @@ -4,7 +4,7 @@ use std::prelude::v1::*; #[macro_use] extern crate std as std; -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -18,8 +18,6 @@ // pretty-mode:expanded // pp-exact:cast-lt.pp -// #4264 fixed-length vector types - macro_rules! negative(( $ e : expr ) => { $ e < 0 }); fn main() { (1 as i32) < 0; }