about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-11-30 02:47:40 +0000
committerMichael Goulet <michael@errs.io>2024-11-30 17:05:47 +0000
commitfa7449d130c70bf96d1302ebd69c054227028ec3 (patch)
treec589ad41b15b7ead0526e487a46c106707d507f7
parent0c4f3a45b86c77b0a89ff06703aa6097af35d924 (diff)
downloadrust-fa7449d130c70bf96d1302ebd69c054227028ec3.tar.gz
rust-fa7449d130c70bf96d1302ebd69c054227028ec3.zip
Do not create trait object type if missing associated types
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs25
-rw-r--r--tests/crashes/131668.rs12
-rw-r--r--tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs1
-rw-r--r--tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr16
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.rs5
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.stderr48
-rw-r--r--tests/ui/dyn-compatibility/missing-assoc-type.rs3
-rw-r--r--tests/ui/dyn-compatibility/missing-assoc-type.stderr49
-rw-r--r--tests/ui/issues/issue-21950.rs3
-rw-r--r--tests/ui/issues/issue-21950.stderr20
-rw-r--r--tests/ui/issues/issue-28344.rs2
-rw-r--r--tests/ui/issues/issue-28344.stderr27
-rw-r--r--tests/ui/suggestions/trait-hidden-method.rs2
-rw-r--r--tests/ui/suggestions/trait-hidden-method.stderr21
15 files changed, 35 insertions, 205 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index cab04ee0987..321a8aba7f7 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -219,11 +219,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
         }
 
-        self.complain_about_missing_assoc_tys(
+        if let Err(guar) = self.check_for_required_assoc_tys(
             associated_types,
             potential_assoc_types,
             hir_trait_bounds,
-        );
+        ) {
+            return Ty::new_error(tcx, guar);
+        }
 
         // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
         // `dyn Trait + Send`.
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 0b58b807090..ff449a858d6 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -714,14 +714,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// reasonable suggestion on how to write it. For the case of multiple associated types in the
     /// same trait bound have the same name (as they come from different supertraits), we instead
     /// emit a generic note suggesting using a `where` clause to constraint instead.
-    pub(crate) fn complain_about_missing_assoc_tys(
+    pub(crate) fn check_for_required_assoc_tys(
         &self,
         associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
         potential_assoc_types: Vec<usize>,
         trait_bounds: &[hir::PolyTraitRef<'_>],
-    ) {
+    ) -> Result<(), ErrorGuaranteed> {
         if associated_types.values().all(|v| v.is_empty()) {
-            return;
+            return Ok(());
         }
 
         let tcx = self.tcx();
@@ -739,7 +739,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // Account for things like `dyn Foo + 'a`, like in tests `issue-22434.rs` and
         // `issue-22560.rs`.
         let mut trait_bound_spans: Vec<Span> = vec![];
-        let mut dyn_compatibility_violations = false;
+        let mut dyn_compatibility_violations = Ok(());
         for (span, items) in &associated_types {
             if !items.is_empty() {
                 trait_bound_spans.push(*span);
@@ -752,13 +752,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let violations =
                     dyn_compatibility_violations_for_assoc_item(tcx, trait_def_id, *assoc_item);
                 if !violations.is_empty() {
-                    report_dyn_incompatibility(tcx, *span, None, trait_def_id, &violations).emit();
-                    dyn_compatibility_violations = true;
+                    dyn_compatibility_violations = Err(report_dyn_incompatibility(
+                        tcx,
+                        *span,
+                        None,
+                        trait_def_id,
+                        &violations,
+                    )
+                    .emit());
                 }
             }
         }
-        if dyn_compatibility_violations {
-            return;
+
+        if let Err(guar) = dyn_compatibility_violations {
+            return Err(guar);
         }
 
         // related to issue #91997, turbofishes added only when in an expr or pat
@@ -965,7 +972,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
-        err.emit();
+        Err(err.emit())
     }
 
     /// On ambiguous associated type, look for an associated function whose name matches the
diff --git a/tests/crashes/131668.rs b/tests/crashes/131668.rs
deleted file mode 100644
index 90aa4494425..00000000000
--- a/tests/crashes/131668.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #131668
-
-#![feature(generic_associated_types_extended)]
-trait B {
-    type Y<const N: i16>;
-}
-
-struct Erase<T: B>(T);
-
-fn make_static() {
-    Erase::<dyn for<'c> B<&'c ()>>(());
-}
diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs
index c0012564843..ee75cb96afd 100644
--- a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs
+++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs
@@ -5,7 +5,6 @@ trait Item {
 pub struct Flatten<I> {
     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
     //~^ ERROR E0191
-    //~| ERROR E0223
 }
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
index 39a2b98e2e2..c80b32dc3d8 100644
--- a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
+++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
@@ -4,18 +4,6 @@ error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIt
 LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator<Item: IntoIterator<Item: >, Item = Type, IntoIter = Type>`
 
-error[E0223]: ambiguous associated type
-  --> $DIR/overlaping-bound-suggestion.rs:6:13
-   |
-LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: if there were a trait named `Example` with associated type `IntoIterator` implemented for `(dyn IntoIterator + 'static)`, you could use the fully-qualified path
-   |
-LL |     inner: <<(dyn IntoIterator + 'static) as Example>::IntoIterator as Item>::Core,
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0191, E0223.
-For more information about an error, try `rustc --explain E0191`.
+For more information about this error, try `rustc --explain E0191`.
diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs
index 772c7d15cfd..a16b7c26f0d 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.rs
+++ b/tests/ui/async-await/async-fn/dyn-pos.rs
@@ -3,9 +3,6 @@
 #![feature(async_closure)]
 
 fn foo(x: &dyn async Fn()) {}
-//~^ ERROR the trait `AsyncFn` cannot be made into an object
-//~| ERROR the trait `AsyncFnMut` cannot be made into an object
-//~| ERROR the trait `AsyncFnMut` cannot be made into an object
-//~| ERROR the trait `AsyncFnMut` cannot be made into an object
+//~^ ERROR the trait `AsyncFnMut` cannot be made into an object
 
 fn main() {}
diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr
index 78e915d49e7..a9abfc5e5c4 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.stderr
+++ b/tests/ui/async-await/async-fn/dyn-pos.stderr
@@ -13,52 +13,6 @@ note: for a trait to be "dyn-compatible" it needs to allow building a vtable to
              &mut F
              std::boxed::Box<F, A>
 
-error[E0038]: the trait `AsyncFnMut` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |                ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
-             &F
-             &mut F
-             std::boxed::Box<F, A>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0038]: the trait `AsyncFnMut` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |                ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
-             &F
-             &mut F
-             std::boxed::Box<F, A>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0038]: the trait `AsyncFn` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:12
-   |
-LL | fn foo(x: &dyn async Fn()) {}
-   |            ^^^^^^^^^^^^^^ `AsyncFn` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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>
-  --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
-   |
-   = note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
-   = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
-             &F
-             std::boxed::Box<F, A>
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.rs b/tests/ui/dyn-compatibility/missing-assoc-type.rs
index c83be544c0a..21f7fd92e80 100644
--- a/tests/ui/dyn-compatibility/missing-assoc-type.rs
+++ b/tests/ui/dyn-compatibility/missing-assoc-type.rs
@@ -3,8 +3,5 @@ trait Foo {
 }
 
 fn bar(x: &dyn Foo) {} //~ ERROR the trait `Foo` cannot be made into an object
-//~^ ERROR the trait `Foo` cannot be made into an object
-//~| ERROR the trait `Foo` cannot be made into an object
-//~| ERROR the trait `Foo` cannot be made into an object
 
 fn main() {}
diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.stderr b/tests/ui/dyn-compatibility/missing-assoc-type.stderr
index f8450ba212d..184201dd1ce 100644
--- a/tests/ui/dyn-compatibility/missing-assoc-type.stderr
+++ b/tests/ui/dyn-compatibility/missing-assoc-type.stderr
@@ -13,53 +13,6 @@ LL |     type Bar<T>;
    |          ^^^ ...because it contains the generic associated type `Bar`
    = help: consider moving `Bar` to another trait
 
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/missing-assoc-type.rs:5:16
-   |
-LL | fn bar(x: &dyn Foo) {}
-   |                ^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     type Bar<T>;
-   |          ^^^ ...because it contains the generic associated type `Bar`
-   = help: consider moving `Bar` to another trait
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/missing-assoc-type.rs:5:16
-   |
-LL | fn bar(x: &dyn Foo) {}
-   |                ^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     type Bar<T>;
-   |          ^^^ ...because it contains the generic associated type `Bar`
-   = help: consider moving `Bar` to another trait
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/missing-assoc-type.rs:5:12
-   |
-LL | fn bar(x: &dyn Foo) {}
-   |            ^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" 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/missing-assoc-type.rs:2:10
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     type Bar<T>;
-   |          ^^^ ...because it contains the generic associated type `Bar`
-   = help: consider moving `Bar` to another trait
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/issues/issue-21950.rs b/tests/ui/issues/issue-21950.rs
index 72a98bd8ddd..7a85ac91bca 100644
--- a/tests/ui/issues/issue-21950.rs
+++ b/tests/ui/issues/issue-21950.rs
@@ -8,6 +8,5 @@ impl Add for i32 {
 
 fn main() {
     let x = &10 as &dyn Add;
-    //~^ ERROR E0393
-    //~| ERROR E0191
+    //~^ ERROR E0191
 }
diff --git a/tests/ui/issues/issue-21950.stderr b/tests/ui/issues/issue-21950.stderr
index 584370c7178..24230cfe17f 100644
--- a/tests/ui/issues/issue-21950.stderr
+++ b/tests/ui/issues/issue-21950.stderr
@@ -7,22 +7,6 @@ LL |     type Output;
 LL |     let x = &10 as &dyn Add;
    |                         ^^^ help: specify the associated type: `Add<Output = Type>`
 
-error[E0393]: the type parameter `Rhs` must be explicitly specified
-  --> $DIR/issue-21950.rs:10:25
-   |
-LL | trait Add<Rhs=Self> {
-   | ------------------- type parameter `Rhs` must be specified for this
-...
-LL |     let x = &10 as &dyn Add;
-   |                         ^^^
-   |
-   = note: because of the default `Self` reference, type parameters must be specified on object types
-help: set the type parameter to the desired type
-   |
-LL |     let x = &10 as &dyn Add<Rhs>;
-   |                            +++++
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0191, E0393.
-For more information about an error, try `rustc --explain E0191`.
+For more information about this error, try `rustc --explain E0191`.
diff --git a/tests/ui/issues/issue-28344.rs b/tests/ui/issues/issue-28344.rs
index 1a6a7f46b27..951ea5d69e9 100644
--- a/tests/ui/issues/issue-28344.rs
+++ b/tests/ui/issues/issue-28344.rs
@@ -3,13 +3,11 @@ use std::ops::BitXor;
 fn main() {
     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
     //~^ ERROR must be specified
-    //~| no function or associated item named
     //~| WARN trait objects without an explicit `dyn` are deprecated
     //~| WARN this is accepted in the current edition
 
     let g = BitXor::bitor;
     //~^ ERROR must be specified
-    //~| no function or associated item named
     //~| WARN trait objects without an explicit `dyn` are deprecated
     //~| WARN this is accepted in the current edition
 }
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index 261f8b67b52..d8febe71652 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -18,17 +18,8 @@ error[E0191]: the value of the associated type `Output` in `BitXor` must be spec
 LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
    |                 ^^^^^^ help: specify the associated type: `BitXor::<Output = Type>`
 
-error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope
-  --> $DIR/issue-28344.rs:4:25
-   |
-LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
-   |                         ^^^^^ function or associated item not found in `dyn BitXor<_>`
-   |
-help: there is a method `bitxor` with a similar name, but with different arguments
-  --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
-
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-28344.rs:10:13
+  --> $DIR/issue-28344.rs:9:13
    |
 LL |     let g = BitXor::bitor;
    |             ^^^^^^
@@ -41,21 +32,11 @@ LL |     let g = <dyn BitXor>::bitor;
    |             ++++       +
 
 error[E0191]: the value of the associated type `Output` in `BitXor` must be specified
-  --> $DIR/issue-28344.rs:10:13
+  --> $DIR/issue-28344.rs:9:13
    |
 LL |     let g = BitXor::bitor;
    |             ^^^^^^ help: specify the associated type: `BitXor::<Output = Type>`
 
-error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope
-  --> $DIR/issue-28344.rs:10:21
-   |
-LL |     let g = BitXor::bitor;
-   |                     ^^^^^ function or associated item not found in `dyn BitXor<_>`
-   |
-help: there is a method `bitxor` with a similar name
-  --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
-
-error: aborting due to 4 previous errors; 2 warnings emitted
+error: aborting due to 2 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0191, E0599.
-For more information about an error, try `rustc --explain E0191`.
+For more information about this error, try `rustc --explain E0191`.
diff --git a/tests/ui/suggestions/trait-hidden-method.rs b/tests/ui/suggestions/trait-hidden-method.rs
index ae7ef47e1d4..1efc1cc6fae 100644
--- a/tests/ui/suggestions/trait-hidden-method.rs
+++ b/tests/ui/suggestions/trait-hidden-method.rs
@@ -1,8 +1,6 @@
 // #107983 - testing that `__iterator_get_unchecked` isn't suggested
 // HELP included so that compiletest errors on the bad suggestion
 pub fn i_can_has_iterator() -> impl Iterator<Item = u32> {
-    //~^ ERROR expected `Box<dyn Iterator>`
-    //~| HELP consider constraining the associated type
     Box::new(1..=10) as Box<dyn Iterator>
     //~^ ERROR the value of the associated type `Item`
     //~| HELP specify the associated type
diff --git a/tests/ui/suggestions/trait-hidden-method.stderr b/tests/ui/suggestions/trait-hidden-method.stderr
index 729523cde55..87753e57846 100644
--- a/tests/ui/suggestions/trait-hidden-method.stderr
+++ b/tests/ui/suggestions/trait-hidden-method.stderr
@@ -1,24 +1,9 @@
 error[E0191]: the value of the associated type `Item` in `Iterator` must be specified
-  --> $DIR/trait-hidden-method.rs:6:33
+  --> $DIR/trait-hidden-method.rs:4:33
    |
 LL |     Box::new(1..=10) as Box<dyn Iterator>
    |                                 ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>`
 
-error[E0271]: expected `Box<dyn Iterator>` to be an iterator that yields `u32`, but it yields `<dyn Iterator as Iterator>::Item`
-  --> $DIR/trait-hidden-method.rs:3:32
-   |
-LL | pub fn i_can_has_iterator() -> impl Iterator<Item = u32> {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found associated type
-...
-LL |     Box::new(1..=10) as Box<dyn Iterator>
-   |     ------------------------------------- return type was inferred to be `Box<dyn Iterator>` here
-   |
-   = note:         expected type `u32`
-           found associated type `<dyn Iterator as Iterator>::Item`
-   = help: consider constraining the associated type `<dyn Iterator as Iterator>::Item` to `u32`
-   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0191, E0271.
-For more information about an error, try `rustc --explain E0191`.
+For more information about this error, try `rustc --explain E0191`.