profile
viewpoint
Philipp Krones flip1995 Karlsruhe, Germany

CryZe/crates.io 0

Source code for crates.io

flip1995/blog.rust-lang.org 0

The Rust Programming Language Blog

flip1995/book 0

The Rust Programming Language

flip1995/cargo 0

The Rust package manager

flip1995/chrono 0

Date and time library for Rust

flip1995/comprakt 0

the compiler

flip1995/comprakt-fuzz 0

A fuzzer for the MiniJava language

flip1995/core 0

Some boilerplate code used across the @actions-rs Actions

flip1995/crates.io 0

Source code for crates.io

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add lint 'ref_option_ref' #1377

+use crate::utils::{last_path_segment, snippet, span_lint_and_sugg};+use rustc_hir::{GenericArg, Mutability, Ty, TyKind};+use rustc_lint::{LateContext, LateLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++use if_chain::if_chain;+use rustc_errors::Applicability;++declare_clippy_lint! {+    /// **What it does:** Checks for usage of `&Option<&T>`.+    ///+    /// **Why is this bad?** Since `&` is Copy, it's useless to have a+    /// reference on `Option<&T>`.+    ///+    /// **Known problems:** It may be irrevelent to use this lint on+    /// public API code as it will make a breaking change to apply it.+    ///+    /// **Example:**+    ///+    /// ```rust,ignore+    /// let x: &Option<&u32> = &Some(&0u32);+    /// ```+    /// Use instead:+    /// ```rust,ignore+    /// let x: Option<&u32> = Some(&0u32);+    /// ```+    pub REF_OPTION_REF,+    style,
    pedantic,

We shouldn't have this lint warn-by-default, if it warns on public functions. This was one reason, why trivially_copy_pass_by_rev was downgraded.

dvermd

comment created time in 15 hours

PullRequestReviewEvent

pull request commentrust-lang/rust-clippy

Identical arguments on assert macro family

Awesome! Thanks for implementing this :)

ThibsG

comment created time in 16 hours

issue commentrust-lang/rust-clippy

CLIPPY_FLAGS to pass options to clippy/ enable disable lints via env vars

Can we close this issue now that RUSTFLAGS works? Or should we document this somewhere first?

matthiaskrgr

comment created time in 3 days

issue commentrust-lang/rust-clippy

Consider reinstating str_to_string and string_to_string

You won't have much luck finding those files, since the repo was at least restructured 2 times since then. You will have to reimplement those lints.

ndmitchell

comment created time in 3 days

issue commentrust-lang/rust-clippy

needless_collect: confusing suggestion & questionable transformation

Yeah sure, go ahead! If you have any questions, feel free to ask here, on Zulip or open a WIP PR.

roy-work

comment created time in 3 days

issue commentrust-lang/rust-clippy

Minimum supported version of Rust (MSVR) config and support

No, just the lints mentioned here. And then, we can iteratively add it to lints in the future, if a issue for them comes up.

mikerite

comment created time in 3 days

pull request commentrust-lang/rust-clippy

Suggest a compatible shell for setup-toolchain.sh

@bors r+

achris

comment created time in 3 days

push eventflip1995/rust-clippy

Tim Nielens

commit sha 07b2da884cda8103af50beb327723dec8204fc61

add lint less_concise_than_option_unwrap_or

view details

Tim Nielens

commit sha 9c9327980becadc15a68307705b3a06c28116ae1

manual-unwrap-or / rename files

view details

Tim Nielens

commit sha 6d4eeeabcda6d6d25738e1e8e2b64580daefc4b9

manual-unwrap-or / pr remarks

view details

Tim Nielens

commit sha fc846c37fcc720c4a5c2e2075102c1957433e703

manual_unwrap_or / use consts::constant_simple helper

view details

Tim Nielens

commit sha a8fb69f065a427f5d3fc7222b834cad9a2a7a712

manual-unwrap-or / more pr remarks

view details

Tim Nielens

commit sha 690a6a6c0eff1a3edeb5f4c2dcbf9994760c3184

manual-unwrap-or / remove unwrap_or_else suggestion due to ownership issues

view details

flip1995

commit sha 6d358d29b0eb4e6f21526ccfb29636dea20d8993

Update semver 0.10 -> 0.11

view details

bors

commit sha e351e5ca693d52abc63b3737ab2abeff0aef15ad

Auto merge of #6180 - flip1995:rustup, r=flip1995 Update semver 0.10 -> 0.11 r? `@ghost,` blocking CI changelog: none

view details

Eduardo Broto

commit sha 701c7e2fbac1f05064519f0800128ea92491689a

bump cargo_metadata version

view details

bors

commit sha 81890c541e2da0d22992237c78190379b7497bb4

Auto merge of #6184 - ebroto:bump_cargo_metadata, r=ebroto bump cargo_metadata version changelog: none r? `@ghost` (master broken)

view details

bors

commit sha 4e83a38618cb6160cf6a7297ed3413f434149242

Auto merge of #6123 - montrivo:less_concise_than, r=ebroto add lint manual_unwrap_or Implements partially #5923. changelog: add lint manual_unwrap_or

view details

Tim Nielens

commit sha 214061b90f9feb3b13679d30dd7b150c4bd418bb

rework use_self impl based on ty::Ty comparison

view details

Tim Nielens

commit sha 6bd4f78b81fd6ed527d6832b59a9f64ac87008cc

use_self - fix issue with `hir_ty_to_ty`

view details

flip1995

commit sha c9ac3ecac096629f48dc15fc0b970ba231e479c1

Rewrite use_self lint one more time This rewrite gets rid of complicated visitors, by using the lint infrastructure as much as possible

view details

flip1995

commit sha 0ffe7c2b12544ebb9ac6838614bdd20bef8b62c6

Update test files

view details

flip1995

commit sha 68d3892abb756469aebf8c1244cb6b83fe6e8ab7

Remove fixed FIXMEs from tests

view details

flip1995

commit sha 08280f611946c9f84a24c34a469348be2e6ee2f3

Add back one FIXME of a FN to the tests

view details

push time in 3 days

Pull request review commentrust-lang/rust-clippy

Improve a suggestion in `needless_collect` with many comments

 LL | |     indirect_contains.contains(&&5);    | help: Check if the original Iterator contains an element instead of collecting then checking    |-LL |      LL |     sample.iter().any(|x| x == &&5);+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++error: avoid using `collect()` when not needed+  --> $DIR/needless_collect_indirect.rs:21:5+   |+LL | /     let indirect_contains_with_comments = sample.iter().collect::<VecDeque<_>>();+LL | |     // This is some stuff,+LL | |     // to pretend that we have some more+LL | |     // code present here+...  |+LL | |     // deal.+LL | |     indirect_contains_with_comments.contains(&&5);+   | |____^+   |+help: Check if the original Iterator contains an element instead of collecting then checking    |+LL |     sample.iter().any(|x| x == &&5);+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Wait, doesn't this remove the comment when auto-applied?

giraffate

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add large_type_pass_by_value lint

 declare_clippy_lint! {     "functions taking small copyable arguments by reference" } +declare_clippy_lint! {+    /// **What it does:** Checks for functions taking arguments by value, where+    /// the argument type is not `Copy` (or an array) and large enough to be worth+    /// considering passing by reference.+    ///+    /// **Why is this bad?** Arguments passed by value might require a shallow copy,+    /// which can be expensive and can be easily improved with passing by reference.+    ///

I think it is fine for the other lint, because of auto-deref. But there is no auto-ref, so I would prevent this lint on pub functions.

cauebs

comment created time in 3 days

PullRequestReviewEvent

pull request commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

@bors retry (please?)

josephlr

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

[WIP] Hex bin digit grouping

 declare_clippy_lint! {     "integer literals with digits grouped inconsistently" } +declare_clippy_lint! {+    /// **What it does:** Warns if a hexadecimal or binary literal is not grouped
    /// **What it does:** Warns if a hexadecimal or binary literals are not grouped
cgm616

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add new lint for undropped ManuallyDrop values

+#![warn(clippy::undropped_manually_drops)]++struct S;++fn main() {+    let f = std::mem::drop;+    let g = std::mem::ManuallyDrop::drop;+    let mut manual1 = std::mem::ManuallyDrop::new(S);+    let mut manual2 = std::mem::ManuallyDrop::new(S);+    let mut manual3 = std::mem::ManuallyDrop::new(S);+    let mut manual4 = std::mem::ManuallyDrop::new(S);++    // These lines will not drop `S` and should be linted+    drop(std::mem::ManuallyDrop::new(S));+    drop(manual1);+    f(manual2);

Just add a FIXME here and write this in the Known Problems section. I don't think binding mem::drop and then using it is a common enough use case for us to take care of it.

cgm616

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

New lint: manual-range-contains

 impl<'tcx> LateLintPass<'tcx> for Ranges {     } } +fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, span: Span) {+    let combine_and = match op {+        BinOpKind::And | BinOpKind::BitAnd => true,+        BinOpKind::Or | BinOpKind::BitOr => false,+        _ => return,+    };+    // value, name, order (higher/lower), inclusiveness+    if let (Some((lval, lname, name_span, lval_span, lord, linc)), Some((rval, rname, _, rval_span, rord, rinc))) =+        (check_range_bounds(cx, l), check_range_bounds(cx, r))+    {+        // we only lint comparisons on the same name and with different+        // direction+        if lname != rname || lord == rord {+            return;+        }+        let ord = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(l), &lval, &rval);+        if combine_and && ord == Some(rord) {+            // order lower bound and upper bound+            let (l_span, u_span, l_inc, u_inc) = if rord == Ordering::Less {+                (lval_span, rval_span, linc, rinc)+            } else {+                (rval_span, lval_span, rinc, linc)+            };+            // we only lint inclusive lower bounds+            if !l_inc {+                return;+            }+            let (range_type, range_op) = if u_inc {+                ("RangeInclusive", "..=")+            } else {+                ("Range", "..")+            };+            span_lint_and_then(+                cx,+                MANUAL_RANGE_CONTAINS,+                span,+                &format!("manual `{}::contains` implementation", range_type),+                |diag| {+                    let mut applicability = Applicability::MachineApplicable;+                    let name = snippet_with_applicability(cx, name_span, "_", &mut applicability);+                    let lo = snippet_with_applicability(cx, l_span, "_", &mut applicability);+                    let hi = snippet_with_applicability(cx, u_span, "_", &mut applicability);+                    diag.span_suggestion(+                        span,+                        "use",+                        format!("({}{}{}).contains({})", lo, range_op, hi, name),+                        applicability,+                    );+                },+            );+        } else if !combine_and && ord == Some(lord) {+            // `!_.contains(_)`+            // order lower bound and upper bound+            let (l_span, u_span, l_inc, u_inc) = if lord == Ordering::Less {+                (lval_span, rval_span, linc, rinc)+            } else {+                (rval_span, lval_span, rinc, linc)+            };+            if l_inc {+                return;+            }+            let (range_type, range_op) = if u_inc {+                ("Range", "..")+            } else {+                ("RangeInclusive", "..=")+            };+            span_lint_and_then(+                cx,+                MANUAL_RANGE_CONTAINS,+                span,+                &format!("manual `!{}::contains` implementation", range_type),+                |diag| {+                    let mut applicability = Applicability::MachineApplicable;+                    let name = snippet_with_applicability(cx, name_span, "_", &mut applicability);+                    let lo = snippet_with_applicability(cx, l_span, "_", &mut applicability);+                    let hi = snippet_with_applicability(cx, u_span, "_", &mut applicability);+                    diag.span_suggestion(+                        span,+                        "use",+                        format!("!({}{}{}).contains({})", lo, range_op, hi, name),+                        applicability,+                    );+                },+            );+        }+    }+}++fn check_range_bounds(cx: &LateContext<'_>, ex: &Expr<'_>) -> Option<(Constant, Ident, Span, Span, Ordering, bool)> {+    if let ExprKind::Binary(ref op, ref l, ref r) = ex.kind {+        let (inclusive, ordering) = match op.node {+            BinOpKind::Gt => (false, Ordering::Greater),+            BinOpKind::Ge => (true, Ordering::Greater),+            BinOpKind::Lt => (false, Ordering::Less),+            BinOpKind::Le => (true, Ordering::Less),+            _ => return None,+        };+        if let Some(id) = match_ident(l) {+            if let Some((c, _)) = constant(cx, cx.typeck_results(), r) {+                return Some((c, id, l.span, r.span, ordering, inclusive));+            }+        } else if let Some(id) = match_ident(r) {+            if let Some((c, _)) = constant(cx, cx.typeck_results(), l) {+                return Some((c, id, r.span, l.span, ordering.reverse(), inclusive));+            }+        }+    }+    None+}++fn match_ident(e: &Expr<'_>) -> Option<Ident> {+    if let ExprKind::Path(ref qpath) = e.kind {+        if let Some(seg) = single_segment_path(qpath) {+            if seg.args.is_none() {+                return Some(seg.ident);+            }+        }+    }+    None+}++fn check_range_zip_with_len(cx: &LateContext<'_>, path: &PathSegment<'_>, args: &[Expr<'_>], span: Span) {+    let name = path.ident.as_str();+    if name == "zip" && args.len() == 2 {+        let iter = &args[0].kind;+        let zip_arg = &args[1];+        if_chain! {+            // `.iter()` call+            if let ExprKind::MethodCall(ref iter_path, _, ref iter_args, _) = *iter;+            if iter_path.ident.name == sym!(iter);+            // range expression in `.zip()` call: `0..x.len()`+            if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(zip_arg);+            if is_integer_const(cx, start, 0);+            // `.len()` call+            if let ExprKind::MethodCall(ref len_path, _, ref len_args, _) = end.kind;+            if len_path.ident.name == sym!(len) && len_args.len() == 1;+            // `.iter()` and `.len()` called on same `Path`+            if let ExprKind::Path(QPath::Resolved(_, ref iter_path)) = iter_args[0].kind;+            if let ExprKind::Path(QPath::Resolved(_, ref len_path)) = len_args[0].kind;+            if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments);+            then {+                span_lint(cx,+                RANGE_ZIP_WITH_LEN,+                span,+                &format!("it is more idiomatic to use `{}.iter().enumerate()`",+                    snippet(cx, iter_args[0].span, "_")));
                span_lint(
                    cx,
                    RANGE_ZIP_WITH_LEN,
                    span,
                    &format!("it is more idiomatic to use `{}.iter().enumerate()`", snippet(cx, iter_args[0].span, "_"))
                );
llogiq

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

New lint: manual-range-contains

 impl<'tcx> LateLintPass<'tcx> for Ranges {     } } +fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, span: Span) {+    let combine_and = match op {+        BinOpKind::And | BinOpKind::BitAnd => true,+        BinOpKind::Or | BinOpKind::BitOr => false,+        _ => return,+    };+    // value, name, order (higher/lower), inclusiveness+    if let (Some((lval, lname, name_span, lval_span, lord, linc)), Some((rval, rname, _, rval_span, rord, rinc))) =+        (check_range_bounds(cx, l), check_range_bounds(cx, r))+    {+        // we only lint comparisons on the same name and with different+        // direction+        if lname != rname || lord == rord {+            return;+        }+        let ord = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(l), &lval, &rval);+        if combine_and && ord == Some(rord) {+            // order lower bound and upper bound+            let (l_span, u_span, l_inc, u_inc) = if rord == Ordering::Less {+                (lval_span, rval_span, linc, rinc)+            } else {+                (rval_span, lval_span, rinc, linc)+            };+            // we only lint inclusive lower bounds+            if !l_inc {+                return;+            }+            let (range_type, range_op) = if u_inc {+                ("RangeInclusive", "..=")+            } else {+                ("Range", "..")+            };+            span_lint_and_then(+                cx,+                MANUAL_RANGE_CONTAINS,+                span,+                &format!("manual `{}::contains` implementation", range_type),+                |diag| {+                    let mut applicability = Applicability::MachineApplicable;+                    let name = snippet_with_applicability(cx, name_span, "_", &mut applicability);+                    let lo = snippet_with_applicability(cx, l_span, "_", &mut applicability);+                    let hi = snippet_with_applicability(cx, u_span, "_", &mut applicability);+                    diag.span_suggestion(+                        span,+                        "use",+                        format!("({}{}{}).contains({})", lo, range_op, hi, name),+                        applicability,+                    );+                },+            );+        } else if !combine_and && ord == Some(lord) {+            // `!_.contains(_)`+            // order lower bound and upper bound+            let (l_span, u_span, l_inc, u_inc) = if lord == Ordering::Less {+                (lval_span, rval_span, linc, rinc)+            } else {+                (rval_span, lval_span, rinc, linc)+            };+            if l_inc {+                return;+            }+            let (range_type, range_op) = if u_inc {+                ("Range", "..")+            } else {+                ("RangeInclusive", "..=")+            };+            span_lint_and_then(

You can use span_lint_and_sugg here. Same above.

llogiq

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

New lint: manual-range-contains

 fn no_panic_with_fake_range_types() {      let _ = Range { foo: 0 }; }++#[warn(clippy::manual_range_contains)]

Can you move those to a new test file and add // run-rustfix there please?

llogiq

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add lint 'ref_option_ref' #1377

+use crate::utils::{last_path_segment, match_def_path, paths, snippet, span_lint_and_sugg};+use rustc_hir::{GenericArg, Mutability, Ty, TyKind};+use rustc_lint::{LateContext, LateLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++use if_chain::if_chain;+use rustc_errors::Applicability;++declare_clippy_lint! {+    /// **What it does:** Checks for usage of `&Option<&T>`.+    ///+    /// **Why is this bad?** Since `&` is Copy, it's useless to have a+    /// reference on `Option<&T>`.+    ///+    /// **Known problems:** None.+    ///+    /// **Example:**+    ///+    /// ```rust,ignore+    /// // example code where clippy issues a warning+    /// let x: &Option<&u32> = &Some(&0u32);+    /// ```+    /// Use instead:+    /// ```rust,ignore+    /// // example code which does not raise clippy warning+    /// let x: Option<&u32> = Some(&0u32);+    /// ```+    pub REF_OPTION_REF,+    style,+    "use `Option<&T>` instead of `&Option<&T>`"+}++declare_lint_pass!(RefOptionRef => [REF_OPTION_REF]);++impl<'tcx> LateLintPass<'tcx> for RefOptionRef {+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {+        if_chain! {+            if let TyKind::Rptr(_, ref mut_ty) = ty.kind;+            if mut_ty.mutbl == Mutability::Not;+            if let TyKind::Path(ref qpath) = &mut_ty.ty.kind;+            let last = last_path_segment(qpath);+            if let Some(res) = last.res;+            if let Some(def_id) = res.opt_def_id();++            if match_def_path(cx, def_id, &paths::OPTION);
            if cx.tcx.is_diagnostic_item(sym!(option_type), def_id);
dvermd

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add lint 'ref_option_ref' #1377

+use crate::utils::{last_path_segment, match_def_path, paths, snippet, span_lint_and_sugg};+use rustc_hir::{GenericArg, Mutability, Ty, TyKind};+use rustc_lint::{LateContext, LateLintPass};+use rustc_session::{declare_lint_pass, declare_tool_lint};++use if_chain::if_chain;+use rustc_errors::Applicability;++declare_clippy_lint! {+    /// **What it does:** Checks for usage of `&Option<&T>`.+    ///+    /// **Why is this bad?** Since `&` is Copy, it's useless to have a+    /// reference on `Option<&T>`.+    ///+    /// **Known problems:** None.+    ///+    /// **Example:**+    ///+    /// ```rust,ignore+    /// // example code where clippy issues a warning+    /// let x: &Option<&u32> = &Some(&0u32);+    /// ```+    /// Use instead:+    /// ```rust,ignore+    /// // example code which does not raise clippy warning+    /// let x: Option<&u32> = Some(&0u32);
    /// let x: &Option<&u32> = &Some(&0u32);
    /// ```
    /// Use instead:
    /// ```rust,ignore
    /// let x: Option<&u32> = Some(&0u32);
dvermd

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add a case to `lint_search_is_some` to handle searching strings

 fn search_is_some() {                                    x < 0                                }                    ).is_some();--    // Check that we don't lint if the caller is not an `Iterator`.+    +    let s1 = String::from("hello world");+    let s2 = String::from("world");+    // Check caller `find()` is a &`static str case+    let _ = "hello world".find("world").is_some();+    let _ = "hello world".find(&s2).is_some();+    let _ = "hello world".find(&s2[2..]).is_some();+    // Check caller of `find()` is a String case+    let _ = s1.find("world").is_some();+    let _ = s1.find(&s2).is_some();+    let _ = s1.find(&s2[2..]).is_some();+    //  Check caller of `find()` is a slice of String case+    let _ = s1[2..].find("world").is_some();+    let _ = s1[2..].find(&s2).is_some();+    let _ = s1[2..].find(&s2[2..]).is_some();++    // Check that we don't lint if `find()` is called with+    // Pattern that is not a string+    let _ = s1.find(|c: char| c == 'o' || c == 'l').is_some();++    // Check that we don't lint if the caller is not an `Iterator` or string     let foo = IteratorFalsePositives { foo: 0 };     let _ = foo.find().is_some();     let _ = foo.position().is_some();

All the tests for the search_is_some lint please. GH doesn't let you comment on unchanged code ;)

rsulli55

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add lint for `&mut Mutex::lock`

+use crate::utils::{is_type_diagnostic_item, span_lint_and_sugg};+use if_chain::if_chain;+use rustc_errors::Applicability;+use rustc_hir::{Expr, ExprKind, Mutability};+use rustc_lint::{LateContext, LateLintPass};+use rustc_middle::ty;+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** Checks for `&mut Mutex::lock` calls+    ///+    /// **Why is this bad?** `Mutex::lock` is less efficient than+    /// calling `Mutex::get_mut`. In addition you also have a statically+    /// guarantee that the mutex isn't locked, instead of just a runtime+    /// guarantee.+    ///+    /// **Known problems:** None.+    ///+    /// **Example:**+    ///+    /// ```rust+    /// use std::sync::{Arc, Mutex};+    ///+    /// let mut value_rc = Arc::new(Mutex::new(42_u8));+    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();+    ///+    /// let mut value = value_mutex.lock().unwrap();+    /// *value += 1;+    /// ```+    /// Use instead:+    /// ```rust+    /// use std::sync::{Arc, Mutex};+    ///+    /// let mut value_rc = Arc::new(Mutex::new(42_u8));+    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();+    ///+    /// let value = value_mutex.get_mut().unwrap();+    /// *value += 1;+    /// ```+    pub MUT_MUTEX_LOCK,+    correctness,+    "`&mut Mutex::lock` does unnecessary locking"+}++declare_lint_pass!(MutMutexLock => [MUT_MUTEX_LOCK]);++impl<'tcx> LateLintPass<'tcx> for MutMutexLock {+    fn check_expr(&mut self, cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>) {+        if_chain! {+            if let ExprKind::MethodCall(path, method_span, args, _) = &ex.kind;+            if path.ident.name == sym!(lock);+            let ty = cx.typeck_results().expr_ty(&args[0]);+            if let ty::Ref(_, inner_ty, Mutability::Mut) = ty.kind();+            if is_type_diagnostic_item(cx, inner_ty, sym!(mutex_type));+            then {+                span_lint_and_sugg(+                    cx,+                    MUT_MUTEX_LOCK,+                    *method_span,+                    "calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",+                    "change this to",+                    "get_mut".to_owned(),+                    Applicability::MachineApplicable,

This is

                    Applicability::MaybeIncorrect,

since it may lead to compiler errors afterwards, because of the mutable borrow it introduces.

FrancisMurillo

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add lint for `&mut Mutex::lock`

+use crate::utils::{is_type_diagnostic_item, span_lint_and_sugg};+use if_chain::if_chain;+use rustc_errors::Applicability;+use rustc_hir::{Expr, ExprKind, Mutability};+use rustc_lint::{LateContext, LateLintPass};+use rustc_middle::ty;+use rustc_session::{declare_lint_pass, declare_tool_lint};++declare_clippy_lint! {+    /// **What it does:** Checks for `&mut Mutex::lock` calls+    ///+    /// **Why is this bad?** `Mutex::lock` is less efficient than+    /// calling `Mutex::get_mut`. In addition you also have a statically+    /// guarantee that the mutex isn't locked, instead of just a runtime+    /// guarantee.+    ///+    /// **Known problems:** None.+    ///+    /// **Example:**+    ///+    /// ```rust+    /// use std::sync::{Arc, Mutex};+    ///+    /// let mut value_rc = Arc::new(Mutex::new(42_u8));+    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();+    ///+    /// let mut value = value_mutex.lock().unwrap();+    /// *value += 1;+    /// ```+    /// Use instead:+    /// ```rust+    /// use std::sync::{Arc, Mutex};+    ///+    /// let mut value_rc = Arc::new(Mutex::new(42_u8));+    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();+    ///+    /// let value = value_mutex.get_mut().unwrap();+    /// *value += 1;+    /// ```+    pub MUT_MUTEX_LOCK,+    correctness,
    style,

I would only classify this as a style lint, rather than a correctness lint.

FrancisMurillo

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

pull request commentrust-lang/rust-clippy

Add lint: from_iter_instead_of_collect

Thanks! Only the dogfood error (https://github.com/rust-lang/rust-clippy/pull/6101#issuecomment-702277887) is now left to fix

pitiK3U

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add new lint `unnecessary_wrap`

+use crate::utils::{+    is_type_diagnostic_item, match_qpath, paths, return_ty, snippet, span_lint_and_then,+    visitors::find_all_ret_expressions,+};+use if_chain::if_chain;+use rustc_errors::Applicability;+use rustc_hir::intravisit::FnKind;+use rustc_hir::*;+use rustc_lint::{LateContext, LateLintPass};+use rustc_middle::ty::subst::GenericArgKind;+use rustc_session::{declare_lint_pass, declare_tool_lint};+use rustc_span::Span;++declare_clippy_lint! {+    /// **What it does:** Checks for private functions that only return `Ok` or `Some`.+    ///+    /// **Why is this bad?** It is not meaningful to wrap values when no `None` or `Err` is returned.+    ///+    /// **Known problems:** Since this lint changes function type signature, you may need to+    /// adjust some code at callee side.+    ///+    /// **Example:**+    ///+    /// ```rust+    /// fn get_cool_number(a: bool, b: bool) -> Option<i32> {+    ///     if a && b {+    ///         return Some(50);+    ///     }+    ///     if a {+    ///         Some(0)+    ///     } else {+    ///         Some(10)+    ///     }+    /// }+    /// ```+    /// Use instead:+    /// ```rust+    /// fn get_cool_number(a: bool, b: bool) -> i32 {+    ///     if a && b {+    ///         return 50;+    ///     }+    ///     if a {+    ///         0+    ///     } else {+    ///         10+    ///     }+    /// }+    /// ```+    pub UNNECESSARY_WRAP,+    complexity,+    "functions that only return `Ok` or `Some`"+}++declare_lint_pass!(UnnecessaryWrap => [UNNECESSARY_WRAP]);++impl<'tcx> LateLintPass<'tcx> for UnnecessaryWrap {+    fn check_fn(+        &mut self,+        cx: &LateContext<'tcx>,+        fn_kind: FnKind<'tcx>,+        fn_decl: &FnDecl<'tcx>,+        body: &Body<'tcx>,+        span: Span,+        hir_id: HirId,+    ) {+        if_chain! {+            if let FnKind::ItemFn(.., visibility, _) = fn_kind;+            if visibility.node.is_pub();+            then {+                return;+            }+        }++        let (return_type, path) = if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym!(option_type)) {

The call to return_ty panics in 106 tests when called on a closure. You could either just exclude closures from this lint with the FnKind or try to get the return type of the closure with cx.tcx.typeck_results().expr_ty(&body.value). Which should give you a ty::Closure(..) where you can get the return_ty from the SubstsRef with cx.tcx.erase_late_bound_regions(substs.as_closure().sig().output())

matsujika

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add new lint `unnecessary_wrap`

+use rustc_hir as hir;

Nah, don't revert the commit, we can do this here. The extra PR for the other visitors would still be appreciated though!

matsujika

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add lint for holding RefCell Ref across an await

 fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {         || match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)         || match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD) }++declare_clippy_lint! {

NIT: usually lint declarations are on top of the file

Daniel-B-Smith

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add lint for holding RefCell Ref across an await

 fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {         || match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)         || match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD) }++declare_clippy_lint! {+    /// **What it does:** Checks for calls to await while holding a+    /// `RefCell` `Ref` or `RefMut`.+    ///+    /// **Why is this bad?** `RefCell` refs only check for exclusive mutable access+    /// at runtime. Holding onto a `RefCell` ref across an `await` suspension point+    /// risks panics from a mutable ref shared while other refs are outstanding.+    ///+    /// **Known problems:** None.+    ///+    /// **Example:**+    ///+    /// ```rust,ignore+    /// use std::cell::RefCell;+    ///+    /// async fn foo(x: &RefCell<u32>) {+    ///   let b = x.borrow_mut()();+    ///   *ref += 1;+    ///   bar.await;+    /// }+    /// ```+    ///+    /// Use instead:+    /// ```rust,ignore+    /// use std::cell::RefCell;+    ///+    /// async fn foo(x: &RefCell<u32>) {+    ///   {+    ///     let b = x.borrow_mut();+    ///     *ref += 1;+    ///   }+    ///   bar.await;+    /// }+    /// ```+    pub AWAIT_HOLDING_REFCELL_REF,+    pedantic,+    "Inside an async function, holding a RefCell ref while calling await"+}++declare_lint_pass!(AwaitHoldingRefCellRef => [AWAIT_HOLDING_REFCELL_REF]);++impl LateLintPass<'_> for AwaitHoldingRefCellRef {+    fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {+        use AsyncGeneratorKind::{Block, Closure, Fn};+        if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {+            let body_id = BodyId {+                hir_id: body.value.hir_id,+            };+            let def_id = cx.tcx.hir().body_owner_def_id(body_id);+            let typeck_results = cx.tcx.typeck(def_id);

this is exactly the same code as in line 55. You can just combine the two lint passes.

Daniel-B-Smith

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add lint for holding RefCell Ref across an await

 LL | | }    | |_^  error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.-  --> $DIR/await_holding_invalid.rs:41:13+  --> $DIR/await_holding_invalid.rs:42:13    | LL |         let guard = x.lock().unwrap();    |             ^^^^^    | note: these are all the await points this lock is held through-  --> $DIR/await_holding_invalid.rs:41:9+  --> $DIR/await_holding_invalid.rs:42:9    | LL | /         let guard = x.lock().unwrap(); LL | |         baz().await LL | |     };    | |_____^  error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.-  --> $DIR/await_holding_invalid.rs:53:13+  --> $DIR/await_holding_invalid.rs:54:13    | LL |         let guard = x.lock().unwrap();    |             ^^^^^    | note: these are all the await points this lock is held through-  --> $DIR/await_holding_invalid.rs:53:9+  --> $DIR/await_holding_invalid.rs:54:9    | LL | /         let guard = x.lock().unwrap(); LL | |         baz().await LL | |     }    | |_____^ -error: aborting due to 4 previous errors+error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await.

It would be nice to keep the tests separated.

Daniel-B-Smith

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Add linter for a single element for loop

+// Tests from for_loop.rs that don't have suggestions
// run-rustfix
// Tests from for_loop.rs that don't have suggestions
patrickelectric

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add linter for a single element for loop

 fn check_for_loop_over_map_kv<'tcx>(     } } +fn check_for_single_element_loop<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>) {+    if_chain! {+        if let ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) = arg.kind;+        if let PatKind::Binding(.., target, _) = pat.kind;+        if let ExprKind::Array(ref expr_list) = expr.kind;+        if expr_list.len() == 1;+        if let ExprKind::Path(ref list_item) = expr_list[0].kind;+        if let Some(list_tem_name) = single_segment_path(list_item).map(|ps| ps.ident.name);++        then {+            span_lint_and_sugg(+                cx,+                SINGLE_ELEMENT_LOOP,+                expr.span,

You should use the span from the start of the for loop to the end of expr. You can do this, by also passing the expr from the check_for_loop function and then use the span for_expr.span.with_hi(expr.span.hi()).

patrickelectric

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add linter for a single element for loop

 fn check_for_loop_over_map_kv<'tcx>(     } } +fn check_for_single_element_loop<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>) {+    if_chain! {+        if let ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) = arg.kind;+        if let PatKind::Binding(.., target, _) = pat.kind;+        if let ExprKind::Array(ref expr_list) = expr.kind;+        if expr_list.len() == 1;+        if let ExprKind::Path(ref list_item) = expr_list[0].kind;+        if let Some(list_tem_name) = single_segment_path(list_item).map(|ps| ps.ident.name);++        then {+            span_lint_and_sugg(+                cx,+                SINGLE_ELEMENT_LOOP,+                expr.span,+                "do not iterate over a single element array",+                "try",
                "`for` loop over a single element",
                "try",
patrickelectric

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add linter for a single element for loop

 fn check_for_loop_over_map_kv<'tcx>(     } } +fn check_for_single_element_loop<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>) {+    if_chain! {+        if let ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) = arg.kind;+        if let PatKind::Binding(.., target, _) = pat.kind;+        if let ExprKind::Array(ref expr_list) = expr.kind;+        if expr_list.len() == 1;+        if let ExprKind::Path(ref list_item) = expr_list[0].kind;
        if let [expr] = expr_list; // or a more fitting name than "expr"
        if let ExprKind::Path(ref list_item) = expr.kind;
patrickelectric

comment created time in 3 days

Pull request review commentrust-lang/rust-clippy

Add linter for a single element for loop

 fn check_for_loop_over_map_kv<'tcx>(     } } +fn check_for_single_element_loop<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>) {+    if_chain! {+        if let ExprKind::AddrOf(BorrowKind::Ref, _, ref expr) = arg.kind;+        if let PatKind::Binding(.., target, _) = pat.kind;+        if let ExprKind::Array(ref expr_list) = expr.kind;+        if expr_list.len() == 1;+        if let ExprKind::Path(ref list_item) = expr_list[0].kind;+        if let Some(list_tem_name) = single_segment_path(list_item).map(|ps| ps.ident.name);
        if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name);
patrickelectric

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

[WIP] Rework use_self impl based on ty::Ty comparison #3410 | Take 2

 declare_clippy_lint! {     "unnecessary structure name repetition whereas `Self` is applicable" } -declare_lint_pass!(UseSelf => [USE_SELF]);+#[derive(Default)]+pub struct UseSelf {+    stack: Vec<StackItem>,+    types_to_skip: Vec<HirId>,+    types_to_lint: Vec<HirId>,+}++#[derive(Debug, PartialEq, Eq, Copy, Clone)]+enum StackItem {+    Check {+        hir_id: HirId,+        impl_trait_ref_def_id: Option<LocalDefId>,+    },+    NoCheck,+}++impl_lint_pass!(UseSelf => [USE_SELF]);  const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element"; +impl<'tcx> LateLintPass<'tcx> for UseSelf {+    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {+        // We push the self types of `impl`s on a stack here. Only the top type on the stack is+        // relevant for linting, since this is the self type of the `impl` we're currently in. To+        // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that+        // we're in an `impl` or nested item, that we don't want to lint+        //+        // NB: If you push something on the stack in this method, remember to also pop it in the+        // `check_item_post` method.+        use ItemKind::{Const, Enum, Fn, Impl, Static, Struct, Trait, Union};+        match &item.kind {+            Impl {+                self_ty: hir_self_ty,+                of_trait,+                ..+            } => {+                let should_check = if let TyKind::Path(QPath::Resolved(_, ref item_path)) = hir_self_ty.kind {+                    let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;+                    parameters.as_ref().map_or(true, |params| {+                        !params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))+                    })+                } else {+                    false+                };+                let impl_trait_ref_def_id = of_trait.as_ref().map(|_| cx.tcx.hir().local_def_id(item.hir_id));+                if should_check {+                    self.stack.push(StackItem::Check {+                        hir_id: hir_self_ty.hir_id,+                        impl_trait_ref_def_id,+                    });+                } else {+                    self.stack.push(StackItem::NoCheck);+                }+            },+            Static(..) | Const(..) | Fn(..) | Enum(..) | Struct(..) | Union(..) | Trait(..) => {+                self.stack.push(StackItem::NoCheck);+            },+            _ => (),+        }+    }++    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {+        use ItemKind::{Const, Enum, Fn, Impl, Static, Struct, Trait, Union};+        match item.kind {+            Impl { .. } | Static(..) | Const(..) | Fn(..) | Enum(..) | Struct(..) | Union(..) | Trait(..) => {+                self.stack.pop();+            },+            _ => (),+        }+    }++    fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {+        // We want to skip types in trait `impl`s that aren't declared as `Self` in the trait+        // declaration. The collection of those types is all this method implementation does.+        if_chain! {+            if let ImplItemKind::Fn(FnSig { decl, .. }, ..) = impl_item.kind;+            if let Some(StackItem::Check { impl_trait_ref_def_id: Some(def_id), .. }) = self.stack.last().copied();+            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(def_id);+            then {+                // `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be+                // `Self`.+                let self_ty = impl_trait_ref.self_ty();++                // `trait_method_sig` is the signature of the function, how it is declared in the+                // trait, not in the impl of the trait.+                let trait_method = cx+                    .tcx+                    .associated_items(impl_trait_ref.def_id)+                    .find_by_name_and_kind(cx.tcx, impl_item.ident, AssocKind::Fn, impl_trait_ref.def_id)+                    .expect("impl method matches a trait method");+                let trait_method_sig = cx.tcx.fn_sig(trait_method.def_id);+                let trait_method_sig = cx.tcx.erase_late_bound_regions(&trait_method_sig);++                // `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the+                // implementation of the trait.+                let output_hir_ty = if let FnRetTy::Return(ty) = &decl.output {+                    Some(&**ty)+                } else {+                    None+                };+                let impl_inputs_outputs = decl.inputs.iter().chain(output_hir_ty);++                // `impl_hir_ty` (of type `hir::Ty`) represents the type written in the signature.+                //+                // `trait_sem_ty` (of type `ty::Ty`) is the semantic type for the signature in the+                // trait declaration. This is used to check if `Self` was used in the trait+                // declaration.+                //+                // If `any`where in the `trait_sem_ty` the `self_ty` was used verbatim (as opposed+                // to `Self`), we want to skip linting that type and all subtypes of it. This+                // avoids suggestions to e.g. replace `Vec<u8>` with `Vec<Self>`, in an `impl Trait+                // for u8`, when the trait always uses `Vec<u8>`.+                //+                // See also https://github.com/rust-lang/rust-clippy/issues/2894.+                for (impl_hir_ty, trait_sem_ty) in impl_inputs_outputs.zip(trait_method_sig.inputs_and_output) {+                    if trait_sem_ty.walk().any(|inner| inner == self_ty.into()) {+                        let mut visitor = SkipTyCollector::default();+                        visitor.visit_ty(&impl_hir_ty);+                        self.types_to_skip.extend(visitor.types_to_skip);+                    }+                }+            }+        }+    }++    fn check_impl_item_post(&mut self, _: &LateContext<'_>, _: &hir::ImplItem<'_>) {+        self.types_to_skip.clear();+    }++    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) {+        // `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies+        // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.

I discovered it randomly by searching for hir_ty_to_ty in rustc. This is used like that in rustc_privacy. https://github.com/rust-lang/rust/blob/8850893d96252172700727fe9e746c8e1ebd5853/compiler/rustc_privacy/src/lib.rs#L1246-L1258

flip1995

comment created time in 4 days

PullRequestReviewEvent

pull request commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

@bors retry

josephlr

comment created time in 4 days

pull request commentrust-lang/rust-clippy

Update semver 0.10 -> 0.11

@bors r+ p=1

flip1995

comment created time in 4 days

PR opened rust-lang/rust-clippy

Update semver 0.10 -> 0.11

r? @ghost, blocking CI

changelog: none

+2 -2

0 comment

2 changed files

pr created time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha 6d358d29b0eb4e6f21526ccfb29636dea20d8993

Update semver 0.10 -> 0.11

view details

push time in 4 days

push eventflip1995/rust-clippy

Darshan Kathiriya

commit sha 1385eb9b5562ec78f772341e1ad5c3d2f5443141

Replace run_compiler with RunCompiler builder pattern. RunCompiler::new takes non-optional params, and optional params can be set using set_*field_name* method. finally `run` will forward all fields to `run_compiler`.

view details

flip1995

commit sha fbf2430f0279adb8132efe60b16f8dd7b6a2acb3

Merge commit '2f6439ae6a6803d030cceb3ee14c9150e91b328b' into clippyup

view details

hosseind75

commit sha ecd308ec394f9d01b4392ee0315ea64d52ab7caa

ICEs should print the top of the query stack

view details

hosseind75

commit sha a9053e4baf251f53d8d6b95cd3f5b8a829ad0ba6

run full query stack print just when RUST_BACKTRACE is set

view details

hosseind75

commit sha 49bc85e947ab7ca793c14b6f3af4a8e9d8db0337

fix clippy custom_ice_message test

view details

hosseind75

commit sha 7f07577e6f873f4a1b3428d29bf520189f4ef79e

add new line

view details

hosseind75

commit sha 3c94914f0c87ba00987e515063dcc9e079a8918d

rebase with master

view details

Jonas Schievink

commit sha 117877745738f21e851686efe57a09e14606dadc

Refactor how SwitchInt stores jump targets

view details

bors

commit sha 29cff6feffd9da569fe3aa171d10db2647bf86c9

Auto merge of #77649 - dash2507:replace_run_compiler, r=matthewjasper Replace run_compiler with RunCompiler builder pattern Fixes #77286. Replaces rustc_driver:run_compiler with RunCompiler builder pattern.

view details

bors

commit sha bf947fcba226a7ec0964bb6be17237e54e04ccdb

Auto merge of #77796 - jonas-schievink:switchint-refactor, r=oli-obk Refactor how SwitchInt stores jump targets Closes https://github.com/rust-lang/rust/issues/65693

view details

hosseind88

commit sha ab0fc477b8b83cb14c584aca281b16fb5cce4c1a

fix stderr file of clippy/custom_ice_message test

view details

est31

commit sha 2c1e8cfc622652ebfb1f0256aa8d2afae91bf416

Remove rustc_session::config::Config The wrapper type led to tons of target.target across the compiler. Its ptr_width field isn't required any more, as target_pointer_width is already present in parsed form.

view details

Dylan DPC

commit sha d2feccc1efcbeff9dfb99daa754b8b47cdac7eaf

Rollup merge of #77493 - hosseind88:ICEs_should_always_print_the_top_of_the_query_stack, r=oli-obk ICEs should always print the top of the query stack see #76920

view details

push time in 4 days

push eventflip1995/rust-clippy

rail

commit sha dc89bb1135afc31fc9ee2272e627192c04354d22

Use if_chain in Increment/InitializeVisitor

view details

rail

commit sha 116f30dc33d9e3744f257f2f7f5467acfbff178b

Use else blocks instead of return statements in Increment/InitializeVisitor

view details

rail

commit sha b2d5b89a1de15df9052fdf44d01b174add82837f

Check if it's after the loop earlier

view details

rail

commit sha 31cb1109648bf4242cab47571343578244e7fb9d

add concinient methods to Increment/InitializeVisitor

view details

rail

commit sha c599e2fcfaaedb12b560f4136bab3d0b450acf8f

Split VarState

view details

rail

commit sha 13c207d3756754c54a6b20d852087616d5abfbf4

Generalise `InitializeVisitor`

view details

rail

commit sha 9573a0d378033a81e55ca834a5d305d3cf2be24d

Rename variables

view details

rail

commit sha 1026b42f0694eb9239b5cebe80be743d5ded0da5

Rename a struct and variables

view details

rail

commit sha b4b4da162f19e9a4c63854a2b5a6167b83f9d8b9

Introduce Start and StartKind

view details

rail

commit sha 720f19f2ec4282f636889b35beabf31272e3b1b2

Implement detecting `manual_memcpy` with loop counters

view details

rail

commit sha de56279cd9047832216e1d1c06dc45375bf01b31

Implement building the `manual_memcpy` sugggestion with loop counters

view details

rail

commit sha 8da6cfd17b7707d678d01a6688572169015ea83e

fmt

view details

rail

commit sha d9a88be0b05c2cfec0679caf428d129c9d46256d

Rename `get_offset` and its private items

view details

rail

commit sha 774e82a566c6c3349700a8bece44d6a8c6755039

Add the tests for `manual_memcpy` with loop counters

view details

rail

commit sha 9aad38bf614c3fb6d306f5dec4a0af606bb3c9c8

Update `manual_memcpy.stderr` to reflect additional parentheses

view details

rail

commit sha 4ea4a972500a8ddecfc737d51eec960324dcb02f

Add tests for bitwise operations

view details

rail

commit sha eb3ffe6ed2999e9d3385be0ff981e30082ea0d2c

make use of macros in operator overloading

view details

rail

commit sha 10d7a18f72155f03dbd27b872a52b5dd45def8db

fmt

view details

rail

commit sha 174065fc98ef9335ea45a234aa18286cdf6c3934

fix the multiple counters test

view details

rail

commit sha 44187383f4724bd7e4b2b220235e93438043947a

Use operator overloading instead of direct calls of `make_binop`

view details

push time in 4 days

PR closed rust-lang/rust-clippy

rework use_self impl based on ty::Ty comparison #3410 P-help-wanted S-waiting-on-review

use_self lint refactoring. As suggested by @eddyb , implement the lint based on ty::Ty comparison instead of hir::Path checks.

This PR introduces negative regressions. The cases were covered in the previous implementation. See the test file.

It fixes #3410, #2843, #3859, #4734 and #4140. Should fix #4143 (example doesn't compile). #4305 false positive seems also fixed but the uitest fails to compile the unmodified test case in use_self.rs.fixed. Implements #5078. Generally the implementation checks are done at mir level and offers higher guarantees against false positives. It is probably fixing other unreported false positives.

changelog: fix use_self generics false positives

+701 -351

7 comments

6 changed files

montrivo

pr closed time in 4 days

pull request commentrust-lang/rust-clippy

rework use_self impl based on ty::Ty comparison #3410

Closing in favor of #6179.

@montrivo Your commits will of course be merged, so your work will not get thrown away.

The only issue left to fix is now #4140. I would be happy to work this out together with you in #6179. If you want to work on my branch, I can give you push access to my fork.

montrivo

comment created time in 4 days

PR opened rust-lang/rust-clippy

[WIP] Rework use_self impl based on ty::Ty comparison #3410 | Take 2

This builds on top of #5531

I already reviewed and approved the commits by @montrivo. So only the review of my commits should be necessary.

I would also appreciate your review @montrivo, since you are familiar with the challenges here.

Fixes #3410 and Fixes #4143 (same problem) Fixes #2843 Fixes #3859 Fixes #4734 Fixes #4305 Fixes #5078 (even at expression level now 🎉)

Not yet: #4140 (test added)

All the credit for the fixes goes to @montrivo. I only refactored and copy and pasted his code.

changelog: none

+812 -214

0 comment

8 changed files

pr created time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha 5892c82bb762b3e0450075ea0d32f41d51b7ad6c

Remove fixed FIXMEs from tests

view details

flip1995

commit sha f074bebf8e30ce0ee97b06c9e805e43f920482e1

Add back one FIXME of a FN to the tests

view details

push time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha 91722217832c6eaa9c63f91085a549f0a52aa430

Add back one FIXME of a FN to the tests

view details

push time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha e79a1b735f0b9d806d7c95f3721995b65e488ff5

Rewrite use_self lint one more time This rewrite gets rid of complicated visitors, by using the lint infrastructure as much as possible

view details

flip1995

commit sha b6c8439e726c3ca154e6e5e1e07b953bd86f0dca

Update test files

view details

flip1995

commit sha 10538312fe00719740db568b46610cc145d59ef5

Remove fixed FIXMEs from tests

view details

push time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha 9f321e75b1edf419d454fa8fc1de57a8e922c176

WIP

view details

push time in 4 days

pull request commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

@bors r+

Thanks!

josephlr

comment created time in 4 days

issue commentrust-lang/rust-clippy

git subtree crashes: can't sync rustc clippy changes into rust-lang/rust-clippy

Only the first time. Once it is cached, it is a matter of seconds. Still not optimal though.

matthiaskrgr

comment created time in 4 days

push eventflip1995/rust-clippy

flip1995

commit sha e5e19f1f93914547aa466872a6896a55726a90e8

WIP

view details

push time in 5 days

create barnchflip1995/rust-clippy

branch : rewrite_use_self

created branch time in 5 days

issue commentrust-lang/rust

Uplift `declare_interior_mutable_const` and `borrow_interior_mutable_const` from clippy to rustc

I don't think this lint is ready to get uplifted, because it has too many FPs. I will do a review round in Clippy tomorrow and also take a look at rust-lang/rust-clippy#6110. If my opinion about that changes with rust-lang/rust-clippy#6110 merged, I'll write that here.

That being said, a FP free version of this lint would definitely be great in rustc.

jyn514

comment created time in 5 days

pull request commentrust-lang/rust-clippy

rework use_self impl based on ty::Ty comparison #3410

So my idea to rewrite this and removing the visitors seems to work. My rewrite is at the state, that it fixed all the FIXMEs that you added. Now I have to fix some FPs I didn't yet address in my prototype rewrite.

montrivo

comment created time in 5 days

Pull request review commentrust-lang/rust-clippy

