diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 29e3f7132766e..91c19e269a7f1 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -1086,10 +1086,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprKind::Ret(ref optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression);
}
- ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
- for expr in outputs.iter().chain(inputs.iter()) {
- visitor.visit_expr(expr)
- }
+ ExprKind::InlineAsm(ref asm) => {
+ walk_list!(visitor, visit_expr, &asm.outputs_exprs);
+ walk_list!(visitor, visit_expr, &asm.inputs_exprs);
}
ExprKind::Yield(ref subexpression, _) => {
visitor.visit_expr(subexpression);
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index d5d3ff0db2ebc..929dce7aa0ff1 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -966,7 +966,7 @@ impl LoweringContext<'_> {
}
fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind {
- let hir_asm = hir::InlineAsm {
+ let inner = hir::InlineAsmInner {
inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
outputs: asm.outputs
.iter()
@@ -984,18 +984,18 @@ impl LoweringContext<'_> {
alignstack: asm.alignstack,
dialect: asm.dialect,
};
-
- let outputs = asm.outputs
- .iter()
- .map(|out| self.lower_expr(&out.expr))
- .collect();
-
- let inputs = asm.inputs
- .iter()
- .map(|&(_, ref input)| self.lower_expr(input))
- .collect();
-
- hir::ExprKind::InlineAsm(P(hir_asm), outputs, inputs)
+ let hir_asm = hir::InlineAsm {
+ inner,
+ inputs_exprs: asm.inputs
+ .iter()
+ .map(|&(_, ref input)| self.lower_expr(input))
+ .collect(),
+ outputs_exprs: asm.outputs
+ .iter()
+ .map(|out| self.lower_expr(&out.expr))
+ .collect(),
+ };
+ hir::ExprKind::InlineAsm(P(hir_asm))
}
fn lower_field(&mut self, f: &Field) -> hir::Field {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 465673082e50a..17b13dae37fdb 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1457,7 +1457,7 @@ pub struct Expr {
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert_size!(Expr, 72);
+static_assert_size!(Expr, 64);
impl Expr {
pub fn precedence(&self) -> ExprPrecedence {
@@ -1656,7 +1656,7 @@ pub enum ExprKind {
Ret(Option
>),
/// Inline assembly (from `asm!`), with its outputs and inputs.
- InlineAsm(P, HirVec, HirVec),
+ InlineAsm(P),
/// A struct or struct-like variant literal expression.
///
@@ -2063,7 +2063,7 @@ pub struct InlineAsmOutput {
// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
// it needs to be `Clone` and use plain `Vec` instead of `HirVec`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct InlineAsm {
+pub struct InlineAsmInner {
pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: Vec,
@@ -2074,6 +2074,13 @@ pub struct InlineAsm {
pub dialect: AsmDialect,
}
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
+pub struct InlineAsm {
+ pub inner: InlineAsmInner,
+ pub outputs_exprs: HirVec,
+ pub inputs_exprs: HirVec,
+}
+
/// Represents a parameter in a function header.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Param {
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index ba618a1da8cef..4cbe0e8099126 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1365,14 +1365,15 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
}
}
- hir::ExprKind::InlineAsm(ref a, ref outputs, ref inputs) => {
+ hir::ExprKind::InlineAsm(ref a) => {
+ let i = &a.inner;
self.s.word("asm!");
self.popen();
- self.print_string(&a.asm.as_str(), a.asm_str_style);
+ self.print_string(&i.asm.as_str(), i.asm_str_style);
self.word_space(":");
let mut out_idx = 0;
- self.commasep(Inconsistent, &a.outputs, |s, out| {
+ self.commasep(Inconsistent, &i.outputs, |s, out| {
let constraint = out.constraint.as_str();
let mut ch = constraint.chars();
match ch.next() {
@@ -1383,7 +1384,7 @@ impl<'a> State<'a> {
_ => s.print_string(&constraint, ast::StrStyle::Cooked),
}
s.popen();
- s.print_expr(&outputs[out_idx]);
+ s.print_expr(&a.outputs_exprs[out_idx]);
s.pclose();
out_idx += 1;
});
@@ -1391,28 +1392,28 @@ impl<'a> State<'a> {
self.word_space(":");
let mut in_idx = 0;
- self.commasep(Inconsistent, &a.inputs, |s, co| {
+ self.commasep(Inconsistent, &i.inputs, |s, co| {
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
s.popen();
- s.print_expr(&inputs[in_idx]);
+ s.print_expr(&a.inputs_exprs[in_idx]);
s.pclose();
in_idx += 1;
});
self.s.space();
self.word_space(":");
- self.commasep(Inconsistent, &a.clobbers, |s, co| {
+ self.commasep(Inconsistent, &i.clobbers, |s, co| {
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
});
let mut options = vec![];
- if a.volatile {
+ if i.volatile {
options.push("volatile");
}
- if a.alignstack {
+ if i.alignstack {
options.push("alignstack");
}
- if a.dialect == ast::AsmDialect::Intel {
+ if i.dialect == ast::AsmDialect::Intel {
options.push("intel");
}
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index bb7ac5d8dbe1a..4571f551aa4d6 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -283,15 +283,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
self.borrow_expr(&base, bk);
}
- hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
- for (o, output) in ia.outputs.iter().zip(outputs) {
+ hir::ExprKind::InlineAsm(ref ia) => {
+ for (o, output) in ia.inner.outputs.iter().zip(&ia.outputs_exprs) {
if o.is_indirect {
self.consume_expr(output);
} else {
self.mutate_expr(output);
}
}
- self.consume_exprs(inputs);
+ self.consume_exprs(&ia.inputs_exprs);
}
hir::ExprKind::Continue(..) |
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 79468b68055d4..b7d0f538db5dc 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -6,7 +6,7 @@
use crate::hir::def::{CtorKind, Namespace};
use crate::hir::def_id::DefId;
-use crate::hir::{self, InlineAsm as HirInlineAsm};
+use crate::hir;
use crate::mir::interpret::{PanicInfo, Scalar};
use crate::mir::visit::MirVisitable;
use crate::ty::adjustment::PointerCast;
@@ -1638,7 +1638,7 @@ pub enum FakeReadCause {
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct InlineAsm<'tcx> {
- pub asm: HirInlineAsm,
+ pub asm: hir::InlineAsmInner,
pub outputs: Box<[Place<'tcx>]>,
pub inputs: Box<[(Span, Operand<'tcx>)]>,
}
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index ccac7720914fc..8fbd2e4e6b157 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -301,7 +301,7 @@ CloneTypeFoldableAndLiftImpls! {
::syntax_pos::symbol::Symbol,
crate::hir::def::Res,
crate::hir::def_id::DefId,
- crate::hir::InlineAsm,
+ crate::hir::InlineAsmInner,
crate::hir::MatchSource,
crate::hir::Mutability,
crate::hir::Unsafety,
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index b68ee2cb44d4b..abdd2e3e8dbd7 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -17,7 +17,7 @@ use libc::{c_uint, c_char};
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn codegen_inline_asm(
&mut self,
- ia: &hir::InlineAsm,
+ ia: &hir::InlineAsmInner,
outputs: Vec>,
mut inputs: Vec<&'ll Value>,
span: Span,
diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs
index c9e1ed86e97e0..612bce2d95854 100644
--- a/src/librustc_codegen_ssa/traits/asm.rs
+++ b/src/librustc_codegen_ssa/traits/asm.rs
@@ -1,13 +1,13 @@
use super::BackendTypes;
use crate::mir::place::PlaceRef;
-use rustc::hir::{GlobalAsm, InlineAsm};
+use rustc::hir::{GlobalAsm, InlineAsmInner};
use syntax_pos::Span;
pub trait AsmBuilderMethods<'tcx>: BackendTypes {
/// Take an inline assembly expression and splat it out via LLVM
fn codegen_inline_asm(
&mut self,
- ia: &InlineAsm,
+ ia: &InlineAsmInner,
outputs: Vec>,
inputs: Vec,
span: Span,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 92c9c702c7a83..f25e4b0ae8639 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -533,11 +533,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
convert_path_expr(cx, expr, res)
}
- hir::ExprKind::InlineAsm(ref asm, ref outputs, ref inputs) => {
+ hir::ExprKind::InlineAsm(ref asm) => {
ExprKind::InlineAsm {
- asm,
- outputs: outputs.to_ref(),
- inputs: inputs.to_ref(),
+ asm: &asm.inner,
+ outputs: asm.outputs_exprs.to_ref(),
+ inputs: asm.inputs_exprs.to_ref(),
}
}
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index b43042f2b1745..78e3a17d76632 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -93,6 +93,10 @@ pub enum StmtKind<'tcx> {
},
}
+// `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<'_>, 168);
+
/// The Hair trait implementor lowers their expressions (`&'tcx H::Expr`)
/// into instances of this `Expr` enum. This lowering can be done
/// basically as lazily or as eagerly as desired: every recursive
@@ -264,7 +268,7 @@ pub enum ExprKind<'tcx> {
user_ty: Option>>,
},
InlineAsm {
- asm: &'tcx hir::InlineAsm,
+ asm: &'tcx hir::InlineAsmInner,
outputs: Vec>,
inputs: Vec>
},
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index 6847e45458a0b..8d7a038812269 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -1184,17 +1184,21 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&e, succ)
}
- hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
+ hir::ExprKind::InlineAsm(ref asm) => {
+ let ia = &asm.inner;
+ let outputs = &asm.outputs_exprs;
+ let inputs = &asm.inputs_exprs;
let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
- // see comment on places
- // in propagate_through_place_components()
- if o.is_indirect {
- self.propagate_through_expr(output, succ)
- } else {
- let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
- let succ = self.write_place(output, succ, acc);
- self.propagate_through_place_components(output, succ)
- }});
+ // see comment on places
+ // in propagate_through_place_components()
+ if o.is_indirect {
+ self.propagate_through_expr(output, succ)
+ } else {
+ let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
+ let succ = self.write_place(output, succ, acc);
+ self.propagate_through_place_components(output, succ)
+ }
+ });
// Inputs are executed first. Propagate last because of rev order
self.propagate_through_exprs(inputs, succ)
@@ -1395,13 +1399,13 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) {
}
}
- hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
- for input in inputs {
+ hir::ExprKind::InlineAsm(ref asm) => {
+ for input in &asm.inputs_exprs {
this.visit_expr(input);
}
// Output operands must be places
- for (o, output) in ia.outputs.iter().zip(outputs) {
+ for (o, output) in asm.inner.outputs.iter().zip(&asm.outputs_exprs) {
if !o.is_indirect {
this.check_place(output);
}
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 0ba56ba5b3ae9..163412f6a16f5 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -244,8 +244,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::Path(ref qpath) => {
self.check_expr_path(qpath, expr)
}
- ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
- for expr in outputs.iter().chain(inputs.iter()) {
+ ExprKind::InlineAsm(ref asm) => {
+ for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
self.check_expr(expr);
}
tcx.mk_unit()