Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7121,6 +7121,7 @@ Released 2018-09-13
[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
[`inherent-impl-lint-scope`]: https://doc.rust-lang.org/clippy/lint_configuration.html#inherent-impl-lint-scope
[`large-error-ignored`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-ignored
[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
[`lint-commented-code`]: https://doc.rust-lang.org/clippy/lint_configuration.html#lint-commented-code
[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold
Expand Down
11 changes: 11 additions & 0 deletions book/src/lint_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,17 @@ Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl`
* [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl)


## `large-error-ignored`
A list of paths to types that should be ignored as overly large `Err`-variants in a
`Result` returned from a function

**Default Value:** `[]`

---
**Affected lints:**
* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)


## `large-error-threshold`
The maximum size of the `Err`-variant in a `Result` returned from a function

Expand Down
4 changes: 4 additions & 0 deletions clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,10 @@ define_Conf! {
/// Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` blocks for the same type are linted.
#[lints(multiple_inherent_impl)]
inherent_impl_lint_scope: InherentImplLintScope = InherentImplLintScope::Crate,
/// A list of paths to types that should be ignored as overly large `Err`-variants in a
/// `Result` returned from a function
#[lints(result_large_err)]
large_error_ignored: Vec<String> = Vec::default(),
/// The maximum size of the `Err`-variant in a `Result` returned from a function
#[lints(result_large_err)]
large_error_threshold: u64 = 128,
Expand Down
30 changes: 27 additions & 3 deletions clippy_lints/src/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ pub struct Functions {
too_many_arguments_threshold: u64,
too_many_lines_threshold: u64,
large_error_threshold: u64,
large_error_ignored: DefIdSet,
avoid_breaking_exported_api: bool,
/// A set of resolved `def_id` of traits that are configured to allow
/// function params renaming.
Expand All @@ -498,6 +499,11 @@ impl Functions {
too_many_arguments_threshold: conf.too_many_arguments_threshold,
too_many_lines_threshold: conf.too_many_lines_threshold,
large_error_threshold: conf.large_error_threshold,
large_error_ignored: conf
.large_error_ignored
.iter()
.flat_map(|ignored_ty| lookup_path_str(tcx, PathNS::Type, ignored_ty))
.collect(),
avoid_breaking_exported_api: conf.avoid_breaking_exported_api,
trait_ids: conf
.allow_renamed_params_for
Expand Down Expand Up @@ -554,12 +560,24 @@ impl<'tcx> LateLintPass<'tcx> for Functions {

fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
must_use::check_item(cx, item);
result::check_item(cx, item, self.large_error_threshold, self.msrv);
result::check_item(
cx,
item,
self.large_error_threshold,
&self.large_error_ignored,
self.msrv,
);
}

fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
must_use::check_impl_item(cx, item);
result::check_impl_item(cx, item, self.large_error_threshold, self.msrv);
result::check_impl_item(
cx,
item,
self.large_error_threshold,
&self.large_error_ignored,
self.msrv,
);
impl_trait_in_params::check_impl_item(cx, item);
renamed_function_params::check_impl_item(cx, item, &self.trait_ids);
}
Expand All @@ -568,7 +586,13 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold);
not_unsafe_ptr_arg_deref::check_trait_item(cx, item);
must_use::check_trait_item(cx, item);
result::check_trait_item(cx, item, self.large_error_threshold, self.msrv);
result::check_trait_item(
cx,
item,
self.large_error_threshold,
&self.large_error_ignored,
self.msrv,
);
impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);
ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api);
}
Expand Down
30 changes: 25 additions & 5 deletions clippy_lints/src/functions/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_errors::Diag;
use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::ty::{self, Ty};
use rustc_span::def_id::DefIdSet;
use rustc_span::{Span, sym};

use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
Expand Down Expand Up @@ -35,22 +36,29 @@ fn result_err_ty<'tcx>(
}
}

pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: Msrv) {
pub(super) fn check_item<'tcx>(
cx: &LateContext<'tcx>,
item: &hir::Item<'tcx>,
large_err_threshold: u64,
large_err_ignored: &DefIdSet,
msrv: Msrv,
) {
if let hir::ItemKind::Fn { ref sig, .. } = item.kind
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
{
if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
check_result_unit_err(cx, err_ty, fn_header_span, msrv);
}
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored);
}
}

pub(super) fn check_impl_item<'tcx>(
cx: &LateContext<'tcx>,
item: &hir::ImplItem<'tcx>,
large_err_threshold: u64,
large_err_ignored: &DefIdSet,
msrv: Msrv,
) {
// Don't lint if method is a trait's implementation, we can't do anything about those
Expand All @@ -62,14 +70,15 @@ pub(super) fn check_impl_item<'tcx>(
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
check_result_unit_err(cx, err_ty, fn_header_span, msrv);
}
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored);
}
}

pub(super) fn check_trait_item<'tcx>(
cx: &LateContext<'tcx>,
item: &hir::TraitItem<'tcx>,
large_err_threshold: u64,
large_err_ignored: &DefIdSet,
msrv: Msrv,
) {
if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
Expand All @@ -78,7 +87,7 @@ pub(super) fn check_trait_item<'tcx>(
if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
check_result_unit_err(cx, err_ty, fn_header_span, msrv);
}
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored);
}
}
}
Expand All @@ -96,7 +105,18 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S
}
}

fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) {
fn check_result_large_err<'tcx>(
cx: &LateContext<'tcx>,
err_ty: Ty<'tcx>,
hir_ty_span: Span,
large_err_threshold: u64,
large_err_ignored: &DefIdSet,
) {
if let ty::Adt(adt, _) = err_ty.kind()
&& large_err_ignored.contains(&adt.did())
{
return;
}
if let ty::Adt(adt, subst) = err_ty.kind()
&& let Some(local_def_id) = adt.did().as_local()
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id)
Expand Down
1 change: 1 addition & 0 deletions tests/ui-toml/result_large_err/clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
large-error-threshold = 512
large-error-ignored = ["result_large_err::IgnoredError", "result_large_err::IgnoredErrorEnum"]
20 changes: 20 additions & 0 deletions tests/ui-toml/result_large_err/result_large_err.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//@compile-flags: --crate-name result_large_err
#![warn(clippy::result_large_err)]
#![allow(clippy::large_enum_variant)]

fn f() -> Result<(), [u8; 511]> {
todo!()
Expand All @@ -7,4 +9,22 @@ fn f2() -> Result<(), [u8; 512]> {
//~^ ERROR: the `Err`-variant returned from this function is very large
todo!()
}

struct IgnoredError {
inner: [u8; 512],
}

fn f3() -> Result<(), IgnoredError> {
todo!()
}

enum IgnoredErrorEnum {
V1,
V2 { inner: [u8; 512] },
}

fn f4() -> Result<(), IgnoredErrorEnum> {
todo!()
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui-toml/result_large_err/result_large_err.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: the `Err`-variant returned from this function is very large
--> tests/ui-toml/result_large_err/result_large_err.rs:6:12
--> tests/ui-toml/result_large_err/result_large_err.rs:8:12
|
LL | fn f2() -> Result<(), [u8; 512]> {
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
Expand Down
3 changes: 3 additions & 0 deletions tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
future-size-threshold
ignore-interior-mutability
inherent-impl-lint-scope
large-error-ignored
large-error-threshold
lint-commented-code
literal-representation-threshold
Expand Down Expand Up @@ -147,6 +148,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
future-size-threshold
ignore-interior-mutability
inherent-impl-lint-scope
large-error-ignored
large-error-threshold
lint-commented-code
literal-representation-threshold
Expand Down Expand Up @@ -244,6 +246,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
future-size-threshold
ignore-interior-mutability
inherent-impl-lint-scope
large-error-ignored
large-error-threshold
lint-commented-code
literal-representation-threshold
Expand Down