Skip to content

Rust compiler panic in librustc/traits/codegen #70243

New issue

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

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

Already on GitHub? # to your account

Closed
calebmer opened this issue Mar 21, 2020 · 5 comments · Fixed by #85499
Closed

Rust compiler panic in librustc/traits/codegen #70243

calebmer opened this issue Mar 21, 2020 · 5 comments · Fixed by #85499
Labels
A-codegen Area: Code generation A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@calebmer
Copy link

The Rust compiler panicked with the following message. I’m not planning on taking the time to create a minimal repro, so you can immediately close if you’d like. Don’t know how useful just sharing a panic. message is.

error: internal compiler error: src/librustc/traits/codegen/mod.rs:57: Encountered error `OutputTypeParameterMismatch(Binder(<[closure@server/universe/schema/types/workspace.rs:66:30: 66:55] as std::ops::FnMut<(<graphql_prepare::prepare::PreparedSelection<model_district_raw::account::Table> as model_core::selection::Selection<'_, model_district_raw::account::Table>>::Data,)>>), Binder(<[closure@server/universe/schema/types/workspace.rs:66:30: 66:55] as std::ops::FnMut<(graphql_prepare::prepare::PreparedData<model_district_raw::account::Table>,)>>), Sorts(ExpectedFound { expected: graphql_prepare::prepare::PreparedData<model_district_raw::account::Table>, found: <graphql_prepare::prepare::PreparedSelection<model_district_raw::account::Table> as model_core::selection::Selection<'_, model_district_raw::account::Table>>::Data }))` selecting `Binder(<[closure@server/universe/schema/types/workspace.rs:66:30: 66:55] as std::ops::FnMut<(graphql_prepare::prepare::PreparedData<model_district_raw::account::Table>,)>>)` during codegen

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:873:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.42.0 (b8cedc004 2020-03-09) running on x86_64-apple-darwin
@calebmer
Copy link
Author

calebmer commented Mar 21, 2020

A little bit more information, if I take this code:

#[harness::test]
async fn select_equals() -> Result<(), Box<dyn Error>> {
    let client = connect().await?;

    assert_eq!(
        test::select()
            .where_eq(test::bar(), 32)
            .with(test::bar())
            .execute(&client)
            .await?
            .collect()
            .await?,
        vec![32]
    );

    Ok(())
}

…and remove #[harness::test] it compiles without error. Here’s the implementation of my harness macro:

https://gist.github.com/calebmer/752055b54d3573435048a41c6fd609e8

Although I think that might only be because the code is unreachable without the test macro.

@calebmer
Copy link
Author

calebmer commented Mar 21, 2020

Expanding the error message:

OutputTypeParameterMismatch(
  Binder(
    <[closure@server/model/core/select.rs:357:26: 357:35] as std::ops::FnMut<(
      <column::Column<select_tests::test::Table, types::I32Type> as selection::Selection<'_, select_tests::test::Table>>::Data,
    )>>
  ),
  Binder(
    <[closure@server/model/core/select.rs:357:26: 357:35] as std::ops::FnMut<(
      i32,
    )>>
  ),
  Sorts(
    ExpectedFound {
      expected: i32,
      found: <column::Column<select_tests::test::Table, types::I32Type> as selection::Selection<'_, select_tests::test::Table>>::Data
    }
  )
)

…and zooming in on:

expected: i32,
found: <column::Column<select_tests::test::Table, types::I32Type> as selection::Selection<'_, select_tests::test::Table>>::Data

…the type <column::Column<select_tests::test::Table, types::I32Type> as selection::Selection<'_, select_tests::test::Table>>::Data should resolve to i32.

@calebmer
Copy link
Author

This code is probably relevant. It’s doing some admittedly weird things:

/// A stream of PostgreSQL rows that were selected with some properly
/// typed `Selection`.
///
/// Doesn’t actually implement `Stream` because we need to make sure the
/// lifetimes are correct.
pub struct RowStream<S> {
    selection: S,
    stream: postgresql::RowStream,
}

impl<S> RowStream<S> {
    /// Maps the typed borrowed row data into whatever format you want to use.
    /// We don’t implement `Stream` since it’s important that we get the
    /// lifetimes right.
    #[inline]
    pub fn map<X, F, T>(self, mut mapper: F) -> impl Stream<Item = Result<T, Error>>
    where
        X: Table,
        S: for<'a> Selection<'a, X>,
        F: for<'a> FnMut(<S as Selection<'a, X>>::Data) -> T,
    {
        let RowStream { selection, stream } = self;
        stream.map(move |row| {
            let row = row.map_err(log::convert_error!("failed to execute sql query"))?;
            let row = Arc::new(row);
            let data = selection.dangerously_select_from_row(&row);
            let data = mapper(data);
            Ok::<_, Error>(data)
        })
    }

    /// Map all the items and then collect them into a `Vec`. Same as
    /// `stream.map().try_collect::<Vec<_>>()`.
    #[inline]
    pub async fn map_collect<X, F, T>(self, mut mapper: F) -> Result<Vec<T>, Error>
    where
        X: Table,
        S: for<'a> Selection<'a, X>,
        F: for<'a> FnMut(<S as Selection<'a, X>>::Data) -> T,
    {
        self.map(mapper).try_collect().await
    }

    /// Collects all the rows into a `Vec` as long as the data does not
    /// contain references.
    #[inline]
    pub async fn collect<'a, X, T>(self) -> Result<Vec<T>, Error>
    where
        X: Table,
        S: for<'b> Selection<'b, X, Data = T>,
        T: 'static,
    {
        self.map_collect(|row| row).await
    }
}

@calebmer calebmer changed the title Rust compiler panic Rust compiler panic in librustc/traits/codegen Mar 21, 2020
@Centril
Copy link
Contributor

Centril commented Mar 21, 2020

Probably a duplicate of #62529.

@Centril Centril added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-codegen Area: Code generation A-trait-system Area: Trait system E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example I-nominated labels Mar 21, 2020
@calebmer
Copy link
Author

I’m able to get this code working by changing map to:

pub fn map<X, F, T, U>(self, mut mapper: F) -> impl Stream<Item = Result<U, Error>>
where
    X: Table,
    S: for<'a> Selection<'a, X, Data = T>,
    F: FnMut(T) -> U,
{
    let RowStream { selection, stream } = self;
    stream.map(move |row| {
        let row = row.map_err(log::convert_error!("failed to execute sql query"))?;
        let row = Arc::new(row);
        let data = selection.dangerously_select_from_row(&row);
        let data = mapper(data);
        Ok::<_, Error>(data)
    })
}

@bors bors closed this as completed in 0afc208 Aug 25, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-codegen Area: Code generation A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority 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.

4 participants