Skip to content

Regression in clone impl of enum with variant that has a field with a bivariant substitution #129286

Closed

Description

@compiler-errors

I tried this code:

trait Array {
    type Item;
}

trait Platform {
    type Assoc: Array<Item = Self::Assoc2>;
    type Assoc2;
}

struct Message<A, B>
where
    A: Array<Item = B>,
{
    pub field: A,
}

impl<A, B> Clone for Message<A, B>
where
    A: Array<Item = B>,
{
    fn clone(&self) -> Self {
        todo!()
    }
}

fn clone<P: Platform>(x: &Message<P::Assoc, P::Assoc2>) {
    let x: Message<_, _> = Clone::clone(x);
}

I expected it to work.

Instead, this happened:

error[E0282]: type annotations needed
  --> src/lib.rs:31:32
   |
31 |     Enum::Variant(Clone::clone(x))
   |                                ^ cannot infer type for reference `&Message<<P as Platform>::Assoc, _>`

I regressed this in #129059. I have no idea yet why it's happening! This also could be minimized further, I think.

Activity

  1. added
    C-bugCategory: This is a bug.
    A-coercionsArea: implicit and explicit `expr as Type` coercions
    A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Aug 20, 2024
  2. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 20, 2024
  3. added and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 20, 2024
  4. compiler-errors commented on Aug 20, 2024

    @compiler-errors
    ContributorAuthor

    Weirdly, this also only happens when the Clone::clone call is being directly passed to Enum::Variant. Is this due to Expectation, perhaps?

    edit: yep, it has to do with the Expectation. Minimized the code a bit more.

  5. compiler-errors commented on Aug 20, 2024

    @compiler-errors
    ContributorAuthor

    // 3. Check if the formal type is a supertype of the checked one
    // and register any such obligations for future type checks
    let supertype_error = self.at(&self.misc(provided_arg.span), self.param_env).sup(
    DefineOpaqueTypes::Yes,
    formal_input_ty,
    coerced_ty,
    );

    lol we're not actually constraining the target of the coercion properly

  6. compiler-errors commented on Aug 20, 2024

    @compiler-errors
    ContributorAuthor

    Minimal:

    trait Trait {
        type Item;
    }
    
    struct Struct<A: Trait<Item = B>, B> {
        pub field: A,
    }
    
    fn identity<T>(x: T) -> T {
        x
    }
    
    fn test<A: Trait<Item = B>, B>(x: &Struct<A, B>) {
        let x: &Struct<_, _> = identity(x);
    }
  7. added 2 commits that reference this issue on Aug 25, 2024
    fc83350
    b4cbff9
  8. added 2 commits that reference this issue on Sep 2, 2024
    3cb42da
    bd53aa3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-coercionsArea: implicit and explicit `expr as Type` coercionsA-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)C-bugCategory: This is a bug.P-mediumMedium priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions