Skip to content

Commit

Permalink
Don't require the user to enable the unsized features.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JamieCunliffe committed Apr 24, 2024
1 parent 17a06d9 commit 351bec3
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 6 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

self.check_rvalue(body, rv, location);
if !self.unsized_feature_enabled() {
if !(self.unsized_feature_enabled() || place_ty.is_scalable_simd()) {
let trait_ref = ty::TraitRef::from_lang_item(
tcx,
LangItem::Sized,
Expand Down Expand Up @@ -1857,7 +1857,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if !self.unsized_feature_enabled() {
let span = local_decl.source_info.span;
let ty = local_decl.ty;
self.ensure_place_sized(ty, span);
if !ty.is_scalable_simd() {
self.ensure_place_sized(ty, span);
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,22 @@ declare_features! (
/// Allows unnamed fields of struct and union type
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
/// Allows unsized fn parameters.
///
/// Note: `repr_scalable` depends on this feature. Rather than forcing the developer to also
/// enable this feature to use scalable SIMD, we have done a check along side this feature to
/// check if the type is a scalable SIMD type. If this feature becomes stable, those checks
/// should be safe to remove so we can just use this feature. The check has been done specific
/// to the type rather than enabling this feature on their behalf to avoid enabling more unsized
/// than is actually required for what they are using.
(unstable, unsized_fn_params, "1.49.0", Some(48055)),
/// Allows unsized rvalues at arguments and parameters.
///
/// Note: `repr_scalable` depends on this feature. Rather than forcing the developer to also
/// enable this feature to use scalable SIMD, we have done a check along side this feature to
/// check if the type is a scalable SIMD type. If this feature becomes stable, those checks
/// should be safe to remove so we can just use this feature. The check has been done specific
/// to the type rather than enabling this feature on their behalf to avoid enabling more unsized
/// than is actually required for what they are using.
(incomplete, unsized_locals, "1.30.0", Some(48055)),
/// Allows unsized tuple coercion.
(unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub(super) fn check_fn<'a, 'tcx>(
}

// Check that argument is Sized.
if !params_can_be_unsized {
if !(params_can_be_unsized || param_ty.is_scalable_simd()) {
fcx.require_type_is_sized(
param_ty,
param.pat.span,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
infer::BoundRegionConversionTime::FnCall,
fn_sig.input(i),
);

if input.is_scalable_simd() {
continue;
}

self.require_type_is_sized_deferred(
input,
span,
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_hir_typeck/src/gather_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
let var_ty = self.assign(p.span, p.hir_id, None);

if let Some((ty_span, hir_id)) = self.outermost_fn_param_pat {
if !self.fcx.tcx.features().unsized_fn_params {
if !(self.fcx.tcx.features().unsized_fn_params
|| self.fcx.tcx.features().repr_scalable)
{
self.fcx.require_type_is_sized(
var_ty,
p.span,
Expand All @@ -162,7 +164,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
);
}
} else {
if !self.fcx.tcx.features().unsized_locals {
if !(self.fcx.tcx.features().unsized_locals
|| self.fcx.tcx.features().repr_scalable)
{
self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id));
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ fn typeck_with_fallback<'tcx>(

for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
let ty = fcx.normalize(span, ty);
// ScalableSIMD: Justify this.
if !ty.is_scalable_simd() {
fcx.require_type_is_sized(ty, span, code);
}
Expand Down
47 changes: 47 additions & 0 deletions tests/ui/simd/scalable/disallow-capture-closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#![allow(incomplete_features, internal_features, improper_ctypes)]
#![feature(
repr_simd,
repr_scalable,
simd_ffi,
unsized_locals,
unsized_fn_params,
link_llvm_intrinsics
)]

#[repr(simd, scalable(4))]
#[allow(non_camel_case_types)]
pub struct svint32_t {
_ty: [i32],
}

#[inline(never)]
#[target_feature(enable = "sve")]
pub unsafe fn svdup_n_s32(op: i32) -> svint32_t {
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")]
fn _svdup_n_s32(op: i32) -> svint32_t;
}
unsafe { _svdup_n_s32(op) }
}

#[inline]
#[target_feature(enable = "sve,sve2")]
pub unsafe fn svxar_n_s32<const IMM3: i32>(op1: svint32_t, op2: svint32_t) -> svint32_t {
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.xar.nxv4i32")]
fn _svxar_n_s32(op1: svint32_t, op2: svint32_t, imm3: i32) -> svint32_t;
}
unsafe { _svxar_n_s32(op1, op2, IMM3) }
}

#[inline(never)]
fn run(f: impl Fn() -> ()) {
f();
}

fn main() {
let a = svdup_n_s32(42);
run(move || {
svxar_n_s32::<2>(a, a); //~ ERROR E0277
});
}
19 changes: 19 additions & 0 deletions tests/ui/simd/scalable/disallow-capture-closure.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> $DIR/disallow-capture-closure.rs:45:26
|
LL | run(move || {
| -- this closure captures all values by move
LL | svxar_n_s32::<2>(a, a);
| ^ doesn't have a size known at compile-time
|
= help: within `svint32_t`, the trait `Sized` is not implemented for `[i32]`, which is required by `svint32_t: Sized`
note: required because it appears within the type `svint32_t`
--> $DIR/disallow-capture-closure.rs:13:12
|
LL | pub struct svint32_t {
| ^^^^^^^^^
= note: all values captured by value by a closure must have a statically known size

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit 351bec3

Please sign in to comment.