about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs15
-rw-r--r--tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.rs15
-rw-r--r--tests/ui/traits/suggest-deferences/dont-suggest-unsize-deref.stderr22
3 files changed, 51 insertions, 1 deletions
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<I>(itr: I)
+where
+    I: IntoIterator<Item = i32>,
+{
+}
+
+fn pass_iterator<I>(i: &dyn IntoIterator<Item = i32, IntoIter = I>)
+where
+    I: Iterator<Item = i32>,
+{
+    use_iterator(i);
+    //~^ ERROR `&dyn IntoIterator<Item = i32, IntoIter = I>` 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<Item = i32, IntoIter = I>` is not an iterator
+  --> $DIR/dont-suggest-unsize-deref.rs:11:18
+   |
+LL |     use_iterator(i);
+   |     ------------ ^ `&dyn IntoIterator<Item = i32, IntoIter = I>` is not an iterator
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Iterator` is not implemented for `&dyn IntoIterator<Item = i32, IntoIter = I>`
+   = note: required for `&dyn IntoIterator<Item = i32, IntoIter = I>` to implement `IntoIterator`
+note: required by a bound in `use_iterator`
+  --> $DIR/dont-suggest-unsize-deref.rs:3:8
+   |
+LL | fn use_iterator<I>(itr: I)
+   |    ------------ required by a bound in this function
+LL | where
+LL |     I: IntoIterator<Item = i32>,
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.