Skip to content

unused_parens now fires on cast expression #110189

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

Closed
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
74 changes: 65 additions & 9 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
@@ -572,6 +572,7 @@ enum UnusedDelimsCtx {
AnonConst,
MatchArmExpr,
IndexExpr,
CastExpr,
}

impl From<UnusedDelimsCtx> for &'static str {
@@ -592,10 +593,18 @@ impl From<UnusedDelimsCtx> for &'static str {
UnusedDelimsCtx::ArrayLenExpr | UnusedDelimsCtx::AnonConst => "const expression",
UnusedDelimsCtx::MatchArmExpr => "match arm expression",
UnusedDelimsCtx::IndexExpr => "index expression",
UnusedDelimsCtx::CastExpr => "cast expression",
}
}
}

#[derive(Copy, Clone, Eq, PartialEq)]
enum UnusedDelimCtxFollowedTokenKind {
Block,
Else,
Cast,
}

/// Used by both `UnusedParens` and `UnusedBraces` to prevent code duplication.
trait UnusedDelimLint {
const DELIM_STR: &'static str;
@@ -629,9 +638,14 @@ trait UnusedDelimLint {

fn is_expr_delims_necessary(
inner: &ast::Expr,
followed_by_block: bool,
followed_by_else: bool,
followed_token: Option<UnusedDelimCtxFollowedTokenKind>,
) -> bool {
let followed_by_block =
matches!(followed_token, Some(UnusedDelimCtxFollowedTokenKind::Block));
let followed_by_else =
matches!(followed_token, Some(UnusedDelimCtxFollowedTokenKind::Else));
let followed_by_cast =
matches!(followed_token, Some(UnusedDelimCtxFollowedTokenKind::Cast));
if followed_by_else {
match inner.kind {
ast::ExprKind::Binary(op, ..) if op.node.lazy() => return true,
@@ -640,6 +654,25 @@ trait UnusedDelimLint {
}
}

if followed_by_cast {
match inner.kind {
// `as` has higher precedence than any binary operator
ast::ExprKind::Binary(..)
// #88519
| ast::ExprKind::Block(..)
| ast::ExprKind::Match(..)
| ast::ExprKind::If(..)
// #51185
| ast::ExprKind::Closure(..)
// This pattern is technically unnecessary, because unary-minus has higher
// precedence than cast. However, casts followed by it may be confusing
// snippet to code readers. If we want to revisit this, this case shall be
// handled by some external approach.
| ast::ExprKind::Unary(ast::UnOp::Neg, ..) => return true,
_ => {}
}
}

// Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
{
let mut innermost = inner;
@@ -964,9 +997,18 @@ impl UnusedDelimLint for UnusedParens {
) {
match value.kind {
ast::ExprKind::Paren(ref inner) => {
let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse;
if !Self::is_expr_delims_necessary(inner, followed_by_block, followed_by_else)
&& value.attrs.is_empty()
if !Self::is_expr_delims_necessary(
inner,
if followed_by_block {
Some(UnusedDelimCtxFollowedTokenKind::Block)
} else if ctx == UnusedDelimsCtx::AssignedValueLetElse {
Some(UnusedDelimCtxFollowedTokenKind::Else)
} else if ctx == UnusedDelimsCtx::CastExpr {
Some(UnusedDelimCtxFollowedTokenKind::Cast)
} else {
None
},
) && value.attrs.is_empty()
&& !value.span.from_expansion()
&& (ctx != UnusedDelimsCtx::LetScrutineeExpr
|| !matches!(inner.kind, ast::ExprKind::Binary(
@@ -989,6 +1031,18 @@ impl UnusedDelimLint for UnusedParens {
false,
);
}
ast::ExprKind::Cast(ref expr, _) => match expr.kind {
_ => self.check_unused_delims_expr(
cx,
expr,
UnusedDelimsCtx::CastExpr,
followed_by_block,
None,
None,
false,
),
},

_ => {}
}
}
@@ -1248,10 +1302,12 @@ impl UnusedDelimLint for UnusedBraces {
// FIXME(const_generics): handle paths when #67075 is fixed.
if let [stmt] = inner.stmts.as_slice() {
if let ast::StmtKind::Expr(ref expr) = stmt.kind {
if !Self::is_expr_delims_necessary(expr, followed_by_block, false)
&& (ctx != UnusedDelimsCtx::AnonConst
|| (matches!(expr.kind, ast::ExprKind::Lit(_))
&& !expr.span.from_expansion()))
if !Self::is_expr_delims_necessary(
expr,
followed_by_block.then_some(UnusedDelimCtxFollowedTokenKind::Block),
) && (ctx != UnusedDelimsCtx::AnonConst
|| (matches!(expr.kind, ast::ExprKind::Lit(_))
&& !expr.span.from_expansion()))
&& !cx.sess().source_map().is_multiline(value.span)
&& value.attrs.is_empty()
&& !value.span.from_expansion()
2 changes: 1 addition & 1 deletion library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ mod tests;
/// This is a global invariant, and also applies when using a compare-exchange loop.
///
/// See comment in `Arc::clone`.
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
const MAX_REFCOUNT: usize = isize::MAX as usize;

/// The error in case either counter reaches above `MAX_REFCOUNT`, and we can `panic` safely.
const INTERNAL_OVERFLOW_ERROR: &str = "Arc counter overflow";
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/number.rs
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ impl Number {
// normal fast path
let value = F::from_u64(self.mantissa);
if self.exponent < 0 {
value / F::pow10_fast_path((-self.exponent) as _)
value / F::pow10_fast_path(-self.exponent as _)
} else {
value * F::pow10_fast_path(self.exponent as _)
}
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/parse.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ fn parse_8digits(mut v: u64) -> u64 {
v = (v * 10) + (v >> 8); // will not overflow, fits in 63 bits
let v1 = (v & MASK).wrapping_mul(MUL1);
let v2 = ((v >> 16) & MASK).wrapping_mul(MUL2);
((v1.wrapping_add(v2) >> 32) as u32) as u64
(v1.wrapping_add(v2) >> 32) as u32 as u64
}

/// Parse digits until a non-digit character is found.
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/slow.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ pub(crate) fn parse_long_mantissa<F: RawFloat>(s: &[u8]) -> BiasedFp {
_ => 1,
}
} else {
get_shift((-d.decimal_point) as _)
get_shift(-d.decimal_point as _)
};
d.left_shift(shift);
if d.decimal_point > Decimal::DECIMAL_POINT_RANGE {
4 changes: 2 additions & 2 deletions library/std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
@@ -244,8 +244,8 @@ impl<R: ?Sized + Seek> BufReader<R> {
pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
let pos = self.buf.pos() as u64;
if offset < 0 {
if let Some(_) = pos.checked_sub((-offset) as u64) {
self.buf.unconsume((-offset) as usize);
if let Some(_) = pos.checked_sub(-offset as u64) {
self.buf.unconsume(-offset as usize);
return Ok(());
}
} else if let Some(new_pos) = pos.checked_add(offset as u64) {
2 changes: 1 addition & 1 deletion library/std/src/sys/unix/os.rs
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ extern "C" {
/// Returns the platform-specific value of errno
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
pub fn errno() -> i32 {
unsafe { (*errno_location()) as i32 }
unsafe { *errno_location() as i32 }
}

/// Sets the platform-specific value of errno
4 changes: 2 additions & 2 deletions library/std/src/thread/tests.rs
Original file line number Diff line number Diff line change
@@ -159,10 +159,10 @@ where
let (tx, rx) = channel();

let x: Box<_> = Box::new(1);
let x_in_parent = (&*x) as *const i32 as usize;
let x_in_parent = &*x as *const i32 as usize;

spawnfn(Box::new(move || {
let x_in_child = (&*x) as *const i32 as usize;
let x_in_child = &*x as *const i32 as usize;
tx.send(x_in_child).unwrap();
}));

4 changes: 2 additions & 2 deletions src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ use std::alloc::{alloc, dealloc, Layout};
fn main() {
unsafe {
let x = alloc(Layout::from_size_align_unchecked(1, 1));
let ptr1 = (&mut *x) as *mut u8;
let ptr2 = (&mut *ptr1) as *mut u8;
let ptr1 = &mut *x as *mut u8;
let ptr2 = &mut *ptr1 as *mut u8;
// Invalidate ptr2 by writing to ptr1.
ptr1.write(0);
// Deallocate through ptr2.
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ fn main() {
name!(n);
let x = &mut *(n as *mut _);
name!(x);
let y = (&mut *n) as *mut _;
let y = &mut *n as *mut _;
name!(y);
write_second(x, y);
unsafe fn write_second(x: &mut u8, y: *mut u8) {
18 changes: 9 additions & 9 deletions src/tools/miri/tests/pass/float.rs
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ fn casts() {
assert_eq::<i32>(f32::INFINITY as i32, i32::MAX);
assert_eq::<i32>(f32::NEG_INFINITY as i32, i32::MIN);
assert_eq::<i32>(f32::NAN as i32, 0);
assert_eq::<i32>((-f32::NAN) as i32, 0);
Copy link
Member

@RalfJung RalfJung Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should lint against (-expr) as i32. Looking at -expr as i32 I have no idea whether the as or the - are executed first, and I might care about that (in particular when casting to an unsigned type). (The formatting indicates that - goes first but I don't know if that actually matches how this is parsed.)

Parentheses to disambiguate parsing precedence are a good thing, we should not steer people away from them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agreed :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The diff in the Miri test can hopefully be removed then. :)

assert_eq::<i32>(-f32::NAN as i32, 0);

// f32 -> u32
test_both_cast::<f32, u32>(0.0, 0);
@@ -223,7 +223,7 @@ fn casts() {
assert_eq::<u32>(f32::INFINITY as u32, u32::MAX);
assert_eq::<u32>(f32::NEG_INFINITY as u32, 0);
assert_eq::<u32>(f32::NAN as u32, 0);
assert_eq::<u32>((-f32::NAN) as u32, 0);
assert_eq::<u32>(-f32::NAN as u32, 0);

// f32 -> i64
test_both_cast::<f32, i64>(4294967296.0, 4294967296);
@@ -281,7 +281,7 @@ fn casts() {
assert_eq::<i64>(f64::INFINITY as i64, i64::MAX);
assert_eq::<i64>(f64::NEG_INFINITY as i64, i64::MIN);
assert_eq::<i64>(f64::NAN as i64, 0);
assert_eq::<i64>((-f64::NAN) as i64, 0);
assert_eq::<i64>(-f64::NAN as i64, 0);

// f64 -> u64
test_both_cast::<f64, u64>(0.0, 0);
@@ -300,7 +300,7 @@ fn casts() {
assert_eq::<u64>(f64::INFINITY as u64, u64::MAX);
assert_eq::<u64>(f64::NEG_INFINITY as u64, 0);
assert_eq::<u64>(f64::NAN as u64, 0);
assert_eq::<u64>((-f64::NAN) as u64, 0);
assert_eq::<u64>(-f64::NAN as u64, 0);

// f64 -> i128
assert_eq::<i128>(f64::MAX as i128, i128::MAX);
@@ -313,12 +313,12 @@ fn casts() {
// int -> f32
assert_eq::<f32>(127i8 as f32, 127.0);
assert_eq::<f32>(2147483647i32 as f32, 2147483648.0);
assert_eq::<f32>((-2147483648i32) as f32, -2147483648.0);
assert_eq::<f32>(-2147483648i32 as f32, -2147483648.0);
assert_eq::<f32>(1234567890i32 as f32, /*0x1.26580cp+30*/ f32::from_bits(0x4e932c06));
assert_eq::<f32>(16777217i32 as f32, 16777216.0);
assert_eq::<f32>((-16777217i32) as f32, -16777216.0);
assert_eq::<f32>(-16777217i32 as f32, -16777216.0);
assert_eq::<f32>(16777219i32 as f32, 16777220.0);
assert_eq::<f32>((-16777219i32) as f32, -16777220.0);
assert_eq::<f32>(-16777219i32 as f32, -16777220.0);
assert_eq::<f32>(
0x7fffff4000000001i64 as f32,
/*0x1.fffffep+62*/ f32::from_bits(0x5effffff),
@@ -370,7 +370,7 @@ fn casts() {
/*0x1.fffffep+127*/ f64::from_bits(0x47efffffe0000000),
);
assert_eq::<f64>(
/*-0x1.fffffep+127*/ (-f32::from_bits(0x7f7fffff)) as f64,
/*-0x1.fffffep+127*/ -f32::from_bits(0x7f7fffff) as f64,
/*-0x1.fffffep+127*/ -f64::from_bits(0x47efffffe0000000),
);
assert_eq::<f64>(
@@ -389,7 +389,7 @@ fn casts() {
assert_eq::<u32>(((-0.0f64) as f32).to_bits(), (-0.0f32).to_bits());
assert_eq::<f32>(5.0f64 as f32, 5.0f32);
assert_eq::<f32>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1) as f32, 0.0);
assert_eq::<f32>(/*-0x0.0000000000001p-1022*/ (-f64::from_bits(0x1)) as f32, -0.0);
assert_eq::<f32>(/*-0x0.0000000000001p-1022*/ -f64::from_bits(0x1) as f32, -0.0);
assert_eq::<f32>(
/*0x1.fffffe0000000p-127*/ f64::from_bits(0x380fffffe0000000) as f32,
/*0x1p-149*/ f32::from_bits(0x800000),
6 changes: 3 additions & 3 deletions src/tools/miri/tests/pass/tree-borrows/reserved.rs
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ unsafe fn int_protected_read() {
name!(base);
let x = &mut *(base as *mut u8);
name!(x);
let y = (&mut *base) as *mut u8;
let y = &mut *base as *mut u8;
name!(y);
read_second(x, y); // Foreign Read for callee:x
print_state!(alloc_id);
@@ -106,7 +106,7 @@ unsafe fn int_unprotected_read() {
let alloc_id = alloc_id!(base);
let x = &mut *(base as *mut u8);
name!(x);
let y = (&mut *base) as *mut u8;
let y = &mut *base as *mut u8;
name!(y);
let _val = *y; // Foreign Read for x
print_state!(alloc_id);
@@ -120,7 +120,7 @@ unsafe fn int_unprotected_write() {
let alloc_id = alloc_id!(base);
let x = &mut *(base as *mut u8);
name!(x);
let y = (&mut *base) as *mut u8;
let y = &mut *base as *mut u8;
name!(y);
*y = 1; // Foreign Write for x
print_state!(alloc_id);
6 changes: 3 additions & 3 deletions tests/ui/const-ptr/allowed_slices.rs
Original file line number Diff line number Diff line change
@@ -20,13 +20,13 @@ pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 1) };
pub static S3: &[MaybeUninit<&u32>] = unsafe { from_raw_parts(&D1, 1) };

// Reinterpreting data is fine, as long as layouts match
pub static S4: &[u8] = unsafe { from_raw_parts((&D0) as *const _ as _, 3) };
pub static S4: &[u8] = unsafe { from_raw_parts(&D0 as *const _ as _, 3) };
// This is only valid because D1 has uninitialized bytes, if it was an initialized pointer,
// that would reinterpret pointers as integers which is UB in CTFE.
pub static S5: &[MaybeUninit<u8>] = unsafe { from_raw_parts((&D1) as *const _ as _, 2) };
pub static S5: &[MaybeUninit<u8>] = unsafe { from_raw_parts(&D1 as *const _ as _, 2) };
// Even though u32 and [bool; 4] have different layouts, D0 has a value that
// is valid as [bool; 4], so this is not UB (it's basically a transmute)
pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
pub static S6: &[bool] = unsafe { from_raw_parts(&D0 as *const _ as _, 4) };

// Structs are considered single allocated objects,
// as long as you don't reinterpret padding as initialized
2 changes: 1 addition & 1 deletion tests/ui/consts/issue-27890.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// run-pass
static PLUS_ONE: &'static (dyn Fn(i32) -> i32 + Sync) = (&|x: i32| { x + 1 })
static PLUS_ONE: &'static (dyn Fn(i32) -> i32 + Sync) = &(|x: i32| { x + 1 })
as &'static (dyn Fn(i32) -> i32 + Sync);

fn main() {
101 changes: 101 additions & 0 deletions tests/ui/lint/unused_parens_cast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// check-pass

#![warn(unused_parens)]

struct Foo(f32);

impl Foo {
pub fn f32(self) -> f32 {
64.0f32
}
}

fn bar() -> f32 {
3.0f32
}

mod inner {
pub mod yet_inner {
pub mod most_inner {
pub static VERY_LONG_PATH: f32 = 99.0f32;
}
}
}

fn basic_test() {
// should fire
let one = 1.0f32;
let _ = (one) as f64;
//~^ WARN unnecessary parentheses around cast expression
let _ = (inner::yet_inner::most_inner::VERY_LONG_PATH) as f64;
//~^ WARN unnecessary parentheses around cast expression
let _ = (Foo(1.0f32).0) as f64;
//~^ WARN unnecessary parentheses around cast expression
let _ = (Foo(1.0f32).f32()) as f64;
//~^ WARN unnecessary parentheses around cast expression
let _ = (bar()) as f64;
//~^ WARN unnecessary parentheses around cast expression
let baz = [4.0f32];
let _ = (baz[0]) as f64;
//~^ WARN unnecessary parentheses around cast expression
// following is technically unnecessary, but is allowed because it may confusing.
let _ = (-1.0f32) as f64;
let x = Box::new(-1.0f32);
let _ = (*x) as f64;
//~^ WARN unnecessary parentheses around cast expression
// cast is left-assoc
let _ = (true as u8) as u16;
//~^ WARN unnecessary parentheses around cast expression
// should not fire
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add unary - to this block (and other unary operator as well?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does your intention include *expr as Ty and &expr as Ty?

let _ = (1.0f32 * 2.0f32) as f64;
let _ = (1.0f32 / 2.0f32) as f64;
let _ = (1.0f32 % 2.0f32) as f64;
let _ = (1.0f32 + 2.0f32) as f64;
let _ = (1.0f32 - 2.0f32) as f64;
let _ = (42 << 1) as i64;
let _ = (42 >> 1) as i64;
let _ = (42 & 0x1F) as f64;
let _ = (42 ^ 0x1F) as f64;
let _ = (42 | 0x1F) as f64;
let _ = (1.0f32 == 2.0f32) as u8;
let _ = (1.0f32 != 2.0f32) as u8;
let _ = (1.0f32 < 2.0f32) as u8;
let _ = (1.0f32 > 2.0f32) as u8;
let _ = (1.0f32 <= 2.0f32) as u8;
let _ = (1.0f32 >= 2.0f32) as u8;
let _ = (true && false) as u8;
let _ = (true || false) as u8;
// skipped range: `as`-cast does not allow non-primitive cast
// also skipped compound operator
}

fn issue_88519() {
let _ = ({ 1 }) as i64;
let _ = (match 0 { x => x }) as i64;
let _ = (if true { 16 } else { 42 }) as i64;
}

fn issue_51185() -> impl Into<for<'a> fn(&'a ())> {
// removing parens will change semantics, and make compile does not pass
(|_| {}) as for<'a> fn(&'a ())
}

fn issue_clippy_10557() {
let x = 0f32;
let y = 0f32;
let width = 100f32;
let height = 100f32;

new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
//~^ WARN unnecessary parentheses around cast expression
//~^^ WARN unnecessary parentheses around cast expression
//~^^^ WARN unnecessary parentheses around cast expression
//~^^^^ WARN unnecessary parentheses around cast expression
}

fn new_rect(x: f64, y: f64, width: f64, height: f64) {

}

fn main() {
}
151 changes: 151 additions & 0 deletions tests/ui/lint/unused_parens_cast.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:28:13
|
LL | let _ = (one) as f64;
| ^ ^
|
note: the lint level is defined here
--> $DIR/unused_parens_cast.rs:3:9
|
LL | #![warn(unused_parens)]
| ^^^^^^^^^^^^^
help: remove these parentheses
|
LL - let _ = (one) as f64;
LL + let _ = one as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:30:13
|
LL | let _ = (inner::yet_inner::most_inner::VERY_LONG_PATH) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (inner::yet_inner::most_inner::VERY_LONG_PATH) as f64;
LL + let _ = inner::yet_inner::most_inner::VERY_LONG_PATH as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:32:13
|
LL | let _ = (Foo(1.0f32).0) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (Foo(1.0f32).0) as f64;
LL + let _ = Foo(1.0f32).0 as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:34:13
|
LL | let _ = (Foo(1.0f32).f32()) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (Foo(1.0f32).f32()) as f64;
LL + let _ = Foo(1.0f32).f32() as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:36:13
|
LL | let _ = (bar()) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (bar()) as f64;
LL + let _ = bar() as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:39:13
|
LL | let _ = (baz[0]) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (baz[0]) as f64;
LL + let _ = baz[0] as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:44:13
|
LL | let _ = (*x) as f64;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (*x) as f64;
LL + let _ = *x as f64;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:47:13
|
LL | let _ = (true as u8) as u16;
| ^ ^
|
help: remove these parentheses
|
LL - let _ = (true as u8) as u16;
LL + let _ = true as u8 as u16;
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:89:14
|
LL | new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
| ^ ^
|
help: remove these parentheses
|
LL - new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
LL + new_rect(x as f64, (y) as f64, (width) as f64, (height) as f64);
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:89:26
|
LL | new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
| ^ ^
|
help: remove these parentheses
|
LL - new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
LL + new_rect((x) as f64, y as f64, (width) as f64, (height) as f64);
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:89:38
|
LL | new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
| ^ ^
|
help: remove these parentheses
|
LL - new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
LL + new_rect((x) as f64, (y) as f64, width as f64, (height) as f64);
|

warning: unnecessary parentheses around cast expression
--> $DIR/unused_parens_cast.rs:89:54
|
LL | new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
| ^ ^
|
help: remove these parentheses
|
LL - new_rect((x) as f64, (y) as f64, (width) as f64, (height) as f64);
LL + new_rect((x) as f64, (y) as f64, (width) as f64, height as f64);
|

warning: 12 warnings emitted

18 changes: 9 additions & 9 deletions tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs
Original file line number Diff line number Diff line change
@@ -226,7 +226,7 @@ fn casts() {
assert_eq::<i32>(f32::INFINITY as i32, i32::MAX);
assert_eq::<i32>(f32::NEG_INFINITY as i32, i32::MIN);
assert_eq::<i32>(f32::NAN as i32, 0);
assert_eq::<i32>((-f32::NAN) as i32, 0);
assert_eq::<i32>(-f32::NAN as i32, 0);

// f32 -> u32
test_both_cast::<f32, u32>(0.0, 0);
@@ -255,7 +255,7 @@ fn casts() {
assert_eq::<u32>(f32::INFINITY as u32, u32::MAX);
assert_eq::<u32>(f32::NEG_INFINITY as u32, 0);
assert_eq::<u32>(f32::NAN as u32, 0);
assert_eq::<u32>((-f32::NAN) as u32, 0);
assert_eq::<u32>(-f32::NAN as u32, 0);

// f32 -> i64
test_both_cast::<f32, i64>(4294967296.0, 4294967296);
@@ -313,7 +313,7 @@ fn casts() {
assert_eq::<i64>(f64::INFINITY as i64, i64::MAX);
assert_eq::<i64>(f64::NEG_INFINITY as i64, i64::MIN);
assert_eq::<i64>(f64::NAN as i64, 0);
assert_eq::<i64>((-f64::NAN) as i64, 0);
assert_eq::<i64>(-f64::NAN as i64, 0);

// f64 -> u64
test_both_cast::<f64, u64>(0.0, 0);
@@ -333,7 +333,7 @@ fn casts() {
assert_eq::<u64>(f64::INFINITY as u64, u64::MAX);
assert_eq::<u64>(f64::NEG_INFINITY as u64, 0);
assert_eq::<u64>(f64::NAN as u64, 0);
assert_eq::<u64>((-f64::NAN) as u64, 0);
assert_eq::<u64>(-f64::NAN as u64, 0);

// FIXME emscripten does not support i128
#[cfg(not(target_os = "emscripten"))]
@@ -350,12 +350,12 @@ fn casts() {
// int -> f32
assert_eq::<f32>(127i8 as f32, 127.0);
assert_eq::<f32>(2147483647i32 as f32, 2147483648.0);
assert_eq::<f32>((-2147483648i32) as f32, -2147483648.0);
assert_eq::<f32>(-2147483648i32 as f32, -2147483648.0);
assert_eq::<f32>(1234567890i32 as f32, /*0x1.26580cp+30*/ f32::from_bits(0x4e932c06));
assert_eq::<f32>(16777217i32 as f32, 16777216.0);
assert_eq::<f32>((-16777217i32) as f32, -16777216.0);
assert_eq::<f32>(-16777217i32 as f32, -16777216.0);
assert_eq::<f32>(16777219i32 as f32, 16777220.0);
assert_eq::<f32>((-16777219i32) as f32, -16777220.0);
assert_eq::<f32>(-16777219i32 as f32, -16777220.0);
assert_eq::<f32>(
0x7fffff4000000001i64 as f32,
/*0x1.fffffep+62*/ f32::from_bits(0x5effffff),
@@ -416,7 +416,7 @@ fn casts() {
/*0x1.fffffep+127*/ f64::from_bits(0x47efffffe0000000),
);
assert_eq::<f64>(
/*-0x1.fffffep+127*/ (-f32::from_bits(0x7f7fffff)) as f64,
/*-0x1.fffffep+127*/ -f32::from_bits(0x7f7fffff) as f64,
/*-0x1.fffffep+127*/ -f64::from_bits(0x47efffffe0000000),
);
assert_eq::<f64>(
@@ -435,7 +435,7 @@ fn casts() {
assert_eq::<u32>(((-0.0f64) as f32).to_bits(), (-0.0f32).to_bits());
assert_eq::<f32>(5.0f64 as f32, 5.0f32);
assert_eq::<f32>(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1) as f32, 0.0);
assert_eq::<f32>(/*-0x0.0000000000001p-1022*/ (-f64::from_bits(0x1)) as f32, -0.0);
assert_eq::<f32>(/*-0x0.0000000000001p-1022*/ -f64::from_bits(0x1) as f32, -0.0);
assert_eq::<f32>(
/*0x1.fffffe0000000p-127*/ f64::from_bits(0x380fffffe0000000) as f32,
/*0x1p-149*/ f32::from_bits(0x800000),
2 changes: 1 addition & 1 deletion tests/ui/traits/region-pointer-simple.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,6 @@ impl Foo for A {

pub fn main() {
let a = A { x: 3 };
let b = (&a) as &dyn Foo;
let b = &a as &dyn Foo;
assert_eq!(b.f(), 3);
}