{"action":"created","issue":{"url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/879","repository_url":"https://api.github.com/repos/Manishearth/rust-clippy","labels_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/879/labels{/name}","comments_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/879/comments","events_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/879/events","html_url":"https://github.com/Manishearth/rust-clippy/issues/879","id":150944416,"number":879,"title":"Enforcing uniform \"use\" order per crate.","user":{"login":"regexident","id":138017,"avatar_url":"https://avatars.githubusercontent.com/u/138017?v=3","gravatar_id":"","url":"https://api.github.com/users/regexident","html_url":"https://github.com/regexident","followers_url":"https://api.github.com/users/regexident/followers","following_url":"https://api.github.com/users/regexident/following{/other_user}","gists_url":"https://api.github.com/users/regexident/gists{/gist_id}","starred_url":"https://api.github.com/users/regexident/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/regexident/subscriptions","organizations_url":"https://api.github.com/users/regexident/orgs","repos_url":"https://api.github.com/users/regexident/repos","events_url":"https://api.github.com/users/regexident/events{/privacy}","received_events_url":"https://api.github.com/users/regexident/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2016-04-25T18:24:48Z","updated_at":"2016-04-25T18:53:48Z","closed_at":null,"body":"When writing crates with lots of inner modules one ends up with a ton of `pub use …;` / `use …;` and `pub mod …;` / `mod …;` at the head of each file.\r\n\r\nWithout some automatic sanitizing this inevitably leads to inconsistencies in their ordering.\r\n\r\nI for one prefer to have them sorted in groups of:\r\n\r\n```rust\r\nextern crate thirdparty;\r\npub mod …;\r\nmod …;\r\npub use std::…;\r\npub use thirdparty::…;\r\npub use internal::…;\r\nuse std::…;\r\nuse thirdparty::…;\r\nuse internal::…;\r\n```\r\n\r\nI am aware that this is a very personal preference and thus plain wrong as a clippy lint (unless rust-lang starts \"enforcing\" a strict code style, at which point this behaviour would become part of rustc anyway).\r\n\r\nMy proposal thus is to add a lint that first scans all files of a crate and creates an ordering profile of the crate and then in a second phase emits warnings for all files that don't match the most common ordering in the crate.\r\n\r\nThis way we wouldn't need any config, nor would we enforce any specific pattern, but would instead derive the pattern from the existing crate files.\r\n\r\nI already have a simple (Markov-based) implementation of such a profile extractor that can be trained on sequences of (one sequence per file):\r\n\r\n```rust\r\nenum Statement {\r\n\tExtCrate,\r\n\tPubMod, PrivMod,\r\n\tPubStdUse, PubExtUse, PubOwnUse,\r\n\tPrivStdUse, PrivExtUse, PrivOwnUse,\r\n}\r\n```\r\n\r\nI'll need to be able to distinguish between paths from `std`, an `external crate` as well as my `own crate` in order to map them to `Statement`.\r\n\r\nCould you give me pointers as to which existing similar clippy lints or `rustc::lint` docs to look into?\r\n\r\n@llogiq, mind mentoring me on this one? 😉 "},"comment":{"url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/comments/214478440","html_url":"https://github.com/Manishearth/rust-clippy/issues/879#issuecomment-214478440","issue_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/879","id":214478440,"user":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"created_at":"2016-04-25T18:53:47Z","updated_at":"2016-04-25T18:53:47Z","body":"So the point is that while I'm okay with `allow` lints that the community doesn't agree with (as in, doesn't agree that it needs to be linted in the first place), I'm more wary of `allow` lints where there is at least one _conflicting_ option that the community likes to use.\r\n\r\nAdditionally, such lints (either kind) are more suited to a tool like rustfmt. Servo uses a python script for alphabetization and it's quite annoying to fix the errors. The output could be improved, but really all you need is a tool that auto-rewrites it, which is rustfmt. Rustfmt would need to store some information about the extern crate declarations for the semantic sort, but it's still duable."}}