diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index a99e39ed3542..163132f56342 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -553,7 +553,7 @@ impl Step for Clippy { builder.add_rustc_lib_path(compiler, &mut cargo); - try_run(builder, &mut cargo.into()); + builder.run(&mut cargo.into()); } } diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index ea560a6d7091..fbb40f1d2f3d 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -201,7 +201,7 @@ fn mul(a: u64, b: u64) -> u128 { ); } - (hi as u128) << 64 + lo as u128 + ((hi as u128) << 64) + lo as u128 } ``` @@ -382,7 +382,9 @@ The macro will initially be supported only on ARM, AArch64, x86, x86-64 and RISC The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). The corresponding arguments are accessed in order, by index, or by name. However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported. -As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after any named arguments if any. Explicit register operands cannot be used by placeholders in the template string. All other operands must appear at least once in the template string, otherwise a compiler error is generated. +As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after named arguments if any. + +Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated. The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler. diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 672ef108969e..d3e3546cf31e 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1174,7 +1174,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>), + /// 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)`). 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 66b8d7f97f0e..2ffef9d48c18 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 b98cc96b3c64..d8b44a22f2c9 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 41c02734442a..ccab46703dff 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 79d16a318d21..b7894eb145b0 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 8ff80df527ce..b1abc08aa67b 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_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs index 6127fcc5a4be..480ee97f2055 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/src/librustc_builtin_macros/asm.rs @@ -391,7 +391,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P = args.named_args.values().cloned().collect(); + let named_pos: FxHashMap = + args.named_args.iter().map(|(&sym, &idx)| (idx, sym)).collect(); let mut arg_spans = parser.arg_places.iter().map(|span| template_span.from_inner(*span)); let mut template = vec![]; for piece in unverified_pieces { @@ -405,7 +406,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P { if idx >= args.operands.len() - || named_pos.contains(&idx) + || named_pos.contains_key(&idx) || args.reg_args.contains(&idx) { let msg = format!("invalid reference to argument at index {}", idx); @@ -426,7 +427,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P, sp: Span, args: AsmArgs) -> P = used - .into_iter() - .enumerate() - .filter(|&(_, used)| !used) - .map(|(idx, _)| { - if named_pos.contains(&idx) { - // named argument - (operands[idx].1, "named argument never used") + let mut unused_operands = vec![]; + let mut help_str = String::new(); + for (idx, used) in used.into_iter().enumerate() { + if !used { + let msg = if let Some(sym) = named_pos.get(&idx) { + help_str.push_str(&format!(" {{{}}}", sym)); + "named argument never used" } else { - // positional argument - (operands[idx].1, "argument never used") - } - }) - .collect(); + help_str.push_str(&format!(" {{{}}}", idx)); + "argument never used" + }; + unused_operands.push((args.operands[idx].1, msg)); + } + } match unused_operands.len() { 0 => {} 1 => { let (sp, msg) = unused_operands.into_iter().next().unwrap(); let mut err = ecx.struct_span_err(sp, msg); err.span_label(sp, msg); + err.help(&format!( + "if this argument is intentionally unused, \ + consider using it in an asm comment: `\"/*{} */\"`", + help_str + )); err.emit(); } _ => { @@ -511,6 +516,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P, sp: Span, args: AsmArgs) -> P Drop for DiagnosticHandlers<'a> { fn report_inline_asm( cgcx: &CodegenContext, msg: String, + level: llvm::DiagnosticLevel, mut cookie: c_uint, source: Option<(String, Vec)>, ) { @@ -251,7 +252,12 @@ fn report_inline_asm( if matches!(cgcx.lto, Lto::Fat | Lto::Thin) { cookie = 0; } - cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, source); + let level = match level { + llvm::DiagnosticLevel::Error => Level::Error, + llvm::DiagnosticLevel::Warning => Level::Warning, + llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note, + }; + cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source); } unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) { @@ -264,6 +270,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void // diagnostics. let mut have_source = false; let mut buffer = String::new(); + let mut level = llvm::DiagnosticLevel::Error; let mut loc = 0; let mut ranges = [0; 8]; let mut num_ranges = ranges.len() / 2; @@ -273,6 +280,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void diag, msg, buffer, + &mut level, &mut loc, ranges.as_mut_ptr(), &mut num_ranges, @@ -290,7 +298,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void (buffer, spans) }); - report_inline_asm(cgcx, msg, cookie, source); + report_inline_asm(cgcx, msg, level, cookie, source); } unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) { @@ -301,7 +309,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void match llvm::diagnostic::Diagnostic::unpack(info) { llvm::diagnostic::InlineAsm(inline) => { - report_inline_asm(cgcx, llvm::twine_to_string(inline.message), inline.cookie, None); + report_inline_asm( + cgcx, + llvm::twine_to_string(inline.message), + inline.level, + inline.cookie, + None, + ); } llvm::diagnostic::Optimization(opt) => { diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 4347cd06532d..47f5c94e70c5 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -88,6 +88,7 @@ impl OptimizationDiagnostic<'ll> { #[derive(Copy, Clone)] pub struct InlineAsmDiagnostic<'ll> { + pub level: super::DiagnosticLevel, pub cookie: c_uint, pub message: &'ll Twine, pub instruction: Option<&'ll Value>, @@ -98,10 +99,17 @@ impl InlineAsmDiagnostic<'ll> { let mut cookie = 0; let mut message = None; let mut instruction = None; + let mut level = super::DiagnosticLevel::Error; - super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut cookie, &mut message, &mut instruction); + super::LLVMRustUnpackInlineAsmDiagnostic( + di, + &mut level, + &mut cookie, + &mut message, + &mut instruction, + ); - InlineAsmDiagnostic { cookie, message: message.unwrap(), instruction } + InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 759c2bf1b85f..3c981af73ab0 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -489,6 +489,17 @@ pub enum DiagnosticKind { Linker, } +/// LLVMRustDiagnosticLevel +#[derive(Copy, Clone)] +#[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. +pub enum DiagnosticLevel { + Error, + Warning, + Note, + Remark, +} + /// LLVMRustArchiveKind #[derive(Copy, Clone)] #[repr(C)] @@ -2054,6 +2065,7 @@ extern "C" { pub fn LLVMRustUnpackInlineAsmDiagnostic( DI: &'a DiagnosticInfo, + level_out: &mut DiagnosticLevel, cookie_out: &mut c_uint, message_out: &mut Option<&'a Twine>, instruction_out: &mut Option<&'a Value>, @@ -2074,6 +2086,7 @@ extern "C" { d: &SMDiagnostic, message_out: &RustString, buffer_out: &RustString, + level_out: &mut DiagnosticLevel, loc_out: &mut c_uint, ranges_out: *mut c_uint, num_ranges: &mut usize, diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index cb5c95c11fad..c118e5ebdb72 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1551,7 +1551,7 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem enum SharedEmitterMessage { Diagnostic(Diagnostic), - InlineAsmError(u32, String, Option<(String, Vec)>), + InlineAsmError(u32, String, Level, Option<(String, Vec)>), AbortIfErrors, Fatal(String), } @@ -1576,9 +1576,10 @@ impl SharedEmitter { &self, cookie: u32, msg: String, + level: Level, source: Option<(String, Vec)>, ) { - drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, source))); + drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source))); } pub fn fatal(&self, msg: &str) { @@ -1631,16 +1632,21 @@ impl SharedEmitterMain { } handler.emit_diagnostic(&d); } - Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, source)) => { + Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { let msg = msg.strip_prefix("error: ").unwrap_or(&msg); + let mut err = match level { + Level::Error => sess.struct_err(&msg), + Level::Warning => sess.struct_warn(&msg), + Level::Note => sess.struct_note_without_error(&msg), + _ => bug!("Invalid inline asm diagnostic level"), + }; + // If the cookie is 0 then we don't have span information. - let mut err = if cookie == 0 { - sess.struct_err(&msg) - } else { + if cookie != 0 { let pos = BytePos::from_u32(cookie); let span = Span::with_root_ctxt(pos, pos); - sess.struct_span_err(span, &msg) + err.set_span(span); }; // Point to the generated assembly if it is available. diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 30a84c4e47b0..74d7fc162158 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_error_codes/error_codes/E0648.md b/src/librustc_error_codes/error_codes/E0648.md index 319bae103f3b..d99dc19503dd 100644 --- a/src/librustc_error_codes/error_codes/E0648.md +++ b/src/librustc_error_codes/error_codes/E0648.md @@ -1,6 +1,15 @@ -`export_name` attributes may not contain null characters (`\0`). +An `export_name` attribute contains null characters (`\0`). + +Erroneous code example: ```compile_fail,E0648 #[export_name="\0foo"] // error: `export_name` may not contain null characters pub fn bar() {} ``` + +To fix this error, remove the null characters: + +``` +#[export_name="foo"] // ok! +pub fn bar() {} +``` diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e4a560e434aa..7261c638ce01 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -581,6 +581,11 @@ impl Handler { DiagnosticBuilder::new(self, Level::Help, msg) } + /// Construct a builder at the `Note` level with the `msg`. + pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { + DiagnosticBuilder::new(self, Level::Note, msg) + } + pub fn span_fatal(&self, span: impl Into, msg: &str) -> FatalError { self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); FatalError diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 6185e014d3c5..20d2ea0a215d 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 1e305c6d32d6..6b751456618e 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 97601a3e1ac7..6bc899622a36 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 da8956ccb4da..bf5b7152f0ea 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -1308,7 +1308,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) => { @@ -2491,7 +2491,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 81cb306d2644..ceaec2ba5db0 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_interface/callbacks.rs b/src/librustc_interface/callbacks.rs index 913c67d045e5..7fa1a3eb0f59 100644 --- a/src/librustc_interface/callbacks.rs +++ b/src/librustc_interface/callbacks.rs @@ -18,7 +18,7 @@ use std::fmt; fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { tls::with_opt(|tcx| { if let Some(tcx) = tcx { - write!(f, "{}", tcx.sess.source_map().span_to_string(span)) + rustc_span::debug_with_source_map(span, f, tcx.sess.source_map()) } else { rustc_span::default_span_debug(span, f) } diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index 3eb587c016ac..5b282c420340 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 e17e8b7b9640..aa0dd9c83113 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 dea829343137..8196b37391b2 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 98973f1b6fb7..126e70e8c48d 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -1131,6 +1131,9 @@ 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, }, /// Jump to the target if the condition has the expected value, @@ -2449,7 +2452,8 @@ impl<'tcx> Debug for Rvalue<'tcx> { tcx.def_path_str_with_substs(def_id.to_def_id(), substs), ) } else { - format!("[closure@{:?}]", tcx.hir().span(hir_id)) + let span = tcx.hir().span(hir_id); + format!("[closure@{}]", tcx.sess.source_map().span_to_string(span)) }; let mut struct_fmt = fmt.debug_struct(&name); diff --git a/src/librustc_middle/mir/type_foldable.rs b/src/librustc_middle/mir/type_foldable.rs index 97c6d6bf5f40..3f5d528d9e7c 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 9f886cbc9fb5..966a709c8a2c 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_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 90fb19816179..017f7270761a 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -605,7 +605,8 @@ pub trait PrettyPrinter<'tcx>: // FIXME(eddyb) should use `def_span`. if let Some(did) = did.as_local() { let hir_id = self.tcx().hir().as_local_hir_id(did); - p!(write("@{:?}", self.tcx().hir().span(hir_id))); + let span = self.tcx().hir().span(hir_id); + p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); if substs.as_generator().is_valid() { let upvar_tys = substs.as_generator().upvar_tys(); @@ -653,7 +654,8 @@ pub trait PrettyPrinter<'tcx>: if self.tcx().sess.opts.debugging_opts.span_free_formats { p!(write("@"), print_def_path(did.to_def_id(), substs)); } else { - p!(write("@{:?}", self.tcx().hir().span(hir_id))); + let span = self.tcx().hir().span(hir_id); + p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); } if substs.as_closure().is_valid() { @@ -1362,7 +1364,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { if !self.empty_path { write!(self, "::")?; } - write!(self, "", span)?; + write!(self, "", self.tcx.sess.source_map().span_to_string(span))?; self.empty_path = false; return Ok(self); diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index 77d16458383d..18a618950709 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 736cda83ca51..786424e870f8 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/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 1d3733371473..375b3210e8c2 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -314,7 +314,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, source: MirSource<'tcx>, body: &Body<'tcx>, - regioncx: &RegionInferenceContext<'_>, + regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, ) { if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) { @@ -325,7 +325,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>( match pass_where { // Before the CFG, dump out the values for each region variable. PassWhere::BeforeCFG => { - regioncx.dump_mir(out)?; + regioncx.dump_mir(infcx.tcx, out)?; writeln!(out, "|")?; if let Some(closure_region_requirements) = closure_region_requirements { diff --git a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/region_infer/dump_mir.rs index 369e54023116..d6e48deb031a 100644 --- a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/region_infer/dump_mir.rs @@ -4,7 +4,9 @@ //! context internal state. use super::{OutlivesConstraint, RegionInferenceContext}; +use crate::borrow_check::type_check::Locations; use rustc_infer::infer::NLLRegionVariableOrigin; +use rustc_middle::ty::TyCtxt; use std::io::{self, Write}; // Room for "'_#NNNNr" before things get misaligned. @@ -14,7 +16,7 @@ const REGION_WIDTH: usize = 8; impl<'tcx> RegionInferenceContext<'tcx> { /// Write out our state into the `.mir` files. - pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> { + pub(crate) fn dump_mir(&self, tcx: TyCtxt<'tcx>, out: &mut dyn Write) -> io::Result<()> { writeln!(out, "| Free Region Mapping")?; for region in self.regions() { @@ -48,7 +50,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { writeln!(out, "|")?; writeln!(out, "| Inference Constraints")?; - self.for_each_constraint(&mut |msg| writeln!(out, "| {}", msg))?; + self.for_each_constraint(tcx, &mut |msg| writeln!(out, "| {}", msg))?; Ok(()) } @@ -59,6 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// inference resulted in the values that it did when debugging. fn for_each_constraint( &self, + tcx: TyCtxt<'tcx>, with_msg: &mut dyn FnMut(&str) -> io::Result<()>, ) -> io::Result<()> { for region in self.definitions.indices() { @@ -72,7 +75,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { constraints.sort(); for constraint in &constraints { let OutlivesConstraint { sup, sub, locations, category } = constraint; - with_msg(&format!("{:?}: {:?} due to {:?} at {:?}", sup, sub, category, locations,))?; + let (name, arg) = match locations { + Locations::All(span) => ("All", tcx.sess.source_map().span_to_string(*span)), + Locations::Single(loc) => ("Single", format!("{:?}", loc)), + }; + with_msg(&format!("{:?}: {:?} due to {:?} at {}({})", sup, sub, category, name, arg))?; } Ok(()) diff --git a/src/librustc_mir/dataflow/framework/direction.rs b/src/librustc_mir/dataflow/framework/direction.rs index da4ad9b6168e..6c9cb529dc2f 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/framework/tests.rs b/src/librustc_mir/dataflow/framework/tests.rs index 3ed0a9594e7d..9349f5133a55 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, }, ); diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index c0ab356756ac..4f6ccdafdda1 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 91b046d7bb26..ddeed92f8512 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 4a63884be4c4..cd7621ea9752 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 b439e919050c..f95fd9b9e90c 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 2c8ad00fd06d..e1311ccd3746 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 5c78307d882f..4c8fc49099b2 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 8f27247bfb4c..a1345452ca97 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/util/pretty.rs b/src/librustc_mir/util/pretty.rs index ff386cb21830..02614044063f 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -135,7 +135,7 @@ fn dump_matched_mir_node<'tcx, F>( } writeln!(file)?; extra_data(PassWhere::BeforeCFG, &mut file)?; - write_user_type_annotations(body, &mut file)?; + write_user_type_annotations(tcx, body, &mut file)?; write_mir_fn(tcx, source, body, &mut extra_data, &mut file)?; extra_data(PassWhere::AfterCFG, &mut file)?; }; @@ -351,7 +351,7 @@ fn write_extra<'tcx, F>(tcx: TyCtxt<'tcx>, write: &mut dyn Write, mut visit_op: where F: FnMut(&mut ExtraComments<'tcx>), { - let mut extra_comments = ExtraComments { _tcx: tcx, comments: vec![] }; + let mut extra_comments = ExtraComments { tcx, comments: vec![] }; visit_op(&mut extra_comments); for comment in extra_comments.comments { writeln!(write, "{:A$} // {}", "", comment, A = ALIGN)?; @@ -360,7 +360,7 @@ where } struct ExtraComments<'tcx> { - _tcx: TyCtxt<'tcx>, // don't need it now, but bet we will soon + tcx: TyCtxt<'tcx>, comments: Vec, } @@ -377,7 +377,7 @@ impl Visitor<'tcx> for ExtraComments<'tcx> { self.super_constant(constant, location); let Constant { span, user_ty, literal } = constant; self.push("mir::Constant"); - self.push(&format!("+ span: {:?}", span)); + self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span))); if let Some(user_ty) = user_ty { self.push(&format!("+ user_ty: {:?}", user_ty)); } @@ -862,12 +862,22 @@ fn write_mir_sig( Ok(()) } -fn write_user_type_annotations(body: &Body<'_>, w: &mut dyn Write) -> io::Result<()> { +fn write_user_type_annotations( + tcx: TyCtxt<'_>, + body: &Body<'_>, + w: &mut dyn Write, +) -> io::Result<()> { if !body.user_type_annotations.is_empty() { writeln!(w, "| User Type Annotations")?; } for (index, annotation) in body.user_type_annotations.iter_enumerated() { - writeln!(w, "| {:?}: {:?} at {:?}", index.index(), annotation.user_ty, annotation.span)?; + writeln!( + w, + "| {:?}: {:?} at {}", + index.index(), + annotation.user_ty, + tcx.sess.source_map().span_to_string(annotation.span) + )?; } if !body.user_type_annotations.is_empty() { writeln!(w, "|")?; diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index e402b2d15961..76096fc2299f 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 74398ca8a40f..3e7bfc7d59b9 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 d0b35f321225..971a89796e28 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 c869699bb20e..d3ec5595365b 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -146,6 +146,9 @@ 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 { arg: ExprRef<'tcx>, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index e0c372848392..49a5c8801766 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 55978afc5943..ff5dabd5418c 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 cb896810951b..d54ec2eca8c9 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 49177906647b..7166fef2d139 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 fbde6bfd9aae..9b08f709f342 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1404,7 +1404,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_session/session.rs b/src/librustc_session/session.rs index 048033846a13..06d7d4f14d8f 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -441,6 +441,9 @@ impl Session { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.diagnostic().span_note_without_error(sp, msg) } + pub fn struct_note_without_error(&self, msg: &str) -> DiagnosticBuilder<'_> { + self.diagnostic().struct_note_without_error(msg) + } pub fn diagnostic(&self) -> &rustc_errors::Handler { &self.parse_sess.span_diagnostic diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index fbab99b2f8f2..a543fd7df8ce 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -726,10 +726,18 @@ pub fn with_source_map T>(source_map: Lrc, f: F) -> f() } +pub fn debug_with_source_map( + span: Span, + f: &mut fmt::Formatter<'_>, + source_map: &SourceMap, +) -> fmt::Result { + write!(f, "{} ({:?})", source_map.span_to_string(span), span.ctxt()) +} + pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { GLOBALS.with(|globals| { if let Some(source_map) = &*globals.source_map.borrow() { - write!(f, "{}", source_map.span_to_string(span)) + debug_with_source_map(span, f, source_map) } else { f.debug_struct("Span") .field("lo", &span.lo()) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 7ac886989853..a504b999e47f 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -307,7 +307,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, @@ -457,7 +457,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 266e9b21d69a..c6a9a37e4407 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 18846813c458..bb87fb244b6e 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 53973eba2294..6baadb8febd3 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/librustdoc/test.rs b/src/librustdoc/test.rs index 4b15a591da71..21aa0ded5a4b 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -676,7 +676,11 @@ impl Collector { } fn generate_name(&self, line: usize, filename: &FileName) -> String { - format!("{} - {} (line {})", filename, self.names.join("::"), line) + let mut item_path = self.names.join("::"); + if !item_path.is_empty() { + item_path.push(' '); + } + format!("{} - {}(line {})", filename, item_path, line) } pub fn set_position(&mut self, position: Span) { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 6fac2662506a..4704622922af 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1094,8 +1094,17 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( MessageOS << Opt->getMsg(); } +enum class LLVMRustDiagnosticLevel { + Error, + Warning, + Note, + Remark, +}; + extern "C" void -LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut, +LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, + LLVMRustDiagnosticLevel *LevelOut, + unsigned *CookieOut, LLVMTwineRef *MessageOut, LLVMValueRef *InstructionOut) { // Undefined to call this not on an inline assembly diagnostic! @@ -1105,6 +1114,23 @@ LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut, *CookieOut = IA->getLocCookie(); *MessageOut = wrap(&IA->getMsgStr()); *InstructionOut = wrap(IA->getInstruction()); + + switch (IA->getSeverity()) { + case DS_Error: + *LevelOut = LLVMRustDiagnosticLevel::Error; + break; + case DS_Warning: + *LevelOut = LLVMRustDiagnosticLevel::Warning; + break; + case DS_Note: + *LevelOut = LLVMRustDiagnosticLevel::Note; + break; + case DS_Remark: + *LevelOut = LLVMRustDiagnosticLevel::Remark; + break; + default: + report_fatal_error("Invalid LLVMRustDiagnosticLevel value!"); + } } extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI, @@ -1166,6 +1192,7 @@ extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) { return toRust((DiagnosticKind)unwrap(DI)->getKind()); } + // This is kept distinct from LLVMGetTypeKind, because when // a new type kind is added, the Rust-side enum must be // updated or UB will result. @@ -1219,6 +1246,7 @@ extern "C" void LLVMRustSetInlineAsmDiagnosticHandler( extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RustStringRef MessageOut, RustStringRef BufferOut, + LLVMRustDiagnosticLevel* LevelOut, unsigned* LocOut, unsigned* RangesOut, size_t* NumRanges) { @@ -1226,6 +1254,23 @@ extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RawRustStringOstream MessageOS(MessageOut); MessageOS << D.getMessage(); + switch (D.getKind()) { + case SourceMgr::DK_Error: + *LevelOut = LLVMRustDiagnosticLevel::Error; + break; + case SourceMgr::DK_Warning: + *LevelOut = LLVMRustDiagnosticLevel::Warning; + break; + case SourceMgr::DK_Note: + *LevelOut = LLVMRustDiagnosticLevel::Note; + break; + case SourceMgr::DK_Remark: + *LevelOut = LLVMRustDiagnosticLevel::Remark; + break; + default: + report_fatal_error("Invalid LLVMRustDiagnosticLevel value!"); + } + if (D.getLoc() == SMLoc()) return false; diff --git a/src/test/rustdoc-ui/doctest-output.rs b/src/test/rustdoc-ui/doctest-output.rs new file mode 100644 index 000000000000..f812263c2526 --- /dev/null +++ b/src/test/rustdoc-ui/doctest-output.rs @@ -0,0 +1,15 @@ +// compile-flags:--test --test-args=--test-threads=1 +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// check-pass + +//! ``` +//! assert_eq!(1 + 1, 2); +//! ``` + +pub mod foo { + + /// ``` + /// assert_eq!(1 + 1, 2); + /// ``` + pub fn bar() {} +} diff --git a/src/test/rustdoc-ui/doctest-output.stdout b/src/test/rustdoc-ui/doctest-output.stdout new file mode 100644 index 000000000000..9a55bf501969 --- /dev/null +++ b/src/test/rustdoc-ui/doctest-output.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/doctest-output.rs - (line 5) ... ok +test $DIR/doctest-output.rs - foo::bar (line 11) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index cef600bed5fd..6da26e6cfbe4 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 { diff --git a/src/test/ui/asm/bad-template.rs b/src/test/ui/asm/bad-template.rs index 0b333eca1ab9..21ce8c6236d0 100644 --- a/src/test/ui/asm/bad-template.rs +++ b/src/test/ui/asm/bad-template.rs @@ -22,5 +22,7 @@ fn main() { //~^ ERROR invalid reference to argument at index 0 asm!("{:foo}", in(reg) foo); //~^ ERROR asm template modifier must be a single character + asm!("", in(reg) 0, in(reg) 1); + //~^ ERROR multiple unused asm arguments } } diff --git a/src/test/ui/asm/bad-template.stderr b/src/test/ui/asm/bad-template.stderr index 2de76ef82419..1aea7467ed0a 100644 --- a/src/test/ui/asm/bad-template.stderr +++ b/src/test/ui/asm/bad-template.stderr @@ -19,6 +19,8 @@ error: argument never used | LL | asm!("{1}", in(reg) foo); | ^^^^^^^^^^^ argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` --> $DIR/bad-template.rs:13:15 @@ -46,6 +48,8 @@ error: named argument never used | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 --> $DIR/bad-template.rs:18:15 @@ -60,6 +64,8 @@ error: named argument never used | LL | asm!("{1}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 0 --> $DIR/bad-template.rs:21:15 @@ -82,5 +88,15 @@ error: asm template modifier must be a single character LL | asm!("{:foo}", in(reg) foo); | ^^^ -error: aborting due to 10 previous errors +error: multiple unused asm arguments + --> $DIR/bad-template.rs:25:18 + | +LL | asm!("", in(reg) 0, in(reg) 1); + | ^^^^^^^^^ ^^^^^^^^^ argument never used + | | + | argument never used + | + = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` + +error: aborting due to 11 previous errors diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr index fa422f56bece..583a10570360 100644 --- a/src/test/ui/asm/parse-error.stderr +++ b/src/test/ui/asm/parse-error.stderr @@ -127,6 +127,8 @@ error: argument never used | LL | asm!("{a}", a = const foo, a = const bar); | ^^^^^^^^^^^^^ argument never used + | + = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: explicit register arguments cannot have names --> $DIR/parse-error.rs:47:18 diff --git a/src/test/ui/asm/srcloc.rs b/src/test/ui/asm/srcloc.rs index 7af6f620a985..402adc50d5b4 100644 --- a/src/test/ui/asm/srcloc.rs +++ b/src/test/ui/asm/srcloc.rs @@ -37,5 +37,8 @@ fn main() { asm!(concat!("invalid", "_", "instruction")); //~^ ERROR: invalid instruction mnemonic 'invalid_instruction' + + asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); + //~^ WARN: scale factor without index register is ignored } } diff --git a/src/test/ui/asm/srcloc.stderr b/src/test/ui/asm/srcloc.stderr index 57a4fbb97422..d5d12b004816 100644 --- a/src/test/ui/asm/srcloc.stderr +++ b/src/test/ui/asm/srcloc.stderr @@ -70,5 +70,17 @@ note: instantiated into assembly here LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +warning: scale factor without index register is ignored + --> $DIR/srcloc.rs:41:15 + | +LL | asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); + | ^ + | +note: instantiated into assembly here + --> :1:23 + | +LL | movaps %xmm3, (%esi, 2) + | ^ + +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr index 163a2c9f44ca..2c05bdbc492a 100644 --- a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr @@ -1,166 +1,166 @@ -TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 }] +TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0) }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0) }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0) }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0) }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0) }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0) }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0) }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0) }] TokenStream [ Ident { ident: "ident", - span: $DIR/dump-debug-span-debug.rs:9:5: 9:10, + span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0), }, Ident { ident: "r#ident", - span: $DIR/dump-debug-span-debug.rs:10:5: 10:12, + span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/dump-debug-span-debug.rs:11:5: 11:6, + span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/dump-debug-span-debug.rs:12:5: 12:7, + span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/dump-debug-span-debug.rs:12:7: 12:8, + span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/dump-debug-span-debug.rs:13:5: 13:7, + span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "_", - span: $DIR/dump-debug-span-debug.rs:14:6: 14:7, + span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0), }, ], - span: $DIR/dump-debug-span-debug.rs:14:5: 14:8, + span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: $DIR/dump-debug-span-debug.rs:17:5: 17:6, + span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0), }, Literal { kind: Float, symbol: "1.0", suffix: None, - span: $DIR/dump-debug-span-debug.rs:18:5: 18:8, + span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0), }, Literal { kind: Str, symbol: "S", suffix: None, - span: $DIR/dump-debug-span-debug.rs:19:5: 19:8, + span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0), }, Literal { kind: ByteStr, symbol: "B", suffix: None, - span: $DIR/dump-debug-span-debug.rs:20:5: 20:9, + span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0), }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, - span: $DIR/dump-debug-span-debug.rs:21:5: 21:9, + span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0), }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, - span: $DIR/dump-debug-span-debug.rs:22:5: 22:13, + span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, - span: $DIR/dump-debug-span-debug.rs:23:5: 23:11, + span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, - span: $DIR/dump-debug-span-debug.rs:24:5: 24:15, + span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0), }, Literal { kind: Char, symbol: "C", suffix: None, - span: $DIR/dump-debug-span-debug.rs:25:5: 25:8, + span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0), }, Literal { kind: Byte, symbol: "B", suffix: None, - span: $DIR/dump-debug-span-debug.rs:26:5: 26:9, + span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0), }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:29:5: 29:7, + span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0), }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:30:5: 30:9, + span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0), }, Literal { kind: Str, symbol: "S", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:31:5: 31:9, + span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0), }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:32:5: 32:10, + span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0), }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:33:5: 33:10, + span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0), }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:34:5: 34:14, + span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:35:5: 35:12, + span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:36:5: 36:16, + span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0), }, Literal { kind: Char, symbol: "C", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:37:5: 37:9, + span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0), }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:38:5: 38:10, + span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0), }, ] 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 000000000000..3f1c8f7abe8b --- /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); +} diff --git a/src/tools/clippy/clippy_lints/src/atomic_ordering.rs b/src/tools/clippy/clippy_lints/src/atomic_ordering.rs index 73b4cef47250..fca9aaaff9dc 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 8031052e073d..f92c564543b8 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 90c00ad098ff..531531a654d0 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 68ec07e2bcb0..1cd30ae2c638 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 05517f6f9f0c..1eb380a22cc6 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 afefa2506381..7171dcef968c 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 7b332c761a0c..f625058b6703 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 d093025fd3d7..a889856de274 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 320121b27714..7269e2b52c2c 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 3a912d928375..ad4f66c52c2c 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 1530538aa7d1..4cae5ca2c432 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 325b6cf32a3d..991d129e8f0d 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 c32e0a2290d1..3629ba623ce4 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 ae92a96d1634..04d17c91d63c 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 9b13f7609247..6a1fcdd1ce44 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 cd989c0ea6f6..a860a9def242 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 f5bfede75a76..13e85fda8ffe 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 57c62d739640..771bc8d05582 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 d5adf6b0f0dc..8f4fdc685ef3 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 fecd91c7814d..8f4b674c04f4 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 214cf0c130f2..f25a9782813b 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 f513161bbbc5..a0947608e607 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 58a8e1a1064a..7fcf15f8acbe 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 9d3b67988dbb..2d4629b683f0 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 66dfa20edb5e..fd653044a1bc 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 bdbaf2695c8e..88ad1e0914f2 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 cc783baa6872..7dce23dd2230 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 ffc59d43750e..d23d7e59b73f 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 e4361b00fb4c..3591972fe082 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 52e540d4e00d..fcd02a196e7b 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 7ee298e9833f..f16b916441ae 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 a7c4f2c2291f..44c9cc19cfb4 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 f84566ef707a..d8e4bff3d702 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 c6302ca03d91..4f132c6db76f 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 bc5fe44b30f8..57d5b27df574 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/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs index 33d8331c2923..e94eebb88e49 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/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index b85134e3d7a9..5f4b5fd9dd91 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 036dd16a224a..a6c7b5d405cd 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 141035a980ad..78d249482d53 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/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs index dcf09da198e2..e60e2a81e070 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/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bbcf396eef7d..8b58bbb5e657 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 f8d197c15e8d..473a730dad50 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 9b672b9ec225..649b166e98ee 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 8e1b047f6f80..89e2bcdd7935 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 7b59917c2bbf..60ab19e71f5e 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 fb6bd5e81585..ee336ecc58d9 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/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/vec_resize_to_zero.rs index 86cbfa8203d5..55758efa32e6 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; 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 7247518e19b9..6d420d491c50 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]);