Skip to content
Open
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
16 changes: 13 additions & 3 deletions clippy_lints/src/types/type_complexity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ use rustc_abi::ExternAbi;
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt as _, walk_ty};
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, TyKind};
use rustc_lint::LateContext;
use rustc_span::Span;
use rustc_span::{Span, sym};

use super::TYPE_COMPLEXITY;

pub(super) fn check(cx: &LateContext<'_>, ty: &hir::Ty<'_>, type_complexity_threshold: u64) -> bool {
let score = {
let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 };
let mut visitor = TypeComplexityVisitor {
score: 0,
nest: 1,
type_alias_impl_trait_enabled: cx.tcx.features().enabled(sym::type_alias_impl_trait),
};
visitor.visit_ty_unambig(ty);
visitor.score
};
Expand All @@ -33,6 +37,8 @@ struct TypeComplexityVisitor {
score: u64,
/// current nesting level
nest: u64,
/// whether opaque `impl Trait` types can be named through `type_alias_impl_trait`
type_alias_impl_trait_enabled: bool,
}

impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
Expand Down Expand Up @@ -72,7 +78,11 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
};
self.score += add_score;
self.nest += sub_nest;
walk_ty(self, ty);
// Opaque `impl Trait` types cannot be extracted into type aliases on stable. Skip
// their subtree only when `type_alias_impl_trait` is not enabled for this crate.
if self.type_alias_impl_trait_enabled || !matches!(ty.kind, TyKind::OpaqueDef(..)) {
walk_ty(self, ty);
}
self.nest -= sub_nest;
}
}
19 changes: 19 additions & 0 deletions tests/ui/type_complexity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,23 @@ struct D {
),
}

// Should not warn, because factoring `impl Trait` into a type alias is not stable (#17195).
fn issue_17195<I, J>(
left: I,
right: J,
) -> std::iter::Map<std::iter::Zip<I::IntoIter, J::IntoIter>, impl FnMut((I::Item, I::Item)) -> [I::Item; 2]>
where
I: IntoIterator,
J: IntoIterator<Item = I::Item>,
{
left.into_iter().zip(right).map(<[I::Item; 2]>::from)
}

// The presence of an opaque type must not hide complexity in a sibling type that can be factored
// out.
fn complex_after_opaque() -> (impl Iterator<Item = u32>, Vec<Vec<Box<(u32, u32, u32, u32)>>>) {
//~^ type_complexity
(std::iter::empty(), vec![])
}

fn main() {}
8 changes: 7 additions & 1 deletion tests/ui/type_complexity.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,11 @@ error: very complex type used. Consider factoring parts into `type` definitions
LL | let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 15 previous errors
error: very complex type used. Consider factoring parts into `type` definitions
--> tests/ui/type_complexity.rs:103:30
|
LL | fn complex_after_opaque() -> (impl Iterator<Item = u32>, Vec<Vec<Box<(u32, u32, u32, u32)>>>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 16 previous errors

9 changes: 9 additions & 0 deletions tests/ui/type_complexity_type_alias_impl_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(type_alias_impl_trait)]
#![warn(clippy::type_complexity)]

fn complex_opaque_bound() -> impl Fn(Vec<Vec<Box<(u32, u32, u32, u32)>>>) {
//~^ type_complexity
|_| {}
}

fn main() {}
11 changes: 11 additions & 0 deletions tests/ui/type_complexity_type_alias_impl_trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: very complex type used. Consider factoring parts into `type` definitions
--> tests/ui/type_complexity_type_alias_impl_trait.rs:4:30
|
LL | fn complex_opaque_bound() -> impl Fn(Vec<Vec<Box<(u32, u32, u32, u32)>>>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::type-complexity` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`

error: aborting due to 1 previous error