fix: result_large_err FN on closures
This commit is contained in:
parent
34fab5cd37
commit
3cf9fa5496
4 changed files with 68 additions and 6 deletions
|
|
@ -596,4 +596,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
|||
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);
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
||||
result::check_expr(cx, expr, self.large_error_threshold, &self.large_error_ignored);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ pub(super) fn check_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, large_err_ignored);
|
||||
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ 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, large_err_ignored);
|
||||
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,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, large_err_ignored);
|
||||
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -111,12 +111,15 @@ fn check_result_large_err<'tcx>(
|
|||
hir_ty_span: Span,
|
||||
large_err_threshold: u64,
|
||||
large_err_ignored: &DefIdSet,
|
||||
is_closure: bool,
|
||||
) {
|
||||
if let ty::Adt(adt, _) = err_ty.kind()
|
||||
&& large_err_ignored.contains(&adt.did())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let subject = if is_closure { "closure" } else { "function" };
|
||||
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)
|
||||
|
|
@ -130,7 +133,7 @@ fn check_result_large_err<'tcx>(
|
|||
cx,
|
||||
RESULT_LARGE_ERR,
|
||||
hir_ty_span,
|
||||
"the `Err`-variant returned from this function is very large",
|
||||
format!("the `Err`-variant returned from this {subject} is very large"),
|
||||
|diag| {
|
||||
diag.span_label(
|
||||
def.variants[first_variant.ind].span,
|
||||
|
|
@ -161,7 +164,7 @@ fn check_result_large_err<'tcx>(
|
|||
cx,
|
||||
RESULT_LARGE_ERR,
|
||||
hir_ty_span,
|
||||
"the `Err`-variant returned from this function is very large",
|
||||
format!("the `Err`-variant returned from this {subject} is very large"),
|
||||
|diag: &mut Diag<'_, ()>| {
|
||||
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}>`"));
|
||||
|
|
@ -170,3 +173,33 @@ fn check_result_large_err<'tcx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn check_expr<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
large_err_threshold: u64,
|
||||
large_err_ignored: &DefIdSet,
|
||||
) {
|
||||
if let hir::ExprKind::Closure(closure) = expr.kind
|
||||
&& let ty::Closure(_, args) = cx.typeck_results().expr_ty(expr).kind()
|
||||
&& let closure_sig = args.as_closure().sig()
|
||||
&& let Ok(err_binder) = closure_sig.output().try_map_bound(|output_ty| {
|
||||
if let ty::Adt(adt, args) = output_ty.kind()
|
||||
&& let [_, err_arg] = args.as_slice()
|
||||
&& let Some(err_ty) = err_arg.as_type()
|
||||
&& adt.is_diag_item(cx, sym::Result)
|
||||
{
|
||||
return Ok(err_ty);
|
||||
}
|
||||
|
||||
Err(())
|
||||
})
|
||||
{
|
||||
let err_ty = cx.tcx.instantiate_bound_regions_with_erased(err_binder);
|
||||
let hir_ty_span = match closure.fn_decl.output {
|
||||
hir::FnRetTy::Return(hir_ty) => hir_ty.span,
|
||||
hir::FnRetTy::DefaultReturn(_) => expr.span,
|
||||
};
|
||||
check_result_large_err(cx, err_ty, hir_ty_span, large_err_threshold, large_err_ignored, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,3 +141,12 @@ fn _empty_error() -> Result<(), Empty> {
|
|||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn issue16249() {
|
||||
type Large = [u8; 1024];
|
||||
|
||||
let closure = || -> Result<(), Large> { Ok(()) };
|
||||
//~^ result_large_err
|
||||
let closure = || Ok::<(), Large>(());
|
||||
//~^ result_large_err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,5 +104,21 @@ LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
|
|||
|
|
||||
= help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box<ArrayError<(i32, T), U>>`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
error: the `Err`-variant returned from this closure is very large
|
||||
--> tests/ui/result_large_err.rs:148:25
|
||||
|
|
||||
LL | let closure = || -> Result<(), Large> { Ok(()) };
|
||||
| ^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes
|
||||
|
|
||||
= help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>`
|
||||
|
||||
error: the `Err`-variant returned from this closure is very large
|
||||
--> tests/ui/result_large_err.rs:150:19
|
||||
|
|
||||
LL | let closure = || Ok::<(), Large>(());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes
|
||||
|
|
||||
= help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>`
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue