Skip to content

Commit fa025e2

Browse files
committed
Refactor Type::size field to TypeId::size method for type_info
1 parent e95e732 commit fa025e2

13 files changed

Lines changed: 166 additions & 126 deletions

File tree

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::borrow::{Borrow, Cow};
22
use std::hash::Hash;
33
use std::{fmt, mem};
44

5-
use rustc_abi::{Align, FIRST_VARIANT, Size};
5+
use rustc_abi::{Align, FIRST_VARIANT, FieldIdx, Size};
66
use rustc_ast::Mutability;
77
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
88
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -11,7 +11,7 @@ use rustc_middle::mir::AssertMessage;
1111
use rustc_middle::mir::interpret::ReportedErrorInfo;
1212
use rustc_middle::query::TyCtxtAt;
1313
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement};
14-
use rustc_middle::ty::{self, FieldInfo, Ty, TyCtxt};
14+
use rustc_middle::ty::{self, FieldInfo, ScalarInt, Ty, TyCtxt};
1515
use rustc_middle::{bug, mir, span_bug};
1616
use rustc_span::{Span, Symbol, sym};
1717
use rustc_target::callconv::FnAbi;
@@ -605,6 +605,23 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
605605
ecx.write_type_info(ty, dest)?;
606606
}
607607

608+
sym::size_of_type_id => {
609+
let ty = ecx.read_type_id(&args[0])?;
610+
let layout = ecx.layout_of(ty)?;
611+
let variant_index = if layout.is_sized() {
612+
let (variant, variant_place) = ecx.project_downcast_sym(dest, sym::Some)?;
613+
let size_field_place = ecx.project_field(&variant_place, FieldIdx::ZERO)?;
614+
ecx.write_scalar(
615+
ScalarInt::try_from_target_usize(layout.size.bytes(), ecx.tcx.tcx).unwrap(),
616+
&size_field_place,
617+
)?;
618+
variant
619+
} else {
620+
ecx.project_downcast_sym(dest, sym::None)?.0
621+
};
622+
ecx.write_discriminant(variant_index, dest)?;
623+
}
624+
608625
sym::field_offset => {
609626
let frt_ty = instance.args.type_at(0);
610627
ensure_monomorphic_enough(ecx.tcx.tcx, frt_ty)?;

compiler/rustc_const_eval/src/const_eval/type_info.rs

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod adt;
22

33
use std::borrow::Cow;
44

5-
use rustc_abi::{ExternAbi, FieldIdx, VariantIdx};
5+
use rustc_abi::{ExternAbi, FieldIdx};
66
use rustc_ast::Mutability;
77
use rustc_hir::LangItem;
88
use rustc_middle::span_bug;
@@ -12,27 +12,11 @@ use rustc_span::{Symbol, sym};
1212

1313
use crate::const_eval::CompileTimeMachine;
1414
use crate::interpret::{
15-
CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Projectable, Scalar,
16-
Writeable, interp_ok,
15+
CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Scalar, Writeable,
16+
interp_ok,
1717
};
1818

1919
impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
20-
/// Equivalent to `project_downcast`, but identifies the variant by name instead of index.
21-
fn downcast<'a>(
22-
&self,
23-
place: &(impl Writeable<'tcx, CtfeProvenance> + 'a),
24-
name: Symbol,
25-
) -> InterpResult<'tcx, (VariantIdx, impl Writeable<'tcx, CtfeProvenance> + 'a)> {
26-
let variants = place.layout().ty.ty_adt_def().unwrap().variants();
27-
let variant_idx = variants
28-
.iter_enumerated()
29-
.find(|(_idx, var)| var.name == name)
30-
.unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}"))
31-
.0;
32-
33-
interp_ok((variant_idx, self.project_downcast(place, variant_idx)?))
34-
}
35-
3620
// A general method to write an array to a static slice place.
3721
fn allocate_fill_and_write_slice_ptr(
3822
&mut self,
@@ -83,7 +67,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
8367
let variant_index = match ty.kind() {
8468
ty::Tuple(fields) => {
8569
let (variant, variant_place) =
86-
self.downcast(&field_dest, sym::Tuple)?;
70+
self.project_downcast_sym(&field_dest, sym::Tuple)?;
8771
// project to the single tuple variant field of `type_info::Tuple` struct type
8872
let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
8973
assert_eq!(
@@ -102,7 +86,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
10286
}
10387
ty::Array(ty, len) => {
10488
let (variant, variant_place) =
105-
self.downcast(&field_dest, sym::Array)?;
89+
self.project_downcast_sym(&field_dest, sym::Array)?;
10690
let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
10791

10892
self.write_array_type_info(array_place, *ty, *len)?;
@@ -111,7 +95,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
11195
}
11296
ty::Slice(ty) => {
11397
let (variant, variant_place) =
114-
self.downcast(&field_dest, sym::Slice)?;
98+
self.project_downcast_sym(&field_dest, sym::Slice)?;
11599
let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
116100

117101
self.write_slice_type_info(slice_place, *ty)?;
@@ -123,16 +107,17 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
123107
}
124108
ty::Bool => {
125109
let (variant, _variant_place) =
126-
self.downcast(&field_dest, sym::Bool)?;
110+
self.project_downcast_sym(&field_dest, sym::Bool)?;
127111
variant
128112
}
129113
ty::Char => {
130114
let (variant, _variant_place) =
131-
self.downcast(&field_dest, sym::Char)?;
115+
self.project_downcast_sym(&field_dest, sym::Char)?;
132116
variant
133117
}
134118
ty::Int(int_ty) => {
135-
let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?;
119+
let (variant, variant_place) =
120+
self.project_downcast_sym(&field_dest, sym::Int)?;
136121
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
137122
self.write_int_type_info(
138123
place,
@@ -142,7 +127,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
142127
variant
143128
}
144129
ty::Uint(uint_ty) => {
145-
let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?;
130+
let (variant, variant_place) =
131+
self.project_downcast_sym(&field_dest, sym::Int)?;
146132
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
147133
self.write_int_type_info(
148134
place,
@@ -153,18 +139,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
153139
}
154140
ty::Float(float_ty) => {
155141
let (variant, variant_place) =
156-
self.downcast(&field_dest, sym::Float)?;
142+
self.project_downcast_sym(&field_dest, sym::Float)?;
157143
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
158144
self.write_float_type_info(place, float_ty.bit_width())?;
159145
variant
160146
}
161147
ty::Str => {
162-
let (variant, _variant_place) = self.downcast(&field_dest, sym::Str)?;
148+
let (variant, _variant_place) =
149+
self.project_downcast_sym(&field_dest, sym::Str)?;
163150
variant
164151
}
165152
ty::Ref(_, ty, mutability) => {
166153
let (variant, variant_place) =
167-
self.downcast(&field_dest, sym::Reference)?;
154+
self.project_downcast_sym(&field_dest, sym::Reference)?;
168155
let reference_place =
169156
self.project_field(&variant_place, FieldIdx::ZERO)?;
170157
self.write_reference_type_info(reference_place, *ty, *mutability)?;
@@ -173,7 +160,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
173160
}
174161
ty::RawPtr(ty, mutability) => {
175162
let (variant, variant_place) =
176-
self.downcast(&field_dest, sym::Pointer)?;
163+
self.project_downcast_sym(&field_dest, sym::Pointer)?;
177164
let pointer_place =
178165
self.project_field(&variant_place, FieldIdx::ZERO)?;
179166

@@ -183,14 +170,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
183170
}
184171
ty::Dynamic(predicates, region) => {
185172
let (variant, variant_place) =
186-
self.downcast(&field_dest, sym::DynTrait)?;
173+
self.project_downcast_sym(&field_dest, sym::DynTrait)?;
187174
let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
188175
self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?;
189176
variant
190177
}
191178
ty::FnPtr(sig, fn_header) => {
192179
let (variant, variant_place) =
193-
self.downcast(&field_dest, sym::FnPtr)?;
180+
self.project_downcast_sym(&field_dest, sym::FnPtr)?;
194181
let fn_ptr_place =
195182
self.project_field(&variant_place, FieldIdx::ZERO)?;
196183

@@ -214,27 +201,10 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
214201
| ty::Bound(..)
215202
| ty::Placeholder(_)
216203
| ty::Infer(..)
217-
| ty::Error(_) => self.downcast(&field_dest, sym::Other)?.0,
204+
| ty::Error(_) => self.project_downcast_sym(&field_dest, sym::Other)?.0,
218205
};
219206
self.write_discriminant(variant_index, &field_dest)?
220207
}
221-
sym::size => {
222-
let layout = self.layout_of(ty)?;
223-
let variant_index = if layout.is_sized() {
224-
let (variant, variant_place) = self.downcast(&field_dest, sym::Some)?;
225-
let size_field_place =
226-
self.project_field(&variant_place, FieldIdx::ZERO)?;
227-
self.write_scalar(
228-
ScalarInt::try_from_target_usize(layout.size.bytes(), self.tcx.tcx)
229-
.unwrap(),
230-
&size_field_place,
231-
)?;
232-
variant
233-
} else {
234-
self.downcast(&field_dest, sym::None)?.0
235-
};
236-
self.write_discriminant(variant_index, &field_dest)?;
237-
}
238208
other => span_bug!(self.tcx.span, "unknown `Type` field {other}"),
239209
}
240210
}
@@ -433,16 +403,17 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
433403
sym::abi => match fn_sig_kind.abi() {
434404
ExternAbi::C { .. } => {
435405
let (rust_variant, _rust_place) =
436-
self.downcast(&field_place, sym::ExternC)?;
406+
self.project_downcast_sym(&field_place, sym::ExternC)?;
437407
self.write_discriminant(rust_variant, &field_place)?;
438408
}
439409
ExternAbi::Rust => {
440410
let (rust_variant, _rust_place) =
441-
self.downcast(&field_place, sym::ExternRust)?;
411+
self.project_downcast_sym(&field_place, sym::ExternRust)?;
442412
self.write_discriminant(rust_variant, &field_place)?;
443413
}
444414
other_abi => {
445-
let (variant, variant_place) = self.downcast(&field_place, sym::Named)?;
415+
let (variant, variant_place) =
416+
self.project_downcast_sym(&field_place, sym::Named)?;
446417
let str_place = self.allocate_str_dedup(other_abi.as_str())?;
447418
let str_ref = self.mplace_to_imm_ptr(&str_place, None)?;
448419
let payload = self.project_field(&variant_place, FieldIdx::ZERO)?;

compiler/rustc_const_eval/src/const_eval/type_info/adt.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
2222
let (adt_ty, adt_def) = adt;
2323
let variant_idx = match adt_def.adt_kind() {
2424
AdtKind::Struct => {
25-
let (variant, variant_place) = self.downcast(place, sym::Struct)?;
25+
let (variant, variant_place) = self.project_downcast_sym(place, sym::Struct)?;
2626
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
2727
self.write_struct_type_info(
2828
place,
@@ -32,7 +32,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
3232
variant
3333
}
3434
AdtKind::Union => {
35-
let (variant, variant_place) = self.downcast(place, sym::Union)?;
35+
let (variant, variant_place) = self.project_downcast_sym(place, sym::Union)?;
3636
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
3737
self.write_union_type_info(
3838
place,
@@ -42,7 +42,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
4242
variant
4343
}
4444
AdtKind::Enum => {
45-
let (variant, variant_place) = self.downcast(place, sym::Enum)?;
45+
let (variant, variant_place) = self.project_downcast_sym(place, sym::Enum)?;
4646
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
4747
self.write_enum_type_info(place, adt, generics)?;
4848
variant
@@ -219,13 +219,13 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
219219
_region: Region<'tcx>,
220220
place: MPlaceTy<'tcx>,
221221
) -> InterpResult<'tcx> {
222-
let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?;
222+
let (variant_idx, _) = self.project_downcast_sym(&place, sym::Lifetime)?;
223223
self.write_discriminant(variant_idx, &place)?;
224224
interp_ok(())
225225
}
226226

227227
fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
228-
let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?;
228+
let (variant_idx, variant_place) = self.project_downcast_sym(&place, sym::Type)?;
229229
let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
230230

231231
for (field_idx, field_def) in generic_type_place
@@ -251,7 +251,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
251251
fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
252252
let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") };
253253

254-
let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?;
254+
let (variant_idx, variant_place) = self.project_downcast_sym(&place, sym::Const)?;
255255
let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
256256

257257
for (field_idx, field_def) in const_place

compiler/rustc_const_eval/src/interpret/projection.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_abi::{self as abi, FieldIdx, Size, VariantIdx};
1414
use rustc_middle::ty::Ty;
1515
use rustc_middle::ty::layout::TyAndLayout;
1616
use rustc_middle::{bug, mir, span_bug, ty};
17+
use rustc_span::Symbol;
1718
use tracing::{debug, instrument};
1819

1920
use super::{
@@ -227,6 +228,22 @@ where
227228
base.offset(Size::ZERO, layout, self)
228229
}
229230

231+
/// Equivalent to `project_downcast`, but identifies the variant by name instead of index.
232+
pub fn project_downcast_sym<P: Projectable<'tcx, M::Provenance>>(
233+
&self,
234+
base: &P,
235+
name: Symbol,
236+
) -> InterpResult<'tcx, (VariantIdx, P)> {
237+
let variants = base.layout().ty.ty_adt_def().unwrap().variants();
238+
let variant_idx = variants
239+
.iter_enumerated()
240+
.find(|(_idx, var)| var.name == name)
241+
.unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}"))
242+
.0;
243+
244+
interp_ok((variant_idx, self.project_downcast(base, variant_idx)?))
245+
}
246+
230247
/// Compute the offset and field layout for accessing the given index.
231248
pub fn project_index<P: Projectable<'tcx, M::Provenance>>(
232249
&self,

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
199199
| sym::sinf64
200200
| sym::sinf128
201201
| sym::size_of
202+
| sym::size_of_type_id
202203
| sym::sqrtf16
203204
| sym::sqrtf32
204205
| sym::sqrtf64
@@ -281,6 +282,7 @@ pub(crate) fn check_intrinsic_type(
281282
let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]).skip_norm_wip();
282283
(Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
283284
};
285+
let type_id_ty = || tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap();
284286

285287
let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
286288
let n_lts = 0;
@@ -294,6 +296,7 @@ pub(crate) fn check_intrinsic_type(
294296
sym::size_of_val | sym::align_of_val => {
295297
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
296298
}
299+
sym::size_of_type_id => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, tcx.types.usize)),
297300
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
298301
sym::field_offset => (1, 0, vec![], tcx.types.usize),
299302
sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
@@ -313,16 +316,8 @@ pub(crate) fn check_intrinsic_type(
313316
sym::needs_drop => (1, 0, vec![], tcx.types.bool),
314317

315318
sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)),
316-
sym::type_id => (
317-
1,
318-
0,
319-
vec![],
320-
tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(),
321-
),
322-
sym::type_id_eq => {
323-
let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap();
324-
(0, 0, vec![type_id, type_id], tcx.types.bool)
325-
}
319+
sym::type_id => (1, 0, vec![], type_id_ty()),
320+
sym::type_id_eq => (0, 0, vec![type_id_ty(), type_id_ty()], tcx.types.bool),
326321
sym::type_id_vtable => {
327322
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span);
328323
let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata);
@@ -335,17 +330,12 @@ pub(crate) fn check_intrinsic_type(
335330
let option_args = tcx.mk_args(&[dyn_ty.into()]);
336331
let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
337332

338-
(
339-
0,
340-
0,
341-
vec![tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(); 2],
342-
ret_ty,
343-
)
333+
(0, 0, vec![type_id_ty(); 2], ret_ty)
344334
}
345335
sym::type_of => (
346336
0,
347337
0,
348-
vec![tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap()],
338+
vec![type_id_ty()],
349339
tcx.type_of(tcx.lang_items().type_struct().unwrap()).no_bound_vars().unwrap(),
350340
),
351341
sym::offload => (

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,7 @@ symbols! {
19271927
sinf128,
19281928
size,
19291929
size_of,
1930+
size_of_type_id,
19301931
size_of_val,
19311932
sized,
19321933
sized_hierarchy,

0 commit comments

Comments
 (0)