Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15317 - HKalbasi:mir, r=HKalbasi
Lookup super traits in `is_dyn_method`
bors 2023-07-20
parent cbf3713 · parent ed8e1fd · commit be82869
-rw-r--r--crates/hir-ty/src/consteval/tests.rs27
-rw-r--r--crates/hir-ty/src/method_resolution.rs22
2 files changed, 42 insertions, 7 deletions
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index de792a6c5a..98ebe55724 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -1941,6 +1941,33 @@ fn dyn_trait() {
"#,
900,
);
+ check_number(
+ r#"
+ //- minicore: coerce_unsized, index, slice
+ trait A {
+ fn x(&self) -> i32;
+ }
+
+ trait B: A {}
+
+ impl A for i32 {
+ fn x(&self) -> i32 {
+ 5
+ }
+ }
+
+ impl B for i32 {
+
+ }
+
+ const fn f(x: &dyn B) -> i32 {
+ x.x()
+ }
+
+ const GOAL: i32 = f(&2i32);
+ "#,
+ 5,
+ );
}
#[test]
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index bc65fd5bac..f3a5f69b2a 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -665,13 +665,21 @@ pub fn is_dyn_method(
};
let self_ty = trait_ref.self_type_parameter(Interner);
if let TyKind::Dyn(d) = self_ty.kind(Interner) {
- let is_my_trait_in_bounds =
- d.bounds.skip_binders().as_slice(Interner).iter().any(|it| match it.skip_binders() {
- // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
- // what the generics are, we are sure that the method is come from the vtable.
- WhereClause::Implemented(tr) => tr.trait_id == trait_ref.trait_id,
- _ => false,
- });
+ let is_my_trait_in_bounds = d
+ .bounds
+ .skip_binders()
+ .as_slice(Interner)
+ .iter()
+ .map(|it| it.skip_binders())
+ .flat_map(|it| match it {
+ WhereClause::Implemented(tr) => {
+ all_super_traits(db.upcast(), from_chalk_trait_id(tr.trait_id))
+ }
+ _ => smallvec![],
+ })
+ // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
+ // what the generics are, we are sure that the method is come from the vtable.
+ .any(|x| x == trait_id);
if is_my_trait_in_bounds {
return Some(fn_params);
}