rework use_self impl based on ty::Ty comparison #3410

 impl<'a, 'tcx> Visitor<'tcx> for ImplVisitor<'a, 'tcx> {     } } +struct FnSigVisitor<'a, 'tcx> {+    cx: &'a LateContext<'tcx>,+    self_ty: Ty<'tcx>,+}++impl<'a, 'tcx> Visitor<'tcx> for FnSigVisitor<'a, 'tcx> {+    type Map = Map<'tcx>;++    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {+        NestedVisitorMap::None+    }++    fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {+        if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind {+            match path.res {+                def::Res::SelfTy(..) => {},+                _ => {+                    match self.cx.tcx.hir().find(self.cx.tcx.hir().get_parent_node(hir_ty.hir_id)) {+                        Some(Node::Expr(Expr {+                            kind: ExprKind::Path(QPath::TypeRelative(_, segment)),+                            ..+                        })) => {+                            // The following block correctly identifies applicable lint locations+                            // but `hir_ty_to_ty` calls cause odd ICEs.+                            //

Is this comment still applicable here?

montrivo

comment created time in 5 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can be miscompiled or 'optimized' out. Also, these busy loops+    /// burn CPU cycles without doing anything.     ///-    /// **Known problems:** None.+    /// It is _almost always_ a better idea to `panic!` than to have a busy loop.+    ///+    /// If panicking isn't possible, think of the environment and either:+    ///   - block on something+    ///   - sleep the thread for some microseconds+    ///   - yield or pause the thread+    ///+    /// For `std` targets, this can be done with+    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)+    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).+    ///+    /// For `no_std` targets, doing this is more complicated, especially because+    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will+    /// probably need to invoke some target-specific intrinsic. Examples include:+    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)+    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)+    ///+    /// If you just care about fixing the LLVM bug (and don't care about burning+    /// CPU), you can:+    ///   - On nightly, insert a non-`pure` `asm!` statement. For example:

I would still include the hint to -Zinsert-sideeffect

josephlr

comment created time in 5 days

PullRequestReviewEvent
PullRequestReviewEvent

issue commentapache/incubator-tvm

[VTA] Tutorial on how to deploy and execute model on device without RPC

Or to be more precise, you have to load your model like this:

import ctypes

import tvm
from tvm.contrib import graph_runtime as runtime

libvta_path = "/home/xilinx/tvm/build/libvta.so"
ctypes.CDLL(libvta_path, ctypes.RTLD_GLOBAL)

# load compiled model
with open("graph.json", "r") as graph_file:
    graph = graph_file.read()
with open("params.params", "rb") as params_file:
    params = bytearray(params_file.read())
lib = tvm.module.load("./lib.tar")

ctx = tvm.ext_dev(0)

module = runtime.create(graph, lib, ctx)
module.load_params(params)

After that module.run(**<input-dict>) should work

tmoreau89

comment created time in 5 days

issue commentapache/incubator-tvm

[VTA] Tutorial on how to deploy and execute model on device without RPC

Oh damn, I totally forgot about it. Basically you have to add those two lines to your python script, that runs your model on the PYNQ:

dll_path = "/home/xilinx/tvm/build/libvta.so"
ctypes.CDLL(dll_path, ctypes.RTLD_GLOBAL)

before the graph_runtime.create(..) command.

I hope this still works. I haven't used TVM/VTA for a long time now.

tmoreau89

comment created time in 5 days

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops+    /// burn CPU cycles without doing anything.     ///-    /// **Known problems:** None.+    /// It is _almost always_ a better idea to `panic!` than to have a busy loop.+    ///+    /// If panicking isn't possible, think of the environment and either:+    ///   - block on something+    ///   - sleep the thread for some microseconds+    ///   - yield or pause the thread+    ///+    /// For `std` targets, this can be done with+    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)+    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).+    ///+    /// For `no_std` targets, doing this is more complicated, especially because+    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will+    /// probably need to invoke some target-specific intrinsic. Examples include:+    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)+    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)+    ///+    /// If you just care about fixing the LLVM bug (and don't care about burning+    /// CPU), you can:+    ///   - On nightly, compile your code with `-Z insert-sideeffect`

The -Z flag is most certainly perma unstable, it may resurface under a -C flag

Oh yeah, -Z flags are of course perma unstable, oops. Time to sleep 🛌

josephlr

comment created time in 6 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops+    /// burn CPU cycles without doing anything.     ///-    /// **Known problems:** None.+    /// It is _almost always_ a better idea to `panic!` than to have a busy loop.+    ///+    /// If panicking isn't possible, think of the environment and either:+    ///   - block on something+    ///   - sleep the thread for some microseconds+    ///   - yield or pause the thread+    ///+    /// For `std` targets, this can be done with+    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)+    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).+    ///+    /// For `no_std` targets, doing this is more complicated, especially because+    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will+    /// probably need to invoke some target-specific intrinsic. Examples include:+    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)+    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)+    ///+    /// If you just care about fixing the LLVM bug (and don't care about burning+    /// CPU), you can:+    ///   - On nightly, compile your code with `-Z insert-sideeffect`

https://github.com/rust-lang/rfcs/pull/2843 / https://github.com/rust-lang/rust/issues/70173

Ah asm! should be reimplemented, so it can become stable sometime in the future. Alright, in that case we should suggest to use asm!

josephlr

comment created time in 6 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops+    /// burn CPU cycles without doing anything.     ///-    /// **Known problems:** None.+    /// It is _almost always_ a better idea to `panic!` than to have a busy loop.+    ///+    /// If panicking isn't possible, think of the environment and either:+    ///   - block on something+    ///   - sleep the thread for some microseconds+    ///   - yield or pause the thread+    ///+    /// For `std` targets, this can be done with+    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)+    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).+    ///+    /// For `no_std` targets, doing this is more complicated, especially because+    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will+    /// probably need to invoke some target-specific intrinsic. Examples include:+    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)+    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)+    ///+    /// If you just care about fixing the LLVM bug (and don't care about burning+    /// CPU), you can:+    ///   - On nightly, compile your code with `-Z insert-sideeffect`

Isn't asm! deprecated and got replaced with llvm_asm! or something?

-Zinsert-sideeffect isn't necessarily perma unstable and may become the default behavior sometime in the future, IIUC.

josephlr

comment created time in 6 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops

I'm good with both or a combination "can be miscompiled, producing undefined behavior"

josephlr

comment created time in 6 days

PullRequestReviewEvent

pull request commentactions-rs/install

Use GitHub Actions cache for installed binaries

@svartalf Can you take another look at actions-rs/core#125 in combination with 57e52b9 then, please?

flip1995

comment created time in 6 days

pull request commentrust-lang/rust-clippy

Identical arguments on assert macro family

2 things:

  1. (you already noticed that) This would greatly profit from #4694 being implemented first
  2. counter example: assert_ne!(my_special_iter.next(), my_special_iter.next()) could be a valid test for some iterator implementation on a type.
ThibsG

comment created time in 6 days

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops
    /// these expressions can produce undefined behavior (in release mode). Also, these busy loops
josephlr

comment created time in 6 days

Pull request review commentrust-lang/rust-clippy

Enable empty_loop for no_std crates.

 declare_clippy_lint! { declare_clippy_lint! {     /// **What it does:** Checks for empty `loop` expressions.     ///-    /// **Why is this bad?** Those busy loops burn CPU cycles without doing-    /// anything. Think of the environment and either block on something or at least-    /// make the thread sleep for some microseconds.+    /// **Why is this bad?** Due to [an LLVM codegen bug](https://github.com/rust-lang/rust/issues/28728)+    /// these expressions can produce undefined behavior. Also, these busy loops+    /// burn CPU cycles without doing anything.     ///-    /// **Known problems:** None.+    /// It is _almost always_ a better idea to `panic!` than to have a busy loop.+    ///+    /// If panicking isn't possible, think of the environment and either:+    ///   - block on something+    ///   - sleep the thread for some microseconds+    ///   - yield or pause the thread+    ///+    /// For `std` targets, this can be done with+    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)+    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).+    ///+    /// For `no_std` targets, doing this is more complicated, especially because+    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will+    /// probably need to invoke some target-specific intrinsic. Examples include:+    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)+    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)+    ///+    /// If you just care about fixing the LLVM bug (and don't care about burning+    /// CPU), you can:+    ///   - On nightly, compile your code with `-Z insert-sideeffect`

Should we also suggest the llvm_asm! version here for nightly? That way the user won't have to set any compiler flags and just has to change some code. Also the llvm_asm! version is a bit better than the read_volatile version, since it doesn't insert any code. (Even though the inserted code doesn't really make a difference performance wise or in any other way, since, as you stated, the program will be trapped in an infinite loop)

josephlr

comment created time in 6 days

PullRequestReviewEvent
PullRequestReviewEvent
PullRequestReviewEvent
more