about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorDavid Wood <david.wood2@arm.com>2025-02-27 21:19:51 +0000
committerDavid Wood <david.wood2@arm.com>2025-06-16 23:04:33 +0000
commit86ab2b60cd22f6190eb586c889f8a2504f0d926b (patch)
treec379a930de63e5cb21b83110dccd82c1c3874a25 /tests
parentf0b84b8dcfc15c3936256ccb438b1d050620ff3c (diff)
hir_analysis: add `{Meta,Pointee}Sized` bounds
Opting-out of `Sized` with `?Sized` is now equivalent to adding a
`MetaSized` bound, and adding a `MetaSized` or `PointeeSized` bound
is equivalent to removing the default `Sized` bound - this commit
implements this change in `rustc_hir_analysis::hir_ty_lowering`.

`MetaSized` is also added as a supertrait of all traits, as this is
necessary to preserve backwards compatibility.

Unfortunately, non-global where clauses being preferred over item bounds
(where `PointeeSized` bounds would be proven) - which can result in
errors when a `PointeeSized` supertrait/bound/predicate is added to some
items. Rather than `PointeeSized` being a bound on everything, it can
be the absence of a bound on everything, as `?Sized` was.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/feature-gates/feature-gate-sized-hierarchy.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr6
-rw-r--r--tests/ui/sized-hierarchy/alias-bounds.rs28
-rw-r--r--tests/ui/sized-hierarchy/default-bound.rs49
-rw-r--r--tests/ui/sized-hierarchy/default-bound.stderr88
-rw-r--r--tests/ui/sized-hierarchy/default-supertrait.rs61
-rw-r--r--tests/ui/sized-hierarchy/default-supertrait.stderr125
-rw-r--r--tests/ui/sized-hierarchy/extern-type-behind-ptr.rs20
-rw-r--r--tests/ui/sized-hierarchy/impls.rs14
-rw-r--r--tests/ui/sized-hierarchy/impls.stderr108
-rw-r--r--tests/ui/sized-hierarchy/pointee-supertrait.rs28
-rw-r--r--tests/ui/sized-hierarchy/trait-aliases.rs9
12 files changed, 475 insertions, 65 deletions
diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs
index 5e2a76ba254..33688c2e2ce 100644
--- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs
+++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs
@@ -3,8 +3,8 @@
 
 use std::marker::{MetaSized, PointeeSized};
 
-fn needs_pointeesized<T: ?Sized + PointeeSized>() {}
-fn needs_metasized<T: ?Sized + MetaSized>() {}
+fn needs_pointeesized<T: PointeeSized>() {}
+fn needs_metasized<T: MetaSized>() {}
 fn needs_sized<T: Sized>() {}
 
 fn main() {
diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
index 8cbea3b6ba4..6a35fcfb0e8 100644
--- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
+++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
@@ -19,10 +19,10 @@ LL |     needs_metasized::<Foo>();
    |
    = help: the trait `MetaSized` is not implemented for `main::Foo`
 note: required by a bound in `needs_metasized`
-  --> $DIR/feature-gate-sized-hierarchy.rs:7:32
+  --> $DIR/feature-gate-sized-hierarchy.rs:7:23
    |
-LL | fn needs_metasized<T: ?Sized + MetaSized>() {}
-   |                                ^^^^^^^^^ required by this bound in `needs_metasized`
+LL | fn needs_metasized<T: MetaSized>() {}
+   |                       ^^^^^^^^^ required by this bound in `needs_metasized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
   --> $DIR/feature-gate-sized-hierarchy.rs:27:19
diff --git a/tests/ui/sized-hierarchy/alias-bounds.rs b/tests/ui/sized-hierarchy/alias-bounds.rs
new file mode 100644
index 00000000000..87b4bab11b7
--- /dev/null
+++ b/tests/ui/sized-hierarchy/alias-bounds.rs
@@ -0,0 +1,28 @@
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+#![feature(sized_hierarchy)]
+
+use std::marker::{PointeeSized, MetaSized};
+
+trait Id: PointeeSized {
+    type This: PointeeSized;
+}
+
+impl<T: PointeeSized> Id for T {
+    type This = T;
+}
+
+fn requires_metasized<T: MetaSized>() {}
+
+fn foo<T>()
+where
+    T: PointeeSized,
+    <T as Id>::This: Sized
+{
+    // `T: Sized` from where bounds (`T: PointeeSized` removes any default bounds and
+    // `<T as Id>::This: Sized` normalizes to `T: Sized`). This should trivially satisfy
+    // `T: MetaSized`.
+    requires_metasized::<T>();
+}
diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs
new file mode 100644
index 00000000000..12b2eb2b5c1
--- /dev/null
+++ b/tests/ui/sized-hierarchy/default-bound.rs
@@ -0,0 +1,49 @@
+//@ check-fail
+#![feature(extern_types, sized_hierarchy)]
+
+use std::marker::{MetaSized, PointeeSized};
+
+fn bare<T>() {}
+
+
+fn sized<T: Sized>() {}
+
+fn neg_sized<T: ?Sized>() {}
+
+
+fn metasized<T: MetaSized>() {}
+
+fn neg_metasized<T: ?MetaSized>() {}
+//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+
+fn pointeesized<T: PointeeSized>() { }
+
+fn neg_pointeesized<T: ?PointeeSized>() { }
+//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+
+fn main() {
+    // Functions which should have a `T: Sized` bound - check for an error given a non-Sized type:
+
+    bare::<[u8]>();
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+    sized::<[u8]>();
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+    metasized::<[u8]>();
+    pointeesized::<[u8]>();
+
+    // Functions which should have a `T: MetaSized` bound - check for an error given a
+    // non-MetaSized type:
+    unsafe extern "C" {
+        type Foo;
+    }
+
+    bare::<Foo>();
+    //~^ ERROR the size for values of type `main::Foo` cannot be known
+    sized::<Foo>();
+    //~^ ERROR the size for values of type `main::Foo` cannot be known
+    metasized::<Foo>();
+    //~^ ERROR the size for values of type `main::Foo` cannot be known
+    pointeesized::<Foo>();
+}
diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr
new file mode 100644
index 00000000000..22f0fa29d3e
--- /dev/null
+++ b/tests/ui/sized-hierarchy/default-bound.stderr
@@ -0,0 +1,88 @@
+error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/default-bound.rs:16:21
+   |
+LL | fn neg_metasized<T: ?MetaSized>() {}
+   |                     ^^^^^^^^^^
+
+error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/default-bound.rs:22:24
+   |
+LL | fn neg_pointeesized<T: ?PointeeSized>() { }
+   |                        ^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/default-bound.rs:29:12
+   |
+LL |     bare::<[u8]>();
+   |            ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by an implicit `Sized` bound in `bare`
+  --> $DIR/default-bound.rs:6:9
+   |
+LL | fn bare<T>() {}
+   |         ^ required by the implicit `Sized` requirement on this type parameter in `bare`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn bare<T: ?Sized>() {}
+   |          ++++++++
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/default-bound.rs:31:13
+   |
+LL |     sized::<[u8]>();
+   |             ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `sized`
+  --> $DIR/default-bound.rs:9:13
+   |
+LL | fn sized<T: Sized>() {}
+   |             ^^^^^ required by this bound in `sized`
+
+error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
+  --> $DIR/default-bound.rs:42:12
+   |
+LL |     bare::<Foo>();
+   |            ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `main::Foo`
+note: required by an implicit `Sized` bound in `bare`
+  --> $DIR/default-bound.rs:6:9
+   |
+LL | fn bare<T>() {}
+   |         ^ required by the implicit `Sized` requirement on this type parameter in `bare`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn bare<T: ?Sized>() {}
+   |          ++++++++
+
+error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
+  --> $DIR/default-bound.rs:44:13
+   |
+LL |     sized::<Foo>();
+   |             ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `main::Foo`
+note: required by a bound in `sized`
+  --> $DIR/default-bound.rs:9:13
+   |
+LL | fn sized<T: Sized>() {}
+   |             ^^^^^ required by this bound in `sized`
+
+error[E0277]: the size for values of type `main::Foo` cannot be known
+  --> $DIR/default-bound.rs:46:17
+   |
+LL |     metasized::<Foo>();
+   |                 ^^^ doesn't have a known size
+   |
+   = help: the trait `MetaSized` is not implemented for `main::Foo`
+note: required by a bound in `metasized`
+  --> $DIR/default-bound.rs:14:17
+   |
+LL | fn metasized<T: MetaSized>() {}
+   |                 ^^^^^^^^^ required by this bound in `metasized`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs
new file mode 100644
index 00000000000..b25acf9e6ea
--- /dev/null
+++ b/tests/ui/sized-hierarchy/default-supertrait.rs
@@ -0,0 +1,61 @@
+//@ check-fail
+#![feature(sized_hierarchy)]
+
+use std::marker::{MetaSized, PointeeSized};
+
+trait Sized_: Sized { }
+
+trait NegSized: ?Sized { }
+//~^ ERROR `?Trait` is not permitted in supertraits
+
+trait MetaSized_: MetaSized { }
+
+trait NegMetaSized: ?MetaSized { }
+//~^ ERROR `?Trait` is not permitted in supertraits
+
+
+trait PointeeSized_: PointeeSized { }
+
+trait NegPointeeSized: ?PointeeSized { }
+//~^ ERROR `?Trait` is not permitted in supertraits
+
+trait Bare {}
+
+fn requires_sized<T: Sized>() {}
+fn requires_metasized<T: MetaSized>() {}
+fn requires_pointeesized<T: PointeeSized>() {}
+
+fn with_sized_supertrait<T: PointeeSized + Sized_>() {
+    requires_sized::<T>();
+    requires_metasized::<T>();
+    requires_pointeesized::<T>();
+}
+
+fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() {
+    requires_sized::<T>();
+    //~^ ERROR the size for values of type `T` cannot be known at compilation time
+    requires_metasized::<T>();
+    requires_pointeesized::<T>();
+}
+
+// It isn't really possible to write this one..
+fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
+    requires_sized::<T>();
+    //~^ ERROR the size for values of type `T` cannot be known
+    requires_metasized::<T>();
+    //~^ ERROR the size for values of type `T` cannot be known
+    requires_pointeesized::<T>();
+}
+
+// `T` won't inherit the `const MetaSized` implicit supertrait of `Bare`, so there is an error on
+// the bound, which is expected.
+fn with_bare_trait<T: PointeeSized + Bare>() {
+//~^ ERROR the size for values of type `T` cannot be known
+    requires_sized::<T>();
+    //~^ ERROR the size for values of type `T` cannot be known
+    requires_metasized::<T>();
+    //~^ ERROR the size for values of type `T` cannot be known
+    requires_pointeesized::<T>();
+}
+
+fn main() { }
diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr
new file mode 100644
index 00000000000..de23936b900
--- /dev/null
+++ b/tests/ui/sized-hierarchy/default-supertrait.stderr
@@ -0,0 +1,125 @@
+error[E0658]: `?Trait` is not permitted in supertraits
+  --> $DIR/default-supertrait.rs:8:17
+   |
+LL | trait NegSized: ?Sized { }
+   |                 ^^^^^^
+   |
+   = note: traits are `?Sized` by default
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` is not permitted in supertraits
+  --> $DIR/default-supertrait.rs:13:21
+   |
+LL | trait NegMetaSized: ?MetaSized { }
+   |                     ^^^^^^^^^^
+   |
+   = note: traits are `?MetaSized` by default
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` is not permitted in supertraits
+  --> $DIR/default-supertrait.rs:19:24
+   |
+LL | trait NegPointeeSized: ?PointeeSized { }
+   |                        ^^^^^^^^^^^^^
+   |
+   = note: traits are `?PointeeSized` by default
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0277]: the size for values of type `T` cannot be known
+  --> $DIR/default-supertrait.rs:52:38
+   |
+LL | fn with_bare_trait<T: PointeeSized + Bare>() {
+   |                                      ^^^^ doesn't have a known size
+   |
+note: required by a bound in `Bare`
+  --> $DIR/default-supertrait.rs:22:1
+   |
+LL | trait Bare {}
+   | ^^^^^^^^^^^^^ required by this bound in `Bare`
+help: consider further restricting type parameter `T` with unstable trait `MetaSized`
+   |
+LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
+   |                                           ++++++++++++++++++++++++
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/default-supertrait.rs:35:22
+   |
+LL | fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() {
+   |                              - this type parameter needs to be `Sized`
+LL |     requires_sized::<T>();
+   |                      ^ doesn't have a size known at compile-time
+   |
+note: required by a bound in `requires_sized`
+  --> $DIR/default-supertrait.rs:24:22
+   |
+LL | fn requires_sized<T: Sized>() {}
+   |                      ^^^^^ required by this bound in `requires_sized`
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/default-supertrait.rs:43:22
+   |
+LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
+   |                                 - this type parameter needs to be `Sized`
+LL |     requires_sized::<T>();
+   |                      ^ doesn't have a size known at compile-time
+   |
+note: required by a bound in `requires_sized`
+  --> $DIR/default-supertrait.rs:24:22
+   |
+LL | fn requires_sized<T: Sized>() {}
+   |                      ^^^^^ required by this bound in `requires_sized`
+
+error[E0277]: the size for values of type `T` cannot be known
+  --> $DIR/default-supertrait.rs:45:26
+   |
+LL |     requires_metasized::<T>();
+   |                          ^ doesn't have a known size
+   |
+note: required by a bound in `requires_metasized`
+  --> $DIR/default-supertrait.rs:25:26
+   |
+LL | fn requires_metasized<T: MetaSized>() {}
+   |                          ^^^^^^^^^ required by this bound in `requires_metasized`
+help: consider further restricting type parameter `T` with unstable trait `MetaSized`
+   |
+LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::marker::MetaSized>() {
+   |                                                                 ++++++++++++++++++++++++
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/default-supertrait.rs:54:22
+   |
+LL | fn with_bare_trait<T: PointeeSized + Bare>() {
+   |                    - this type parameter needs to be `Sized`
+LL |
+LL |     requires_sized::<T>();
+   |                      ^ doesn't have a size known at compile-time
+   |
+note: required by a bound in `requires_sized`
+  --> $DIR/default-supertrait.rs:24:22
+   |
+LL | fn requires_sized<T: Sized>() {}
+   |                      ^^^^^ required by this bound in `requires_sized`
+
+error[E0277]: the size for values of type `T` cannot be known
+  --> $DIR/default-supertrait.rs:56:26
+   |
+LL |     requires_metasized::<T>();
+   |                          ^ doesn't have a known size
+   |
+note: required by a bound in `requires_metasized`
+  --> $DIR/default-supertrait.rs:25:26
+   |
+LL | fn requires_metasized<T: MetaSized>() {}
+   |                          ^^^^^^^^^ required by this bound in `requires_metasized`
+help: consider further restricting type parameter `T` with unstable trait `MetaSized`
+   |
+LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
+   |                                           ++++++++++++++++++++++++
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs
new file mode 100644
index 00000000000..70a84aabf2c
--- /dev/null
+++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+#![feature(extern_types, sized_hierarchy)]
+
+use std::marker::{MetaSized, PointeeSized};
+
+pub fn hash<T: PointeeSized>(_: *const T) {
+    unimplemented!();
+}
+
+unsafe extern "C" {
+    type Foo;
+}
+
+fn get() -> *const Foo {
+    unimplemented!()
+}
+
+fn main() {
+    hash::<Foo>(get());
+}
diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs
index b05313dccae..601d837043e 100644
--- a/tests/ui/sized-hierarchy/impls.rs
+++ b/tests/ui/sized-hierarchy/impls.rs
@@ -1,8 +1,10 @@
 //@ check-fail
-//@ edition:2021
+//@ edition: 2024
+
 #![allow(incomplete_features, internal_features)]
 #![feature(sized_hierarchy)]
 #![feature(coroutines, dyn_star, extern_types, f16, never_type, unsized_fn_params)]
+
 use std::fmt::Debug;
 use std::marker::{MetaSized, PointeeSized};
 
@@ -11,11 +13,11 @@ use std::marker::{MetaSized, PointeeSized};
 fn needs_sized<T: Sized>() { }
 fn takes_sized<T: Sized>(_t: T) { }
 
-fn needs_metasized<T: ?Sized + MetaSized>() { }
-fn takes_metasized<T: ?Sized + MetaSized>(_t: T) { }
+fn needs_metasized<T: MetaSized>() { }
+fn takes_metasized<T: MetaSized>(_t: T) { }
 
-fn needs_pointeesized<T: ?Sized + PointeeSized>() { }
-fn takes_pointeesized<T: ?Sized + PointeeSized>(_t: T) { }
+fn needs_pointeesized<T: PointeeSized>() { }
+fn takes_pointeesized<T: PointeeSized>(_t: T) { }
 
 fn main() {
     // `bool`
@@ -173,7 +175,7 @@ fn main() {
     needs_pointeesized::<dyn Debug>();
 
     // `extern type`
-    extern "C" {
+    unsafe extern "C" {
         type Foo;
     }
     needs_sized::<Foo>();
diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr
index 5fffe478663..02ccfebdc44 100644
--- a/tests/ui/sized-hierarchy/impls.stderr
+++ b/tests/ui/sized-hierarchy/impls.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:237:42
+  --> $DIR/impls.rs:239:42
    |
 LL |     struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
    |                                          ^^^^ doesn't have a size known at compile-time
@@ -17,7 +17,7 @@ LL |     struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] }
    |                                          ++++    +
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:245:40
+  --> $DIR/impls.rs:247:40
    |
 LL |     struct StructAllFieldsUnsized { x: Foo, y: Foo }
    |                                        ^^^ doesn't have a size known at compile-time
@@ -35,7 +35,7 @@ LL |     struct StructAllFieldsUnsized { x: Box<Foo>, y: Foo }
    |                                        ++++   +
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:281:44
+  --> $DIR/impls.rs:283:44
    |
 LL |     enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } }
    |                                            ^^^^ doesn't have a size known at compile-time
@@ -53,7 +53,7 @@ LL |     enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } }
    |                                            ++++    +
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:288:42
+  --> $DIR/impls.rs:290:42
    |
 LL |     enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } }
    |                                          ^^^ doesn't have a size known at compile-time
@@ -71,7 +71,7 @@ LL |     enum EnumAllFieldsUnsized { Qux { x: Box<Foo>, y: Foo } }
    |                                          ++++   +
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:295:52
+  --> $DIR/impls.rs:297:52
    |
 LL |     enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } }
    |                                                    ^^^^ doesn't have a size known at compile-time
@@ -89,7 +89,7 @@ LL |     enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } }
    |                                                    ++++    +
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:302:50
+  --> $DIR/impls.rs:304:50
    |
 LL |     enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } }
    |                                                  ^^^ doesn't have a size known at compile-time
@@ -107,72 +107,72 @@ LL |     enum EnumLastFieldUnsized { Qux { x: u32, y: Box<Foo> } }
    |                                                  ++++   +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/impls.rs:158:19
+  --> $DIR/impls.rs:160:19
    |
 LL |     needs_sized::<str>();
    |                   ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:164:19
+  --> $DIR/impls.rs:166:19
    |
 LL |     needs_sized::<[u8]>();
    |                   ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
-  --> $DIR/impls.rs:170:19
+  --> $DIR/impls.rs:172:19
    |
 LL |     needs_sized::<dyn Debug>();
    |                   ^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Debug`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:179:19
+  --> $DIR/impls.rs:181:19
    |
 LL |     needs_sized::<Foo>();
    |                   ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `main::Foo`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known
-  --> $DIR/impls.rs:181:23
+  --> $DIR/impls.rs:183:23
    |
 LL |     needs_metasized::<Foo>();
    |                       ^^^ doesn't have a known size
    |
    = help: the trait `MetaSized` is not implemented for `main::Foo`
 note: required by a bound in `needs_metasized`
-  --> $DIR/impls.rs:14:32
+  --> $DIR/impls.rs:16:23
    |
-LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
-   |                                ^^^^^^^^^ required by this bound in `needs_metasized`
+LL | fn needs_metasized<T: MetaSized>() { }
+   |                       ^^^^^^^^^ required by this bound in `needs_metasized`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:196:19
+  --> $DIR/impls.rs:198:19
    |
 LL |     needs_sized::<([u8], [u8])>();
    |                   ^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -181,7 +181,7 @@ LL |     needs_sized::<([u8], [u8])>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:198:23
+  --> $DIR/impls.rs:200:23
    |
 LL |     needs_metasized::<([u8], [u8])>();
    |                       ^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -190,7 +190,7 @@ LL |     needs_metasized::<([u8], [u8])>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:200:26
+  --> $DIR/impls.rs:202:26
    |
 LL |     needs_pointeesized::<([u8], [u8])>();
    |                          ^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -199,7 +199,7 @@ LL |     needs_pointeesized::<([u8], [u8])>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:204:19
+  --> $DIR/impls.rs:206:19
    |
 LL |     needs_sized::<(Foo, Foo)>();
    |                   ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -208,7 +208,7 @@ LL |     needs_sized::<(Foo, Foo)>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:206:23
+  --> $DIR/impls.rs:208:23
    |
 LL |     needs_metasized::<(Foo, Foo)>();
    |                       ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -217,7 +217,7 @@ LL |     needs_metasized::<(Foo, Foo)>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:208:26
+  --> $DIR/impls.rs:210:26
    |
 LL |     needs_pointeesized::<(Foo, Foo)>();
    |                          ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -226,7 +226,7 @@ LL |     needs_pointeesized::<(Foo, Foo)>();
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:212:19
+  --> $DIR/impls.rs:214:19
    |
 LL |     needs_sized::<(u32, [u8])>();
    |                   ^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -234,13 +234,13 @@ LL |     needs_sized::<(u32, [u8])>();
    = help: within `(u32, [u8])`, the trait `Sized` is not implemented for `[u8]`
    = note: required because it appears within the type `(u32, [u8])`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:218:19
+  --> $DIR/impls.rs:220:19
    |
 LL |     needs_sized::<(u32, Foo)>();
    |                   ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -248,13 +248,13 @@ LL |     needs_sized::<(u32, Foo)>();
    = help: within `(u32, main::Foo)`, the trait `Sized` is not implemented for `main::Foo`
    = note: required because it appears within the type `(u32, main::Foo)`
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known
-  --> $DIR/impls.rs:220:23
+  --> $DIR/impls.rs:222:23
    |
 LL |     needs_metasized::<(u32, Foo)>();
    |                       ^^^^^^^^^^ doesn't have a known size
@@ -262,118 +262,118 @@ LL |     needs_metasized::<(u32, Foo)>();
    = help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
    = note: required because it appears within the type `(u32, main::Foo)`
 note: required by a bound in `needs_metasized`
-  --> $DIR/impls.rs:14:32
+  --> $DIR/impls.rs:16:23
    |
-LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
-   |                                ^^^^^^^^^ required by this bound in `needs_metasized`
+LL | fn needs_metasized<T: MetaSized>() { }
+   |                       ^^^^^^^^^ required by this bound in `needs_metasized`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:239:19
+  --> $DIR/impls.rs:241:19
    |
 LL |     needs_sized::<StructAllFieldsMetaSized>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]`
 note: required because it appears within the type `StructAllFieldsMetaSized`
-  --> $DIR/impls.rs:237:12
+  --> $DIR/impls.rs:239:12
    |
 LL |     struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:247:19
+  --> $DIR/impls.rs:249:19
    |
 LL |     needs_sized::<StructAllFieldsUnsized>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo`
 note: required because it appears within the type `StructAllFieldsUnsized`
-  --> $DIR/impls.rs:245:12
+  --> $DIR/impls.rs:247:12
    |
 LL |     struct StructAllFieldsUnsized { x: Foo, y: Foo }
    |            ^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known
-  --> $DIR/impls.rs:249:23
+  --> $DIR/impls.rs:251:23
    |
 LL |     needs_metasized::<StructAllFieldsUnsized>();
    |                       ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
    |
    = help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
 note: required because it appears within the type `StructAllFieldsUnsized`
-  --> $DIR/impls.rs:245:12
+  --> $DIR/impls.rs:247:12
    |
 LL |     struct StructAllFieldsUnsized { x: Foo, y: Foo }
    |            ^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_metasized`
-  --> $DIR/impls.rs:14:32
+  --> $DIR/impls.rs:16:23
    |
-LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
-   |                                ^^^^^^^^^ required by this bound in `needs_metasized`
+LL | fn needs_metasized<T: MetaSized>() { }
+   |                       ^^^^^^^^^ required by this bound in `needs_metasized`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/impls.rs:255:19
+  --> $DIR/impls.rs:257:19
    |
 LL |     needs_sized::<StructLastFieldMetaSized>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]`
 note: required because it appears within the type `StructLastFieldMetaSized`
-  --> $DIR/impls.rs:254:12
+  --> $DIR/impls.rs:256:12
    |
 LL |     struct StructLastFieldMetaSized { x: u32, y: [u8] }
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
-  --> $DIR/impls.rs:262:19
+  --> $DIR/impls.rs:264:19
    |
 LL |     needs_sized::<StructLastFieldUnsized>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo`
 note: required because it appears within the type `StructLastFieldUnsized`
-  --> $DIR/impls.rs:261:12
+  --> $DIR/impls.rs:263:12
    |
 LL |     struct StructLastFieldUnsized { x: u32, y: Foo }
    |            ^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_sized`
