From 28946b3486d507418b8a4acb92d5e2baae193d65 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 9 Jun 2020 15:34:23 -0400 Subject: [PATCH 1/6] Track span of function in method calls, and use this in #[track_caller] Fixes #69977 When we parse a chain of method calls like `foo.a().b().c()`, each `MethodCallExpr` gets assigned a span that starts at the beginning of the call chain (`foo`). While this is useful for diagnostics, it means that `Location::caller` will return the same location for every call in a call chain. This PR makes us separately record the span of the function name and arguments for a method call (e.g. `b()` in `foo.a().b().c()`). This `Span` is passed through HIR lowering and MIR building to `TerminatorKind::Call`, where it is used in preference to `Terminator.source_info.span` when determining `Location::caller`. This new span is also useful for diagnostics where we want to emphasize a particular method call - for an example, see https://github.com/rust-lang/rust/pull/72389#discussion_r436035990 --- src/librustc_ast/ast.rs | 4 ++- src/librustc_ast/mut_visit.rs | 3 +- src/librustc_ast/util/parser.rs | 2 +- src/librustc_ast/visit.rs | 2 +- src/librustc_ast_lowering/expr.rs | 4 +-- src/librustc_ast_pretty/pprust.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 12 +++++-- src/librustc_expand/build.rs | 2 +- src/librustc_hir/hir.rs | 6 ++-- src/librustc_hir/intravisit.rs | 2 +- src/librustc_hir_pretty/lib.rs | 4 +-- .../infer/error_reporting/need_type_info.rs | 4 +-- src/librustc_lint/array_into_iter.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_middle/mir/mod.rs | 1 + src/librustc_middle/mir/type_foldable.rs | 3 +- src/librustc_middle/mir/visit.rs | 1 + src/librustc_mir/borrow_check/invalidation.rs | 1 + src/librustc_mir/borrow_check/mod.rs | 1 + .../dataflow/framework/direction.rs | 2 +- .../dataflow/move_paths/builder.rs | 1 + .../interpret/intrinsics/caller_location.rs | 32 +++++++++++++------ src/librustc_mir/interpret/terminator.rs | 1 + src/librustc_mir/shim.rs | 2 ++ src/librustc_mir/transform/promote_consts.rs | 3 +- .../transform/qualify_min_const_fn.rs | 9 +++++- src/librustc_mir/util/elaborate_drops.rs | 2 ++ src/librustc_mir_build/build/expr/into.rs | 5 ++- src/librustc_mir_build/build/matches/test.rs | 1 + src/librustc_mir_build/hair/cx/expr.rs | 16 +++++++--- src/librustc_mir_build/hair/mod.rs | 1 + src/librustc_parse/parser/expr.rs | 6 ++-- src/librustc_passes/liveness.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_resolve/late.rs | 2 +- src/librustc_save_analysis/dump_visitor.rs | 4 ++- src/librustc_typeck/check/demand.rs | 4 +-- src/librustc_typeck/check/expr.rs | 4 +-- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/expr_use_visitor.rs | 2 +- .../ui/rfc-2091-track-caller/call-chain.rs | 28 ++++++++++++++++ 42 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 src/test/ui/rfc-2091-track-caller/call-chain.rs diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index efcf95ec706..5012fbb30b0 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1165,7 +1165,9 @@ pub enum ExprKind { /// and the remaining elements are the rest of the arguments. /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. - MethodCall(PathSegment, Vec>), + /// The `Span` is the span of the function, without the dot and receiver + /// (e.g. `foo(a, b)` in `x.foo(a, b)` + MethodCall(PathSegment, Vec>, Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(Vec>), /// A binary operation (e.g., `a + b`, `a * b`). diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index 7ececb814a6..f0441c6b885 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -1111,11 +1111,12 @@ pub fn noop_visit_expr( vis.visit_expr(f); visit_exprs(args, vis); } - ExprKind::MethodCall(PathSegment { ident, id, args }, exprs) => { + ExprKind::MethodCall(PathSegment { ident, id, args }, exprs, span) => { vis.visit_ident(ident); vis.visit_id(id); visit_opt(args, |args| vis.visit_generic_args(args)); visit_exprs(exprs, vis); + vis.visit_span(span); } ExprKind::Binary(_binop, lhs, rhs) => { vis.visit_expr(lhs); diff --git a/src/librustc_ast/util/parser.rs b/src/librustc_ast/util/parser.rs index b98cc96b3c6..d8b44a22f2c 100644 --- a/src/librustc_ast/util/parser.rs +++ b/src/librustc_ast/util/parser.rs @@ -394,7 +394,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { contains_exterior_struct_lit(&x) } - ast::ExprKind::MethodCall(.., ref exprs) => { + ast::ExprKind::MethodCall(.., ref exprs, _) => { // X { y: 1 }.bar(...) contains_exterior_struct_lit(&exprs[0]) } diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs index 41c02734442..ccab46703df 100644 --- a/src/librustc_ast/visit.rs +++ b/src/librustc_ast/visit.rs @@ -726,7 +726,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref segment, ref arguments) => { + ExprKind::MethodCall(ref segment, ref arguments, _span) => { visitor.visit_path_segment(expression.span, segment); walk_list!(visitor, visit_expr, arguments); } diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index c9037da377e..af7b851954a 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -39,7 +39,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let f = self.lower_expr(f); hir::ExprKind::Call(f, self.lower_exprs(args)) } - ExprKind::MethodCall(ref seg, ref args) => { + ExprKind::MethodCall(ref seg, ref args, span) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -50,7 +50,7 @@ impl<'hir> LoweringContext<'_, 'hir> { None, )); let args = self.lower_exprs(args); - hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args) + hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args, span) } ExprKind::Binary(binop, ref lhs, ref rhs) => { let binop = self.lower_binop(binop); diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 872126646f3..ca37bd6cf81 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1818,7 +1818,7 @@ impl<'a> State<'a> { ast::ExprKind::Call(ref func, ref args) => { self.print_expr_call(func, &args[..]); } - ast::ExprKind::MethodCall(ref segment, ref args) => { + ast::ExprKind::MethodCall(ref segment, ref args, _) => { self.print_expr_method_call(segment, &args[..]); } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 30a84c4e47b..74d7fc16215 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -530,6 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args: &Vec>, destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, cleanup: Option, + fn_span: Span, ) { let span = terminator.source_info.span; // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar. @@ -634,7 +635,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if intrinsic == Some("caller_location") { if let Some((_, target)) = destination.as_ref() { - let location = self.get_caller_location(&mut bx, span); + let location = self.get_caller_location(&mut bx, fn_span); if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { location.val.store(&mut bx, tmp); @@ -798,7 +799,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args.len() + 1, "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR", ); - let location = self.get_caller_location(&mut bx, span); + let location = self.get_caller_location(&mut bx, fn_span); + debug!( + "codegen_call_terminator({:?}): location={:?} (fn_span {:?})", + terminator, location, fn_span + ); + let last_arg = fn_abi.args.last().unwrap(); self.codegen_argument(&mut bx, location, &mut llargs, last_arg); } @@ -1016,6 +1022,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ref destination, cleanup, from_hir_call: _, + fn_span, } => { self.codegen_call_terminator( helper, @@ -1025,6 +1032,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args, destination, cleanup, + fn_span, ); } mir::TerminatorKind::GeneratorDrop | mir::TerminatorKind::Yield { .. } => { diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 6185e014d3c..20d2ea0a215 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -272,7 +272,7 @@ impl<'a> ExtCtxt<'a> { ) -> P { args.insert(0, expr); let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); - self.expr(span, ast::ExprKind::MethodCall(segment, args)) + self.expr(span, ast::ExprKind::MethodCall(segment, args, span)) } pub fn expr_block(&self, b: P) -> P { self.expr(b.span, ast::ExprKind::Block(b, None)) diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 1e305c6d32d..6b751456618 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1371,7 +1371,7 @@ pub struct Expr<'hir> { // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] -rustc_data_structures::static_assert_size!(Expr<'static>, 64); +rustc_data_structures::static_assert_size!(Expr<'static>, 72); impl Expr<'_> { pub fn precedence(&self) -> ExprPrecedence { @@ -1568,12 +1568,14 @@ pub enum ExprKind<'hir> { /// and the remaining elements are the rest of the arguments. /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. + /// The final `Span` represents the span of the function and arguments + /// (e.g. `foo::(a, b, c, d)` in `x.foo::(a, b, c, d)` /// /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with /// the `hir_id` of the `MethodCall` node itself. /// /// [`type_dependent_def_id`]: ../ty/struct.TypeckTables.html#method.type_dependent_def_id - MethodCall(&'hir PathSegment<'hir>, Span, &'hir [Expr<'hir>]), + MethodCall(&'hir PathSegment<'hir>, Span, &'hir [Expr<'hir>], Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(&'hir [Expr<'hir>]), /// A binary operation (e.g., `a + b`, `a * b`). diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 97601a3e1ac..6bc899622a3 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -1090,7 +1090,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref segment, _, arguments) => { + ExprKind::MethodCall(ref segment, _, arguments, _) => { visitor.visit_path_segment(expression.span, segment); walk_list!(visitor, visit_expr, arguments); } diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index e642915b86a..f30f9944e58 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -1286,7 +1286,7 @@ impl<'a> State<'a> { hir::ExprKind::Call(ref func, ref args) => { self.print_expr_call(&func, args); } - hir::ExprKind::MethodCall(ref segment, _, ref args) => { + hir::ExprKind::MethodCall(ref segment, _, ref args, _) => { self.print_expr_method_call(segment, args); } hir::ExprKind::Binary(op, ref lhs, ref rhs) => { @@ -2469,7 +2469,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool { contains_exterior_struct_lit(&x) } - hir::ExprKind::MethodCall(.., ref exprs) => { + hir::ExprKind::MethodCall(.., ref exprs, _) => { // `X { y: 1 }.bar(...)` contains_exterior_struct_lit(&exprs[0]) } diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/src/librustc_infer/infer/error_reporting/need_type_info.rs index dfc7177921d..c72ea699f90 100644 --- a/src/librustc_infer/infer/error_reporting/need_type_info.rs +++ b/src/librustc_infer/infer/error_reporting/need_type_info.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { - if let ExprKind::MethodCall(_, call_span, exprs) = expr.kind { + if let ExprKind::MethodCall(_, call_span, exprs, _) = expr.kind { if call_span == self.target_span && Some(self.target) == self.infcx.in_progress_tables.and_then(|tables| { @@ -294,7 +294,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // 3 | let _ = x.sum() as f64; // | ^^^ cannot infer type for `S` span - } else if let Some(ExprKind::MethodCall(_, call_span, _)) = + } else if let Some(ExprKind::MethodCall(_, call_span, _, _)) = local_visitor.found_method_call.map(|e| &e.kind) { // Point at the call instead of the whole expression: diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 3eb587c016a..5b282c42034 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -24,7 +24,7 @@ declare_lint_pass!( impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'tcx>) { // We only care about method call expressions. - if let hir::ExprKind::MethodCall(call, span, args) = &expr.kind { + if let hir::ExprKind::MethodCall(call, span, args, _) = &expr.kind { if call.ident.name != sym::into_iter { return; } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e17e8b7b964..aa0dd9c8311 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1899,7 +1899,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { } } } - } else if let hir::ExprKind::MethodCall(_, _, ref args) = expr.kind { + } else if let hir::ExprKind::MethodCall(_, _, ref args, _) = expr.kind { // Find problematic calls to `MaybeUninit::assume_init`. let def_id = cx.tables.type_dependent_def_id(expr.hir_id)?; if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index dea82934313..8196b37391b 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -526,7 +526,7 @@ trait UnusedDelimLint { let (args_to_check, ctx) = match *call_or_other { Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg), // first "argument" is self (which sometimes needs delims) - MethodCall(_, ref args) => (&args[1..], UnusedDelimsCtx::MethodArg), + MethodCall(_, ref args, _) => (&args[1..], UnusedDelimsCtx::MethodArg), // actual catch-all arm _ => { return; diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 98973f1b6fb..6ffed524400 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -1131,6 +1131,7 @@ pub enum TerminatorKind<'tcx> { /// `true` if this is from a call in HIR rather than from an overloaded /// operator. True for overloaded function call. from_hir_call: bool, + fn_span: Span, }, /// Jump to the target if the condition has the expected value, diff --git a/src/librustc_middle/mir/type_foldable.rs b/src/librustc_middle/mir/type_foldable.rs index 97c6d6bf5f4..3f5d528d9e7 100644 --- a/src/librustc_middle/mir/type_foldable.rs +++ b/src/librustc_middle/mir/type_foldable.rs @@ -42,7 +42,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { resume_arg: resume_arg.fold_with(folder), drop, }, - Call { ref func, ref args, ref destination, cleanup, from_hir_call } => { + Call { ref func, ref args, ref destination, cleanup, from_hir_call, fn_span } => { let dest = destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest)); @@ -52,6 +52,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { destination: dest, cleanup, from_hir_call, + fn_span, } } Assert { ref cond, expected, ref msg, target, cleanup } => { diff --git a/src/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs index 9f886cbc9fb..966a709c8a2 100644 --- a/src/librustc_middle/mir/visit.rs +++ b/src/librustc_middle/mir/visit.rs @@ -492,6 +492,7 @@ macro_rules! make_mir_visitor { destination, cleanup: _, from_hir_call: _, + fn_span: _ } => { self.visit_operand(func, source_location); for arg in args { diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index 77d16458383..18a61895070 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -142,6 +142,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { destination, cleanup: _, from_hir_call: _, + fn_span: _, } => { self.consume_operand(location, func); for arg in args { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 736cda83ca5..786424e870f 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -699,6 +699,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc ref destination, cleanup: _, from_hir_call: _, + fn_span: _, } => { self.consume_operand(loc, (func, span), flow_state); for arg in args { diff --git a/src/librustc_mir/dataflow/framework/direction.rs b/src/librustc_mir/dataflow/framework/direction.rs index da4ad9b6168..6c9cb529dc2 100644 --- a/src/librustc_mir/dataflow/framework/direction.rs +++ b/src/librustc_mir/dataflow/framework/direction.rs @@ -467,7 +467,7 @@ impl Direction for Forward { propagate(target, exit_state); } - Call { cleanup, destination, ref func, ref args, from_hir_call: _ } => { + Call { cleanup, destination, ref func, ref args, from_hir_call: _, fn_span: _ } => { if let Some(unwind) = cleanup { if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { propagate(unwind, exit_state); diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index c0ab356756a..4f6ccdafdda 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -401,6 +401,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { ref destination, cleanup: _, from_hir_call: _, + fn_span: _, } => { self.gather_operand(func); for arg in args { diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs index 91b046d7bb2..ddeed92f851 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs @@ -1,6 +1,7 @@ use std::convert::TryFrom; use rustc_hir::lang_items::PanicLocationLangItem; +use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::subst::Subst; use rustc_span::{Span, Symbol}; use rustc_target::abi::LayoutOf; @@ -14,19 +15,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a /// frame which is not `#[track_caller]`. crate fn find_closest_untracked_caller_location(&self) -> Span { - self.stack() + let frame = self + .stack() .iter() .rev() // Find first non-`#[track_caller]` frame. - .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx)) + .find(|frame| { + debug!( + "find_closest_untracked_caller_location: checking frame {:?}", + frame.instance + ); + !frame.instance.def.requires_caller_location(*self.tcx) + }) // Assert that there is always such a frame. - .unwrap() - .current_source_info() - // Assert that the frame we look at is actually executing code currently - // (`current_source_info` is None when we are unwinding and the frame does - // not require cleanup). - .unwrap() - .span + .unwrap(); + let loc = frame.loc.unwrap(); + let block = &frame.body.basic_blocks()[loc.block]; + assert_eq!(block.statements.len(), loc.statement_index); + debug!( + "find_closest_untracked_caller_location:: got terminator {:?} ({:?})", + block.terminator(), + block.terminator().kind + ); + if let TerminatorKind::Call { fn_span, .. } = block.terminator().kind { + return fn_span; + } + unreachable!(); } /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 4a63884be4c..cd7621ea975 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -56,6 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { destination, ref cleanup, from_hir_call: _from_hir_call, + fn_span: _, } => { let old_stack = self.frame_idx(); let old_loc = self.frame().loc; diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index b439e919050..f95fd9b9e90 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -460,6 +460,7 @@ impl CloneShimBuilder<'tcx> { destination: Some((dest, next)), cleanup: Some(cleanup), from_hir_call: true, + fn_span: self.span, }, false, ); @@ -788,6 +789,7 @@ fn build_call_shim<'tcx>( None }, from_hir_call: true, + fn_span: span, }, false, ); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 2c8ad00fd06..e1311ccd374 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -909,7 +909,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { }; match terminator.kind { - TerminatorKind::Call { mut func, mut args, from_hir_call, .. } => { + TerminatorKind::Call { mut func, mut args, from_hir_call, fn_span, .. } => { self.visit_operand(&mut func, loc); for arg in &mut args { self.visit_operand(arg, loc); @@ -925,6 +925,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { cleanup: None, destination: Some((Place::from(new_temp), new_target)), from_hir_call, + fn_span, }, ..terminator }; diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 5c78307d882..4c8fc49099b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -368,7 +368,14 @@ fn check_terminator( Err((span, "const fn generators are unstable".into())) } - TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => { + TerminatorKind::Call { + func, + args, + from_hir_call: _, + destination: _, + cleanup: _, + fn_span: _, + } => { let fn_ty = func.ty(body, tcx); if let ty::FnDef(def_id, _) = fn_ty.kind { if !crate::const_eval::is_min_const_fn(tcx, def_id) { diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 8f27247bfb4..a1345452ca9 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -644,6 +644,7 @@ where destination: Some((unit_temp, succ)), cleanup: unwind.into_option(), from_hir_call: true, + fn_span: self.source_info.span, }, source_info: self.source_info, }), @@ -988,6 +989,7 @@ where destination: Some((unit_temp, target)), cleanup: None, from_hir_call: false, + fn_span: self.source_info.span, }; // FIXME(#43234) let free_block = self.new_block(unwind, call); diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index e402b2d1596..76096fc2299 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -162,7 +162,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }); exit_block.unit() } - ExprKind::Call { ty, fun, args, from_hir_call } => { + ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => { let intrinsic = match ty.kind { ty::FnDef(def_id, _) => { let f = ty.fn_sig(this.hir.tcx()); @@ -206,6 +206,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.record_operands_moved(&args); + debug!("into_expr: fn_span={:?}", fn_span); + this.cfg.terminate( block, source_info, @@ -222,6 +224,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some((destination, success)) }, from_hir_call, + fn_span }, ); success.unit() diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index 74398ca8a40..3e7bfc7d59b 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -443,6 +443,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: Some((eq_result, eq_block)), cleanup: Some(cleanup), from_hir_call: false, + fn_span: source_info.span }, ); diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index d0b35f32122..971a89796e2 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -139,11 +139,11 @@ fn make_mirror_unadjusted<'a, 'tcx>( let kind = match expr.kind { // Here comes the interesting stuff: - hir::ExprKind::MethodCall(_, method_span, ref args) => { + hir::ExprKind::MethodCall(_, method_span, ref args, fn_span) => { // Rewrite a.b(c) into UFCS form like Trait::b(a, c) let expr = method_callee(cx, expr, method_span, None); let args = args.iter().map(|e| e.to_ref()).collect(); - ExprKind::Call { ty: expr.ty, fun: expr.to_ref(), args, from_hir_call: true } + ExprKind::Call { ty: expr.ty, fun: expr.to_ref(), args, from_hir_call: true, fn_span } } hir::ExprKind::Call(ref fun, ref args) => { @@ -170,6 +170,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( fun: method.to_ref(), args: vec![fun.to_ref(), tupled_args.to_ref()], from_hir_call: true, + fn_span: expr.span, } } else { let adt_data = @@ -215,6 +216,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( fun: fun.to_ref(), args: args.to_ref(), from_hir_call: true, + fn_span: expr.span, } } } @@ -1024,7 +1026,7 @@ fn overloaded_operator<'a, 'tcx>( args: Vec>, ) -> ExprKind<'tcx> { let fun = method_callee(cx, expr, expr.span, None); - ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), args, from_hir_call: false } + ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), args, from_hir_call: false, fn_span: expr.span } } fn overloaded_place<'a, 'tcx>( @@ -1060,7 +1062,13 @@ fn overloaded_place<'a, 'tcx>( temp_lifetime, ty: ref_ty, span: expr.span, - kind: ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), args, from_hir_call: false }, + kind: ExprKind::Call { + ty: fun.ty, + fun: fun.to_ref(), + args, + from_hir_call: false, + fn_span: expr.span, + }, }; // construct and return a deref wrapper `*foo()` diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs index c869699bb20..140b8bbe15e 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -146,6 +146,7 @@ crate enum ExprKind<'tcx> { // Whether this is from a call in HIR, rather than from an overloaded // operator. True for overloaded function call. from_hir_call: bool, + fn_span: Span, }, Deref { arg: ExprRef<'tcx>, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index e0c37284839..49a5c880176 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -639,7 +639,7 @@ impl<'a> Parser<'a> { ExprKind::Index(_, _) => "indexing", ExprKind::Try(_) => "?", ExprKind::Field(_, _) => "a field access", - ExprKind::MethodCall(_, _) => "a method call", + ExprKind::MethodCall(_, _, _) => "a method call", ExprKind::Call(_, _) => "a function call", ExprKind::Await(_) => "`.await`", ExprKind::Err => return Ok(with_postfix), @@ -865,6 +865,7 @@ impl<'a> Parser<'a> { return self.mk_await_expr(self_arg, lo); } + let fn_span_lo = self.token.span; let segment = self.parse_path_segment(PathStyle::Expr)?; self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren)); @@ -873,8 +874,9 @@ impl<'a> Parser<'a> { let mut args = self.parse_paren_expr_seq()?; args.insert(0, self_arg); + let fn_span = fn_span_lo.to(self.prev_token.span); let span = lo.to(self.prev_token.span); - Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args), AttrVec::new())) + Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span), AttrVec::new())) } else { // Field access `expr.f` if let Some(args) = segment.args { diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 55978afc594..ff5dabd5418 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -1198,7 +1198,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&f, succ) } - hir::ExprKind::MethodCall(.., ref args) => { + hir::ExprKind::MethodCall(.., ref args, _) => { let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id(); let succ = if self.ir.tcx.is_ty_uninhabited_from( m, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index cb896810951..d54ec2eca8c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1302,7 +1302,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { return; } } - hir::ExprKind::MethodCall(_, span, _) => { + hir::ExprKind::MethodCall(_, span, _, _) => { // Method calls have to be checked specially. self.span = span; if let Some(def_id) = self.tables.type_dependent_def_id(expr.hir_id) { diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 49177906647..7166fef2d13 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -2117,7 +2117,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Field(ref subexpression, _) => { self.resolve_expr(subexpression, Some(expr)); } - ExprKind::MethodCall(ref segment, ref arguments) => { + ExprKind::MethodCall(ref segment, ref arguments, _) => { let mut arguments = arguments.iter(); self.resolve_expr(arguments.next().unwrap(), Some(expr)); for argument in arguments { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 489d38b00df..39cb39ba619 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1375,7 +1375,9 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> { let res = self.save_ctxt.get_path_res(hir_expr.hir_id); self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), *base) } - hir::ExprKind::MethodCall(ref seg, _, args) => self.process_method_call(ex, seg, args), + hir::ExprKind::MethodCall(ref seg, _, args, _) => { + self.process_method_call(ex, seg, args) + } hir::ExprKind::Field(ref sub_ex, _) => { self.visit_expr(&sub_ex); diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 700b9359d06..c097787e472 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -305,7 +305,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (method_path, method_span, method_expr) = match (hir, closure_params_len) { ( Some(Node::Expr(hir::Expr { - kind: hir::ExprKind::MethodCall(path, span, expr), + kind: hir::ExprKind::MethodCall(path, span, expr, _), .. })), 1, @@ -455,7 +455,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if self.can_coerce(ref_ty, expected) { let mut sugg_sp = sp; - if let hir::ExprKind::MethodCall(ref segment, sp, ref args) = expr.kind { + if let hir::ExprKind::MethodCall(ref segment, sp, ref args, _) = expr.kind { let clone_trait = self.tcx.require_lang_item(CloneTraitLangItem, Some(sp)); if let ([arg], Some(true), sym::clone) = ( &args[..], diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 266e9b21d69..c6a9a37e440 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -182,7 +182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Call(ref callee, _) => { self.warn_if_unreachable(expr.hir_id, callee.span, "call") } - ExprKind::MethodCall(_, ref span, _) => { + ExprKind::MethodCall(_, ref span, _, _) => { self.warn_if_unreachable(expr.hir_id, *span, "call") } _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"), @@ -262,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ExprKind::Block(ref body, _) => self.check_block_with_expected(&body, expected), ExprKind::Call(ref callee, ref args) => self.check_call(expr, &callee, args, expected), - ExprKind::MethodCall(ref segment, span, ref args) => { + ExprKind::MethodCall(ref segment, span, ref args, _) => { self.check_method_call(expr, segment, span, args, expected, needs) } ExprKind::Cast(ref e, ref t) => self.check_expr_cast(e, t, expr), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f2aeed4f1e4..b2aeed09469 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3912,7 +3912,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_unit: bool| { let (span, start_span, args) = match &expr.kind { hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]), - hir::ExprKind::MethodCall(path_segment, span, args) => ( + hir::ExprKind::MethodCall(path_segment, span, args, _) => ( *span, // `sp` doesn't point at the whole `foo.bar()`, only at `bar`. path_segment diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index 53973eba229..6baadb8febd 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -185,7 +185,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.consume_exprs(args); } - hir::ExprKind::MethodCall(.., ref args) => { + hir::ExprKind::MethodCall(.., ref args, _) => { // callee.m(args) self.consume_exprs(args); } diff --git a/src/test/ui/rfc-2091-track-caller/call-chain.rs b/src/test/ui/rfc-2091-track-caller/call-chain.rs new file mode 100644 index 00000000000..3f1c8f7abe8 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/call-chain.rs @@ -0,0 +1,28 @@ +// run-pass + +#![feature(track_caller)] + +use std::panic::Location; + +struct Foo; + +impl Foo { + #[track_caller] + fn check_loc(&self, line: u32, col: u32) -> &Self { + let loc = Location::caller(); + assert_eq!(loc.file(), file!(), "file mismatch"); + assert_eq!(loc.line(), line, "line mismatch"); + assert_eq!(loc.column(), col, "column mismatch"); + self + } +} + +fn main() { + // Tests that when `Location::caller` is used in a method chain, + // it points to the start of the correct call (the first character after the dot) + // instead of to the very first expression in the chain + let foo = Foo; + foo. + check_loc(line!(), 9).check_loc(line!(), 31) + .check_loc(line!(), 10); +} From 6e4d0b4205dbffa76258527aba9ea2e55492e66e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 9 Jun 2020 17:44:04 -0400 Subject: [PATCH 2/6] Update Clippy for MethodCall changes --- .../clippy_lints/src/atomic_ordering.rs | 2 +- src/tools/clippy/clippy_lints/src/booleans.rs | 2 +- .../clippy/clippy_lints/src/bytecount.rs | 6 ++--- .../clippy/clippy_lints/src/dereference.rs | 2 +- .../clippy/clippy_lints/src/double_parens.rs | 2 +- .../clippy_lints/src/duration_subsec.rs | 2 +- src/tools/clippy/clippy_lints/src/entry.rs | 4 ++-- .../clippy/clippy_lints/src/eta_reduction.rs | 4 ++-- .../clippy/clippy_lints/src/explicit_write.rs | 4 ++-- .../src/floating_point_arithmetic.rs | 4 ++-- src/tools/clippy/clippy_lints/src/format.rs | 2 +- .../clippy/clippy_lints/src/functions.rs | 4 ++-- .../clippy_lints/src/get_last_with_len.rs | 4 ++-- .../clippy/clippy_lints/src/if_let_mutex.rs | 2 +- .../clippy_lints/src/if_let_some_result.rs | 2 +- .../clippy/clippy_lints/src/infinite_iter.rs | 4 ++-- src/tools/clippy/clippy_lints/src/len_zero.rs | 2 +- src/tools/clippy/clippy_lints/src/loops.rs | 22 +++++++++---------- .../clippy/clippy_lints/src/map_clone.rs | 4 ++-- .../clippy/clippy_lints/src/map_unit_fn.rs | 2 +- .../clippy/clippy_lints/src/methods/mod.rs | 16 +++++++------- src/tools/clippy/clippy_lints/src/misc.rs | 4 ++-- .../clippy/clippy_lints/src/mut_reference.rs | 2 +- .../clippy/clippy_lints/src/open_options.rs | 4 ++-- .../clippy_lints/src/option_env_unwrap.rs | 2 +- .../src/path_buf_push_overwrite.rs | 2 +- .../clippy/clippy_lints/src/precedence.rs | 2 +- .../clippy_lints/src/ptr_offset_with_cast.rs | 2 +- .../clippy/clippy_lints/src/question_mark.rs | 2 +- src/tools/clippy/clippy_lints/src/ranges.rs | 6 ++--- .../src/redundant_pattern_matching.rs | 2 +- .../src/slow_vector_initialization.rs | 6 ++--- src/tools/clippy/clippy_lints/src/strings.rs | 2 +- .../clippy_lints/src/to_digit_is_some.rs | 4 ++-- src/tools/clippy/clippy_lints/src/types.rs | 6 ++--- .../clippy_lints/src/unused_io_amount.rs | 4 ++-- src/tools/clippy/clippy_lints/src/unwrap.rs | 4 ++-- .../clippy_lints/src/useless_conversion.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 4 ++-- .../clippy_lints/src/utils/hir_utils.rs | 4 ++-- .../clippy_lints/src/utils/inspector.rs | 2 +- .../clippy_lints/src/utils/internal_lints.rs | 4 ++-- .../clippy/clippy_lints/src/utils/mod.rs | 6 ++--- .../clippy/clippy_lints/src/utils/ptr.rs | 2 +- .../clippy_lints/src/verbose_file_reads.rs | 4 ++-- 45 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/atomic_ordering.rs b/src/tools/clippy/clippy_lints/src/atomic_ordering.rs index 73b4cef4725..fca9aaaff9d 100644 --- a/src/tools/clippy/clippy_lints/src/atomic_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/atomic_ordering.rs @@ -70,7 +70,7 @@ fn match_ordering_def_path(cx: &LateContext<'_, '_>, did: DefId, orderings: &[&s fn check_atomic_load_store(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { - if let ExprKind::MethodCall(ref method_path, _, args) = &expr.kind; + if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind; let method = method_path.ident.name.as_str(); if type_is_atomic(cx, &args[0]); if method == "load" || method == "store"; diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index 8031052e073..f92c564543b 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -247,7 +247,7 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { )) }) }, - 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]); if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type)) && !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type)) diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs index 90c00ad098f..531531a654d 100644 --- a/src/tools/clippy/clippy_lints/src/bytecount.rs +++ b/src/tools/clippy/clippy_lints/src/bytecount.rs @@ -38,10 +38,10 @@ declare_lint_pass!(ByteCount => [NAIVE_BYTECOUNT]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { - if let ExprKind::MethodCall(ref count, _, ref count_args) = expr.kind; + if let ExprKind::MethodCall(ref count, _, ref count_args, _) = expr.kind; if count.ident.name == sym!(count); if count_args.len() == 1; - if let ExprKind::MethodCall(ref filter, _, ref filter_args) = count_args[0].kind; + if let ExprKind::MethodCall(ref filter, _, ref filter_args, _) = count_args[0].kind; if filter.ident.name == sym!(filter); if filter_args.len() == 2; if let ExprKind::Closure(_, _, body_id, _, _) = filter_args[1].kind; @@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount { if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).kind { return; } - let haystack = if let ExprKind::MethodCall(ref path, _, ref args) = + let haystack = if let ExprKind::MethodCall(ref path, _, ref args, _) = filter_args[0].kind { let p = path.ident.name; if (p == sym!(iter) || p == sym!(iter_mut)) && args.len() == 1 { diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 68ec07e2bcb..1cd30ae2c63 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { if !expr.span.from_expansion(); - if let ExprKind::MethodCall(ref method_name, _, ref args) = &expr.kind; + if let ExprKind::MethodCall(ref method_name, _, ref args, _) = &expr.kind; if args.len() == 1; then { diff --git a/src/tools/clippy/clippy_lints/src/double_parens.rs b/src/tools/clippy/clippy_lints/src/double_parens.rs index 05517f6f9f0..1eb380a22cc 100644 --- a/src/tools/clippy/clippy_lints/src/double_parens.rs +++ b/src/tools/clippy/clippy_lints/src/double_parens.rs @@ -70,7 +70,7 @@ impl EarlyLintPass for DoubleParens { } } }, - ExprKind::MethodCall(_, ref params) => { + ExprKind::MethodCall(_, ref params, _) => { if params.len() == 2 { let param = ¶ms[1]; if let ExprKind::Paren(_) = param.kind { diff --git a/src/tools/clippy/clippy_lints/src/duration_subsec.rs b/src/tools/clippy/clippy_lints/src/duration_subsec.rs index afefa250638..7171dcef968 100644 --- a/src/tools/clippy/clippy_lints/src/duration_subsec.rs +++ b/src/tools/clippy/clippy_lints/src/duration_subsec.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { 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 let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right); then { diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs index 7b332c761a0..f625058b670 100644 --- a/src/tools/clippy/clippy_lints/src/entry.rs +++ b/src/tools/clippy/clippy_lints/src/entry.rs @@ -103,7 +103,7 @@ fn check_cond<'a, 'tcx, 'b>( check: &'b Expr<'b>, ) -> Option<(&'static str, &'b Expr<'b>, &'b Expr<'b>)> { if_chain! { - if let ExprKind::MethodCall(ref path, _, ref params) = check.kind; + if let ExprKind::MethodCall(ref path, _, ref params, _) = check.kind; if params.len() >= 2; if path.ident.name == sym!(contains_key); if let ExprKind::AddrOf(BorrowKind::Ref, _, ref key) = params[1].kind; @@ -140,7 +140,7 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> { fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { if_chain! { - if let ExprKind::MethodCall(ref path, _, ref params) = expr.kind; + if let ExprKind::MethodCall(ref path, _, ref params, _) = expr.kind; if params.len() == 3; if path.ident.name == sym!(insert); if get_item_name(self.cx, self.map) == get_item_name(self.cx, ¶ms[0]); diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index d093025fd3d..a889856de27 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -71,7 +71,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaReduction { } match expr.kind { - ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args) => { + ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) => { for arg in args { check_closure(cx, arg) } @@ -120,7 +120,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { ); if_chain!( - if let ExprKind::MethodCall(ref path, _, ref args) = ex.kind; + if let ExprKind::MethodCall(ref path, _, ref args, _) = ex.kind; // Not the same number of arguments, there is no way the closure is the same as the function return; if args.len() == decl.inputs.len(); diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs index 320121b2771..7269e2b52c2 100644 --- a/src/tools/clippy/clippy_lints/src/explicit_write.rs +++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs @@ -32,11 +32,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitWrite { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { // match call to unwrap - if let ExprKind::MethodCall(ref unwrap_fun, _, ref unwrap_args) = expr.kind; + if let ExprKind::MethodCall(ref unwrap_fun, _, ref unwrap_args, _) = expr.kind; if unwrap_fun.ident.name == sym!(unwrap); // match call to write_fmt if !unwrap_args.is_empty(); - if let ExprKind::MethodCall(ref write_fun, _, write_args) = + if let ExprKind::MethodCall(ref write_fun, _, write_args, _) = unwrap_args[0].kind; if write_fun.ident.name == sym!(write_fmt); // match calls to std::io::stdout() / std::io::stderr () diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs index 3a912d92837..ad4f66c52c2 100644 --- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs @@ -301,7 +301,7 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if cx.tables.expr_ty(lhs).is_floating_point(); if let Some((value, _)) = constant(cx, cx.tables, rhs); 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 path.ident.name.as_str() == "exp"; then { @@ -481,7 +481,7 @@ fn check_custom_abs(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic { 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]); if recv_ty.is_floating_point() { diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs index 1530538aa7d..4cae5ca2c43 100644 --- a/src/tools/clippy/clippy_lints/src/format.rs +++ b/src/tools/clippy/clippy_lints/src/format.rs @@ -104,7 +104,7 @@ fn on_argumentv1_new<'a, 'tcx>( } } else { let snip = snippet(cx, format_args.span, ""); - if let ExprKind::MethodCall(ref path, _, _) = format_args.kind { + if let ExprKind::MethodCall(ref path, _, _, _) = format_args.kind { if path.ident.name == sym!(to_string) { return Some(format!("{}", snip)); } diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs index 325b6cf32a3..991d129e8f0 100644 --- a/src/tools/clippy/clippy_lints/src/functions.rs +++ b/src/tools/clippy/clippy_lints/src/functions.rs @@ -556,7 +556,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> { } } }, - hir::ExprKind::MethodCall(_, _, args) => { + hir::ExprKind::MethodCall(_, _, args, _) => { let def_id = self.tables.type_dependent_def_id(expr.hir_id).unwrap(); let base_type = self.cx.tcx.type_of(def_id); @@ -610,7 +610,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> { return; } match expr.kind { - Call(_, args) | MethodCall(_, _, args) => { + Call(_, args) | MethodCall(_, _, args, _) => { let mut tys = FxHashSet::default(); for arg in args { let def_id = arg.hir_id.owner.to_def_id(); diff --git a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs index c32e0a2290d..3629ba623ce 100644 --- a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs +++ b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs @@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for GetLastWithLen { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { // Is a method call - if let ExprKind::MethodCall(ref path, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; // Method name is "get" if path.ident.name == sym!(get); @@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for GetLastWithLen { ) = &get_index_arg.kind; // LHS of subtraction is "x.len()" - if let ExprKind::MethodCall(arg_lhs_path, _, lhs_args) = &lhs.kind; + if let ExprKind::MethodCall(arg_lhs_path, _, lhs_args, _) = &lhs.kind; if arg_lhs_path.ident.name == sym!(len); if let Some(arg_lhs_struct) = lhs_args.get(0); diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs index ae92a96d163..04d17c91d63 100644 --- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs +++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs @@ -147,7 +147,7 @@ impl<'tcx, 'l> ArmVisitor<'tcx, 'l> { fn is_mutex_lock_call<'a>(cx: &LateContext<'a, '_>, expr: &'a Expr<'_>) -> Option<&'a Expr<'a>> { 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"; let ty = cx.tables.expr_ty(&args[0]); if is_type_diagnostic_item(cx, ty, sym!(mutex_type)); diff --git a/src/tools/clippy/clippy_lints/src/if_let_some_result.rs b/src/tools/clippy/clippy_lints/src/if_let_some_result.rs index 9b13f760924..6a1fcdd1ce4 100644 --- a/src/tools/clippy/clippy_lints/src/if_let_some_result.rs +++ b/src/tools/clippy/clippy_lints/src/if_let_some_result.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet { if_chain! { //begin checking variables if let ExprKind::Match(ref op, ref body, source) = expr.kind; //test if expr is a match if let MatchSource::IfLetDesugar { .. } = source; //test if it is an If Let - if let ExprKind::MethodCall(_, ok_span, ref result_types) = op.kind; //check is expr.ok() has type Result.ok() + if let ExprKind::MethodCall(_, ok_span, ref result_types, _) = op.kind; //check is expr.ok() has type Result.ok(, _) 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 is_type_diagnostic_item(cx, cx.tables.expr_ty(&result_types[0]), sym!(result_type)); diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index cd989c0ea6f..a860a9def24 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -142,7 +142,7 @@ const HEURISTICS: [(&str, usize, Heuristic, Finiteness); 19] = [ fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { - ExprKind::MethodCall(ref method, _, ref args) => { + ExprKind::MethodCall(ref method, _, ref args, _) => { for &(name, len, heuristic, cap) in &HEURISTICS { if method.ident.name.as_str() == name && args.len() == len { return (match heuristic { @@ -218,7 +218,7 @@ const INFINITE_COLLECTORS: [&[&str]; 8] = [ fn complete_infinite_iter(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { - ExprKind::MethodCall(ref method, _, ref args) => { + ExprKind::MethodCall(ref method, _, ref args, _) => { for &(name, len) in &COMPLETING_METHODS { if method.ident.name.as_str() == name && args.len() == len { return is_infinite(cx, &args[0]); diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index f5bfede75a7..13e85fda8ff 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -211,7 +211,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item<'_>, impl_items: &[Imp } fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) { - if let (&ExprKind::MethodCall(ref method_path, _, ref args), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) { + if let (&ExprKind::MethodCall(ref method_path, _, ref args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) { // check if we are in an is_empty() method if let Some(name) = get_item_name(cx, method) { if name.as_str() == "is_empty" { diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index 57c62d73964..771bc8d0558 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -526,7 +526,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { let pat = &arms[0].pat.kind; if let ( &PatKind::TupleStruct(ref qpath, ref pat_args, _), - &ExprKind::MethodCall(ref method_path, _, ref method_args), + &ExprKind::MethodCall(ref method_path, _, ref method_args, _), ) = (pat, &match_expr.kind) { let iter_expr = &method_args[0]; @@ -654,7 +654,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { | ExprKind::Struct(_, _, Some(ref e)) | ExprKind::Repeat(ref e, _) | ExprKind::DropTemps(ref e) => never_loop_expr(e, main_loop_id), - ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es) | ExprKind::Tup(ref es) => { + ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es, _) | ExprKind::Tup(ref es) => { never_loop_expr_all(&mut es.iter(), main_loop_id) }, ExprKind::Call(ref e, ref es) => never_loop_expr_all(&mut once(&**e).chain(es.iter()), main_loop_id), @@ -806,7 +806,7 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool { fn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { if_chain! { - if let ExprKind::MethodCall(method, _, args) = expr.kind; + if let ExprKind::MethodCall(method, _, args, _) = expr.kind; if method.ident.name == sym!(clone); if args.len() == 1; if let Some(arg) = args.get(0); @@ -915,7 +915,7 @@ fn build_manual_memcpy_suggestion<'a, 'tcx>( let print_limit = |end: &Expr<'_>, offset: Offset, var: &Expr<'_>| { if_chain! { - if let ExprKind::MethodCall(method, _, len_args) = end.kind; + if let ExprKind::MethodCall(method, _, len_args, _) = end.kind; if method.ident.name == sym!(len); if len_args.len() == 1; if let Some(arg) = len_args.get(0); @@ -1190,7 +1190,7 @@ fn check_for_loop_range<'a, 'tcx>( fn is_len_call(expr: &Expr<'_>, var: Name) -> bool { if_chain! { - if let ExprKind::MethodCall(ref method, _, ref len_args) = expr.kind; + if let ExprKind::MethodCall(ref method, _, ref len_args, _) = expr.kind; if len_args.len() == 1; if method.ident.name == sym!(len); if let ExprKind::Path(QPath::Resolved(_, ref path)) = len_args[0].kind; @@ -1244,7 +1244,7 @@ fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr<'_>], arg: &Expr<'_>, fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) { let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used - if let ExprKind::MethodCall(ref method, _, ref args) = arg.kind { + if let ExprKind::MethodCall(ref method, _, ref args, _) = arg.kind { // just the receiver, no arguments if args.len() == 1 { let method_name = &*method.ident.as_str(); @@ -1718,7 +1718,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { if_chain! { // a range index op - if let ExprKind::MethodCall(ref meth, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref meth, _, ref args, _) = expr.kind; if (meth.ident.name == sym!(index) && match_trait_method(self.cx, expr, &paths::INDEX)) || (meth.ident.name == sym!(index_mut) && match_trait_method(self.cx, expr, &paths::INDEX_MUT)); if !self.check(&args[1], &args[0], expr); @@ -1776,7 +1776,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { self.visit_expr(expr); } }, - ExprKind::MethodCall(_, _, args) => { + ExprKind::MethodCall(_, _, args, _) => { 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) { self.prefer_mutable = false; @@ -2369,8 +2369,8 @@ const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, 'tcx>) { if_chain! { - if let ExprKind::MethodCall(ref method, _, ref args) = expr.kind; - if let ExprKind::MethodCall(ref chain_method, _, _) = args[0].kind; + if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind; + if let ExprKind::MethodCall(ref chain_method, _, _, _) = args[0].kind; if chain_method.ident.name == sym!(collect) && match_trait_method(cx, &args[0], &paths::ITERATOR); if let Some(ref generic_args) = chain_method.args; if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0); @@ -2437,7 +2437,7 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'a, ' fn shorten_span(expr: &Expr<'_>, target_fn_name: Symbol) -> Span { let mut current_expr = expr; - while let ExprKind::MethodCall(ref path, ref span, ref args) = current_expr.kind { + while let ExprKind::MethodCall(ref path, ref span, ref args, _) = current_expr.kind { if path.ident.name == target_fn_name { return expr.span.with_lo(span.lo()); } diff --git a/src/tools/clippy/clippy_lints/src/map_clone.rs b/src/tools/clippy/clippy_lints/src/map_clone.rs index d5adf6b0f0d..8f4fdc685ef 100644 --- a/src/tools/clippy/clippy_lints/src/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/map_clone.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { } if_chain! { - 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 method.ident.as_str() == "map"; let ty = cx.tables.expr_ty(&args[0]); @@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone { } } }, - hir::ExprKind::MethodCall(ref method, _, ref obj) => { + hir::ExprKind::MethodCall(ref method, _, ref obj, _) => { if ident_eq(name, &obj[0]) && method.ident.as_str() == "clone" && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) { diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs index fecd91c7814..8f4b674c04f 100644 --- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs +++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs @@ -125,7 +125,7 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr<'_>) } match expr.kind { - hir::ExprKind::Call(_, _) | hir::ExprKind::MethodCall(_, _, _) => { + hir::ExprKind::Call(_, _) | hir::ExprKind::MethodCall(_, _, _, _) => { // Calls can't be reduced any more Some(expr.span) }, diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 214cf0c130f..f25a9782813 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -1429,7 +1429,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { } match expr.kind { - hir::ExprKind::MethodCall(ref method_call, ref method_span, ref args) => { + hir::ExprKind::MethodCall(ref method_call, ref method_span, ref 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); @@ -1677,7 +1677,7 @@ fn lint_or_fun_call<'a, 'tcx>( or_has_args: bool, span: Span, ) { - 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" { let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); @@ -1751,7 +1751,7 @@ fn lint_or_fun_call<'a, 'tcx>( ); } }, - hir::ExprKind::MethodCall(_, span, ref or_args) => check_general_case( + hir::ExprKind::MethodCall(_, span, ref or_args, _) => check_general_case( cx, name, method_span, @@ -1782,7 +1782,7 @@ fn lint_expect_fun_call( loop { arg_root = match &arg_root.kind { hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr, - hir::ExprKind::MethodCall(method_name, _, call_args) => { + hir::ExprKind::MethodCall(method_name, _, call_args, _) => { if call_args.len() == 1 && (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref)) && { @@ -2002,7 +2002,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &hir: // &*x is a nop, &x.clone() is not hir::ExprKind::AddrOf(..) => return, // (*x).func() is useless, x.clone().func() can work in case func borrows mutably - hir::ExprKind::MethodCall(_, _, parent_args) if expr.hir_id == parent_args[0].hir_id => return, + hir::ExprKind::MethodCall(_, _, parent_args, _) if expr.hir_id == parent_args[0].hir_id => return, _ => {}, }, @@ -2478,7 +2478,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])) { Some(&args[0]) } else { @@ -3182,7 +3182,7 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, call_name: &str, a // allow the `as_ref` or `as_mut` if it is followed by another method call if_chain! { if let Some(parent) = get_parent_expr(cx, expr); - if let hir::ExprKind::MethodCall(_, ref span, _) = parent.kind; + if let hir::ExprKind::MethodCall(_, ref span, _, _) = parent.kind; if span != &expr.span; then { return; @@ -3310,7 +3310,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( let closure_expr = remove_blocks(&closure_body.value); match &closure_expr.kind { - hir::ExprKind::MethodCall(_, _, args) => { + hir::ExprKind::MethodCall(_, _, args, _) => { if_chain! { if args.len() == 1; if let hir::ExprKind::Path(qpath) = &args[0].kind; diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index f513161bbbc..a0947608e60 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -545,7 +545,7 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { } if_chain! { - if let ExprKind::MethodCall(ref method_name, _, ref expressions) = expr.kind; + if let ExprKind::MethodCall(ref method_name, _, ref expressions, _) = expr.kind; if sym!(signum) == method_name.ident.name; // Check that the receiver of the signum() is a float (expressions[0] is the receiver of // the method call) @@ -572,7 +572,7 @@ fn is_array(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool { fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr<'_>, other: &Expr<'_>) { 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) { (cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, "..")) } else { diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 58a8e1a1064..7fcf15f8acb 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { ); } }, - 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 substs = cx.tables.node_substs(e.hir_id); let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); diff --git a/src/tools/clippy/clippy_lints/src/open_options.rs b/src/tools/clippy/clippy_lints/src/open_options.rs index 9d3b67988db..2d4629b683f 100644 --- a/src/tools/clippy/clippy_lints/src/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/open_options.rs @@ -29,7 +29,7 @@ declare_lint_pass!(OpenOptions => [NONSENSICAL_OPEN_OPTIONS]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions { 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])); if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { let mut options = Vec::new(); @@ -57,7 +57,7 @@ enum OpenOption { } 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])); // Only proceed if this is a call on some object of type std::fs::OpenOptions diff --git a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs index 66dfa20edb5..fd653044a1b 100644 --- a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs @@ -35,7 +35,7 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]); impl EarlyLintPass for OptionEnvUnwrap { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if_chain! { - if let ExprKind::MethodCall(path_segment, args) = &expr.kind; + if let ExprKind::MethodCall(path_segment, args, _) = &expr.kind; let method_name = path_segment.ident.as_str(); if method_name == "expect" || method_name == "unwrap"; if let ExprKind::Call(caller, _) = &args[0].kind; diff --git a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs index bdbaf2695c8..88ad1e0914f 100644 --- a/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/path_buf_push_overwrite.rs @@ -43,7 +43,7 @@ declare_lint_pass!(PathBufPushOverwrite => [PATH_BUF_PUSH_OVERWRITE]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathBufPushOverwrite { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { if_chain! { - 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 args.len() == 2; if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::PATH_BUF); diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs index cc783baa687..7dce23dd223 100644 --- a/src/tools/clippy/clippy_lints/src/precedence.rs +++ b/src/tools/clippy/clippy_lints/src/precedence.rs @@ -103,7 +103,7 @@ impl EarlyLintPass for Precedence { } if let ExprKind::Unary(UnOp::Neg, ref rhs) = expr.kind { - if let ExprKind::MethodCall(ref path_segment, ref args) = rhs.kind { + if let ExprKind::MethodCall(ref path_segment, ref args, _) = rhs.kind { let path_segment_str = path_segment.ident.name.as_str(); if let Some(slf) = args.first() { if let ExprKind::Lit(ref lit) = slf.kind { diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs index ffc59d43750..d23d7e59b73 100644 --- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs +++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs @@ -90,7 +90,7 @@ fn expr_as_ptr_offset_call<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, Method)> { - if let ExprKind::MethodCall(ref path_segment, _, ref args) = expr.kind { + if let ExprKind::MethodCall(ref path_segment, _, ref args, _) = expr.kind { if is_expr_ty_raw_ptr(cx, &args[0]) { if path_segment.ident.name == sym!(offset) { return Some((&args[0], &args[1], Method::Offset)); diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index e4361b00fb4..3591972fe08 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -50,7 +50,7 @@ impl QuestionMark { fn check_is_none_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { if_chain! { if let Some((if_expr, body, else_)) = higher::if_block(&expr); - if let ExprKind::MethodCall(segment, _, args) = &if_expr.kind; + if let ExprKind::MethodCall(segment, _, args, _) = &if_expr.kind; if segment.ident.name == sym!(is_none); if Self::expression_returns_none(cx, body); if let Some(subject) = args.get(0); diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index 52e540d4e00..fcd02a196e7 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -129,20 +129,20 @@ declare_lint_pass!(Ranges => [ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ranges { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::MethodCall(ref path, _, ref args) = expr.kind { + if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind { let name = path.ident.as_str(); if name == "zip" && args.len() == 2 { let iter = &args[0].kind; let zip_arg = &args[1]; if_chain! { // `.iter()` call - if let ExprKind::MethodCall(ref iter_path, _, ref iter_args ) = *iter; + if let ExprKind::MethodCall(ref iter_path, _, ref iter_args , _) = *iter; if iter_path.ident.name == sym!(iter); // range expression in `.zip()` call: `0..x.len()` if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg); if is_integer_const(cx, start, 0); // `.len()` call - if let ExprKind::MethodCall(ref len_path, _, ref len_args) = end.kind; + if let ExprKind::MethodCall(ref len_path, _, ref len_args, _) = end.kind; if len_path.ident.name == sym!(len) && len_args.len() == 1; // `.iter()` and `.len()` called on same `Path` if let ExprKind::Path(QPath::Resolved(_, ref iter_path)) = iter_args[0].kind; diff --git a/src/tools/clippy/clippy_lints/src/redundant_pattern_matching.rs b/src/tools/clippy/clippy_lints/src/redundant_pattern_matching.rs index 7ee298e9833..f16b916441a 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_pattern_matching.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_pattern_matching.rs @@ -89,7 +89,7 @@ fn find_sugg_for_if_let<'a, 'tcx>( // check that `while_let_on_iterator` lint does not trigger if_chain! { if keyword == "while"; - if let ExprKind::MethodCall(method_path, _, _) = op.kind; + if let ExprKind::MethodCall(method_path, _, _, _) = op.kind; if method_path.ident.name == sym!(next); if match_trait_method(cx, op, &paths::ITERATOR); then { diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs index a7c4f2c2291..44c9cc19cfb 100644 --- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs +++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs @@ -207,7 +207,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> { fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) { if_chain! { if self.initialization_found; - if let ExprKind::MethodCall(ref path, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if let ExprKind::Path(ref qpath_subj) = args[0].kind; if match_qpath(&qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]); if path.ident.name == sym!(extend); @@ -224,7 +224,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> { fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) { if_chain! { if self.initialization_found; - if let ExprKind::MethodCall(ref path, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref path, _, ref args, _) = expr.kind; if let ExprKind::Path(ref qpath_subj) = args[0].kind; if match_qpath(&qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]); if path.ident.name == sym!(resize); @@ -246,7 +246,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> { /// Returns `true` if give expression is `repeat(0).take(...)` fn is_repeat_take(&self, expr: &Expr<'_>) -> bool { if_chain! { - if let ExprKind::MethodCall(ref take_path, _, ref take_args) = expr.kind; + if let ExprKind::MethodCall(ref take_path, _, ref take_args, _) = expr.kind; if take_path.ident.name == sym!(take); // Check that take is applied to `repeat(0)` diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index f84566ef707..d8e4bff3d70 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -164,7 +164,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes { use rustc_ast::ast::LitKind; if_chain! { - if let ExprKind::MethodCall(path, _, args) = &e.kind; + if let ExprKind::MethodCall(path, _, args, _) = &e.kind; if path.ident.name == sym!(as_bytes); if let ExprKind::Lit(lit) = &args[0].kind; if let LitKind::Str(lit_content, _) = &lit.node; diff --git a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs index c6302ca03d9..4f132c6db76 100644 --- a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs @@ -34,12 +34,12 @@ declare_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ToDigitIsSome { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) { if_chain! { - if let hir::ExprKind::MethodCall(is_some_path, _, is_some_args) = &expr.kind; + if let hir::ExprKind::MethodCall(is_some_path, _, is_some_args, _) = &expr.kind; if is_some_path.ident.name.as_str() == "is_some"; if let [to_digit_expr] = &**is_some_args; then { let match_result = match &to_digit_expr.kind { - hir::ExprKind::MethodCall(to_digits_path, _, to_digit_args) => { + hir::ExprKind::MethodCall(to_digits_path, _, to_digit_args, _) => { if_chain! { if let [char_arg, radix_arg] = &**to_digit_args; if to_digits_path.ident.name.as_str() == "to_digit"; diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs index bc5fe44b30f..57d5b27df57 100644 --- a/src/tools/clippy/clippy_lints/src/types.rs +++ b/src/tools/clippy/clippy_lints/src/types.rs @@ -778,7 +778,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg { } match expr.kind { - ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args) => { + ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) => { let args_to_recover = args .iter() .filter(|arg| { @@ -1262,14 +1262,14 @@ fn check_loss_of_sign(cx: &LateContext<'_, '_>, expr: &Expr<'_>, op: &Expr<'_>, } // don't lint for the result of methods that always return non-negative values - if let ExprKind::MethodCall(ref path, _, _) = op.kind { + if let ExprKind::MethodCall(ref path, _, _, _) = op.kind { let mut method_name = path.ident.name.as_str(); let whitelisted_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"]; if_chain! { if method_name == "unwrap"; if let Some(arglist) = method_chain_args(op, &["unwrap"]); - if let ExprKind::MethodCall(ref inner_path, _, _) = &arglist[0][0].kind; + if let ExprKind::MethodCall(ref inner_path, _, _, _) = &arglist[0][0].kind; then { method_name = inner_path.ident.name.as_str(); } diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index b85134e3d7a..5f4b5fd9dd9 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { } }, - hir::ExprKind::MethodCall(ref path, _, ref args) => match &*path.ident.as_str() { + hir::ExprKind::MethodCall(ref path, _, ref args, _) => match &*path.ident.as_str() { "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => { check_method_call(cx, &args[0], expr); }, @@ -65,7 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { } fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) { - if let hir::ExprKind::MethodCall(ref path, _, _) = call.kind { + if let hir::ExprKind::MethodCall(ref path, _, _, _) = call.kind { let symbol = &*path.ident.as_str(); let read_trait = match_trait_method(cx, call, &paths::IO_READ); let write_trait = match_trait_method(cx, call, &paths::IO_WRITE); diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 036dd16a224..a6c7b5d405c 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -112,7 +112,7 @@ fn collect_unwrap_info<'a, 'tcx>( return collect_unwrap_info(cx, expr, branch, !invert); } else { 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; let ty = cx.tables.expr_ty(&args[0]); let name = method_name.ident.as_str(); @@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> { } else { // find `unwrap[_err]()` calls: if_chain! { - if let ExprKind::MethodCall(ref method_name, _, ref args) = expr.kind; + if let ExprKind::MethodCall(ref method_name, _, ref args, _) = expr.kind; if let ExprKind::Path(QPath::Resolved(None, ref path)) = args[0].kind; if [sym!(unwrap), sym!(unwrap_err)].contains(&method_name.ident.name); let call_to_unwrap = method_name.ident.name == sym!(unwrap); diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 141035a980a..78d249482d5 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -61,7 +61,7 @@ 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" { let a = cx.tables.expr_ty(e); let b = cx.tables.expr_ty(&args[0]); diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bbcf396eef7..8b58bbb5e65 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -250,8 +250,8 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { self.visit_expr(arg); } }, - ExprKind::MethodCall(ref _method_name, ref _generics, ref _args) => { - println!("MethodCall(ref method_name, ref generics, ref args) = {};", current); + ExprKind::MethodCall(ref _method_name, ref _generics, ref _args, ref _fn_span) => { + println!("MethodCall(ref method_name, ref generics, ref args, ref fn_span) = {};", current); println!(" // unimplemented: `ExprKind::MethodCall` is not further destructured at the moment"); }, ExprKind::Tup(ref elements) => { diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs index f8d197c15e8..473a730dad5 100644 --- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { && self.eq_pat(&l.pat, &r.pat) }) }, - (&ExprKind::MethodCall(l_path, _, l_args), &ExprKind::MethodCall(r_path, _, r_args)) => { + (&ExprKind::MethodCall(l_path, _, l_args, _), &ExprKind::MethodCall(r_path, _, r_args, _)) => { !self.ignore_fn && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args) }, (&ExprKind::Repeat(ref le, ref ll_id), &ExprKind::Repeat(ref re, ref rl_id)) => { @@ -542,7 +542,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { s.hash(&mut self.s); }, - ExprKind::MethodCall(ref path, ref _tys, args) => { + ExprKind::MethodCall(ref path, ref _tys, args, ref _fn_span) => { self.hash_name(path.ident.name); self.hash_exprs(args); }, diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 9b672b9ec22..649b166e98e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -167,7 +167,7 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, indent: usize) { print_expr(cx, arg, indent + 1); } }, - hir::ExprKind::MethodCall(ref path, _, args) => { + hir::ExprKind::MethodCall(ref path, _, args, _) => { println!("{}MethodCall", ind); println!("{}method name: {}", ind, path.ident.name); for arg in args { diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs index 8e1b047f6f8..89e2bcdd793 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs @@ -402,7 +402,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions { } if_chain! { - 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; if let Some(sugg) = self.map.get(&*fn_name.as_str()); let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); @@ -491,7 +491,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CollapsibleCalls { let stmts = &block.stmts; if stmts.len() == 1 && block.expr.is_none(); if let StmtKind::Semi(only_expr) = &stmts[0].kind; - if let ExprKind::MethodCall(ref ps, _, ref span_call_args) = &only_expr.kind; + if let ExprKind::MethodCall(ref ps, _, ref span_call_args, _) = &only_expr.kind; let and_then_snippets = get_and_then_snippets(cx, and_then_args); let mut sle = SpanlessEq::new(cx).ignore_fn(); then { diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 7b59917c2bb..60ab19e71f5 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -379,7 +379,7 @@ pub fn method_calls<'tcx>( let mut current = expr; for _ in 0..max_depth { - if let ExprKind::MethodCall(path, span, args) = ¤t.kind { + if let ExprKind::MethodCall(path, span, args, _) = ¤t.kind { if args.iter().any(|e| e.span.from_expansion()) { break; } @@ -406,7 +406,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option first - if let ExprKind::MethodCall(ref path, _, ref args) = current.kind { + if let ExprKind::MethodCall(ref path, _, ref args, _) = current.kind { if path.ident.name.as_str() == *method_name { if args.iter().any(|e| e.span.from_expansion()) { return None; @@ -1324,7 +1324,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool None } }, - ExprKind::MethodCall(_, _, _) => cx.tables.type_dependent_def_id(expr.hir_id), + ExprKind::MethodCall(_, _, _, _) => cx.tables.type_dependent_def_id(expr.hir_id), _ => None, }; diff --git a/src/tools/clippy/clippy_lints/src/utils/ptr.rs b/src/tools/clippy/clippy_lints/src/utils/ptr.rs index fb6bd5e8158..ee336ecc58d 100644 --- a/src/tools/clippy/clippy_lints/src/utils/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/utils/ptr.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> { if self.abort { return; } - if let ExprKind::MethodCall(ref seg, _, ref args) = expr.kind { + if let ExprKind::MethodCall(ref seg, _, ref args, _) = expr.kind { if args.len() == 1 && match_var(&args[0], self.name) { if seg.ident.name.as_str() == "capacity" { self.abort = true; diff --git a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs b/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs index 7247518e19b..6d420d491c5 100644 --- a/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs +++ b/src/tools/clippy/clippy_lints/src/verbose_file_reads.rs @@ -59,7 +59,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VerboseFileReads { fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if_chain! { - 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 let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; let ty = cx.tables.expr_ty(&exprs[0]); @@ -73,7 +73,7 @@ fn is_file_read_to_end<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'t fn is_file_read_to_string<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool { if_chain! { - 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 let ExprKind::Path(QPath::Resolved(None, _)) = &exprs[0].kind; let ty = cx.tables.expr_ty(&exprs[0]); From f69a2a6cbd38a13c039fd1f1114424fe0e55b14a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 9 Jun 2020 20:25:47 -0400 Subject: [PATCH 3/6] Fix pprust-expr-roundtrip --- src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index cef600bed5f..6da26e6cfbe 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -84,9 +84,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { 2 => { let seg = PathSegment::from_ident(Ident::from_str("x")); iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( - seg.clone(), vec![e, make_x()]))); + seg.clone(), vec![e, make_x()], DUMMY_SP))); iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall( - seg.clone(), vec![make_x(), e]))); + seg.clone(), vec![make_x(), e], DUMMY_SP))); }, 3..=8 => { let op = Spanned { From bbf497b0eb2caec0e8c9ffba7f37dc84885e2e90 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 9 Jun 2020 20:31:12 -0400 Subject: [PATCH 4/6] Add doc comments --- src/librustc_ast/ast.rs | 2 +- src/librustc_middle/mir/mod.rs | 2 ++ src/librustc_mir_build/hair/mod.rs | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 5012fbb30b0..9016d35ea0e 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1165,7 +1165,7 @@ pub enum ExprKind { /// and the remaining elements are the rest of the arguments. /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. - /// The `Span` is the span of the function, without the dot and receiver + /// This `Span` is the span of the function, without the dot and receiver /// (e.g. `foo(a, b)` in `x.foo(a, b)` MethodCall(PathSegment, Vec>, Span), /// A tuple (e.g., `(a, b, c, d)`). diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 6ffed524400..98746d63fac 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -1131,6 +1131,8 @@ pub enum TerminatorKind<'tcx> { /// `true` if this is from a call in HIR rather than from an overloaded /// operator. True for overloaded function call. from_hir_call: bool, + /// This `Span` is the span of the function, without the dot and receiver + /// (e.g. `foo(a, b)` in `x.foo(a, b)` fn_span: Span, }, diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs index 140b8bbe15e..d3ec5595365 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -146,6 +146,8 @@ crate enum ExprKind<'tcx> { // Whether this is from a call in HIR, rather than from an overloaded // operator. True for overloaded function call. from_hir_call: bool, + /// This `Span` is the span of the function, without the dot and receiver + /// (e.g. `foo(a, b)` in `x.foo(a, b)` fn_span: Span, }, Deref { From e5f3b94d561bfb8f9c78a9ef2b276c22b29a8faf Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 9 Jun 2020 23:45:32 -0400 Subject: [PATCH 5/6] Clippy fixes --- src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs | 6 +++--- src/tools/clippy/clippy_lints/src/utils/ast_utils.rs | 2 +- src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs index 33d8331c292..e94eebb88e4 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs @@ -95,7 +95,7 @@ fn mirrored_exprs( // The two exprs are method calls. // Check to see that the function is the same and the arguments are mirrored // This is enough because the receiver of the method is listed in the arguments - (ExprKind::MethodCall(left_segment, _, left_args), ExprKind::MethodCall(right_segment, _, right_args)) => { + (ExprKind::MethodCall(left_segment, _, left_args, _), ExprKind::MethodCall(right_segment, _, right_args, _)) => { left_segment.ident == right_segment.ident && left_args .iter() @@ -170,7 +170,7 @@ fn mirrored_exprs( fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option { if_chain! { - if let ExprKind::MethodCall(name_ident, _, args) = &expr.kind; + if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind; if let name = name_ident.ident.name.to_ident_string(); if name == "sort_by" || name == "sort_unstable_by"; if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args; @@ -180,7 +180,7 @@ fn detect_lint(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..}, Param { pat: Pat { kind: PatKind::Binding(_, _, right_ident, _), .. }, .. } ] = &closure_body.params; - if let ExprKind::MethodCall(method_path, _, [ref left_expr, ref right_expr]) = &closure_body.value.kind; + if let ExprKind::MethodCall(method_path, _, [ref left_expr, ref right_expr], _) = &closure_body.value.kind; if method_path.ident.name.to_ident_string() == "cmp"; then { let (closure_body, closure_arg, reverse) = if mirrored_exprs( diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs index dcf09da198e..e60e2a81e07 100755 --- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs @@ -120,7 +120,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), - (MethodCall(lc, la), MethodCall(rc, ra)) => eq_path_seg(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), + (MethodCall(lc, la, _), MethodCall(rc, ra, _)) => eq_path_seg(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr), (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r), (Lit(l), Lit(r)) => l.kind == r.kind, diff --git a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs index 86cbfa8203d..55758efa32e 100644 --- a/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs @@ -31,7 +31,7 @@ declare_lint_pass!(VecResizeToZero => [VEC_RESIZE_TO_ZERO]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VecResizeToZero { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { 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 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; From 9d36fa3d47b617930a8eb4a8a3a6c4db426cab45 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 10 Jun 2020 18:39:05 -0400 Subject: [PATCH 6/6] Fix test --- src/librustc_mir/dataflow/framework/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/src/librustc_mir/dataflow/framework/tests.rs index 3ed0a9594e7..9349f5133a5 100644 --- a/src/librustc_mir/dataflow/framework/tests.rs +++ b/src/librustc_mir/dataflow/framework/tests.rs @@ -41,6 +41,7 @@ fn mock_body() -> mir::Body<'static> { destination: Some((dummy_place.clone(), mir::START_BLOCK)), cleanup: None, from_hir_call: false, + fn_span: DUMMY_SP, }, ); block(3, mir::TerminatorKind::Return); @@ -53,6 +54,7 @@ fn mock_body() -> mir::Body<'static> { destination: Some((dummy_place.clone(), mir::START_BLOCK)), cleanup: None, from_hir_call: false, + fn_span: DUMMY_SP, }, );