Skip to content

Commit 0e4aed3

Browse files
committed
Add splat to libcore's TypeInfo
fixup! Impl TypeInfo for splat
1 parent 0d3a8d7 commit 0e4aed3

5 files changed

Lines changed: 96 additions & 3 deletions

File tree

compiler/rustc_const_eval/src/const_eval/type_info.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,17 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
436436
sym::variadic => {
437437
self.write_scalar(Scalar::from_bool(fn_sig_kind.c_variadic()), &field_place)?;
438438
}
439-
sym::splat => {
439+
sym::is_splatted => {
440+
self.write_scalar(
441+
Scalar::from_bool(fn_sig_kind.splatted().is_some()),
442+
&field_place,
443+
)?;
444+
}
445+
sym::splatted_index => {
440446
self.write_scalar(
441-
// Use the same encoding as FnSigKind.splatted
442447
Scalar::from_u16(
448+
// Currently the same encoding as FnSigKind.splatted
449+
// FIXME(splat): make these two fields into a single Option<u16>, or choose a stable encoding
443450
fn_sig_kind.splatted().unwrap_or(FnSigKind::NO_SPLATTED_ARG_INDEX),
444451
),
445452
&field_place,

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,7 @@ symbols! {
11171117
irrefutable_let_patterns,
11181118
is,
11191119
is_auto,
1120+
is_splatted,
11201121
is_val_statically_known,
11211122
isa_attribute,
11221123
isize,
@@ -1952,6 +1953,7 @@ symbols! {
19521953
speed,
19531954
spirv,
19541955
splat,
1956+
splatted_index,
19551957
spotlight,
19561958
sqrtf16,
19571959
sqrtf32,

library/core/src/mem/type_info.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ pub struct Variant {
214214
pub name: &'static str,
215215
/// All fields of the variant.
216216
pub fields: &'static [Field],
217-
/// Whether the enum variant fields is non-exhaustive.
217+
/// Whether the enum variant fields are non-exhaustive.
218218
pub non_exhaustive: bool,
219219
}
220220

@@ -341,6 +341,22 @@ pub struct FnPtr {
341341

342342
/// Vardiadic function, e.g. extern "C" fn add(n: usize, mut args: ...);
343343
pub variadic: bool,
344+
345+
// FIXME(splat): should these fields be private, or merged into an Option<u16>?
346+
/// Is any function argument splatted?
347+
pub is_splatted: bool,
348+
349+
/// The index of the splatted function argument in `inputs`, only valid if `is_splatted` is true.
350+
/// e.g. in `fn overload(a: u8, #[splat] b: (f32, usize))` the index is 1, and it can be called
351+
/// as `overload(a, 1.0, 2)`.
352+
pub splatted_index: u16,
353+
}
354+
355+
impl FnPtr {
356+
/// Returns the splatted function argument index, or `None` if no argument is splatted.
357+
pub const fn splatted(&self) -> Option<u16> {
358+
if self.is_splatted { Some(self.splatted_index) } else { None }
359+
}
344360
}
345361

346362
#[derive(Debug, Default)]

library/coretests/tests/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
#![feature(slice_shift)]
108108
#![feature(slice_split_once)]
109109
#![feature(sliceindex_wrappers)]
110+
#![feature(splat)]
110111
#![feature(split_array)]
111112
#![feature(split_as_slice)]
112113
#![feature(std_internals)]
@@ -129,6 +130,7 @@
129130
#![feature(widening_mul)]
130131
// tidy-alphabetical-end
131132
#![allow(internal_features)]
133+
#![expect(incomplete_features)]
132134
#![deny(fuzzy_provenance_casts)]
133135
#![deny(unsafe_op_in_unsafe_fn)]
134136

library/coretests/tests/mem/fn_ptr.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const STRING_TY: TypeId = const { TypeId::of::<String>() };
55
const U8_TY: TypeId = const { TypeId::of::<u8>() };
66
const _U8_REF_TY: TypeId = const { TypeId::of::<&u8>() };
77
const UNIT_TY: TypeId = const { TypeId::of::<()>() };
8+
const TUPLE_STRING_U8_TY: TypeId = const { TypeId::of::<(String, u8)>() };
89

910
#[test]
1011
fn test_fn_ptrs() {
@@ -14,6 +15,8 @@ fn test_fn_ptrs() {
1415
inputs: &[],
1516
output,
1617
variadic: false,
18+
is_splatted: false,
19+
splatted_index: _,
1720
}) = (const { Type::of::<fn()>().kind })
1821
else {
1922
panic!();
@@ -31,6 +34,8 @@ fn test_ref() {
3134
inputs: &[ty1, ty2],
3235
output,
3336
variadic: false,
37+
is_splatted: false,
38+
splatted_index: _,
3439
}) = (const { Type::of::<fn(&u8, &u8)>().kind })
3540
else {
3641
panic!();
@@ -61,6 +66,8 @@ fn test_unsafe() {
6166
inputs: &[],
6267
output,
6368
variadic: false,
69+
is_splatted: false,
70+
splatted_index: _,
6471
}) = (const { Type::of::<unsafe fn()>().kind })
6572
else {
6673
panic!();
@@ -75,6 +82,8 @@ fn test_abi() {
7582
inputs: &[],
7683
output,
7784
variadic: false,
85+
is_splatted: false,
86+
splatted_index: _,
7887
}) = (const { Type::of::<extern "Rust" fn()>().kind })
7988
else {
8089
panic!();
@@ -87,6 +96,8 @@ fn test_abi() {
8796
inputs: &[],
8897
output,
8998
variadic: false,
99+
is_splatted: false,
100+
splatted_index: _,
90101
}) = (const { Type::of::<extern "C" fn()>().kind })
91102
else {
92103
panic!();
@@ -99,6 +110,8 @@ fn test_abi() {
99110
inputs: &[],
100111
output,
101112
variadic: false,
113+
is_splatted: false,
114+
splatted_index: _,
102115
}) = (const { Type::of::<unsafe extern "system" fn()>().kind })
103116
else {
104117
panic!();
@@ -114,6 +127,8 @@ fn test_inputs() {
114127
inputs: &[ty1, ty2],
115128
output,
116129
variadic: false,
130+
is_splatted: false,
131+
splatted_index: _,
117132
}) = (const { Type::of::<fn(String, u8)>().kind })
118133
else {
119134
panic!();
@@ -128,6 +143,8 @@ fn test_inputs() {
128143
inputs: &[ty1, ty2],
129144
output,
130145
variadic: false,
146+
is_splatted: false,
147+
splatted_index: _,
131148
}) = (const { Type::of::<fn(val: String, p2: u8)>().kind })
132149
else {
133150
panic!();
@@ -145,6 +162,8 @@ fn test_output() {
145162
inputs: &[],
146163
output,
147164
variadic: false,
165+
is_splatted: false,
166+
splatted_index: _,
148167
}) = (const { Type::of::<fn() -> u8>().kind })
149168
else {
150169
panic!();
@@ -160,10 +179,57 @@ fn test_variadic() {
160179
inputs: [ty1],
161180
output,
162181
variadic: true,
182+
is_splatted: false,
183+
splatted_index: _,
163184
}) = &(const { Type::of::<extern "C" fn(u8, ...)>().kind })
164185
else {
165186
panic!();
166187
};
167188
assert_eq!(output, &UNIT_TY);
168189
assert_eq!(*ty1, U8_TY);
169190
}
191+
192+
#[test]
193+
fn test_splat() {
194+
#[rustfmt::skip]
195+
let TypeKind::FnPtr(fn_ptr_ty) = &(const { Type::of::<fn(#[splat] (String, u8))>().kind }) else {
196+
panic!();
197+
};
198+
let FnPtr {
199+
unsafety: false,
200+
abi: Abi::ExternRust,
201+
inputs: [ty1],
202+
output,
203+
variadic: false,
204+
is_splatted: true,
205+
splatted_index: 0,
206+
} = fn_ptr_ty
207+
else {
208+
panic!();
209+
};
210+
assert_eq!(output, &UNIT_TY);
211+
assert_eq!(*ty1, TUPLE_STRING_U8_TY);
212+
assert_eq!(fn_ptr_ty.splatted(), Some(0));
213+
}
214+
215+
#[test]
216+
fn test_not_splat() {
217+
let TypeKind::FnPtr(fn_ptr_ty) = &(const { Type::of::<fn((String, u8))>().kind }) else {
218+
panic!();
219+
};
220+
let FnPtr {
221+
unsafety: false,
222+
abi: Abi::ExternRust,
223+
inputs: [ty1],
224+
output,
225+
variadic: false,
226+
is_splatted: false,
227+
splatted_index: _,
228+
} = fn_ptr_ty
229+
else {
230+
panic!();
231+
};
232+
assert_eq!(output, &UNIT_TY);
233+
assert_eq!(*ty1, TUPLE_STRING_U8_TY);
234+
assert_eq!(fn_ptr_ty.splatted(), None);
235+
}

0 commit comments

Comments
 (0)