Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new solver equates opaque to trait object instead of coercing #147

Open
lcnr opened this issue Jan 21, 2025 · 1 comment
Open

new solver equates opaque to trait object instead of coercing #147

lcnr opened this issue Jan 21, 2025 · 1 comment

Comments

@lcnr
Copy link
Contributor

lcnr commented Jan 21, 2025

affected test

  • tests/ui/impl-trait/unsized_coercion.rs
trait Trait {}

impl Trait for u32 {}

fn hello() -> Box<impl Trait> {
    if true {
        let x = hello();
        //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
        let y: Box<dyn Trait> = x;
    }
    Box::new(1u32)
}

fn main() {}

Assignig dyn Trait to the opaque should cause the existing ?hidden_ty: Sized obligation to fail, at least after proving Subtype obligations as well. We may want to check obligations before committing to coercions/equality in typeck.

@compiler-errors
Copy link
Member

compiler-errors commented Jan 22, 2025

We may want to check obligations before committing to coercions/equality in typeck.

I don't think this idea makes sense, since coercions falling back to equality is the last choice we have in coercion, namely after we've tried and failed to do an unsizing coercion first.

The real problem here is that this unsizing hack is not resilient enough with how we handle opaque types in the new solver:
https://github.com/rust-lang/rust/blob/dee7d0e730a3a3ed98c89dd33c4ac16edc82de8a/compiler/rustc_hir_typeck/src/coercion.rs#L641-L657

In the old solver, we see that we're trying to coerce Box<?0> to Box<dyn Trait>, and also see that ?0: Sized via an item bound of the opaque. But that doesn't work in the new solver since we have Box<impl Trait> being unsized to Box<dyn Trait>, but since we don't know the hidden type we just bail with ambiguity and fail to do the unsizing coercion.

edit: My analysis of how this succeeds in the old trait solver may be wrong too -- it may be due to the fact that we can rely on opaque item bounds holding in the defining scope even if we don't know the hidden type. That would allow impl Trait: Sized to hold, which is required for the unsize goal.

We probably could special-case this behavior in a new way if we turned this coercion loop into a proper proof tree visitor in the new solver, but this is also somewhat dissatisfying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants