Unnamed repository; edit this file 'description' to name the repository.
Ignore impls with `#[rustc_reservation_impl]`
Ryo Yoshida 2023-05-06
parent a4966c9 · commit 9360adc
-rw-r--r--crates/hir-ty/src/chalk_db.rs2
-rw-r--r--crates/hir-ty/src/method_resolution.rs9
-rw-r--r--crates/hir-ty/src/tests/never_type.rs19
3 files changed, 29 insertions, 1 deletions
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index d68703ce1d..983cc22212 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -453,7 +453,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
}
}
-impl<'a> chalk_ir::UnificationDatabase<Interner> for &'a dyn HirDatabase {
+impl chalk_ir::UnificationDatabase<Interner> for &dyn HirDatabase {
fn fn_def_variance(
&self,
fn_def_id: chalk_ir::FnDefId<Interner>,
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 912efc3a89..8d57211db0 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -187,6 +187,15 @@ impl TraitImpls {
fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
for (_module_id, module_data) in def_map.modules() {
for impl_id in module_data.scope.impls() {
+ // Reservation impls should be ignored during trait resolution, so we never need
+ // them during type analysis. See rust-lang/rust#64631 for details.
+ //
+ // FIXME: Reservation impls should be considered during coherence checks. If we are
+ // (ever) to implement coherence checks, this filtering should be done by the trait
+ // solver.
+ if db.attrs(impl_id.into()).by_key("rustc_reservation_impl").exists() {
+ continue;
+ }
let target_trait = match db.impl_trait(impl_id) {
Some(tr) => tr.skip_binders().hir_trait_id(),
None => continue,
diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs
index fbdc8209f8..09c63f873e 100644
--- a/crates/hir-ty/src/tests/never_type.rs
+++ b/crates/hir-ty/src/tests/never_type.rs
@@ -483,3 +483,22 @@ fn example() -> bool {
"#,
);
}
+
+#[test]
+fn reservation_impl_should_be_ignored() {
+ // See rust-lang/rust#64631.
+ check_types(
+ r#"
+//- minicore: from
+struct S;
+#[rustc_reservation_impl]
+impl<T> From<!> for T {}
+fn foo<T, U: From<T>>(_: U) -> T { loop {} }
+
+fn test() {
+ let s = foo(S);
+ //^ S
+}
+"#,
+ );
+}