-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
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: