- let ty_size = approx_ty_size(cx, err_ty);
- if ty_size >= large_err_threshold {
- span_lint_and_then(
- cx,
- RESULT_LARGE_ERR,
- hir_ty_span,
- "the `Err`-variant returned from this function is very large",
- |diag: &mut Diagnostic| {
- diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
- diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
- },
- );
+ if_chain! {
+ if let Adt(adt, subst) = err_ty.kind();
+ if let Some(local_def_id) = err_ty.ty_adt_def().expect("already checked this is adt").did().as_local();
+ if let Some(hir::Node::Item(item)) = cx
+ .tcx
+ .hir()
+ .find_by_def_id(local_def_id);
+ if let hir::ItemKind::Enum(ref def, _) = item.kind;
+ then {
+ let variants_size = AdtVariantInfo::new(cx, *adt, subst);
+ if variants_size[0].size >= large_err_threshold {
+ span_lint_and_then(
+ cx,
+ RESULT_LARGE_ERR,
+ hir_ty_span,
+ "the `Err`-variant returned from this function is very large",
+ |diag| {
+ diag.span_label(
+ def.variants[variants_size[0].ind].span,
+ format!("the largest variant contains at least {} bytes", variants_size[0].size),
+ );
+
+ for variant in &variants_size[1..] {
+ if variant.size >= large_err_threshold {
+ let variant_def = &def.variants[variant.ind];
+ diag.span_label(
+ variant_def.span,
+ format!("the variant `{}` contains at least {} bytes", variant_def.ident, variant.size),
+ );
+ }
+ }
+
+ diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+ }
+ );
+ }
+ }
+ else {
+ let ty_size = approx_ty_size(cx, err_ty);
+ if ty_size >= large_err_threshold {
+ span_lint_and_then(
+ cx,
+ RESULT_LARGE_ERR,
+ hir_ty_span,
+ "the `Err`-variant returned from this function is very large",
+ |diag: &mut Diagnostic| {
+ diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
+ diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+ },
+ );
+ }
+ }