diff options
| author | Michael Goulet <michael@errs.io> | 2024-11-30 02:47:40 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-11-30 17:05:47 +0000 |
| commit | fa7449d130c70bf96d1302ebd69c054227028ec3 (patch) | |
| tree | c589ad41b15b7ead0526e487a46c106707d507f7 | |
| parent | 0c4f3a45b86c77b0a89ff06703aa6097af35d924 (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs | 25 | ||||
| -rw-r--r-- | tests/crashes/131668.rs | 12 | ||||
| -rw-r--r-- | tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs | 1 | ||||
| -rw-r--r-- | tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr | 16 | ||||
| -rw-r--r-- | tests/ui/async-await/async-fn/dyn-pos.rs | 5 | ||||
| -rw-r--r-- | tests/ui/async-await/async-fn/dyn-pos.stderr | 48 | ||||
| -rw-r--r-- | tests/ui/dyn-compatibility/missing-assoc-type.rs | 3 | ||||
| -rw-r--r-- | tests/ui/dyn-compatibility/missing-assoc-type.stderr | 49 | ||||
| -rw-r--r-- | tests/ui/issues/issue-21950.rs | 3 | ||||
| -rw-r--r-- | tests/ui/issues/issue-21950.stderr | 20 | ||||
| -rw-r--r-- | tests/ui/issues/issue-28344.rs | 2 | ||||
| -rw-r--r-- | tests/ui/issues/issue-28344.stderr | 27 | ||||
| -rw-r--r-- | tests/ui/suggestions/trait-hidden-method.rs | 2 | ||||
| -rw-r--r-- | tests/ui/suggestions/trait-hidden-method.stderr | 21 |
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`. |
