-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
ICE with higher-ranked lifetimes #48112
Comments
Did some minimization, and found some weird behavior. More minimal caseuse std::cell::RefMut;
fn main() {
StateMachine2::Init.resume();
}
enum StateMachine2<'a> {
Init,
#[allow(dead_code)] // match required for ICE
AfterTwoYields {
p: Backed<'a, *mut String>,
},
}
impl<'a> StateMachine2<'a> {
fn take(&self) -> Self {
StateMachine2::Init
}
}
impl<'a> StateMachine2<'a> {
fn resume(&mut self) -> () {
use StateMachine2::*;
match self.take() {
AfterTwoYields { p } => {
p.with(|_| {});
}
_ => panic!("Resume after completed."),
}
}
}
unsafe trait Unpack<'a> {
type Unpacked: 'a;
fn unpack(&self) -> Self::Unpacked {
unsafe { std::mem::transmute_copy(&self) }
}
}
unsafe trait Pack {
type Packed;
fn pack(&self) -> Self::Packed {
unsafe { std::mem::transmute_copy(&self) }
}
}
unsafe impl<'a> Unpack<'a> for String {
type Unpacked = String;
}
unsafe impl Pack for String {
type Packed = String;
}
unsafe impl<'a> Unpack<'a> for *mut String {
type Unpacked = &'a mut String;
}
unsafe impl<'a> Pack for &'a mut String {
type Packed = *mut String;
}
struct Backed<'a, U>(RefMut<'a, Option<String>>, U);
impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> {
fn with<F>(self, f: F) -> Backed<'a, ()>
where
F: for<'f> FnOnce(<U as Unpack<'f>>::Unpacked) -> (),
{
let result = f(self.1.unpack());
Backed(self.0, result)
}
} I ran into a wall in minimization here because my next step was to inline impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> {
fn with<F>(self, f: F) -> Backed<'a, ()>
where
F: for<'f> FnOnce(<U as Unpack<'f>>::Unpacked) -> (),
{
let result = f(self.1.unpack());
Backed(self.0, result)
}
} impl<'a, 'b> Backed<'a, *mut String> {
fn with<F>(self, f: F) -> Backed<'a, ()>
where
F: for<'f> FnOnce(&'f mut String) -> (),
{
let result = f(self.1.unpack());
Backed(self.0, result)
}
} When making that transformation, the ICE goes away. Replacing the entire body with
|
You are doing a better job of minimizing than I managed! |
CC #29997. |
closing as duplicate of #62529, which is where I will try to track future instances of this field of ICE. |
In the middle of mucking around with coding existential lifetime polymorphism with higher-ranked lifetimes, I got an ICE. No surprise there.
https://play.rust-lang.org/?gist=b09f418c9fd12193515708d11ec80eb2&version=stable
produces
I'm afraid it's as far from a small self-contained example as possible, sigh.
The text was updated successfully, but these errors were encountered: