Skip to content

Commit

Permalink
Auto merge of rust-lang#14750 - lowr:fix/rustc_reservation_impl, r=HK…
Browse files Browse the repository at this point in the history
…albasi

fix: ignore impls with `#[rustc_reservation_impl]`

Fixes rust-lang#12247
Fixes rust-lang#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#64631 and rust-lang#64715 for details.

I chose to entirely ignore them in hir-ty because we don't do coherence checks.
  • Loading branch information
bors committed May 6, 2023
2 parents 5ee39a6 + 9360adc commit bb66f6f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
9 changes: 9 additions & 0 deletions crates/hir-ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions crates/hir-ty/src/tests/never_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
"#,
);
}

0 comments on commit bb66f6f

Please sign in to comment.