Unnamed repository; edit this file 'description' to name the repository.
fix: Binding wrong assoc ty when lowering trait ref bound
Shoyu Vanilla 2025-02-19
parent 9691da7 · commit 9d459e8
-rw-r--r--crates/hir-ty/src/lower/path.rs19
-rw-r--r--crates/hir-ty/src/mir/eval/tests.rs36
2 files changed, 45 insertions, 10 deletions
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs
index 22c5bb9923..176c147b71 100644
--- a/crates/hir-ty/src/lower/path.rs
+++ b/crates/hir-ty/src/lower/path.rs
@@ -837,15 +837,16 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
}
(_, ImplTraitLoweringMode::Param | ImplTraitLoweringMode::Variable) => {
// Find the generic index for the target of our `bound`
- let target_param_idx =
- self.ctx.resolver.where_predicates_in_scope().find_map(|(p, _)| {
- match p {
- WherePredicate::TypeBound {
- target: WherePredicateTypeTarget::TypeOrConstParam(idx),
- bound: b,
- } if b == bound => Some(idx),
- _ => None,
- }
+ let target_param_idx = self
+ .ctx
+ .resolver
+ .where_predicates_in_scope()
+ .find_map(|(p, (_, types_map))| match p {
+ WherePredicate::TypeBound {
+ target: WherePredicateTypeTarget::TypeOrConstParam(idx),
+ bound: b,
+ } if b == bound && self.ctx.types_map == types_map => Some(idx),
+ _ => None,
});
let ty = if let Some(target_param_idx) = target_param_idx {
let mut counter = 0;
diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs
index 9625ae5f88..2b5486fc5f 100644
--- a/crates/hir-ty/src/mir/eval/tests.rs
+++ b/crates/hir-ty/src/mir/eval/tests.rs
@@ -3,7 +3,7 @@ use span::{Edition, EditionedFileId};
use syntax::{TextRange, TextSize};
use test_fixture::WithFixture;
-use crate::{db::HirDatabase, test_db::TestDB, Interner, Substitution};
+use crate::{db::HirDatabase, mir::MirLowerError, test_db::TestDB, Interner, Substitution};
use super::{interpret_mir, MirEvalError};
@@ -84,6 +84,16 @@ fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic:
assert_eq!(e.is_panic().unwrap_or_else(|| panic!("unexpected error: {e:?}")), expected_panic);
}
+fn check_error_with(
+ #[rust_analyzer::rust_fixture] ra_fixture: &str,
+ expect_err: impl FnOnce(MirEvalError) -> bool,
+) {
+ let (db, file_ids) = TestDB::with_many_files(ra_fixture);
+ let file_id = *file_ids.last().unwrap();
+ let e = eval_main(&db, file_id).unwrap_err();
+ assert!(expect_err(e));
+}
+
#[test]
fn function_with_extern_c_abi() {
check_pass(
@@ -945,3 +955,27 @@ fn main() {
"#,
);
}
+
+#[test]
+fn regression_19177() {
+ check_error_with(
+ r#"
+//- minicore: copy
+trait Foo {}
+trait Bar {}
+trait Baz {}
+trait Qux {
+ type Assoc;
+}
+
+fn main<'a, T: Foo + Bar + Baz>(
+ x: &T,
+ y: (),
+ z: &'a dyn Qux<Assoc = T>,
+ w: impl Foo + Bar,
+) {
+}
+"#,
+ |e| matches!(e, MirEvalError::MirLowerError(_, MirLowerError::GenericArgNotProvided(..))),
+ );
+}