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

Rust-dogme #632

Open
graydon opened this issue Feb 6, 2016 · 2 comments
Open

Rust-dogme #632

graydon opened this issue Feb 6, 2016 · 2 comments
Labels
S-needs-discussion Status: Needs further discussion before merging or work can be started

Comments

@graydon
Copy link

graydon commented Feb 6, 2016

In response to: https://llogiq.github.io/2016/02/05/hundred-sequel.html

Well, you asked for a followup! I guess I don't really know if lints are similar enough to restrictions to go in the same tool, which is why I phrased it in terms of a possibly-different tool. But I did want to at least broach the topic because people seem to pleased with clippy, and it's only exercising part of the intended purpose of the allow/warn/deny/forbid (AWDF?) system.

It's not just there to help you catch mistakes; it was also explicitly built as a way to restrict yourself (or .. your team) to subsets of the language. Like the difference between deny and forbid, or the application of those levels to specific modules scopes. These are part of the system so that you can make policy, at a relatively high level, about prohibited features in a project. My motivation/inspiration for this was always the set of restrictions you can pragma-into in the Ada language:

https://en.wikibooks.org/wiki/Ada_Programming/Pragmas/Restrictions

So I guess I'll leave this as a marker for that purpose, if anyone's interested. There are obviously multiple "levels" to doing this sort of thing -- strictly local analyses, intra-crate, or inter-crate come to mind! -- but even the local ones have some utility, and you can imagine approximating others even if the analysis isn't entirely sound. For example it'd be relatively easy to forbid dynamic dispatch locally, or operator overloading, or floating point, dynamic array indexing, explicit lifetimes, raw pointers, casting, destructors, recursion, panics, calls to particular lang items or intrinsics, marker traits, macros, mutability, statics, unsized types, target-dependent types ... I'm sure there are many others.

In contrast to lints, restrictions are not things that are "probably an error" when used; they're more things that you might, for peculiar and problem-specific reasons, feel disinclined to use. Even though they're perfectly good language features. You just might want to opt your project out of using them. Maybe they have too much performance variability at runtime, or require target-environment support you can't provide -- limited stack, no FPU, etc. -- or make your program harder to reason about, or make a 3rd party tool's analysis of your program harder, or simply seem distasteful to your team for some personal reason.

(I jokingly suggested calling such a tool rust-dogme, in reference to https://en.wikipedia.org/wiki/Dogme_95 ... which perhaps captures a more "artistic-purity" element of the idea also)

@llogiq
Copy link
Contributor

llogiq commented Feb 6, 2016

Thank you @graydon for following up on this. I too find the idea very exciting, especially in light of the interest of bringing Rust to embedded systems (where a restriction like static stack, no heap alloc may be very useful to ensure code keeps running).

We already have some lints that are explicitly not for errors, that are...opinionated to say the least. On the other hand, we've restricted ourselves to local analysis, because that's obviously the easiest to implement in the scope of a rustc lint, and as I wrote in my prior post, it gives us a lot of bang for a small buck. Sooner or later, we may find it useful to set our sights on bigger things and this may be one of them. Perhaps there may be value in some crate-wide restrictions, maybe in a #[no_std] environment.

@Manishearth Manishearth added the S-needs-discussion Status: Needs further discussion before merging or work can be started label Feb 7, 2016
@Manishearth
Copy link
Member

Thanks for articulating this!

It's not just there to help you catch mistakes; it was also explicitly built as a way to restrict yourself (or .. your team) to subsets of the language.

Ah, this is an interesting observation. We currently have a dichotomy of lints, there is the "clippy" group, which contains Warn/Deny lints which are both precise (i.e., few false positives) and clear-cut as far as recommending a style improvement goes. Then there is the "clippy_pedantic" group, containing lints which are Allow by default. These lints may be imprecise, or may represent style choices for which there is less consensus (e.g., whether or not match foo { something => {....}, _ => {...} } should be rewritten in if-let-else form.). The idea is that people finding interesting lints which they agree with here will turn them on; however we do want this group to be something one may want to turn on for the entire crate (and still get sensible suggestions). I have seen crates in the wild doing this (and clippy does it too).

On the other hand, as you said, "restrictions" are things which you probably don't want to just turn on all at once and magically get better code; rather they're something you will pick and choose carefully based on your needs. The in-built "ban all unsafe code" lint comes to mind, sort of. You gave a bunch more examples which make sense too. These don't fit into the current dichotomy.

Clippy wasn't intended to be a crate for things like this; the stated goal when it was created was to have lints which improve your code. However, I'm completely fine with having such lints in the codebase, as a separate lint group 😄. I already proposed somewhere else that we add a third "unstable_replacement" lint group which suggests stable replacements for unstable methods -- something which, similar to "restrictions", is not necessarily a net gain but people may want to use.

As far as local vs global analysis goes; I'd avoid context-sensitive or otherwise global analysis within clippy itself. A lint will always be run, regardless of the lint level (the lint level just can suppress the warnings), so things with a large performance impact would not be something I'd like to include by default in clippy (making the lint a cargo feature works, as does a separate crate).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-needs-discussion Status: Needs further discussion before merging or work can be started
Projects
None yet
Development

No branches or pull requests

3 participants