Skip to content

Commit b157e3e

Browse files
committed
Fix clippy::pedantic lints
1 parent c6b6dfe commit b157e3e

File tree

9 files changed

+88
-32
lines changed

9 files changed

+88
-32
lines changed

Cargo.toml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ authors = ["Techcable <git@techcable.net>"]
66
license = "Apache-2.0 OR MIT"
77
edition = "2024"
88
repository = "https://github.com/DuckLogic/qbe-parser.rs"
9+
keywords = ["qbe", "ir", "parser"]
10+
categories = [
11+
"parser-implementations",
12+
"compilers",
13+
]
914

1015
[dependencies]
1116
equivalent = "1"
@@ -25,3 +30,45 @@ chumsky = "0.11"
2530
[dev-dependencies]
2631
indoc = "2"
2732
similar-asserts = "1"
33+
34+
[lints.clippy]
35+
## groups ##
36+
cargo = { priority = -1, level = "warn" }
37+
pedantic = { level = "warn", priority = -1 }
38+
39+
# restrictions
40+
redundant_test_prefix = "warn" # name test_foo is redundant with #[test] attr
41+
42+
# safety
43+
undocumented_unsafe_blocks = "deny"
44+
multiple_unsafe_ops_per_block = "deny"
45+
46+
## aggressively lint casts ##
47+
# in an ideal world, overflowing casts would panic
48+
# linting them (with deny) is the second best option
49+
cast-possible-truncation = "deny"
50+
cast-possible-wrap = "deny"
51+
cast-precision-loss = "deny"
52+
cast-sign-loss = "deny"
53+
char-lit-as-u8 = "deny"
54+
cast-ptr-alignment = "deny"
55+
fn-to-numeric-cast = "deny"
56+
fn-to-numeric-cast-any = "deny"
57+
fn-to-numeric-cast-with-truncation = "deny"
58+
cast-lossless = "allow" # lossless casts are fine, lints will catch if types change
59+
ptr_as_ptr = "allow" # pointer casts are fine as long as they don't violate another rule
60+
61+
#
62+
# excessively pedantic (even for clippy::pedantic)
63+
#
64+
too-many-lines = "allow"
65+
# We don't put #[must_use] on len
66+
must-use-candidate = "allow"
67+
return-self-not-must-use = "allow"
68+
items-after-statements = "allow"
69+
redundant-else = "allow"
70+
if-not-else = "allow"
71+
missing-errors-doc = "allow"
72+
wildcard-imports = "allow"
73+
single-match-else = "allow"
74+
trivially-copy-pass-by-ref = "allow"

src/ast/core.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ impl Ident {
131131
pub fn unspanned(text: impl Into<AstString>) -> Self {
132132
Self::new(text, Span::MISSING)
133133
}
134+
/// Create an identifier from a string.
135+
///
136+
/// This accepts keywords without errors.
137+
/// Using the `From<Keyword>` implementation does the same thing,
138+
/// but more explicitly.
139+
///
140+
/// # Panics
141+
/// If the characters are not valid, this will panic.
134142
#[inline]
135143
#[track_caller]
136144
pub fn new(text: impl Into<AstString>, span: Span) -> Self {
@@ -139,20 +147,22 @@ impl Ident {
139147
let first = chars
140148
.next()
141149
.unwrap_or_else(|| panic!("Identifier is empty at {span:?}"));
142-
if !is_xid_start(first) {
143-
panic!("Invalid start char {first:?} for ident at {span:?}")
144-
}
150+
assert!(
151+
is_xid_start(first),
152+
"Invalid start char {first:?} for ident at {span:?}"
153+
);
145154
for other in chars {
146-
if !is_xid_continue(other) {
147-
panic!("Invalid char {other:?} for ident at {span:?}")
148-
}
155+
assert!(
156+
is_xid_continue(other),
157+
"Invalid char {other:?} for ident at {span:?}"
158+
);
149159
}
150160
if let Ok(byte_len) = span.byte_len() {
151161
assert_eq!(
152162
byte_len,
153163
text.len() as u64,
154164
"Length of span {span} doesn't match {text:?}"
155-
)
165+
);
156166
}
157167
Ident { text, span }
158168
}

src/ast/functions.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ impl FunctionDef {
3636
if index > 0 {
3737
res.push(InvalidFunctionReason::EnvironmentParamMustComeFirst {
3838
span: param.span(),
39-
})
39+
});
4040
}
4141
}
4242
ParamDef::Variadic(_) => {
4343
if index < self.params.len() - 1 {
4444
res.push(InvalidFunctionReason::VariadicParamMustComeLast {
4545
span: param.span(),
46-
})
46+
});
4747
}
4848
}
4949
}
@@ -511,7 +511,7 @@ impl Display for JumpInstruction {
511511
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
512512
match self {
513513
JumpInstruction::Jump { span: _, target } => {
514-
write!(f, "jmp {}", target)
514+
write!(f, "jmp {target}")
515515
}
516516
JumpInstruction::JumpNonZero {
517517
span: _,
@@ -547,7 +547,7 @@ impl Display for UnknownInstructionNameError {
547547
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
548548
f.write_str("Unknown")?;
549549
if let Some(kind) = self.kind_desc {
550-
write!(f, " {}", kind)?;
550+
write!(f, " {kind}")?;
551551
}
552552
write!(f, " instruction name: {:?}", self.name)
553553
}

src/ast/linkage.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl Linkage {
115115
for entry in &self.specifiers {
116116
if entry.kind() == kind {
117117
assert!(res.is_none(), "Internal Error: Duplicate {kind:?} entries");
118-
res = Some(entry)
118+
res = Some(entry);
119119
}
120120
}
121121
res
@@ -462,7 +462,7 @@ mod test {
462462
.with_thread()
463463
.with_section_and_flags("foo", "flags")
464464
.build(),
465-
)
465+
);
466466
}
467467

468468
#[test]

src/ast/span.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl Default for Location {
129129

130130
/// References a range of bytes in the original source file.
131131
///
132-
/// Can be ["missing"](Span::MISSING),
132+
/// Can be [missing](Span::MISSING),
133133
/// in which case doesn't correspond to any actual portion of the source file.
134134
/// This is the [`Default`] value.
135135
///
@@ -168,9 +168,7 @@ impl Span {
168168
#[track_caller]
169169
pub fn new(start: Location, end: Location) -> Span {
170170
// don't use assert! because missing locations will return false
171-
if start > end {
172-
panic!("start > end: {start} > {end}");
173-
}
171+
assert!(start <= end, "start > end: {start} > {end}");
174172
Span { start, end }
175173
}
176174

@@ -566,6 +564,7 @@ impl ResolvedLocation {
566564
self.original
567565
}
568566
}
567+
#[allow(clippy::missing_fields_in_debug, reason = "intentional")]
569568
impl Debug for ResolvedLocation {
570569
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
571570
if self.is_missing() {

src/ast/types/test.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn parse_struct() {
5252
body: TypeDefBody::Struct(struct1_body()),
5353
align: None,
5454
}
55-
)
55+
);
5656
}
5757

5858
#[test]
@@ -75,7 +75,7 @@ fn print_struct() {
7575
}
7676
"}
7777
.trim_end()
78-
)
78+
);
7979
}
8080

8181
fn union1_body() -> UnionBody {
@@ -121,7 +121,7 @@ fn parse_union() {
121121
}),
122122
body: TypeDefBody::Union(union1_body()),
123123
}
124-
)
124+
);
125125
}
126126

127127
#[test]
@@ -149,7 +149,7 @@ fn print_union() {
149149
}
150150
"}
151151
.trim_end()
152-
)
152+
);
153153
}
154154

155155
fn opaque1() -> TypeDef {
@@ -172,10 +172,10 @@ fn parse_opaque_type() {
172172
assert_eq!(
173173
"type :hello = align 8 { 12 }".parse::<TypeDef>().unwrap(),
174174
opaque1(),
175-
)
175+
);
176176
}
177177

178178
#[test]
179179
fn print_opaque_type() {
180-
assert_eq!(format!("{}", opaque1()), "type :hello = align 8 { 12 }")
180+
assert_eq!(format!("{}", opaque1()), "type :hello = align 8 { 12 }");
181181
}

src/lexer.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ fn floating_point_value<'a>() -> impl StringParser<'a, NumericLiteral<OrderedFlo
173173
}
174174
/// Parse a single ASCII newline.
175175
///
176-
/// Unlike text::newline, this only accepts ASCII newline operators
176+
/// Unlike [`text::newline`], this only accepts ASCII newline operators
177177
/// that would be recognized by [`str::lines`] ("\r\n" and "\n").
178178
///
179179
/// TODO: Contribute this to chumsky?
@@ -410,7 +410,7 @@ mod test {
410410
res.into_output(),
411411
Some(text),
412412
"Parse should succeed even with invalid whitespace"
413-
)
413+
);
414414
}
415415
let iws = inline_whitespace(); // primary parser being tested
416416
let iws = &iws;
@@ -466,7 +466,7 @@ mod test {
466466
keyword!(type).into(),
467467
Token::Newline,
468468
])
469-
)
469+
);
470470
}
471471

472472
#[test]
@@ -527,7 +527,7 @@ mod test {
527527
assert_eq!(
528528
tokenize("d_5.8 s_1.0").unwrap(),
529529
tokens([double(5.8), single(1.0)])
530-
)
530+
);
531531
}
532532

533533
#[test]
@@ -540,7 +540,7 @@ mod test {
540540
TemporaryName::unspanned("baz").into(),
541541
BlockName::unspanned("foo").into(),
542542
]
543-
)
543+
);
544544
}
545545

546546
#[test]
@@ -567,6 +567,6 @@ mod test {
567567
operator!(,).into(),
568568
Token::Number(1.into()),
569569
]
570-
)
570+
);
571571
}
572572
}

src/lexer/tokens.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,11 @@ const _TOKEN_USED: () = {
188188
};
189189

190190
macro_rules! define_keyword_enum {
191-
(enum $target:ident {
191+
($evis:vis enum $target:ident {
192192
$($kw:ident),+ $(,)?
193193
}) => {
194194
paste3::paste! {
195-
define_string_enum!(enum $target {
195+
define_string_enum!($evis enum $target {
196196
$($kw([<$kw:snake>])),*
197197
});
198198
}

src/print.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'a> IndentedPrinter<'a> {
6060
fn flush(&mut self) -> fmt::Result {
6161
if !self.buffer.is_empty() {
6262
self.output.write_str(&self.buffer)?;
63-
self.buffer.clear()
63+
self.buffer.clear();
6464
}
6565
Ok(())
6666
}

0 commit comments

Comments
 (0)