Skip to content
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

Rollup of 7 pull requests #128186

Merged
merged 17 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
de560c3
Implement `ambiguous_negative_literals` lint
Urgau Feb 20, 2024
c5e1a12
Remove unary neg from `clippy::precedence` lint
Urgau Feb 20, 2024
c31ff97
centralize turning asm flags into human readable names
folkertdev Jul 24, 2024
4b7a87d
use an allow list for allowed asm options in naked functions
folkertdev Jul 24, 2024
2c7ae38
std: unsafe-wrap gcc::rust_eh_personality and impl
workingjubilee Jul 24, 2024
c9cd4a6
std: update comments on gcc personality fn
workingjubilee Jul 24, 2024
40d132f
Make sure that args are compatible in resolve_associated_item
compiler-errors Jul 25, 2024
d004edf
Don't ICE if HIR and middle types disagree in borrowck error reporting
compiler-errors Jul 25, 2024
34819b7
Don't add crashes for misuses of intrinsics
compiler-errors Jul 25, 2024
17b4fbc
In connect timeout, read readiness of socket for vxworks. Check pollh…
Jul 25, 2024
ae71900
Rollup merge of #121364 - Urgau:unary_precedence, r=compiler-errors
matthiaskrgr Jul 25, 2024
d1070df
Rollup merge of #127300 - biabbas:fix_connect_timeout, r=tgross35
matthiaskrgr Jul 25, 2024
e76bb3f
Rollup merge of #128138 - folkertdev:asm-option-allowlist, r=lcnr
matthiaskrgr Jul 25, 2024
606c9fc
Rollup merge of #128158 - workingjubilee:unsafe-wrap-personality-gcc,…
matthiaskrgr Jul 25, 2024
5a853d0
Rollup merge of #128171 - compiler-errors:arg-compat, r=oli-obk
matthiaskrgr Jul 25, 2024
4cf4196
Rollup merge of #128172 - compiler-errors:non-self-arg, r=chenyukang
matthiaskrgr Jul 25, 2024
c98d704
Rollup merge of #128173 - compiler-errors:misused-intrinsics, r=oli-obk
matthiaskrgr Jul 25, 2024
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
5 changes: 5 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ lint_ambiguous_glob_reexport = ambiguous glob re-exports
.label_first_reexport = the name `{$name}` in the {$namespace} namespace is first re-exported here
.label_duplicate_reexport = but the name `{$name}` in the {$namespace} namespace is also re-exported here

lint_ambiguous_negative_literals = `-` has lower precedence than method calls, which might be unexpected
.example = e.g. `-4.abs()` equals `-4`; while `(-4).abs()` equals `4`
.negative_literal = add parentheses around the `-` and the literal to call the method on a negative literal
.current_behavior = add parentheses around the literal and the method call to keep the current behavior

lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
.addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses
.addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mod noop_method_call;
mod opaque_hidden_inferred_bound;
mod pass_by_value;
mod passes;
mod precedence;
mod ptr_nulls;
mod redundant_semicolon;
mod reference_casting;
Expand Down Expand Up @@ -111,6 +112,7 @@ use nonstandard_style::*;
use noop_method_call::*;
use opaque_hidden_inferred_bound::*;
use pass_by_value::*;
use precedence::*;
use ptr_nulls::*;
use redundant_semicolon::*;
use reference_casting::*;
Expand Down Expand Up @@ -174,6 +176,7 @@ early_lint_methods!(
RedundantSemicolons: RedundantSemicolons,
UnusedDocComment: UnusedDocComment,
Expr2024: Expr2024,
Precedence: Precedence,
]
]
);
Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,35 @@ pub struct NonLocalDefinitionsCargoUpdateNote {
pub crate_name: Symbol,
}

// precedence.rs
#[derive(LintDiagnostic)]
#[diag(lint_ambiguous_negative_literals)]
#[note(lint_example)]
pub struct AmbiguousNegativeLiteralsDiag {
#[subdiagnostic]
pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
#[subdiagnostic]
pub current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")]
pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
#[suggestion_part(code = "(")]
pub start_span: Span,
#[suggestion_part(code = ")")]
pub end_span: Span,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")]
pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
#[suggestion_part(code = "(")]
pub start_span: Span,
#[suggestion_part(code = ")")]
pub end_span: Span,
}

