1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
2
use clippy_utils:: is_range_full;
3
- use clippy_utils:: ty:: is_type_diagnostic_item;
3
+ use clippy_utils:: ty:: { is_type_diagnostic_item, is_type_lang_item } ;
4
4
use rustc_errors:: Applicability ;
5
5
use rustc_hir as hir;
6
- use rustc_hir:: { Expr , ExprKind , QPath } ;
6
+ use rustc_hir:: { Expr , ExprKind , LangItem , QPath } ;
7
7
use rustc_lint:: LateContext ;
8
8
use rustc_span:: symbol:: sym;
9
9
use rustc_span:: Span ;
10
10
11
11
use super :: CLEAR_WITH_DRAIN ;
12
12
13
- const ACCEPTABLE_TYPES_WITH_ARG : [ rustc_span:: Symbol ; 3 ] = [ sym:: String , sym:: Vec , sym:: VecDeque ] ;
13
+ // Add `String` here when it is added to diagnostic items
14
+ const ACCEPTABLE_TYPES_WITH_ARG : [ rustc_span:: Symbol ; 2 ] = [ sym:: Vec , sym:: VecDeque ] ;
14
15
15
16
const ACCEPTABLE_TYPES_WITHOUT_ARG : [ rustc_span:: Symbol ; 3 ] = [ sym:: BinaryHeap , sym:: HashMap , sym:: HashSet ] ;
16
17
@@ -30,11 +31,14 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
30
31
fn match_acceptable_type ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , types : & [ rustc_span:: Symbol ] ) -> bool {
31
32
let expr_ty = cx. typeck_results ( ) . expr_ty ( expr) . peel_refs ( ) ;
32
33
types. iter ( ) . any ( |& ty| is_type_diagnostic_item ( cx, expr_ty, ty) )
34
+ // String type is a lang item but not a diagnostic item for now so we need a separate check
35
+ || is_type_lang_item ( cx, expr_ty, LangItem :: String )
33
36
}
34
37
35
38
fn suggest ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , recv : & Expr < ' _ > , span : Span ) {
36
39
if let Some ( adt) = cx. typeck_results ( ) . expr_ty ( recv) . ty_adt_def ( )
37
- && let Some ( ty_name) = cx. tcx . get_diagnostic_name ( adt. did ( ) )
40
+ // Use `opt_item_name` while `String` is not a diagnostic item
41
+ && let Some ( ty_name) = cx. tcx . opt_item_name ( adt. did ( ) )
38
42
{
39
43
span_lint_and_sugg (
40
44
cx,
0 commit comments