Skip to content

Commit

Permalink
chore(lints): Introduce lints.rust table, warn for all allow-by-d…
Browse files Browse the repository at this point in the history
…efault & fix
  • Loading branch information
alexpovel committed Jul 28, 2024
1 parent 8b766d4 commit c2bcc27
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 44 deletions.
60 changes: 59 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,69 @@ complexity = "warn"
correctness = "warn"
nursery = "warn"
suspicious = "warn"

# Overrides
multiple_crate_versions = { level = "allow", priority = 1 }
module_name_repetitions = { level = "allow", priority = 1 }

[lints.rust]
# Just took everything at
# https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
# and made it more strict. Will perhaps get too annoying.

absolute_paths_not_starting_with_crate = "warn"
async-idents = "warn"
box_pointers = "allow" # Not useful nowadays
deprecated_safe = "warn"
disjoint-capture-migration = "warn"
elided-lifetime-in-path = "warn"
elided_lifetimes_in_paths = "warn"
explicit_outlives_requirements = "warn"
ffi_unwind_calls = "warn"
# fuzzy_provenance_casts = "warn" # Unstable
# impl_trait_overcaptures = "warn" # Unstable
keyword-idents = "warn"
keyword_idents_2018 = "warn"
keyword_idents_2024 = "warn"
let_underscore_drop = "warn"
# lossy_provenance_casts = "warn" # Unstable
macro_use_extern_crate = "warn"
meta_variable_misuse = "warn"
missing_abi = "warn"
missing_copy_implementations = "warn"
missing_debug_implementations = "warn"
missing_docs = "warn"
missing_unsafe_on_extern = "warn"
# multiple_supertrait_upcastable = "warn" # Unstable
# must_not_suspend = "warn" # Unstable
non_ascii_idents = "warn"
# non_exhaustive_omitted_patterns = "warn" # Unstable
non_local_definitions = "warn"
or-patterns-back-compat = "warn"
redundant_lifetimes = "warn"
rust_2021_incompatible_closure_captures = "warn"
rust_2021_incompatible_or_patterns = "warn"
rust_2021_prefixes_incompatible_syntax = "warn"
rust_2021_prelude_collisions = "warn"
# rust_2024_incompatible_pat = "warn" # Unstable
single-use-lifetime = "warn"
single_use_lifetimes = "warn"
trivial_casts = "warn"
trivial_numeric_casts = "warn"
unit_bindings = "warn"
unnameable_types = "warn"
unreachable_pub = "allow" # Too noisy
unsafe_code = "warn"
unsafe_op_in_unsafe_fn = "warn"
unstable_features = "warn"
unused_crate_dependencies = "allow"
unused_extern_crates = "allow"
unused_import_braces = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"
unused_results = "allow" # Too noisy
variant_size_differences = "warn"

[profile.dev.package.insta]
# https://insta.rs/docs/quickstart/#optional-faster-runs
opt-level = 3
Expand Down
10 changes: 7 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ fn main() {
}

