Skip to content

Commit

Permalink
Rollup merge of #111354 - jonas-schievink:enable-future-combinators, …
Browse files Browse the repository at this point in the history
…r=compiler-errors

Fix miscompilation when calling default methods on `Future`

In #111264 I discovered a lingering miscompilation when calling a default method on `Future` (none currently exist). #111279 added a debug assertion, which sadly doesn't help much since to my knowledge stage0 is not built with them enabled, and it still doesn't make default methods work like they should.

This PR fixes `resolve_instance` to resolve default methods on `Future` correctly, allowing library contributors to add `Future` combinators without running into ICEs or miscompilations. I've tested this as part of #111347, but no test is included here (assuming that future methods include their own tests that would cover this sufficiently).

r? `@compiler-errors`
  • Loading branch information
compiler-errors authored May 8, 2023
2 parents 24ba82d + 3bbb69e commit bbea63f
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions compiler/rustc_ty_utils/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,18 @@ fn resolve_associated_item<'tcx>(
})
}
traits::ImplSource::Future(future_data) => {
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll {
// For compiler developers who'd like to add new items to `Future`,
// you either need to generate a shim body, or perhaps return
// `InstanceDef::Item` pointing to a trait default method body if
// it is given a default implementation by the trait.
span_bug!(
tcx.def_span(future_data.generator_def_id),
"no definition for `{trait_ref}::{}` for built-in async generator type",
tcx.item_name(trait_item_id)
)
if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
// `Future::poll` is generated by the compiler.
Some(Instance {
def: ty::InstanceDef::Item(future_data.generator_def_id),
substs: future_data.substs,
})
} else {
// All other methods are default methods of the `Future` trait.
// (this assumes that `ImplSource::Future` is only used for methods on `Future`)
debug_assert!(tcx.impl_defaultness(trait_item_id).has_value());
Some(Instance::new(trait_item_id, rcvr_substs))
}
Some(Instance {
def: ty::InstanceDef::Item(future_data.generator_def_id),
substs: future_data.substs,
})
}
traits::ImplSource::Closure(closure_data) => {
if cfg!(debug_assertions)
Expand Down

0 comments on commit bbea63f

Please sign in to comment.