From ceab7546935480e0b6f27d3f3036e65107d36dbd Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 20 Feb 2025 00:47:21 +0900 Subject: [PATCH 1/2] fix: Binding wrong assoc ty when lowering trait ref bound --- .../crates/hir-ty/src/lower/path.rs | 19 +++++----- .../crates/hir-ty/src/mir/eval/tests.rs | 36 ++++++++++++++++++- 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 22c5bb9923f0..176c147b7108 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 9625ae5f88ed..2b5486fc5fa0 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, + w: impl Foo + Bar, +) { +} +"#, + |e| matches!(e, MirEvalError::MirLowerError(_, MirLowerError::GenericArgNotProvided(..))), + ); +} From 851ef81f4a4b23e191d75cd80545fd48b3ca6a4d Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 20 Feb 2025 08:49:00 +0900 Subject: [PATCH 2/2] Explicitly compare `TypesMap` as ptrs --- .../crates/hir-ty/src/lower/path.rs | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 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 176c147b7108..a165932ddcc8 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; @@ -837,17 +837,22 @@ 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, (_, 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 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 std::ptr::eq::( + 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");