// pass_by_value.rs
#[derive(LintDiagnostic)]
#[diag(lint_pass_by_value)]
Expand Down
70 changes: 70 additions & 0 deletions compiler/rustc_lint/src/precedence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use rustc_ast::token::LitKind;
use rustc_ast::{Expr, ExprKind, MethodCall, UnOp};
use rustc_session::{declare_lint, declare_lint_pass};

use crate::lints::{
AmbiguousNegativeLiteralsCurrentBehaviorSuggestion, AmbiguousNegativeLiteralsDiag,
AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
};
use crate::{EarlyContext, EarlyLintPass, LintContext};

declare_lint! {
/// The `ambiguous_negative_literals` lint checks for cases that are
/// confusing between a negative literal and a negation that's not part
/// of the literal.
///
/// ### Example
///
/// ```rust,compile_fail
/// # #![allow(unused)]
/// -1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Method calls take precedence over unary precedence. Setting the
/// precedence explicitly makes the code clearer and avoid potential bugs.
pub AMBIGUOUS_NEGATIVE_LITERALS,
Deny,
"ambiguous negative literals operations",
report_in_external_macro
}

declare_lint_pass!(Precedence => [AMBIGUOUS_NEGATIVE_LITERALS]);

impl EarlyLintPass for Precedence {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
let ExprKind::Unary(UnOp::Neg, operand) = &expr.kind else {
return;
};

let mut arg = operand;
let mut at_least_one = false;
while let ExprKind::MethodCall(box MethodCall { receiver, .. }) = &arg.kind {
at_least_one = true;
arg = receiver;
}

if at_least_one
&& let ExprKind::Lit(lit) = &arg.kind
&& let LitKind::Integer | LitKind::Float = &lit.kind
{
cx.emit_span_lint(
AMBIGUOUS_NEGATIVE_LITERALS,
expr.span,
AmbiguousNegativeLiteralsDiag {
negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
start_span: expr.span.shrink_to_lo(),
end_span: arg.span.shrink_to_hi(),
},
current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
start_span: operand.span.shrink_to_lo(),
end_span: operand.span.shrink_to_hi(),
},
},
);
}
}
}
56 changes: 1 addition & 55 deletions src/tools/clippy/clippy_lints/src/precedence.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,17 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, MethodCall, UnOp};
use rustc_ast::token;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::source_map::Spanned;

const ALLOWED_ODD_FUNCTIONS: [&str; 14] = [
"asin",
"asinh",
"atan",
"atanh",
"cbrt",
"fract",
"round",
"signum",
"sin",
"sinh",
"tan",
"tanh",
"to_degrees",
"to_radians",
];

declare_clippy_lint! {
/// ### What it does
/// Checks for operations where precedence may be unclear
/// and suggests to add parentheses. Currently it catches the following:
/// * mixed usage of arithmetic and bit shifting/combining operators without
/// parentheses
/// * a "negative" numeric literal (which is really a unary `-` followed by a
/// numeric literal)
/// followed by a method call
///
/// ### Why is this bad?
/// Not everyone knows the precedence of those operators by
Expand All @@ -41,7 +20,6 @@ declare_clippy_lint! {
///
/// ### Example
/// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
/// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1
#[clippy::version = "pre 1.29.0"]
pub PRECEDENCE,
complexity,
Expand Down Expand Up @@ -104,38 +82,6 @@ impl EarlyLintPass for Precedence {
(false, false) => (),
}
}

if let ExprKind::Unary(UnOp::Neg, operand) = &expr.kind {
let mut arg = operand;

let mut all_odd = true;
while let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &arg.kind {
let seg_str = seg.ident.name.as_str();
all_odd &= ALLOWED_ODD_FUNCTIONS
.iter()
.any(|odd_function| **odd_function == *seg_str);
arg = receiver;
}

if !all_odd
&& let ExprKind::Lit(lit) = &arg.kind
&& let token::LitKind::Integer | token::LitKind::Float = &lit.kind
{
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
PRECEDENCE,
expr.span,
"unary minus has lower precedence than method call",
"consider adding parentheses to clarify your intent",
format!(
"-({})",
snippet_with_applicability(cx, operand.span, "..", &mut applicability)
),
applicability,
);
}
}
}
}

