X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Futils%2Fhir_utils.rs;h=27f49e72b33d104a2729e002e2155414b794f02e;hb=f5831523d335bc57a6371806b2ea1978942ac490;hp=ddac8bd3835e83d02c8fa404f1b4b745a8c243ae;hpb=621fdcc3bcea3828cd25ee0801c39bc9c2bbafce;p=rust.git diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index ddac8bd3835..27f49e72b33 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -1,12 +1,21 @@ -use crate::consts::{constant_simple, constant_context}; -use rustc::lint::*; -use rustc::hir::*; -use rustc::ty::{TypeckTables}; -use std::hash::{Hash, Hasher}; -use std::collections::hash_map::DefaultHasher; -use syntax::ast::Name; -use syntax::ptr::P; +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::consts::{constant_context, constant_simple}; +use crate::rustc::hir::*; +use crate::rustc::lint::LateContext; +use crate::rustc::ty::TypeckTables; +use crate::syntax::ast::Name; +use crate::syntax::ptr::P; use crate::utils::differing_macro_contexts; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; /// Type used to check whether two ast are the same. This is different from the /// operator @@ -43,16 +52,15 @@ pub fn ignore_fn(self) -> Self { /// Check whether two statements are the same. pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool { match (&left.node, &right.node) { - (&StmtDecl(ref l, _), &StmtDecl(ref r, _)) => { - if let (&DeclLocal(ref l), &DeclLocal(ref r)) = (&l.node, &r.node) { + (&StmtKind::Decl(ref l, _), &StmtKind::Decl(ref r, _)) => { + if let (&DeclKind::Local(ref l), &DeclKind::Local(ref r)) = (&l.node, &r.node) { both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) } else { false } }, - (&StmtExpr(ref l, _), &StmtExpr(ref r, _)) | (&StmtSemi(ref l, _), &StmtSemi(ref r, _)) => { - self.eq_expr(l, r) - }, + (&StmtKind::Expr(ref l, _), &StmtKind::Expr(ref r, _)) + | (&StmtKind::Semi(ref l, _), &StmtKind::Semi(ref r, _)) => self.eq_expr(l, r), _ => false, } } @@ -63,64 +71,79 @@ pub fn eq_block(&mut self, left: &Block, right: &Block) -> bool { && both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r)) } + #[allow(clippy::similar_names)] pub fn eq_expr(&mut self, left: &Expr, right: &Expr) -> bool { if self.ignore_fn && differing_macro_contexts(left.span, right.span) { return false; } - if let (Some(l), Some(r)) = (constant_simple(self.cx, self.tables, left), constant_simple(self.cx, self.tables, right)) { + if let (Some(l), Some(r)) = ( + constant_simple(self.cx, self.tables, left), + constant_simple(self.cx, self.tables, right), + ) { if l == r { return true; } } match (&left.node, &right.node) { - (&ExprAddrOf(l_mut, ref le), &ExprAddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re), - (&ExprAgain(li), &ExprAgain(ri)) => { - both(&li.label, &ri.label, |l, r| l.name.as_str() == r.name.as_str()) + (&ExprKind::AddrOf(l_mut, ref le), &ExprKind::AddrOf(r_mut, ref re)) => { + l_mut == r_mut && self.eq_expr(le, re) }, - (&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr), - (&ExprAssignOp(ref lo, ref ll, ref lr), &ExprAssignOp(ref ro, ref rl, ref rr)) => { + (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => { + both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str()) + }, + (&ExprKind::Assign(ref ll, ref lr), &ExprKind::Assign(ref rl, ref rr)) => { + self.eq_expr(ll, rl) && self.eq_expr(lr, rr) + }, + (&ExprKind::AssignOp(ref lo, ref ll, ref lr), &ExprKind::AssignOp(ref ro, ref rl, ref rr)) => { lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) }, - (&ExprBlock(ref l, _), &ExprBlock(ref r, _)) => self.eq_block(l, r), - (&ExprBinary(l_op, ref ll, ref lr), &ExprBinary(r_op, ref rl, ref rr)) => { + (&ExprKind::Block(ref l, _), &ExprKind::Block(ref r, _)) => self.eq_block(l, r), + (&ExprKind::Binary(l_op, ref ll, ref lr), &ExprKind::Binary(r_op, ref rl, ref rr)) => { l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) || swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| { l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) }) }, - (&ExprBreak(li, ref le), &ExprBreak(ri, ref re)) => { - both(&li.label, &ri.label, |l, r| l.name.as_str() == r.name.as_str()) + (&ExprKind::Break(li, ref le), &ExprKind::Break(ri, ref re)) => { + both(&li.label, &ri.label, |l, r| l.ident.as_str() == r.ident.as_str()) && both(le, re, |l, r| self.eq_expr(l, r)) }, - (&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r), - (&ExprCall(ref l_fun, ref l_args), &ExprCall(ref r_fun, ref r_args)) => { + (&ExprKind::Box(ref l), &ExprKind::Box(ref r)) => self.eq_expr(l, r), + (&ExprKind::Call(ref l_fun, ref l_args), &ExprKind::Call(ref r_fun, ref r_args)) => { !self.ignore_fn && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args) }, - (&ExprCast(ref lx, ref lt), &ExprCast(ref rx, ref rt)) | - (&ExprType(ref lx, ref lt), &ExprType(ref rx, ref rt)) => self.eq_expr(lx, rx) && self.eq_ty(lt, rt), - (&ExprField(ref l_f_exp, ref l_f_ident), &ExprField(ref r_f_exp, ref r_f_ident)) => { + (&ExprKind::Cast(ref lx, ref lt), &ExprKind::Cast(ref rx, ref rt)) + | (&ExprKind::Type(ref lx, ref lt), &ExprKind::Type(ref rx, ref rt)) => { + self.eq_expr(lx, rx) && self.eq_ty(lt, rt) + }, + (&ExprKind::Field(ref l_f_exp, ref l_f_ident), &ExprKind::Field(ref r_f_exp, ref r_f_ident)) => { l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp) }, - (&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri), - (&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => { - self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r)) + (&ExprKind::Index(ref la, ref li), &ExprKind::Index(ref ra, ref ri)) => { + self.eq_expr(la, ra) && self.eq_expr(li, ri) }, - (&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node, - (&ExprLoop(ref lb, ref ll, ref lls), &ExprLoop(ref rb, ref rl, ref rls)) => { - lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.name.as_str() == r.name.as_str()) + (&ExprKind::If(ref lc, ref lt, ref le), &ExprKind::If(ref rc, ref rt, ref re)) => { + self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r)) }, - (&ExprMatch(ref le, ref la, ref ls), &ExprMatch(ref re, ref ra, ref rs)) => { - ls == rs && self.eq_expr(le, re) && over(la, ra, |l, r| { - self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) - && over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) - }) + (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node, + (&ExprKind::Loop(ref lb, ref ll, ref lls), &ExprKind::Loop(ref rb, ref rl, ref rls)) => { + lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str()) + }, + (&ExprKind::Match(ref le, ref la, ref ls), &ExprKind::Match(ref re, ref ra, ref rs)) => { + ls == rs + && self.eq_expr(le, re) + && over(la, ra, |l, r| { + self.eq_expr(&l.body, &r.body) + && both(&l.guard, &r.guard, |l, r| self.eq_guard(l, r)) + && over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) + }) }, - (&ExprMethodCall(ref l_path, _, ref l_args), &ExprMethodCall(ref r_path, _, ref r_args)) => { - !self.ignore_fn && l_path == r_path && self.eq_exprs(l_args, r_args) + (&ExprKind::MethodCall(ref l_path, _, ref l_args), &ExprKind::MethodCall(ref r_path, _, ref r_args)) => { + !self.ignore_fn && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args) }, - (&ExprRepeat(ref le, ref ll_id), &ExprRepeat(ref re, ref rl_id)) => { + (&ExprKind::Repeat(ref le, ref ll_id), &ExprKind::Repeat(ref re, ref rl_id)) => { let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); let ll = celcx.expr(&self.cx.tcx.hir.body(ll_id.body).value); let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(rl_id.body)); @@ -128,17 +151,20 @@ pub fn eq_expr(&mut self, left: &Expr, right: &Expr) -> bool { 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), - (&ExprStruct(ref l_path, ref lf, ref lo), &ExprStruct(ref r_path, ref rf, ref ro)) => { - self.eq_qpath(l_path, r_path) && both(lo, ro, |l, r| self.eq_expr(l, r)) + (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)), + (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r), + (&ExprKind::Struct(ref l_path, ref lf, ref lo), &ExprKind::Struct(ref r_path, ref rf, ref ro)) => { + self.eq_qpath(l_path, r_path) + && both(lo, ro, |l, r| self.eq_expr(l, r)) && over(lf, rf, |l, r| self.eq_field(l, r)) }, - (&ExprTup(ref l_tup), &ExprTup(ref r_tup)) => self.eq_exprs(l_tup, r_tup), - (&ExprUnary(l_op, ref le), &ExprUnary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re), - (&ExprArray(ref l), &ExprArray(ref r)) => self.eq_exprs(l, r), - (&ExprWhile(ref lc, ref lb, ref ll), &ExprWhile(ref rc, ref rb, ref rl)) => { - self.eq_expr(lc, rc) && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.name.as_str() == r.name.as_str()) + (&ExprKind::Tup(ref l_tup), &ExprKind::Tup(ref r_tup)) => self.eq_exprs(l_tup, r_tup), + (&ExprKind::Unary(l_op, ref le), &ExprKind::Unary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re), + (&ExprKind::Array(ref l), &ExprKind::Array(ref r)) => self.eq_exprs(l, r), + (&ExprKind::While(ref lc, ref lb, ref ll), &ExprKind::While(ref rc, ref rb, ref rl)) => { + self.eq_expr(lc, rc) + && self.eq_block(lb, rb) + && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str()) }, _ => false, } @@ -152,6 +178,20 @@ fn eq_field(&mut self, left: &Field, right: &Field) -> bool { left.ident.name == right.ident.name && self.eq_expr(&left.expr, &right.expr) } + fn eq_guard(&mut self, left: &Guard, right: &Guard) -> bool { + match (left, right) { + (Guard::If(l), Guard::If(r)) => self.eq_expr(l, r), + } + } + + fn eq_generic_arg(&mut self, left: &GenericArg, right: &GenericArg) -> bool { + match (left, right) { + (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => self.eq_lifetime(l_lt, r_lt), + (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty), + _ => false, + } + } + fn eq_lifetime(&mut self, left: &Lifetime, right: &Lifetime) -> bool { left.name == right.name } @@ -164,7 +204,7 @@ pub fn eq_pat(&mut self, left: &Pat, right: &Pat) -> bool { self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs }, (&PatKind::Binding(ref lb, _, ref li, ref lp), &PatKind::Binding(ref rb, _, ref ri, ref rp)) => { - lb == rb && li.node.as_str() == ri.node.as_str() && both(lp, rp, |l, r| self.eq_pat(l, r)) + lb == rb && li.name.as_str() == ri.name.as_str() && both(lp, rp, |l, r| self.eq_pat(l, r)) }, (&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, r), (&PatKind::Lit(ref l), &PatKind::Lit(ref r)) => self.eq_expr(l, r), @@ -176,7 +216,8 @@ pub fn eq_pat(&mut self, left: &Pat, right: &Pat) -> bool { }, (&PatKind::Ref(ref le, ref lm), &PatKind::Ref(ref re, ref rm)) => lm == rm && self.eq_pat(le, re), (&PatKind::Slice(ref ls, ref li, ref le), &PatKind::Slice(ref rs, ref ri, ref re)) => { - over(ls, rs, |l, r| self.eq_pat(l, r)) && over(le, re, |l, r| self.eq_pat(l, r)) + over(ls, rs, |l, r| self.eq_pat(l, r)) + && over(le, re, |l, r| self.eq_pat(l, r)) && both(li, ri, |l, r| self.eq_pat(l, r)) }, (&PatKind::Wild, &PatKind::Wild) => true, @@ -184,6 +225,7 @@ pub fn eq_pat(&mut self, left: &Pat, right: &Pat) -> bool { } } + #[allow(clippy::similar_names)] fn eq_qpath(&mut self, left: &QPath, right: &QPath) -> bool { match (left, right) { (&QPath::Resolved(ref lty, ref lpath), &QPath::Resolved(ref rty, ref rpath)) => { @@ -201,40 +243,46 @@ fn eq_path(&mut self, left: &Path, right: &Path) -> bool { && over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r)) } - fn eq_path_parameters(&mut self, left: &PathParameters, right: &PathParameters) -> bool { + fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> bool { if !(left.parenthesized || right.parenthesized) { - over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) - && over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) + over(&left.args, &right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work && over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r)) } else if left.parenthesized && right.parenthesized { over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r)) - && both( - &Some(&left.bindings[0].ty), - &Some(&right.bindings[0].ty), - |l, r| self.eq_ty(l, r), - ) + && both(&Some(&left.bindings[0].ty), &Some(&right.bindings[0].ty), |l, r| { + self.eq_ty(l, r) + }) } else { false } } - fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool { + pub fn eq_path_segments(&mut self, left: &[PathSegment], right: &[PathSegment]) -> bool { + left.len() == right.len() && left.iter().zip(right).all(|(l, r)| self.eq_path_segment(l, r)) + } + + pub fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool { // The == of idents doesn't work with different contexts, // we have to be explicit about hygiene - if left.name.as_str() != right.name.as_str() { + if left.ident.as_str() != right.ident.as_str() { return false; } - match (&left.parameters, &right.parameters) { + match (&left.args, &right.args) { (&None, &None) => true, (&Some(ref l), &Some(ref r)) => self.eq_path_parameters(l, r), _ => false, } } - fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool { - match (&left.node, &right.node) { - (&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec), - (&TyArray(ref lt, ref ll_id), &TyArray(ref rt, ref rl_id)) => { + pub fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool { + self.eq_ty_kind(&left.node, &right.node) + } + + #[allow(clippy::similar_names)] + pub fn eq_ty_kind(&mut self, left: &TyKind, right: &TyKind) -> bool { + match (left, right) { + (&TyKind::Slice(ref l_vec), &TyKind::Slice(ref r_vec)) => self.eq_ty(l_vec, r_vec), + (&TyKind::Array(ref lt, ref ll_id), &TyKind::Array(ref rt, ref rl_id)) => { let full_table = self.tables; let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); @@ -249,30 +297,44 @@ fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool { self.tables = full_table; eq_ty && ll == rl }, - (&TyPtr(ref l_mut), &TyPtr(ref r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty), - (&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => { + (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => { + l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty) + }, + (&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => { l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(&*l_rmut.ty, &*r_rmut.ty) }, - (&TyPath(ref l), &TyPath(ref r)) => self.eq_qpath(l, r), - (&TyTup(ref l), &TyTup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)), - (&TyInfer, &TyInfer) => true, + (&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r), + (&TyKind::Tup(ref l), &TyKind::Tup(ref r)) => over(l, r, |l, r| self.eq_ty(l, r)), + (&TyKind::Infer, &TyKind::Infer) => true, _ => false, } } fn eq_type_binding(&mut self, left: &TypeBinding, right: &TypeBinding) -> bool { - left.name == right.name && self.eq_ty(&left.ty, &right.ty) + left.ident.name == right.ident.name && self.eq_ty(&left.ty, &right.ty) } } -fn swap_binop<'a>(binop: BinOp_, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOp_, &'a Expr, &'a Expr)> { +fn swap_binop<'a>(binop: BinOpKind, lhs: &'a Expr, rhs: &'a Expr) -> Option<(BinOpKind, &'a Expr, &'a Expr)> { match binop { - BiAdd | BiMul | BiBitXor | BiBitAnd | BiEq | BiNe | BiBitOr => Some((binop, rhs, lhs)), - BiLt => Some((BiGt, rhs, lhs)), - BiLe => Some((BiGe, rhs, lhs)), - BiGe => Some((BiLe, rhs, lhs)), - BiGt => Some((BiLt, rhs, lhs)), - BiShl | BiShr | BiRem | BiSub | BiDiv | BiAnd | BiOr => None, + BinOpKind::Add + | BinOpKind::Mul + | BinOpKind::Eq + | BinOpKind::Ne + | BinOpKind::BitAnd + | BinOpKind::BitXor + | BinOpKind::BitOr => Some((binop, rhs, lhs)), + BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)), + BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)), + BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)), + BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)), + BinOpKind::Shl + | BinOpKind::Shr + | BinOpKind::Rem + | BinOpKind::Sub + | BinOpKind::Div + | BinOpKind::And + | BinOpKind::Or => None, } } @@ -294,7 +356,6 @@ fn over(left: &[X], right: &[X], mut eq_fn: F) -> bool left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y)) } - /// Type used to hash an ast element. This is different from the `Hash` trait /// on ast types as this /// trait would consider IDs and spans. @@ -329,110 +390,120 @@ pub fn hash_block(&mut self, b: &Block) { self.hash_expr(e); } - b.rules.hash(&mut self.s); + match b.rules { + BlockCheckMode::DefaultBlock => 0, + BlockCheckMode::UnsafeBlock(_) => 1, + BlockCheckMode::PushUnsafeBlock(_) => 2, + BlockCheckMode::PopUnsafeBlock(_) => 3, + } + .hash(&mut self.s); } - #[allow(many_single_char_names)] + #[allow(clippy::many_single_char_names)] pub fn hash_expr(&mut self, e: &Expr) { if let Some(e) = constant_simple(self.cx, self.tables, e) { return e.hash(&mut self.s); } match e.node { - ExprAddrOf(m, ref e) => { - let c: fn(_, _) -> _ = ExprAddrOf; + ExprKind::AddrOf(m, ref e) => { + let c: fn(_, _) -> _ = ExprKind::AddrOf; c.hash(&mut self.s); m.hash(&mut self.s); self.hash_expr(e); }, - ExprAgain(i) => { - let c: fn(_) -> _ = ExprAgain; + ExprKind::Continue(i) => { + let c: fn(_) -> _ = ExprKind::Continue; c.hash(&mut self.s); if let Some(i) = i.label { - self.hash_name(i.name); + self.hash_name(i.ident.name); } }, - ExprYield(ref e) => { - let c: fn(_) -> _ = ExprYield; + ExprKind::Yield(ref e) => { + let c: fn(_) -> _ = ExprKind::Yield; c.hash(&mut self.s); self.hash_expr(e); }, - ExprAssign(ref l, ref r) => { - let c: fn(_, _) -> _ = ExprAssign; + ExprKind::Assign(ref l, ref r) => { + let c: fn(_, _) -> _ = ExprKind::Assign; c.hash(&mut self.s); self.hash_expr(l); self.hash_expr(r); }, - ExprAssignOp(ref o, ref l, ref r) => { - let c: fn(_, _, _) -> _ = ExprAssignOp; + ExprKind::AssignOp(ref o, ref l, ref r) => { + let c: fn(_, _, _) -> _ = ExprKind::AssignOp; c.hash(&mut self.s); o.hash(&mut self.s); self.hash_expr(l); self.hash_expr(r); }, - ExprBlock(ref b, _) => { - let c: fn(_, _) -> _ = ExprBlock; + ExprKind::Block(ref b, _) => { + let c: fn(_, _) -> _ = ExprKind::Block; c.hash(&mut self.s); self.hash_block(b); }, - ExprBinary(op, ref l, ref r) => { - let c: fn(_, _, _) -> _ = ExprBinary; + ExprKind::Binary(op, ref l, ref r) => { + let c: fn(_, _, _) -> _ = ExprKind::Binary; c.hash(&mut self.s); op.node.hash(&mut self.s); self.hash_expr(l); self.hash_expr(r); }, - ExprBreak(i, ref j) => { - let c: fn(_, _) -> _ = ExprBreak; + ExprKind::Break(i, ref j) => { + let c: fn(_, _) -> _ = ExprKind::Break; c.hash(&mut self.s); if let Some(i) = i.label { - self.hash_name(i.name); + self.hash_name(i.ident.name); } if let Some(ref j) = *j { self.hash_expr(&*j); } }, - ExprBox(ref e) => { - let c: fn(_) -> _ = ExprBox; + ExprKind::Box(ref e) => { + let c: fn(_) -> _ = ExprKind::Box; c.hash(&mut self.s); self.hash_expr(e); }, - ExprCall(ref fun, ref args) => { - let c: fn(_, _) -> _ = ExprCall; + ExprKind::Call(ref fun, ref args) => { + let c: fn(_, _) -> _ = ExprKind::Call; c.hash(&mut self.s); self.hash_expr(fun); self.hash_exprs(args); }, - ExprCast(ref e, ref _ty) => { - let c: fn(_, _) -> _ = ExprCast; + ExprKind::Cast(ref e, ref _ty) => { + let c: fn(_, _) -> _ = ExprKind::Cast; c.hash(&mut self.s); self.hash_expr(e); // TODO: _ty }, - ExprClosure(cap, _, eid, _, _) => { - let c: fn(_, _, _, _, _) -> _ = ExprClosure; + ExprKind::Closure(cap, _, eid, _, _) => { + let c: fn(_, _, _, _, _) -> _ = ExprKind::Closure; c.hash(&mut self.s); - cap.hash(&mut self.s); + match cap { + CaptureClause::CaptureByValue => 0, + CaptureClause::CaptureByRef => 1, + } + .hash(&mut self.s); self.hash_expr(&self.cx.tcx.hir.body(eid).value); }, - ExprField(ref e, ref f) => { - let c: fn(_, _) -> _ = ExprField; + ExprKind::Field(ref e, ref f) => { + let c: fn(_, _) -> _ = ExprKind::Field; c.hash(&mut self.s); self.hash_expr(e); self.hash_name(f.name); }, - ExprIndex(ref a, ref i) => { - let c: fn(_, _) -> _ = ExprIndex; + ExprKind::Index(ref a, ref i) => { + let c: fn(_, _) -> _ = ExprKind::Index; c.hash(&mut self.s); self.hash_expr(a); self.hash_expr(i); }, - ExprInlineAsm(..) => { - let c: fn(_, _, _) -> _ = ExprInlineAsm; + ExprKind::InlineAsm(..) => { + let c: fn(_, _, _) -> _ = ExprKind::InlineAsm; c.hash(&mut self.s); }, - ExprIf(ref cond, ref t, ref e) => { - let c: fn(_, _, _) -> _ = ExprIf; + ExprKind::If(ref cond, ref t, ref e) => { + let c: fn(_, _, _) -> _ = ExprKind::If; c.hash(&mut self.s); self.hash_expr(cond); self.hash_expr(&**t); @@ -440,42 +511,42 @@ pub fn hash_expr(&mut self, e: &Expr) { self.hash_expr(e); } }, - ExprLit(ref l) => { - let c: fn(_) -> _ = ExprLit; + ExprKind::Lit(ref l) => { + let c: fn(_) -> _ = ExprKind::Lit; c.hash(&mut self.s); l.hash(&mut self.s); }, - ExprLoop(ref b, ref i, _) => { - let c: fn(_, _, _) -> _ = ExprLoop; + ExprKind::Loop(ref b, ref i, _) => { + let c: fn(_, _, _) -> _ = ExprKind::Loop; c.hash(&mut self.s); self.hash_block(b); if let Some(i) = *i { - self.hash_name(i.name); + self.hash_name(i.ident.name); } }, - ExprMatch(ref e, ref arms, ref s) => { - let c: fn(_, _, _) -> _ = ExprMatch; + ExprKind::Match(ref e, ref arms, ref s) => { + let c: fn(_, _, _) -> _ = ExprKind::Match; c.hash(&mut self.s); self.hash_expr(e); for arm in arms { // TODO: arm.pat? if let Some(ref e) = arm.guard { - self.hash_expr(e); + self.hash_guard(e); } self.hash_expr(&arm.body); } s.hash(&mut self.s); }, - ExprMethodCall(ref path, ref _tys, ref args) => { - let c: fn(_, _, _) -> _ = ExprMethodCall; + ExprKind::MethodCall(ref path, ref _tys, ref args) => { + let c: fn(_, _, _) -> _ = ExprKind::MethodCall; c.hash(&mut self.s); - self.hash_name(path.name); + self.hash_name(path.ident.name); self.hash_exprs(args); }, - ExprRepeat(ref e, ref l_id) => { - let c: fn(_, _) -> _ = ExprRepeat; + ExprKind::Repeat(ref e, ref l_id) => { + let c: fn(_, _) -> _ = ExprKind::Repeat; c.hash(&mut self.s); self.hash_expr(e); let full_table = self.tables; @@ -483,20 +554,20 @@ pub fn hash_expr(&mut self, e: &Expr) { self.hash_expr(&self.cx.tcx.hir.body(l_id.body).value); self.tables = full_table; }, - ExprRet(ref e) => { - let c: fn(_) -> _ = ExprRet; + ExprKind::Ret(ref e) => { + let c: fn(_) -> _ = ExprKind::Ret; c.hash(&mut self.s); if let Some(ref e) = *e { self.hash_expr(e); } }, - ExprPath(ref qpath) => { - let c: fn(_) -> _ = ExprPath; + ExprKind::Path(ref qpath) => { + let c: fn(_) -> _ = ExprKind::Path; c.hash(&mut self.s); self.hash_qpath(qpath); }, - ExprStruct(ref path, ref fields, ref expr) => { - let c: fn(_, _, _) -> _ = ExprStruct; + ExprKind::Struct(ref path, ref fields, ref expr) => { + let c: fn(_, _, _) -> _ = ExprKind::Struct; c.hash(&mut self.s); self.hash_qpath(path); @@ -510,38 +581,38 @@ pub fn hash_expr(&mut self, e: &Expr) { self.hash_expr(e); } }, - ExprTup(ref tup) => { - let c: fn(_) -> _ = ExprTup; + ExprKind::Tup(ref tup) => { + let c: fn(_) -> _ = ExprKind::Tup; c.hash(&mut self.s); self.hash_exprs(tup); }, - ExprType(ref e, ref _ty) => { - let c: fn(_, _) -> _ = ExprType; + ExprKind::Type(ref e, ref _ty) => { + let c: fn(_, _) -> _ = ExprKind::Type; c.hash(&mut self.s); self.hash_expr(e); // TODO: _ty }, - ExprUnary(lop, ref le) => { - let c: fn(_, _) -> _ = ExprUnary; + ExprKind::Unary(lop, ref le) => { + let c: fn(_, _) -> _ = ExprKind::Unary; c.hash(&mut self.s); lop.hash(&mut self.s); self.hash_expr(le); }, - ExprArray(ref v) => { - let c: fn(_) -> _ = ExprArray; + ExprKind::Array(ref v) => { + let c: fn(_) -> _ = ExprKind::Array; c.hash(&mut self.s); self.hash_exprs(v); }, - ExprWhile(ref cond, ref b, l) => { - let c: fn(_, _, _) -> _ = ExprWhile; + ExprKind::While(ref cond, ref b, l) => { + let c: fn(_, _, _) -> _ = ExprKind::While; c.hash(&mut self.s); self.hash_expr(cond); self.hash_block(b); if let Some(l) = l { - self.hash_name(l.name); + self.hash_name(l.ident.name); } }, } @@ -563,7 +634,7 @@ pub fn hash_qpath(&mut self, p: &QPath) { self.hash_path(path); }, QPath::TypeRelative(_, ref path) => { - self.hash_name(path.name); + self.hash_name(path.ident.name); }, } // self.cx.tables.qpath_def(p, id).hash(&mut self.s); @@ -572,29 +643,39 @@ pub fn hash_qpath(&mut self, p: &QPath) { pub fn hash_path(&mut self, p: &Path) { p.is_global().hash(&mut self.s); for p in &p.segments { - self.hash_name(p.name); + self.hash_name(p.ident.name); } } pub fn hash_stmt(&mut self, b: &Stmt) { match b.node { - StmtDecl(ref decl, _) => { - let c: fn(_, _) -> _ = StmtDecl; + StmtKind::Decl(ref decl, _) => { + let c: fn(_, _) -> _ = StmtKind::Decl; c.hash(&mut self.s); - if let DeclLocal(ref local) = decl.node { + if let DeclKind::Local(ref local) = decl.node { if let Some(ref init) = local.init { self.hash_expr(init); } } }, - StmtExpr(ref expr, _) => { - let c: fn(_, _) -> _ = StmtExpr; + StmtKind::Expr(ref expr, _) => { + let c: fn(_, _) -> _ = StmtKind::Expr; c.hash(&mut self.s); self.hash_expr(expr); }, - StmtSemi(ref expr, _) => { - let c: fn(_, _) -> _ = StmtSemi; + StmtKind::Semi(ref expr, _) => { + let c: fn(_, _) -> _ = StmtKind::Semi; + c.hash(&mut self.s); + self.hash_expr(expr); + }, + } + } + + pub fn hash_guard(&mut self, g: &Guard) { + match g { + Guard::If(ref expr) => { + let c: fn(_) -> _ = Guard::If; c.hash(&mut self.s); self.hash_expr(expr); },