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

rkyv in Rust 1.56: type annotations needed #90195

Closed
xobs opened this issue Oct 23, 2021 · 10 comments · Fixed by #90375
Closed

rkyv in Rust 1.56: type annotations needed #90195

xobs opened this issue Oct 23, 2021 · 10 comments · Fixed by #90375
Assignees
Labels
C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@xobs
Copy link
Contributor

xobs commented Oct 23, 2021

Prior to Rust 1.56, I could use const usize values when defining rkyv structs. However, in Rust 1.56, this is no longer allowed.

Code

I tried this code:

const ARRAY_SIZE: usize = 32;

#[derive(rkyv::Archive, rkyv::Deserialize)]
struct SomeStruct1 {
    buffer_one: Option<[u8; ARRAY_SIZE]>,
    buffer_two: Option<[u8; ARRAY_SIZE]>,
}

fn main() {
    println!("Pass");
}

I expected to see this happen: Prior to Rust 1.56, this compiled.

Instead, this happened: The following error appears:

error[E0284]: type annotations needed: cannot satisfy `<Option<[u8; 32]> as Archive>::Archived == _`
 --> src\main.rs:3:25
  |
3 | #[derive(rkyv::Archive, rkyv::Deserialize)]
  |                         ^^^^^^^^^^^^^^^^^ cannot satisfy `<Option<[u8; 32]> as Archive>::Archived == _`
  |
  = note: this error originates in the derive macro `rkyv::Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0284`.
error: could not compile `rkyv-test` due to previous error

Version it worked on

It most recently worked on: Rust 1.55

Version with regression

rustc --version --verbose:

rustc 1.56.0 (09c42c458 2021-10-18)
binary: rustc
commit-hash: 09c42c45858d5f3aedfa670698275303a3d19afa
commit-date: 2021-10-18
host: x86_64-pc-windows-msvc
release: 1.56.0
LLVM version: 13.0.0
@xobs xobs added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Oct 23, 2021
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-untriaged Untriaged performance or correctness regression. labels Oct 23, 2021
@xobs
Copy link
Contributor Author

xobs commented Oct 23, 2021

Further information: This is using the rkyv crate. We use an older 0.4.0, however this still occurs with the latest 0.7 version.

bunnie added a commit to betrusted-io/xous-core that referenced this issue Oct 23, 2021
@hkratz
Copy link
Contributor

hkratz commented Oct 23, 2021

Bisected to #87280.

@rustbot label +E-needs-mcve

@rustbot rustbot added the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Oct 23, 2021
@hkratz
Copy link
Contributor

hkratz commented Oct 23, 2021

Reproducer without macros, but still dependent on rkyv:

#![allow(dead_code)]
#![allow(unused_variables)]

use rkyv::{Archive, Archived, Deserialize, Fallible};

const ARRAY_SIZE: usize = 32;
struct SomeStruct1 {
    buffer_one: Option<[u8; ARRAY_SIZE]>,
    buffer_two: Option<[u8; ARRAY_SIZE]>,
}

struct ArchivedSomeStruct1
where
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
{
    buffer_one: ::rkyv::Archived<Option<[u8; ARRAY_SIZE]>>,
    buffer_two: ::rkyv::Archived<Option<[u8; ARRAY_SIZE]>>,
}

struct SomeStruct1Resolver
where
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
{
    buffer_one: ::rkyv::Resolver<Option<[u8; ARRAY_SIZE]>>,
    buffer_two: ::rkyv::Resolver<Option<[u8; ARRAY_SIZE]>>,
}

impl Archive for SomeStruct1
where
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
    Option<[u8; ARRAY_SIZE]>: ::rkyv::Archive,
{
    type Archived = ArchivedSomeStruct1;
    type Resolver = SomeStruct1Resolver;
    #[allow(clippy::unit_arg)]
    #[inline]
    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
        unreachable!();
    }
}

