jiebi/CodeConvo huggingface dataset:
Code change:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

Related discussion:
text: /// # Examples /// /// Initialize static variables with `LazyLock`. <del> /// </del> /// ``` <del> /// use std::collections::HashMap; /// </del> /// use std::sync::LazyLock; /// <del> /// static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| { ///     println!("initializing"); ///     let mut m = HashMap::new(); ///     m.insert(13, "Spica".to_string()); ///     m.insert(74, "Hoyten".to_string()); ///     m </del> <ins> /// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated. /// // this is fine, as the OS can deallocate the terminated program faster than we can free memory /// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional. /// static DEEP_THOUGHT: LazyLock<String> = LazyLock::new(|| { /// # mod another_crate { /// #     pub fn great_question() -> String { "42".to_string() } /// # } ///     // M3 Ultra takes about 16 million years in --release config ///     another_crate::great_question() </ins> /// }); /// <del> /// fn main() { ///     println!("ready"); ///     std::thread::spawn(|| { ///         println!("{:?}", HASHMAP.get(&13)); ///     }).join().unwrap(); ///     println!("{:?}", HASHMAP.get(&74)); /// ///     // Prints: ///     //   ready ///     //   initializing ///     //   Some("Spica") ///     //   Some("Hoyten") /// } </del> <ins> /// // The `String` is built, stored in the `LazyLock`, and returned as `&String`. /// let _ = &*DEEP_THOUGHT; /// // The `String` is retrieved from the `LazyLock` and returned as `&String`. /// let _ = &*DEEP_THOUGHT; </ins> /// ``` <ins> /// </ins> /// Initialize fields with `LazyLock`. /// ``` /// use std::sync::LazyLock;
Code change:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

Related discussion:
text: //! - [`Once`]: Used for a thread-safe, one-time global initialization routine //! //! - [`OnceLock`]: Used for thread-safe, one-time initialization of a <del> //!   global variable. </del> <ins> //!   variable, with potentially different initializers based on the caller. //! //! - [`LazyLock`]: Used for thread-safe, one-time initialization of a //!   variable, using one nullary initializer function provided at creation. </ins> //! //! - [`RwLock`]: Provides a mutual exclusion mechanism which allows //!   multiple readers at the same time, while allowing only one
Code change:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

Related discussion:
text: /// A synchronization primitive which can be written to only once. /// /// This type is a thread-safe [`OnceCell`], and can be used in statics. <ins> /// In many simple cases, you can use [`LazyLock<T, F>`] instead to get the benefits of this type /// with less effort: `LazyLock<T, F>` "looks like" `&T` because it initializes with `F` on deref! /// Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock /// doesn't allow additional inputs to its function after you call [`LazyLock::new(|| ...)`]. </ins> /// /// [`OnceCell`]: crate::cell::OnceCell <ins> /// [`LazyLock<T, F>`]: crate::sync::LazyLock /// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new </ins> /// /// # Examples /// <del> /// Using `OnceLock` to store a function’s previously computed value (a.k.a. /// ‘lazy static’ or ‘memoizing’): /// /// ``` /// use std::sync::OnceLock; /// /// struct DeepThought { ///     answer: String, /// } /// /// impl DeepThought { /// #   fn great_question() -> String { /// #       "42".to_string() /// #   } /// # ///     fn new() -> Self { ///         Self { ///             // M3 Ultra takes about 16 million years in --release config ///             answer: Self::great_question(), ///         } ///     } /// } /// /// fn computation() -> &'static DeepThought { ///     // n.b. static items do not call [`Drop`] on program termination, so if ///     // [`DeepThought`] impls Drop, that will not be used for this instance. ///     static COMPUTATION: OnceLock<DeepThought> = OnceLock::new(); ///     COMPUTATION.get_or_init(|| DeepThought::new()) /// } /// /// // The `DeepThought` is built, stored in the `OnceLock`, and returned. /// let _ = computation().answer; /// // The `DeepThought` is retrieved from the `OnceLock` and returned. /// let _ = computation().answer; /// ``` /// </del> /// Writing to a `OnceLock` from a separate thread: /// /// ```
Code change:
These types are now, however, the docs don't properly mention them everywhere yet: lists OnceCell in the overview, but not LazyCell. The docs should also explain when I should use which of these types, as they are superficially pretty similar. lists Once and OnceLock, but not LazyLock. The same point about "when to use which type" applies. (It seems like is basically the same as , but I am not sure.) Cc
thatnks for the PR! The question of Once vs OnceLock seems to remain unresolved though. If Once is to OnceLock what is to Mutex, then it should probably be considered extremely niche as one can't even safely protect any data that way?
Yeah, I do indeed have nothing useful to say about Once, basically, because it doesn't seem very useful except as a raw implementation primitive of OnceLock. I suppose we could add a comment that soft-discourages it?
Yeah I think that would be useful.

