about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs36
2 files changed, 45 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
index 22c5bb9923f..176c147b710 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
index 9625ae5f88e..2b5486fc5fa 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
+++ b/src/tools/rust-analyzer/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(..))),
+    );
+}