From bcf2e4142127c5e8411f69878de2fe4895608a06 Mon Sep 17 00:00:00 2001 From: Guillem Nieto Date: Tue, 6 Feb 2018 00:31:06 +0100 Subject: [PATCH] Fix ICE comparing `ExprRange` `eq_expr` on hir::utils was throwing an ICE due to an invalid LateContext being used. Due to this missusage, it was generating an ICE with the code on the following issue: https://github.com/rust-lang-nursery/rust-clippy/issues/2423 --- clippy_lints/src/consts.rs | 15 +++++++++++++-- clippy_lints/src/utils/hir_utils.rs | 10 +++++++--- tests/ui/copies.rs | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 69527ba6ff8..a99a56bc554 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -229,7 +229,18 @@ pub fn constant_simple(lcx: &LateContext, e: &Expr) -> Option { constant(lcx, e).and_then(|(cst, res)| if res { None } else { Some(cst) }) } -struct ConstEvalLateContext<'a, 'tcx: 'a> { +/// Creates a ConstEvalLateContext from the given LateContext and TypeckTables +pub fn constant_context<'c, 'cc>(lcx: &LateContext<'c, 'cc>, tables: &'cc ty::TypeckTables<'cc>) -> ConstEvalLateContext<'c, 'cc> { + ConstEvalLateContext { + tcx: lcx.tcx, + tables, + param_env: lcx.param_env, + needed_resolution: false, + substs: lcx.tcx.intern_substs(&[]), + } +} + +pub struct ConstEvalLateContext<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::TypeckTables<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -239,7 +250,7 @@ struct ConstEvalLateContext<'a, 'tcx: 'a> { impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { /// simple constant folding: Insert an expression, get a constant or none. - fn expr(&mut self, e: &Expr) -> Option { + pub fn expr(&mut self, e: &Expr) -> Option { match e.node { ExprPath(ref qpath) => self.fetch_path(qpath, e.hir_id), ExprBlock(ref block) => self.block(block), diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 5932c41dc13..34073d9725b 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -1,4 +1,4 @@ -use consts::constant; +use consts::{constant, constant_context}; use rustc::lint::*; use rustc::hir::*; use std::hash::{Hash, Hasher}; @@ -117,8 +117,12 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { !self.ignore_fn && l_path == r_path && self.eq_exprs(l_args, r_args) }, (&ExprRepeat(ref le, ll_id), &ExprRepeat(ref re, rl_id)) => { - self.eq_expr(le, re) - && self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value) + let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id)); + let ll = celcx.expr(&self.cx.tcx.hir.body(ll_id).value); + let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(rl_id)); + let rl = celcx.expr(&self.cx.tcx.hir.body(rl_id).value); + + self.eq_expr(le, re) && ll == rl }, (&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)), (&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r), diff --git a/tests/ui/copies.rs b/tests/ui/copies.rs index 4c4050c014f..0488591bae9 100644 --- a/tests/ui/copies.rs +++ b/tests/ui/copies.rs @@ -396,3 +396,18 @@ fn ifs_same_cond() { } fn main() {} + +// Issue #2423. This was causing an ICE +fn func() { + if true { + f(&[0; 62]); + f(&[0; 4]); + f(&[0; 3]); + } else { + f(&[0; 62]); + f(&[0; 6]); + f(&[0; 6]); + } +} + +fn f(val: &[u8]) {}