1
Fork 0

rustc_lint: only query typeck_tables_of when a lint needs it.

This commit is contained in:
Eduard-Mihai Burtescu 2020-06-26 02:56:23 +03:00
parent 80bcbf521c
commit f5ce0e5fe9
100 changed files with 361 additions and 366 deletions

View file

@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
_ => (), _ => (),
} }
let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r)); let (l_ty, r_ty) = (cx.tables().expr_ty(l), cx.tables().expr_ty(r));
if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() { if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() {
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
self.expr_span = Some(expr.span); self.expr_span = Some(expr.span);
@ -96,8 +96,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
} }
}, },
hir::ExprKind::Unary(hir::UnOp::UnNeg, arg) => { hir::ExprKind::Unary(hir::UnOp::UnNeg, arg) => {
let ty = cx.tables.expr_ty(arg); let ty = cx.tables().expr_ty(arg);
if constant_simple(cx, cx.tables, expr).is_none() { if constant_simple(cx, cx.tables(), expr).is_none() {
if ty.is_integral() { if ty.is_integral() {
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
self.expr_span = Some(expr.span); self.expr_span = Some(expr.span);

View file

@ -72,7 +72,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants {
} }
if_chain! { if_chain! {
if let ExprKind::Unary(_, ref lit) = e.kind; if let ExprKind::Unary(_, ref lit) = e.kind;
if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, lit); if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables(), lit);
if is_true; if is_true;
then { then {
lint_true(true); lint_true(true);
@ -121,7 +121,7 @@ fn match_assert_with_message<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx E
if let ExprKind::DropTemps(ref expr) = expr.kind; if let ExprKind::DropTemps(ref expr) = expr.kind;
if let ExprKind::Unary(UnOp::UnNot, ref expr) = expr.kind; if let ExprKind::Unary(UnOp::UnNot, ref expr) = expr.kind;
// bind the first argument of the `assert!` macro // bind the first argument of the `assert!` macro
if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, expr); if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables(), expr);
// arm 1 pattern // arm 1 pattern
if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind; if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind;
if let ExprKind::Lit(ref lit) = lit_expr.kind; if let ExprKind::Lit(ref lit) = lit_expr.kind;

View file

@ -82,8 +82,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
hir::ExprKind::Assign(assignee, e, _) => { hir::ExprKind::Assign(assignee, e, _) => {
if let hir::ExprKind::Binary(op, l, r) = &e.kind { if let hir::ExprKind::Binary(op, l, r) = &e.kind {
let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| { let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
let ty = cx.tables.expr_ty(assignee); let ty = cx.tables().expr_ty(assignee);
let rty = cx.tables.expr_ty(rhs); let rty = cx.tables().expr_ty(rhs);
macro_rules! ops { macro_rules! ops {
($op:expr, ($op:expr,
$cx:expr, $cx:expr,
@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
// a = b commutative_op a // a = b commutative_op a
// Limited to primitive type as these ops are know to be commutative // Limited to primitive type as these ops are know to be commutative
if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r)
&& cx.tables.expr_ty(assignee).is_primitive_ty() && cx.tables().expr_ty(assignee).is_primitive_ty()
{ {
match op.node { match op.node {
hir::BinOpKind::Add hir::BinOpKind::Add

View file

@ -53,7 +53,7 @@ const ATOMIC_TYPES: [&str; 12] = [
]; ];
fn type_is_atomic(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn type_is_atomic(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
if let ty::Adt(&ty::AdtDef { did, .. }, _) = cx.tables.expr_ty(expr).kind { if let ty::Adt(&ty::AdtDef { did, .. }, _) = cx.tables().expr_ty(expr).kind {
ATOMIC_TYPES ATOMIC_TYPES
.iter() .iter()
.any(|ty| match_def_path(cx, did, &["core", "sync", "atomic", ty])) .any(|ty| match_def_path(cx, did, &["core", "sync", "atomic", ty]))
@ -76,7 +76,7 @@ fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
if method == "load" || method == "store"; if method == "load" || method == "store";
let ordering_arg = if method == "load" { &args[1] } else { &args[2] }; let ordering_arg = if method == "load" { &args[1] } else { &args[2] };
if let ExprKind::Path(ref ordering_qpath) = ordering_arg.kind; if let ExprKind::Path(ref ordering_qpath) = ordering_arg.kind;
if let Some(ordering_def_id) = cx.tables.qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id(); if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, ordering_arg.hir_id).opt_def_id();
then { then {
if method == "load" && if method == "load" &&
match_ordering_def_path(cx, ordering_def_id, &["Release", "AcqRel"]) { match_ordering_def_path(cx, ordering_def_id, &["Release", "AcqRel"]) {
@ -107,12 +107,12 @@ fn check_memory_fence(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
if_chain! { if_chain! {
if let ExprKind::Call(ref func, ref args) = expr.kind; if let ExprKind::Call(ref func, ref args) = expr.kind;
if let ExprKind::Path(ref func_qpath) = func.kind; if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id();
if ["fence", "compiler_fence"] if ["fence", "compiler_fence"]
.iter() .iter()
.any(|func| match_def_path(cx, def_id, &["core", "sync", "atomic", func])); .any(|func| match_def_path(cx, def_id, &["core", "sync", "atomic", func]));
if let ExprKind::Path(ref ordering_qpath) = &args[0].kind; if let ExprKind::Path(ref ordering_qpath) = &args[0].kind;
if let Some(ordering_def_id) = cx.tables.qpath_res(ordering_qpath, args[0].hir_id).opt_def_id(); if let Some(ordering_def_id) = cx.tables().qpath_res(ordering_qpath, args[0].hir_id).opt_def_id();
if match_ordering_def_path(cx, ordering_def_id, &["Relaxed"]); if match_ordering_def_path(cx, ordering_def_id, &["Relaxed"]);
then { then {
span_lint_and_help( span_lint_and_help(

View file

@ -319,7 +319,7 @@ fn check_ineffective_gt(cx: &LateContext<'_, '_>, span: Span, m: u128, c: u128,
} }
fn fetch_int_literal(cx: &LateContext<'_, '_>, lit: &Expr<'_>) -> Option<u128> { fn fetch_int_literal(cx: &LateContext<'_, '_>, lit: &Expr<'_>) -> Option<u128> {
match constant(cx, cx.tables, lit)?.0 { match constant(cx, cx.tables(), lit)?.0 {
Constant::Int(n) => Some(n), Constant::Int(n) => Some(n),
_ => None, _ => None,
} }

View file

@ -248,7 +248,7 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<String> {
}) })
}, },
ExprKind::MethodCall(path, _, args, _) if args.len() == 1 => { ExprKind::MethodCall(path, _, args, _) if args.len() == 1 => {
let type_of_receiver = cx.tables.expr_ty(&args[0]); let type_of_receiver = cx.tables().expr_ty(&args[0]);
if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type)) if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type))
&& !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type)) && !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type))
{ {
@ -450,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
self.bool_expr(e) self.bool_expr(e)
}, },
ExprKind::Unary(UnOp::UnNot, inner) => { ExprKind::Unary(UnOp::UnNot, inner) => {
if self.cx.tables.node_types()[inner.hir_id].is_bool() { if self.cx.tables().node_types()[inner.hir_id].is_bool() {
self.bool_expr(e); self.bool_expr(e);
} else { } else {
walk_expr(self, e); walk_expr(self, e);
@ -465,7 +465,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
} }
fn implements_ord<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { fn implements_ord<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[])) get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]))
} }

View file

@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
if let ExprKind::Binary(ref op, ref l, ref r) = body.value.kind; if let ExprKind::Binary(ref op, ref l, ref r) = body.value.kind;
if op.node == BinOpKind::Eq; if op.node == BinOpKind::Eq;
if match_type(cx, if match_type(cx,
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])), walk_ptrs_ty(cx.tables().expr_ty(&filter_args[0])),
&paths::SLICE_ITER); &paths::SLICE_ITER);
then { then {
let needle = match get_path_name(l) { let needle = match get_path_name(l) {
@ -63,7 +63,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
_ => { return; } _ => { return; }
} }
}; };
if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).kind { if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables().expr_ty(needle)).kind {
return; return;
} }
let haystack = if let ExprKind::MethodCall(ref path, _, ref args, _) = let haystack = if let ExprKind::MethodCall(ref path, _, ref args, _) =

View file

@ -60,7 +60,7 @@ impl CognitiveComplexity {
let mut helper = CCHelper { cc: 1, returns: 0 }; let mut helper = CCHelper { cc: 1, returns: 0 };
helper.visit_expr(expr); helper.visit_expr(expr);
let CCHelper { cc, returns } = helper; let CCHelper { cc, returns } = helper;
let ret_ty = cx.tables.node_type(expr.hir_id); let ret_ty = cx.tables().node_type(expr.hir_id);
let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym!(result_type)) { let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym!(result_type)) {
returns returns
} else { } else {

View file

@ -99,7 +99,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain {
} }
// Check that the type being compared implements `core::cmp::Ord` // Check that the type being compared implements `core::cmp::Ord`
let ty = cx.tables.expr_ty(lhs1); let ty = cx.tables().expr_ty(lhs1);
let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[])); let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]));
if !is_ord { if !is_ord {

View file

@ -192,7 +192,7 @@ fn lint_same_then_else(cx: &LateContext<'_, '_>, blocks: &[&Block<'_>]) {
/// Implementation of `IFS_SAME_COND`. /// Implementation of `IFS_SAME_COND`.
fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) {
let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 {
let mut h = SpanlessHash::new(cx, cx.tables); let mut h = SpanlessHash::new(cx, cx.tables());
h.hash_expr(expr); h.hash_expr(expr);
h.finish() h.finish()
}; };
@ -215,7 +215,7 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) {
/// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`. /// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`.
fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) { fn lint_same_fns_in_if_cond(cx: &LateContext<'_, '_>, conds: &[&Expr<'_>]) {
let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 { let hash: &dyn Fn(&&Expr<'_>) -> u64 = &|expr| -> u64 {
let mut h = SpanlessHash::new(cx, cx.tables); let mut h = SpanlessHash::new(cx, cx.tables());
h.hash_expr(expr); h.hash_expr(expr);
h.finish() h.finish()
}; };
@ -251,7 +251,7 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr<'_>) {
if let ExprKind::Match(_, ref arms, MatchSource::Normal) = expr.kind { if let ExprKind::Match(_, ref arms, MatchSource::Normal) = expr.kind {
let hash = |&(_, arm): &(usize, &Arm<'_>)| -> u64 { let hash = |&(_, arm): &(usize, &Arm<'_>)| -> u64 {
let mut h = SpanlessHash::new(cx, cx.tables); let mut h = SpanlessHash::new(cx, cx.tables());
h.hash_expr(&arm.body); h.hash_expr(&arm.body);
h.finish() h.finish()
}; };
@ -320,7 +320,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat<'_>) -> FxHashMap<Sy
}, },
PatKind::Binding(.., ident, ref as_pat) => { PatKind::Binding(.., ident, ref as_pat) => {
if let Entry::Vacant(v) = map.entry(ident.name) { if let Entry::Vacant(v) = map.entry(ident.name) {
v.insert(cx.tables.pat_ty(pat)); v.insert(cx.tables().pat_ty(pat));
} }
if let Some(ref as_pat) = *as_pat { if let Some(ref as_pat) = *as_pat {
bindings_impl(cx, as_pat, map); bindings_impl(cx, as_pat, map);

View file

@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
if let ExprKind::Call(ref path, ..) = expr.kind; if let ExprKind::Call(ref path, ..) = expr.kind;
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id); if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
if let ExprKind::Path(ref qpath) = path.kind; if let ExprKind::Path(ref qpath) = path.kind;
if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD); if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
then { then {
match qpath { match qpath {
@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
// TODO: Work out a way to put "whatever the imported way of referencing // TODO: Work out a way to put "whatever the imported way of referencing
// this type in this file" rather than a fully-qualified type. // this type in this file" rather than a fully-qualified type.
let expr_ty = cx.tables.expr_ty(expr); let expr_ty = cx.tables().expr_ty(expr);
if let ty::Adt(..) = expr_ty.kind { if let ty::Adt(..) = expr_ty.kind {
let replacement = format!("{}::default()", expr_ty); let replacement = format!("{}::default()", expr_ty);
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -73,12 +73,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing {
fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) { fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) {
match method_name { match method_name {
"deref" => { "deref" => {
if cx if cx.tcx.lang_items().deref_trait().map_or(false, |id| {
.tcx implements_trait(cx, cx.tables().expr_ty(&call_expr), id, &[])
.lang_items() }) {
.deref_trait()
.map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[]))
{
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
EXPLICIT_DEREF_METHODS, EXPLICIT_DEREF_METHODS,
@ -91,12 +88,9 @@ fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>,
} }
}, },
"deref_mut" => { "deref_mut" => {
if cx if cx.tcx.lang_items().deref_mut_trait().map_or(false, |id| {
.tcx implements_trait(cx, cx.tables().expr_ty(&call_expr), id, &[])
.lang_items() }) {
.deref_mut_trait()
.map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[]))
{
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
EXPLICIT_DEREF_METHODS, EXPLICIT_DEREF_METHODS,

View file

@ -119,7 +119,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropForgetRef {
let lint; let lint;
let msg; let msg;
let arg = &args[0]; let arg = &args[0];
let arg_ty = cx.tables.expr_ty(arg); let arg_ty = cx.tables().expr_ty(arg);
if let ty::Ref(..) = arg_ty.kind { if let ty::Ref(..) = arg_ty.kind {
if match_def_path(cx, def_id, &paths::DROP) { if match_def_path(cx, def_id, &paths::DROP) {

View file

@ -43,8 +43,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec {
if_chain! { if_chain! {
if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.kind; if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.kind;
if let ExprKind::MethodCall(ref method_path, _ , ref args, _) = left.kind; if let ExprKind::MethodCall(ref method_path, _ , ref args, _) = left.kind;
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION); if match_type(cx, walk_ptrs_ty(cx.tables().expr_ty(&args[0])), &paths::DURATION);
if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right); if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables(), right);
then { then {
let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) { let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) {
("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis", ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis",

View file

@ -109,7 +109,7 @@ fn check_cond<'a, 'tcx, 'b>(
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref key) = params[1].kind; if let ExprKind::AddrOf(BorrowKind::Ref, _, ref key) = params[1].kind;
then { then {
let map = &params[0]; let map = &params[0];
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map)); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(map));
return if match_type(cx, obj_ty, &paths::BTREEMAP) { return if match_type(cx, obj_ty, &paths::BTREEMAP) {
Some(("BTreeMap", map, key)) Some(("BTreeMap", map, key))

View file

@ -103,8 +103,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
(&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {}, (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
// &foo == &bar // &foo == &bar
(&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => { (&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => {
let lty = cx.tables.expr_ty(l); let lty = cx.tables().expr_ty(l);
let rty = cx.tables.expr_ty(r); let rty = cx.tables().expr_ty(r);
let lcpy = is_copy(cx, lty); let lcpy = is_copy(cx, lty);
let rcpy = is_copy(cx, rty); let rcpy = is_copy(cx, rty);
// either operator autorefs or both args are copyable // either operator autorefs or both args are copyable
@ -126,7 +126,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
) )
} else if lcpy } else if lcpy
&& !rcpy && !rcpy
&& implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) && implements_trait(cx, lty, trait_id, &[cx.tables().expr_ty(right).into()])
{ {
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -145,7 +145,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
) )
} else if !lcpy } else if !lcpy
&& rcpy && rcpy
&& implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) && implements_trait(cx, cx.tables().expr_ty(left), trait_id, &[rty.into()])
{ {
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -166,10 +166,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
}, },
// &foo == bar // &foo == bar
(&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), _) => { (&ExprKind::AddrOf(BorrowKind::Ref, _, ref l), _) => {
let lty = cx.tables.expr_ty(l); let lty = cx.tables().expr_ty(l);
let lcpy = is_copy(cx, lty); let lcpy = is_copy(cx, lty);
if (requires_ref || lcpy) if (requires_ref || lcpy)
&& implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right).into()]) && implements_trait(cx, lty, trait_id, &[cx.tables().expr_ty(right).into()])
{ {
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -190,10 +190,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
}, },
// foo == &bar // foo == &bar
(_, &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => { (_, &ExprKind::AddrOf(BorrowKind::Ref, _, ref r)) => {
let rty = cx.tables.expr_ty(r); let rty = cx.tables().expr_ty(r);
let rcpy = is_copy(cx, rty); let rcpy = is_copy(cx, rty);
if (requires_ref || rcpy) if (requires_ref || rcpy)
&& implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty.into()]) && implements_trait(cx, cx.tables().expr_ty(left), trait_id, &[rty.into()])
{ {
span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| { span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| {
let rsnip = snippet(cx, r.span, "...").to_string(); let rsnip = snippet(cx, r.span, "...").to_string();

View file

@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp {
} }
fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, span: Span) { fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, span: Span) {
if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables, e) { if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables(), e) {
span_lint( span_lint(
cx, cx,
ERASING_OP, ERASING_OP,

View file

@ -84,7 +84,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal {
let fn_def_id = cx.tcx.hir().local_def_id(hir_id); let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
cx.tcx.infer_ctxt().enter(|infcx| { cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body); ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.tables()).consume_body(body);
}); });
for node in v.set { for node in v.set {

View file

@ -97,7 +97,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
// Are the expression or the arguments type-adjusted? Then we need the closure // Are the expression or the arguments type-adjusted? Then we need the closure
if !(is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg))); if !(is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg)));
let fn_ty = cx.tables.expr_ty(caller); let fn_ty = cx.tables().expr_ty(caller);
if matches!(fn_ty.kind, ty::FnDef(_, _) | ty::FnPtr(_) | ty::Closure(_, _)); if matches!(fn_ty.kind, ty::FnDef(_, _) | ty::FnPtr(_) | ty::Closure(_, _));
@ -128,7 +128,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
// Are the expression or the arguments type-adjusted? Then we need the closure // Are the expression or the arguments type-adjusted? Then we need the closure
if !(is_adjusted(cx, ex) || args.iter().skip(1).any(|arg| is_adjusted(cx, arg))); if !(is_adjusted(cx, ex) || args.iter().skip(1).any(|arg| is_adjusted(cx, arg)));
let method_def_id = cx.tables.type_dependent_def_id(ex.hir_id).unwrap(); let method_def_id = cx.tables().type_dependent_def_id(ex.hir_id).unwrap();
if !type_is_unsafe_function(cx, cx.tcx.type_of(method_def_id)); if !type_is_unsafe_function(cx, cx.tcx.type_of(method_def_id));
if compare_inputs(&mut iter_input_pats(decl, body), &mut args.iter()); if compare_inputs(&mut iter_input_pats(decl, body), &mut args.iter());
@ -153,7 +153,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
/// Tries to determine the type for universal function call to be used instead of the closure /// Tries to determine the type for universal function call to be used instead of the closure
fn get_ufcs_type_name(cx: &LateContext<'_, '_>, method_def_id: def_id::DefId, self_arg: &Expr<'_>) -> Option<String> { fn get_ufcs_type_name(cx: &LateContext<'_, '_>, method_def_id: def_id::DefId, self_arg: &Expr<'_>) -> Option<String> {
let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0]; let expected_type_of_self = &cx.tcx.fn_sig(method_def_id).inputs_and_output().skip_binder()[0];
let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id); let actual_type_of_self = &cx.tables().node_type(self_arg.hir_id);
if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) { if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) {
if match_borrow_depth(expected_type_of_self, &actual_type_of_self) if match_borrow_depth(expected_type_of_self, &actual_type_of_self)

View file

@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence {
if let ExprKind::Path(ref qpath) = lhs.kind { if let ExprKind::Path(ref qpath) = lhs.kind {
if let QPath::Resolved(_, ref path) = *qpath { if let QPath::Resolved(_, ref path) = *qpath {
if path.segments.len() == 1 { if path.segments.len() == 1 {
if let def::Res::Local(var) = cx.tables.qpath_res(qpath, lhs.hir_id) { if let def::Res::Local(var) = cx.tables().qpath_res(qpath, lhs.hir_id) {
let mut visitor = ReadVisitor { let mut visitor = ReadVisitor {
cx, cx,
var, var,
@ -137,7 +137,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
match e.kind { match e.kind {
ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e), ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e),
ExprKind::Call(ref func, _) => { ExprKind::Call(ref func, _) => {
let typ = self.cx.tables.expr_ty(func); let typ = self.cx.tables().expr_ty(func);
match typ.kind { match typ.kind {
ty::FnDef(..) | ty::FnPtr(_) => { ty::FnDef(..) | ty::FnPtr(_) => {
let sig = typ.fn_sig(self.cx.tcx); let sig = typ.fn_sig(self.cx.tcx);
@ -149,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
} }
}, },
ExprKind::MethodCall(..) => { ExprKind::MethodCall(..) => {
let borrowed_table = self.cx.tables; let borrowed_table = self.cx.tables();
if borrowed_table.expr_ty(e).is_never() { if borrowed_table.expr_ty(e).is_never() {
self.report_diverging_sub_expr(e); self.report_diverging_sub_expr(e);
} }
@ -309,7 +309,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
if_chain! { if_chain! {
if let QPath::Resolved(None, ref path) = *qpath; if let QPath::Resolved(None, ref path) = *qpath;
if path.segments.len() == 1; if path.segments.len() == 1;
if let def::Res::Local(local_id) = self.cx.tables.qpath_res(qpath, expr.hir_id); if let def::Res::Local(local_id) = self.cx.tables().qpath_res(qpath, expr.hir_id);
if local_id == self.var; if local_id == self.var;
// Check that this is a read, not a write. // Check that this is a read, not a write.
if !is_in_assignment_position(self.cx, expr); if !is_in_assignment_position(self.cx, expr);

View file

@ -61,7 +61,7 @@ declare_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatLiteral { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatLiteral {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! { if_chain! {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if let ty::Float(fty) = ty.kind; if let ty::Float(fty) = ty.kind;
if let hir::ExprKind::Lit(ref lit) = expr.kind; if let hir::ExprKind::Lit(ref lit) = expr.kind;
if let LitKind::Float(sym, lit_float_ty) = lit.node; if let LitKind::Float(sym, lit_float_ty) = lit.node;

View file

@ -112,7 +112,7 @@ declare_lint_pass!(FloatingPointArithmetic => [
// Returns the specialized log method for a given base if base is constant // Returns the specialized log method for a given base if base is constant
// and is one of 2, 10 and e // and is one of 2, 10 and e
fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Option<&'static str> { fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Option<&'static str> {
if let Some((value, _)) = constant(cx, cx.tables, base) { if let Some((value, _)) = constant(cx, cx.tables(), base) {
if F32(2.0) == value || F64(2.0) == value { if F32(2.0) == value || F64(2.0) == value {
return Some("log2"); return Some("log2");
} else if F32(10.0) == value || F64(10.0) == value { } else if F32(10.0) == value || F64(10.0) == value {
@ -136,7 +136,7 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_, '_>, mut expr: &'a Expr<'a>) -
if_chain! { if_chain! {
// if the expression is a float literal and it is unsuffixed then // if the expression is a float literal and it is unsuffixed then
// add a suffix so the suggestion is valid and unambiguous // add a suffix so the suggestion is valid and unambiguous
if let ty::Float(float_ty) = cx.tables.expr_ty(expr).kind; if let ty::Float(float_ty) = cx.tables().expr_ty(expr).kind;
if let ExprKind::Lit(lit) = &expr.kind; if let ExprKind::Lit(lit) = &expr.kind;
if let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node; if let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node;
then { then {
@ -188,7 +188,7 @@ fn check_ln1p(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
rhs, rhs,
) = &args[0].kind ) = &args[0].kind
{ {
let recv = match (constant(cx, cx.tables, lhs), constant(cx, cx.tables, rhs)) { let recv = match (constant(cx, cx.tables(), lhs), constant(cx, cx.tables(), rhs)) {
(Some((value, _)), _) if F32(1.0) == value || F64(1.0) == value => rhs, (Some((value, _)), _) if F32(1.0) == value || F64(1.0) == value => rhs,
(_, Some((value, _))) if F32(1.0) == value || F64(1.0) == value => lhs, (_, Some((value, _))) if F32(1.0) == value || F64(1.0) == value => lhs,
_ => return, _ => return,
@ -233,7 +233,7 @@ fn get_integer_from_float_constant(value: &Constant) -> Option<i32> {
fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
// Check receiver // Check receiver
if let Some((value, _)) = constant(cx, cx.tables, &args[0]) { if let Some((value, _)) = constant(cx, cx.tables(), &args[0]) {
let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value {
"exp" "exp"
} else if F32(2.0) == value || F64(2.0) == value { } else if F32(2.0) == value || F64(2.0) == value {
@ -254,7 +254,7 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
} }
// Check argument // Check argument
if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { if let Some((value, _)) = constant(cx, cx.tables(), &args[1]) {
let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value {
( (
SUBOPTIMAL_FLOPS, SUBOPTIMAL_FLOPS,
@ -298,11 +298,11 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
if_chain! { if_chain! {
if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) = expr.kind; if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) = expr.kind;
if cx.tables.expr_ty(lhs).is_floating_point(); if cx.tables().expr_ty(lhs).is_floating_point();
if let Some((value, _)) = constant(cx, cx.tables, rhs); if let Some((value, _)) = constant(cx, cx.tables(), rhs);
if F32(1.0) == value || F64(1.0) == value; if F32(1.0) == value || F64(1.0) == value;
if let ExprKind::MethodCall(ref path, _, ref method_args, _) = lhs.kind; if let ExprKind::MethodCall(ref path, _, ref method_args, _) = lhs.kind;
if cx.tables.expr_ty(&method_args[0]).is_floating_point(); if cx.tables().expr_ty(&method_args[0]).is_floating_point();
if path.ident.name.as_str() == "exp"; if path.ident.name.as_str() == "exp";
then { then {
span_lint_and_sugg( span_lint_and_sugg(
@ -324,8 +324,8 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> {
if_chain! { if_chain! {
if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lhs, ref rhs) = &expr.kind; if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lhs, ref rhs) = &expr.kind;
if cx.tables.expr_ty(lhs).is_floating_point(); if cx.tables().expr_ty(lhs).is_floating_point();
if cx.tables.expr_ty(rhs).is_floating_point(); if cx.tables().expr_ty(rhs).is_floating_point();
then { then {
return Some((lhs, rhs)); return Some((lhs, rhs));
} }
@ -404,7 +404,7 @@ fn are_exprs_equal(cx: &LateContext<'_, '_>, expr1: &Expr<'_>, expr2: &Expr<'_>)
/// Returns true iff expr is some zero literal /// Returns true iff expr is some zero literal
fn is_zero(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_zero(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
match constant_simple(cx, cx.tables, expr) { match constant_simple(cx, cx.tables(), expr) {
Some(Constant::Int(i)) => i == 0, Some(Constant::Int(i)) => i == 0,
Some(Constant::F32(f)) => f == 0.0, Some(Constant::F32(f)) => f == 0.0,
Some(Constant::F64(f)) => f == 0.0, Some(Constant::F64(f)) => f == 0.0,
@ -482,7 +482,7 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind { if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind {
let recv_ty = cx.tables.expr_ty(&args[0]); let recv_ty = cx.tables().expr_ty(&args[0]);
if recv_ty.is_floating_point() { if recv_ty.is_floating_point() {
match &*path.ident.name.as_str() { match &*path.ident.name.as_str() {

View file

@ -88,13 +88,13 @@ fn on_argumentv1_new<'a, 'tcx>(
// matches `core::fmt::Display::fmt` // matches `core::fmt::Display::fmt`
if args.len() == 2; if args.len() == 2;
if let ExprKind::Path(ref qpath) = args[1].kind; if let ExprKind::Path(ref qpath) = args[1].kind;
if let Some(did) = cx.tables.qpath_res(qpath, args[1].hir_id).opt_def_id(); if let Some(did) = cx.tables().qpath_res(qpath, args[1].hir_id).opt_def_id();
if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD); if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD);
// check `(arg0,)` in match block // check `(arg0,)` in match block
if let PatKind::Tuple(ref pats, None) = arms[0].pat.kind; if let PatKind::Tuple(ref pats, None) = arms[0].pat.kind;
if pats.len() == 1; if pats.len() == 1;
then { then {
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0])); let ty = walk_ptrs_ty(cx.tables().pat_ty(&pats[0]));
if ty.kind != rustc_middle::ty::Str && !is_type_diagnostic_item(cx, ty, sym!(string_type)) { if ty.kind != rustc_middle::ty::Str && !is_type_diagnostic_item(cx, ty, sym!(string_type)) {
return None; return None;
} }

View file

@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for GetLastWithLen {
// Argument 0 (the struct we're calling the method on) is a vector // Argument 0 (the struct we're calling the method on) is a vector
if let Some(struct_calling_on) = args.get(0); if let Some(struct_calling_on) = args.get(0);
let struct_ty = cx.tables.expr_ty(struct_calling_on); let struct_ty = cx.tables().expr_ty(struct_calling_on);
if is_type_diagnostic_item(cx, struct_ty, sym!(vec_type)); if is_type_diagnostic_item(cx, struct_ty, sym!(vec_type));
// Argument to "get" is a subtraction // Argument to "get" is a subtraction

View file

@ -62,8 +62,8 @@ fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Exp
// `1 << 0` is a common pattern in bit manipulation code // `1 << 0` is a common pattern in bit manipulation code
if_chain! { if_chain! {
if let BinOpKind::Shl = cmp.node; if let BinOpKind::Shl = cmp.node;
if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables, right); if let Some(Constant::Int(0)) = constant_simple(cx, cx.tables(), right);
if let Some(Constant::Int(1)) = constant_simple(cx, cx.tables, left); if let Some(Constant::Int(1)) = constant_simple(cx, cx.tables(), left);
then { then {
return true; return true;
} }
@ -74,8 +74,8 @@ fn is_allowed(cx: &LateContext<'_, '_>, cmp: BinOp, left: &Expr<'_>, right: &Exp
#[allow(clippy::cast_possible_wrap)] #[allow(clippy::cast_possible_wrap)]
fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) { fn check(cx: &LateContext<'_, '_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) { if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables(), e) {
let check = match cx.tables.expr_ty(e).kind { let check = match cx.tables().expr_ty(e).kind {
ty::Int(ity) => unsext(cx.tcx, -1_i128, ity), ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
ty::Uint(uty) => clip(cx.tcx, !0, uty), ty::Uint(uty) => clip(cx.tcx, !0, uty),
_ => return, _ => return,

View file

@ -149,7 +149,7 @@ fn is_mutex_lock_call<'a>(cx: &LateContext<'a, '_>, expr: &'a Expr<'_>) -> Optio
if_chain! { if_chain! {
if let ExprKind::MethodCall(path, _span, args, _) = &expr.kind; if let ExprKind::MethodCall(path, _span, args, _) = &expr.kind;
if path.ident.to_string() == "lock"; if path.ident.to_string() == "lock";
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables().expr_ty(&args[0]);
if is_type_diagnostic_item(cx, ty, sym!(mutex_type)); if is_type_diagnostic_item(cx, ty, sym!(mutex_type));
then { then {
Some(&args[0]) Some(&args[0])

View file

@ -45,7 +45,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet {
if let ExprKind::MethodCall(_, ok_span, ref result_types, _) = op.kind; //check is expr.ok() has type Result<T,E>.ok(, _) if let ExprKind::MethodCall(_, ok_span, ref result_types, _) = op.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.kind; //get operation if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.kind; //get operation
if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized; if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
if is_type_diagnostic_item(cx, cx.tables.expr_ty(&result_types[0]), sym!(result_type)); if is_type_diagnostic_item(cx, cx.tables().expr_ty(&result_types[0]), sym!(result_type));
if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some"; if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some";
then { then {

View file

@ -108,7 +108,7 @@ fn expr_match(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
ExprKind::Call(expr, ..) => { ExprKind::Call(expr, ..) => {
if_chain! { if_chain! {
if let ExprKind::Path(qpath) = &expr.kind; if let ExprKind::Path(qpath) = &expr.kind;
if let Some(path_def_id) = cx.tables.qpath_res(qpath, expr.hir_id).opt_def_id(); if let Some(path_def_id) = cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id();
if match_def_path(cx, path_def_id, &BEGIN_PANIC) || if match_def_path(cx, path_def_id, &BEGIN_PANIC) ||
match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT); match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT);
then { } then { }

View file

@ -81,7 +81,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub {
}; };
// Check if the variable in the condition statement is an integer // Check if the variable in the condition statement is an integer
if !cx.tables.expr_ty(cond_var).is_integral() { if !cx.tables().expr_ty(cond_var).is_integral() {
return; return;
} }
@ -93,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitSaturatingSub {
ExprKind::Lit(ref cond_lit) => { ExprKind::Lit(ref cond_lit) => {
// Check if the constant is zero // Check if the constant is zero
if let LitKind::Int(0, _) = cond_lit.node { if let LitKind::Int(0, _) = cond_lit.node {
if cx.tables.expr_ty(cond_left).is_signed() { if cx.tables().expr_ty(cond_left).is_signed() {
} else { } else {
print_lint_and_sugg(cx, &var_name, expr); print_lint_and_sugg(cx, &var_name, expr);
}; };

View file

@ -88,7 +88,7 @@ declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Index(ref array, ref index) = &expr.kind { if let ExprKind::Index(ref array, ref index) = &expr.kind {
let ty = cx.tables.expr_ty(array); let ty = cx.tables().expr_ty(array);
if let Some(range) = higher::range(cx, index) { if let Some(range) = higher::range(cx, index) {
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..] // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
if let ty::Array(_, s) = ty.kind { if let ty::Array(_, s) = ty.kind {
@ -143,7 +143,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
// Catchall non-range index, i.e., [n] or [n << m] // Catchall non-range index, i.e., [n] or [n << m]
if let ty::Array(..) = ty.kind { if let ty::Array(..) = ty.kind {
// Index is a constant uint. // Index is a constant uint.
if let Some(..) = constant(cx, cx.tables, index) { if let Some(..) = constant(cx, cx.tables(), index) {
// Let rustc's `const_err` lint handle constant `usize` indexing on arrays. // Let rustc's `const_err` lint handle constant `usize` indexing on arrays.
return; return;
} }
@ -169,14 +169,14 @@ fn to_const_range<'a, 'tcx>(
range: higher::Range<'_>, range: higher::Range<'_>,
array_size: u128, array_size: u128,
) -> (Option<u128>, Option<u128>) { ) -> (Option<u128>, Option<u128>) {
let s = range.start.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); let s = range.start.map(|expr| constant(cx, cx.tables(), expr).map(|(c, _)| c));
let start = match s { let start = match s {
Some(Some(Constant::Int(x))) => Some(x), Some(Some(Constant::Int(x))) => Some(x),
Some(_) => None, Some(_) => None,
None => Some(0), None => Some(0),
}; };
let e = range.end.map(|expr| constant(cx, cx.tables, expr).map(|(c, _)| c)); let e = range.end.map(|expr| constant(cx, cx.tables(), expr).map(|(c, _)| c));
let end = match e { let end = match e {
Some(Some(Constant::Int(x))) => { Some(Some(Constant::Int(x))) => {
if range.limits == RangeLimits::Closed { if range.limits == RangeLimits::Closed {

View file

@ -230,13 +230,14 @@ fn complete_infinite_iter(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finitene
} }
} }
if method.ident.name == sym!(last) && args.len() == 1 { if method.ident.name == sym!(last) && args.len() == 1 {
let not_double_ended = get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR) let not_double_ended = get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR).map_or(false, |id| {
.map_or(false, |id| !implements_trait(cx, cx.tables.expr_ty(&args[0]), id, &[])); !implements_trait(cx, cx.tables().expr_ty(&args[0]), id, &[])
});
if not_double_ended { if not_double_ended {
return is_infinite(cx, &args[0]); return is_infinite(cx, &args[0]);
} }
} else if method.ident.name == sym!(collect) { } else if method.ident.name == sym!(collect) {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) { if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) {
return is_infinite(cx, &args[0]); return is_infinite(cx, &args[0]);
} }

View file

@ -50,7 +50,7 @@ fn is_integer_division<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Ex
if let hir::ExprKind::Binary(binop, left, right) = &expr.kind; if let hir::ExprKind::Binary(binop, left, right) = &expr.kind;
if let hir::BinOpKind::Div = &binop.node; if let hir::BinOpKind::Div = &binop.node;
then { then {
let (left_ty, right_ty) = (cx.tables.expr_ty(left), cx.tables.expr_ty(right)); let (left_ty, right_ty) = (cx.tables().expr_ty(left), cx.tables().expr_ty(right));
return left_ty.is_integral() && right_ty.is_integral(); return left_ty.is_integral() && right_ty.is_integral();
} }
} }

View file

@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeStackArrays {
fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
if_chain! { if_chain! {
if let ExprKind::Repeat(_, _) = expr.kind; if let ExprKind::Repeat(_, _) = expr.kind;
if let ty::Array(element_type, cst) = cx.tables.expr_ty(expr).kind; if let ty::Array(element_type, cst) = cx.tables().expr_ty(expr).kind;
if let ConstKind::Value(val) = cst.val; if let ConstKind::Value(val) = cst.val;
if let ConstValue::Scalar(element_count) = val; if let ConstValue::Scalar(element_count) = val;
if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx); if let Ok(element_count) = element_count.to_machine_usize(&cx.tcx);

View file

@ -300,7 +300,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
return false; return false;
} }
let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr)); let ty = &walk_ptrs_ty(cx.tables().expr_ty(expr));
match ty.kind { match ty.kind {
ty::Dynamic(ref tt, ..) => { ty::Dynamic(ref tt, ..) => {
if let Some(principal) = tt.principal() { if let Some(principal) = tt.principal() {

View file

@ -100,14 +100,14 @@ struct BorrowVisitor<'a, 'tcx> {
impl BorrowVisitor<'_, '_> { impl BorrowVisitor<'_, '_> {
fn fn_def_id(&self, expr: &Expr<'_>) -> Option<DefId> { fn fn_def_id(&self, expr: &Expr<'_>) -> Option<DefId> {
match &expr.kind { match &expr.kind {
ExprKind::MethodCall(..) => self.cx.tables.type_dependent_def_id(expr.hir_id), ExprKind::MethodCall(..) => self.cx.tables().type_dependent_def_id(expr.hir_id),
ExprKind::Call( ExprKind::Call(
Expr { Expr {
kind: ExprKind::Path(qpath), kind: ExprKind::Path(qpath),
.. ..
}, },
.., ..,
) => self.cx.tables.qpath_res(qpath, expr.hir_id).opt_def_id(), ) => self.cx.tables().qpath_res(qpath, expr.hir_id).opt_def_id(),
_ => None, _ => None,
} }
} }

View file

@ -73,7 +73,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
then { then {
let span = stmt.span.to(if_.span); let span = stmt.span.to(if_.span);
let has_interior_mutability = !cx.tables.node_type(canonical_id).is_freeze( let has_interior_mutability = !cx.tables().node_type(canonical_id).is_freeze(
cx.tcx.at(span), cx.tcx.at(span),
cx.param_env, cx.param_env,
); );

View file

@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore {
if let PatKind::Wild = local.pat.kind; if let PatKind::Wild = local.pat.kind;
if let Some(ref init) = local.init; if let Some(ref init) = local.init;
then { then {
let init_ty = cx.tables.expr_ty(init); let init_ty = cx.tables().expr_ty(init);
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() { let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
GenericArgKind::Type(inner_ty) => { GenericArgKind::Type(inner_ty) => {
SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)) SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path))
@ -94,7 +94,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore {
"consider using an underscore-prefixed named \ "consider using an underscore-prefixed named \
binding or dropping explicitly with `std::mem::drop`" binding or dropping explicitly with `std::mem::drop`"
) )
} else if is_must_use_ty(cx, cx.tables.expr_ty(init)) { } else if is_must_use_ty(cx, cx.tables().expr_ty(init)) {
span_lint_and_help( span_lint_and_help(
cx, cx,
LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_MUST_USE,

View file

@ -343,7 +343,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
}) })
{ {
let hir_id = ty.hir_id; let hir_id = ty.hir_id;
match self.cx.tables.qpath_res(qpath, hir_id) { match self.cx.tables().qpath_res(qpath, hir_id) {
Res::Def(DefKind::TyAlias | DefKind::Struct, def_id) => { Res::Def(DefKind::TyAlias | DefKind::Struct, def_id) => {
let generics = self.cx.tcx.generics_of(def_id); let generics = self.cx.tcx.generics_of(def_id);
for _ in generics.params.as_slice() { for _ in generics.params.as_slice() {

View file

@ -535,7 +535,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
if_chain! { if_chain! {
if let ExprKind::MethodCall(..) | ExprKind::Call(..) = iter_expr.kind; if let ExprKind::MethodCall(..) | ExprKind::Call(..) = iter_expr.kind;
if let Some(iter_def_id) = get_trait_def_id(cx, &paths::ITERATOR); if let Some(iter_def_id) = get_trait_def_id(cx, &paths::ITERATOR);
if implements_trait(cx, cx.tables.expr_ty(iter_expr), iter_def_id, &[]); if implements_trait(cx, cx.tables().expr_ty(iter_expr), iter_def_id, &[]);
then { then {
return; return;
} }
@ -985,8 +985,8 @@ fn detect_manual_memcpy<'a, 'tcx>(
if_chain! { if_chain! {
if let ExprKind::Index(seqexpr_left, idx_left) = lhs.kind; if let ExprKind::Index(seqexpr_left, idx_left) = lhs.kind;
if let ExprKind::Index(seqexpr_right, idx_right) = rhs.kind; if let ExprKind::Index(seqexpr_right, idx_right) = rhs.kind;
if is_slice_like(cx, cx.tables.expr_ty(seqexpr_left)) if is_slice_like(cx, cx.tables().expr_ty(seqexpr_left))
&& is_slice_like(cx, cx.tables.expr_ty(seqexpr_right)); && is_slice_like(cx, cx.tables().expr_ty(seqexpr_right));
if let Some(offset_left) = get_offset(cx, &idx_left, canonical_id); if let Some(offset_left) = get_offset(cx, &idx_left, canonical_id);
if let Some(offset_right) = get_offset(cx, &idx_right, canonical_id); if let Some(offset_right) = get_offset(cx, &idx_right, canonical_id);
@ -1254,8 +1254,8 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e
lint_iter_method(cx, args, arg, method_name); lint_iter_method(cx, args, arg, method_name);
} }
} else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
let receiver_ty = cx.tables.expr_ty(&args[0]); let receiver_ty = cx.tables().expr_ty(&args[0]);
let receiver_ty_adjusted = cx.tables.expr_ty_adjusted(&args[0]); let receiver_ty_adjusted = cx.tables().expr_ty_adjusted(&args[0]);
if TyS::same_type(receiver_ty, receiver_ty_adjusted) { if TyS::same_type(receiver_ty, receiver_ty_adjusted) {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability); let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability);
@ -1300,7 +1300,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e
/// Checks for `for` loops over `Option`s and `Result`s. /// Checks for `for` loops over `Option`s and `Result`s.
fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) { fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) {
let ty = cx.tables.expr_ty(arg); let ty = cx.tables().expr_ty(arg);
if is_type_diagnostic_item(cx, ty, sym!(option_type)) { if is_type_diagnostic_item(cx, ty, sym!(option_type)) {
span_lint_and_help( span_lint_and_help(
cx, cx,
@ -1405,7 +1405,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
/// actual `Iterator` that the loop uses. /// actual `Iterator` that the loop uses.
fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String { fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String {
let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR) let impls_iterator = get_trait_def_id(cx, &paths::ITERATOR)
.map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(arg), id, &[])); .map_or(false, |id| implements_trait(cx, cx.tables().expr_ty(arg), id, &[]));
if impls_iterator { if impls_iterator {
format!( format!(
"{}", "{}",
@ -1416,7 +1416,7 @@ fn make_iterator_snippet(cx: &LateContext<'_, '_>, arg: &Expr<'_>, applic_ref: &
// (&mut x).into_iter() ==> x.iter_mut() // (&mut x).into_iter() ==> x.iter_mut()
match &arg.kind { match &arg.kind {
ExprKind::AddrOf(BorrowKind::Ref, mutability, arg_inner) ExprKind::AddrOf(BorrowKind::Ref, mutability, arg_inner)
if has_iter_method(cx, cx.tables.expr_ty(&arg_inner)).is_some() => if has_iter_method(cx, cx.tables().expr_ty(&arg_inner)).is_some() =>
{ {
let meth_name = match mutability { let meth_name = match mutability {
Mutability::Mut => "iter_mut", Mutability::Mut => "iter_mut",
@ -1449,7 +1449,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
if let PatKind::Tuple(ref pat, _) = pat.kind { if let PatKind::Tuple(ref pat, _) = pat.kind {
if pat.len() == 2 { if pat.len() == 2 {
let arg_span = arg.span; let arg_span = arg.span;
let (new_pat_span, kind, ty, mutbl) = match cx.tables.expr_ty(arg).kind { let (new_pat_span, kind, ty, mutbl) = match cx.tables().expr_ty(arg).kind {
ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) { ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) {
(key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl), (key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl),
(_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not), (_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not),
@ -1594,7 +1594,7 @@ fn check_for_mutation<'a, 'tcx>(
}; };
let def_id = body.hir_id.owner.to_def_id(); let def_id = body.hir_id.owner.to_def_id();
cx.tcx.infer_ctxt().enter(|infcx| { cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables).walk_expr(body); ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables()).walk_expr(body);
}); });
delegate.mutation_span() delegate.mutation_span()
} }
@ -1688,7 +1688,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
if index_used_directly { if index_used_directly {
self.indexed_directly.insert( self.indexed_directly.insert(
seqvar.segments[0].ident.name, seqvar.segments[0].ident.name,
(Some(extent), self.cx.tables.node_type(seqexpr.hir_id)), (Some(extent), self.cx.tables().node_type(seqexpr.hir_id)),
); );
} }
return false; // no need to walk further *on the variable* return false; // no need to walk further *on the variable*
@ -1700,7 +1700,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
if index_used_directly { if index_used_directly {
self.indexed_directly.insert( self.indexed_directly.insert(
seqvar.segments[0].ident.name, seqvar.segments[0].ident.name,
(None, self.cx.tables.node_type(seqexpr.hir_id)), (None, self.cx.tables().node_type(seqexpr.hir_id)),
); );
} }
return false; // no need to walk further *on the variable* return false; // no need to walk further *on the variable*
@ -1768,7 +1768,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
ExprKind::Call(ref f, args) => { ExprKind::Call(ref f, args) => {
self.visit_expr(f); self.visit_expr(f);
for expr in args { for expr in args {
let ty = self.cx.tables.expr_ty_adjusted(expr); let ty = self.cx.tables().expr_ty_adjusted(expr);
self.prefer_mutable = false; self.prefer_mutable = false;
if let ty::Ref(_, _, mutbl) = ty.kind { if let ty::Ref(_, _, mutbl) = ty.kind {
if mutbl == Mutability::Mut { if mutbl == Mutability::Mut {
@ -1779,7 +1779,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
} }
}, },
ExprKind::MethodCall(_, _, args, _) => { ExprKind::MethodCall(_, _, args, _) => {
let def_id = self.cx.tables.type_dependent_def_id(expr.hir_id).unwrap(); let def_id = self.cx.tables().type_dependent_def_id(expr.hir_id).unwrap();
for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) { for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) {
self.prefer_mutable = false; self.prefer_mutable = false;
if let ty::Ref(_, _, mutbl) = ty.kind { if let ty::Ref(_, _, mutbl) = ty.kind {
@ -1866,7 +1866,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> {
fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool {
// no walk_ptrs_ty: calling iter() on a reference can make sense because it // no walk_ptrs_ty: calling iter() on a reference can make sense because it
// will allow further borrows afterwards // will allow further borrows afterwards
let ty = cx.tables.expr_ty(e); let ty = cx.tables().expr_ty(e);
is_iterable_array(ty, cx) || is_iterable_array(ty, cx) ||
is_type_diagnostic_item(cx, ty, sym!(vec_type)) || is_type_diagnostic_item(cx, ty, sym!(vec_type)) ||
match_type(cx, ty, &paths::LINKED_LIST) || match_type(cx, ty, &paths::LINKED_LIST) ||
@ -2241,7 +2241,7 @@ fn path_name(e: &Expr<'_>) -> Option<Name> {
} }
fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) { fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {
if constant(cx, cx.tables, cond).is_some() { if constant(cx, cx.tables(), cond).is_some() {
// A pure constant condition (e.g., `while false`) is not linted. // A pure constant condition (e.g., `while false`) is not linted.
return; return;
} }
@ -2377,7 +2377,7 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, '
if let Some(ref generic_args) = chain_method.args; if let Some(ref generic_args) = chain_method.args;
if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0);
then { then {
let ty = cx.tables.node_type(ty.hir_id); let ty = cx.tables().node_type(ty.hir_id);
if is_type_diagnostic_item(cx, ty, sym!(vec_type)) || if is_type_diagnostic_item(cx, ty, sym!(vec_type)) ||
is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) || is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) ||
match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &paths::BTREEMAP) ||

View file

@ -52,7 +52,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
if let hir::ExprKind::MethodCall(ref method, _, ref args, _) = e.kind; if let hir::ExprKind::MethodCall(ref method, _, ref args, _) = e.kind;
if args.len() == 2; if args.len() == 2;
if method.ident.as_str() == "map"; if method.ident.as_str() == "map";
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables().expr_ty(&args[0]);
if is_type_diagnostic_item(cx, ty, sym!(option_type)) || match_trait_method(cx, e, &paths::ITERATOR); if is_type_diagnostic_item(cx, ty, sym!(option_type)) || match_trait_method(cx, e, &paths::ITERATOR);
if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind; if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind;
let closure_body = cx.tcx.hir().body(body_id); let closure_body = cx.tcx.hir().body(body_id);
@ -70,7 +70,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
match closure_expr.kind { match closure_expr.kind {
hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner) => { hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner) => {
if ident_eq(name, inner) { if ident_eq(name, inner) {
if let ty::Ref(.., Mutability::Not) = cx.tables.expr_ty(inner).kind { if let ty::Ref(.., Mutability::Not) = cx.tables().expr_ty(inner).kind {
lint(cx, e.span, args[0].span, true); lint(cx, e.span, args[0].span, true);
} }
} }
@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
if ident_eq(name, &obj[0]) && method.ident.as_str() == "clone" if ident_eq(name, &obj[0]) && method.ident.as_str() == "clone"
&& match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) { && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) {
let obj_ty = cx.tables.expr_ty(&obj[0]); let obj_ty = cx.tables().expr_ty(&obj[0]);
if let ty::Ref(_, ty, _) = obj_ty.kind { if let ty::Ref(_, ty, _) = obj_ty.kind {
let copy = is_copy(cx, ty); let copy = is_copy(cx, ty);
lint(cx, e.span, args[0].span, copy); lint(cx, e.span, args[0].span, copy);

View file

@ -101,7 +101,7 @@ fn is_unit_type(ty: Ty<'_>) -> bool {
} }
fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if let ty::FnDef(id, _) = ty.kind { if let ty::FnDef(id, _) = ty.kind {
if let Some(fn_type) = cx.tcx.fn_sig(id).no_bound_vars() { if let Some(fn_type) = cx.tcx.fn_sig(id).no_bound_vars() {
@ -112,7 +112,7 @@ fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool {
} }
fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool { fn is_unit_expression(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> bool {
is_unit_type(cx.tables.expr_ty(expr)) is_unit_type(cx.tables().expr_ty(expr))
} }
/// The expression inside a closure may or may not have surrounding braces and /// The expression inside a closure may or may not have surrounding braces and
@ -205,9 +205,9 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String {
fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) { fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) {
let var_arg = &map_args[0]; let var_arg = &map_args[0];
let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(option_type)) { let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables().expr_ty(var_arg), sym!(option_type)) {
("Option", "Some", OPTION_MAP_UNIT_FN) ("Option", "Some", OPTION_MAP_UNIT_FN)
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(result_type)) { } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(var_arg), sym!(result_type)) {
("Result", "Ok", RESULT_MAP_UNIT_FN) ("Result", "Ok", RESULT_MAP_UNIT_FN)
} else { } else {
return; return;

View file

@ -88,13 +88,13 @@ fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>)
} }
fn is_vector(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_vector(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
let ty = walk_ptrs_ty(ty); let ty = walk_ptrs_ty(ty);
is_type_diagnostic_item(cx, ty, sym!(vec_type)) is_type_diagnostic_item(cx, ty, sym!(vec_type))
} }
fn is_full_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_full_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
let ty = walk_ptrs_ty(ty); let ty = walk_ptrs_ty(ty);
match_type(cx, ty, &utils::paths::RANGE_FULL) match_type(cx, ty, &utils::paths::RANGE_FULL)
} }

View file

@ -540,7 +540,7 @@ fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>],
// allow match arms with just expressions // allow match arms with just expressions
return; return;
}; };
let ty = cx.tables.expr_ty(ex); let ty = cx.tables().expr_ty(ex);
if ty.kind != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.hir_id) { if ty.kind != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.hir_id) {
check_single_match_single_pattern(cx, ex, arms, expr, els); check_single_match_single_pattern(cx, ex, arms, expr, els);
check_single_match_opt_like(cx, ex, arms, expr, ty, els); check_single_match_opt_like(cx, ex, arms, expr, ty, els);
@ -632,7 +632,7 @@ fn check_single_match_opt_like(
fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
// Type of expression is `bool`. // Type of expression is `bool`.
if cx.tables.expr_ty(ex).kind == ty::Bool { if cx.tables().expr_ty(ex).kind == ty::Bool {
span_lint_and_then( span_lint_and_then(
cx, cx,
MATCH_BOOL, MATCH_BOOL,
@ -695,8 +695,8 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], e
} }
fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
if arms.len() >= 2 && cx.tables.expr_ty(ex).is_integral() { if arms.len() >= 2 && cx.tables().expr_ty(ex).is_integral() {
let ranges = all_ranges(cx, arms, cx.tables.expr_ty(ex)); let ranges = all_ranges(cx, arms, cx.tables().expr_ty(ex));
let type_ranges = type_ranges(&ranges); let type_ranges = type_ranges(&ranges);
if !type_ranges.is_empty() { if !type_ranges.is_empty() {
if let Some((start, end)) = overlapping(&type_ranges) { if let Some((start, end)) = overlapping(&type_ranges) {
@ -714,7 +714,7 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'
} }
fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex)); let ex_ty = walk_ptrs_ty(cx.tables().expr_ty(ex));
if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) { if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) {
for arm in arms { for arm in arms {
if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.kind { if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.kind {
@ -755,7 +755,7 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>])
} }
fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
let ty = cx.tables.expr_ty(ex); let ty = cx.tables().expr_ty(ex);
if !ty.is_enum() { if !ty.is_enum() {
// If there isn't a nice closed set of possible values that can be conveniently enumerated, // If there isn't a nice closed set of possible values that can be conveniently enumerated,
// don't complain about not enumerating the mall. // don't complain about not enumerating the mall.
@ -935,8 +935,8 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>],
"as_mut" "as_mut"
}; };
let output_ty = cx.tables.expr_ty(expr); let output_ty = cx.tables().expr_ty(expr);
let input_ty = cx.tables.expr_ty(ex); let input_ty = cx.tables().expr_ty(ex);
let cast = if_chain! { let cast = if_chain! {
if let ty::Adt(_, substs) = input_ty.kind; if let ty::Adt(_, substs) = input_ty.kind;
@ -1006,13 +1006,13 @@ fn check_match_single_binding<'a>(cx: &LateContext<'_, 'a>, ex: &Expr<'a>, arms:
match match_body.kind { match match_body.kind {
ExprKind::Block(block, _) => { ExprKind::Block(block, _) => {
// macro + expr_ty(body) == () // macro + expr_ty(body) == ()
if block.span.from_expansion() && cx.tables.expr_ty(&match_body).is_unit() { if block.span.from_expansion() && cx.tables().expr_ty(&match_body).is_unit() {
snippet_body.push(';'); snippet_body.push(';');
} }
}, },
_ => { _ => {
// expr_ty(body) == () // expr_ty(body) == ()
if cx.tables.expr_ty(&match_body).is_unit() { if cx.tables().expr_ty(&match_body).is_unit() {
snippet_body.push(';'); snippet_body.push(';');
} }
}, },
@ -1111,11 +1111,11 @@ fn all_ranges<'a, 'tcx>(
{ {
if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind { if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind {
let lhs = match lhs { let lhs = match lhs {
Some(lhs) => constant(cx, cx.tables, lhs)?.0, Some(lhs) => constant(cx, cx.tables(), lhs)?.0,
None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?, None => miri_to_const(ty.numeric_min_val(cx.tcx)?)?,
}; };
let rhs = match rhs { let rhs = match rhs {
Some(rhs) => constant(cx, cx.tables, rhs)?.0, Some(rhs) => constant(cx, cx.tables(), rhs)?.0,
None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?, None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?,
}; };
let rhs = match range_end { let rhs = match range_end {
@ -1129,7 +1129,7 @@ fn all_ranges<'a, 'tcx>(
} }
if let PatKind::Lit(ref value) = pat.kind { if let PatKind::Lit(ref value) = pat.kind {
let value = constant(cx, cx.tables, value)?.0; let value = constant(cx, cx.tables(), value)?.0;
return Some(SpannedRange { return Some(SpannedRange {
span: pat.span, span: pat.span,
node: (value.clone(), Bound::Included(value)), node: (value.clone(), Bound::Included(value)),

View file

@ -35,10 +35,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemDiscriminant {
if let ExprKind::Call(ref func, ref func_args) = expr.kind; if let ExprKind::Call(ref func, ref func_args) = expr.kind;
// is `mem::discriminant` // is `mem::discriminant`
if let ExprKind::Path(ref func_qpath) = func.kind; if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT); if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT);
// type is non-enum // type is non-enum
let ty_param = cx.tables.node_substs(func.hir_id).type_at(0); let ty_param = cx.tables().node_substs(func.hir_id).type_at(0);
if !ty_param.is_enum(); if !ty_param.is_enum();
then { then {

View file

@ -31,7 +31,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget {
if let ExprKind::Path(ref qpath) = path_expr.kind { if let ExprKind::Path(ref qpath) = path_expr.kind {
if let Some(def_id) = qpath_res(cx, qpath, path_expr.hir_id).opt_def_id() { if let Some(def_id) = qpath_res(cx, qpath, path_expr.hir_id).opt_def_id() {
if match_def_path(cx, def_id, &paths::MEM_FORGET) { if match_def_path(cx, def_id, &paths::MEM_FORGET) {
let forgot_ty = cx.tables.expr_ty(&args[0]); let forgot_ty = cx.tables().expr_ty(&args[0]);
if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) { if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) {
span_lint(cx, MEM_FORGET, e.span, "usage of `mem::forget` on `Drop` type"); span_lint(cx, MEM_FORGET, e.span, "usage of `mem::forget` on `Drop` type");

View file

@ -138,7 +138,7 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest
fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) {
if_chain! { if_chain! {
// check if replacement is mem::MaybeUninit::uninit().assume_init() // check if replacement is mem::MaybeUninit::uninit().assume_init()
if let Some(method_def_id) = cx.tables.type_dependent_def_id(src.hir_id); if let Some(method_def_id) = cx.tables().type_dependent_def_id(src.hir_id);
if cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id); if cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id);
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
@ -162,7 +162,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex
if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind; if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind;
if repl_args.is_empty(); if repl_args.is_empty();
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
then { then {
if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) { if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
@ -179,7 +179,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &Ex
applicability, applicability,
); );
} else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) && } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) &&
!cx.tables.expr_ty(src).is_primitive() { !cx.tables().expr_ty(src).is_primitive() {
span_lint_and_help( span_lint_and_help(
cx, cx,
MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_UNINIT,
@ -198,7 +198,7 @@ fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest: &E
if_chain! { if_chain! {
if !in_external_macro(cx.tcx.sess, expr_span); if !in_external_macro(cx.tcx.sess, expr_span);
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); if let Some(repl_def_id) = cx.tables().qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
if match_def_path(cx, repl_def_id, &paths::DEFAULT_TRAIT_METHOD); if match_def_path(cx, repl_def_id, &paths::DEFAULT_TRAIT_METHOD);
then { then {
span_lint_and_then( span_lint_and_then(
@ -230,7 +230,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
// Check that `expr` is a call to `mem::replace()` // Check that `expr` is a call to `mem::replace()`
if let ExprKind::Call(ref func, ref func_args) = expr.kind; if let ExprKind::Call(ref func, ref func_args) = expr.kind;
if let ExprKind::Path(ref func_qpath) = func.kind; if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::MEM_REPLACE); if match_def_path(cx, def_id, &paths::MEM_REPLACE);
if let [dest, src] = &**func_args; if let [dest, src] = &**func_args;
then { then {

View file

@ -157,7 +157,7 @@ pub(crate) trait BindInsteadOfMap {
/// Lint use of `_.and_then(|x| Some(y))` for `Option`s /// Lint use of `_.and_then(|x| Some(y))` for `Option`s
fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
if !match_type(cx, cx.tables.expr_ty(&args[0]), Self::TYPE_QPATH) { if !match_type(cx, cx.tables().expr_ty(&args[0]), Self::TYPE_QPATH) {
return; return;
} }

View file

@ -11,9 +11,9 @@ use rustc_middle::ty::{self, Ty};
/// Checks for the `INEFFICIENT_TO_STRING` lint /// Checks for the `INEFFICIENT_TO_STRING` lint
pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) { pub fn lint<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) {
if_chain! { if_chain! {
if let Some(to_string_meth_did) = cx.tables.type_dependent_def_id(expr.hir_id); if let Some(to_string_meth_did) = cx.tables().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
if let Some(substs) = cx.tables.node_substs_opt(expr.hir_id); if let Some(substs) = cx.tables().node_substs_opt(expr.hir_id);
let self_ty = substs.type_at(0); let self_ty = substs.type_at(0);
let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty); let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty);
if deref_count >= 1; if deref_count >= 1;

View file

@ -11,7 +11,7 @@ pub fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[&[hir::Expr<
let arith_lhs = &args[1][0]; let arith_lhs = &args[1][0];
let arith_rhs = &args[1][1]; let arith_rhs = &args[1][1];
let ty = cx.tables.expr_ty(arith_lhs); let ty = cx.tables().expr_ty(arith_lhs);
if !ty.is_integral() { if !ty.is_integral() {
return; return;
} }
@ -101,7 +101,7 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &hir::Expr<'_>) -> Opti
} }
} }
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
let ty_str = ty.to_string(); let ty_str = ty.to_string();
// `std::T::MAX` `std::T::MIN` constants // `std::T::MAX` `std::T::MIN` constants

View file

@ -1433,7 +1433,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
lint_or_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); lint_or_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args); lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
let self_ty = cx.tables.expr_ty_adjusted(&args[0]); let self_ty = cx.tables().expr_ty_adjusted(&args[0]);
if args.len() == 1 && method_call.ident.name == sym!(clone) { if args.len() == 1 && method_call.ident.name == sym!(clone) {
lint_clone_on_copy(cx, expr, &args[0], self_ty); lint_clone_on_copy(cx, expr, &args[0], self_ty);
lint_clone_on_ref_ptr(cx, expr, &args[0]); lint_clone_on_ref_ptr(cx, expr, &args[0]);
@ -1639,7 +1639,7 @@ fn lint_or_fun_call<'a, 'tcx>(
if let hir::ExprKind::Path(ref qpath) = fun.kind; if let hir::ExprKind::Path(ref qpath) = fun.kind;
let path = &*last_path_segment(qpath).ident.as_str(); let path = &*last_path_segment(qpath).ident.as_str();
if ["default", "new"].contains(&path); if ["default", "new"].contains(&path);
let arg_ty = cx.tables.expr_ty(arg); let arg_ty = cx.tables().expr_ty(arg);
if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT);
if implements_trait(cx, arg_ty, default_trait_id, &[]); if implements_trait(cx, arg_ty, default_trait_id, &[]);
@ -1679,7 +1679,7 @@ fn lint_or_fun_call<'a, 'tcx>(
) { ) {
if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind { if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind {
if path.ident.as_str() == "len" { if path.ident.as_str() == "len" {
let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0]));
match ty.kind { match ty.kind {
ty::Slice(_) | ty::Array(_, _) => return, ty::Slice(_) | ty::Array(_, _) => return,
@ -1707,7 +1707,7 @@ fn lint_or_fun_call<'a, 'tcx>(
if { finder.visit_expr(&arg); finder.found }; if { finder.visit_expr(&arg); finder.found };
if !contains_return(&arg); if !contains_return(&arg);
let self_ty = cx.tables.expr_ty(self_expr); let self_ty = cx.tables().expr_ty(self_expr);
if let Some(&(_, fn_has_arguments, poss, suffix)) = if let Some(&(_, fn_has_arguments, poss, suffix)) =
know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)); know_types.iter().find(|&&i| match_type(cx, self_ty, i.0));
@ -1786,7 +1786,7 @@ fn lint_expect_fun_call(
if call_args.len() == 1 if call_args.len() == 1
&& (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref)) && (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref))
&& { && {
let arg_type = cx.tables.expr_ty(&call_args[0]); let arg_type = cx.tables().expr_ty(&call_args[0]);
let base_type = walk_ptrs_ty(arg_type); let base_type = walk_ptrs_ty(arg_type);
base_type.kind == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type)) base_type.kind == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type))
} }
@ -1805,7 +1805,7 @@ fn lint_expect_fun_call(
// Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be
// converted to string. // converted to string.
fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool { fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr<'_>) -> bool {
let arg_ty = cx.tables.expr_ty(arg); let arg_ty = cx.tables().expr_ty(arg);
if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) { if is_type_diagnostic_item(cx, arg_ty, sym!(string_type)) {
return false; return false;
} }
@ -1824,7 +1824,7 @@ fn lint_expect_fun_call(
hir::ExprKind::Lit(_) => true, hir::ExprKind::Lit(_) => true,
hir::ExprKind::Call(fun, _) => { hir::ExprKind::Call(fun, _) => {
if let hir::ExprKind::Path(ref p) = fun.kind { if let hir::ExprKind::Path(ref p) = fun.kind {
match cx.tables.qpath_res(p, fun.hir_id) { match cx.tables().qpath_res(p, fun.hir_id) {
hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
cx.tcx.fn_sig(def_id).output().skip_binder().kind, cx.tcx.fn_sig(def_id).output().skip_binder().kind,
ty::Ref(ty::ReStatic, ..) ty::Ref(ty::ReStatic, ..)
@ -1835,13 +1835,16 @@ fn lint_expect_fun_call(
false false
} }
}, },
hir::ExprKind::MethodCall(..) => cx.tables.type_dependent_def_id(arg.hir_id).map_or(false, |method_id| { hir::ExprKind::MethodCall(..) => cx
matches!( .tables()
cx.tcx.fn_sig(method_id).output().skip_binder().kind, .type_dependent_def_id(arg.hir_id)
ty::Ref(ty::ReStatic, ..) .map_or(false, |method_id| {
) matches!(
}), cx.tcx.fn_sig(method_id).output().skip_binder().kind,
hir::ExprKind::Path(ref p) => match cx.tables.qpath_res(p, arg.hir_id) { ty::Ref(ty::ReStatic, ..)
)
}),
hir::ExprKind::Path(ref p) => match cx.tables().qpath_res(p, arg.hir_id) {
hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true, hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true,
_ => false, _ => false,
}, },
@ -1888,7 +1891,7 @@ fn lint_expect_fun_call(
return; return;
} }
let receiver_type = cx.tables.expr_ty_adjusted(&args[0]); let receiver_type = cx.tables().expr_ty_adjusted(&args[0]);
let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym!(option_type)) { let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym!(option_type)) {
"||" "||"
} else if is_type_diagnostic_item(cx, receiver_type, sym!(result_type)) { } else if is_type_diagnostic_item(cx, receiver_type, sym!(result_type)) {
@ -1954,7 +1957,7 @@ fn lint_expect_fun_call(
/// Checks for the `CLONE_ON_COPY` lint. /// Checks for the `CLONE_ON_COPY` lint.
fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) { fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if let ty::Ref(_, inner, _) = arg_ty.kind { if let ty::Ref(_, inner, _) = arg_ty.kind {
if let ty::Ref(_, innermost, _) = inner.kind { if let ty::Ref(_, innermost, _) = inner.kind {
span_lint_and_then( span_lint_and_then(
@ -2018,11 +2021,11 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir:
} }
// x.clone() might have dereferenced x, possibly through Deref impls // x.clone() might have dereferenced x, possibly through Deref impls
if cx.tables.expr_ty(arg) == ty { if cx.tables().expr_ty(arg) == ty {
snip = Some(("try removing the `clone` call", format!("{}", snippet))); snip = Some(("try removing the `clone` call", format!("{}", snippet)));
} else { } else {
let deref_count = cx let deref_count = cx
.tables .tables()
.expr_adjustments(arg) .expr_adjustments(arg)
.iter() .iter()
.filter(|adj| { .filter(|adj| {
@ -2048,7 +2051,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir:
} }
fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) { fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg)); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(arg));
if let ty::Adt(_, subst) = obj_ty.kind { if let ty::Adt(_, subst) = obj_ty.kind {
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) { let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
@ -2082,7 +2085,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi
let arg = &args[1]; let arg = &args[1];
if let Some(arglists) = method_chain_args(arg, &["chars"]) { if let Some(arglists) = method_chain_args(arg, &["chars"]) {
let target = &arglists[0][0]; let target = &arglists[0][0];
let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target)); let self_ty = walk_ptrs_ty(cx.tables().expr_ty(target));
let ref_str = if self_ty.kind == ty::Str { let ref_str = if self_ty.kind == ty::Str {
"" ""
} else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) { } else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
@ -2110,7 +2113,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hi
} }
fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0]));
if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) { if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) {
lint_string_extend(cx, expr, args); lint_string_extend(cx, expr, args);
} }
@ -2118,7 +2121,7 @@ fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr
fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) { fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) {
if_chain! { if_chain! {
let source_type = cx.tables.expr_ty(source); let source_type = cx.tables().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind; if let ty::Adt(def, substs) = source_type.kind;
if cx.tcx.is_diagnostic_item(sym!(result_type), def.did); if cx.tcx.is_diagnostic_item(sym!(result_type), def.did);
if match_type(cx, substs.type_at(0), &paths::CSTRING); if match_type(cx, substs.type_at(0), &paths::CSTRING);
@ -2142,8 +2145,8 @@ fn lint_iter_cloned_collect<'a, 'tcx>(
iter_args: &'tcx [hir::Expr<'_>], iter_args: &'tcx [hir::Expr<'_>],
) { ) {
if_chain! { if_chain! {
if is_type_diagnostic_item(cx, cx.tables.expr_ty(expr), sym!(vec_type)); if is_type_diagnostic_item(cx, cx.tables().expr_ty(expr), sym!(vec_type));
if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])); if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables().expr_ty(&iter_args[0]));
if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite()); if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite());
then { then {
@ -2250,7 +2253,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, fold_ar
fn lint_step_by<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) { fn lint_step_by<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) {
if match_trait_method(cx, expr, &paths::ITERATOR) { if match_trait_method(cx, expr, &paths::ITERATOR) {
if let Some((Constant::Int(0), _)) = constant(cx, cx.tables, &args[1]) { if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &args[1]) {
span_lint( span_lint(
cx, cx,
ITERATOR_STEP_BY_ZERO, ITERATOR_STEP_BY_ZERO,
@ -2274,7 +2277,7 @@ fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_
parent_expr_opt = get_parent_expr(cx, parent_expr); parent_expr_opt = get_parent_expr(cx, parent_expr);
} }
if derefs_to_slice(cx, caller_expr, cx.tables.expr_ty(caller_expr)).is_some() { if derefs_to_slice(cx, caller_expr, cx.tables().expr_ty(caller_expr)).is_some() {
// caller is a Slice // caller is a Slice
if_chain! { if_chain! {
if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind; if let hir::ExprKind::Index(ref caller_var, ref index_expr) = &caller_expr.kind;
@ -2295,8 +2298,8 @@ fn lint_iter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_
); );
} }
} }
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(caller_expr), sym!(vec_type)) } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(caller_expr), sym!(vec_type))
|| matches!(&walk_ptrs_ty(cx.tables.expr_ty(caller_expr)).kind, ty::Array(_, _)) || matches!(&walk_ptrs_ty(cx.tables().expr_ty(caller_expr)).kind, ty::Array(_, _))
{ {
// caller is a Vec or an Array // caller is a Vec or an Array
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
@ -2323,11 +2326,11 @@ fn lint_iter_nth<'a, 'tcx>(
) { ) {
let iter_args = nth_and_iter_args[1]; let iter_args = nth_and_iter_args[1];
let mut_str = if is_mut { "_mut" } else { "" }; let mut_str = if is_mut { "_mut" } else { "" };
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() { let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables().expr_ty(&iter_args[0])).is_some() {
"slice" "slice"
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vec_type)) { } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(&iter_args[0]), sym!(vec_type)) {
"Vec" "Vec"
} else if is_type_diagnostic_item(cx, cx.tables.expr_ty(&iter_args[0]), sym!(vecdeque_type)) { } else if is_type_diagnostic_item(cx, cx.tables().expr_ty(&iter_args[0]), sym!(vecdeque_type)) {
"VecDeque" "VecDeque"
} else { } else {
let nth_args = nth_and_iter_args[0]; let nth_args = nth_and_iter_args[0];
@ -2348,7 +2351,7 @@ fn lint_iter_nth<'a, 'tcx>(
fn lint_iter_nth_zero<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) { fn lint_iter_nth_zero<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) {
if_chain! { if_chain! {
if match_trait_method(cx, expr, &paths::ITERATOR); if match_trait_method(cx, expr, &paths::ITERATOR);
if let Some((Constant::Int(0), _)) = constant(cx, cx.tables, &nth_args[1]); if let Some((Constant::Int(0), _)) = constant(cx, cx.tables(), &nth_args[1]);
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg( span_lint_and_sugg(
@ -2373,7 +2376,7 @@ fn lint_get_unwrap<'a, 'tcx>(
// Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`, // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`,
// because they do not implement `IndexMut` // because they do not implement `IndexMut`
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let expr_ty = cx.tables.expr_ty(&get_args[0]); let expr_ty = cx.tables().expr_ty(&get_args[0]);
let get_args_str = if get_args.len() > 1 { let get_args_str = if get_args.len() > 1 {
snippet_with_applicability(cx, get_args[1].span, "_", &mut applicability) snippet_with_applicability(cx, get_args[1].span, "_", &mut applicability)
} else { } else {
@ -2479,7 +2482,7 @@ fn derefs_to_slice<'a, 'tcx>(
} }
if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind {
if path.ident.name == sym!(iter) && may_slice(cx, cx.tables.expr_ty(&args[0])) { if path.ident.name == sym!(iter) && may_slice(cx, cx.tables().expr_ty(&args[0])) {
Some(&args[0]) Some(&args[0])
} else { } else {
None None
@ -2502,7 +2505,7 @@ fn derefs_to_slice<'a, 'tcx>(
/// lint use of `unwrap()` for `Option`s and `Result`s /// lint use of `unwrap()` for `Option`s and `Result`s
fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) { fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&unwrap_args[0])); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&unwrap_args[0]));
let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
Some((UNWRAP_USED, "an Option", "None")) Some((UNWRAP_USED, "an Option", "None"))
@ -2530,7 +2533,7 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hi
/// lint use of `expect()` for `Option`s and `Result`s /// lint use of `expect()` for `Option`s and `Result`s
fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) { fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&expect_args[0])); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&expect_args[0]));
let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) { let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
Some((EXPECT_USED, "an Option", "None")) Some((EXPECT_USED, "an Option", "None"))
@ -2556,8 +2559,8 @@ fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hi
fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) { fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) {
if_chain! { if_chain! {
// lint if the caller of `ok()` is a `Result` // lint if the caller of `ok()` is a `Result`
if is_type_diagnostic_item(cx, cx.tables.expr_ty(&ok_args[0]), sym!(result_type)); if is_type_diagnostic_item(cx, cx.tables().expr_ty(&ok_args[0]), sym!(result_type));
let result_type = cx.tables.expr_ty(&ok_args[0]); let result_type = cx.tables().expr_ty(&ok_args[0]);
if let Some(error_type) = get_error_type(cx, result_type); if let Some(error_type) = get_error_type(cx, result_type);
if has_debug_impl(error_type, cx); if has_debug_impl(error_type, cx);
@ -2595,7 +2598,7 @@ fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<
} }
// lint if caller of `.map().flatten()` is an Option // lint if caller of `.map().flatten()` is an Option
if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) { if is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type)) {
let msg = "called `map(..).flatten()` on an `Option`. \ let msg = "called `map(..).flatten()` on an `Option`. \
This is more succinctly expressed by calling `.and_then(..)`"; This is more succinctly expressed by calling `.and_then(..)`";
let self_snippet = snippet(cx, map_args[0].span, ".."); let self_snippet = snippet(cx, map_args[0].span, "..");
@ -2621,8 +2624,8 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(
unwrap_args: &'tcx [hir::Expr<'_>], unwrap_args: &'tcx [hir::Expr<'_>],
) { ) {
// lint if the caller of `map()` is an `Option` // lint if the caller of `map()` is an `Option`
let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)); let is_option = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type));
let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(result_type)); let is_result = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(result_type));
if is_option || is_result { if is_option || is_result {
// Don't make a suggestion that may fail to compile due to mutably borrowing // Don't make a suggestion that may fail to compile due to mutably borrowing
@ -2676,8 +2679,8 @@ fn lint_map_or_none<'a, 'tcx>(
expr: &'tcx hir::Expr<'_>, expr: &'tcx hir::Expr<'_>,
map_or_args: &'tcx [hir::Expr<'_>], map_or_args: &'tcx [hir::Expr<'_>],
) { ) {
let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(option_type)); let is_option = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(option_type));
let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(result_type)); let is_result = is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_or_args[0]), sym!(result_type));
// There are two variants of this `map_or` lint: // There are two variants of this `map_or` lint:
// (1) using `map_or` as an adapter from `Result<T,E>` to `Option<T>` // (1) using `map_or` as an adapter from `Result<T,E>` to `Option<T>`
@ -3042,7 +3045,7 @@ fn lint_chars_cmp(
if segment.ident.name == sym!(Some); if segment.ident.name == sym!(Some);
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0])); let self_ty = walk_ptrs_ty(cx.tables().expr_ty_adjusted(&args[0][0]));
if self_ty.kind != ty::Str { if self_ty.kind != ty::Str {
return false; return false;
@ -3174,8 +3177,8 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, call_name: &str, a
if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) { if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) {
// check if the type after `as_ref` or `as_mut` is the same as before // check if the type after `as_ref` or `as_mut` is the same as before
let recvr = &as_ref_args[0]; let recvr = &as_ref_args[0];
let rcv_ty = cx.tables.expr_ty(recvr); let rcv_ty = cx.tables().expr_ty(recvr);
let res_ty = cx.tables.expr_ty(expr); let res_ty = cx.tables().expr_ty(expr);
let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty); let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty); let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
if base_rcv_ty == base_res_ty && rcv_depth >= res_depth { if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
@ -3244,7 +3247,7 @@ fn lint_maybe_uninit(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, outer: &hir
if args.is_empty(); if args.is_empty();
if let hir::ExprKind::Path(ref path) = callee.kind; if let hir::ExprKind::Path(ref path) = callee.kind;
if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT);
if !is_maybe_uninit_ty_valid(cx, cx.tables.expr_ty_adjusted(outer)); if !is_maybe_uninit_ty_valid(cx, cx.tables().expr_ty_adjusted(outer));
then { then {
span_lint( span_lint(
cx, cx,
@ -3286,7 +3289,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>(
) { ) {
let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not); let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not);
let option_ty = cx.tables.expr_ty(&as_ref_args[0]); let option_ty = cx.tables().expr_ty(&as_ref_args[0]);
if !is_type_diagnostic_item(cx, option_ty, sym!(option_type)) { if !is_type_diagnostic_item(cx, option_ty, sym!(option_type)) {
return; return;
} }
@ -3314,12 +3317,12 @@ fn lint_option_as_ref_deref<'a, 'tcx>(
if_chain! { if_chain! {
if args.len() == 1; if args.len() == 1;
if let hir::ExprKind::Path(qpath) = &args[0].kind; if let hir::ExprKind::Path(qpath) = &args[0].kind;
if let hir::def::Res::Local(local_id) = cx.tables.qpath_res(qpath, args[0].hir_id); if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, args[0].hir_id);
if closure_body.params[0].pat.hir_id == local_id; if closure_body.params[0].pat.hir_id == local_id;
let adj = cx.tables.expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::<Box<[_]>>(); let adj = cx.tables().expr_adjustments(&args[0]).iter().map(|x| &x.kind).collect::<Box<[_]>>();
if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj; if let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj;
then { then {
let method_did = cx.tables.type_dependent_def_id(closure_expr.hir_id).unwrap(); let method_did = cx.tables().type_dependent_def_id(closure_expr.hir_id).unwrap();
deref_aliases.iter().any(|path| match_def_path(cx, method_did, path)) deref_aliases.iter().any(|path| match_def_path(cx, method_did, path))
} else { } else {
false false
@ -3331,7 +3334,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>(
if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner1) = inner.kind; if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner1) = inner.kind;
if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner2) = inner1.kind; if let hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner2) = inner1.kind;
if let hir::ExprKind::Path(ref qpath) = inner2.kind; if let hir::ExprKind::Path(ref qpath) = inner2.kind;
if let hir::def::Res::Local(local_id) = cx.tables.qpath_res(qpath, inner2.hir_id); if let hir::def::Res::Local(local_id) = cx.tables().qpath_res(qpath, inner2.hir_id);
then { then {
closure_body.params[0].pat.hir_id == local_id closure_body.params[0].pat.hir_id == local_id
} else { } else {
@ -3614,7 +3617,7 @@ fn contains_return(expr: &hir::Expr<'_>) -> bool {
fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
if_chain! { if_chain! {
if args.len() == 2; if args.len() == 2;
if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables.expr_ty(&args[0]).kind; if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables().expr_ty(&args[0]).kind;
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty)); if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
if layout.is_zst(); if layout.is_zst();
then { then {
@ -3624,7 +3627,7 @@ fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[
} }
fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { fn lint_filetype_is_file(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables().expr_ty(&args[0]);
if !match_type(cx, ty, &paths::FILE_TYPE) { if !match_type(cx, ty, &paths::FILE_TYPE) {
return; return;

View file

@ -20,8 +20,8 @@ pub(super) fn lint<'a, 'tcx>(
map_span: Span, map_span: Span,
) { ) {
// lint if the caller of `map()` is an `Option` // lint if the caller of `map()` is an `Option`
if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) { if is_type_diagnostic_item(cx, cx.tables().expr_ty(&map_args[0]), sym!(option_type)) {
if !is_copy(cx, cx.tables.expr_ty(&unwrap_args[1])) { if !is_copy(cx, cx.tables().expr_ty(&unwrap_args[1])) {
// Do not lint if the `map` argument uses identifiers in the `map` // Do not lint if the `map` argument uses identifiers in the `map`
// argument that are also used in the `unwrap_or` argument // argument that are also used in the `unwrap_or` argument

View file

@ -65,7 +65,7 @@ fn check_expression<'a, 'tcx>(
if match_qpath(path, &paths::OPTION_SOME) { if match_qpath(path, &paths::OPTION_SOME) {
if_chain! { if_chain! {
if let hir::ExprKind::Path(path) = &args[0].kind; if let hir::ExprKind::Path(path) = &args[0].kind;
if let Res::Local(ref local) = cx.tables.qpath_res(path, args[0].hir_id); if let Res::Local(ref local) = cx.tables().qpath_res(path, args[0].hir_id);
then { then {
if arg_id == *local { if arg_id == *local {
return (false, false) return (false, false)

View file

@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass {
} }
match ( match (
outer_max, outer_max,
Constant::partial_cmp(cx.tcx, cx.tables.expr_ty(ie), &outer_c, &inner_c), Constant::partial_cmp(cx.tcx, cx.tables().expr_ty(ie), &outer_c, &inner_c),
) { ) {
(_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (), (_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
_ => { _ => {
@ -62,15 +62,18 @@ enum MinMax {
fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> { fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> {
if let ExprKind::Call(ref path, ref args) = expr.kind { if let ExprKind::Call(ref path, ref args) = expr.kind {
if let ExprKind::Path(ref qpath) = path.kind { if let ExprKind::Path(ref qpath) = path.kind {
cx.tables.qpath_res(qpath, path.hir_id).opt_def_id().and_then(|def_id| { cx.tables()
if match_def_path(cx, def_id, &paths::CMP_MIN) { .qpath_res(qpath, path.hir_id)
fetch_const(cx, args, MinMax::Min) .opt_def_id()
} else if match_def_path(cx, def_id, &paths::CMP_MAX) { .and_then(|def_id| {
fetch_const(cx, args, MinMax::Max) if match_def_path(cx, def_id, &paths::CMP_MIN) {
} else { fetch_const(cx, args, MinMax::Min)
None } else if match_def_path(cx, def_id, &paths::CMP_MAX) {
} fetch_const(cx, args, MinMax::Max)
}) } else {
None
}
})
} else { } else {
None None
} }
@ -87,14 +90,14 @@ fn fetch_const<'a>(
if args.len() != 2 { if args.len() != 2 {
return None; return None;
} }
if let Some(c) = constant_simple(cx, cx.tables, &args[0]) { if let Some(c) = constant_simple(cx, cx.tables(), &args[0]) {
if constant_simple(cx, cx.tables, &args[1]).is_none() { if constant_simple(cx, cx.tables(), &args[1]).is_none() {
// otherwise ignore // otherwise ignore
Some((m, c, &args[1])) Some((m, c, &args[1]))
} else { } else {
None None
} }
} else if let Some(c) = constant_simple(cx, cx.tables, &args[1]) { } else if let Some(c) = constant_simple(cx, cx.tables(), &args[1]) {
Some((m, c, &args[0])) Some((m, c, &args[0]))
} else { } else {
None None

View file

@ -436,7 +436,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
binding != "_result" && // FIXME: #944 binding != "_result" && // FIXME: #944
is_used(cx, expr) && is_used(cx, expr) &&
// don't lint if the declaration is in a macro // don't lint if the declaration is in a macro
non_macro_local(cx, cx.tables.qpath_res(qpath, expr.hir_id)) non_macro_local(cx, cx.tables().qpath_res(qpath, expr.hir_id))
{ {
Some(binding) Some(binding)
} else { } else {
@ -496,7 +496,7 @@ fn get_lint_and_message(
fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) { fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) {
if_chain! { if_chain! {
if !in_constant(cx, cmp_expr.hir_id); if !in_constant(cx, cmp_expr.hir_id);
if let Some((value, _)) = constant(cx, cx.tables, expr); if let Some((value, _)) = constant(cx, cx.tables(), expr);
then { then {
let needs_lint = match value { let needs_lint = match value {
Constant::F32(num) => num.is_nan(), Constant::F32(num) => num.is_nan(),
@ -517,7 +517,7 @@ fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr<'_>, cmp_expr: &Expr<'_>) {
} }
fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool {
if let Some((_, res)) = constant(cx, cx.tables, expr) { if let Some((_, res)) = constant(cx, cx.tables(), expr) {
res res
} else { } else {
false false
@ -525,7 +525,7 @@ fn is_named_constant<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>)
} }
fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool { fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> bool {
match constant(cx, cx.tables, expr) { match constant(cx, cx.tables(), expr) {
Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(), Some((Constant::F32(f), _)) => f == 0.0 || f.is_infinite(),
Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(), Some((Constant::F64(f), _)) => f == 0.0 || f.is_infinite(),
Some((Constant::Vec(vec), _)) => vec.iter().all(|f| match f { Some((Constant::Vec(vec), _)) => vec.iter().all(|f| match f {
@ -557,7 +557,7 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
} }
fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
let value = &walk_ptrs_ty(cx.tables.expr_ty(expr)).kind; let value = &walk_ptrs_ty(cx.tables().expr_ty(expr)).kind;
if let ty::Array(arr_ty, _) = value { if let ty::Array(arr_ty, _) = value {
return matches!(arr_ty.kind, ty::Float(_)); return matches!(arr_ty.kind, ty::Float(_));
@ -567,14 +567,14 @@ fn is_float(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
} }
fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
matches!(&walk_ptrs_ty(cx.tables.expr_ty(expr)).kind, ty::Array(_, _)) matches!(&walk_ptrs_ty(cx.tables().expr_ty(expr)).kind, ty::Array(_, _))
} }
fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) {
let (arg_ty, snip) = match expr.kind { let (arg_ty, snip) = match expr.kind {
ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => { ExprKind::MethodCall(.., ref args, _) if args.len() == 1 => {
if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) { if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) {
(cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) (cx.tables().expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, ".."))
} else { } else {
return; return;
} }
@ -582,7 +582,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) {
ExprKind::Call(ref path, ref v) if v.len() == 1 => { ExprKind::Call(ref path, ref v) if v.len() == 1 => {
if let ExprKind::Path(ref path) = path.kind { if let ExprKind::Path(ref path) = path.kind {
if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) { if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) {
(cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, "..")) (cx.tables().expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, ".."))
} else { } else {
return; return;
} }
@ -593,7 +593,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) {
_ => return, _ => return,
}; };
let other_ty = cx.tables.expr_ty_adjusted(other); let other_ty = cx.tables().expr_ty_adjusted(other);
let partial_eq_trait_id = match cx.tcx.lang_items().eq_trait() { let partial_eq_trait_id = match cx.tcx.lang_items().eq_trait() {
Some(id) => id, Some(id) => id,
None => return, None => return,

View file

@ -37,8 +37,8 @@ struct OperandInfo {
} }
fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<OperandInfo> { fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<OperandInfo> {
match constant(cx, cx.tables, operand) { match constant(cx, cx.tables(), operand) {
Some((Constant::Int(v), _)) => match cx.tables.expr_ty(expr).kind { Some((Constant::Int(v), _)) => match cx.tables().expr_ty(expr).kind {
ty::Int(ity) => { ty::Int(ity) => {
let value = sext(cx.tcx, v, ity); let value = sext(cx.tcx, v, ity);
return Some(OperandInfo { return Some(OperandInfo {
@ -106,7 +106,7 @@ fn check_const_operands<'a, 'tcx>(
} }
fn check_non_const_operands<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) { fn check_non_const_operands<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) {
let operand_type = cx.tables.expr_ty(operand); let operand_type = cx.tables().expr_ty(operand);
if might_have_negative_value(operand_type) { if might_have_negative_value(operand_type) {
span_lint_and_then( span_lint_and_then(
cx, cx,

View file

@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableKeyType {
if let hir::PatKind::Wild = local.pat.kind { if let hir::PatKind::Wild = local.pat.kind {
return; return;
} }
check_ty(cx, local.span, cx.tables.pat_ty(&*local.pat)); check_ty(cx, local.span, cx.tables().pat_ty(&*local.pat));
} }
} }

View file

@ -69,7 +69,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
expr.span, expr.span,
"generally you want to avoid `&mut &mut _` if possible", "generally you want to avoid `&mut &mut _` if possible",
); );
} else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.tables.expr_ty(e).kind { } else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.tables().expr_ty(e).kind {
span_lint( span_lint(
self.cx, self.cx,
MUT_MUT, MUT_MUT,

View file

@ -37,14 +37,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
check_arguments( check_arguments(
cx, cx,
arguments, arguments,
cx.tables.expr_ty(fn_expr), cx.tables().expr_ty(fn_expr),
&rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)), &rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false)),
); );
} }
}, },
ExprKind::MethodCall(ref path, _, ref arguments, _) => { ExprKind::MethodCall(ref path, _, ref arguments, _) => {
let def_id = cx.tables.type_dependent_def_id(e.hir_id).unwrap(); let def_id = cx.tables().type_dependent_def_id(e.hir_id).unwrap();
let substs = cx.tables.node_substs(e.hir_id); let substs = cx.tables().node_substs(e.hir_id);
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
check_arguments(cx, arguments, method_type, &path.ident.as_str()) check_arguments(cx, arguments, method_type, &path.ident.as_str())
}, },

View file

@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MutArgVisitor<'a, 'tcx> {
return; return;
}, },
ExprKind::Path(_) => { ExprKind::Path(_) => {
if let Some(adj) = self.cx.tables.adjustments().get(expr.hir_id) { if let Some(adj) = self.cx.tables().adjustments().get(expr.hir_id) {
if adj if adj
.iter() .iter()
.any(|a| matches!(a.target.kind, ty::Ref(_, _, Mutability::Mut))) .any(|a| matches!(a.target.kind, ty::Ref(_, _, Mutability::Mut)))

View file

@ -66,7 +66,7 @@ declare_lint_pass!(Mutex => [MUTEX_ATOMIC, MUTEX_INTEGER]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if let ty::Adt(_, subst) = ty.kind { if let ty::Adt(_, subst) = ty.kind {
if is_type_diagnostic_item(cx, ty, sym!(mutex_type)) { if is_type_diagnostic_item(cx, ty, sym!(mutex_type)) {
let mutex_param = subst.type_at(0); let mutex_param = subst.type_at(0);

View file

@ -229,7 +229,7 @@ fn check_comparison<'a, 'tcx>(
use self::Expression::{Bool, Other}; use self::Expression::{Bool, Other};
if let ExprKind::Binary(op, ref left_side, ref right_side) = e.kind { if let ExprKind::Binary(op, ref left_side, ref right_side) = e.kind {
let (l_ty, r_ty) = (cx.tables.expr_ty(left_side), cx.tables.expr_ty(right_side)); let (l_ty, r_ty) = (cx.tables().expr_ty(left_side), cx.tables().expr_ty(right_side));
if l_ty.is_bool() && r_ty.is_bool() { if l_ty.is_bool() && r_ty.is_bool() {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;

View file

@ -46,8 +46,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
return; return;
} }
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = e.kind { if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = e.kind {
if let ty::Ref(..) = cx.tables.expr_ty(inner).kind { if let ty::Ref(..) = cx.tables().expr_ty(inner).kind {
for adj3 in cx.tables.expr_adjustments(e).windows(3) { for adj3 in cx.tables().expr_adjustments(e).windows(3) {
if let [Adjustment { if let [Adjustment {
kind: Adjust::Deref(_), .. kind: Adjust::Deref(_), ..
}, Adjustment { }, Adjustment {
@ -85,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
} }
if_chain! { if_chain! {
if let PatKind::Binding(BindingAnnotation::Ref, .., name, _) = pat.kind; if let PatKind::Binding(BindingAnnotation::Ref, .., name, _) = pat.kind;
if let ty::Ref(_, tam, mutbl) = cx.tables.pat_ty(pat).kind; if let ty::Ref(_, tam, mutbl) = cx.tables().pat_ty(pat).kind;
if mutbl == Mutability::Not; if mutbl == Mutability::Not;
if let ty::Ref(_, _, mutbl) = tam.kind; if let ty::Ref(_, _, mutbl) = tam.kind;
// only lint immutable refs, because borrowed `&mut T` cannot be moved out // only lint immutable refs, because borrowed `&mut T` cannot be moved out

View file

@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
} = { } = {
let mut ctx = MovedVariablesCtxt::default(); let mut ctx = MovedVariablesCtxt::default();
cx.tcx.infer_ctxt().enter(|infcx| { cx.tcx.infer_ctxt().enter(|infcx| {
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.tables).consume_body(body); euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.tables()).consume_body(body);
}); });
ctx ctx
}; };
@ -173,13 +173,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
!preds.is_empty() && { !preds.is_empty() && {
let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty); let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_root_empty, ty);
preds.iter().all(|t| { preds.iter().all(|t| {
let ty_params = &t let ty_params = &t.skip_binder().trait_ref.substs.iter().skip(1).collect::<Vec<_>>();
.skip_binder()
.trait_ref
.substs
.iter()
.skip(1)
.collect::<Vec<_>>();
implements_trait(cx, ty_empty_region, t.def_id(), ty_params) implements_trait(cx, ty_empty_region, t.def_id(), ty_params)
}) })
}, },

View file

@ -47,7 +47,7 @@ declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessUpdate { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessUpdate {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind { if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind {
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if let ty::Adt(def, _) = ty.kind { if let ty::Adt(def, _) = ty.kind {
if fields.len() == def.non_enum_variant().fields.len() { if fields.len() == def.non_enum_variant().fields.len() {
span_lint( span_lint(

View file

@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd {
then { then {
let ty = cx.tables.expr_ty(left); let ty = cx.tables().expr_ty(left);
let implements_ord = { let implements_ord = {
if let Some(id) = utils::get_trait_def_id(cx, &paths::ORD) { if let Some(id) = utils::get_trait_def_id(cx, &paths::ORD) {

View file

@ -44,8 +44,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
if_chain! { if_chain! {
if let ExprKind::Lit(ref l) = lit.kind; if let ExprKind::Lit(ref l) = lit.kind;
if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.tables.expr_ty_opt(lit)); if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.tables().expr_ty_opt(lit));
if cx.tables.expr_ty(exp).is_integral(); if cx.tables().expr_ty(exp).is_integral();
then { then {
span_lint(cx, NEG_MULTIPLY, span, "Negation by multiplying with `-1`"); span_lint(cx, NEG_MULTIPLY, span, "Negation by multiplying with `-1`");
} }

View file

@ -48,7 +48,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
} }
match expr.kind { match expr.kind {
ExprKind::Lit(..) | ExprKind::Closure(..) => true, ExprKind::Lit(..) | ExprKind::Closure(..) => true,
ExprKind::Path(..) => !has_drop(cx, cx.tables.expr_ty(expr)), ExprKind::Path(..) => !has_drop(cx, cx.tables().expr_ty(expr)),
ExprKind::Index(ref a, ref b) | ExprKind::Binary(_, ref a, ref b) => { ExprKind::Index(ref a, ref b) | ExprKind::Binary(_, ref a, ref b) => {
has_no_effect(cx, a) && has_no_effect(cx, b) has_no_effect(cx, a) && has_no_effect(cx, b)
}, },
@ -61,7 +61,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
| ExprKind::AddrOf(_, _, ref inner) | ExprKind::AddrOf(_, _, ref inner)
| ExprKind::Box(ref inner) => has_no_effect(cx, inner), | ExprKind::Box(ref inner) => has_no_effect(cx, inner),
ExprKind::Struct(_, ref fields, ref base) => { ExprKind::Struct(_, ref fields, ref base) => {
!has_drop(cx, cx.tables.expr_ty(expr)) !has_drop(cx, cx.tables().expr_ty(expr))
&& fields.iter().all(|field| has_no_effect(cx, &field.expr)) && fields.iter().all(|field| has_no_effect(cx, &field.expr))
&& base.as_ref().map_or(true, |base| has_no_effect(cx, base)) && base.as_ref().map_or(true, |base| has_no_effect(cx, base))
}, },
@ -70,7 +70,7 @@ fn has_no_effect(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
let res = qpath_res(cx, qpath, callee.hir_id); let res = qpath_res(cx, qpath, callee.hir_id);
match res { match res {
Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) => { Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) => {
!has_drop(cx, cx.tables.expr_ty(expr)) && args.iter().all(|arg| has_no_effect(cx, arg)) !has_drop(cx, cx.tables().expr_ty(expr)) && args.iter().all(|arg| has_no_effect(cx, arg))
}, },
_ => false, _ => false,
} }
@ -137,7 +137,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option
| ExprKind::AddrOf(_, _, ref inner) | ExprKind::AddrOf(_, _, ref inner)
| ExprKind::Box(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])), | ExprKind::Box(ref inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
ExprKind::Struct(_, ref fields, ref base) => { ExprKind::Struct(_, ref fields, ref base) => {
if has_drop(cx, cx.tables.expr_ty(expr)) { if has_drop(cx, cx.tables().expr_ty(expr)) {
None None
} else { } else {
Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect()) Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect())
@ -148,7 +148,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option
let res = qpath_res(cx, qpath, callee.hir_id); let res = qpath_res(cx, qpath, callee.hir_id);
match res { match res {
Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)
if !has_drop(cx, cx.tables.expr_ty(expr)) => if !has_drop(cx, cx.tables().expr_ty(expr)) =>
{ {
Some(args.iter().collect()) Some(args.iter().collect())
}, },

View file

@ -237,13 +237,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
} }
let ty = if needs_check_adjustment { let ty = if needs_check_adjustment {
let adjustments = cx.tables.expr_adjustments(dereferenced_expr); let adjustments = cx.tables().expr_adjustments(dereferenced_expr);
if let Some(i) = adjustments.iter().position(|adj| match adj.kind { if let Some(i) = adjustments.iter().position(|adj| match adj.kind {
Adjust::Borrow(_) | Adjust::Deref(_) => true, Adjust::Borrow(_) | Adjust::Deref(_) => true,
_ => false, _ => false,
}) { }) {
if i == 0 { if i == 0 {
cx.tables.expr_ty(dereferenced_expr) cx.tables().expr_ty(dereferenced_expr)
} else { } else {
adjustments[i - 1].target adjustments[i - 1].target
} }
@ -252,7 +252,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
return; return;
} }
} else { } else {
cx.tables.expr_ty(dereferenced_expr) cx.tables().expr_ty(dereferenced_expr)
}; };
verify_ty_bound(cx, ty, Source::Expr { expr: expr.span }); verify_ty_bound(cx, ty, Source::Expr { expr: expr.span });

View file

@ -30,7 +30,7 @@ declare_lint_pass!(OpenOptions => [NONSENSICAL_OPEN_OPTIONS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
if let ExprKind::MethodCall(ref path, _, ref arguments, _) = e.kind { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = e.kind {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0]));
if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
let mut options = Vec::new(); let mut options = Vec::new();
get_open_options(cx, &arguments[0], &mut options); get_open_options(cx, &arguments[0], &mut options);
@ -58,7 +58,7 @@ enum OpenOption {
fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) { fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) {
if let ExprKind::MethodCall(ref path, _, ref arguments, _) = argument.kind { if let ExprKind::MethodCall(ref path, _, ref arguments, _) = argument.kind {
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0])); let obj_ty = walk_ptrs_ty(cx.tables().expr_ty(&arguments[0]));
// Only proceed if this is a call on some object of type std::fs::OpenOptions // Only proceed if this is a call on some object of type std::fs::OpenOptions
if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 { if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 {

View file

@ -36,8 +36,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind; if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind;
if let ExprKind::Path(QPath::Resolved(_, ref path3)) = second.kind; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = second.kind;
if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]);
if cx.tables.expr_ty(ident1).is_integral(); if cx.tables().expr_ty(ident1).is_integral();
if cx.tables.expr_ty(ident2).is_integral(); if cx.tables().expr_ty(ident2).is_integral();
then { then {
if let BinOpKind::Lt = op.node { if let BinOpKind::Lt = op.node {
if let BinOpKind::Add = op2.node { if let BinOpKind::Add = op2.node {
@ -61,8 +61,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind; if let ExprKind::Path(QPath::Resolved(_, ref path2)) = ident2.kind;
if let ExprKind::Path(QPath::Resolved(_, ref path3)) = first.kind; if let ExprKind::Path(QPath::Resolved(_, ref path3)) = first.kind;
if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]);
if cx.tables.expr_ty(ident1).is_integral(); if cx.tables().expr_ty(ident1).is_integral();
if cx.tables.expr_ty(ident2).is_integral(); if cx.tables().expr_ty(ident2).is_integral();
then { then {
if let BinOpKind::Gt = op.node { if let BinOpKind::Gt = op.node {
if let BinOpKind::Add = op2.node { if let BinOpKind::Add = op2.node {

View file

@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathBufPushOverwrite {
if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind;
if path.ident.name == sym!(push); if path.ident.name == sym!(push);
if args.len() == 2; if args.len() == 2;
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::PATH_BUF); if match_type(cx, walk_ptrs_ty(cx.tables().expr_ty(&args[0])), &paths::PATH_BUF);
if let Some(get_index_arg) = args.get(1); if let Some(get_index_arg) = args.get(1);
if let ExprKind::Lit(ref lit) = get_index_arg.kind; if let ExprKind::Lit(ref lit) = get_index_arg.kind;
if let LitKind::Str(ref path_lit, _) = lit.node; if let LitKind::Str(ref path_lit, _) = lit.node;

View file

@ -105,12 +105,12 @@ fn expr_as_ptr_offset_call<'a, 'tcx>(
// Is the type of the expression a usize? // Is the type of the expression a usize?
fn is_expr_ty_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { fn is_expr_ty_usize<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool {
cx.tables.expr_ty(expr) == cx.tcx.types.usize cx.tables().expr_ty(expr) == cx.tcx.types.usize
} }
// Is the type of the expression a raw pointer? // Is the type of the expression a raw pointer?
fn is_expr_ty_raw_ptr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool { fn is_expr_ty_raw_ptr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr<'_>) -> bool {
cx.tables.expr_ty(expr).is_unsafe_ptr() cx.tables().expr_ty(expr).is_unsafe_ptr()
} }
fn build_suggestion<'a, 'tcx>( fn build_suggestion<'a, 'tcx>(

View file

@ -135,13 +135,13 @@ impl QuestionMark {
} }
fn moves_by_default(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { fn moves_by_default(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
let expr_ty = cx.tables.expr_ty(expression); let expr_ty = cx.tables().expr_ty(expression);
!expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env) !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env)
} }
fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool { fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
let expr_ty = cx.tables.expr_ty(expression); let expr_ty = cx.tables().expr_ty(expression);
is_type_diagnostic_item(cx, expr_ty, sym!(option_type)) is_type_diagnostic_item(cx, expr_ty, sym!(option_type))
} }
@ -158,7 +158,7 @@ impl QuestionMark {
ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr), ExprKind::Ret(Some(ref expr)) => Self::expression_returns_none(cx, expr),
ExprKind::Path(ref qp) => { ExprKind::Path(ref qp) => {
if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) = if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) =
cx.tables.qpath_res(qp, expression.hir_id) cx.tables().qpath_res(qp, expression.hir_id)
{ {
return match_def_path(cx, def_id, &paths::OPTION_NONE); return match_def_path(cx, def_id, &paths::OPTION_NONE);
} }

View file

@ -272,10 +272,10 @@ fn check_reversed_empty_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
if_chain! { if_chain! {
if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(cx, expr); if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(cx, expr);
let ty = cx.tables.expr_ty(start); let ty = cx.tables().expr_ty(start);
if let ty::Int(_) | ty::Uint(_) = ty.kind; if let ty::Int(_) | ty::Uint(_) = ty.kind;
if let Some((start_idx, _)) = constant(cx, cx.tables, start); if let Some((start_idx, _)) = constant(cx, cx.tables(), start);
if let Some((end_idx, _)) = constant(cx, cx.tables, end); if let Some((end_idx, _)) = constant(cx, cx.tables(), end);
if let Some(ordering) = Constant::partial_cmp(cx.tcx, ty, &start_idx, &end_idx); if let Some(ordering) = Constant::partial_cmp(cx.tcx, ty, &start_idx, &end_idx);
if is_empty_range(limits, ordering); if is_empty_range(limits, ordering);
then { then {

View file

@ -82,7 +82,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex {
if_chain! { if_chain! {
if self.last.is_none(); if self.last.is_none();
if let Some(ref expr) = block.expr; if let Some(ref expr) = block.expr;
if match_type(cx, cx.tables.expr_ty(expr), &paths::REGEX); if match_type(cx, cx.tables().expr_ty(expr), &paths::REGEX);
if let Some(span) = is_expn_of(expr.span, "regex"); if let Some(span) = is_expn_of(expr.span, "regex");
then { then {
if !self.spans.contains(&span) { if !self.spans.contains(&span) {
@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex {
if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Call(ref fun, ref args) = expr.kind;
if let ExprKind::Path(ref qpath) = fun.kind; if let ExprKind::Path(ref qpath) = fun.kind;
if args.len() == 1; if args.len() == 1;
if let Some(def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id();
then { then {
if match_def_path(cx, def_id, &paths::REGEX_NEW) || if match_def_path(cx, def_id, &paths::REGEX_NEW) ||
match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) { match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) {
@ -140,7 +140,7 @@ fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span {
} }
fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> Option<String> { fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) -> Option<String> {
constant(cx, cx.tables, e).and_then(|(c, _)| match c { constant(cx, cx.tables(), e).and_then(|(c, _)| match c {
Constant::Str(s) => Some(s), Constant::Str(s) => Some(s),
_ => None, _ => None,
}) })

View file

@ -164,7 +164,7 @@ fn check_local<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>, bin
} }
fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool { fn is_binding(cx: &LateContext<'_, '_>, pat_id: HirId) -> bool {
let var_ty = cx.tables.node_type_opt(pat_id); let var_ty = cx.tables().node_type_opt(pat_id);
if let Some(var_ty) = var_ty { if let Some(var_ty) = var_ty {
match var_ty.kind { match var_ty.kind {
ty::Adt(..) => false, ty::Adt(..) => false,

View file

@ -134,7 +134,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
} }
fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { fn is_string(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool {
is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), sym!(string_type)) is_type_diagnostic_item(cx, walk_ptrs_ty(cx.tables().expr_ty(e)), sym!(string_type))
} }
fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool { fn is_add(cx: &LateContext<'_, '_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {

View file

@ -194,7 +194,7 @@ fn check_for_slice<'a>(cx: &LateContext<'_, '_>, lhs1: &'a Expr<'_>, lhs2: &'a E
if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.kind { if let ExprKind::Index(ref lhs1, ref idx1) = lhs1.kind {
if let ExprKind::Index(ref lhs2, ref idx2) = lhs2.kind { if let ExprKind::Index(ref lhs2, ref idx2) = lhs2.kind {
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) { if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) {
let ty = walk_ptrs_ty(cx.tables.expr_ty(lhs1)); let ty = walk_ptrs_ty(cx.tables().expr_ty(lhs1));
if matches!(ty.kind, ty::Slice(_)) if matches!(ty.kind, ty::Slice(_))
|| matches!(ty.kind, ty::Array(_, _)) || matches!(ty.kind, ty::Array(_, _))

View file

@ -26,7 +26,7 @@ fn is_temporary(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
match &expr.kind { match &expr.kind {
ExprKind::Struct(..) | ExprKind::Tup(..) => true, ExprKind::Struct(..) | ExprKind::Tup(..) => true,
ExprKind::Path(qpath) => { ExprKind::Path(qpath) => {
if let Res::Def(DefKind::Const, ..) = cx.tables.qpath_res(qpath, expr.hir_id) { if let Res::Def(DefKind::Const, ..) = cx.tables().qpath_res(qpath, expr.hir_id) {
true true
} else { } else {
false false

View file

@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome {
if_chain! { if_chain! {
if let [char_arg, radix_arg] = &**to_digit_args; if let [char_arg, radix_arg] = &**to_digit_args;
if to_digits_path.ident.name.as_str() == "to_digit"; if to_digits_path.ident.name.as_str() == "to_digit";
let char_arg_ty = cx.tables.expr_ty_adjusted(char_arg); let char_arg_ty = cx.tables().expr_ty_adjusted(char_arg);
if char_arg_ty.kind == ty::Char; if char_arg_ty.kind == ty::Char;
then { then {
Some((true, char_arg, radix_arg)) Some((true, char_arg, radix_arg))
@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome {
if_chain! { if_chain! {
if let [char_arg, radix_arg] = &**to_digit_args; if let [char_arg, radix_arg] = &**to_digit_args;
if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind; if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind;
if let to_digits_call_res = cx.tables.qpath_res(to_digits_path, to_digits_call.hir_id); if let to_digits_call_res = cx.tables().qpath_res(to_digits_path, to_digits_call.hir_id);
if let Some(to_digits_def_id) = to_digits_call_res.opt_def_id(); if let Some(to_digits_def_id) = to_digits_call_res.opt_def_id();
if match_def_path(cx, to_digits_def_id, &["core", "char", "methods", "<impl char>", "to_digit"]); if match_def_path(cx, to_digits_def_id, &["core", "char", "methods", "<impl char>", "to_digit"]);
then { then {

View file

@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TraitBounds {
return; return;
} }
let hash = |ty| -> u64 { let hash = |ty| -> u64 {
let mut hasher = SpanlessHash::new(cx, cx.tables); let mut hasher = SpanlessHash::new(cx, cx.tables());
hasher.hash_ty(ty); hasher.hash_ty(ty);
hasher.finish() hasher.finish()
}; };

View file

@ -299,11 +299,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
if_chain! { if_chain! {
if let ExprKind::Call(ref path_expr, ref args) = e.kind; if let ExprKind::Call(ref path_expr, ref args) = e.kind;
if let ExprKind::Path(ref qpath) = path_expr.kind; if let ExprKind::Path(ref qpath) = path_expr.kind;
if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(qpath, path_expr.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::TRANSMUTE); if match_def_path(cx, def_id, &paths::TRANSMUTE);
then { then {
let from_ty = cx.tables.expr_ty(&args[0]); let from_ty = cx.tables().expr_ty(&args[0]);
let to_ty = cx.tables.expr_ty(e); let to_ty = cx.tables().expr_ty(e);
match (&from_ty.kind, &to_ty.kind) { match (&from_ty.kind, &to_ty.kind) {
_ if from_ty == to_ty => span_lint( _ if from_ty == to_ty => span_lint(

View file

@ -44,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutingNull {
then { then {
// Catching transmute over constants that resolve to `null`. // Catching transmute over constants that resolve to `null`.
let mut const_eval_context = constant_context(cx, cx.tables); let mut const_eval_context = constant_context(cx, cx.tables());
if_chain! { if_chain! {
if let ExprKind::Path(ref _qpath) = args[0].kind; if let ExprKind::Path(ref _qpath) = args[0].kind;
let x = const_eval_context.expr(&args[0]); let x = const_eval_context.expr(&args[0]);

View file

@ -68,7 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TryErr {
if let Some(return_type) = find_err_return_type(cx, &expr.kind); if let Some(return_type) = find_err_return_type(cx, &expr.kind);
then { then {
let err_type = cx.tables.expr_ty(err_arg); let err_type = cx.tables().expr_ty(err_arg);
let origin_snippet = if err_arg.span.from_expansion() { let origin_snippet = if err_arg.span.from_expansion() {
snippet_with_macro_callsite(cx, err_arg.span, "_") snippet_with_macro_callsite(cx, err_arg.span, "_")
} else { } else {
@ -114,7 +114,7 @@ fn find_err_return_type_arm<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arm: &'tcx Arm
if match_qpath(from_error_fn, &paths::TRY_FROM_ERROR); if match_qpath(from_error_fn, &paths::TRY_FROM_ERROR);
if let Some(from_error_arg) = from_error_args.get(0); if let Some(from_error_arg) = from_error_args.get(0);
then { then {
Some(cx.tables.expr_ty(from_error_arg)) Some(cx.tables().expr_ty(from_error_arg))
} else { } else {
None None
} }

View file

@ -603,7 +603,7 @@ declare_lint_pass!(LetUnitValue => [LET_UNIT_VALUE]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue {
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt<'_>) {
if let StmtKind::Local(ref local) = stmt.kind { if let StmtKind::Local(ref local) = stmt.kind {
if is_unit(cx.tables.pat_ty(&local.pat)) { if is_unit(cx.tables().pat_ty(&local.pat)) {
if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() { if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() {
return; return;
} }
@ -688,7 +688,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind { if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind {
if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind { if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind {
let op = cmp.node; let op = cmp.node;
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) { if op.is_comparison() && is_unit(cx.tables().expr_ty(left)) {
let result = match &*symbol.as_str() { let result = match &*symbol.as_str() {
"assert_eq" | "debug_assert_eq" => "succeed", "assert_eq" | "debug_assert_eq" => "succeed",
"assert_ne" | "debug_assert_ne" => "fail", "assert_ne" | "debug_assert_ne" => "fail",
@ -712,7 +712,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
} }
if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind { if let ExprKind::Binary(ref cmp, ref left, _) = expr.kind {
let op = cmp.node; let op = cmp.node;
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) { if op.is_comparison() && is_unit(cx.tables().expr_ty(left)) {
let result = match op { let result = match op {
BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => "true", BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => "true",
_ => "false", _ => "false",
@ -782,7 +782,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
let args_to_recover = args let args_to_recover = args
.iter() .iter()
.filter(|arg| { .filter(|arg| {
if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) { if is_unit(cx.tables().expr_ty(arg)) && !is_unit_literal(arg) {
if let ExprKind::Match(.., MatchSource::TryDesugar) = &arg.kind { if let ExprKind::Match(.., MatchSource::TryDesugar) = &arg.kind {
false false
} else { } else {
@ -1250,7 +1250,7 @@ fn check_loss_of_sign(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>,
} }
// don't lint for positive constants // don't lint for positive constants
let const_val = constant(cx, &cx.tables, op); let const_val = constant(cx, &cx.tables(), op);
if_chain! { if_chain! {
if let Some((const_val, _)) = const_val; if let Some((const_val, _)) = const_val;
if let Constant::Int(n) = const_val; if let Constant::Int(n) = const_val;
@ -1416,7 +1416,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Casts {
return; return;
} }
if let ExprKind::Cast(ref ex, _) = expr.kind { if let ExprKind::Cast(ref ex, _) = expr.kind {
let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr)); let (cast_from, cast_to) = (cx.tables().expr_ty(ex), cx.tables().expr_ty(expr));
lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to);
if let ExprKind::Lit(ref lit) = ex.kind { if let ExprKind::Lit(ref lit) = ex.kind {
if_chain! { if_chain! {
@ -1804,7 +1804,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 {
if let ExprKind::Cast(e, _) = &expr.kind; if let ExprKind::Cast(e, _) = &expr.kind;
if let ExprKind::Lit(l) = &e.kind; if let ExprKind::Lit(l) = &e.kind;
if let LitKind::Char(c) = l.node; if let LitKind::Char(c) = l.node;
if ty::Uint(UintTy::U8) == cx.tables.expr_ty(expr).kind; if ty::Uint(UintTy::U8) == cx.tables().expr_ty(expr).kind;
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability); let snippet = snippet_with_applicability(cx, e.span, "'x'", &mut applicability);
@ -1880,8 +1880,8 @@ enum AbsurdComparisonResult {
fn is_cast_between_fixed_and_target<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { fn is_cast_between_fixed_and_target<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
if let ExprKind::Cast(ref cast_exp, _) = expr.kind { if let ExprKind::Cast(ref cast_exp, _) = expr.kind {
let precast_ty = cx.tables.expr_ty(cast_exp); let precast_ty = cx.tables().expr_ty(cast_exp);
let cast_ty = cx.tables.expr_ty(expr); let cast_ty = cx.tables().expr_ty(expr);
return is_isize_or_usize(precast_ty) != is_isize_or_usize(cast_ty); return is_isize_or_usize(precast_ty) != is_isize_or_usize(cast_ty);
} }
@ -1901,7 +1901,7 @@ fn detect_absurd_comparison<'a, 'tcx>(
// absurd comparison only makes sense on primitive types // absurd comparison only makes sense on primitive types
// primitive types don't implement comparison operators with each other // primitive types don't implement comparison operators with each other
if cx.tables.expr_ty(lhs) != cx.tables.expr_ty(rhs) { if cx.tables().expr_ty(lhs) != cx.tables().expr_ty(rhs) {
return None; return None;
} }
@ -1939,9 +1939,9 @@ fn detect_absurd_comparison<'a, 'tcx>(
fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option<ExtremeExpr<'tcx>> { fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option<ExtremeExpr<'tcx>> {
use crate::types::ExtremeType::{Maximum, Minimum}; use crate::types::ExtremeType::{Maximum, Minimum};
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
let cv = constant(cx, cx.tables, expr)?.0; let cv = constant(cx, cx.tables(), expr)?.0;
let which = match (&ty.kind, cv) { let which = match (&ty.kind, cv) {
(&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => Minimum, (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => Minimum,
@ -2071,8 +2071,8 @@ impl Ord for FullInt {
fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> { fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> {
if let ExprKind::Cast(ref cast_exp, _) = expr.kind { if let ExprKind::Cast(ref cast_exp, _) = expr.kind {
let pre_cast_ty = cx.tables.expr_ty(cast_exp); let pre_cast_ty = cx.tables().expr_ty(cast_exp);
let cast_ty = cx.tables.expr_ty(expr); let cast_ty = cx.tables().expr_ty(expr);
// if it's a cast from i32 to u32 wrapping will invalidate all these checks // if it's a cast from i32 to u32 wrapping will invalidate all these checks
if cx.layout_of(pre_cast_ty).ok().map(|l| l.size) == cx.layout_of(cast_ty).ok().map(|l| l.size) { if cx.layout_of(pre_cast_ty).ok().map(|l| l.size) == cx.layout_of(cast_ty).ok().map(|l| l.size) {
return None; return None;
@ -2102,9 +2102,9 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'_>)
} }
fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option<FullInt> { fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> Option<FullInt> {
let val = constant(cx, cx.tables, expr)?.0; let val = constant(cx, cx.tables(), expr)?.0;
if let Constant::Int(const_int) = val { if let Constant::Int(const_int) = val {
match cx.tables.expr_ty(expr).kind { match cx.tables().expr_ty(expr).kind {
ty::Int(ity) => Some(FullInt::S(sext(cx.tcx, const_int, ity))), ty::Int(ity) => Some(FullInt::S(sext(cx.tcx, const_int, ity))),
ty::Uint(_) => Some(FullInt::U(const_int)), ty::Uint(_) => Some(FullInt::U(const_int)),
_ => None, _ => None,
@ -2499,7 +2499,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
fn new(cx: &'a LateContext<'a, 'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self { fn new(cx: &'a LateContext<'a, 'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self {
Self { Self {
cx, cx,
body: cx.tables, body: cx.tables(),
target, target,
suggestions: BTreeMap::new(), suggestions: BTreeMap::new(),
} }
@ -2608,7 +2608,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RefToMut {
if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind; if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind;
if let ExprKind::Cast(e, t) = &e.kind; if let ExprKind::Cast(e, t) = &e.kind;
if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind; if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind;
if let ty::Ref(..) = cx.tables.node_type(e.hir_id).kind; if let ty::Ref(..) = cx.tables().node_type(e.hir_id).kind;
then { then {
span_lint( span_lint(
cx, cx,

View file

@ -65,14 +65,14 @@ impl LateLintPass<'_, '_> for UnnamedAddress {
} }
fn is_trait_ptr(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_trait_ptr(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
match cx.tables.expr_ty_adjusted(expr).kind { match cx.tables().expr_ty_adjusted(expr).kind {
ty::RawPtr(ty::TypeAndMut { ty, .. }) => ty.is_trait(), ty::RawPtr(ty::TypeAndMut { ty, .. }) => ty.is_trait(),
_ => false, _ => false,
} }
} }
fn is_fn_def(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn is_fn_def(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
if let ty::FnDef(..) = cx.tables.expr_ty(expr).kind { if let ty::FnDef(..) = cx.tables().expr_ty(expr).kind {
true true
} else { } else {
false false
@ -98,11 +98,11 @@ impl LateLintPass<'_, '_> for UnnamedAddress {
if_chain! { if_chain! {
if let ExprKind::Call(ref func, [ref _left, ref _right]) = expr.kind; if let ExprKind::Call(ref func, [ref _left, ref _right]) = expr.kind;
if let ExprKind::Path(ref func_qpath) = func.kind; if let ExprKind::Path(ref func_qpath) = func.kind;
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(func_qpath, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::PTR_EQ) || if match_def_path(cx, def_id, &paths::PTR_EQ) ||
match_def_path(cx, def_id, &paths::RC_PTR_EQ) || match_def_path(cx, def_id, &paths::RC_PTR_EQ) ||
match_def_path(cx, def_id, &paths::ARC_PTR_EQ); match_def_path(cx, def_id, &paths::ARC_PTR_EQ);
let ty_param = cx.tables.node_substs(func.hir_id).type_at(0); let ty_param = cx.tables().node_substs(func.hir_id).type_at(0);
if ty_param.is_trait(); if ty_param.is_trait();
then { then {
span_lint_and_help( span_lint_and_help(
@ -119,8 +119,8 @@ impl LateLintPass<'_, '_> for UnnamedAddress {
if_chain! { if_chain! {
if let ExprKind::Binary(binop, ref left, ref right) = expr.kind; if let ExprKind::Binary(binop, ref left, ref right) = expr.kind;
if is_comparison(binop.node); if is_comparison(binop.node);
if cx.tables.expr_ty_adjusted(left).is_fn_ptr() && if cx.tables().expr_ty_adjusted(left).is_fn_ptr() &&
cx.tables.expr_ty_adjusted(right).is_fn_ptr(); cx.tables().expr_ty_adjusted(right).is_fn_ptr();
if is_fn_def(cx, left) || is_fn_def(cx, right); if is_fn_def(cx, left) || is_fn_def(cx, right);
then { then {
span_lint( span_lint(

View file

@ -177,7 +177,7 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<LintTrigger>
if let name = name_ident.ident.name.to_ident_string(); if let name = name_ident.ident.name.to_ident_string();
if name == "sort_by" || name == "sort_unstable_by"; if name == "sort_by" || name == "sort_unstable_by";
if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args; if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args;
if utils::match_type(cx, &cx.tables.expr_ty(vec), &paths::VEC); if utils::match_type(cx, &cx.tables().expr_ty(vec), &paths::VEC);
if let closure_body = cx.tcx.hir().body(*closure_body_id); if let closure_body = cx.tcx.hir().body(*closure_body_id);
if let &[ if let &[
Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..}, Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..},

View file

@ -114,7 +114,7 @@ fn collect_unwrap_info<'a, 'tcx>(
if_chain! { if_chain! {
if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind; if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind;
if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind; if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind;
let ty = cx.tables.expr_ty(&args[0]); let ty = cx.tables().expr_ty(&args[0]);
let name = method_name.ident.as_str(); let name = method_name.ident.as_str();
if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name); if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name);
then { then {

View file

@ -63,8 +63,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
ExprKind::MethodCall(ref name, .., ref args, _) => { ExprKind::MethodCall(ref name, .., ref args, _) => {
if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" { if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" {
let a = cx.tables.expr_ty(e); let a = cx.tables().expr_ty(e);
let b = cx.tables.expr_ty(&args[0]); let b = cx.tables().expr_ty(&args[0]);
if TyS::same_type(a, b) { if TyS::same_type(a, b) {
let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string(); let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
span_lint_and_sugg( span_lint_and_sugg(
@ -79,8 +79,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
} }
} }
if match_trait_method(cx, e, &paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" { if match_trait_method(cx, e, &paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" {
let a = cx.tables.expr_ty(e); let a = cx.tables().expr_ty(e);
let b = cx.tables.expr_ty(&args[0]); let b = cx.tables().expr_ty(&args[0]);
if TyS::same_type(a, b) { if TyS::same_type(a, b) {
let sugg = snippet(cx, args[0].span, "<expr>").into_owned(); let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
span_lint_and_sugg( span_lint_and_sugg(
@ -96,8 +96,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
} }
if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && &*name.ident.as_str() == "try_into" { if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && &*name.ident.as_str() == "try_into" {
if_chain! { if_chain! {
let a = cx.tables.expr_ty(e); let a = cx.tables().expr_ty(e);
let b = cx.tables.expr_ty(&args[0]); let b = cx.tables().expr_ty(&args[0]);
if is_type_diagnostic_item(cx, a, sym!(result_type)); if is_type_diagnostic_item(cx, a, sym!(result_type));
if let ty::Adt(_, substs) = a.kind; if let ty::Adt(_, substs) = a.kind;
if let Some(a_type) = substs.types().next(); if let Some(a_type) = substs.types().next();
@ -121,9 +121,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessConversion {
if_chain! { if_chain! {
if args.len() == 1; if args.len() == 1;
if let ExprKind::Path(ref qpath) = path.kind; if let ExprKind::Path(ref qpath) = path.kind;
if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id(); if let Some(def_id) = cx.tables().qpath_res(qpath, path.hir_id).opt_def_id();
let a = cx.tables.expr_ty(e); let a = cx.tables().expr_ty(e);
let b = cx.tables.expr_ty(&args[0]); let b = cx.tables().expr_ty(&args[0]);
then { then {
if_chain! { if_chain! {

View file

@ -56,7 +56,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr<'_>)
Some(expr) Some(expr)
} }
let def_path = match cx.tables.expr_ty(expr).kind { let def_path = match cx.tables().expr_ty(expr).kind {
ty::Adt(def, _) => cx.tcx.def_path(def.did), ty::Adt(def, _) => cx.tcx.def_path(def.did),
_ => return None, _ => return None,
}; };
@ -262,7 +262,7 @@ pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr<'_>) -> Optio
if let hir::ExprKind::Call(ref fun, ref args) = expr.kind; if let hir::ExprKind::Call(ref fun, ref args) = expr.kind;
if let hir::ExprKind::Path(ref qpath) = fun.kind; if let hir::ExprKind::Path(ref qpath) = fun.kind;
if is_expn_of(fun.span, "vec").is_some(); if is_expn_of(fun.span, "vec").is_some();
if let Some(fun_def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id();
then { then {
return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 { return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 {
// `vec![elem; size]` case // `vec![elem; size]` case

View file

@ -32,7 +32,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self {
Self { Self {
cx, cx,
tables: cx.tables, tables: cx.tables(),
ignore_fn: false, ignore_fn: false,
} }
} }
@ -40,7 +40,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
pub fn ignore_fn(self) -> Self { pub fn ignore_fn(self) -> Self {
Self { Self {
cx: self.cx, cx: self.cx,
tables: self.cx.tables, tables: self.cx.tables(),
ignore_fn: true, ignore_fn: true,
} }
} }

View file

@ -114,7 +114,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector {
} }
match stmt.kind { match stmt.kind {
hir::StmtKind::Local(ref local) => { hir::StmtKind::Local(ref local) => {
println!("local variable of type {}", cx.tables.node_type(local.hir_id)); println!("local variable of type {}", cx.tables().node_type(local.hir_id));
println!("pattern:"); println!("pattern:");
print_pat(cx, &local.pat, 0); print_pat(cx, &local.pat, 0);
if let Some(ref e) = local.init { if let Some(ref e) = local.init {
@ -144,8 +144,8 @@ fn has_attr(sess: &Session, attrs: &[Attribute]) -> bool {
fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) { fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) {
let ind = " ".repeat(indent); let ind = " ".repeat(indent);
println!("{}+", ind); println!("{}+", ind);
println!("{}ty: {}", ind, cx.tables.expr_ty(expr)); println!("{}ty: {}", ind, cx.tables().expr_ty(expr));
println!("{}adjustments: {:?}", ind, cx.tables.adjustments().get(expr.hir_id)); println!("{}adjustments: {:?}", ind, cx.tables().adjustments().get(expr.hir_id));
match expr.kind { match expr.kind {
hir::ExprKind::Box(ref e) => { hir::ExprKind::Box(ref e) => {
println!("{}Box", ind); println!("{}Box", ind);

View file

@ -347,7 +347,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty<'_>) -> bool {
) = ty.kind ) = ty.kind
{ {
if let TyKind::Path(ref path) = inner.kind { if let TyKind::Path(ref path) = inner.kind {
if let Res::Def(DefKind::Struct, def_id) = cx.tables.qpath_res(path, inner.hir_id) { if let Res::Def(DefKind::Struct, def_id) = cx.tables().qpath_res(path, inner.hir_id) {
return match_def_path(cx, def_id, &paths::LINT); return match_def_path(cx, def_id, &paths::LINT);
} }
} }
@ -405,7 +405,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions {
if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind;
let fn_name = path.ident; let fn_name = path.ident;
if let Some(sugg) = self.map.get(&*fn_name.as_str()); if let Some(sugg) = self.map.get(&*fn_name.as_str());
let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); let ty = walk_ptrs_ty(cx.tables().expr_ty(&args[0]));
if match_type(cx, ty, &paths::EARLY_CONTEXT) if match_type(cx, ty, &paths::EARLY_CONTEXT)
|| match_type(cx, ty, &paths::LATE_CONTEXT); || match_type(cx, ty, &paths::LATE_CONTEXT);
then { then {
@ -438,7 +438,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnDataPass {
let args = arg_lists[1]; let args = arg_lists[1];
if args.len() == 1; if args.len() == 1;
let self_arg = &args[0]; let self_arg = &args[0];
let self_ty = walk_ptrs_ty(cx.tables.expr_ty(self_arg)); let self_ty = walk_ptrs_ty(cx.tables().expr_ty(self_arg));
if match_type(cx, self_ty, &paths::SYNTAX_CONTEXT); if match_type(cx, self_ty, &paths::SYNTAX_CONTEXT);
then { then {
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -151,7 +151,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_, '_>, ty: Ty<'_>, diag_item:
/// Checks if the method call given in `expr` belongs to the given trait. /// Checks if the method call given in `expr` belongs to the given trait.
pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr<'_>, path: &[&str]) -> bool { pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr<'_>, path: &[&str]) -> bool {
let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap(); let def_id = cx.tables().type_dependent_def_id(expr.hir_id).unwrap();
let trt_id = cx.tcx.trait_of_item(def_id); let trt_id = cx.tcx.trait_of_item(def_id);
if let Some(trt_id) = trt_id { if let Some(trt_id) = trt_id {
match_def_path(cx, trt_id, path) match_def_path(cx, trt_id, path)
@ -824,7 +824,7 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool {
/// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_typeck::check::coercion` for more /// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_typeck::check::coercion` for more
/// information on adjustments and coercions. /// information on adjustments and coercions.
pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool { pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr<'_>) -> bool {
cx.tables.adjustments().get(e.hir_id).is_some() cx.tables().adjustments().get(e.hir_id).is_some()
} }
/// Returns the pre-expansion span if is this comes from an expansion of the /// Returns the pre-expansion span if is this comes from an expansion of the
@ -898,7 +898,7 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
if let ExprKind::Call(ref fun, _) = expr.kind { if let ExprKind::Call(ref fun, _) = expr.kind {
if let ExprKind::Path(ref qp) = fun.kind { if let ExprKind::Path(ref qp) = fun.kind {
let res = cx.tables.qpath_res(qp, fun.hir_id); let res = cx.tables().qpath_res(qp, fun.hir_id);
return match res { return match res {
def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id), def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
@ -914,7 +914,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_, '_>, expr: &Exp
pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool { pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool {
fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, id: HirId) -> bool { fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath<'_>, id: HirId) -> bool {
matches!( matches!(
cx.tables.qpath_res(qpath, id), cx.tables().qpath_res(qpath, id),
def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _) def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
) )
} }
@ -941,7 +941,7 @@ pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat<'_>) -> bool {
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats.iter().map(|pat| &**pat)) is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats.iter().map(|pat| &**pat))
}, },
PatKind::Slice(ref head, ref middle, ref tail) => { PatKind::Slice(ref head, ref middle, ref tail) => {
match &cx.tables.node_type(pat.hir_id).kind { match &cx.tables().node_type(pat.hir_id).kind {
ty::Slice(..) => { ty::Slice(..) => {
// [..] is the only irrefutable slice pattern. // [..] is the only irrefutable slice pattern.
!head.is_empty() || middle.is_none() || !tail.is_empty() !head.is_empty() || middle.is_none() || !tail.is_empty()
@ -1190,7 +1190,7 @@ pub fn match_function_call<'a, 'tcx>(
if_chain! { if_chain! {
if let ExprKind::Call(ref fun, ref args) = expr.kind; if let ExprKind::Call(ref fun, ref args) = expr.kind;
if let ExprKind::Path(ref qpath) = fun.kind; if let ExprKind::Path(ref qpath) = fun.kind;
if let Some(fun_def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id(); if let Some(fun_def_id) = cx.tables().qpath_res(qpath, fun.hir_id).opt_def_id();
if match_def_path(cx, fun_def_id, path); if match_def_path(cx, fun_def_id, path);
then { then {
return Some(&args) return Some(&args)
@ -1317,14 +1317,14 @@ pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool
let did = match expr.kind { let did = match expr.kind {
ExprKind::Call(ref path, _) => if_chain! { ExprKind::Call(ref path, _) => if_chain! {
if let ExprKind::Path(ref qpath) = path.kind; if let ExprKind::Path(ref qpath) = path.kind;
if let def::Res::Def(_, did) = cx.tables.qpath_res(qpath, path.hir_id); if let def::Res::Def(_, did) = cx.tables().qpath_res(qpath, path.hir_id);
then { then {
Some(did) Some(did)
} else { } else {
None None
} }
}, },
ExprKind::MethodCall(_, _, _, _) => cx.tables.type_dependent_def_id(expr.hir_id), ExprKind::MethodCall(_, _, _, _) => cx.tables().type_dependent_def_id(expr.hir_id),
_ => None, _ => None,
}; };

View file

@ -18,7 +18,7 @@ pub fn mutated_variables<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &'a LateContext<'a,
}; };
let def_id = expr.hir_id.owner.to_def_id(); let def_id = expr.hir_id.owner.to_def_id();
cx.tcx.infer_ctxt().enter(|infcx| { cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables).walk_expr(expr); ExprUseVisitor::new(&mut delegate, &infcx, def_id.expect_local(), cx.param_env, cx.tables()).walk_expr(expr);
}); });
if delegate.skip { if delegate.skip {

View file

@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
// search for `&vec![_]` expressions where the adjusted type is `&[_]` // search for `&vec![_]` expressions where the adjusted type is `&[_]`
if_chain! { if_chain! {
if let ty::Ref(_, ty, _) = cx.tables.expr_ty_adjusted(expr).kind; if let ty::Ref(_, ty, _) = cx.tables().expr_ty_adjusted(expr).kind;
if let ty::Slice(..) = ty.kind; if let ty::Slice(..) = ty.kind;
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref addressee) = expr.kind; if let ExprKind::AddrOf(BorrowKind::Ref, _, ref addressee) = expr.kind;
if let Some(vec_args) = higher::vec_macro(cx, addressee); if let Some(vec_args) = higher::vec_macro(cx, addressee);
@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec {
if_chain! { if_chain! {
if let Some((_, arg, _)) = higher::for_loop(expr); if let Some((_, arg, _)) = higher::for_loop(expr);
if let Some(vec_args) = higher::vec_macro(cx, arg); if let Some(vec_args) = higher::vec_macro(cx, arg);
if is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg))); if is_copy(cx, vec_type(cx.tables().expr_ty_adjusted(arg)));
then { then {
// report the error around the `vec!` not inside `<std macros>:` // report the error around the `vec!` not inside `<std macros>:`
let span = arg.span let span = arg.span
@ -70,7 +70,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let snippet = match *vec_args { let snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => { higher::VecArgs::Repeat(elem, len) => {
if constant(cx, cx.tables, len).is_some() { if constant(cx, cx.tables(), len).is_some() {
format!( format!(
"&[{}; {}]", "&[{}; {}]",
snippet_with_applicability(cx, elem.span, "elem", &mut applicability), snippet_with_applicability(cx, elem.span, "elem", &mut applicability),

View file

@ -32,7 +32,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VecResizeToZero {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
if_chain! { if_chain! {
if let hir::ExprKind::MethodCall(path_segment, _, ref args, _) = expr.kind; if let hir::ExprKind::MethodCall(path_segment, _, ref args, _) = expr.kind;
if let Some(method_def_id) = cx.tables.type_dependent_def_id(expr.hir_id); if let Some(method_def_id) = cx.tables().type_dependent_def_id(expr.hir_id);
if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3; if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3;
if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind;
if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind;

View file

@ -62,7 +62,7 @@ fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'t
if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind;
if method_name.ident.as_str() == "read_to_end"; if method_name.ident.as_str() == "read_to_end";
if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind;
let ty = cx.tables.expr_ty(&exprs[0]); let ty = cx.tables().expr_ty(&exprs[0]);
if match_type(cx, ty, &paths::FILE); if match_type(cx, ty, &paths::FILE);
then { then {
return true return true
@ -76,7 +76,7 @@ fn is_file_read_to_string<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr
if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind; if let ExprKind::MethodCall(method_name, _, exprs, _) = expr.kind;
if method_name.ident.as_str() == "read_to_string"; if method_name.ident.as_str() == "read_to_string";
if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; if let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind;
let ty = cx.tables.expr_ty(&exprs[0]); let ty = cx.tables().expr_ty(&exprs[0]);
if match_type(cx, ty, &paths::FILE); if match_type(cx, ty, &paths::FILE);
then { then {
return true return true

View file

@ -36,8 +36,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ZeroDiv {
// TODO - constant_simple does not fold many operations involving floats. // TODO - constant_simple does not fold many operations involving floats.
// That's probably fine for this lint - it's pretty unlikely that someone would // That's probably fine for this lint - it's pretty unlikely that someone would
// do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too. // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too.
if let Some(lhs_value) = constant_simple(cx, cx.tables, left); if let Some(lhs_value) = constant_simple(cx, cx.tables(), left);
if let Some(rhs_value) = constant_simple(cx, cx.tables, right); if let Some(rhs_value) = constant_simple(cx, cx.tables(), right);
if Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value; if Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value;
if Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value; if Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value;
then { then {

View file

@ -19,11 +19,11 @@ Useful Rustc dev guide links:
Sometimes you may want to retrieve the type `Ty` of an expression `Expr`, for example to answer following questions: Sometimes you may want to retrieve the type `Ty` of an expression `Expr`, for example to answer following questions:
- which type does this expression correspond to (using its [`TyKind`][TyKind])? - which type does this expression correspond to (using its [`TyKind`][TyKind])?
- is it a sized type? - is it a sized type?
- is it a primitive type? - is it a primitive type?
- does it implement a trait? - does it implement a trait?
This operation is performed using the [`expr_ty()`][expr_ty] method from the [`TypeckTables`][TypeckTables] struct, This operation is performed using the [`expr_ty()`][expr_ty] method from the [`TypeckTables`][TypeckTables] struct,
that gives you access to the underlying structure [`TyS`][TyS]. that gives you access to the underlying structure [`TyS`][TyS].
Example of use: Example of use:
@ -31,7 +31,7 @@ Example of use:
impl LateLintPass<'_, '_> for MyStructLint { impl LateLintPass<'_, '_> for MyStructLint {
fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
// Get type of `expr` // Get type of `expr`
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
// Match its kind to enter its type // Match its kind to enter its type
match ty.kind { match ty.kind {
ty::Adt(adt_def, _) if adt_def.is_struct() => println!("Our `expr` is a struct!"), ty::Adt(adt_def, _) if adt_def.is_struct() => println!("Our `expr` is a struct!"),
@ -41,14 +41,14 @@ impl LateLintPass<'_, '_> for MyStructLint {
} }
``` ```
Similarly in [`TypeckTables`][TypeckTables] methods, you have the [`pat_ty()`][pat_ty] method Similarly in [`TypeckTables`][TypeckTables] methods, you have the [`pat_ty()`][pat_ty] method
to retrieve a type from a pattern. to retrieve a type from a pattern.
Two noticeable items here: Two noticeable items here:
- `cx` is the lint context [`LateContext`][LateContext]. - `cx` is the lint context [`LateContext`][LateContext].
The two most useful data structures in this context are `tcx` and `tables`, The two most useful data structures in this context are `tcx` and `tables`,
allowing us to jump to type definitions and other compilation stages such as HIR. allowing us to jump to type definitions and other compilation stages such as HIR.
- `tables` is [`TypeckTables`][TypeckTables] and is created by type checking step, - `tables` is [`TypeckTables`][TypeckTables] and is created by type checking step,
it includes useful information such as types of expressions, ways to resolve methods and so on. it includes useful information such as types of expressions, ways to resolve methods and so on.
# Checking if an expr is calling a specific method # Checking if an expr is calling a specific method
@ -87,7 +87,7 @@ impl LateLintPass<'_, '_> for MyStructLint {
} }
// 2. Using type context `TyCtxt` // 2. Using type context `TyCtxt`
let ty = cx.tables.expr_ty(expr); let ty = cx.tables().expr_ty(expr);
if cx.tcx.lang_items() if cx.tcx.lang_items()
// we are looking for the `DefId` of `Drop` trait in lang items // we are looking for the `DefId` of `Drop` trait in lang items
.drop_trait() .drop_trait()