@@ -14,7 +14,7 @@ use rustc_hir::def_id::DefId;
1414use rustc_hir:: { Expr , FnDecl , LangItem , find_attr} ;
1515use rustc_hir_analysis:: lower_ty;
1616use rustc_infer:: infer:: TyCtxtInferExt ;
17- use rustc_lint:: LateContext ;
17+ use rustc_lint:: { LateContext , LintContext } ;
1818use rustc_middle:: mir:: ConstValue ;
1919use rustc_middle:: mir:: interpret:: Scalar ;
2020use rustc_middle:: traits:: EvaluationResult ;
@@ -36,7 +36,7 @@ use std::{iter, mem};
3636
3737use crate :: paths:: { PathNS , lookup_path_str} ;
3838use crate :: res:: { MaybeDef , MaybeQPath } ;
39- use crate :: sym;
39+ use crate :: { get_unique_builtin_attr , sym} ;
4040
4141mod type_certainty;
4242pub use type_certainty:: expr_type_is_certain;
@@ -1071,6 +1071,17 @@ impl<'tcx> InteriorMut<'tcx> {
10711071 /// this type to be interior mutable. False negatives may be expected for infinitely recursive
10721072 /// types, and `None` will be returned there.
10731073 pub fn interior_mut_ty_chain ( & mut self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> Option < & ' tcx ty:: List < Ty < ' tcx > > > {
1074+ // Check if given type has a `#[clippy::ignore_interior_mutability]` attribute
1075+ if let Some ( did) = ty. ty_adt_def ( ) . map ( AdtDef :: did)
1076+ && !self . ignored_def_ids . contains ( & did)
1077+ && let attrs = cx. tcx . get_all_attrs ( did)
1078+ && get_unique_builtin_attr ( cx. sess ( ) , attrs, sym:: ignore_interior_mutability) . is_some ( )
1079+ {
1080+ self . ignored_def_ids . insert ( did) ;
1081+ // Small optimization: since we know that we're going to ignore interior mutability for
1082+ // this type anyway, running `self.interior_mut_ty_chain_inner` is unnecessary
1083+ return None ;
1084+ }
10741085 self . interior_mut_ty_chain_inner ( cx, ty, 0 )
10751086 }
10761087
0 commit comments