1- use clippy_utils:: diagnostics:: span_lint_and_help;
1+ use clippy_utils:: diagnostics:: span_lint_and_then;
2+ use clippy_utils:: macros:: macro_backtrace;
23use clippy_utils:: source:: snippet;
34use rustc_hir:: { Expr , ExprKind , Item , ItemKind , Node } ;
45use rustc_lint:: { LateContext , LateLintPass } ;
56use rustc_middle:: ty:: layout:: LayoutOf ;
67use rustc_middle:: ty:: { self , ConstKind } ;
78use rustc_session:: impl_lint_pass;
9+ use rustc_span:: { sym, Span } ;
810
911declare_clippy_lint ! {
1012 /// ### What it does
@@ -39,6 +41,7 @@ impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);
3941impl < ' tcx > LateLintPass < ' tcx > for LargeStackArrays {
4042 fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
4143 if let ExprKind :: Repeat ( _, _) | ExprKind :: Array ( _) = expr. kind
44+ && !is_from_vec_macro ( cx, expr. span )
4245 && let ty:: Array ( element_type, cst) = cx. typeck_results ( ) . expr_ty ( expr) . kind ( )
4346 && let ConstKind :: Value ( ty:: ValTree :: Leaf ( element_count) ) = cst. kind ( )
4447 && let Ok ( element_count) = element_count. try_to_target_usize ( cx. tcx )
@@ -54,20 +57,28 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
5457 } )
5558 && self . maximum_allowed_size < u128:: from ( element_count) * u128:: from ( element_size)
5659 {
57- span_lint_and_help (
60+ span_lint_and_then (
5861 cx,
5962 LARGE_STACK_ARRAYS ,
6063 expr. span ,
6164 format ! (
6265 "allocating a local array larger than {} bytes" ,
6366 self . maximum_allowed_size
6467 ) ,
65- None ,
66- format ! (
67- "consider allocating on the heap with `vec!{}.into_boxed_slice()`" ,
68- snippet( cx, expr. span, "[...]" )
69- ) ,
68+ |diag| {
69+ if !expr. span . from_expansion ( ) {
70+ diag. help ( format ! (
71+ "consider allocating on the heap with `vec!{}.into_boxed_slice()`" ,
72+ snippet( cx, expr. span, "[...]" )
73+ ) ) ;
74+ }
75+ } ,
7076 ) ;
7177 }
7278 }
7379}
80+
81+ /// We shouldn't lint messages if the expr is already in a `vec!` call
82+ fn is_from_vec_macro ( cx : & LateContext < ' _ > , expr_span : Span ) -> bool {
83+ macro_backtrace ( expr_span) . any ( |mac| cx. tcx . is_diagnostic_item ( sym:: vec_macro, mac. def_id ) )
84+ }
0 commit comments