Make a fake body to store typeck results for global_asm
This commit is contained in:
parent
37060aae13
commit
6ba39f7dc7
37 changed files with 244 additions and 232 deletions
|
@ -482,15 +482,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}),
|
||||
}
|
||||
}
|
||||
thir::InlineAsmOperand::SymFn { value, span } => {
|
||||
mir::InlineAsmOperand::SymFn {
|
||||
value: Box::new(ConstOperand {
|
||||
span,
|
||||
user_ty: None,
|
||||
const_: value,
|
||||
}),
|
||||
}
|
||||
}
|
||||
thir::InlineAsmOperand::SymFn { value } => mir::InlineAsmOperand::SymFn {
|
||||
value: Box::new(this.as_constant(&this.thir[value])),
|
||||
},
|
||||
thir::InlineAsmOperand::SymStatic { def_id } => {
|
||||
mir::InlineAsmOperand::SymStatic { def_id }
|
||||
}
|
||||
|
@ -518,10 +512,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let asm_macro = match asm_macro {
|
||||
AsmMacro::Asm => InlineAsmMacro::Asm,
|
||||
AsmMacro::GlobalAsm => {
|
||||
span_bug!(expr_span, "unexpected global_asm! in inline asm")
|
||||
}
|
||||
AsmMacro::Asm | AsmMacro::GlobalAsm => InlineAsmMacro::Asm,
|
||||
AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
|
||||
};
|
||||
|
||||
|
|
|
@ -61,7 +61,9 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
|
|||
Ok((thir, expr)) => {
|
||||
let build_mir = |thir: &Thir<'tcx>| match thir.body_type {
|
||||
thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, thir, expr, fn_sig),
|
||||
thir::BodyTy::Const(ty) => construct_const(tcx, def, thir, expr, ty),
|
||||
thir::BodyTy::Const(ty) | thir::BodyTy::GlobalAsm(ty) => {
|
||||
construct_const(tcx, def, thir, expr, ty)
|
||||
}
|
||||
};
|
||||
|
||||
// this must run before MIR dump, because
|
||||
|
@ -576,6 +578,7 @@ fn construct_const<'a, 'tcx>(
|
|||
let span = tcx.def_span(def);
|
||||
(span, span)
|
||||
}
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::GlobalAsm { .. }, span, .. }) => (*span, *span),
|
||||
_ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::borrow::Cow;
|
|||
use std::mem;
|
||||
use std::ops::Bound;
|
||||
|
||||
use rustc_ast::AsmMacro;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::DiagArgValue;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
@ -559,7 +560,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
ExprKind::InlineAsm(box InlineAsmExpr {
|
||||
asm_macro: _,
|
||||
asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
|
||||
ref operands,
|
||||
template: _,
|
||||
options: _,
|
||||
|
@ -583,7 +584,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
}
|
||||
Out { expr: None, reg: _, late: _ }
|
||||
| Const { value: _, span: _ }
|
||||
| SymFn { value: _, span: _ }
|
||||
| SymFn { value: _ }
|
||||
| SymStatic { def_id: _ } => {}
|
||||
Label { block } => {
|
||||
// Label blocks are safe context.
|
||||
|
|
|
@ -739,13 +739,8 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
|
||||
InlineAsmOperand::Const { value, span }
|
||||
}
|
||||
hir::InlineAsmOperand::SymFn { ref anon_const } => {
|
||||
let value =
|
||||
mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
|
||||
.instantiate_identity();
|
||||
let span = tcx.def_span(anon_const.def_id);
|
||||
|
||||
InlineAsmOperand::SymFn { value, span }
|
||||
hir::InlineAsmOperand::SymFn { expr } => {
|
||||
InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
|
||||
}
|
||||
hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
|
||||
InlineAsmOperand::SymStatic { def_id }
|
||||
|
|
|
@ -76,23 +76,29 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
let hir = tcx.hir();
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def);
|
||||
|
||||
let body_type = if tcx.hir_body_owner_kind(def).is_fn_or_closure() {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
// types/lifetimes replaced)
|
||||
BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id])
|
||||
} else {
|
||||
// Get the revealed type of this const. This is *not* the adjusted
|
||||
// type of its body, which may be a subtype of this type. For
|
||||
// example:
|
||||
//
|
||||
// fn foo(_: &()) {}
|
||||
// static X: fn(&'static ()) = foo;
|
||||
//
|
||||
// The adjusted type of the body of X is `for<'a> fn(&'a ())` which
|
||||
// is not the same as the type of X. We need the type of the return
|
||||
// place to be the type of the constant because NLL typeck will
|
||||
// equate them.
|
||||
BodyTy::Const(typeck_results.node_type(hir_id))
|
||||
let body_type = match tcx.hir_body_owner_kind(def) {
|
||||
rustc_hir::BodyOwnerKind::Fn | rustc_hir::BodyOwnerKind::Closure => {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
// types/lifetimes replaced)
|
||||
BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id])
|
||||
}
|
||||
rustc_hir::BodyOwnerKind::Const { .. } | rustc_hir::BodyOwnerKind::Static(_) => {
|
||||
// Get the revealed type of this const. This is *not* the adjusted
|
||||
// type of its body, which may be a subtype of this type. For
|
||||
// example:
|
||||
//
|
||||
// fn foo(_: &()) {}
|
||||
// static X: fn(&'static ()) = foo;
|
||||
//
|
||||
// The adjusted type of the body of X is `for<'a> fn(&'a ())` which
|
||||
// is not the same as the type of X. We need the type of the return
|
||||
// place to be the type of the constant because NLL typeck will
|
||||
// equate them.
|
||||
BodyTy::Const(typeck_results.node_type(hir_id))
|
||||
}
|
||||
rustc_hir::BodyOwnerKind::GlobalAsm => {
|
||||
BodyTy::GlobalAsm(typeck_results.node_type(hir_id))
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
|
|
|
@ -921,10 +921,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
|
||||
print_indented!(self, "}", depth_lvl + 1);
|
||||
}
|
||||
InlineAsmOperand::SymFn { value, span } => {
|
||||
InlineAsmOperand::SymFn { value } => {
|
||||
print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl);
|
||||
print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1);
|
||||
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
|
||||
print_indented!(self, "value: ", depth_lvl + 1);
|
||||
self.print_expr(*value, depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl + 1);
|
||||
}
|
||||
InlineAsmOperand::SymStatic { def_id } => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue