Unimplement unsized_locals
This commit is contained in:
@@ -373,8 +373,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unsized_feature_enabled(&self) -> bool {
|
fn unsized_feature_enabled(&self) -> bool {
|
||||||
let features = self.tcx().features();
|
self.tcx().features().unsized_fn_params()
|
||||||
features.unsized_locals() || features.unsized_fn_params()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equate the inferred type and the annotated type for user type annotations
|
/// Equate the inferred type and the annotated type for user type annotations
|
||||||
@@ -957,7 +956,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When `unsized_fn_params` or `unsized_locals` is enabled, only function calls
|
// When `unsized_fn_params` is enabled, only function calls
|
||||||
// and nullary ops are checked in `check_call_dest`.
|
// and nullary ops are checked in `check_call_dest`.
|
||||||
if !self.unsized_feature_enabled() {
|
if !self.unsized_feature_enabled() {
|
||||||
match self.body.local_kind(local) {
|
match self.body.local_kind(local) {
|
||||||
@@ -1941,7 +1940,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When `unsized_fn_params` and `unsized_locals` are both not enabled,
|
// When `unsized_fn_params` is not enabled,
|
||||||
// this check is done at `check_local`.
|
// this check is done at `check_local`.
|
||||||
if self.unsized_feature_enabled() {
|
if self.unsized_feature_enabled() {
|
||||||
let span = term.source_info.span;
|
let span = term.source_info.span;
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
|
|||||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
|
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
// This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
|
|
||||||
// without unsized_locals), but wrappers around `Self` currently are not.
|
|
||||||
// FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
|
|
||||||
// fn wrapper(self: Wrapper<Self>) -> i32;
|
|
||||||
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
||||||
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
||||||
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
||||||
|
|||||||
@@ -37,10 +37,6 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
|
|||||||
|
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
// This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
|
|
||||||
// without unsized_locals), but wrappers around `Self` currently are not.
|
|
||||||
// FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
|
|
||||||
// fn wrapper(self: Wrapper<Self>) -> i32;
|
|
||||||
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
||||||
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
||||||
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
||||||
|
|||||||
@@ -263,6 +263,8 @@ declare_features! (
|
|||||||
/// Allows unnamed fields of struct and union type
|
/// Allows unnamed fields of struct and union type
|
||||||
(removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign"), 131045),
|
(removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign"), 131045),
|
||||||
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
|
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
|
||||||
|
/// Allows unsized rvalues at arguments and parameters.
|
||||||
|
(removed, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), Some("removed due to implementation concerns; see https://github.com/rust-lang/rust/issues/111942")),
|
||||||
(removed, unsized_tuple_coercion, "1.87.0", Some(42877),
|
(removed, unsized_tuple_coercion, "1.87.0", Some(42877),
|
||||||
Some("The feature restricts possible layouts for tuples, and this restriction is not worth it."), 137728),
|
Some("The feature restricts possible layouts for tuples, and this restriction is not worth it."), 137728),
|
||||||
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
|
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
|
||||||
|
|||||||
@@ -665,8 +665,6 @@ declare_features! (
|
|||||||
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
|
(incomplete, unsized_const_params, "1.82.0", Some(95174)),
|
||||||
/// Allows unsized fn parameters.
|
/// Allows unsized fn parameters.
|
||||||
(internal, unsized_fn_params, "1.49.0", Some(48055)),
|
(internal, unsized_fn_params, "1.49.0", Some(48055)),
|
||||||
/// Allows unsized rvalues at arguments and parameters.
|
|
||||||
(incomplete, unsized_locals, "1.30.0", Some(48055)),
|
|
||||||
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
|
/// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
|
||||||
(unstable, used_with_arg, "1.60.0", Some(93798)),
|
(unstable, used_with_arg, "1.60.0", Some(93798)),
|
||||||
/// Allows use of attributes in `where` clauses.
|
/// Allows use of attributes in `where` clauses.
|
||||||
|
|||||||
@@ -1662,9 +1662,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
blk_id,
|
blk_id,
|
||||||
expression,
|
expression,
|
||||||
);
|
);
|
||||||
if !fcx.tcx.features().unsized_locals() {
|
unsized_return = self.is_return_ty_definitely_unsized(fcx);
|
||||||
unsized_return = self.is_return_ty_definitely_unsized(fcx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ObligationCauseCode::ReturnValue(return_expr_id) => {
|
ObligationCauseCode::ReturnValue(return_expr_id) => {
|
||||||
err = self.report_return_mismatched_types(
|
err = self.report_return_mismatched_types(
|
||||||
@@ -1676,9 +1674,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
return_expr_id,
|
return_expr_id,
|
||||||
expression,
|
expression,
|
||||||
);
|
);
|
||||||
if !fcx.tcx.features().unsized_locals() {
|
unsized_return = self.is_return_ty_definitely_unsized(fcx);
|
||||||
unsized_return = self.is_return_ty_definitely_unsized(fcx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
|
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
|
||||||
arm_span,
|
arm_span,
|
||||||
|
|||||||
@@ -809,9 +809,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Here we want to prevent struct constructors from returning unsized types.
|
// Here we want to prevent struct constructors from returning unsized types,
|
||||||
// There were two cases this happened: fn pointer coercion in stable
|
// which can happen with fn pointer coercion on stable.
|
||||||
// and usual function call in presence of unsized_locals.
|
|
||||||
// Also, as we just want to check sizedness, instead of introducing
|
// Also, as we just want to check sizedness, instead of introducing
|
||||||
// placeholder lifetimes with probing, we just replace higher lifetimes
|
// placeholder lifetimes with probing, we just replace higher lifetimes
|
||||||
// with fresh vars.
|
// with fresh vars.
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if !self.fcx.tcx.features().unsized_locals() {
|
} else {
|
||||||
self.fcx.require_type_is_sized(
|
self.fcx.require_type_is_sized(
|
||||||
var_ty,
|
var_ty,
|
||||||
p.span,
|
p.span,
|
||||||
|
|||||||
@@ -492,7 +492,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let final_upvar_tys = self.final_upvar_tys(closure_def_id);
|
let final_upvar_tys = self.final_upvar_tys(closure_def_id);
|
||||||
debug!(?closure_hir_id, ?args, ?final_upvar_tys);
|
debug!(?closure_hir_id, ?args, ?final_upvar_tys);
|
||||||
|
|
||||||
if self.tcx.features().unsized_locals() || self.tcx.features().unsized_fn_params() {
|
if self.tcx.features().unsized_fn_params() {
|
||||||
for capture in
|
for capture in
|
||||||
self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id)
|
self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1133,13 +1133,6 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
|
|||||||
/// Each local naturally corresponds to the place `Place { local, projection: [] }`. This place has
|
/// Each local naturally corresponds to the place `Place { local, projection: [] }`. This place has
|
||||||
/// the address of the local's allocation and the type of the local.
|
/// the address of the local's allocation and the type of the local.
|
||||||
///
|
///
|
||||||
/// **Needs clarification:** Unsized locals seem to present a bit of an issue. Their allocation
|
|
||||||
/// can't actually be created on `StorageLive`, because it's unclear how big to make the allocation.
|
|
||||||
/// Furthermore, MIR produces assignments to unsized locals, although that is not permitted under
|
|
||||||
/// `#![feature(unsized_locals)]` in Rust. Besides just putting "unsized locals are special and
|
|
||||||
/// different" in a bunch of places, I (JakobDegen) don't know how to incorporate this behavior into
|
|
||||||
/// the current MIR semantics in a clean way - possibly this needs some design work first.
|
|
||||||
///
|
|
||||||
/// For places that are not locals, ie they have a non-empty list of projections, we define the
|
/// For places that are not locals, ie they have a non-empty list of projections, we define the
|
||||||
/// values as a function of the parent place, that is the place with its last [`ProjectionElem`]
|
/// values as a function of the parent place, that is the place with its last [`ProjectionElem`]
|
||||||
/// stripped. The way this is computed of course depends on the kind of that last projection
|
/// stripped. The way this is computed of course depends on the kind of that last projection
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ pub enum InstanceKind<'tcx> {
|
|||||||
Intrinsic(DefId),
|
Intrinsic(DefId),
|
||||||
|
|
||||||
/// `<T as Trait>::method` where `method` receives unsizeable `self: Self` (part of the
|
/// `<T as Trait>::method` where `method` receives unsizeable `self: Self` (part of the
|
||||||
/// `unsized_locals` feature).
|
/// `unsized_fn_params` feature).
|
||||||
///
|
///
|
||||||
/// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` -
|
/// The generated shim will take `Self` via `*mut Self` - conceptually this is `&owned Self` -
|
||||||
/// and dereference the argument to call the original function.
|
/// and dereference the argument to call the original function.
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
/// local variable of unsized type. For example, consider this program:
|
/// local variable of unsized type. For example, consider this program:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(unsized_locals, unsized_fn_params)]
|
/// #![feature(unsized_fn_params)]
|
||||||
/// # use core::fmt::Debug;
|
/// # use core::fmt::Debug;
|
||||||
/// fn foo(p: dyn Debug) { dbg!(p); }
|
/// fn foo(_p: dyn Debug) { /* ... */ }
|
||||||
///
|
///
|
||||||
/// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
|
/// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -84,7 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
/// will actually provide a pointer to the interior of the box, and not move the `dyn Debug`
|
/// will actually provide a pointer to the interior of the box, and not move the `dyn Debug`
|
||||||
/// value to the stack.
|
/// value to the stack.
|
||||||
///
|
///
|
||||||
/// See #68304 for more details.
|
/// See <https://github.com/rust-lang/rust/issues/68304> for more details.
|
||||||
pub(crate) fn as_local_call_operand(
|
pub(crate) fn as_local_call_operand(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
|
|||||||
@@ -1417,9 +1417,9 @@ fn check_field_tys_sized<'tcx>(
|
|||||||
coroutine_layout: &CoroutineLayout<'tcx>,
|
coroutine_layout: &CoroutineLayout<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) {
|
) {
|
||||||
// No need to check if unsized_locals/unsized_fn_params is disabled,
|
// No need to check if unsized_fn_params is disabled,
|
||||||
// since we will error during typeck.
|
// since we will error during typeck.
|
||||||
if !tcx.features().unsized_locals() && !tcx.features().unsized_fn_params() {
|
if !tcx.features().unsized_fn_params() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,8 +240,6 @@ struct VnState<'body, 'tcx> {
|
|||||||
next_opaque: usize,
|
next_opaque: usize,
|
||||||
/// Cache the deref values.
|
/// Cache the deref values.
|
||||||
derefs: Vec<VnIndex>,
|
derefs: Vec<VnIndex>,
|
||||||
/// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
|
|
||||||
feature_unsized_locals: bool,
|
|
||||||
ssa: &'body SsaLocals,
|
ssa: &'body SsaLocals,
|
||||||
dominators: Dominators<BasicBlock>,
|
dominators: Dominators<BasicBlock>,
|
||||||
reused_locals: DenseBitSet<Local>,
|
reused_locals: DenseBitSet<Local>,
|
||||||
@@ -273,7 +271,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||||||
evaluated: IndexVec::with_capacity(num_values),
|
evaluated: IndexVec::with_capacity(num_values),
|
||||||
next_opaque: 1,
|
next_opaque: 1,
|
||||||
derefs: Vec::new(),
|
derefs: Vec::new(),
|
||||||
feature_unsized_locals: tcx.features().unsized_locals(),
|
|
||||||
ssa,
|
ssa,
|
||||||
dominators,
|
dominators,
|
||||||
reused_locals: DenseBitSet::new_empty(local_decls.len()),
|
reused_locals: DenseBitSet::new_empty(local_decls.len()),
|
||||||
@@ -329,13 +326,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||||||
fn assign(&mut self, local: Local, value: VnIndex) {
|
fn assign(&mut self, local: Local, value: VnIndex) {
|
||||||
debug_assert!(self.ssa.is_ssa(local));
|
debug_assert!(self.ssa.is_ssa(local));
|
||||||
self.locals[local] = Some(value);
|
self.locals[local] = Some(value);
|
||||||
|
self.rev_locals[value].push(local);
|
||||||
// Only register the value if its type is `Sized`, as we will emit copies of it.
|
|
||||||
let is_sized = !self.feature_unsized_locals
|
|
||||||
|| self.local_decls[local].ty.is_sized(self.tcx, self.typing_env());
|
|
||||||
if is_sized {
|
|
||||||
self.rev_locals[value].push(local);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
|
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
|
||||||
|
|||||||
@@ -2995,9 +2995,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
if local {
|
if local {
|
||||||
err.note("all local variables must have a statically known size");
|
err.note("all local variables must have a statically known size");
|
||||||
}
|
}
|
||||||
if !tcx.features().unsized_locals() {
|
|
||||||
err.help("unsized locals are gated as an unstable feature");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ObligationCauseCode::SizedArgumentType(hir_id) => {
|
ObligationCauseCode::SizedArgumentType(hir_id) => {
|
||||||
let mut ty = None;
|
let mut ty = None;
|
||||||
|
|||||||
@@ -414,8 +414,8 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||||||
|
|
||||||
let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));
|
let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));
|
||||||
|
|
||||||
// Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
|
// `self: Self` can't be dispatched on.
|
||||||
// However, this is already considered dyn compatible. We allow it as a special case here.
|
// However, this is considered dyn compatible. We allow it as a special case here.
|
||||||
// FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
|
// FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
|
||||||
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
|
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
|
||||||
if receiver_ty != tcx.types.self_param {
|
if receiver_ty != tcx.types.self_param {
|
||||||
|
|||||||
@@ -149,8 +149,32 @@ pub const fn forget<T>(t: T) {
|
|||||||
|
|
||||||
/// Like [`forget`], but also accepts unsized values.
|
/// Like [`forget`], but also accepts unsized values.
|
||||||
///
|
///
|
||||||
/// This function is just a shim intended to be removed when the `unsized_locals` feature gets
|
/// While Rust does not permit unsized locals since its removal in [#111942] it is
|
||||||
/// stabilized.
|
/// still possible to call functions with unsized values from a function argument
|
||||||
|
/// or in-place construction.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #![feature(unsized_fn_params, forget_unsized)]
|
||||||
|
/// #![allow(internal_features)]
|
||||||
|
///
|
||||||
|
/// use std::mem::forget_unsized;
|
||||||
|
///
|
||||||
|
/// pub fn in_place() {
|
||||||
|
/// forget_unsized(*Box::<str>::from("str"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// pub fn param(x: str) {
|
||||||
|
/// forget_unsized(x);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This works because the compiler will alter these functions to pass the parameter
|
||||||
|
/// by reference instead. This trick is necessary to support `Box<dyn FnOnce()>: FnOnce()`.
|
||||||
|
/// See [#68304] and [#71170] for more information.
|
||||||
|
///
|
||||||
|
/// [#111942]: https://github.com/rust-lang/rust/issues/111942
|
||||||
|
/// [#68304]: https://github.com/rust-lang/rust/issues/68304
|
||||||
|
/// [#71170]: https://github.com/rust-lang/rust/pull/71170
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "forget_unsized", issue = "none")]
|
#[unstable(feature = "forget_unsized", issue = "none")]
|
||||||
pub fn forget_unsized<T: ?Sized>(t: T) {
|
pub fn forget_unsized<T: ?Sized>(t: T) {
|
||||||
|
|||||||
@@ -653,7 +653,6 @@ fn thin_box() {
|
|||||||
// if `{size,align}_of_for_meta<T: ?Sized>(T::Metadata)` are added.
|
// if `{size,align}_of_for_meta<T: ?Sized>(T::Metadata)` are added.
|
||||||
// * Constructing a `ThinBox` without consuming and deallocating a `Box`
|
// * Constructing a `ThinBox` without consuming and deallocating a `Box`
|
||||||
// requires either the unstable `Unsize` marker trait,
|
// requires either the unstable `Unsize` marker trait,
|
||||||
// or the unstable `unsized_locals` language feature,
|
|
||||||
// or taking `&dyn T` and restricting to `T: Copy`.
|
// or taking `&dyn T` and restricting to `T: Copy`.
|
||||||
|
|
||||||
use std::alloc::*;
|
use std::alloc::*;
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ a new unstable feature:
|
|||||||
[`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features
|
[`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features
|
||||||
|
|
||||||
```rust ignore
|
```rust ignore
|
||||||
/// Allows unsized rvalues at arguments and parameters.
|
/// Allows deref patterns.
|
||||||
(incomplete, unsized_locals, "CURRENT_RUSTC_VERSION", Some(48055), None),
|
(incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None),
|
||||||
```
|
```
|
||||||
|
|
||||||
To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or
|
To avoid [semantic merge conflicts], please use `CURRENT_RUSTC_VERSION` instead of `1.70` or
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
# `unsized_locals`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#48055]
|
|
||||||
|
|
||||||
[#48055]: https://github.com/rust-lang/rust/issues/48055
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
|
|
||||||
|
|
||||||
[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
|
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x: Box<dyn Any> = Box::new(42);
|
|
||||||
let x: dyn Any = *x;
|
|
||||||
// ^ unsized local variable
|
|
||||||
// ^^ unsized temporary
|
|
||||||
foo(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo(_: dyn Any) {}
|
|
||||||
// ^^^^^^ unsized argument
|
|
||||||
```
|
|
||||||
|
|
||||||
The RFC still forbids the following unsized expressions:
|
|
||||||
|
|
||||||
```rust,compile_fail
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
struct MyStruct<T: ?Sized> {
|
|
||||||
content: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MyTupleStruct<T: ?Sized>(T);
|
|
||||||
|
|
||||||
fn answer() -> Box<dyn Any> {
|
|
||||||
Box::new(42)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// You CANNOT have unsized statics.
|
|
||||||
static X: dyn Any = *answer(); // ERROR
|
|
||||||
const Y: dyn Any = *answer(); // ERROR
|
|
||||||
|
|
||||||
// You CANNOT have struct initialized unsized.
|
|
||||||
MyStruct { content: *answer() }; // ERROR
|
|
||||||
MyTupleStruct(*answer()); // ERROR
|
|
||||||
(42, *answer()); // ERROR
|
|
||||||
|
|
||||||
// You CANNOT have unsized return types.
|
|
||||||
fn my_function() -> dyn Any { *answer() } // ERROR
|
|
||||||
|
|
||||||
// You CAN have unsized local variables...
|
|
||||||
let mut x: dyn Any = *answer(); // OK
|
|
||||||
// ...but you CANNOT reassign to them.
|
|
||||||
x = *answer(); // ERROR
|
|
||||||
|
|
||||||
// You CANNOT even initialize them separately.
|
|
||||||
let y: dyn Any; // OK
|
|
||||||
y = *answer(); // ERROR
|
|
||||||
|
|
||||||
// Not mentioned in the RFC, but by-move captured variables are also Sized.
|
|
||||||
let x: dyn Any = *answer();
|
|
||||||
(move || { // ERROR
|
|
||||||
let y = x;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// You CAN create a closure with unsized arguments,
|
|
||||||
// but you CANNOT call it.
|
|
||||||
// This is an implementation detail and may be changed in the future.
|
|
||||||
let f = |x: dyn Any| {};
|
|
||||||
f(*answer()); // ERROR
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## By-value trait objects
|
|
||||||
|
|
||||||
With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(unsized_fn_params)]
|
|
||||||
|
|
||||||
trait Foo {
|
|
||||||
fn foo(self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized> Foo for T {}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let slice: Box<[i32]> = Box::new([1, 2, 3]);
|
|
||||||
<[i32] as Foo>::foo(*slice);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
And `Foo` will also be object-safe.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(unsized_fn_params)]
|
|
||||||
|
|
||||||
trait Foo {
|
|
||||||
fn foo(self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ?Sized> Foo for T {}
|
|
||||||
|
|
||||||
fn main () {
|
|
||||||
let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
|
|
||||||
// doesn't compile yet
|
|
||||||
<dyn Foo as Foo>::foo(*slice);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
|
|
||||||
|
|
||||||
## Variable length arrays
|
|
||||||
|
|
||||||
The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`.
|
|
||||||
|
|
||||||
```rust,ignore (not-yet-implemented)
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
fn mergesort<T: Ord>(a: &mut [T]) {
|
|
||||||
let mut tmp = [T; dyn a.len()];
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut a = [3, 1, 5, 6];
|
|
||||||
mergesort(&mut a);
|
|
||||||
assert_eq!(a, [1, 3, 5, 6]);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`.
|
|
||||||
|
|
||||||
## Advisory on stack usage
|
|
||||||
|
|
||||||
It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
|
|
||||||
|
|
||||||
- When you need a by-value trait objects.
|
|
||||||
- When you really need a fast allocation of small temporary arrays.
|
|
||||||
|
|
||||||
Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
|
|
||||||
let _x = {{{{{{{{{{*x}}}}}}}}}};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
and the code
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
for _ in 0..10 {
|
|
||||||
let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
|
|
||||||
let _x = *x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
will unnecessarily extend the stack frame.
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
//@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR"
|
//@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR"
|
||||||
//@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR"
|
//@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR"
|
||||||
#![allow(unused, incomplete_features)]
|
#![allow(unused)]
|
||||||
#![warn(clippy::large_stack_frames)]
|
#![warn(clippy::large_stack_frames)]
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
use std::hint::black_box;
|
use std::hint::black_box;
|
||||||
|
|
||||||
@@ -11,11 +10,6 @@ fn generic<T: Default>() {
|
|||||||
black_box(&x);
|
black_box(&x);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsized_local() {
|
|
||||||
let x: dyn std::fmt::Display = *(Box::new(1) as Box<dyn std::fmt::Display>);
|
|
||||||
black_box(&x);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ArrayDefault<const N: usize>([u8; N]);
|
struct ArrayDefault<const N: usize>([u8; N]);
|
||||||
|
|
||||||
impl<const N: usize> Default for ArrayDefault<N> {
|
impl<const N: usize> Default for ArrayDefault<N> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error: this function may allocate 250$PTR bytes on the stack
|
error: this function may allocate 250$PTR bytes on the stack
|
||||||
--> tests/ui/large_stack_frames.rs:27:4
|
--> tests/ui/large_stack_frames.rs:21:4
|
||||||
|
|
|
|
||||||
LL | fn many_small_arrays() {
|
LL | fn many_small_arrays() {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
@@ -13,7 +13,7 @@ LL | let x5 = [0u8; 500_000];
|
|||||||
= help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
|
= help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
|
||||||
|
|
||||||
error: this function may allocate 1000000 bytes on the stack
|
error: this function may allocate 1000000 bytes on the stack
|
||||||
--> tests/ui/large_stack_frames.rs:38:4
|
--> tests/ui/large_stack_frames.rs:32:4
|
||||||
|
|
|
|
||||||
LL | fn large_return_value() -> ArrayDefault<1_000_000> {
|
LL | fn large_return_value() -> ArrayDefault<1_000_000> {
|
||||||
| ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
| ^^^^^^^^^^^^^^^^^^ ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
||||||
@@ -21,7 +21,7 @@ LL | fn large_return_value() -> ArrayDefault<1_000_000> {
|
|||||||
= note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
= note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
||||||
|
|
||||||
error: this function may allocate 100$PTR bytes on the stack
|
error: this function may allocate 100$PTR bytes on the stack
|
||||||
--> tests/ui/large_stack_frames.rs:44:4
|
--> tests/ui/large_stack_frames.rs:38:4
|
||||||
|
|
|
|
||||||
LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
|
LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
|
||||||
| ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
| ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
|
||||||
@@ -29,7 +29,7 @@ LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
|
|||||||
= note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
= note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
|
||||||
|
|
||||||
error: this function may allocate 100$PTR bytes on the stack
|
error: this function may allocate 100$PTR bytes on the stack
|
||||||
--> tests/ui/large_stack_frames.rs:51:13
|
--> tests/ui/large_stack_frames.rs:45:13
|
||||||
|
|
|
|
||||||
LL | let f = || black_box(&[0u8; 1_000_000]);
|
LL | let f = || black_box(&[0u8; 1_000_000]);
|
||||||
| ^^^^^^^^^^^^^^----------------^
|
| ^^^^^^^^^^^^^^----------------^
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
#![feature(unsized_locals)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
pub trait Foo {
|
|
||||||
fn foo(self) -> String;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct A;
|
|
||||||
|
|
||||||
impl Foo for A {
|
|
||||||
fn foo(self) -> String {
|
|
||||||
format!("hello")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR: unsized locals are not supported
|
|
||||||
assert_eq!(x.foo(), format!("hello"));
|
|
||||||
|
|
||||||
// I'm not sure whether we want this to work
|
|
||||||
let x = Box::new(A) as Box<dyn Foo>;
|
|
||||||
assert_eq!(x.foo(), format!("hello"));
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
error: unsupported operation: unsized locals are not supported
|
|
||||||
--> tests/fail/unsized-local.rs:LL:CC
|
|
||||||
|
|
|
||||||
LL | let x = *(Box::new(A) as Box<dyn Foo>);
|
|
||||||
| ^ unsized locals are not supported
|
|
||||||
|
|
|
||||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
|
|
||||||
= note: BACKTRACE:
|
|
||||||
= note: inside `main` at tests/fail/unsized-local.rs:LL:CC
|
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
|
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![allow(incomplete_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
// CHECK-LABEL: emptyfn:
|
// CHECK-LABEL: emptyfn:
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -357,27 +357,3 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
|
|||||||
// none-NOT: __security_check_cookie
|
// none-NOT: __security_check_cookie
|
||||||
// missing-NOT: __security_check_cookie
|
// missing-NOT: __security_check_cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: unsized_local
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
|
|
||||||
let n = if l { 1 } else { 2 };
|
|
||||||
let mut a: [u8] = *Box::<[u8]>::from(&s[0..n]); // slice-copy with Box::from
|
|
||||||
f(&mut a);
|
|
||||||
|
|
||||||
// This function allocates a slice as a local variable in its stack
|
|
||||||
// frame. Since the size is not a compile-time constant, an array
|
|
||||||
// alloca is required, and the function is protected by both the
|
|
||||||
// `strong` and `basic` heuristic.
|
|
||||||
|
|
||||||
// We should have a __security_check_cookie call in `all`, `strong` and `basic` modes but
|
|
||||||
// LLVM does not support generating stack protectors in functions with funclet
|
|
||||||
// based EH personalities.
|
|
||||||
// https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4
|
|
||||||
// all-NOT: __security_check_cookie
|
|
||||||
// strong-NOT: __security_check_cookie
|
|
||||||
// basic-NOT: __security_check_cookie
|
|
||||||
|
|
||||||
// none-NOT: __security_check_cookie
|
|
||||||
// missing-NOT: __security_check_cookie
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
|
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![allow(incomplete_features)]
|
#![feature(unsized_fn_params)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
|
|
||||||
// CHECK-LABEL: emptyfn:
|
// CHECK-LABEL: emptyfn:
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -365,27 +364,3 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
|
|||||||
// none-NOT: __security_check_cookie
|
// none-NOT: __security_check_cookie
|
||||||
// missing-NOT: __security_check_cookie
|
// missing-NOT: __security_check_cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: unsized_local
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
|
|
||||||
let n = if l { 1 } else { 2 };
|
|
||||||
let mut a: [u8] = *Box::<[u8]>::from(&s[0..n]); // slice-copy with Box::from
|
|
||||||
f(&mut a);
|
|
||||||
|
|
||||||
// This function allocates a slice as a local variable in its stack
|
|
||||||
// frame. Since the size is not a compile-time constant, an array
|
|
||||||
// alloca is required, and the function is protected by both the
|
|
||||||
// `strong` and `basic` heuristic.
|
|
||||||
|
|
||||||
// We should have a __security_check_cookie call in `all`, `strong` and `basic` modes but
|
|
||||||
// LLVM does not support generating stack protectors in functions with funclet
|
|
||||||
// based EH personalities.
|
|
||||||
// https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4
|
|
||||||
// all-NOT: __security_check_cookie
|
|
||||||
// strong-NOT: __security_check_cookie
|
|
||||||
// basic-NOT: __security_check_cookie
|
|
||||||
|
|
||||||
// none-NOT: __security_check_cookie
|
|
||||||
// missing-NOT: __security_check_cookie
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
// See comments on https://github.com/rust-lang/rust/issues/114903.
|
// See comments on https://github.com/rust-lang/rust/issues/114903.
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![allow(incomplete_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
// CHECK-LABEL: emptyfn{{:|\[}}
|
// CHECK-LABEL: emptyfn{{:|\[}}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -343,22 +343,3 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
|
|||||||
// none-NOT: __stack_chk_fail
|
// none-NOT: __stack_chk_fail
|
||||||
// missing-NOT: __stack_chk_fail
|
// missing-NOT: __stack_chk_fail
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: unsized_local{{:|\[}}
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
|
|
||||||
let n = if l { 1 } else { 2 };
|
|
||||||
let mut a: [u8] = *Box::<[u8]>::from(&s[0..n]); // slice-copy with Box::from
|
|
||||||
f(&mut a);
|
|
||||||
|
|
||||||
// This function allocates a slice as a local variable in its stack
|
|
||||||
// frame. Since the size is not a compile-time constant, an array
|
|
||||||
// alloca is required, and the function is protected by both the
|
|
||||||
// `strong` and `basic` heuristic.
|
|
||||||
|
|
||||||
// all: __stack_chk_fail
|
|
||||||
// strong: __stack_chk_fail
|
|
||||||
// basic: __stack_chk_fail
|
|
||||||
// none-NOT: __stack_chk_fail
|
|
||||||
// missing-NOT: __stack_chk_fail
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//@ compile-flags: -Copt-level=3
|
//@ compile-flags: -Copt-level=3
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![allow(incomplete_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::hint;
|
use std::hint;
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
// CHECK: @vtable.2 = {{.*}}, !type ![[TYPE2:[0-9]+]], !vcall_visibility ![[VCALL_VIS2:[0-9]+]]
|
// CHECK: @vtable.2 = {{.*}}, !type ![[TYPE2:[0-9]+]], !vcall_visibility ![[VCALL_VIS2:[0-9]+]]
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
//@ known-bug: #79409
|
|
||||||
|
|
||||||
#![feature(extern_types)]
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
extern {
|
|
||||||
type Device;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn make_device() -> Box<Device> {
|
|
||||||
Box::from_raw(0 as *mut _)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let d: Device = unsafe { *make_device() };
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ LL | let x = t.get();
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `<T as Get>::Value`
|
= help: the trait `Sized` is not implemented for `<T as Get>::Value`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider further restricting the associated type
|
help: consider further restricting the associated type
|
||||||
|
|
|
|
||||||
LL | fn foo<T:Get>(t: T) where <T as Get>::Value: Sized {
|
LL | fn foo<T:Get>(t: T) where <T as Get>::Value: Sized {
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
|
|
||||||
#![feature(unsized_fn_params, unsized_locals)]
|
#![feature(unsized_fn_params)]
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
|
async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
|
||||||
//~^ ERROR the size for values of type `(dyn Future<Output = T> + Unpin + 'static)` cannot be known at compilation time
|
//~^ ERROR the size for values of type `dyn Future<Output = T> + Unpin` cannot be known at compilation time
|
||||||
(&mut f).await
|
(&mut f).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,12 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
error[E0277]: the size for values of type `dyn Future<Output = T> + Unpin` cannot be known at compilation time
|
||||||
--> $DIR/awaiting-unsized-param.rs:3:31
|
--> $DIR/awaiting-unsized-param.rs:7:17
|
||||||
|
|
|
||||||
LL | #![feature(unsized_fn_params, unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Future<Output = T> + Unpin + 'static)` cannot be known at compilation time
|
|
||||||
--> $DIR/awaiting-unsized-param.rs:8:17
|
|
||||||
|
|
|
|
||||||
LL | async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
|
LL | async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
|
||||||
| ^^^^^ doesn't have a size known at compile-time
|
| ^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Future<Output = T> + Unpin + 'static)`
|
= help: the trait `Sized` is not implemented for `dyn Future<Output = T> + Unpin`
|
||||||
= note: all values captured by value by a closure must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
async fn f() {}
|
async fn f() {}
|
||||||
|
|
||||||
async fn g(x: Box<dyn std::fmt::Display>) {
|
async fn g(x: Box<dyn std::fmt::Display>) {
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/unsized-across-await.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
|
error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
|
||||||
--> $DIR/unsized-across-await.rs:9:9
|
--> $DIR/unsized-across-await.rs:6:9
|
||||||
|
|
|
|
||||||
LL | let _x = *x;
|
LL | let _x = *x;
|
||||||
| ^^ doesn't have a size known at compile-time
|
| ^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `dyn std::fmt::Display`
|
= help: the trait `Sized` is not implemented for `dyn std::fmt::Display`
|
||||||
= note: all values live across `await` must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let _x = *x;
|
||||||
|
LL + let _x = x;
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#![feature(coroutine_trait)]
|
#![feature(coroutine_trait)]
|
||||||
#![feature(coroutines)]
|
#![feature(coroutines)]
|
||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
use std::ops::Coroutine;
|
use std::ops::Coroutine;
|
||||||
|
|
||||||
fn capture() -> impl Coroutine {
|
fn capture() -> impl Coroutine {
|
||||||
let b: [u8] = *(Box::new([]) as Box<[u8]>);
|
let b: [u8] = *(Box::new([]) as Box<[u8]>); //~ERROR he size for values of type `[u8]` cannot be known at compilation time
|
||||||
#[coroutine]
|
#[coroutine]
|
||||||
move || {
|
move || {
|
||||||
println!("{:?}", &b);
|
println!("{:?}", &b);
|
||||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
|
||||||
|
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,16 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/unsized-capture-across-yield.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
--> $DIR/unsized-capture-across-yield.rs:12:27
|
--> $DIR/unsized-capture-across-yield.rs:7:9
|
||||||
|
|
|
|
||||||
LL | move || {
|
LL | let b: [u8] = *(Box::new([]) as Box<[u8]>);
|
||||||
| -- this closure captures all values by move
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | println!("{:?}", &b);
|
|
||||||
| ^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all values captured by value by a closure must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let b: &[u8] = *(Box::new([]) as Box<[u8]>);
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#![feature(coroutine_trait)]
|
#![feature(coroutine_trait)]
|
||||||
#![feature(coroutines)]
|
#![feature(coroutines)]
|
||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
use std::ops::Coroutine;
|
use std::ops::Coroutine;
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/unsized-local-across-yield.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
--> $DIR/unsized-local-across-yield.rs:11:13
|
--> $DIR/unsized-local-across-yield.rs:9:13
|
||||||
|
|
|
|
||||||
LL | let b: [u8] = *(Box::new([]) as Box<[u8]>);
|
LL | let b: [u8] = *(Box::new([]) as Box<[u8]>);
|
||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all values live across `yield` must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let b: &[u8] = *(Box::new([]) as Box<[u8]>);
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
// Check that E0161 is a hard error in all possible configurations that might
|
// Check that E0161 is a hard error in all possible configurations that might
|
||||||
// affect it.
|
// affect it.
|
||||||
|
|
||||||
//@ revisions: base ul
|
#![crate_type = "lib"]
|
||||||
//@[base] check-fail
|
|
||||||
//@[ul] check-pass
|
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![cfg_attr(ul, feature(unsized_locals))]
|
|
||||||
|
|
||||||
trait Bar {
|
trait Bar {
|
||||||
fn f(self);
|
fn f(self);
|
||||||
@@ -14,7 +9,5 @@ trait Bar {
|
|||||||
|
|
||||||
fn foo(x: Box<dyn Bar>) {
|
fn foo(x: Box<dyn Bar>) {
|
||||||
x.f();
|
x.f();
|
||||||
//[base]~^ ERROR E0161
|
//~^ ERROR E0161
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
error[E0161]: cannot move a value of type `dyn Bar`
|
error[E0161]: cannot move a value of type `dyn Bar`
|
||||||
--> $DIR/E0161.rs:16:5
|
--> $DIR/E0161.rs:11:5
|
||||||
|
|
|
|
||||||
LL | x.f();
|
LL | x.f();
|
||||||
| ^ the size of `dyn Bar` cannot be statically determined
|
| ^ the size of `dyn Bar` cannot be statically determined
|
||||||
15
tests/ui/extern/unsized-extern-derefmove.rs
vendored
Normal file
15
tests/ui/extern/unsized-extern-derefmove.rs
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//! Regression test for #79409
|
||||||
|
|
||||||
|
#![feature(extern_types)]
|
||||||
|
|
||||||
|
unsafe extern "C" {
|
||||||
|
type Device;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn make_device() -> Box<Device> {
|
||||||
|
Box::from_raw(0 as *mut _)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let d: Device = unsafe { *make_device() }; //~ERROR the size for values of type `Device` cannot be known at compilation time
|
||||||
|
}
|
||||||
16
tests/ui/extern/unsized-extern-derefmove.stderr
vendored
Normal file
16
tests/ui/extern/unsized-extern-derefmove.stderr
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
error[E0277]: the size for values of type `Device` cannot be known at compilation time
|
||||||
|
--> $DIR/unsized-extern-derefmove.rs:14:9
|
||||||
|
|
|
||||||
|
LL | let d: Device = unsafe { *make_device() };
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `Device`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let d: &Device = unsafe { *make_device() };
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -6,7 +6,6 @@ LL | &mut something
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[T]`
|
= help: the trait `Sized` is not implemented for `[T]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ LL | let some_generated_vec = (0..10).collect();
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[i32]`
|
= help: the trait `Sized` is not implemented for `[i32]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/collect-into-slice.rs:6:38
|
--> $DIR/collect-into-slice.rs:6:38
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
//@ dont-require-annotations: NOTE
|
//@ dont-require-annotations: NOTE
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize)]
|
#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
// This tests a few edge-cases around `arbitrary_self_types`. Most specifically,
|
// This tests a few edge-cases around `arbitrary_self_types`. Most specifically,
|
||||||
// it checks that the `ObjectCandidate` you get from method matching can't
|
// it checks that the `ObjectCandidate` you get from method matching can't
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:4:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:89:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:88:24
|
||||||
|
|
|
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
@@ -16,7 +7,7 @@ LL | let _seetype: () = z;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:106:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:105:24
|
||||||
|
|
|
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u64`
|
| -- ^ expected `()`, found `u64`
|
||||||
@@ -24,23 +15,23 @@ LL | let _seetype: () = z;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error[E0034]: multiple applicable items in scope
|
error[E0034]: multiple applicable items in scope
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:124:15
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:123:15
|
||||||
|
|
|
|
||||||
LL | let z = x.foo();
|
LL | let z = x.foo();
|
||||||
| ^^^ multiple `foo` found
|
| ^^^ multiple `foo` found
|
||||||
|
|
|
|
||||||
note: candidate #1 is defined in the trait `FinalFoo`
|
note: candidate #1 is defined in the trait `FinalFoo`
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:61:5
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:60:5
|
||||||
|
|
|
|
||||||
LL | fn foo(&self) -> u8;
|
LL | fn foo(&self) -> u8;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T`
|
note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T`
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:74:9
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:73:9
|
||||||
|
|
|
|
||||||
LL | fn foo(self) {}
|
LL | fn foo(self) {}
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
note: candidate #3 is defined in an impl of the trait `X` for the type `T`
|
note: candidate #3 is defined in an impl of the trait `X` for the type `T`
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:47:9
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:46:9
|
||||||
|
|
|
|
||||||
LL | fn foo(self: Smaht<Self, u64>) -> u64 {
|
LL | fn foo(self: Smaht<Self, u64>) -> u64 {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -61,7 +52,7 @@ LL + let z = X::foo(x);
|
|||||||
|
|
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:141:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:140:24
|
||||||
|
|
|
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u8`
|
| -- ^ expected `()`, found `u8`
|
||||||
@@ -69,7 +60,7 @@ LL | let _seetype: () = z;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:159:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:158:24
|
||||||
|
|
|
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
@@ -77,14 +68,14 @@ LL | let _seetype: () = z;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:176:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:175:24
|
||||||
|
|
|
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
| |
|
| |
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error: aborting due to 6 previous errors; 1 warning emitted
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0034, E0308.
|
Some errors have detailed explanations: E0034, E0308.
|
||||||
For more information about an error, try `rustc --explain E0034`.
|
For more information about an error, try `rustc --explain E0034`.
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
struct A;
|
struct A;
|
||||||
@@ -9,28 +7,24 @@ struct C;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let a: Box<[A]> = Box::new([A]);
|
let a: Box<[A]> = Box::new([A]);
|
||||||
match *a {
|
match *a {
|
||||||
//~^ ERROR cannot move out of type `[A]`, a non-copy slice
|
[a @ ..] => {} //~ERROR the size for values of type `[A]` cannot be known at compilation time [E0277]
|
||||||
[a @ ..] => {}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let b: Box<[A]> = Box::new([A, A, A]);
|
let b: Box<[A]> = Box::new([A, A, A]);
|
||||||
match *b {
|
match *b {
|
||||||
//~^ ERROR cannot move out of type `[A]`, a non-copy slice
|
[_, _, b @ .., _] => {} //~ERROR the size for values of type `[A]` cannot be known at compilation time [E0277]
|
||||||
[_, _, b @ .., _] => {}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `[C]` isn't `Copy`, even if `C` is.
|
// `[C]` isn't `Copy`, even if `C` is.
|
||||||
let c: Box<[C]> = Box::new([C]);
|
let c: Box<[C]> = Box::new([C]);
|
||||||
match *c {
|
match *c {
|
||||||
//~^ ERROR cannot move out of type `[C]`, a non-copy slice
|
[c @ ..] => {} //~ERROR the size for values of type `[C]` cannot be known at compilation time [E0277]
|
||||||
[c @ ..] => {}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let d: Box<[C]> = Box::new([C, C, C]);
|
let d: Box<[C]> = Box::new([C, C, C]);
|
||||||
match *d {
|
match *d {
|
||||||
//~^ ERROR cannot move out of type `[C]`, a non-copy slice
|
[_, _, d @ .., _] => {} //~ERROR the size for values of type `[C]` cannot be known at compilation time [E0277]
|
||||||
[_, _, d @ .., _] => {}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +1,39 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
error[E0277]: the size for values of type `[A]` cannot be known at compilation time
|
||||||
--> $DIR/move-out-of-slice-2.rs:1:12
|
--> $DIR/move-out-of-slice-2.rs:10:10
|
||||||
|
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0508]: cannot move out of type `[A]`, a non-copy slice
|
|
||||||
--> $DIR/move-out-of-slice-2.rs:11:11
|
|
||||||
|
|
|
||||||
LL | match *a {
|
|
||||||
| ^^ cannot move out of here
|
|
||||||
LL |
|
|
||||||
LL | [a @ ..] => {}
|
LL | [a @ ..] => {}
|
||||||
| -
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| data moved here
|
|
||||||
| move occurs because `a` has type `[A]`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
help: consider borrowing the pattern binding
|
= help: the trait `Sized` is not implemented for `[A]`
|
||||||
|
|
= note: all local variables must have a statically known size
|
||||||
LL | [ref a @ ..] => {}
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error[E0508]: cannot move out of type `[A]`, a non-copy slice
|
error[E0277]: the size for values of type `[A]` cannot be known at compilation time
|
||||||
--> $DIR/move-out-of-slice-2.rs:17:11
|
--> $DIR/move-out-of-slice-2.rs:15:16
|
||||||
|
|
|
|
||||||
LL | match *b {
|
|
||||||
| ^^ cannot move out of here
|
|
||||||
LL |
|
|
||||||
LL | [_, _, b @ .., _] => {}
|
LL | [_, _, b @ .., _] => {}
|
||||||
| -
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| data moved here
|
|
||||||
| move occurs because `b` has type `[A]`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
help: consider borrowing the pattern binding
|
= help: the trait `Sized` is not implemented for `[A]`
|
||||||
|
|
= note: all local variables must have a statically known size
|
||||||
LL | [_, _, ref b @ .., _] => {}
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error[E0508]: cannot move out of type `[C]`, a non-copy slice
|
error[E0277]: the size for values of type `[C]` cannot be known at compilation time
|
||||||
--> $DIR/move-out-of-slice-2.rs:25:11
|
--> $DIR/move-out-of-slice-2.rs:22:10
|
||||||
|
|
|
|
||||||
LL | match *c {
|
|
||||||
| ^^ cannot move out of here
|
|
||||||
LL |
|
|
||||||
LL | [c @ ..] => {}
|
LL | [c @ ..] => {}
|
||||||
| -
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| data moved here
|
|
||||||
| move occurs because `c` has type `[C]`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
help: consider borrowing the pattern binding
|
= help: the trait `Sized` is not implemented for `[C]`
|
||||||
|
|
= note: all local variables must have a statically known size
|
||||||
LL | [ref c @ ..] => {}
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error[E0508]: cannot move out of type `[C]`, a non-copy slice
|
error[E0277]: the size for values of type `[C]` cannot be known at compilation time
|
||||||
--> $DIR/move-out-of-slice-2.rs:31:11
|
--> $DIR/move-out-of-slice-2.rs:27:16
|
||||||
|
|
|
|
||||||
LL | match *d {
|
|
||||||
| ^^ cannot move out of here
|
|
||||||
LL |
|
|
||||||
LL | [_, _, d @ .., _] => {}
|
LL | [_, _, d @ .., _] => {}
|
||||||
| -
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| data moved here
|
|
||||||
| move occurs because `d` has type `[C]`, which does not implement the `Copy` trait
|
|
||||||
|
|
|
|
||||||
help: consider borrowing the pattern binding
|
= help: the trait `Sized` is not implemented for `[C]`
|
||||||
|
|
= note: all local variables must have a statically known size
|
||||||
LL | [_, _, ref d @ .., _] => {}
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0508`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -50,10 +50,6 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
|
|||||||
|
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
// This method isn't dyn-compatible yet. Unsized by-value `self` is dyn-compatible (but not
|
|
||||||
// callable without unsized_locals), but wrappers arond `Self` currently are not.
|
|
||||||
// FIXME (mikeyhew) uncomment this when unsized rvalues dyn-compatibility is implemented
|
|
||||||
// fn wrapper(self: Wrapper<Self>) -> i32;
|
|
||||||
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
|
||||||
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
|
||||||
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ LL | let x = *"";
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
|
||||||
LL - let x = *"";
|
LL - let x = *"";
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ fn main() {
|
|||||||
//~^ ERROR the size for values of type `str` cannot be known at compilation time
|
//~^ ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
//~| HELP consider not dereferencing the expression
|
//~| HELP consider not dereferencing the expression
|
||||||
//~| HELP the trait `Sized` is not implemented for `str`
|
//~| HELP the trait `Sized` is not implemented for `str`
|
||||||
//~| HELP unsized locals are gated as an unstable feature
|
|
||||||
bar(x);
|
bar(x);
|
||||||
S.baz(x);
|
S.baz(x);
|
||||||
bar(*"");
|
bar(*"");
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ LL | let x = *"";
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
|
||||||
LL - let x = *"";
|
LL - let x = *"";
|
||||||
@@ -30,7 +29,7 @@ LL + let x = "";
|
|||||||
|
|
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:22:9
|
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:21:9
|
||||||
|
|
|
|
||||||
LL | bar(*"");
|
LL | bar(*"");
|
||||||
| --- ^^^ doesn't have a size known at compile-time
|
| --- ^^^ doesn't have a size known at compile-time
|
||||||
@@ -50,7 +49,7 @@ LL + bar("");
|
|||||||
|
|
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:26:11
|
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:25:11
|
||||||
|
|
|
|
||||||
LL | S.baz(*"");
|
LL | S.baz(*"");
|
||||||
| --- ^^^ doesn't have a size known at compile-time
|
| --- ^^^ doesn't have a size known at compile-time
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ LL | let v = s[..2];
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | let v = &s[..2];
|
LL | let v = &s[..2];
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// Test that unsized locals uphold alignment requirements.
|
// Test that unsized locals uphold alignment requirements.
|
||||||
// Regression test for #71416.
|
// Regression test for #71416.
|
||||||
//@ run-pass
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
#[repr(align(256))]
|
#[repr(align(256))]
|
||||||
@@ -23,7 +20,7 @@ fn mk() -> Box<dyn Any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = *mk();
|
let x = *mk(); //~ERROR the size for values of type `dyn Any` cannot be known at compilation time
|
||||||
let dwncst = x.downcast_ref::<A>().unwrap();
|
let dwncst = x.downcast_ref::<A>().unwrap();
|
||||||
let addr = dwncst.f();
|
let addr = dwncst.f();
|
||||||
assert_eq!(addr as usize % 256, 0);
|
assert_eq!(addr as usize % 256, 0);
|
||||||
|
|||||||
17
tests/ui/unsized-locals/align.stderr
Normal file
17
tests/ui/unsized-locals/align.stderr
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the size for values of type `dyn Any` cannot be known at compilation time
|
||||||
|
--> $DIR/align.rs:23:9
|
||||||
|
|
|
||||||
|
LL | let x = *mk();
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn Any`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *mk();
|
||||||
|
LL + let x = mk();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
//@ run-pass
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String;
|
fn foo(self) -> String;
|
||||||
@@ -26,7 +23,7 @@ impl Foo for dyn FnMut() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
|
let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>); //~ERROR the size for values of type `[char]` cannot be known at compilation time
|
||||||
assert_eq!(&x.foo() as &str, "hello");
|
assert_eq!(&x.foo() as &str, "hello");
|
||||||
|
|
||||||
let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>;
|
let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>;
|
||||||
@@ -35,13 +32,13 @@ fn main() {
|
|||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
assert_eq!(&x.foo() as &str, "hello");
|
assert_eq!(&x.foo() as &str, "hello");
|
||||||
|
|
||||||
let x = *("hello".to_owned().into_boxed_str());
|
let x = *("hello".to_owned().into_boxed_str()); //~ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
assert_eq!(&x.foo() as &str, "hello");
|
assert_eq!(&x.foo() as &str, "hello");
|
||||||
|
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
assert_eq!(&x.foo() as &str, "hello");
|
assert_eq!(&x.foo() as &str, "hello");
|
||||||
|
|
||||||
let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
|
let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>); //~ERROR the size for values of type `dyn FnMut() -> String` cannot be known at compilation time
|
||||||
assert_eq!(&x.foo() as &str, "hello");
|
assert_eq!(&x.foo() as &str, "hello");
|
||||||
|
|
||||||
let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
|
let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
|
||||||
|
|||||||
45
tests/ui/unsized-locals/autoderef.stderr
Normal file
45
tests/ui/unsized-locals/autoderef.stderr
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
error[E0277]: the size for values of type `[char]` cannot be known at compilation time
|
||||||
|
--> $DIR/autoderef.rs:26:9
|
||||||
|
|
|
||||||
|
LL | let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[char]`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
|
||||||
|
LL + let x = (Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/autoderef.rs:35:9
|
||||||
|
|
|
||||||
|
LL | let x = *("hello".to_owned().into_boxed_str());
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *("hello".to_owned().into_boxed_str());
|
||||||
|
LL + let x = ("hello".to_owned().into_boxed_str());
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `dyn FnMut() -> String` cannot be known at compilation time
|
||||||
|
--> $DIR/autoderef.rs:41:9
|
||||||
|
|
|
||||||
|
LL | let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn FnMut() -> String`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
|
||||||
|
LL + let x = (Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
pub fn udrop<T: ?Sized>(_x: T) {}
|
pub fn udrop<T: ?Sized>(_x: T) {}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String;
|
fn foo(self) -> String;
|
||||||
@@ -16,28 +15,23 @@ fn drop_unsized<T: ?Sized>(_: T) {}
|
|||||||
fn main() {
|
fn main() {
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let y = *x;
|
let y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
drop_unsized(y);
|
drop_unsized(y);
|
||||||
println!("{}", &x);
|
println!("{}", &x);
|
||||||
//~^ERROR borrow of moved value
|
|
||||||
println!("{}", &y);
|
println!("{}", &y);
|
||||||
//~^ERROR borrow of moved value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let y = *x;
|
let y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
y.foo();
|
y.foo();
|
||||||
println!("{}", &x);
|
println!("{}", &x);
|
||||||
//~^ERROR borrow of moved value
|
|
||||||
println!("{}", &y);
|
println!("{}", &y);
|
||||||
//~^ERROR borrow of moved value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
x.foo();
|
x.foo();
|
||||||
println!("{}", &x);
|
println!("{}", &x);
|
||||||
//~^ERROR borrow of moved value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,85 +1,31 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/borrow-after-move.rs:1:12
|
--> $DIR/borrow-after-move.rs:18:13
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `x`
|
|
||||||
--> $DIR/borrow-after-move.rs:21:24
|
|
||||||
|
|
|
|
||||||
LL | let y = *x;
|
LL | let y = *x;
|
||||||
| -- value moved here
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | drop_unsized(y);
|
|
|
||||||
LL | println!("{}", &x);
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
| ^^ value borrowed here after move
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let y = *x;
|
||||||
|
LL + let y = x;
|
||||||
|
|
|
|
||||||
= note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `y`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/borrow-after-move.rs:23:24
|
--> $DIR/borrow-after-move.rs:26:13
|
||||||
|
|
|
|
||||||
LL | let y = *x;
|
LL | let y = *x;
|
||||||
| - move occurs because `y` has type `str`, which does not implement the `Copy` trait
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | drop_unsized(y);
|
|
||||||
| - value moved here
|
|
||||||
...
|
|
||||||
LL | println!("{}", &y);
|
|
||||||
| ^^ value borrowed here after move
|
|
||||||
|
|
|
|
||||||
note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
--> $DIR/borrow-after-move.rs:14:31
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let y = *x;
|
||||||
|
LL + let y = x;
|
||||||
|
|
|
|
||||||
LL | fn drop_unsized<T: ?Sized>(_: T) {}
|
|
||||||
| ------------ ^ this parameter takes ownership of the value
|
|
||||||
| |
|
|
||||||
| in this function
|
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `x`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/borrow-after-move.rs:31:24
|
|
||||||
|
|
|
||||||
LL | let y = *x;
|
|
||||||
| -- value moved here
|
|
||||||
LL | y.foo();
|
|
||||||
LL | println!("{}", &x);
|
|
||||||
| ^^ value borrowed here after move
|
|
||||||
|
|
|
||||||
= note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `y`
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
--> $DIR/borrow-after-move.rs:33:24
|
|
||||||
|
|
|
||||||
LL | let y = *x;
|
|
||||||
| - move occurs because `y` has type `str`, which does not implement the `Copy` trait
|
|
||||||
LL | y.foo();
|
|
||||||
| ----- `y` moved due to this method call
|
|
||||||
...
|
|
||||||
LL | println!("{}", &y);
|
|
||||||
| ^^ value borrowed here after move
|
|
||||||
|
|
|
||||||
note: `Foo::foo` takes ownership of the receiver `self`, which moves `y`
|
|
||||||
--> $DIR/borrow-after-move.rs:5:12
|
|
||||||
|
|
|
||||||
LL | fn foo(self) -> String;
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `x`
|
|
||||||
--> $DIR/borrow-after-move.rs:40:24
|
|
||||||
|
|
|
||||||
LL | let x = "hello".to_owned().into_boxed_str();
|
|
||||||
| - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
|
|
||||||
LL | x.foo();
|
|
||||||
| - value moved here
|
|
||||||
LL | println!("{}", &x);
|
|
||||||
| ^^ value borrowed here after move
|
|
||||||
|
|
|
||||||
help: consider cloning the value if the performance cost is acceptable
|
|
||||||
|
|
|
||||||
LL | x.clone().foo();
|
|
||||||
| ++++++++
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0382`.
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
//@ run-pass
|
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String;
|
fn foo(self) -> String;
|
||||||
}
|
}
|
||||||
@@ -16,7 +11,7 @@ impl Foo for A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = *(Box::new(A) as Box<dyn Foo>);
|
let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR the size for values of type `dyn Foo` cannot be known at compilation time
|
||||||
assert_eq!(x.foo(), format!("hello"));
|
assert_eq!(x.foo(), format!("hello"));
|
||||||
|
|
||||||
// I'm not sure whether we want this to work
|
// I'm not sure whether we want this to work
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
|
||||||
|
--> $DIR/by-value-trait-dyn-compatibility-rpass.rs:14:9
|
||||||
|
|
|
||||||
|
LL | let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn Foo`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
LL + let x = (Box::new(A) as Box<dyn Foo>);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
//@ run-pass
|
#![allow(internal_features)]
|
||||||
|
#![feature(unsized_fn_params)]
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String {
|
fn foo(self) -> String {
|
||||||
@@ -14,7 +12,7 @@ struct A;
|
|||||||
impl Foo for A {}
|
impl Foo for A {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = *(Box::new(A) as Box<dyn Foo>);
|
let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR the size for values of type `dyn Foo` cannot be known at compilation time
|
||||||
assert_eq!(x.foo(), format!("hello"));
|
assert_eq!(x.foo(), format!("hello"));
|
||||||
|
|
||||||
// I'm not sure whether we want this to work
|
// I'm not sure whether we want this to work
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
|
||||||
|
--> $DIR/by-value-trait-dyn-compatibility-with-default.rs:15:9
|
||||||
|
|
|
||||||
|
LL | let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn Foo`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
LL + let x = (Box::new(A) as Box<dyn Foo>);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String
|
fn foo(self) -> String
|
||||||
where
|
where
|
||||||
@@ -16,7 +13,7 @@ impl Foo for A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = *(Box::new(A) as Box<dyn Foo>);
|
let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR the size for values of type `dyn Foo` cannot be known at compilation time [E0277]
|
||||||
x.foo();
|
x.foo();
|
||||||
//~^ERROR the `foo` method cannot be invoked on a trait object
|
//~^ERROR the `foo` method cannot be invoked on a trait object
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/by-value-trait-dyn-compatibility.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: the `foo` method cannot be invoked on a trait object
|
error: the `foo` method cannot be invoked on a trait object
|
||||||
--> $DIR/by-value-trait-dyn-compatibility.rs:20:7
|
--> $DIR/by-value-trait-dyn-compatibility.rs:17:7
|
||||||
|
|
|
|
||||||
LL | Self: Sized;
|
LL | Self: Sized;
|
||||||
| ----- this has a `Sized` requirement
|
| ----- this has a `Sized` requirement
|
||||||
@@ -16,5 +7,20 @@ LL | Self: Sized;
|
|||||||
LL | x.foo();
|
LL | x.foo();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
|
||||||
|
--> $DIR/by-value-trait-dyn-compatibility.rs:16:9
|
||||||
|
|
|
||||||
|
LL | let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn Foo`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let x = *(Box::new(A) as Box<dyn Foo>);
|
||||||
|
LL + let x = (Box::new(A) as Box<dyn Foo>);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo(self) -> String;
|
fn foo(self) -> String;
|
||||||
@@ -16,39 +15,39 @@ fn drop_unsized<T: ?Sized>(_: T) {}
|
|||||||
fn main() {
|
fn main() {
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let y = *x;
|
let y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
|
drop_unsized(y);
|
||||||
drop_unsized(y);
|
drop_unsized(y);
|
||||||
drop_unsized(y); //~ERROR use of moved value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let _y = *x;
|
let _y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
drop_unsized(x); //~ERROR use of moved value
|
drop_unsized(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
drop_unsized(x);
|
drop_unsized(x);
|
||||||
let _y = *x; //~ERROR use of moved value
|
let _y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let y = *x;
|
let y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
|
y.foo();
|
||||||
y.foo();
|
y.foo();
|
||||||
y.foo(); //~ERROR use of moved value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
let _y = *x;
|
let _y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
x.foo(); //~ERROR use of moved value
|
x.foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let x = "hello".to_owned().into_boxed_str();
|
let x = "hello".to_owned().into_boxed_str();
|
||||||
x.foo();
|
x.foo();
|
||||||
let _y = *x; //~ERROR use of moved value
|
let _y = *x; //~ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +1,87 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:1:12
|
--> $DIR/double-move.rs:18:13
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `y`
|
|
||||||
--> $DIR/double-move.rs:21:22
|
|
||||||
|
|
|
|
||||||
LL | let y = *x;
|
LL | let y = *x;
|
||||||
| - move occurs because `y` has type `str`, which does not implement the `Copy` trait
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | drop_unsized(y);
|
|
||||||
| - value moved here
|
|
||||||
LL | drop_unsized(y);
|
|
||||||
| ^ value used here after move
|
|
||||||
|
|
|
|
||||||
note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
--> $DIR/double-move.rs:14:31
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let y = *x;
|
||||||
|
LL + let y = x;
|
||||||
|
|
|
|
||||||
LL | fn drop_unsized<T: ?Sized>(_: T) {}
|
|
||||||
| ------------ ^ this parameter takes ownership of the value
|
|
||||||
| |
|
|
||||||
| in this function
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `x`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:27:22
|
--> $DIR/double-move.rs:25:13
|
||||||
|
|
|
|
||||||
LL | let _y = *x;
|
LL | let _y = *x;
|
||||||
| -- value moved here
|
| ^^ doesn't have a size known at compile-time
|
||||||
LL | drop_unsized(x);
|
|
|
||||||
| ^ value used here after move
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let _y = *x;
|
||||||
|
LL + let _y = x;
|
||||||
|
|
|
|
||||||
= note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `*x`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:33:18
|
--> $DIR/double-move.rs:32:13
|
||||||
|
|
|
|
||||||
LL | let x = "hello".to_owned().into_boxed_str();
|
|
||||||
| - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
|
|
||||||
LL | drop_unsized(x);
|
|
||||||
| - value moved here
|
|
||||||
LL | let _y = *x;
|
LL | let _y = *x;
|
||||||
| ^^ value used here after move
|
| ^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let _y = *x;
|
||||||
|
LL + let _y = x;
|
||||||
|
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `y`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:40:9
|
--> $DIR/double-move.rs:37:13
|
||||||
|
|
|
|
||||||
LL | let y = *x;
|
LL | let y = *x;
|
||||||
| - move occurs because `y` has type `str`, which does not implement the `Copy` trait
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | y.foo();
|
|
||||||
| ----- `y` moved due to this method call
|
|
||||||
LL | y.foo();
|
|
||||||
| ^ value used here after move
|
|
||||||
|
|
|
|
||||||
note: `Foo::foo` takes ownership of the receiver `self`, which moves `y`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
--> $DIR/double-move.rs:5:12
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let y = *x;
|
||||||
|
LL + let y = x;
|
||||||
|
|
|
|
||||||
LL | fn foo(self) -> String;
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `x`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:46:9
|
--> $DIR/double-move.rs:44:13
|
||||||
|
|
|
|
||||||
LL | let _y = *x;
|
LL | let _y = *x;
|
||||||
| -- value moved here
|
| ^^ doesn't have a size known at compile-time
|
||||||
LL | x.foo();
|
|
|
||||||
| ^ value used here after move
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let _y = *x;
|
||||||
|
LL + let _y = x;
|
||||||
|
|
|
|
||||||
= note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
|
|
||||||
|
|
||||||
error[E0382]: use of moved value: `*x`
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/double-move.rs:52:18
|
--> $DIR/double-move.rs:51:13
|
||||||
|
|
|
|
||||||
LL | let x = "hello".to_owned().into_boxed_str();
|
|
||||||
| - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
|
|
||||||
LL | x.foo();
|
|
||||||
| - value moved here
|
|
||||||
LL | let _y = *x;
|
LL | let _y = *x;
|
||||||
| ^^ value used here after move
|
| ^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
||||||
|
|
|
||||||
|
LL - let _y = *x;
|
||||||
|
LL + let _y = x;
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors; 1 warning emitted
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0382`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// ICE size_and_align_of::<[closure@test.rs:15:5: 17:7]> not supported #88212
|
// ICE size_and_align_of::<[closure@test.rs:15:5: 17:7]> not supported #88212
|
||||||
// issue: rust-lang/rust#88212
|
// issue: rust-lang/rust#88212
|
||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
trait Example {}
|
trait Example {}
|
||||||
struct Foo();
|
struct Foo();
|
||||||
@@ -13,9 +11,8 @@ fn example() -> Box<dyn Example> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: dyn Example = *example();
|
let x: dyn Example = *example(); //~ERROR the size for values of type `dyn Example` cannot be known at compilation time
|
||||||
(move || {
|
(move || {
|
||||||
let _y = x;
|
let _y = x; //~ERROR the size for values of type `dyn Example` cannot be known at compilation time
|
||||||
//~^ ERROR the size for values of type `dyn Example` cannot be known at compilation time
|
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `dyn Example` cannot be known at compilation time
|
error[E0277]: the size for values of type `dyn Example` cannot be known at compilation time
|
||||||
--> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:18:18
|
--> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:14:9
|
||||||
|
|
|
|
||||||
LL | (move || {
|
LL | let x: dyn Example = *example();
|
||||||
| -- this closure captures all values by move
|
| ^ doesn't have a size known at compile-time
|
||||||
LL | let _y = x;
|
|
||||||
| ^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `dyn Example`
|
= help: the trait `Sized` is not implemented for `dyn Example`
|
||||||
= note: all values captured by value by a closure must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let x: &dyn Example = *example();
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error[E0277]: the size for values of type `dyn Example` cannot be known at compilation time
|
||||||
|
--> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:16:13
|
||||||
|
|
|
||||||
|
LL | let _y = x;
|
||||||
|
| ^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `dyn Example`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
#![feature(unsized_locals)]
|
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
struct Test([i32]);
|
struct Test([i32]);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/issue-30276-feature-flagged.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/issue-30276-feature-flagged.rs:7:29
|
--> $DIR/issue-30276-feature-flagged.rs:4:29
|
||||||
|
|
|
|
||||||
LL | let _x: fn(_) -> Test = Test;
|
LL | let _x: fn(_) -> Test = Test;
|
||||||
| ^^^^ doesn't have a size known at compile-time
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
@@ -17,6 +8,6 @@ LL | let _x: fn(_) -> Test = Test;
|
|||||||
= note: all function arguments must have a statically known size
|
= note: all function arguments must have a statically known size
|
||||||
= help: unsized fn params are gated as an unstable feature
|
= help: unsized fn params are gated as an unstable feature
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
//~^ WARN the feature `unsized_locals` is incomplete
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
struct A<X: ?Sized>(X);
|
struct A<X: ?Sized>(X);
|
||||||
|
|||||||
@@ -1,26 +1,17 @@
|
|||||||
warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/issue-50940-with-feature.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(unsized_locals, unsized_fn_params)]
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/issue-50940-with-feature.rs:6:5
|
--> $DIR/issue-50940-with-feature.rs:5:5
|
||||||
|
|
|
|
||||||
LL | A as fn(str) -> A<str>;
|
LL | A as fn(str) -> A<str>;
|
||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: within `A<str>`, the trait `Sized` is not implemented for `str`
|
= help: within `A<str>`, the trait `Sized` is not implemented for `str`
|
||||||
note: required because it appears within the type `A<str>`
|
note: required because it appears within the type `A<str>`
|
||||||
--> $DIR/issue-50940-with-feature.rs:5:12
|
--> $DIR/issue-50940-with-feature.rs:4:12
|
||||||
|
|
|
|
||||||
LL | struct A<X: ?Sized>(X);
|
LL | struct A<X: ?Sized>(X);
|
||||||
| ^
|
| ^
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
//@ run-pass
|
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let foo: Box<[u8]> = Box::new(*b"foo");
|
let foo: Box<[u8]> = Box::new(*b"foo");
|
||||||
let foo: [u8] = *foo;
|
let foo: [u8] = *foo; //~ERROR the size for values of type `[u8]` cannot be known at compilation time [E0277]
|
||||||
assert_eq!(&foo, b"foo" as &[u8]);
|
assert_eq!(&foo, b"foo" as &[u8]);
|
||||||
}
|
}
|
||||||
|
|||||||
16
tests/ui/unsized-locals/reference-unsized-locals.stderr
Normal file
16
tests/ui/unsized-locals/reference-unsized-locals.stderr
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/reference-unsized-locals.rs:3:9
|
||||||
|
|
|
||||||
|
LL | let foo: [u8] = *foo;
|
||||||
|
| ^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let foo: &[u8] = *foo;
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
//@ run-pass
|
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(unsized_locals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let foo: Box<[u8]> = Box::new(*b"foo");
|
let foo: Box<[u8]> = Box::new(*b"foo");
|
||||||
let _foo: [u8] = *foo;
|
let _foo: [u8] = *foo; //~ERROR the size for values of type `[u8]` cannot be known at compilation time [E0277]
|
||||||
}
|
}
|
||||||
|
|||||||
16
tests/ui/unsized-locals/simple-unsized-locals.stderr
Normal file
16
tests/ui/unsized-locals/simple-unsized-locals.stderr
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/simple-unsized-locals.rs:3:9
|
||||||
|
|
|
||||||
|
LL | let _foo: [u8] = *foo;
|
||||||
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
|
= note: all local variables must have a statically known size
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | let _foo: &[u8] = *foo;
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
@@ -6,7 +6,6 @@ LL | let x: [u8] = vec!(1, 2, 3)[..];
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | let x: &[u8] = vec!(1, 2, 3)[..];
|
LL | let x: &[u8] = vec!(1, 2, 3)[..];
|
||||||
@@ -51,7 +50,6 @@ LL | let x: [u8] = &vec!(1, 2, 3)[..];
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | let x: &[u8] = &vec!(1, 2, 3)[..];
|
LL | let x: &[u8] = &vec!(1, 2, 3)[..];
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
#![allow(incomplete_features, unused_braces, unused_parens)]
|
#![allow(internal_features, unused_braces, unused_parens)]
|
||||||
#![feature(unsized_locals, unsized_fn_params)]
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
struct A<X: ?Sized>(#[allow(dead_code)] X);
|
struct A<X: ?Sized>(#[allow(dead_code)] X);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ LL | fn f1(box box _b: Box<Box<[u8]>>) {}
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/unsized-locals-using-unsized-fn-params.rs:8:12
|
--> $DIR/unsized-locals-using-unsized-fn-params.rs:8:12
|
||||||
@@ -16,7 +15,6 @@ LL | fn f2((_x, _y): (i32, [i32])) {}
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[i32]`
|
= help: the trait `Sized` is not implemented for `[i32]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
--> $DIR/unsized-locals-using-unsized-fn-params.rs:13:9
|
--> $DIR/unsized-locals-using-unsized-fn-params.rs:13:9
|
||||||
@@ -26,7 +24,6 @@ LL | let _foo: [u8] = *foo;
|
|||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u8]`
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | let _foo: &[u8] = *foo;
|
LL | let _foo: &[u8] = *foo;
|
||||||
|
|||||||
4
tests/ui/unsized-locals/yote.rs
Normal file
4
tests/ui/unsized-locals/yote.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
|
||||||
|
|
||||||
|
#![feature(unsized_locals)] //~ERROR feature has been removed
|
||||||
|
#![crate_type = "lib"]
|
||||||
12
tests/ui/unsized-locals/yote.stderr
Normal file
12
tests/ui/unsized-locals/yote.stderr
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
error[E0557]: feature has been removed
|
||||||
|
--> $DIR/yote.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(unsized_locals)]
|
||||||
|
| ^^^^^^^^^^^^^^ feature has been removed
|
||||||
|
|
|
||||||
|
= note: removed in CURRENT_RUSTC_VERSION (you are using $RUSTC_VERSION)
|
||||||
|
= note: removed due to implementation concerns; see https://github.com/rust-lang/rust/issues/111942
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0557`.
|
||||||
@@ -8,7 +8,6 @@ LL | let y: Y;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
|
LL - fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
|
||||||
@@ -60,7 +59,6 @@ LL | let y: X;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
|
LL - fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
|
||||||
@@ -96,7 +94,6 @@ LL | let y: X = *x1;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
@@ -117,7 +114,6 @@ LL | let y = *x2;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
@@ -139,7 +135,6 @@ LL | let (y, z) = (*x3, 4);
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
@@ -155,7 +150,6 @@ LL | let y: X = *x1;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
@@ -176,7 +170,6 @@ LL | let y = *x2;
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
@@ -198,7 +191,6 @@ LL | let (y, z) = (*x3, 4);
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= note: all local variables must have a statically known size
|
= note: all local variables must have a statically known size
|
||||||
= help: unsized locals are gated as an unstable feature
|
|
||||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
|
||||||
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user