Skip to content

Commit

Permalink
Auto merge of #73246 - Dylan-DPC:rollup-xnm531f, r=Dylan-DPC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 11, 2020
2 parents 50c0192 + 8650df5 commit a37c32e
Show file tree
Hide file tree
Showing 118 changed files with 534 additions and 232 deletions.
2 changes: 1 addition & 1 deletion src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ impl Step for Clippy {

builder.add_rustc_lib_path(compiler, &mut cargo);

try_run(builder, &mut cargo.into());
builder.run(&mut cargo.into());
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/doc/unstable-book/src/library-features/asm.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
```

Expand Down Expand Up @@ -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.

Expand Down
4 changes: 3 additions & 1 deletion src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_ast/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_ast_lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let f = self.lower_expr(f);
hir::ExprKind::Call(f, self.lower_exprs(args))
}
ExprKind::MethodCall(ref seg, ref args) => {
ExprKind::MethodCall(ref seg, ref args, span) => {
let hir_seg = self.arena.alloc(self.lower_path_segment(
e.span,
seg,
Expand All @@ -50,7 +50,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
None,
));
let args = self.lower_exprs(args);
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args, span)
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {
let binop = self.lower_binop(binop);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_pretty/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,7 @@ impl<'a> State<'a> {
ast::ExprKind::Call(ref func, ref args) => {
self.print_expr_call(func, &args[..]);
}
ast::ExprKind::MethodCall(ref segment, ref args) => {
ast::ExprKind::MethodCall(ref segment, ref args, _) => {
self.print_expr_method_call(segment, &args[..]);
}
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
Expand Down
47 changes: 29 additions & 18 deletions src/librustc_builtin_macros/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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();
}
_ => {
Expand All @@ -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();
}
}
Expand All @@ -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)),
Expand Down
22 changes: 18 additions & 4 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, Mo
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{FatalError, Handler};
use rustc_errors::{FatalError, Handler, Level};
use rustc_fs_util::{link_or_copy, path_to_c_string};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
Expand Down Expand Up @@ -242,6 +242,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
fn report_inline_asm(
cgcx: &CodegenContext<LlvmCodegenBackend>,
msg: String,
level: llvm::DiagnosticLevel,
mut cookie: c_uint,
source: Option<(String, Vec<InnerSpan>)>,
) {
Expand All @@ -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) {
Expand All @@ -264,6 +270,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
// diagnostics.
let mut have_source = false;
let mut buffer = String::new();
let mut level = llvm::DiagnosticLevel::Error;
let mut loc = 0;
let mut ranges = [0; 8];
let mut num_ranges = ranges.len() / 2;
Expand All @@ -273,6 +280,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
diag,
msg,
buffer,
&mut level,
&mut loc,
ranges.as_mut_ptr(),
&mut num_ranges,
Expand All @@ -290,7 +298,7 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
(buffer, spans)
});

report_inline_asm(cgcx, msg, cookie, source);
report_inline_asm(cgcx, msg, level, cookie, source);
}

unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
Expand All @@ -301,7 +309,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void

match llvm::diagnostic::Diagnostic::unpack(info) {
llvm::diagnostic::InlineAsm(inline) => {
report_inline_asm(cgcx, llvm::twine_to_string(inline.message), inline.cookie, None);
report_inline_asm(
cgcx,
llvm::twine_to_string(inline.message),
inline.level,
inline.cookie,
None,
);
}

llvm::diagnostic::Optimization(opt) => {
Expand Down
12 changes: 10 additions & 2 deletions src/librustc_codegen_llvm/llvm/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl OptimizationDiagnostic<'ll> {

#[derive(Copy, Clone)]
pub struct InlineAsmDiagnostic<'ll> {
pub level: super::DiagnosticLevel,
pub cookie: c_uint,
pub message: &'ll Twine,
pub instruction: Option<&'ll Value>,
Expand All @@ -98,10 +99,17 @@ impl InlineAsmDiagnostic<'ll> {
let mut cookie = 0;
let mut message = None;
let mut instruction = None;
let mut level = super::DiagnosticLevel::Error;

super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut cookie, &mut message, &mut instruction);
super::LLVMRustUnpackInlineAsmDiagnostic(
di,
&mut level,
&mut cookie,
&mut message,
&mut instruction,
);

InlineAsmDiagnostic { cookie, message: message.unwrap(), instruction }
InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction }
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -2054,6 +2065,7 @@ extern "C" {

pub fn LLVMRustUnpackInlineAsmDiagnostic(
DI: &'a DiagnosticInfo,
level_out: &mut DiagnosticLevel,
cookie_out: &mut c_uint,
message_out: &mut Option<&'a Twine>,
instruction_out: &mut Option<&'a Value>,
Expand All @@ -2074,6 +2086,7 @@ extern "C" {
d: &SMDiagnostic,
message_out: &RustString,
buffer_out: &RustString,
level_out: &mut DiagnosticLevel,
loc_out: &mut c_uint,
ranges_out: *mut c_uint,
num_ranges: &mut usize,
Expand Down
20 changes: 13 additions & 7 deletions src/librustc_codegen_ssa/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1551,7 +1551,7 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>

enum SharedEmitterMessage {
Diagnostic(Diagnostic),
InlineAsmError(u32, String, Option<(String, Vec<InnerSpan>)>),
InlineAsmError(u32, String, Level, Option<(String, Vec<InnerSpan>)>),
AbortIfErrors,
Fatal(String),
}
Expand All @@ -1576,9 +1576,10 @@ impl SharedEmitter {
&self,
cookie: u32,
msg: String,
level: Level,
source: Option<(String, Vec<InnerSpan>)>,
) {
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, source)));
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
}

pub fn fatal(&self, msg: &str) {
Expand Down Expand Up @@ -1631,16 +1632,21 @@ impl SharedEmitterMain {
}
handler.emit_diagnostic(&d);
}
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, source)) => {
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
let msg = msg.strip_prefix("error: ").unwrap_or(&msg);

let mut err = match level {
Level::Error => sess.struct_err(&msg),
Level::Warning => sess.struct_warn(&msg),
Level::Note => sess.struct_note_without_error(&msg),
_ => bug!("Invalid inline asm diagnostic level"),
};

// If the cookie is 0 then we don't have span information.
let mut err = if cookie == 0 {
sess.struct_err(&msg)
} else {
if cookie != 0 {
let pos = BytePos::from_u32(cookie);
let span = Span::with_root_ctxt(pos, pos);
sess.struct_span_err(span, &msg)
err.set_span(span);
};

// Point to the generated assembly if it is available.
Expand Down
Loading

0 comments on commit a37c32e

Please sign in to comment.