Skip to content

Commit da06b7c

Browse files
Merge pull request rust-lang#19182 from ShoyuVanilla/issue-19177
fix: Binding wrong associated type when lowering bounds like `T: Trait<Assoc = U>`
2 parents 01c3ba8 + 851ef81 commit da06b7c

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir_def::{
1010
generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
1111
path::{GenericArg, GenericArgs, Path, PathSegment, PathSegments},
1212
resolver::{ResolveValueResult, TypeNs, ValueNs},
13-
type_ref::{TypeBound, TypeRef},
13+
type_ref::{TypeBound, TypeRef, TypesMap},
1414
GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId,
1515
};
1616
use smallvec::SmallVec;
@@ -838,15 +838,21 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
838838
(_, ImplTraitLoweringMode::Param | ImplTraitLoweringMode::Variable) => {
839839
// Find the generic index for the target of our `bound`
840840
let target_param_idx =
841-
self.ctx.resolver.where_predicates_in_scope().find_map(|(p, _)| {
842-
match p {
841+
self.ctx.resolver.where_predicates_in_scope().find_map(
842+
|(p, (_, types_map))| match p {
843843
WherePredicate::TypeBound {
844844
target: WherePredicateTypeTarget::TypeOrConstParam(idx),
845845
bound: b,
846-
} if b == bound => Some(idx),
846+
} if std::ptr::eq::<TypesMap>(
847+
self.ctx.types_map,
848+
types_map,
849+
) && bound == b =>
850+
{
851+
Some(idx)
852+
}
847853
_ => None,
848-
}
849-
});
854+
},
855+
);
850856
let ty = if let Some(target_param_idx) = target_param_idx {
851857
let mut counter = 0;
852858
let generics = self.ctx.generics().expect("generics in scope");

src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use span::{Edition, EditionedFileId};
33
use syntax::{TextRange, TextSize};
44
use test_fixture::WithFixture;
55

6-
use crate::{db::HirDatabase, test_db::TestDB, Interner, Substitution};
6+
use crate::{db::HirDatabase, mir::MirLowerError, test_db::TestDB, Interner, Substitution};
77

88
use super::{interpret_mir, MirEvalError};
99

@@ -84,6 +84,16 @@ fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic:
8484
assert_eq!(e.is_panic().unwrap_or_else(|| panic!("unexpected error: {e:?}")), expected_panic);
8585
}
8686

87+
fn check_error_with(
88+
#[rust_analyzer::rust_fixture] ra_fixture: &str,
89+
expect_err: impl FnOnce(MirEvalError) -> bool,
90+
) {
91+
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
92+
let file_id = *file_ids.last().unwrap();
93+
let e = eval_main(&db, file_id).unwrap_err();
94+
assert!(expect_err(e));
95+
}
96+
8797
#[test]
8898
fn function_with_extern_c_abi() {
8999
check_pass(
@@ -945,3 +955,27 @@ fn main() {
945955
"#,
946956
);
947957
}
958+
959+
#[test]
960+
fn regression_19177() {
961+
check_error_with(
962+
r#"
963+
//- minicore: copy
964+
trait Foo {}
965+
trait Bar {}
966+
trait Baz {}
967+
trait Qux {
968+
type Assoc;
969+
}
970+
971+
fn main<'a, T: Foo + Bar + Baz>(
972+
x: &T,
973+
y: (),
974+
z: &'a dyn Qux<Assoc = T>,
975+
w: impl Foo + Bar,
976+
) {
977+
}
978+
"#,
979+
|e| matches!(e, MirEvalError::MirLowerError(_, MirLowerError::GenericArgNotProvided(..))),
980+
);
981+
}

0 commit comments

Comments
 (0)