From ee9727e263f32d1bc3aa5b8fdbe42098e84aa923 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 7 Sep 2023 04:51:36 +0000 Subject: [PATCH] Don't suggest dereferencing to unsized type --- .../src/traits/error_reporting/suggestions.rs | 15 ++++++++++++- .../dont-suggest-unsize-deref.rs | 15 +++++++++++++ .../dont-suggest-unsize-deref.stderr | 22 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.rs create mode 100644 tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 611ec6b00ef..32fb10ce4a6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -838,7 +838,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.param_env, real_trait_pred_and_base_ty, ); - if self.predicate_may_hold(&obligation) { + let sized_obligation = Obligation::new( + self.tcx, + obligation.cause.clone(), + obligation.param_env, + ty::TraitRef::from_lang_item( + self.tcx, + hir::LangItem::Sized, + obligation.cause.span, + [base_ty], + ), + ); + if self.predicate_may_hold(&obligation) + && self.predicate_must_hold_modulo_regions(&sized_obligation) + { let call_node = self.tcx.hir().get(*call_hir_id); let msg = "consider dereferencing here"; let is_receiver = matches!( diff --git a/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.rs b/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.rs new file mode 100644 index 00000000000..8133036991c --- /dev/null +++ b/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.rs @@ -0,0 +1,15 @@ +fn use_iterator(itr: I) +where + I: IntoIterator, +{ +} + +fn pass_iterator(i: &dyn IntoIterator) +where + I: Iterator, +{ + use_iterator(i); + //~^ ERROR `&dyn IntoIterator` is not an iterator +} + +fn main() {} diff --git a/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.stderr b/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.stderr new file mode 100644 index 00000000000..18ce9939eb2 --- /dev/null +++ b/tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.stderr @@ -0,0 +1,22 @@ +error[E0277]: `&dyn IntoIterator` is not an iterator + --> $DIR/dont-suggest-unsize-deref.rs:11:18 + | +LL | use_iterator(i); + | ------------ ^ `&dyn IntoIterator` is not an iterator + | | + | required by a bound introduced by this call + | + = help: the trait `Iterator` is not implemented for `&dyn IntoIterator` + = note: required for `&dyn IntoIterator` to implement `IntoIterator` +note: required by a bound in `use_iterator` + --> $DIR/dont-suggest-unsize-deref.rs:3:8 + | +LL | fn use_iterator(itr: I) + | ------------ required by a bound in this function +LL | where +LL | I: IntoIterator, + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_iterator` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.