Skip to content

Commit

Permalink
Restrict param constraint suggestion
Browse files Browse the repository at this point in the history
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 rust-lang#117209.
  • Loading branch information
estebank committed Oct 26, 2023
1 parent 6f65201 commit 3bbc70a
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,11 @@ impl<T> Trait<T> for X {
};
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::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;
};
Expand All @@ -390,6 +389,10 @@ impl<T> Trait<T> 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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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<L, I>
where
L: LowT + Identify<Id = I>,
{
lows: HashMap<I, L>,
}

impl<L, I> MapStore<L, I>
where
L: LowT + Identify<Id = I>,
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() {}
Original file line number Diff line number Diff line change
@@ -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 `<impl LowT as Identify>::Id`
= help: consider constraining the associated type `<impl LowT as Identify>::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`.

0 comments on commit 3bbc70a

Please sign in to comment.