From 3bbc70a5f72a8e54e50d981c01d748d3d9087b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 26 Oct 2023 18:33:03 +0000 Subject: [PATCH] Restrict param constraint suggestion When encountering an associated item with a type param that could be constrained, do not look at the parent item if the type param comes from the associated item. Fix #117209. --- .../infer/error_reporting/note_and_explain.rs | 11 +++++--- ...on-for-type-param-of-current-assoc-item.rs | 28 +++++++++++++++++++ ...or-type-param-of-current-assoc-item.stderr | 18 ++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs create mode 100644 tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 00289f9bfb4..799e41650b6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -364,12 +364,11 @@ impl Trait for X { }; // Get the `DefId` for the type parameter corresponding to `A` in `::Foo`. // This will also work for `impl Trait`. - let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() { - let generics = tcx.generics_of(body_owner_def_id); - generics.type_param(param_ty, tcx).def_id - } else { + let ty::Param(param_ty) = proj_ty.self_ty().kind() else { return false; }; + let generics = tcx.generics_of(body_owner_def_id); + let def_id = generics.type_param(param_ty, tcx).def_id; let Some(def_id) = def_id.as_local() else { return false; }; @@ -390,6 +389,10 @@ impl Trait for X { return true; } } + if (param_ty.index as usize) >= generics.parent_count { + // The param comes from the current item, do not look at the parent. (#117209) + return false; + } // If associated item, look to constrain the params of the trait/impl. let hir_id = match item { hir::Node::ImplItem(item) => item.hir_id(), diff --git a/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs b/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs new file mode 100644 index 00000000000..c1047d85645 --- /dev/null +++ b/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; +use std::hash::Hash; + +trait LowT: Identify {} + +trait Identify { + type Id: Clone + Hash + PartialEq + Eq; + fn identify(&self) -> Self::Id; +} + +struct MapStore +where + L: LowT + Identify, +{ + lows: HashMap, +} + +impl MapStore +where + L: LowT + Identify, + I: Clone + Hash + PartialEq + Eq, +{ + fn remove_low(&mut self, low: &impl LowT) { + let _low = self.lows.remove(low.identify()).unwrap(); //~ ERROR mismatched types + } +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.stderr b/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.stderr new file mode 100644 index 00000000000..78bf93c32d5 --- /dev/null +++ b/tests/ui/associated-type-bounds/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/do-not-look-at-parent-item-in-suggestion-for-type-param-of-current-assoc-item.rs:24:37 + | +LL | let _low = self.lows.remove(low.identify()).unwrap(); + | ------ ^^^^^^^^^^^^^^ expected `&I`, found associated type + | | + | arguments to this method are incorrect + | + = note: expected reference `&I` + found associated type `::Id` + = help: consider constraining the associated type `::Id` to `&I` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: method defined here + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.