-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
internal compiler error: src/librustc_traits/normalize_erasing_regions.rs:42 #67684
Comments
If possible, a self-contained reproducer in the playground would be quite helpful towards fixing the bug. |
@Centril -- I tried, but the |
@dpp You can't. What I would do is inline the pieces you need from |
🙄 Okay... y'all have a bug that causes the compiler to panic. This is suboptimal in a language that is supposed to make guarantees about this kinda thing. But okay... there's a panic in the compiler. Me... a Rust n00b, but a person who's been doing open source for 29 years and have my share But you've just asked me to copy/paste 13,000 LoC into the playground and nibble away at the Not real welcoming. |
@dpp I think there’s some misunderstanding here:
as @Centril wrote, he was just trying to guide you to create a mcve. If time is tough for you, just leave this ICE here, mvce of an ICE is not a must from the original reporter, people from the community will pick this up to minimize as the |
ICE occurs in:
|
triage P-high, at least to learn more about the nature of this bug itself (e.g. getting the MCVE, and/or a stack trace...) |
Not minimal but maybe small enough (playground): use std::marker::PhantomData;
trait StreamError<Item, Range>: Sized {}
trait ParseError<Item, Range>: Sized {
type StreamError: StreamError<Item, Range>;
}
struct FastResult<T, E> {
_marker: PhantomData<(T, E)>,
}
type ConsumedResult<O, I> = FastResult<O, <I as Stream>::Error>;
trait Stream {
type Item;
type Range;
type Error: ParseError<Self::Item, Self::Range>;
}
enum Error<T, R> {
Expected(PhantomData<(T, R)>),
}
impl<Item, Range> StreamError<Item, Range> for Error<Item, Range> {}
impl<Item, Range> ParseError<Item, Range> for Errors<Item, Range> {
type StreamError = Error<Item, Range>;
}
type EasyParseError<S> = Errors<<S as Stream>::Item, <S as Stream>::Range>;
struct Errors<I, R> {
_marker: PhantomData<(I, R)>,
}
fn token<I>(_c: I::Item) -> Token<I>
where
I: Stream,
I::Item: PartialEq,
{
unimplemented!()
}
struct Token<I>
where
I: Stream,
{
_marker: PhantomData<I>,
}
impl<I> Parser for Token<I>
where
I: Stream,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
}
struct AndThen<P, F>(P, F);
impl<P, F, O, E, I> Parser for AndThen<P, F>
where
I: Stream,
P: Parser<Input = I>,
F: FnMut(P::Output) -> Result<O, E>,
E: Into<<I::Error as ParseError<I::Item, I::Range>>::StreamError>,
I::Error: ParseError<I::Item, I::Range>,
{
type Input = P::Input;
type Output = O;
type PartialState = P::PartialState;
}
trait Parser {
type Input: Stream;
type Output;
type PartialState: Default;
fn parse_mode(
&mut self,
_input: &mut Self::Input,
_state: &mut Self::PartialState,
) -> ConsumedResult<Self::Output, Self::Input>
where
Self: Sized,
{
unimplemented!()
}
fn and_then<F, O, E, I>(self, _f: F) -> AndThen<Self, F>
where
Self: Parser<Input = I> + Sized,
F: FnMut(Self::Output) -> Result<O, E>,
I: Stream,
E: Into<<I::Error as ParseError<I::Item, I::Range>>::StreamError>,
{
unimplemented!()
}
}
fn expr<I>() -> impl Parser<Input = I, Output = ()>
where
I: Stream<Item = char, Error = EasyParseError<I>>,
{
let int2 = token('-').and_then(|_| Err(Error::Expected(PhantomData)));
int2
}
struct Expr<I>
where
<I as Stream>::Error: ParseError<<I as Stream>::Item, <I as Stream>::Range>,
I: Stream<Item = char, Error = EasyParseError<I>>,
{
_marker: std::marker::PhantomData<fn(I) -> ()>,
}
impl<I> Expr<I>
where
<I as Stream>::Error: ParseError<<I as Stream>::Item, <I as Stream>::Range>,
I: Stream<Item = char, Error = EasyParseError<I>>,
{
#[allow(dead_code)]
fn parse_mode_impl(&mut self, input: &mut I) -> ConsumedResult<(), I> {
let Expr { .. } = *self;
{
let mut state = Default::default();
expr().parse_mode(input, &mut state)
}
}
} Backtrace details
Seemingly while computing the optimized MIR: evaluating a constant in the const propagator. |
Reduced so far: use std::marker::PhantomData;
trait ParseError<Item, Range> {
type StreamError;
}
trait Stream {
type Item;
type Range;
type Error: ParseError<Self::Item, Self::Range>;
}
impl<Item, Range> ParseError<Item, Range> for Errors<Item, Range> {
type StreamError = ();
}
type EasyParseError<S> = Errors<<S as Stream>::Item, <S as Stream>::Range>;
struct Errors<I, R> {
_marker: PhantomData<(I, R)>,
}
impl<I> Parser for PhantomData<I> {
type Input = I;
type Output = I;
type PartialState = ();
}
struct AndThen<P, I, O, E>(P, I, O, E);
impl<P, O, E, I> Parser for AndThen<P, I, O, E>
where
I: Stream,
P: Parser,
E: Into<<I::Error as ParseError<I::Item, I::Range>>::StreamError>,
{
type Input = P::Input;
type Output = ();
type PartialState = ();
}
trait Parser {
type Input;
type Output;
type PartialState: Default;
fn parse_mode(self, _: Self::Input, _: Self::PartialState)
where
Self: Sized,
{
loop {}
}
}
struct Expr<I>
where
I: Stream<Error = EasyParseError<I>>,
{
_marker: std::marker::PhantomData<fn(I) -> ()>,
}
impl<I> Expr<I>
where
<I as Stream>::Error: ParseError<<I as Stream>::Item, <I as Stream>::Range>,
I: Stream<Error = EasyParseError<I>>,
{
#[allow(dead_code)]
fn parse_mode_impl(self, input: I) {
fn expr<I>() -> impl Parser<Input = I, Output = ()>
where
I: Stream<Error = EasyParseError<I>>,
{
(loop {}) as AndThen<PhantomData<I>, I, (), ()>
}
expr().parse_mode(input, Default::default())
}
} |
Reduced more: #![allow(dead_code)]
trait ParseError {
type StreamError;
}
impl<T> ParseError for T {
type StreamError = ();
}
trait Stream {
type Item;
type Error: ParseError;
}
trait Parser
where
<Self as Parser>::PartialState: Default,
{
type PartialState;
fn parse_mode(_: &Self, _: Self::PartialState) {
loop {}
}
}
impl Stream for () {
type Item = ();
type Error = ();
}
impl Parser for () {
type PartialState = ();
}
struct AndThen<A, B>(core::marker::PhantomData<(A, B)>);
impl<A, B> Parser for AndThen<A, B>
where
A: Stream,
B: Into<<A::Error as ParseError>::StreamError>,
{
type PartialState = ();
}
fn expr<A>() -> impl Parser
where
A: Stream<Error = <A as Stream>::Item>,
{
AndThen::<A, ()>(core::marker::PhantomData)
}
fn parse_mode_impl<A>()
where
<A as Stream>::Error: ParseError,
A: Stream<Error = <A as Stream>::Item>,
{
Parser::parse_mode(&expr::<A>(), Default::default())
} |
Curiously, I can't get the latest MVCE to ICE on the latest nightly for Mac, even though it ICEs just fine on the playground. |
I am reliably hitting this ICE with nightly-2020-09-07-x86_64-unknown-freebsd, but not with nightly-2020-08-28-x86_64-unknown-freebsd. Unfortunately, I'm hitting it in a large application that only builds on FreeBSD, so my odds of reducing it to a slim test case are slim. But it looks like the same error as in the playground link above. |
@dpp You may be interested in how @chengniansun uses Perses. |
Further reduced with perses. trait ParseError {
type StreamError;
}
impl<T> ParseError for T {
type StreamError = ();
}
trait Stream {
type Error;
}
trait Parser
where
<Self as Parser>::PartialState: Default,
{
type PartialState;
fn parse_mode(&Self, Self::PartialState) {}
}
struct AndThen<A, B>(core::marker::PhantomData<(A, B)>);
impl<A, B> Parser for AndThen<A, B>
where
A: Stream,
B: Into<<A::Error as ParseError>::StreamError>,
{
type PartialState = ();
}
fn expr<A>() -> impl Parser
where
A: Stream,
{
AndThen::<A, ()>(core::marker::PhantomData)
}
fn parse_mode_impl<A>()
where
A::Error: ParseError,
A: Stream,
{
Parser::parse_mode(&expr::<A>(), Default::default())
} Stack trace
|
Issue: rust-lang/rust#67684
Issue: rust-lang/rust#67684
EDITED: MCVE is here: #67684 (comment)
I received this compiler bug:
Compiling with this cargo.toml file:
And this
main.rs
:The text was updated successfully, but these errors were encountered: