Skip to content

Commit a227994

Browse files
authored
Merge pull request rust-lang#202 from rust-lang/fix/recursive-types
Cleanup regarding handling of recursive types
2 parents 22e4f18 + 5f630f3 commit a227994

File tree

9 files changed

+30
-41
lines changed

9 files changed

+30
-41
lines changed

src/asm.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
156156
use ConstraintOrRegister::*;
157157

158158
let (constraint, ty) = match (reg_to_gcc(reg), place) {
159-
(Constraint(constraint), Some(place)) => (constraint, place.layout.gcc_type(self.cx, false)),
159+
(Constraint(constraint), Some(place)) => (constraint, place.layout.gcc_type(self.cx)),
160160
// When `reg` is a class and not an explicit register but the out place is not specified,
161161
// we need to create an unused output variable to assign the output to. This var
162162
// needs to be of a type that's "compatible" with the register class, but specific type
@@ -225,7 +225,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
225225
// This decision is also backed by the fact that LLVM needs in and out
226226
// values to be of *exactly the same type*, not just "compatible".
227227
// I'm not sure if GCC is so picky too, but better safe than sorry.
228-
let ty = in_value.layout.gcc_type(self.cx, false);
228+
let ty = in_value.layout.gcc_type(self.cx);
229229
let tmp_var = self.current_func().new_local(None, ty, "output_register");
230230

231231
// If the out_place is None (i.e `inout(reg) _` syntax was used), we translate
@@ -285,7 +285,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
285285
continue
286286
};
287287

288-
let ty = out_place.layout.gcc_type(self.cx, false);
288+
let ty = out_place.layout.gcc_type(self.cx);
289289
let tmp_var = self.current_func().new_local(None, ty, "output_register");
290290
tmp_var.set_register_name(reg_name);
291291

@@ -305,7 +305,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
305305
// `in("explicit register") var`
306306
InlineAsmOperandRef::In { reg, value } => {
307307
if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) {
308-
let ty = value.layout.gcc_type(self.cx, false);
308+
let ty = value.layout.gcc_type(self.cx);
309309
let reg_var = self.current_func().new_local(None, ty, "input_register");
310310
reg_var.set_register_name(reg_name);
311311
self.llbb().add_assignment(None, reg_var, value.immediate());
@@ -324,7 +324,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
324324
InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => {
325325
if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) {
326326
// See explanation in the first pass.
327-
let ty = in_value.layout.gcc_type(self.cx, false);
327+
let ty = in_value.layout.gcc_type(self.cx);
328328
let tmp_var = self.current_func().new_local(None, ty, "output_register");
329329
tmp_var.set_register_name(reg_name);
330330

src/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
745745
}
746746
else if place.layout.is_gcc_immediate() {
747747
let load = self.load(
748-
place.layout.gcc_type(self, false),
748+
place.layout.gcc_type(self),
749749
place.llval,
750750
place.align,
751751
);
@@ -756,7 +756,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
756756
}
757757
else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
758758
let b_offset = a.size(self).align_to(b.align(self).abi);
759-
let pair_type = place.layout.gcc_type(self, false);
759+
let pair_type = place.layout.gcc_type(self);
760760

761761
let mut load = |i, scalar: &abi::Scalar, align| {
762762
let llptr = self.struct_gep(pair_type, place.llval, i as u64);

src/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
132132
});
133133
let len = s_str.len();
134134
let cs = self.const_ptrcast(str_global.get_address(None),
135-
self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self, true)),
135+
self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self)),
136136
);
137137
(cs, self.const_usize(len as u64))
138138
}
@@ -235,7 +235,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
235235

236236
fn from_const_alloc(&self, layout: TyAndLayout<'tcx>, alloc: ConstAllocation<'tcx>, offset: Size) -> PlaceRef<'tcx, RValue<'gcc>> {
237237
assert_eq!(alloc.inner().align, layout.align.abi);
238-
let ty = self.type_ptr_to(layout.gcc_type(self, true));
238+
let ty = self.type_ptr_to(layout.gcc_type(self));
239239
let value =
240240
if layout.size == Size::ZERO {
241241
let value = self.const_usize(alloc.inner().align.bytes());

src/consts.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
8080

8181
let instance = Instance::mono(self.tcx, def_id);
8282
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
83-
let gcc_type = self.layout_of(ty).gcc_type(self, true);
83+
let gcc_type = self.layout_of(ty).gcc_type(self);
8484

8585
// TODO(antoyo): set alignment.
8686

@@ -211,7 +211,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
211211
let global =
212212
if let Some(def_id) = def_id.as_local() {
213213
let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
214-
let llty = self.layout_of(ty).gcc_type(self, true);
214+
let llty = self.layout_of(ty).gcc_type(self);
215215
// FIXME: refactor this to work without accessing the HIR
216216
let global = match self.tcx.hir().get(id) {
217217
Node::Item(&hir::Item { span, kind: hir::ItemKind::Static(..), .. }) => {
@@ -356,7 +356,7 @@ pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id
356356

357357
fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str, span: Span) -> LValue<'gcc> {
358358
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
359-
let llty = cx.layout_of(ty).gcc_type(cx, true);
359+
let llty = cx.layout_of(ty).gcc_type(cx);
360360
if let Some(linkage) = attrs.linkage {
361361
// If this is a static with a linkage specified, then we need to handle
362362
// it a little specially. The typesystem prevents things like &T and
@@ -365,7 +365,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg
365365
// that the static actually has a null value.
366366
let llty2 =
367367
if let ty::RawPtr(ref mt) = ty.kind() {
368-
cx.layout_of(mt.ty).gcc_type(cx, true)
368+
cx.layout_of(mt.ty).gcc_type(cx)
369369
}
370370
else {
371371
cx.sess().span_fatal(

src/context.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::cell::{Cell, RefCell};
22

3-
use gccjit::{Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, RValue, Struct, Type};
3+
use gccjit::{Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, RValue, Type};
44
use rustc_codegen_ssa::base::wants_msvc_seh;
55
use rustc_codegen_ssa::traits::{
66
BackendTypes,
@@ -78,8 +78,6 @@ pub struct CodegenCx<'gcc, 'tcx> {
7878

7979
pub struct_types: RefCell<FxHashMap<Vec<Type<'gcc>>, Type<'gcc>>>,
8080

81-
pub types_with_fields_to_set: RefCell<FxHashMap<Type<'gcc>, (Struct<'gcc>, TyAndLayout<'tcx>)>>,
82-
8381
/// Cache instances of monomorphic and polymorphic items
8482
pub instances: RefCell<FxHashMap<Instance<'tcx>, LValue<'gcc>>>,
8583
/// Cache function instances of monomorphic and polymorphic items
@@ -243,7 +241,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
243241
types: Default::default(),
244242
tcx,
245243
struct_types: Default::default(),
246-
types_with_fields_to_set: Default::default(),
247244
local_gen_sym_counter: Cell::new(0),
248245
eh_personality: Cell::new(None),
249246
pointee_infos: Default::default(),

src/intrinsic/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
9090
let name = tcx.item_name(def_id);
9191
let name_str = name.as_str();
9292

93-
let llret_ty = self.layout_of(ret_ty).gcc_type(self, true);
93+
let llret_ty = self.layout_of(ret_ty).gcc_type(self);
9494
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
9595

9696
let simple = get_simple_intrinsic(self, name);
@@ -389,7 +389,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
389389
/// Gets the LLVM type for a place of the original Rust type of
390390
/// this argument/return, i.e., the result of `type_of::type_of`.
391391
fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
392-
self.layout.gcc_type(cx, true)
392+
self.layout.gcc_type(cx)
393393
}
394394

395395
/// Stores a direct/indirect value described by this ArgAbi into a

src/mono_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
1515
let attrs = self.tcx.codegen_fn_attrs(def_id);
1616
let instance = Instance::mono(self.tcx, def_id);
1717
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
18-
let gcc_type = self.layout_of(ty).gcc_type(self, true);
18+
let gcc_type = self.layout_of(ty).gcc_type(self);
1919

2020
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
2121
let global = self.define_global(symbol_name, gcc_type, is_tls, attrs.link_section);

src/type_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
273273
assert_eq!(offset.align_to(padding_align) + padding, target_offset);
274274
result.push(cx.type_padding_filler(padding, padding_align));
275275

276-
result.push(field.gcc_type(cx, !field.ty.is_any_ptr())); // FIXME(antoyo): might need to check if the type is inside another, like Box<Type>.
276+
result.push(field.gcc_type(cx));
277277
offset = target_offset + field.size;
278278
prev_effective_align = effective_field_align;
279279
}

src/type_of.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
5050
}
5151
}
5252

53-
pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> {
53+
fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> {
5454
match layout.abi {
5555
Abi::Scalar(_) => bug!("handled elsewhere"),
5656
Abi::Vector { ref element, count } => {
@@ -114,7 +114,7 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa
114114
},
115115
}
116116
}
117-
FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx, true), count),
117+
FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx), count),
118118
FieldsShape::Arbitrary { .. } =>
119119
match name {
120120
None => {
@@ -133,7 +133,7 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa
133133
pub trait LayoutGccExt<'tcx> {
134134
fn is_gcc_immediate(&self) -> bool;
135135
fn is_gcc_scalar_pair(&self) -> bool;
136-
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, set_fields: bool) -> Type<'gcc>;
136+
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
137137
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
138138
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>;
139139
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc>;
@@ -168,8 +168,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
168168
/// with the inner-most trailing unsized field using the "minimal unit"
169169
/// of that field's type - this is useful for taking the address of
170170
/// that field and ensuring the struct has the right alignment.
171-
//TODO(antoyo): do we still need the set_fields parameter?
172-
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, set_fields: bool) -> Type<'gcc> {
171+
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
173172
if let Abi::Scalar(ref scalar) = self.abi {
174173
// Use a different cache for scalars because pointers to DSTs
175174
// can be either fat or thin (data pointers of fat pointers).
@@ -179,10 +178,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
179178
let ty =
180179
match *self.ty.kind() {
181180
ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
182-
cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx, set_fields))
181+
cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx))
183182
}
184183
ty::Adt(def, _) if def.is_box() => {
185-
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx, true))
184+
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx))
186185
}
187186
ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())),
188187
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
@@ -199,13 +198,6 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
199198
};
200199
let cached_type = cx.types.borrow().get(&(self.ty, variant_index)).cloned();
201200
if let Some(ty) = cached_type {
202-
let type_to_set_fields = cx.types_with_fields_to_set.borrow_mut().remove(&ty);
203-
if let Some((struct_type, layout)) = type_to_set_fields {
204-
// Since we might be trying to generate a type containing another type which is not
205-
// completely generated yet, we deferred setting the fields until now.
206-
let (fields, packed) = struct_fields(cx, layout);
207-
cx.set_struct_body(struct_type, &fields, packed);
208-
}
209201
return ty;
210202
}
211203