#[cfg(feature = "german")]
#[allow(unreachable_pub)] // Cannot get this to play nice with clippy
mod natural_languages {
use std::io::{BufReader, BufWriter};
use std::{
Expand All @@ -27,7 +28,10 @@ mod natural_languages {
// German
let source_file = base_source_path.join("de.txt");
let destination_file = base_destination_path.join("de.fst");
destination_file.parent().map(fs::create_dir_all);
destination_file
.parent()
.map(|p| fs::create_dir_all(p).expect("directory creation to succeed"))
.expect("parent directory to be present");

german::process(
&mut BufReader::new(File::open(&source_file).unwrap()),
Expand Down Expand Up @@ -63,7 +67,7 @@ mod natural_languages {
W: Write,
{
let mut contents = String::new();
source.read_to_string(&mut contents).unwrap();
let _ = source.read_to_string(&mut contents).unwrap();

let words: HashSet<&str> = time_it!(
"Constructing hashset of words",
Expand Down Expand Up @@ -113,7 +117,7 @@ mod natural_languages {
keepers.len(),
{
let mut path: std::path::PathBuf = env::var_os("OUT_DIR").unwrap().into();
path.pop(); // Remove "out"
assert!(path.pop(), "no parent element"); // Remove "out"
path.push("output"); // The log file
path
},
Expand Down
6 changes: 3 additions & 3 deletions src/actions/german/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ pub(super) struct StateMachine {
}

impl StateMachine {
pub fn new() -> Self {
pub(super) fn new() -> Self {
Self {
state: State::default(),
word: Word::default(),
transition: None,
}
}

pub const fn current_word(&self) -> &Word {
pub(super) const fn current_word(&self) -> &Word {
&self.word
}

Expand All @@ -71,7 +71,7 @@ impl StateMachine {
};
}

pub fn transition(&mut self, input: MachineInput) -> Transition {
pub(super) fn transition(&mut self, input: MachineInput) -> Transition {
self.pre_transition();

let next = match (&self.state, input) {
Expand Down
22 changes: 11 additions & 11 deletions src/actions/german/words.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use itertools::Itertools;
use std::{fmt::Display, ops::Range};

#[derive(Debug, PartialEq, Eq)]
pub enum WordCasing {
pub(super) enum WordCasing {
AllLowercase,
AllUppercase,
Titlecase,
Expand All @@ -11,7 +11,7 @@ pub enum WordCasing {

/// Error conditions when parsing a string into a `WordCasing`.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum WordCasingError {
pub(super) enum WordCasingError {
/// The string is empty.
EmptyString,
/// The string contains characters with undecidable casing.
Expand Down Expand Up @@ -124,31 +124,31 @@ pub(super) struct Replacement {

impl Word {
/// Clears the word's contents while retaining any allocated capacities.
pub fn clear(&mut self) {
pub(super) fn clear(&mut self) {
self.content.clear();
self.replacements.clear();
}

pub fn push(&mut self, character: char) {
pub(super) fn push(&mut self, character: char) {
self.content.push(character);
}

pub fn len(&self) -> usize {
pub(super) fn len(&self) -> usize {
self.content.len()
}

pub fn add_replacement(&mut self, start: usize, end: usize, content: SpecialCharacter) {
pub(super) fn add_replacement(&mut self, start: usize, end: usize, content: SpecialCharacter) {
self.replacements.push(Replacement {
span: Range { start, end },
content,
});
}

pub const fn replacements(&self) -> &Vec<Replacement> {
pub(super) const fn replacements(&self) -> &Vec<Replacement> {
&self.replacements
}

pub fn content(&self) -> &str {
pub(super) fn content(&self) -> &str {
&self.content
}
}
Expand All @@ -163,15 +163,15 @@ impl Default for Word {
}

impl Replacement {
pub const fn start(&self) -> usize {
pub(super) const fn start(&self) -> usize {
self.span.start
}

pub const fn end(&self) -> usize {
pub(super) const fn end(&self) -> usize {
self.span.end
}

pub const fn content(&self) -> &SpecialCharacter {
pub(super) const fn content(&self) -> &SpecialCharacter {
&self.content
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/actions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ mod deletion;
mod german;
mod lower;
mod normalization;
mod replace;
/// Replacing inputs.
pub mod replace;
mod style;
#[cfg(feature = "symbols")]
mod symbols;
Expand Down Expand Up @@ -45,7 +46,11 @@ pub trait Action: Send + Sync {
///
/// This is fallible, as the context is dynamically created at runtime and
/// potentially contains bad data. See docs of the [`Err`] variant type.
fn act_with_context(&self, input: &str, context: &ScopeContext) -> Result<String, ActionError> {
fn act_with_context(
&self,
input: &str,
context: &ScopeContext<'_>,
) -> Result<String, ActionError> {
let _ = context; // Mark variable as used
Ok(self.act(input))
}
Expand Down Expand Up @@ -87,7 +92,11 @@ impl Action for Box<dyn Action> {
self.as_ref().act(input)
}

fn act_with_context(&self, input: &str, context: &ScopeContext) -> Result<String, ActionError> {
fn act_with_context(
&self,
input: &str,
context: &ScopeContext<'_>,
) -> Result<String, ActionError> {
self.as_ref().act_with_context(input, context)
}
}
5 changes: 3 additions & 2 deletions src/actions/replace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::{error::Error, fmt};
use unescape::unescape;
use variables::{inject_variables, VariableExpressionError};

mod variables;
/// Items for dealing with variables in replacement values.
pub mod variables;

/// Replaces input with a fixed string.
///
Expand Down Expand Up @@ -135,7 +136,7 @@ impl Action for Replacement {
fn act_with_context(
&self,
_input: &str,
context: &ScopeContext,
context: &ScopeContext<'_>,
) -> Result<String, ActionError> {
match context {
ScopeContext::CaptureGroups(cgs) => {
Expand Down
4 changes: 2 additions & 2 deletions src/actions/replace/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Variables<'a> = HashMap<CaptureGroup, &'a str>;
#[allow(clippy::too_many_lines)] // :(
pub(super) fn inject_variables(
input: &str,
variables: &Variables,
variables: &Variables<'_>,
) -> Result<String, VariableExpressionError> {
let mut state = State::default();
let mut out = String::with_capacity(input.len());
Expand Down Expand Up @@ -359,7 +359,7 @@ mod test {
fn test_inject_variables(
#[case] expression: &str,
#[case] expected: Result<&str, VariableExpressionError>,
variables: Variables,
variables: Variables<'_>,
) {
let result = inject_variables(expression, &variables);
let expected = expected.map(str::to_owned);
Expand Down
22 changes: 17 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,8 +810,13 @@ mod cli {
}

/// <https://github.com/clap-rs/clap/blob/f65d421607ba16c3175ffe76a20820f123b6c4cb/clap_complete/examples/completion-derive.rs#L69>
pub fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout());
pub fn print_completions<G: Generator>(generator: G, cmd: &mut Command) {
generate(
generator,
cmd,
cmd.get_name().to_string(),
&mut std::io::stdout(),
);
}

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -1175,11 +1180,18 @@ mod tests {
(Some("trace"), 1, LevelFilter::Trace),
(Some("trace"), 128, LevelFilter::Trace),
] {
#[allow(unsafe_code)]
// Test itself runs sequentially and this env var doesn't otherwise matter.
// And it's just a test...
if let Some(env_value) = env_value {
env::set_var(DEFAULT_FILTER_ENV, env_value);
unsafe {
env::set_var(DEFAULT_FILTER_ENV, env_value);
}
} else {
// Might be set on parent and fork()ed down
env::remove_var(DEFAULT_FILTER_ENV);
unsafe {
// Might be set on parent and fork()ed down
env::remove_var(DEFAULT_FILTER_ENV);
}
}

// Sanity check for sequential tests
Expand Down
2 changes: 1 addition & 1 deletion src/ranges/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ mod tests {
#[case(1u128..2)]
#[case(1usize..2)]
fn test_various_generic_inputs(#[case] range: Range<impl Ord + Copy + Debug>) {
let _ = Ranges::from_iter(vec![range]);
Ranges::from_iter(vec![range]);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/scoping/dosfix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mod tests {
#[case("\r", ScopedView::new(RWScopes(vec![RWScope(Out("\r"))])))]
#[case("a\r", ScopedView::new(RWScopes(vec![RWScope(In(Borrowed("a"), None)), RWScope(Out("\r"))])))]
#[case("a\r\n", ScopedView::new(RWScopes(vec![RWScope(In(Borrowed("a"), None)), RWScope(Out("\r")), RWScope(In(Borrowed("\n"), None))])))]
fn test_dos_fix(#[case] input: &str, #[case] expected: ScopedView) {
fn test_dos_fix(#[case] input: &str, #[case] expected: ScopedView<'_>) {
let mut builder = crate::scoping::view::ScopedViewBuilder::new(input);
let dosfix = DosFix;
builder.explode(&dosfix);
Expand Down
2 changes: 1 addition & 1 deletion src/scoping/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod tests {
fn test_literal_scoping(
#[case] input: &str,
#[case] literal: &str,
#[case] expected: ScopedView,
#[case] expected: ScopedView<'_>,
) {
let mut builder = crate::scoping::view::ScopedViewBuilder::new(input);
let literal = Literal::try_from(literal.to_owned()).unwrap();
Expand Down
8 changes: 4 additions & 4 deletions src/scoping/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod tests {

/// Get 'Capture Group 0', the default which is always present.
#[allow(clippy::unnecessary_wraps)]
fn cg0(string: &str) -> Option<ScopeContext> {
fn cg0(string: &str) -> Option<ScopeContext<'_>> {
Some(ScopeContext::CaptureGroups(HashMap::from([(
CaptureGroup::Numbered(0),
string,
Expand Down Expand Up @@ -454,7 +454,7 @@ mod tests {
fn test_regex_scoping(
#[case] input: &str,
#[case] pattern: &str,
#[case] expected: ScopedView,
#[case] expected: ScopedView<'_>,
) {
let mut builder = ScopedViewBuilder::new(input);
let regex = Regex::new(RegexPattern::new(pattern).unwrap());
Expand Down Expand Up @@ -545,7 +545,7 @@ mod tests {
// https://docs.rs/regex/latest/regex/#matching-one-character
// https://www.unicode.org/reports/tr44/tr44-24.html#General_Category_Values
let pattern = r"\P{other}+";
let gen = rand_regex::Regex::compile(pattern, 100).unwrap();
let generated = rand_regex::Regex::compile(pattern, 100).unwrap();

let now = Instant::now();

Expand All @@ -556,7 +556,7 @@ mod tests {
continue;
};
let scope = Regex::new(regex);
let input: String = rng.sample(&gen);
let input: String = rng.sample(&generated);

let scopes = scope.scope(&input);

Expand Down
Loading

0 comments on commit c2bcc27

Please sign in to comment.