diff options
| author | Yoshitomo Nakanishi <yurayura.rounin.3@gmail.com> | 2021-02-16 11:20:51 +0900 |
|---|---|---|
| committer | Yoshitomo Nakanishi <yurayura.rounin.3@gmail.com> | 2021-02-16 11:20:51 +0900 |
| commit | 1f8ee3cc19f9259eea5e633affef968280d2ed1a (patch) | |
| tree | f19191db10c5b3c78e6e3f962a33fa3c7dd22e00 /clippy_lints/src/default_numeric_fallback.rs | |
| parent | fb91c76586a3a01fef6a8c49edb9e4598fbd138f (diff) | |
| download | rust-1f8ee3cc19f9259eea5e633affef968280d2ed1a.tar.gz rust-1f8ee3cc19f9259eea5e633affef968280d2ed1a.zip | |
Handle struct ctor case
Diffstat (limited to 'clippy_lints/src/default_numeric_fallback.rs')
| -rw-r--r-- | clippy_lints/src/default_numeric_fallback.rs | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index d755112a178..33a577f336d 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -64,7 +64,7 @@ struct NumericFallbackVisitor<'a, 'tcx> { impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> { fn new(cx: &'a LateContext<'tcx>) -> Self { Self { - ty_bounds: Vec::new(), + ty_bounds: vec![TyBound::Nothing], cx, } } @@ -121,6 +121,42 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { } }, + ExprKind::Struct(qpath, fields, base) => { + if_chain! { + if let Some(def_id) = self.cx.qpath_res(qpath, expr.hir_id).opt_def_id(); + let ty = self.cx.tcx.type_of(def_id); + if let Some(adt_def) = ty.ty_adt_def(); + if adt_def.is_struct(); + if let Some(variant) = adt_def.variants.iter().next(); + then { + let fields_def = &variant.fields; + + // Push field type then visit each field expr. + for field in fields.iter() { + let bound = + fields_def + .iter() + .find_map(|f_def| { + if f_def.ident == field.ident + { Some(self.cx.tcx.type_of(f_def.did)) } + else { None } + }); + self.ty_bounds.push(bound.into()); + self.visit_expr(field.expr); + self.ty_bounds.pop(); + } + + // Visit base with no bound. + if let Some(base) = base { + self.ty_bounds.push(TyBound::Nothing); + self.visit_expr(base); + self.ty_bounds.pop(); + } + return; + } + } + }, + ExprKind::Lit(lit) => { let ty = self.cx.typeck_results().expr_ty(expr); self.check_lit(lit, ty); @@ -166,13 +202,13 @@ fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<' } #[derive(Debug, Clone, Copy)] -enum TyBound<'ctx> { +enum TyBound<'tcx> { Any, - Ty(Ty<'ctx>), + Ty(Ty<'tcx>), Nothing, } -impl<'ctx> TyBound<'ctx> { +impl<'tcx> TyBound<'tcx> { fn is_integral(self) -> bool { match self { TyBound::Any => true, @@ -181,3 +217,12 @@ impl<'ctx> TyBound<'ctx> { } } } + +impl<'tcx> From<Option<Ty<'tcx>>> for TyBound<'tcx> { + fn from(v: Option<Ty<'tcx>>) -> Self { + match v { + Some(t) => TyBound::Ty(t), + None => TyBound::Nothing, + } + } +} |
