diff options
| author | bors <bors@rust-lang.org> | 2023-05-06 17:44:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-05-06 17:44:48 +0000 |
| commit | bb66f6fc3c9fc7de653701ce692aec9ec9458f12 (patch) | |
| tree | 07ad9c13b9fa2b1136c29cef153d428ddbf8086b | |
| parent | 5ee39a6ee50e6ddfdf5ac5532bbd13e268b3bf36 (diff) | |
| parent | 9360adccda17f3236a93514a44f8c57b0be4c890 (diff) | |
| download | rust-bb66f6fc3c9fc7de653701ce692aec9ec9458f12.tar.gz rust-bb66f6fc3c9fc7de653701ce692aec9ec9458f12.zip | |
Auto merge of #14750 - lowr:fix/rustc_reservation_impl, r=HKalbasi
fix: ignore impls with `#[rustc_reservation_impl]` Fixes #12247 Fixes #14279 Currently core has two blanket impls for `From`: `impl<T> From<T> for T` and `impl<T> From<!> for T`. These are conflicting and thus chalk cannot uniquely solve `S: From<?0>` for any type `S`. The latter impl is actually a reservation impl and should not be considered during trait selection. More generally, impls attributed with perma-unstable `#[rustc_reservation_impl]` attribute should be disregarded except for coherence checks. See rust-lang/rust#64631 and rust-lang/rust#64715 for details. I chose to entirely ignore them in hir-ty because we don't do coherence checks.
| -rw-r--r-- | crates/hir-ty/src/chalk_db.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 9 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/never_type.rs | 19 |
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 d68703ce1d4..983cc222124 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 912efc3a896..8d57211db07 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 fbdc8209f8f..09c63f873ee 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 +} +"#, + ); +} |