-  --> $DIR/impls.rs:11:19
+  --> $DIR/impls.rs:13:19
    |
 LL | fn needs_sized<T: Sized>() { }
    |                   ^^^^^ required by this bound in `needs_sized`
 
 error[E0277]: the size for values of type `main::Foo` cannot be known
-  --> $DIR/impls.rs:264:23
+  --> $DIR/impls.rs:266:23
    |
 LL |     needs_metasized::<StructLastFieldUnsized>();
    |                       ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
    |
    = help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
 note: required because it appears within the type `StructLastFieldUnsized`
-  --> $DIR/impls.rs:261:12
+  --> $DIR/impls.rs:263:12
    |
 LL |     struct StructLastFieldUnsized { x: u32, y: Foo }
    |            ^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `needs_metasized`
-  --> $DIR/impls.rs:14:32
+  --> $DIR/impls.rs:16:23
    |
-LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
-   |                                ^^^^^^^^^ required by this bound in `needs_metasized`
+LL | fn needs_metasized<T: MetaSized>() { }
+   |                       ^^^^^^^^^ required by this bound in `needs_metasized`
 
 error: aborting due to 26 previous errors
 
diff --git a/tests/ui/sized-hierarchy/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs
new file mode 100644
index 00000000000..4bf486890bf
--- /dev/null
+++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs
@@ -0,0 +1,28 @@
+//@ check-pass
+#![feature(sized_hierarchy)]
+
+// This is a reduction of some code in `library/core/src/cmp.rs` that would ICE if a default
+// `Pointee` bound is added - motivating the current status quo of `PointeeSized` being syntactic
+// sugar for an absense of any bounds whatsoever.
+
+use std::marker::PhantomData;
+
+pub trait Bar<'a> {
+    type Foo;
+}
+
+pub struct Foo<'a, T: Bar<'a>> {
+    phantom: PhantomData<&'a T>,
+}
+
+impl<'a, 'b, T> PartialEq<Foo<'b, T>> for Foo<'a, T>
+    where
+        T: for<'c> Bar<'c>,
+        <T as Bar<'a>>::Foo: PartialEq<<T as Bar<'b>>::Foo>,
+{
+    fn eq(&self, _: &Foo<'b, T>) -> bool {
+        loop {}
+    }
+}
+
+fn main() { }
diff --git a/tests/ui/sized-hierarchy/trait-aliases.rs b/tests/ui/sized-hierarchy/trait-aliases.rs
new file mode 100644
index 00000000000..ffec302adaa
--- /dev/null
+++ b/tests/ui/sized-hierarchy/trait-aliases.rs
@@ -0,0 +1,9 @@
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+#![feature(trait_alias)]
+
+// Checks that `?Sized` in a trait alias doesn't trigger an ICE.
+
+use std::ops::{Index, IndexMut};
+
+pub trait SlicePrereq<T> = ?Sized + IndexMut<usize, Output = <[T] as Index<usize>>::Output>;