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

Fix clippy warnings and enable clippy in CI #1008

Merged
merged 11 commits into from
Apr 9, 2024
16 changes: 15 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ env:
PROTOC_VERSION: 3.20.3

jobs:

rustfmt:
runs-on: ubuntu-latest
steps:
Expand All @@ -22,6 +21,21 @@ jobs:
components: rustfmt
- run: cargo fmt --all --check

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: install protoc
uses: taiki-e/install-action@v2
with:
tool: protoc@${{ env.PROTOC_VERSION }}
- name: install ninja
uses: ./.github/actions/setup-ninja
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: cargo clippy --workspace --all-features --tests -- -D warnings

machete:
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 1 addition & 1 deletion conformance/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tests::{roundtrip, RoundtripResult};

fn main() -> io::Result<()> {
env_logger::init();
let mut bytes = Vec::new();
let mut bytes = vec![0; 4];

loop {
bytes.resize(4, 0);
Expand Down
15 changes: 5 additions & 10 deletions prost-build/src/code_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,7 @@ impl<'a> CodeGenerator<'a> {
.as_ref()
.and_then(|type_name| map_types.get(type_name))
{
Some(&(ref key, ref value)) => {
self.append_map_field(&fq_message_name, field, key, value)
}
Some((key, value)) => self.append_map_field(&fq_message_name, field, key, value),
None => self.append_field(&fq_message_name, field),
}
self.path.pop();
Expand Down Expand Up @@ -268,7 +266,7 @@ impl<'a> CodeGenerator<'a> {
self.buf.push_str(&format!(
"impl {}::Name for {} {{\n",
self.config.prost_path.as_deref().unwrap_or("::prost"),
to_upper_camel(&message_name)
to_upper_camel(message_name)
));
self.depth += 1;

Expand Down Expand Up @@ -377,7 +375,7 @@ impl<'a> CodeGenerator<'a> {
|| (self
.config
.boxed
.get_first_field(&fq_message_name, field.name())
.get_first_field(fq_message_name, field.name())
.is_some());

debug!(
Expand Down Expand Up @@ -559,10 +557,7 @@ impl<'a> CodeGenerator<'a> {
self.buf.push_str(&format!(
"#[prost(oneof=\"{}\", tags=\"{}\")]\n",
name,
fields
.iter()
.map(|&(ref field, _)| field.number())
.join(", ")
fields.iter().map(|(field, _)| field.number()).join(", ")
));
self.append_field_attributes(fq_message_name, oneof.name());
self.push_indent();
Expand Down Expand Up @@ -596,7 +591,7 @@ impl<'a> CodeGenerator<'a> {
"#[derive(Clone, PartialEq, {}::Oneof)]\n",
self.config.prost_path.as_deref().unwrap_or("::prost")
));
self.append_skip_debug(&fq_message_name);
self.append_skip_debug(fq_message_name);
self.push_indent();
self.buf.push_str("pub enum ");
self.buf.push_str(&to_upper_camel(oneof.name()));
Expand Down
3 changes: 0 additions & 3 deletions prost-build/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ pub fn to_upper_camel(s: &str) -> String {

#[cfg(test)]
mod tests {

#![allow(clippy::cognitive_complexity)]

use super::*;

#[test]
Expand Down
8 changes: 2 additions & 6 deletions prost-derive/src/field/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,7 @@ fn bool_attr(key: &str, attr: &Meta) -> Result<Option<bool>, Error> {
}
match *attr {
Meta::Path(..) => Ok(Some(true)),
Meta::List(ref meta_list) => {
return Ok(Some(meta_list.parse_args::<LitBool>()?.value()));
}
Meta::List(ref meta_list) => Ok(Some(meta_list.parse_args::<LitBool>()?.value())),
Meta::NameValue(MetaNameValue {
value:
Expr::Lit(ExprLit {
Expand Down Expand Up @@ -310,9 +308,7 @@ pub(super) fn tag_attr(attr: &Meta) -> Result<Option<u32>, Error> {
return Ok(None);
}
match *attr {
Meta::List(ref meta_list) => {
return Ok(Some(meta_list.parse_args::<LitInt>()?.base10_parse()?));
}
Meta::List(ref meta_list) => Ok(Some(meta_list.parse_args::<LitInt>()?.base10_parse()?)),
Meta::NameValue(MetaNameValue {
value: Expr::Lit(ref expr),
..
Expand Down
3 changes: 1 addition & 2 deletions prost-derive/src/field/scalar.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::convert::TryFrom;
use std::fmt;

use anyhow::{anyhow, bail, Error};
Expand Down Expand Up @@ -272,7 +271,7 @@ impl Field {
pub fn methods(&self, ident: &TokenStream) -> Option<TokenStream> {
let mut ident_str = ident.to_string();
if ident_str.starts_with("r#") {
ident_str = ident_str[2..].to_owned();
ident_str = ident_str.split_off(2);
}

// Prepend `get_` for getter methods of tuple structs.
Expand Down
40 changes: 19 additions & 21 deletions prost-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {
// TODO: This encodes oneof fields in the position of their lowest tag,
// regardless of the currently occupied variant, is that consequential?
// See: https://developers.google.com/protocol-buffers/docs/encoding#order
fields.sort_by_key(|&(_, ref field)| field.tags().into_iter().min().unwrap());
fields.sort_by_key(|(_, field)| field.tags().into_iter().min().unwrap());
let fields = fields;

let mut tags = fields
.iter()
.flat_map(|&(_, ref field)| field.tags())
.flat_map(|(_, field)| field.tags())
.collect::<Vec<_>>();
let num_tags = tags.len();
tags.sort_unstable();
Expand All @@ -104,13 +104,13 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {

let encoded_len = fields
.iter()
.map(|&(ref field_ident, ref field)| field.encoded_len(quote!(self.#field_ident)));
.map(|(field_ident, field)| field.encoded_len(quote!(self.#field_ident)));

let encode = fields
.iter()
.map(|&(ref field_ident, ref field)| field.encode(quote!(self.#field_ident)));
.map(|(field_ident, field)| field.encode(quote!(self.#field_ident)));

let merge = fields.iter().map(|&(ref field_ident, ref field)| {
let merge = fields.iter().map(|(field_ident, field)| {
let merge = field.merge(quote!(value));
let tags = field.tags().into_iter().map(|tag| quote!(#tag));
let tags = Itertools::intersperse(tags, quote!(|));
Expand All @@ -136,7 +136,7 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {

let clear = fields
.iter()
.map(|&(ref field_ident, ref field)| field.clear(quote!(self.#field_ident)));
.map(|(field_ident, field)| field.clear(quote!(self.#field_ident)));

let default = if is_struct {
let default = fields.iter().map(|(field_ident, field)| {
Expand All @@ -158,7 +158,7 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {

let methods = fields
.iter()
.flat_map(|&(ref field_ident, ref field)| field.methods(field_ident))
.flat_map(|(field_ident, field)| field.methods(field_ident))
.collect::<Vec<_>>();
let methods = if methods.is_empty() {
quote!()
Expand Down Expand Up @@ -213,7 +213,7 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {
let expanded = if skip_debug {
expanded
} else {
let debugs = unsorted_fields.iter().map(|&(ref field_ident, ref field)| {
let debugs = unsorted_fields.iter().map(|(field_ident, field)| {
let wrapper = field.debug(quote!(self.#field_ident));
let call = if is_struct {
quote!(builder.field(stringify!(#field_ident), &wrapper))
Expand Down Expand Up @@ -300,16 +300,14 @@ fn try_enumeration(input: TokenStream) -> Result<TokenStream, Error> {

let default = variants[0].0.clone();

let is_valid = variants
let is_valid = variants.iter().map(|(_, value)| quote!(#value => true));
let from = variants
.iter()
.map(|&(_, ref value)| quote!(#value => true));
let from = variants.iter().map(
|&(ref variant, ref value)| quote!(#value => ::core::option::Option::Some(#ident::#variant)),
);
.map(|(variant, value)| quote!(#value => ::core::option::Option::Some(#ident::#variant)));

let try_from = variants.iter().map(
|&(ref variant, ref value)| quote!(#value => ::core::result::Result::Ok(#ident::#variant)),
);
let try_from = variants
.iter()
.map(|(variant, value)| quote!(#value => ::core::result::Result::Ok(#ident::#variant)));

let is_valid_doc = format!("Returns `true` if `value` is a variant of `{}`.", ident);
let from_i32_doc = format!(
Expand Down Expand Up @@ -416,7 +414,7 @@ fn try_oneof(input: TokenStream) -> Result<TokenStream, Error> {

let mut tags = fields
.iter()
.flat_map(|&(ref variant_ident, ref field)| -> Result<u32, Error> {
.flat_map(|(variant_ident, field)| -> Result<u32, Error> {
if field.tags().len() > 1 {
bail!(
"invalid oneof variant {}::{}: oneof variants may only have a single tag",
Expand All @@ -433,12 +431,12 @@ fn try_oneof(input: TokenStream) -> Result<TokenStream, Error> {
panic!("invalid oneof {}: variants have duplicate tags", ident);
}

let encode = fields.iter().map(|&(ref variant_ident, ref field)| {
let encode = fields.iter().map(|(variant_ident, field)| {
let encode = field.encode(quote!(*value));
quote!(#ident::#variant_ident(ref value) => { #encode })
});

let merge = fields.iter().map(|&(ref variant_ident, ref field)| {
let merge = fields.iter().map(|(variant_ident, field)| {
let tag = field.tags()[0];
let merge = field.merge(quote!(value));
quote! {
Expand All @@ -457,7 +455,7 @@ fn try_oneof(input: TokenStream) -> Result<TokenStream, Error> {
}
});

let encoded_len = fields.iter().map(|&(ref variant_ident, ref field)| {
let encoded_len = fields.iter().map(|(variant_ident, field)| {
let encoded_len = field.encoded_len(quote!(*value));
quote!(#ident::#variant_ident(ref value) => #encoded_len)
});
Expand Down Expand Up @@ -499,7 +497,7 @@ fn try_oneof(input: TokenStream) -> Result<TokenStream, Error> {
let expanded = if skip_debug {
expanded
} else {
let debug = fields.iter().map(|&(ref variant_ident, ref field)| {
let debug = fields.iter().map(|(variant_ident, field)| {
let wrapper = field.debug(quote!(*value));
quote!(#ident::#variant_ident(ref value) => {
let wrapper = #wrapper;
Expand Down
9 changes: 3 additions & 6 deletions prost-types/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@ impl Any {
{
let expected_type_url = M::type_url();

match (
if let (Some(expected), Some(actual)) = (
caspermeijn marked this conversation as resolved.
Show resolved Hide resolved
TypeUrl::new(&expected_type_url),
TypeUrl::new(&self.type_url),
) {
(Some(expected), Some(actual)) => {
if expected == actual {
return Ok(M::decode(self.value.as_slice())?);
}
if expected == actual {
return M::decode(self.value.as_slice());
}
_ => (),
}

let mut err = DecodeError::new(format!(
Expand Down
5 changes: 1 addition & 4 deletions prost-types/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,10 +567,7 @@ pub(crate) fn parse_duration(s: &str) -> Option<Duration> {
(seconds, nanos as i32)
};

Some(Duration {
seconds,
nanos: nanos as i32,
})
Some(Duration { seconds, nanos })
}

impl From<DateTime> for Timestamp {
Expand Down
1 change: 0 additions & 1 deletion prost-types/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ impl Name for Timestamp {
impl Eq for Timestamp {}

#[cfg(feature = "std")]
#[allow(clippy::derive_hash_xor_eq)] // Derived logic is correct: comparing the 2 fields for equality
impl std::hash::Hash for Timestamp {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.seconds.hash(state);
Expand Down
26 changes: 17 additions & 9 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
use core::cmp::min;
use core::convert::TryFrom;
use core::mem;
use core::str;
use core::u32;
Expand Down Expand Up @@ -1423,15 +1422,16 @@ pub mod btree_map {

#[cfg(test)]
mod test {
#[cfg(not(feature = "std"))]
use alloc::string::ToString;
use core::borrow::Borrow;
use core::fmt::Debug;
use core::u64;

use ::bytes::{Bytes, BytesMut};
use ::bytes::BytesMut;
use proptest::{prelude::*, test_runner::TestCaseResult};

use crate::encoding::*;
use super::*;

pub fn check_type<T, B>(
value: T,
Expand Down Expand Up @@ -1616,11 +1616,14 @@ mod test {

assert_eq!(encoded_len_varint(value), encoded.len());

let roundtrip_value = decode_varint(&mut encoded.clone()).expect("decoding failed");
// See: https://github.com/tokio-rs/prost/pull/1008 for copying reasoning.
let mut encoded_copy = encoded;
let roundtrip_value = decode_varint(&mut encoded_copy).expect("decoding failed");
assert_eq!(value, roundtrip_value);

let mut encoded_copy = encoded;
let roundtrip_value =
decode_varint_slow(&mut encoded.clone()).expect("slow decoding failed");
decode_varint_slow(&mut encoded_copy).expect("slow decoding failed");
assert_eq!(value, roundtrip_value);
}

Expand Down Expand Up @@ -1679,13 +1682,18 @@ mod test {
);
}

const U64_MAX_PLUS_ONE: &[u8] = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02];

#[test]
fn varint_overflow() {
let u64_max_plus_one: &[u8] = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02];
let mut copy = U64_MAX_PLUS_ONE;
decode_varint(&mut copy).expect_err("decoding u64::MAX + 1 succeeded");
}

decode_varint(&mut u64_max_plus_one.clone()).expect_err("decoding u64::MAX + 1 succeeded");
decode_varint_slow(&mut u64_max_plus_one.clone())
.expect_err("slow decoding u64::MAX + 1 succeeded");
#[test]
fn variant_slow_overflow() {
gibbz00 marked this conversation as resolved.
Show resolved Hide resolved
let mut copy = U64_MAX_PLUS_ONE;
decode_varint_slow(&mut copy).expect_err("slow decoding u64::MAX + 1 succeeded");
}

/// This big bowl o' macro soup generates an encoding property test for each combination of map
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Protobuf encoding and decoding errors.

use alloc::borrow::Cow;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

use core::fmt;
Expand Down
3 changes: 2 additions & 1 deletion src/message.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

use core::fmt::Debug;
use core::usize;

use bytes::{Buf, BufMut};

Expand Down
2 changes: 2 additions & 0 deletions src/name.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Support for associating type name information with a [`Message`].

use crate::Message;

#[cfg(not(feature = "std"))]
use alloc::{format, string::String};

/// Associate a type name with a [`Message`] type.
Expand Down
Loading
Loading