Related discussion:
text: ///     Some(&12345), /// ); /// ``` <ins> /// /// You can use `OnceLock` to implement a type that requires "append-only" logic: /// /// ``` /// use std::sync::{OnceLock, atomic::{AtomicU32, Ordering}}; /// use std::thread; /// /// struct OnceList<T> { ///     data: OnceLock<T>, ///     next: OnceLock<Box<OnceList<T>>>, /// } /// impl<T> OnceList<T> { ///     const fn new() -> OnceList<T> { ///         OnceList { data: OnceLock::new(), next: OnceLock::new() } ///     } ///     fn push(&self, value: T) { ///         // FIXME: this impl is concise, but is also slow for long lists or many threads. ///         // as an exercise, consider how you might improve on it while preserving the behavior ///         if let Err(value) = self.data.set(value) { ///             let next = self.next.get_or_init(|| Box::new(OnceList::new())); ///             next.push(value) ///         }; ///     } ///     fn contains(&self, example: &T) -> bool ///     where ///         T: PartialEq, ///     { ///         self.data.get().map(|item| item == example).filter(|v| *v).unwrap_or_else(|| { ///             self.next.get().map(|next| next.contains(example)).unwrap_or(false) ///         }) ///     } /// } /// /// // Let's exercise this new Sync append-only list by doing a little counting /// static LIST: OnceList<u32> = OnceList::new(); /// static COUNTER: AtomicU32 = AtomicU32::new(0); /// /// let vec = (0..thread::available_parallelism().unwrap().get()).map(|_| thread::spawn(|| { ///     while let i @ 0..=1000 = COUNTER.fetch_add(1, Ordering::Relaxed) { ///         LIST.push(i); ///     } /// })).collect::<Vec<thread::JoinHandle<_>>>(); /// vec.into_iter().for_each(|handle| handle.join().unwrap()); /// /// for i in 0..=1000 { ///     assert!(LIST.contains(&i)); /// } /// /// ``` </ins> #[stable(feature = "once_cell", since = "1.70.0")] pub struct OnceLock<T> { once: Once,
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: // Get the arguments for the found method, only specifying that `Self` is the receiver type. let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return }; let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { <del> if param.index == 0 { </del> <ins> if let ty::GenericParamDefKind::Lifetime = param.kind { tcx.lifetimes.re_erased.into() } else if param.index == 0 && param.name == kw::SelfUpper { </ins> possible_rcvr_ty.into() } else if param.index == closure_param.index { closure_ty.into()
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: Obligation::misc(tcx, span, self.mir_def_id(), self.param_env, pred) })); <del> if ocx.select_all_or_error().is_empty() { </del> <ins> if ocx.select_all_or_error().is_empty() && count > 0 { </ins> diag.span_suggestion_verbose( tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(), "dereference the return value",
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: <del> //@ known-bug: rust-lang/rust#124563 use std::marker::PhantomData; pub trait Trait {} pub trait Foo { type Trait: Trait; type Bar: Bar; fn foo(&mut self); } pub struct FooImpl<'a, 'b, A: Trait>(PhantomData<&'a &'b A>); impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> where T: Trait, { type Trait = T; type Bar = BarImpl<'a, 'b, T>; fn foo(&mut self) { self.enter_scope(|ctx| { BarImpl(ctx); }); } } impl<'a, 'b, T> FooImpl<'a, 'b, T> where T: Trait, { fn enter_scope(&mut self, _scope: impl FnOnce(&mut Self)) {} } pub trait Bar { type Foo: Foo; } pub struct BarImpl<'a, 'b, T: Trait>(&'b mut FooImpl<'a, 'b, T>); impl<'a, 'b, T> Bar for BarImpl<'a, 'b, T> where T: Trait, { type Foo = FooImpl<'a, 'b, T>; } </del>
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: <ins> // #125634 struct Thing; // Invariant in 'a, Covariant in 'b struct TwoThings<'a, 'b>(*mut &'a (), &'b mut ()); impl Thing { fn enter_scope<'a>(self, _scope: impl for<'b> FnOnce(TwoThings<'a, 'b>)) {} } fn foo() { Thing.enter_scope(|ctx| { SameLifetime(ctx); //~ ERROR lifetime may not live long enough }); } struct SameLifetime<'a>(TwoThings<'a, 'a>); fn main() {} </ins>
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: <ins> error: lifetime may not live long enough --> $DIR/account-for-lifetimes-in-closure-suggestion.rs:13:22 | LL |     Thing.enter_scope(|ctx| { |                        --- |                        | |                        has type `TwoThings<'_, '1>` |                        has type `TwoThings<'2, '_>` LL |         SameLifetime(ctx); |                      ^^^ this usage requires that `'1` must outlive `'2` | = note: requirement occurs because of the type `TwoThings<'_, '_>`, which makes the generic argument `'_` invariant = note: the struct `TwoThings<'a, 'b>` is invariant over the parameter `'a` = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error: aborting due to 1 previous error </ins>
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: <ins> // #124563 use std::marker::PhantomData; pub trait Trait {} pub trait Foo { type Trait: Trait; type Bar: Bar; fn foo(&mut self); } pub struct FooImpl<'a, 'b, A: Trait>(PhantomData<&'a &'b A>); impl<'a, 'b, T> Foo for FooImpl<'a, 'b, T> where T: Trait, { type Trait = T; type Bar = BarImpl<'a, 'b, T>; //~ ERROR lifetime bound not satisfied fn foo(&mut self) { self.enter_scope(|ctx| { //~ ERROR lifetime may not live long enough BarImpl(ctx); //~ ERROR lifetime may not live long enough }); } } impl<'a, 'b, T> FooImpl<'a, 'b, T> where T: Trait, { fn enter_scope(&mut self, _scope: impl FnOnce(&mut Self)) {} } pub trait Bar { type Foo: Foo; } pub struct BarImpl<'a, 'b, T: Trait>(&'b mut FooImpl<'a, 'b, T>); impl<'a, 'b, T> Bar for BarImpl<'a, 'b, T> where T: Trait, { type Foo = FooImpl<'a, 'b, T>; } fn main() {} </ins>
Code change:
<!-- [31mICE[0m: Rustc '' 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'', 'thread 'rustc' panicked at 'expected region for ('a//0) but found Type(&'{erased} mut FooImpl<'{erased}, '{erased}, T/) when instantiating args=[&'{erased} mut FooImpl<'{erased}, '{erased}, T/, '?27, ?2t, Closure(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), ['{erased}, '{erased}, T/, i32, Binder(fn((&ReLateParam(DefId(0:22 ~ a[a197]::{impl}::foo::{closure}), BrAnon) mut FooImpl<'{erased}, '{erased}, T/,)), []), ()])]'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [mirborrowck] borrow-checking --
ICEs on nightly and beta, but not on stable. Minimized further: <details<summaryProgram output</summary</details
The ICE is another one from , cc
Still reproduces on 1.81.0-nightly (2024-06-13 ) -E-needs-test
I'll look into it later today.

Related discussion:
text: <ins> // Test a method call where the parameter `B` would (illegally) be // inferred to a region bound in the method argument. If this program // were accepted, then the closure passed to `s.f` could escape its // argument. //@ run-rustfix struct S; impl S { fn f<B, F>(&self, _: F) where F: FnOnce(&i32) -> B { } } fn main() { let s = S; s.f(|p| *p) //~ ERROR lifetime may not live long enough } </ins>