mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-01 15:50:05 +03: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:
@@ -553,7 +553,7 @@ fn run(self, builder: &Builder<'_>) {
|
||||
|
||||
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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline: bool) {
|
||||
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::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 @@ fn drop(&mut self) {
|
||||
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 @@ fn report_inline_asm(
|
||||
// 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 @@ fn report_inline_asm(
|
||||
diag,
|
||||
msg,
|
||||
buffer,
|
||||
&mut level,
|
||||
&mut loc,
|
||||
ranges.as_mut_ptr(),
|
||||
&mut num_ranges,
|
||||
@@ -290,7 +298,7 @@ fn report_inline_asm(
|
||||
(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 @@ fn report_inline_asm(
|
||||
|
||||
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 @@ unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> S
|
||||
|
||||
#[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 @@ unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
|
||||
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 @@ pub fn LLVMRustUnpackOptimizationDiagnostic(
|
||||
|
||||
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 @@ pub fn LLVMRustUnpackSMDiagnostic(
|
||||
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 drop(&mut self) {
|
||||
|
||||
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 @@ pub fn inline_asm_error(
|
||||
&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 @@ pub fn check(&self, sess: &Session, blocking: bool) {
|
||||
}
|
||||
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 @@ fn codegen_call_terminator(
|
||||
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 @@ fn codegen_call_terminator(
|
||||
|
||||
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 @@ fn codegen_call_terminator(
|
||||
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 @@ fn codegen_terminator(
|
||||
ref destination,
|
||||
cleanup,
|
||||
from_hir_call: _,
|
||||
fn_span,
|
||||
} => {
|
||||
self.codegen_call_terminator(
|
||||
helper,
|
||||
@@ -1025,6 +1032,7 @@ fn codegen_terminator(
|
||||
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 @@ pub fn struct_help(&self, msg: &str) -> DiagnosticBuilder<'_> {
|
||||
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 @@ pub fn expr_method_call(
|
||||
) -> 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 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
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 @@ fn visit_body(&mut self, body: &'tcx Body<'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 @@ pub fn need_type_info_err(
|
||||
// 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 @@
|
||||
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 @@
|
||||
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 @@ fn is_dangerous_init(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>) -> Option<I
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
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 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||
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 @@ fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
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 @@ fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
destination: dest,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
fn_span,
|
||||
}
|
||||
}
|
||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||
|
||||
@@ -492,6 +492,7 @@ fn super_terminator_kind(&mut self,
|
||||
destination,
|
||||
cleanup: _,
|
||||
from_hir_call: _,
|
||||
fn_span: _
|
||||
} => {
|
||||
self.visit_operand(func, source_location);
|
||||
for arg in args {
|
||||
|
||||
@@ -605,7 +605,8 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
||||
// 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 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
||||
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 @@ fn print_def_path(
|
||||
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 @@ fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Locat
|
||||
destination,
|
||||
cleanup: _,
|
||||
from_hir_call: _,
|
||||
fn_span: _,
|
||||
} => {
|
||||
self.consume_operand(location, func);
|
||||
for arg in args {
|
||||
|
||||
@@ -699,6 +699,7 @@ fn visit_terminator_before_primary_effect(
|
||||
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 @@
|
||||
|
||||
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 @@ pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> {
|
||||
|
||||
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 @@ pub(crate) fn dump_mir(&self, out: &mut dyn Write) -> io::Result<()> {
|
||||
/// 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 @@ fn for_each_constraint(
|
||||
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 @@ fn join_state_into_successors_of<A>(
|
||||
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 @@ fn gather_terminator(&mut self, term: &Terminator<'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 @@ pub(super) fn eval_terminator(
|
||||
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 @@ fn make_clone_call(
|
||||
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 @@ fn promote_temp(&mut self, temp: Local) -> Local {
|
||||
};
|
||||
|
||||
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 @@ fn promote_temp(&mut self, temp: Local) -> Local {
|
||||
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 @@ fn destructor_call_block(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> Bas
|
||||
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 @@ fn unelaborated_free_block(
|
||||
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 @@ fn write_extra<'tcx, F>(tcx: TyCtxt<'tcx>, write: &mut dyn Write, mut visit_op:
|
||||
}
|
||||
|
||||
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 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||
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 @@ fn non_scalar_compare(
|
||||
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 @@
|
||||
// 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 @@ fn parse_and_disallow_postfix_after_cast(
|
||||
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 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
|
||||
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 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
|
||||
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 @@ fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNod
|
||||
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 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'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 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
|
||||
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 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'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 @@ pub fn note_without_error(&self, msg: &str) {
|
||||
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 @@ fn drop(&mut self) {
|
||||
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 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St
|
||||
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 @@ pub fn check_ref(
|
||||
};
|
||||
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 @@ fn check_expr_with_expectation_and_needs(
|
||||
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 @@ fn check_expr_kind(
|
||||
}
|
||||
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 @@ fn check_argument_types(
|
||||
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 @@ pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
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 @@ pub fn new(
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
@@ -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),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -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 @@
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
|
||||
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 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
}
|
||||
}
|
||||
},
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
|
||||
}
|
||||
|
||||
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 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
|
||||
}
|
||||
}
|
||||
},
|
||||
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 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
|
||||
) = &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 @@ fn same_mutex(&self, cx: &LateContext<'_, '_>, op_mutex: &Expr<'_>) -> bool {
|
||||
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
|
||||
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 @@ enum Heuristic {
|
||||
|
||||
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 @@ fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Finiteness {
|
||||
|
||||
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 is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef<'_>, name: &str) -
|
||||
}
|
||||
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
|
||||
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 print_offset(start_str: &str, inline_offset: &Offset) -> String {
|
||||
|
||||
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 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
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 @@ fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) {
|
||||
}
|
||||
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr<'_>) {
|
||||
}
|
||||
}
|
||||
},
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>)
|
||||
}
|
||||
|
||||
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 check_general_case<'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 check_general_case<'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 get_arg_root<'a>(cx: &LateContext<'_, '_>, arg: &'a hir::Expr<'a>) -> &'a hir
|
||||
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 may_slice<'a>(cx: &LateContext<'_, 'a>, ty: Ty<'a>) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr<'_>) {
|
||||
);
|
||||
}
|
||||
},
|
||||
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 @@
|
||||
|
||||
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 @@
|
||||
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 @@
|
||||
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 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
}
|
||||
|
||||
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 @@
|
||||
|
||||
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
Reference in New Issue
Block a user