about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-09-02 05:06:21 +0000
committerMichael Goulet <michael@errs.io>2023-09-02 05:08:38 +0000
commit07fc6441327a02dd8aa8497b1e4e890f1801e8cf (patch)
treed840a7cfff93f909c2966fc4573241e27f5c277c
parent7a6b52bf0d29b614df0e9528798462ad8ab53d7e (diff)
downloadrust-07fc6441327a02dd8aa8497b1e4e890f1801e8cf.tar.gz
rust-07fc6441327a02dd8aa8497b1e4e890f1801e8cf.zip
Do not require associated types with Self: Sized to uphold bounds when confirming object candidate
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs6
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.stderr17
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_sized_used.rs6
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_sized_used.stderr21
-rw-r--r--tests/ui/object-safety/call-when-assoc-ty-is-sized.rs25
7 files changed, 54 insertions, 28 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 60f5084adc1..b61e02ba761 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -354,9 +354,9 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
         // FIXME(associated_const_equality): Also add associated consts to
         // the requirements here.
         if item.kind == ty::AssocKind::Type {
-            // RPITITs are not checked here, since they are not (currently) object-safe
-            // and cannot be named from a non-`Self: Sized` method.
-            if item.is_impl_trait_in_trait() {
+            // associated types that require `Self: Sized` do not show up in the built-in
+            // implementation of `Trait for dyn Trait`, and can be dropped here.
+            if tcx.generics_require_sized_self(item.def_id) {
                 continue;
             }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index f2b546c3956..eadac70057c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -535,9 +535,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let assoc_types: Vec<_> = tcx
             .associated_items(trait_predicate.def_id())
             .in_definition_order()
-            // RPITITs are not checked here, since they are not (currently) object-safe
-            // and cannot be named from a non-`Self: Sized` method.
-            .filter(|item| !item.is_impl_trait_in_trait())
+            // Associated types that require `Self: Sized` do not show up in the built-in
+            // implementation of `Trait for dyn Trait`, and can be dropped here.
+            .filter(|item| !tcx.generics_require_sized_self(item.def_id))
             .filter_map(
                 |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
             )
diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs
index dd35b9a2d8a..9a231e59b09 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.rs
+++ b/tests/ui/impl-trait/in-trait/object-safety.rs
@@ -19,4 +19,5 @@ fn main() {
     //~| ERROR the trait `Foo` cannot be made into an object
     let s = i.baz();
     //~^ ERROR the trait `Foo` cannot be made into an object
+    //~| ERROR the trait `Foo` cannot be made into an object
 }
diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr
index 4a3b3b11465..0170dc5d0fc 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.stderr
@@ -14,6 +14,21 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:20:15
+   |
+LL |     let s = i.baz();
+   |               ^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:7:22
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> impl Debug;
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+   = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety.rs:20:13
    |
 LL |     let s = i.baz();
@@ -44,6 +59,6 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
    = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs
index cf5345b1c1d..d59fc1712ea 100644
--- a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs
+++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs
@@ -1,6 +1,5 @@
-//! This test checks that even if some associated types have
-//! `where Self: Sized` bounds, those without still need to be
-//! mentioned in trait objects.
+//! This test checks that associated types with `Self: Sized` cannot be projected
+//! from a `dyn Trait`.
 
 trait Bop {
     type Bar: Default
@@ -16,5 +15,4 @@ fn bop<T: Bop + ?Sized>() {
 
 fn main() {
     bop::<dyn Bop>();
-    //~^ ERROR: the size for values of type `dyn Bop` cannot be known at compilation time
 }
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr
index 6b5bc360349..224d33fb2da 100644
--- a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr
+++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr
@@ -1,5 +1,5 @@
 error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::Bar`, but its trait bounds were not satisfied
-  --> $DIR/assoc_type_bounds_sized_used.rs:12:30
+  --> $DIR/assoc_type_bounds_sized_used.rs:11:30
    |
 LL |     let _ = <T as Bop>::Bar::default();
    |                              ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
@@ -13,7 +13,7 @@ LL | fn bop<T: Bop + ?Sized>() where T: Sized {
    |                           ++++++++++++++
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/assoc_type_bounds_sized_used.rs:12:14
+  --> $DIR/assoc_type_bounds_sized_used.rs:11:14
    |
 LL | fn bop<T: Bop + ?Sized>() {
    |        - this type parameter needs to be `Sized`
@@ -21,7 +21,7 @@ LL |     let _ = <T as Bop>::Bar::default();
    |              ^ doesn't have a size known at compile-time
    |
 note: required by a bound in `Bop::Bar`
-  --> $DIR/assoc_type_bounds_sized_used.rs:8:15
+  --> $DIR/assoc_type_bounds_sized_used.rs:7:15
    |
 LL |     type Bar: Default
    |          --- required by a bound in this associated type
@@ -34,20 +34,7 @@ LL - fn bop<T: Bop + ?Sized>() {
 LL + fn bop<T: Bop>() {
    |
 
-error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time
-  --> $DIR/assoc_type_bounds_sized_used.rs:18:11
-   |
-LL |     bop::<dyn Bop>();
-   |           ^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Bop`
-note: required by a bound in `bop`
-  --> $DIR/assoc_type_bounds_sized_used.rs:11:11
-   |
-LL | fn bop<T: Bop + ?Sized>() {
-   |           ^^^ required by this bound in `bop`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0277, E0599.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
new file mode 100644
index 00000000000..0b30a88fdd4
--- /dev/null
+++ b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
@@ -0,0 +1,25 @@
+// check-pass
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+trait Foo {
+    type Bar<'a>
+    where
+        Self: Sized;
+
+    fn test(&self);
+}
+
+impl Foo for () {
+    type Bar<'a> = () where Self: Sized;
+
+    fn test(&self) {}
+}
+
+fn test(x: &dyn Foo) {
+    x.test();
+}
+
+fn main() {
+    test(&());
+}