Auto merge of #55087 - levex:e0669-improve-span, r=nagisa

rustc: improve E0669 span

E0669 refers to an operand that cannot be coerced into a single LLVM
value, unfortunately right now this uses the Span for the entire inline
assembly statement, which is less than ideal.

This commit preserves the Span from HIR, which lets us emit the error
using the Span for the operand itself in MIR.

r? @nagisa
cc/ @parched
This commit is contained in:
bors 2018-11-02 18:28:51 +00:00
commit 8b096314a6
9 changed files with 49 additions and 26 deletions

View File

@ -1751,7 +1751,7 @@ pub enum StatementKind<'tcx> {
InlineAsm {
asm: Box<InlineAsm>,
outputs: Box<[Place<'tcx>]>,
inputs: Box<[Operand<'tcx>]>,
inputs: Box<[(Span, Operand<'tcx>)]>,
},
/// Retag references in the given place, ensuring they got fresh tags. This is

View File

@ -409,7 +409,8 @@ macro_rules! make_mir_visitor {
location
);
}
for input in & $($mutability)* inputs[..] {
for (span, input) in & $($mutability)* inputs[..] {
self.visit_span(span);
self.visit_operand(input, location);
}
}

View File

@ -84,21 +84,18 @@ impl FunctionCx<'a, 'll, 'tcx> {
}).collect();
let input_vals = inputs.iter()
.try_fold(Vec::with_capacity(inputs.len()), |mut acc, input| {
.fold(Vec::with_capacity(inputs.len()), |mut acc, (span, input)| {
let op = self.codegen_operand(&bx, input);
if let OperandValue::Immediate(_) = op.val {
acc.push(op.immediate());
Ok(acc)
} else {
Err(op)
span_err!(bx.sess(), span.to_owned(), E0669,
"invalid value for constraint in inline assembly");
}
acc
});
if input_vals.is_err() {
span_err!(bx.sess(), statement.source_info.span, E0669,
"invalid value for constraint in inline assembly");
} else {
let input_vals = input_vals.unwrap();
if input_vals.len() == inputs.len() {
let res = asm::codegen_inline_asm(&bx, asm, outputs, input_vals);
if !res {
span_err!(bx.sess(), statement.source_info.span, E0668,

View File

@ -590,7 +590,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
);
}
}
for input in inputs.iter() {
for (_, input) in inputs.iter() {
self.consume_operand(context, (input, span), flow_state);
}
}

View File

@ -128,7 +128,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
);
}
}
for input in inputs.iter() {
for (_, input) in inputs.iter() {
self.consume_operand(context, input);
}
}

View File

@ -167,8 +167,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
.into_boxed_slice();
let inputs = inputs
.into_iter()
.map(|input| unpack!(block = this.as_local_operand(block, input)))
.collect::<Vec<_>>()
.map(|input| {
(
input.span(),
unpack!(block = this.as_local_operand(block, input)),
)
}).collect::<Vec<_>>()
.into_boxed_slice();
this.cfg.push(
block,

View File

@ -289,7 +289,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
self.gather_init(output, InitKind::Deep);
}
}
for input in inputs.iter() {
for (_, input) in inputs.iter() {
self.gather_operand(input);
}
}

View File

@ -21,6 +21,7 @@ fn main() {
issue_37437();
issue_40187();
issue_54067();
multiple_errors();
}
fn issue_37433() {
@ -55,3 +56,11 @@ fn issue_54067() {
asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
}
}
fn multiple_errors() {
let addr: (u32, u32) = (1, 2);
unsafe {
asm!("mov sp, $0"::"r"(addr), //~ ERROR E0669
"r"("hello e0669")); //~ ERROR E0669
}
}

View File

@ -1,33 +1,45 @@
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:28:9
--> $DIR/inline-asm-bad-operand.rs:29:24
|
LL | asm!("" :: "r"("")); //~ ERROR E0669
| ^^^^^^^^^^^^^^^^^^^^
| ^^
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:33:9
--> $DIR/inline-asm-bad-operand.rs:34:32
|
LL | asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:40:14
--> $DIR/inline-asm-bad-operand.rs:41:29
|
LL | unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:48:9
--> $DIR/inline-asm-bad-operand.rs:49:38
|
LL | asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:55:9
--> $DIR/inline-asm-bad-operand.rs:56:32
|
LL | asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
error: aborting due to 5 previous errors
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:63:32
|
LL | asm!("mov sp, $0"::"r"(addr), //~ ERROR E0669
| ^^^^
error[E0669]: invalid value for constraint in inline assembly
--> $DIR/inline-asm-bad-operand.rs:64:32
|
LL | "r"("hello e0669")); //~ ERROR E0669
| ^^^^^^^^^^^^^
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0669`.