mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Auto merge of #73246 - Dylan-DPC:rollup-xnm531f, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #72180 (remove extra space from crate-level doctest names) - #73012 (Show `SyntaxContext` in formatted `Span` debug output) - #73097 (Try_run must only be used if toolstate is populated) - #73169 (Handle assembler warnings properly) - #73182 (Track span of function in method calls, and use this in #[track_caller]) - #73207 (Clean up E0648 explanation) - #73230 (Suggest including unused asm arguments in a comment to avoid error) Failed merges: r? @ghost
This commit is contained in:
commit
a37c32e2d5
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1174,7 +1174,9 @@ pub enum ExprKind {
|
||||
/// and the remaining elements are the rest of the arguments.
|
||||
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
|
||||
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
|
||||
MethodCall(PathSegment, Vec<P<Expr>>),
|
||||
/// 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<P<Expr>>, Span),
|
||||
/// A tuple (e.g., `(a, b, c, d)`).
|
||||
Tup(Vec<P<Expr>>),
|
||||
/// A binary operation (e.g., `a + b`, `a * b`).
|
||||
|
@ -1111,11 +1111,12 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
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);
|
||||
|
@ -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])
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) => {
|
||||
|
@ -391,7 +391,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
||||
used[*pos] = true;
|
||||
}
|
||||
|
||||
let named_pos: FxHashSet<usize> = args.named_args.values().cloned().collect();
|
||||
let named_pos: FxHashMap<usize, Symbol> =
|
||||
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<ast
|
||||
let operand_idx = match arg.position {
|
||||
parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
|
||||
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<ast
|
||||
};
|
||||
err.note(&msg);
|
||||
|
||||
if named_pos.contains(&idx) {
|
||||
if named_pos.contains_key(&idx) {
|
||||
err.span_label(args.operands[idx].1, "named argument");
|
||||
err.span_note(
|
||||
args.operands[idx].1,
|
||||
@ -480,27 +481,31 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
||||
}
|
||||
}
|
||||
|
||||
let operands = args.operands;
|
||||
let unused_operands: Vec<_> = 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<ast
|
||||
for (sp, msg) in unused_operands {
|
||||
err.span_label(sp, msg);
|
||||
}
|
||||
err.help(&format!(
|
||||
"if these arguments are intentionally unused, \
|
||||
consider using them in an asm comment: `\"/*{} */\"`",
|
||||
help_str
|
||||
));
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
@ -521,7 +531,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
||||
parser.line_spans.iter().map(|span| template_span.from_inner(*span)).collect()
|
||||
};
|
||||
|
||||
let inline_asm = ast::InlineAsm { template, operands, options: args.options, line_spans };
|
||||
let inline_asm =
|
||||
ast::InlineAsm { template, operands: args.operands, options: args.options, line_spans };
|
||||
P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
|
||||
|
@ -16,7 +16,7 @@ use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, Mo
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc_errors::{FatalError, Handler, Level};
|
||||
use rustc_fs_util::{link_or_copy, path_to_c_string};
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::bug;
|
||||
@ -242,6 +242,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
|
||||
fn report_inline_asm(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
msg: String,
|
||||
level: llvm::DiagnosticLevel,
|
||||
mut cookie: c_uint,
|
||||
source: Option<(String, Vec<InnerSpan>)>,
|
||||
) {
|
||||
@ -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) => {
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -1551,7 +1551,7 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>
|
||||
|
||||
enum SharedEmitterMessage {
|
||||
Diagnostic(Diagnostic),
|
||||
InlineAsmError(u32, String, Option<(String, Vec<InnerSpan>)>),
|
||||
InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
|
||||
AbortIfErrors,
|
||||
Fatal(String),
|
||||
}
|
||||
@ -1576,9 +1576,10 @@ impl SharedEmitter {
|
||||
&self,
|
||||
cookie: u32,
|
||||
msg: String,
|
||||
level: Level,
|
||||
source: Option<(String, Vec<InnerSpan>)>,
|
||||
) {
|
||||
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.
|
||||
|
@ -530,6 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
args: &Vec<mir::Operand<'tcx>>,
|
||||
destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
|
||||
cleanup: Option<mir::BasicBlock>,
|
||||
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 { .. } => {
|
||||
|
@ -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() {}
|
||||
```
|
||||
|
@ -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<MultiSpan>, msg: &str) -> FatalError {
|
||||
self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span);
|
||||
FatalError
|
||||
|
@ -272,7 +272,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
) -> P<ast::Expr> {
|
||||
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<ast::Block>) -> P<ast::Expr> {
|
||||
self.expr(b.span, ast::ExprKind::Block(b, None))
|
||||
|
@ -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::<Bar, Baz>(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::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(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`).
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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])
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 } => {
|
||||
|
@ -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 {
|
||||
|
@ -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<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
if !self.empty_path {
|
||||
write!(self, "::")?;
|
||||
}
|
||||
write!(self, "<impl at {:?}>", span)?;
|
||||
write!(self, "<impl at {}>", self.tcx.sess.source_map().span_to_string(span))?;
|
||||
self.empty_path = false;
|
||||
|
||||
return Ok(self);
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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<ClosureRegionRequirements<'_>>,
|
||||
) {
|
||||
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 {
|
||||
|
@ -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(())
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<String>,
|
||||
}
|
||||
|
||||
@ -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, "|")?;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -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<ExprRef<'tcx>>,
|
||||
) -> 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()`
|
||||
|
@ -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>,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -441,6 +441,9 @@ impl Session {
|
||||
pub fn span_note_without_error<S: Into<MultiSpan>>(&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
|
||||
|
@ -726,10 +726,18 @@ pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, 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())
|
||||
|
@ -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[..],
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
15
src/test/rustdoc-ui/doctest-output.rs
Normal file
15
src/test/rustdoc-ui/doctest-output.rs
Normal file
@ -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() {}
|
||||
}
|
7
src/test/rustdoc-ui/doctest-output.stdout
Normal file
7
src/test/rustdoc-ui/doctest-output.stdout
Normal file
@ -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
|
||||
|
@ -84,9 +84,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
|
||||
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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
--> <inline asm>:1:23
|
||||
|
|
||||
LL | movaps %xmm3, (%esi, 2)
|
||||
| ^
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
|
||||
|
@ -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),
|
||||
},
|
||||
]
|
||||
|
28
src/test/ui/rfc-2091-track-caller/call-chain.rs
Normal file
28
src/test/ui/rfc-2091-track-caller/call-chain.rs
Normal file
@ -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);
|
||||
}
|
@ -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";
|
||||
|
@ -247,7 +247,7 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<String> {
|
||||
))
|
||||
})
|
||||
},
|
||||
ExprKind::MethodCall(path, _, args) if args.len() == 1 => {
|
||||
ExprKind::MethodCall(path, _, args, _) if args.len() == 1 => {
|
||||
let type_of_receiver = cx.tables.expr_ty(&args[0]);
|
||||
if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type))
|
||||
&& !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type))
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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]);
|
||||
|
@ -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();
|
||||
|
@ -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 ()
|
||||
|
@ -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() {
|
||||
|
@ -104,7 +104,7 @@ fn on_argumentv1_new<'a, 'tcx>(
|
||||
}
|
||||
} else {
|
||||
let snip = snippet(cx, format_args.span, "<arg>");
|
||||
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));
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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<T,E>.ok()
|
||||
if let ExprKind::MethodCall(_, ok_span, ref result_types, _) = op.kind; //check is expr.ok() has type Result<T,E>.ok(, _)
|
||||
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.kind; //get operation
|
||||
if 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));
|
||||
|
@ -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]);
|
||||
|
@ -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" {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user