Expand Down
34 changes: 0 additions & 34 deletions src/tools/clippy/tests/ui/precedence.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,6 @@ fn main() {
1 ^ (1 - 1);
3 | (2 - 1);
3 & (5 - 2);
-(1i32.abs());
-(1f32.abs());

// These should not trigger an error
let _ = (-1i32).abs();
let _ = (-1f32).abs();
let _ = -(1i32).abs();
let _ = -(1f32).abs();
let _ = -(1i32.abs());
let _ = -(1f32.abs());

// Odd functions should not trigger an error
let _ = -1f64.asin();
let _ = -1f64.asinh();
let _ = -1f64.atan();
let _ = -1f64.atanh();
let _ = -1f64.cbrt();
let _ = -1f64.fract();
let _ = -1f64.round();
let _ = -1f64.signum();
let _ = -1f64.sin();
let _ = -1f64.sinh();
let _ = -1f64.tan();
let _ = -1f64.tanh();
let _ = -1f64.to_degrees();
let _ = -1f64.to_radians();

// Chains containing any non-odd function should trigger (issue #5924)
let _ = -(1.0_f64.cos().cos());
let _ = -(1.0_f64.cos().sin());
let _ = -(1.0_f64.sin().cos());

// Chains of odd functions shouldn't trigger
let _ = -1f64.sin().sin();

let b = 3;
trip!(b * 8);
Expand Down
34 changes: 0 additions & 34 deletions src/tools/clippy/tests/ui/precedence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,6 @@ fn main() {
1 ^ 1 - 1;
3 | 2 - 1;
3 & 5 - 2;
-1i32.abs();
-1f32.abs();

// These should not trigger an error
let _ = (-1i32).abs();
let _ = (-1f32).abs();
let _ = -(1i32).abs();
let _ = -(1f32).abs();
let _ = -(1i32.abs());
let _ = -(1f32.abs());

// Odd functions should not trigger an error
let _ = -1f64.asin();
let _ = -1f64.asinh();
let _ = -1f64.atan();
let _ = -1f64.atanh();
let _ = -1f64.cbrt();
let _ = -1f64.fract();
let _ = -1f64.round();
let _ = -1f64.signum();
let _ = -1f64.sin();
let _ = -1f64.sinh();
let _ = -1f64.tan();
let _ = -1f64.tanh();
let _ = -1f64.to_degrees();
let _ = -1f64.to_radians();

// Chains containing any non-odd function should trigger (issue #5924)
let _ = -1.0_f64.cos().cos();
let _ = -1.0_f64.cos().sin();
let _ = -1.0_f64.sin().cos();

// Chains of odd functions shouldn't trigger
let _ = -1f64.sin().sin();

let b = 3;
trip!(b * 8);
Expand Down
32 changes: 1 addition & 31 deletions src/tools/clippy/tests/ui/precedence.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,5 @@ error: operator precedence can trip the unwary
LL | 3 & 5 - 2;
| ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)`

error: unary minus has lower precedence than method call
--> tests/ui/precedence.rs:23:5
|
LL | -1i32.abs();
| ^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1i32.abs())`

error: unary minus has lower precedence than method call
--> tests/ui/precedence.rs:24:5
|
LL | -1f32.abs();
| ^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1f32.abs())`

error: unary minus has lower precedence than method call
--> tests/ui/precedence.rs:51:13
|
LL | let _ = -1.0_f64.cos().cos();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.cos().cos())`

error: unary minus has lower precedence than method call
--> tests/ui/precedence.rs:52:13
|
LL | let _ = -1.0_f64.cos().sin();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.cos().sin())`

error: unary minus has lower precedence than method call
--> tests/ui/precedence.rs:53:13
|
LL | let _ = -1.0_f64.sin().cos();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.sin().cos())`

error: aborting due to 12 previous errors
error: aborting due to 7 previous errors

2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/unnecessary_cast.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ mod fixable {

fn issue_9563() {
let _: f64 = (-8.0_f64).exp();
#[allow(clippy::precedence)]
#[allow(ambiguous_negative_literals)]
let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/unnecessary_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ mod fixable {

fn issue_9563() {
let _: f64 = (-8.0 as f64).exp();
#[allow(clippy::precedence)]
#[allow(ambiguous_negative_literals)]
let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
}

Expand Down
Loading