]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_ssa/src/mono_item.rs
Rollup merge of #93757 - jackh726:gat-bug-tests, r=nikomatsakis
[rust.git] / compiler / rustc_codegen_ssa / src / mono_item.rs
1 use crate::base;
2 use crate::common;
3 use crate::traits::*;
4 use rustc_hir as hir;
5 use rustc_middle::mir::mono::MonoItem;
6 use rustc_middle::mir::mono::{Linkage, Visibility};
7 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
8
9 pub trait MonoItemExt<'a, 'tcx> {
10     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx);
11     fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
12         &self,
13         cx: &'a Bx::CodegenCx,
14         linkage: Linkage,
15         visibility: Visibility,
16     );
17     fn to_raw_string(&self) -> String;
18 }
19
20 impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
21     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
22         debug!(
23             "BEGIN IMPLEMENTING '{} ({})' in cgu {}",
24             self,
25             self.to_raw_string(),
26             cx.codegen_unit().name()
27         );
28
29         match *self {
30             MonoItem::Static(def_id) => {
31                 cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id));
32             }
33             MonoItem::GlobalAsm(item_id) => {
34                 let item = cx.tcx().hir().item(item_id);
35                 if let hir::ItemKind::GlobalAsm(ref asm) = item.kind {
36                     let operands: Vec<_> = asm
37                         .operands
38                         .iter()
39                         .map(|(op, op_sp)| match *op {
40                             hir::InlineAsmOperand::Const { ref anon_const } => {
41                                 let anon_const_def_id =
42                                     cx.tcx().hir().local_def_id(anon_const.hir_id).to_def_id();
43                                 let const_value =
44                                     cx.tcx().const_eval_poly(anon_const_def_id).unwrap_or_else(
45                                         |_| span_bug!(*op_sp, "asm const cannot be resolved"),
46                                     );
47                                 let ty = cx
48                                     .tcx()
49                                     .typeck_body(anon_const.body)
50                                     .node_type(anon_const.hir_id);
51                                 let string = common::asm_const_to_str(
52                                     cx.tcx(),
53                                     *op_sp,
54                                     const_value,
55                                     cx.layout_of(ty),
56                                 );
57                                 GlobalAsmOperandRef::Const { string }
58                             }
59                             _ => span_bug!(*op_sp, "invalid operand type for global_asm!"),
60                         })
61                         .collect();
62
63                     cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
64                 } else {
65                     span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
66                 }
67             }
68             MonoItem::Fn(instance) => {
69                 base::codegen_instance::<Bx>(&cx, instance);
70             }
71         }
72
73         debug!(
74             "END IMPLEMENTING '{} ({})' in cgu {}",
75             self,
76             self.to_raw_string(),
77             cx.codegen_unit().name()
78         );
79     }
80
81     fn predefine<Bx: BuilderMethods<'a, 'tcx>>(
82         &self,
83         cx: &'a Bx::CodegenCx,
84         linkage: Linkage,
85         visibility: Visibility,
86     ) {
87         debug!(
88             "BEGIN PREDEFINING '{} ({})' in cgu {}",
89             self,
90             self.to_raw_string(),
91             cx.codegen_unit().name()
92         );
93
94         let symbol_name = self.symbol_name(cx.tcx()).name;
95
96         debug!("symbol {}", &symbol_name);
97
98         match *self {
99             MonoItem::Static(def_id) => {
100                 cx.predefine_static(def_id, linkage, visibility, &symbol_name);
101             }
102             MonoItem::Fn(instance) => {
103                 cx.predefine_fn(instance, linkage, visibility, &symbol_name);
104             }
105             MonoItem::GlobalAsm(..) => {}
106         }
107
108         debug!(
109             "END PREDEFINING '{} ({})' in cgu {}",
110             self,
111             self.to_raw_string(),
112             cx.codegen_unit().name()
113         );
114     }
115
116     fn to_raw_string(&self) -> String {
117         match *self {
118             MonoItem::Fn(instance) => {
119                 format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize)
120             }
121             MonoItem::Static(id) => format!("Static({:?})", id),
122             MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
123         }
124     }
125 }