|
1 | 1 | use rustc_abi::{FieldIdx, VariantIdx}; |
2 | | -use rustc_middle::ty::layout::TyAndLayout; |
3 | 2 | use rustc_middle::ty::{ |
4 | | - AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, VariantDef, |
| 3 | + AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, |
5 | 4 | }; |
6 | 5 | use rustc_span::{bug, span_bug, sym}; |
7 | 6 |
|
8 | 7 | use crate::const_eval::CompileTimeMachine; |
9 | 8 | use crate::interpret::{ |
10 | | - CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Scalar, Writeable, interp_ok, |
| 9 | + CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Writeable, interp_ok, |
11 | 10 | }; |
12 | 11 |
|
13 | 12 | impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { |
14 | 13 | // FIXME(type_info): No semver considerations for now |
15 | 14 | pub(crate) fn write_adt_type_info( |
16 | 15 | &mut self, |
17 | 16 | place: &impl Writeable<'tcx, CtfeProvenance>, |
18 | | - adt: (Ty<'tcx>, AdtDef<'tcx>), |
19 | | - generics: &'tcx GenericArgs<'tcx>, |
| 17 | + adt_def: AdtDef<'tcx>, |
20 | 18 | ) -> InterpResult<'tcx, VariantIdx> { |
21 | | - let (adt_ty, adt_def) = adt; |
22 | 19 | let variant_idx = match adt_def.adt_kind() { |
23 | 20 | AdtKind::Struct => { |
24 | | - let (variant, variant_place) = self.project_downcast_named(place, sym::Struct)?; |
25 | | - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; |
26 | | - self.write_struct_type_info( |
27 | | - place, |
28 | | - (adt_ty, adt_def.variant(VariantIdx::ZERO)), |
29 | | - generics, |
30 | | - )?; |
| 21 | + let (variant, _) = self.project_downcast_named(place, sym::Struct)?; |
31 | 22 | variant |
32 | 23 | } |
33 | 24 | AdtKind::Union => { |
34 | | - let (variant, variant_place) = self.project_downcast_named(place, sym::Union)?; |
35 | | - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; |
36 | | - self.write_union_type_info( |
37 | | - place, |
38 | | - (adt_ty, adt_def.variant(VariantIdx::ZERO)), |
39 | | - generics, |
40 | | - )?; |
| 25 | + let (variant, _) = self.project_downcast_named(place, sym::Union)?; |
41 | 26 | variant |
42 | 27 | } |
43 | 28 | AdtKind::Enum => { |
44 | | - let (variant, variant_place) = self.project_downcast_named(place, sym::Enum)?; |
45 | | - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; |
46 | | - self.write_enum_type_info(place, adt, generics)?; |
| 29 | + let (variant, _) = self.project_downcast_named(place, sym::Enum)?; |
47 | 30 | variant |
48 | 31 | } |
49 | 32 | }; |
50 | 33 | interp_ok(variant_idx) |
51 | 34 | } |
52 | 35 |
|
53 | | - pub(crate) fn write_struct_type_info( |
54 | | - &mut self, |
55 | | - place: impl Writeable<'tcx, CtfeProvenance>, |
56 | | - struct_: (Ty<'tcx>, &'tcx VariantDef), |
57 | | - generics: &'tcx GenericArgs<'tcx>, |
58 | | - ) -> InterpResult<'tcx> { |
59 | | - let (struct_ty, struct_def) = struct_; |
60 | | - let struct_layout = self.layout_of(struct_ty)?; |
61 | | - |
62 | | - for (field_idx, field) in |
63 | | - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() |
64 | | - { |
65 | | - let field_place = self.project_field(&place, field_idx)?; |
66 | | - |
67 | | - match field.name { |
68 | | - sym::generics => self.write_generics(&field_place, generics)?, |
69 | | - sym::fields => { |
70 | | - self.write_variant_fields(field_place, struct_def, struct_layout, generics)? |
71 | | - } |
72 | | - sym::non_exhaustive => { |
73 | | - let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); |
74 | | - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? |
75 | | - } |
76 | | - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), |
77 | | - } |
78 | | - } |
79 | | - |
80 | | - interp_ok(()) |
81 | | - } |
82 | | - |
83 | | - pub(crate) fn write_union_type_info( |
84 | | - &mut self, |
85 | | - place: impl Writeable<'tcx, CtfeProvenance>, |
86 | | - union_: (Ty<'tcx>, &'tcx VariantDef), |
87 | | - generics: &'tcx GenericArgs<'tcx>, |
88 | | - ) -> InterpResult<'tcx> { |
89 | | - let (union_ty, union_def) = union_; |
90 | | - let union_layout = self.layout_of(union_ty)?; |
91 | | - |
92 | | - for (field_idx, field) in |
93 | | - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() |
94 | | - { |
95 | | - let field_place = self.project_field(&place, field_idx)?; |
96 | | - |
97 | | - match field.name { |
98 | | - sym::generics => self.write_generics(&field_place, generics)?, |
99 | | - sym::fields => { |
100 | | - self.write_variant_fields(field_place, union_def, union_layout, generics)? |
101 | | - } |
102 | | - sym::non_exhaustive => { |
103 | | - let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); |
104 | | - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? |
105 | | - } |
106 | | - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), |
107 | | - } |
108 | | - } |
109 | | - |
110 | | - interp_ok(()) |
111 | | - } |
112 | | - |
113 | | - pub(crate) fn write_enum_type_info( |
114 | | - &mut self, |
115 | | - place: impl Writeable<'tcx, CtfeProvenance>, |
116 | | - enum_: (Ty<'tcx>, AdtDef<'tcx>), |
117 | | - generics: &'tcx GenericArgs<'tcx>, |
118 | | - ) -> InterpResult<'tcx> { |
119 | | - let (enum_ty, enum_def) = enum_; |
120 | | - let enum_layout = self.layout_of(enum_ty)?; |
121 | | - |
122 | | - for (field_idx, field) in |
123 | | - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() |
124 | | - { |
125 | | - let field_place = self.project_field(&place, field_idx)?; |
126 | | - |
127 | | - match field.name { |
128 | | - sym::generics => self.write_generics(&field_place, generics)?, |
129 | | - sym::type_id_variants => { |
130 | | - self.allocate_fill_and_write_slice_ptr( |
131 | | - &field_place, |
132 | | - enum_def.variants().len() as u64, |
133 | | - |this, i, place| { |
134 | | - let variant_idx = VariantIdx::from_usize(i as usize); |
135 | | - let variant_def = &enum_def.variants()[variant_idx]; |
136 | | - let variant_layout = enum_layout.for_variant(this, variant_idx); |
137 | | - this.write_enum_variant(place, (variant_layout, &variant_def), generics) |
138 | | - }, |
139 | | - )?; |
140 | | - } |
141 | | - sym::non_exhaustive => { |
142 | | - let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); |
143 | | - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? |
144 | | - } |
145 | | - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), |
146 | | - } |
147 | | - } |
148 | | - |
149 | | - interp_ok(()) |
150 | | - } |
151 | | - |
152 | | - fn write_enum_variant( |
153 | | - &mut self, |
154 | | - place: impl Writeable<'tcx, CtfeProvenance>, |
155 | | - variant: (TyAndLayout<'tcx>, &'tcx VariantDef), |
156 | | - generics: &'tcx GenericArgs<'tcx>, |
157 | | - ) -> InterpResult<'tcx> { |
158 | | - let (variant_layout, variant_def) = variant; |
159 | | - |
160 | | - for (field_idx, field_def) in |
161 | | - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() |
162 | | - { |
163 | | - let field_place = self.project_field(&place, field_idx)?; |
164 | | - match field_def.name { |
165 | | - sym::name => { |
166 | | - let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; |
167 | | - let ptr = self.mplace_to_imm_ptr(&name_place, None)?; |
168 | | - self.write_immediate(*ptr, &field_place)? |
169 | | - } |
170 | | - sym::fields => { |
171 | | - self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? |
172 | | - } |
173 | | - sym::non_exhaustive => { |
174 | | - let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); |
175 | | - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? |
176 | | - } |
177 | | - other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), |
178 | | - } |
179 | | - } |
180 | | - interp_ok(()) |
181 | | - } |
182 | | - |
183 | | - // Write fields for struct, enum variants |
184 | | - fn write_variant_fields( |
185 | | - &mut self, |
186 | | - place: impl Writeable<'tcx, CtfeProvenance>, |
187 | | - variant_def: &'tcx VariantDef, |
188 | | - variant_layout: TyAndLayout<'tcx>, |
189 | | - generics: &'tcx GenericArgs<'tcx>, |
190 | | - ) -> InterpResult<'tcx> { |
191 | | - self.allocate_fill_and_write_slice_ptr( |
192 | | - &place, |
193 | | - variant_def.fields.len() as u64, |
194 | | - |this, i, place| { |
195 | | - let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; |
196 | | - let field_ty = field_def.ty(*this.tcx, generics).skip_norm_wip(); |
197 | | - this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) |
198 | | - }, |
199 | | - ) |
200 | | - } |
201 | | - |
202 | 36 | pub(super) fn write_generics( |
203 | 37 | &mut self, |
204 | 38 | place: &impl Writeable<'tcx, CtfeProvenance>, |
|
0 commit comments