Skip to content

Commit e237c35

Browse files
committed
Don't require the user to enable the unsized features.
Rather than forcing the user to enable the unsized_fn_params and unsized_locals features, we condition those features tests with if the type is a scalable simd type.
1 parent d5834cc commit e237c35

File tree

8 files changed

+96
-6
lines changed

8 files changed

+96
-6
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12751275
}
12761276

12771277
self.check_rvalue(body, rv, location);
1278-
if !self.unsized_feature_enabled() {
1278+
if !(self.unsized_feature_enabled() || place_ty.is_scalable_simd()) {
12791279
let trait_ref = ty::TraitRef::new(
12801280
tcx,
12811281
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
@@ -1796,7 +1796,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17961796
if !self.unsized_feature_enabled() {
17971797
let span = local_decl.source_info.span;
17981798
let ty = local_decl.ty;
1799-
self.ensure_place_sized(ty, span);
1799+
if !ty.is_scalable_simd() {
1800+
self.ensure_place_sized(ty, span);
1801+
}
18001802
}
18011803
}
18021804

compiler/rustc_feature/src/unstable.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,22 @@ declare_features! (
637637
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
638638
(incomplete, unsized_const_params, "CURRENT_RUSTC_VERSION", Some(95174)),
639639
/// Allows unsized fn parameters.
640+
///
641+
/// Note: `repr_scalable` depends on this feature. Rather than forcing the developer to also
642+
/// enable this feature to use scalable SIMD, we have done a check along side this feature to
643+
/// check if the type is a scalable SIMD type. If this feature becomes stable, those checks
644+
/// should be safe to remove so we can just use this feature. The check has been done specific
645+
/// to the type rather than enabling this feature on their behalf to avoid enabling more unsized
646+
/// than is actually required for what they are using.
640647
(internal, unsized_fn_params, "1.49.0", Some(48055)),
641648
/// Allows unsized rvalues at arguments and parameters.
649+
///
650+
/// Note: `repr_scalable` depends on this feature. Rather than forcing the developer to also
651+
/// enable this feature to use scalable SIMD, we have done a check along side this feature to
652+
/// check if the type is a scalable SIMD type. If this feature becomes stable, those checks
653+
/// should be safe to remove so we can just use this feature. The check has been done specific
654+
/// to the type rather than enabling this feature on their behalf to avoid enabling more unsized
655+
/// than is actually required for what they are using.
642656
(incomplete, unsized_locals, "1.30.0", Some(48055)),
643657
/// Allows unsized tuple coercion.
644658
(unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),

compiler/rustc_hir_typeck/src/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub(super) fn check_fn<'a, 'tcx>(
9494
}
9595

9696
// Check that argument is Sized.
97-
if !params_can_be_unsized {
97+
if !(params_can_be_unsized || param_ty.is_scalable_simd()) {
9898
fcx.require_type_is_sized(
9999
param_ty,
100100
param.pat.span,

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
578578
infer::BoundRegionConversionTime::FnCall,
579579
fn_sig.input(i),
580580
);
581+
582+
if input.is_scalable_simd() {
583+
continue;
584+
}
585+
581586
self.require_type_is_sized_deferred(
582587
input,
583588
span,

compiler/rustc_hir_typeck/src/gather_locals.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
140140
let var_ty = self.assign(p.span, p.hir_id, None);
141141

142142
if let Some((ty_span, hir_id)) = self.outermost_fn_param_pat {
143-
if !self.fcx.tcx.features().unsized_fn_params {
143+
if !(self.fcx.tcx.features().unsized_fn_params
144+
|| self.fcx.tcx.features().repr_scalable)
145+
{
144146
self.fcx.require_type_is_sized(
145147
var_ty,
146148
p.span,
@@ -158,7 +160,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
158160
);
159161
}
160162
} else {
161-
if !self.fcx.tcx.features().unsized_locals {
163+
if !(self.fcx.tcx.features().unsized_locals
164+
|| self.fcx.tcx.features().repr_scalable)
165+
{
162166
self.fcx.require_type_is_sized(
163167
var_ty,
164168
p.span,

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ fn typeck_with_fallback<'tcx>(
197197

198198
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
199199
let ty = fcx.normalize(span, ty);
200-
// ScalableSIMD: Justify this.
201200
if !ty.is_scalable_simd() {
202201
fcx.require_type_is_sized(ty, span, code);
203202
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#![allow(incomplete_features, internal_features, improper_ctypes)]
2+
#![feature(
3+
repr_simd,
4+
repr_scalable,
5+
simd_ffi,
6+
unsized_locals,
7+
unsized_fn_params,
8+
link_llvm_intrinsics
9+
)]
10+
11+
#[repr(simd, scalable(4))]
12+
#[allow(non_camel_case_types)]
13+
pub struct svint32_t {
14+
_ty: [i32],
15+
}
16+
17+
#[inline(never)]
18+
#[target_feature(enable = "sve")]
19+
pub unsafe fn svdup_n_s32(op: i32) -> svint32_t {
20+
extern "C" {
21+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")]
22+
fn _svdup_n_s32(op: i32) -> svint32_t;
23+
}
24+
unsafe { _svdup_n_s32(op) }
25+
}
26+
27+
#[inline]
28+
#[target_feature(enable = "sve,sve2")]
29+
pub unsafe fn svxar_n_s32<const IMM3: i32>(op1: svint32_t, op2: svint32_t) -> svint32_t {
30+
extern "C" {
31+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.xar.nxv4i32")]
32+
fn _svxar_n_s32(op1: svint32_t, op2: svint32_t, imm3: i32) -> svint32_t;
33+
}
34+
unsafe { _svxar_n_s32(op1, op2, IMM3) }
35+
}
36+
37+
#[inline(never)]
38+
fn run(f: impl Fn() -> ()) {
39+
f();
40+
}
41+
42+
fn main() {
43+
let a = svdup_n_s32(42);
44+
run(move || {
45+
svxar_n_s32::<2>(a, a); //~ ERROR E0277
46+
});
47+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
2+
--> $DIR/disallow-capture-closure.rs:45:26
3+
|
4+
LL | run(move || {
5+
| -- this closure captures all values by move
6+
LL | svxar_n_s32::<2>(a, a);
7+
| ^ doesn't have a size known at compile-time
8+
|
9+
= help: within `svint32_t`, the trait `Sized` is not implemented for `[i32]`, which is required by `svint32_t: Sized`
10+
note: required because it appears within the type `svint32_t`
11+
--> $DIR/disallow-capture-closure.rs:13:12
12+
|
13+
LL | pub struct svint32_t {
14+
| ^^^^^^^^^
15+
= note: all values captured by value by a closure must have a statically known size
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)