impl<__D: Fallible + ?Sized> Deserialize<SomeStruct1, __D> for Archived<SomeStruct1>
where
    Option<[u8; ARRAY_SIZE]>: Archive,
    Archived<Option<[u8; ARRAY_SIZE]>>: Deserialize<Option<[u8; ARRAY_SIZE]>, __D>,
    Option<[u8; ARRAY_SIZE]>: Archive,
    Archived<Option<[u8; ARRAY_SIZE]>>: Deserialize<Option<[u8; ARRAY_SIZE]>, __D>,
{
    fn deserialize(
        &self,
        deserializer: &mut __D,
    ) -> ::core::result::Result<SomeStruct1, __D::Error> {
        unreachable!();
    }
}

fn main() {}

@SNCPlay42
Copy link
Contributor

Reduced:

pub trait Archive {
    type Archived;
}

impl<T> Archive for Option<T> {
    type Archived = ();
}
pub type Archived<T> = <T as Archive>::Archived;

pub trait Deserialize<D> {}

const ARRAY_SIZE: usize = 32;
impl<__D> Deserialize<__D> for ()
where
    Option<[u8; ARRAY_SIZE]>: Archive,
    Option<[u8; ARRAY_SIZE]>: Archive,
    Archived<Option<[u8; ARRAY_SIZE]>>: Deserialize<__D>,
{
}

Also, if you remove one of the Option<[u8; ARRAY_SIZE]>: Archive, lines, the code still compiles on 1.55 but the error on 1.56 changes to:

error[E0275]: overflow evaluating the requirement `(): Deserialize<__D>`
  --> <source>:13:11
   |
13 | impl<__D> Deserialize<__D> for ()
   |           ^^^^^^^^^^^^^^^^
   |
note: required by a bound in `Deserialize`
  --> <source>:10:1
   |
10 | pub trait Deserialize<D> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Deserialize`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.

@rustbot label regression-from-stable-to-stable

(not sure what happened with rustbot and the labels above)

@rustbot rustbot added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 23, 2021
@SNCPlay42
Copy link
Contributor

@rustbot label -E-needs-mcve

@rustbot rustbot removed the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Oct 23, 2021
@yanok
Copy link
Contributor

yanok commented Oct 28, 2021

@rustbot claim

@apiraino
Copy link
Contributor

Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.

@rustbot label -I-prioritize +P-high +T-compiler

@rustbot rustbot added P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 28, 2021
@yanok
Copy link
Contributor

yanok commented Oct 28, 2021

Ok, I know what is the problem and have a fix.

Apparently when looking for Archive implementation for Option<[u8; ARRAY_SIZE]> compiler considers candidates: one for top-level impl and two ParamCandidates.

Before #87280 candidate_should_be_dropped_in_favor_of was using TypeFoldable::is_global() that was enough to discard the two ParamCandidates. But #87280 changed it to use TypeFoldable::is_know_global() instead, which is pessimistic, so now the compiler drops the global impl instead (because is_known_global is not sure) and then can't decide between the two ParamCandidates.

@yanok
Copy link
Contributor

yanok commented Oct 28, 2021

Funny thing is it seems like it's fixed already in the master branch... Trying to bisect what fixed it to better understand if my change is needed after all.

@yanok
Copy link
Contributor

yanok commented Oct 28, 2021

c6b6901 also fixes it.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Oct 30, 2021
Use `is_global` in `candidate_should_be_dropped_in_favor_of`

This manifistated in rust-lang#90195 with compiler being unable to keep
one candidate for a trait impl, if where is a global impl and more
than one trait bound in the where clause.

Before rust-lang#87280 `candidate_should_be_dropped_in_favor_of` was using
`TypeFoldable::is_global()` that was enough to discard the two
`ParamCandidate`s. But rust-lang#87280 changed it to use
`TypeFoldable::is_known_global()` instead, which is pessimistic, so
now the compiler drops the global impl instead (because
`is_known_global` is not sure) and then can't decide between the
two `ParamCandidate`s.

Switching it to use `is_global` again solves the issue.

Fixes rust-lang#90195.
@bors bors closed this as completed in 6c61db4 Oct 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants