Skip to content

coercion ?0: Sized check, rewrite to not rely on fulfill internals #104490

@lcnr

Description

@lcnr

The behavior of fn coerce_unsized for some inference variable ?0 changes depending on whether there's a pending ?0: Sized obligation in the fulfillment context:

match selcx.select(&obligation.with(trait_pred)) {
// Uncertain or unimplemented.
Ok(None) => {
if trait_pred.def_id() == unsize_did {
let trait_pred = self.resolve_vars_if_possible(trait_pred);
let self_ty = trait_pred.skip_binder().self_ty();
let unsize_ty = trait_pred.skip_binder().trait_ref.substs[1].expect_ty();
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
match (&self_ty.kind(), &unsize_ty.kind()) {
(ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
if self.type_var_is_sized(*v) =>

This pending obligation can be a nested obligation, e.g. we may have only added a Vec<?0>: Debug obligation to the fulfillment context. But proving that adds a nested ?0: Sized obligation from the impl candidate to the FulfillmentContext, which then influences coercion.

As our new solver should try to fully prove obligations instead of selecting a candidate and adding nested obligations to the root, this has to change.

cc @rust-lang/initiative-trait-system-refactor

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.T-typesRelevant to the types team, which will review and decide on the PR/issue.WG-trait-system-refactorThe Rustc Trait System Refactor Initiative (-Znext-solver)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions