- fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
- match item.kind {
- TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => self.check_type(cx, ty),
- TraitItemKind::Fn(FnSig { ref decl, .. }, TraitFn::Required(_)) => self.check_fndecl(cx, decl),
- // methods with default impl are covered by check_fn
- TraitItemKind::Type(..) | TraitItemKind::Fn(_, TraitFn::Provided(_)) => (),
- }
- }
-
- fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
- match item.kind {
- ImplItemKind::Const(ref ty, _) | ImplItemKind::TyAlias(ref ty) => self.check_type(cx, ty),
- // methods are covered by check_fn
- ImplItemKind::Fn(..) => (),
- }
- }
-
- fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
- if let Some(ref ty) = local.ty {
- self.check_type(cx, ty);
- }
- }
-}
-
-impl<'tcx> TypeComplexity {
- fn check_fndecl(&self, cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>) {
- for arg in decl.inputs {
- self.check_type(cx, arg);
- }
- if let FnRetTy::Return(ref ty) = decl.output {
- self.check_type(cx, ty);
- }
- }
-
- fn check_type(&self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) {
- if ty.span.from_expansion() {
- return;
- }
- let score = {
- let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 };
- visitor.visit_ty(ty);
- visitor.score
- };
-
- if score > self.threshold {
- span_lint(
- cx,
- TYPE_COMPLEXITY,
- ty.span,
- "very complex type used. Consider factoring parts into `type` definitions",
- );
- }