about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-02-22 21:32:46 +0000
committerGitHub <noreply@github.com>2025-02-22 21:32:46 +0000
commitda06b7c1bbf3b10aafbee635418e5afad12468c1 (patch)
tree48c80493949c90145ec9fbeb718b5de87778ee78 /src
parent01c3ba8a47c1e0f668b4a3bd9404ac7144e57acf (diff)
parent851ef81f4a4b23e191d75cd80545fd48b3ca6a4d (diff)
downloadrust-da06b7c1bbf3b10aafbee635418e5afad12468c1.tar.gz
rust-da06b7c1bbf3b10aafbee635418e5afad12468c1.zip
Merge pull request #19182 from ShoyuVanilla/issue-19177
fix: Binding wrong associated type when lowering bounds like `T: Trait<Assoc = U>`
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs36
2 files changed, 47 insertions, 7 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..a165932ddcc 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
@@ -10,7 +10,7 @@ use hir_def::{
     generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
     path::{GenericArg, GenericArgs, Path, PathSegment, PathSegments},
     resolver::{ResolveValueResult, TypeNs, ValueNs},
-    type_ref::{TypeBound, TypeRef},
+    type_ref::{TypeBound, TypeRef, TypesMap},
     GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId,
 };
 use smallvec::SmallVec;
@@ -838,15 +838,21 @@ 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 {
+                                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 => Some(idx),
+                                        } if std::ptr::eq::<TypesMap>(
+                                            self.ctx.types_map,
+                                            types_map,
+                                        ) && bound == b =>
+                                        {
+                                            Some(idx)
+                                        }
                                         _ => None,
-                                    }
-                                });
+                                    },
+                                );
                             let ty = if let Some(target_param_idx) = target_param_idx {
                                 let mut counter = 0;
                                 let generics = self.ctx.generics().expect("generics in scope");
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(..))),
+    );
+}