From 9360adccda17f3236a93514a44f8c57b0be4c890 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Sun, 7 May 2023 01:31:36 +0900 Subject: [PATCH] Ignore impls with `#[rustc_reservation_impl]` --- crates/hir-ty/src/chalk_db.rs | 2 +- crates/hir-ty/src/method_resolution.rs | 9 +++++++++ crates/hir-ty/src/tests/never_type.rs | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index d68703ce1d47c..983cc22212421 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 for ChalkContext<'a> { } } -impl<'a> chalk_ir::UnificationDatabase for &'a dyn HirDatabase { +impl chalk_ir::UnificationDatabase for &dyn HirDatabase { fn fn_def_variance( &self, fn_def_id: chalk_ir::FnDefId, diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 912efc3a89605..8d57211db0778 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 fbdc8209f8f4b..09c63f873ee62 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 From for T {} +fn foo>(_: U) -> T { loop {} } + +fn test() { + let s = foo(S); + //^ S +} +"#, + ); +}