@@ -222,17 +214,17 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
222214
if let Some(v) = variant_index {
223215
layout = layout.for_variant(cx, v);
224216
}
225-
layout.gcc_type(cx, true)
217+
layout.gcc_type(cx)
226218
}
227219
else {
228220
uncached_gcc_type(cx, *self, &mut defer)
229221
};
230222

231223
cx.types.borrow_mut().insert((self.ty, variant_index), ty);
232224

233-
if let Some((ty, layout)) = defer {
225+
if let Some((deferred_ty, layout)) = defer {
234226
let (fields, packed) = struct_fields(cx, layout);
235-
cx.set_struct_body(ty, &fields, packed);
227+
cx.set_struct_body(deferred_ty, &fields, packed);
236228
}
237229

238230
ty
@@ -244,7 +236,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
244236
return cx.type_i1();
245237
}
246238
}
247-
self.gcc_type(cx, true)
239+
self.gcc_type(cx)
248240
}
249241

250242
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc> {
@@ -273,7 +265,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
273265
// pointee types, to avoid bitcasting every `OperandRef::deref`.
274266
match self.ty.kind() {
275267
ty::Ref(..) | ty::RawPtr(_) => {
276-
return self.field(cx, index).gcc_type(cx, true);
268+
return self.field(cx, index).gcc_type(cx);
277269
}
278270
// only wide pointer boxes are handled as pointers
279271
// thin pointer boxes with scalar allocators are handled by the general logic below
@@ -343,7 +335,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
343335

344336
impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
345337
fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> {
346-
layout.gcc_type(self, true)
338+
layout.gcc_type(self)
347339
}
348340

349341
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> {

0 commit comments

Comments
 (0)