Skip to content

Make tuples implicitly sized #138093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1918,12 +1918,11 @@ impl<'tcx> Ty<'tcx> {
| ty::CoroutineClosure(..)
| ty::Never
| ty::Error(_)
| ty::Tuple(_)
| ty::Dynamic(_, _, ty::DynStar) => true,

ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false,

ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.is_trivially_sized(tcx)),

ty::Adt(def, args) => def
.sized_constraint(tcx)
.is_none_or(|ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)),
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,6 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

ty::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
f();
ty = last_ty;
}

ty::Tuple(_) => break,

ty::Pat(inner, _) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ where
match ty.kind() {
// impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, !
// impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure
// impl Sized for tuple
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Uint(_)
| ty::Int(_)
Expand All @@ -126,6 +127,7 @@ where
| ty::CoroutineClosure(..)
| ty::Never
| ty::Dynamic(_, _, ty::DynStar)
| ty::Tuple(_)
| ty::Error(_) => Ok(ty::Binder::dummy(vec![])),

ty::Str
Expand All @@ -143,10 +145,6 @@ where

ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])),

// impl Sized for ()
// impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))),

// impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
// `sized_constraint(Adt)` is the deepest struct trail that can be determined
// by the definition of `Adt`, independent of the generic args.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2712,9 +2712,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
ObligationCauseCode::ArrayLen(array_ty) => {
err.note(format!("the length of array `{array_ty}` must be type `usize`"));
}
ObligationCauseCode::TupleElem => {
err.note("only the last element of a tuple may have a dynamically sized type");
}
ObligationCauseCode::TupleElem => {}
ObligationCauseCode::WhereClause(item_def_id, span)
| ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
| ObligationCauseCode::HostEffectInExpr(item_def_id, span, ..)
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2090,17 +2090,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
| ty::CoroutineClosure(..)
| ty::Never
| ty::Dynamic(_, _, ty::DynStar)
| ty::Tuple(_)
| ty::Error(_) => {
// safe for everything
Where(ty::Binder::dummy(Vec::new()))
}

ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,

ty::Tuple(tys) => Where(
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
),

ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])),

ty::Adt(def, args) => {
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,10 +749,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
}

ty::Tuple(tys) => {
if let Some((_last, rest)) = tys.split_last() {
for &elem in rest {
self.require_sized(elem, ObligationCauseCode::TupleElem);
}
for elem in tys {
self.require_sized(elem, ObligationCauseCode::TupleElem);
}
}

Expand Down
7 changes: 1 addition & 6 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2851,7 +2851,7 @@ macro_rules! tuple {
maybe_tuple_doc! {
$($name)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($name:Debug),+> Debug for ($($name,)+) where last_type!($($name,)+): ?Sized {
impl<$($name:Debug),+> Debug for ($($name,)+) {
#[allow(non_snake_case, unused_assignments)]
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
let mut builder = f.debug_tuple("");
Expand Down Expand Up @@ -2882,11 +2882,6 @@ macro_rules! maybe_tuple_doc {
};
}

macro_rules! last_type {
($a:ident,) => { $a };
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
}

tuple! { E, D, C, B, A, Z, Y, X, W, V, U, T, }

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
7 changes: 1 addition & 6 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ mod impls {
maybe_tuple_doc! {
$($name)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
impl<$($name: Hash),+> Hash for ($($name,)+) {
#[allow(non_snake_case)]
#[inline]
fn hash<S: Hasher>(&self, state: &mut S) {
Expand All @@ -912,11 +912,6 @@ mod impls {
};
}

macro_rules! last_type {
($a:ident,) => { $a };
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
}

impl_hash_tuple! {}
impl_hash_tuple! { T }
impl_hash_tuple! { T B }
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ops/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,7 +1211,7 @@ pub enum OneSidedRangeBound {
/// Types that implement `OneSidedRange<T>` must return `Bound::Unbounded`
/// from one of `RangeBounds::start_bound` or `RangeBounds::end_bound`.
#[unstable(feature = "one_sided_range", issue = "69780")]
pub trait OneSidedRange<T: ?Sized>: RangeBounds<T> {
pub trait OneSidedRange<T>: RangeBounds<T> {
/// An internal-only helper function for `split_off` and
/// `split_off_mut` that returns the bound of the one-sided range.
fn bound(self) -> (OneSidedRangeBound, T);
Expand Down
16 changes: 1 addition & 15 deletions library/core/src/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ macro_rules! tuple_impls {
maybe_tuple_doc! {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T: PartialEq),+> PartialEq for ($($T,)+)
where
last_type!($($T,)+): ?Sized
{
impl<$($T: PartialEq),+> PartialEq for ($($T,)+) {
#[inline]
fn eq(&self, other: &($($T,)+)) -> bool {
$( ${ignore($T)} self.${index()} == other.${index()} )&&+
Expand All @@ -41,8 +38,6 @@ macro_rules! tuple_impls {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T: Eq),+> Eq for ($($T,)+)
where
last_type!($($T,)+): ?Sized
{}
}

Expand Down Expand Up @@ -71,8 +66,6 @@ macro_rules! tuple_impls {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
where
last_type!($($T,)+): ?Sized
{
#[inline]
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
Expand Down Expand Up @@ -101,8 +94,6 @@ macro_rules! tuple_impls {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T: Ord),+> Ord for ($($T,)+)
where
last_type!($($T,)+): ?Sized
{
#[inline]
fn cmp(&self, other: &($($T,)+)) -> Ordering {
Expand Down Expand Up @@ -205,9 +196,4 @@ macro_rules! lexical_cmp {
($a:expr, $b:expr) => { ($a).cmp(&$b) };
}

macro_rules! last_type {
($a:ident,) => { $a };
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
}

tuple_impls!(E D C B A Z Y X W V U T);
2 changes: 0 additions & 2 deletions src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2094,7 +2094,6 @@ ui/issues/issue-32950.rs
ui/issues/issue-32995-2.rs
ui/issues/issue-32995.rs
ui/issues/issue-33202.rs
ui/issues/issue-33241.rs
ui/issues/issue-33287.rs
ui/issues/issue-33293.rs
ui/issues/issue-33387.rs
Expand Down Expand Up @@ -2247,7 +2246,6 @@ ui/issues/issue-42007.rs
ui/issues/issue-4208.rs
ui/issues/issue-42106.rs
ui/issues/issue-42148.rs
ui/issues/issue-42210.rs
ui/issues/issue-4228.rs
ui/issues/issue-42312.rs
ui/issues/issue-42453.rs
Expand Down
2 changes: 1 addition & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ignore::Walk;
const ENTRY_LIMIT: u32 = 901;
// FIXME: The following limits should be reduced eventually.

const ISSUES_ENTRY_LIMIT: u32 = 1634;
const ISSUES_ENTRY_LIMIT: u32 = 1632;

const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files
Expand Down
1 change: 0 additions & 1 deletion tests/ui/abi/compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ mod unsized_ {
use super::*;
test_transparent_unsized!(str_, str);
test_transparent_unsized!(slice, [u8]);
test_transparent_unsized!(slice_with_prefix, (usize, [u8]));
test_transparent_unsized!(dyn_trait, dyn Any);
}

Expand Down
1 change: 0 additions & 1 deletion tests/ui/abi/debug.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: only the last element of a tuple may have a dynamically sized type

error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
--> $DIR/debug.rs:29:5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::marker::PhantomData;
use std::ops::Deref;

pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>);
pub struct Cow<'a, B: ?Sized>(PhantomData<&'a ()>, PhantomData<B>);

/// Trait for moving into a `Cow`
pub trait IntoCow<'a, B: ?Sized> {
Expand All @@ -14,7 +14,7 @@ pub trait IntoCow<'a, B: ?Sized> {

impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
fn into_cow(self) -> Cow<'a, B> {
Cow(PhantomData)
Cow(PhantomData, PhantomData)
}
}

Expand All @@ -28,7 +28,7 @@ impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
//~^ ERROR E0119
fn into_cow(self) -> Cow<'a, B> {
Cow(PhantomData)
Cow(PhantomData, PhantomData)
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/ui/async-await/awaiting-unsized-param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::future::Future;

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
}

Expand Down
10 changes: 9 additions & 1 deletion tests/ui/async-await/awaiting-unsized-param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ LL | async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
= help: the trait `Sized` is not implemented for `(dyn Future<Output = T> + Unpin + 'static)`
= note: all values captured by value by a closure must have a statically known size

error: aborting due to 1 previous error; 1 warning emitted
error[E0277]: the size for values of type `dyn Future<Output = T> + Unpin` cannot be known at compilation time
--> $DIR/awaiting-unsized-param.rs:8:1
|
LL | async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Future<Output = T> + Unpin`

error: aborting due to 2 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0277`.
8 changes: 8 additions & 0 deletions tests/ui/box/into-boxed-slice-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ LL | let _ = Box::into_boxed_slice(boxed_slice);
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Box::<T, A>::into_boxed_slice`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: use a unary tuple instead
|
LL | let _ = Box::into_boxed_slice((boxed_slice,));
| + ++

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/into-boxed-slice-fail.rs:7:13
Expand All @@ -30,6 +34,10 @@ LL | let _ = Box::into_boxed_slice(boxed_trait);
= help: the trait `Sized` is not implemented for `dyn Debug`
note: required by a bound in `Box::<T, A>::into_boxed_slice`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
help: use a unary tuple instead
|
LL | let _ = Box::into_boxed_slice((boxed_trait,));
| + ++

error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
--> $DIR/into-boxed-slice-fail.rs:11:13
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/closures/issue-111932.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ LL | println!("{:?}", foo);
note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'_>::new_debug`
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use a unary tuple instead
|
LL | println!("{:?}", (foo,));
| + ++

error: aborting due to 2 previous errors

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/const-generics/occurs-check/unused-substs-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct Foo<const N: usize>;

trait Bind<T> {
fn bind() -> (T, Self);
//~^ ERROR: the size for values of type `Self` cannot be known at compilation time
//~| NOTE: doesn't have a size known at compile-time
}

// `N` has to be `ConstKind::Unevaluated`.
Expand Down
18 changes: 15 additions & 3 deletions tests/ui/const-generics/occurs-check/unused-substs-2.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/unused-substs-2.rs:11:18
|
LL | fn bind() -> (T, Self);
| ^^^^^^^^^ doesn't have a size known at compile-time
|
help: consider further restricting `Self`
|
LL | fn bind() -> (T, Self) where Self: Sized;
| +++++++++++++++++

error[E0308]: mismatched types
--> $DIR/unused-substs-2.rs:22:24
--> $DIR/unused-substs-2.rs:24:24
|
LL | let (mut t, foo) = Foo::bind();
| ^^^^^^^^^^^ cyclic type of infinite size

error: aborting due to 1 previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
12 changes: 1 addition & 11 deletions tests/ui/dst/dst-bad-coerce2.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Attempt to change the mutability as well as unsizing.

struct Fat<T: ?Sized> {
ptr: T
ptr: T,
}

struct Foo;
Expand All @@ -18,14 +18,4 @@ pub fn main() {
let f1 = Fat { ptr: Foo };
let f2: &Fat<Foo> = &f1;
let f3: &mut Fat<dyn Bar> = f2; //~ ERROR mismatched types

// Tuple with a vec of ints.
let f1 = ([1, 2, 3],);
let f2: &([isize; 3],) = &f1;
let f3: &mut ([isize],) = f2; //~ ERROR mismatched types

// Tuple with a trait.
let f1 = (Foo,);
let f2: &(Foo,) = &f1;
let f3: &mut (dyn Bar,) = f2; //~ ERROR mismatched types
}
Loading
Loading