Question:
Found with the help of .
There's two slicing operations in . I'm trying to figure out how a non-boundary index could be appearing in there... maybe is calling with a span that begins at index 10? (where does this come from? ?) Building a debug compiler to check those log statements... Edit: Building the debug compiler was a bust. Embarassingly, things seem to have changed and I don't know how to get those debug macros to fire in the current compiler.
do you mean you were using and not seeing debug output? If so, that is because the environment variable name under was changed to . (I make this mistake pretty much every day due to muscle memory.) As an example, here is the tail of my log output:
triage: P-medium. Removing nomination.
This was broken between 1.15 and 1.16, but those are so old and the nature of the ICE itself has changed from 1.28 to 1.29, so I do not think bisection would be worthwhile.
<details<summaryOfftopic</summary : Thanks. Unfortunately, I did guess the name of after didn't work, and all it showed me was this: I set in my before building, and didn't see anything else in there. (I recall that and used to be but it is no longer, so I did not enable it.) </details
Okay, I did the following evil, evil thing: <details<summaryPure evil, do not open</summary</detailsAnd acquired the following backtrace of when the span was first constructed: It also gets constructed a second time: <details<summarySecond backtrace</summary(the region of the backtrace that differs between the two is items 22-29 in the first one, or 22-25 in the second) </detailsSome interesting spots from here: This is clearly where the value of 10 is created: calls this if there are no remaining tokens and it still hasn't seen the closing delimiter (it seems to have as an unstated precondition that the closing delimiter must exist). Here's the innermost bit that's specific to parsing. Doesn't look that odd...
I’m not familiar with I tend to list (comma separated) module paths in my own use of RUSTCLOG; did you try that? You can see an example in the transcript I gave in my comment above
Oh. (I'm so used to prompts I didn't notice you included the command!). Yeah, that was the issue.
Same ICE occurs with: Which returns:
could you post a base64-encoded version of your ? When I copy/paste what you've posted above, I don't see a compiler crash, presumably because some non-ascii characters are getting lost.
My bad
Hm, the example from hasn't been fixed?
Seems so, on the current nightly:
I guess my fix would help. I'll get some time to test it out.
Confirmed that my fix fixed this issue, I also add this unit test in this PR:

<ins> // ignore-tidy-trailing-newlines // error-pattern: aborting due to 3 previous errors y![ Ϥ, </ins>  No newline at end of file


Question:
Found with the help of .
There's two slicing operations in . I'm trying to figure out how a non-boundary index could be appearing in there... maybe is calling with a span that begins at index 10? (where does this come from? ?) Building a debug compiler to check those log statements... Edit: Building the debug compiler was a bust. Embarassingly, things seem to have changed and I don't know how to get those debug macros to fire in the current compiler.
do you mean you were using and not seeing debug output? If so, that is because the environment variable name under was changed to . (I make this mistake pretty much every day due to muscle memory.) As an example, here is the tail of my log output:
triage: P-medium. Removing nomination.
This was broken between 1.15 and 1.16, but those are so old and the nature of the ICE itself has changed from 1.28 to 1.29, so I do not think bisection would be worthwhile.
<details<summaryOfftopic</summary : Thanks. Unfortunately, I did guess the name of after didn't work, and all it showed me was this: I set in my before building, and didn't see anything else in there. (I recall that and used to be but it is no longer, so I did not enable it.) </details
Okay, I did the following evil, evil thing: <details<summaryPure evil, do not open</summary</detailsAnd acquired the following backtrace of when the span was first constructed: It also gets constructed a second time: <details<summarySecond backtrace</summary(the region of the backtrace that differs between the two is items 22-29 in the first one, or 22-25 in the second) </detailsSome interesting spots from here: This is clearly where the value of 10 is created: calls this if there are no remaining tokens and it still hasn't seen the closing delimiter (it seems to have as an unstated precondition that the closing delimiter must exist). Here's the innermost bit that's specific to parsing. Doesn't look that odd...
I’m not familiar with I tend to list (comma separated) module paths in my own use of RUSTCLOG; did you try that? You can see an example in the transcript I gave in my comment above
Oh. (I'm so used to prompts I didn't notice you included the command!). Yeah, that was the issue.
Same ICE occurs with: Which returns:
could you post a base64-encoded version of your ? When I copy/paste what you've posted above, I don't see a compiler crash, presumably because some non-ascii characters are getting lost.
My bad
Hm, the example from hasn't been fixed?
Seems so, on the current nightly:
I guess my fix would help. I'll get some time to test it out.
Confirmed that my fix fixed this issue, I also add this unit test in this PR:

<ins> error: this file contains an un-closed delimiter --> $DIR/issue-62524.rs:4:3 | LL | y![ |   - un-closed delimiter LL | Ϥ, |   ^ error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/issue-62524.rs:3:3 | LL |   y![ |  ___^ LL | | Ϥ, | |__^ | help: change the delimiters to curly braces | LL | y!{ LL | Ϥ} | help: add a semicolon | LL | Ϥ,; |   ^ error: cannot find macro `y` in this scope --> $DIR/issue-62524.rs:3:1 | LL | y![ | ^ error: aborting due to 3 previous errors </ins>


Question:
The godbolt link: I think this snippet should just return : The generated asm with :
I think there are 2 issues: is not const fn is not const fn See this modified example:
I may misunderstand but in the C version, does clang require similar conditions to optimize code? modify labels: A-codegen A-const-eval
Those are preprocessor directives and are handled at compile time so their Rust equivalent would be:
states that macro:
Good point, those two are equal: I don't know enough about const and I could be totally wrong but I think in the first case expands to something like: It cannot make constant because is not yet complete.
Interesting, If I look at MIR output, I think rustc already have enough information: <details<summaryMIR</summary</details
Whether a function is marked at the source level has no effect on whether or not it can be optimized by LLVM. Even if was not , inlining and const propagation could conceivably reduce this to a constant.
Rust now generates the for the OP's code: I would guess that recent improvements to const propagation in the MIR are responsible for this (thanks but it might also have been a change in LLVM. This seems like a decent candidate for a codegen regression test, although an equivalent one might already exist.
It is better now. But are and instructions necessary?
I assume it is due to a difference in calling convention, but it does seem kind of silly. You'll need to ask someone more knowledgeable unfortunately.
A quick google leads me to believe that the is used to align the stack to a 16-byte boundary.
So does it: Looks like only regression tests are needed.
This version doesn't need any stack alignment:
I tried to leave this alone since I'm not very knowledgeable in this area, but curiosity got the better of me. The following might be incorrect, but it's my best guess. In the optimized LLVM IR for rust, a call to remains which has been optimized out in the C++ version. I believe stack alignment on x64 is required only prior to a instruction, so LLVM sees that a non-trivial call instruction exists in the IR from rust and that only has an 8-byte return pointer on the stack, meaning the stack would be misaligned for that . That's why it inserts the stack alignment code in the rust version only. At some point during translation to x86 assembly, the gets removed entirely (I have no idea how), resulting in a function that has a / to align the stack for a call but that doesn't actually call anything. Perhaps someone more familiar with the various LLVM passes could say more. BTW, a fairer C++ comparison is the following, but this gives the same results:
There's some discussion of this in . I was indeed wrong BTW :smile:.
This issue appears to be fixed on beta. Maybe we need a codegen test for it. Edit: It seems that the llvm-ir generated by rustc are the same between beta and stable. Only the optimized asm for x86 is different. Should I just write assembly codegen or just close this issue.
The issue seems to have re-appeared in master :(
Both & generates the following asm (with )

<ins> // Ensure the asm for array comparisons is properly optimized. //@ compile-flags: -C opt-level=2 #![crate_type = "lib"] // CHECK-LABEL: @compare // CHECK: start: // CHECK-NEXT: ret i1 true #[no_mangle] pub fn compare() -> bool { let bytes = 12.5f32.to_ne_bytes(); bytes == if cfg!(target_endian = "big") { [0x41, 0x48, 0x00, 0x00] } else { [0x00, 0x00, 0x48, 0x41] } } </ins>


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

self.tcx().mk_const( ty::Const { val: ConstValue::Infer(InferConst::Canonical(self.binder_index, var.into())), <del> ty: const_var.ty, </del> <ins> ty: self.fold_ty(const_var.ty), </ins> } ) }


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

<ins> // revisions:rpass1 #![feature(const_generics)] struct Struct<T>(T); impl<T, const N: usize> Struct<[T; N]> { fn f() {} fn g() { Self::f(); } } fn main() { Struct::<[u32; 3]>::g(); } </ins>


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

<ins> // revisions:rpass1 #![feature(const_generics)] struct FakeArray<T, const N: usize>(T); impl<T, const N: usize> FakeArray<T, { N }> { fn len(&self) -> usize { N } } fn main() { let fa = FakeArray::<u32, { 32 }>(1); assert_eq!(fa.len(), 32); } </ins>


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

<ins> // revisions:cfail1 #![feature(const_generics)] //[cfail1]~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash struct S<T, const N: usize>([T; N]); fn f<T, const N: usize>(x: T) -> S<T, {N}> { panic!() } fn main() { f(0u8); //[cfail1]~^ ERROR type annotations needed } </ins>


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

<ins> // revisions:cfail1 #![feature(const_generics)] //[cfail1]~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash fn combinator<T, const S: usize>() -> [T; S] {} //[cfail1]~^ ERROR mismatched types fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed } </ins>


Question:
A clean rust project on the latest nightly rustc with just this : produces the following error on cargo check/build: <details</detailsThe error is most likely caused by the inability to deduce the value of the const generic parameter ; when it is made clear (with, say, ) the ICE no longer occurs. Thus the expected behavior is probably still a failure to build (just not an ICE).
EDIT: Apparently const-generics in array repeat positions isn't a thing yet, at all. I apologize for the not-even-currently-valid example. I get the same ICE for this code: <details</detailswhich does give the explicit type, so it's not (entirely) a deduction thing. Entire build log: <details</details
Could you check the ICE still appears? I cannot reproduce it with latest nightly on playground.
Although this isn't throwing an error on the playground, I get an assertion failure when adding a test: Let's leave this open until we have a test for it.

<ins> // revisions:rpass1 #![feature(const_generics)] pub struct Foo<T, const N: usize>([T; 0]); impl<T, const N: usize> Foo<T, {N}> { pub fn new() -> Self { Foo([]) } } fn main() { let _: Foo<u32, 0> = Foo::new(); } </ins>


Question:
The following code () leads to an ICE: Broken since 1.32.0 up to the current nightly, earlier versions are not affected. <details<summaryBacktrace of the nightly build</summary</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
modify labels to +T-compiler, +A-diagnostics, +A-parser, +I-ICE
claim
you will need to change the line to bubble the error up: Once you've done that code change create a new test file in .

F: Fn(&token::Token) -> bool { let attrs = self.parse_arg_attributes()?; <del> if let Ok(Some(mut arg)) = self.parse_self_arg() { </del> <ins> if let Some(mut arg) = self.parse_self_arg()? { </ins> arg.attrs = attrs.into(); return self.recover_bad_self_arg(arg, is_trait_item); }


Question:
The following code () leads to an ICE: Broken since 1.32.0 up to the current nightly, earlier versions are not affected. <details<summaryBacktrace of the nightly build</summary</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
modify labels to +T-compiler, +A-diagnostics, +A-parser, +I-ICE
claim
you will need to change the line to bubble the error up: Once you've done that code change create a new test file in .

<ins> // Regression test for issue #62660: if a receiver's type does not // successfully parse, emit the correct error instead of ICE-ing the compiler. struct Foo; impl Foo { pub fn foo(_: i32, self: Box<Self) {} //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)` } fn main() {} </ins>


Question:
The following code () leads to an ICE: Broken since 1.32.0 up to the current nightly, earlier versions are not affected. <details<summaryBacktrace of the nightly build</summary</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
modify labels to +T-compiler, +A-diagnostics, +A-parser, +I-ICE
claim
you will need to change the line to bubble the error up: Once you've done that code change create a new test file in .

<ins> error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)` --> $DIR/issue-62660.rs:7:38 | LL |     pub fn foo(_: i32, self: Box<Self) {} |                                      ^ expected one of 7 possible tokens here error: aborting due to previous error </ins>


Question:
Reproduction code: If I re-export in the module, it works as expected, having enum in the type-namespace and variant in the value-namespace ().
Compiler team check-in: I'm marking this as P-medium for now as it is not classified as a regression, although it seems like a fairly major problem. appears to be on it, though.
Feel free to add the I-nominated label if you think it should be P-high
late last year. could you take a look at this to see if it is valid for the invariant being checked not to hold in this case? If I comment out the the output is reasonable:
I'll see what happens (that's why I self-assigned). The assert is there to catch the cases that resolve logic assumes to be impossible. It may work ok if the assert is removed, but it may also mean some deeper issues, this needs a more detailed look.
The above error message without the looks a lot like and .
but it may also mean some deeper issues was exactly the case here! Thank you for reporting. Fixed in

/// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> { let orig_vis = import.vis.replace(ty::Visibility::Invisible); <ins> let orig_blacklisted_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => { Some(mem::replace(&mut self.r.blacklisted_binding, target_bindings[TypeNS].get())) } _ => None, }; </ins> let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( &import.module_path,


Question:
Reproduction code: If I re-export in the module, it works as expected, having enum in the type-namespace and variant in the value-namespace ().
Compiler team check-in: I'm marking this as P-medium for now as it is not classified as a regression, although it seems like a fairly major problem. appears to be on it, though.
Feel free to add the I-nominated label if you think it should be P-high
late last year. could you take a look at this to see if it is valid for the invariant being checked not to hold in this case? If I comment out the the output is reasonable:
I'll see what happens (that's why I self-assigned). The assert is there to catch the cases that resolve logic assumes to be impossible. It may work ok if the assert is removed, but it may also mean some deeper issues, this needs a more detailed look.
The above error message without the looks a lot like and .
but it may also mean some deeper issues was exactly the case here! Thank you for reporting. Fixed in

import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; <ins> if let Some(orig_blacklisted_binding) = orig_blacklisted_binding { self.r.blacklisted_binding = orig_blacklisted_binding; } </ins> import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics.


Question:
Reproduction code: If I re-export in the module, it works as expected, having enum in the type-namespace and variant in the value-namespace ().
Compiler team check-in: I'm marking this as P-medium for now as it is not classified as a regression, although it seems like a fairly major problem. appears to be on it, though.
Feel free to add the I-nominated label if you think it should be P-high
late last year. could you take a look at this to see if it is valid for the invariant being checked not to hold in this case? If I comment out the the output is reasonable:
I'll see what happens (that's why I self-assigned). The assert is there to catch the cases that resolve logic assumes to be impossible. It may work ok if the assert is removed, but it may also mean some deeper issues, this needs a more detailed look.
The above error message without the looks a lot like and .
but it may also mean some deeper issues was exactly the case here! Thank you for reporting. Fixed in

<ins> // check-pass mod m { pub enum Same { Same, } } use m::*; // The variant `Same` introduced by this import is not considered when resolving the prefix // `Same::` during import validation (issue #62767). use Same::Same; fn main() {} </ins>


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

let ret = f(self); let last_token = if self.token_cursor.stack.len() == prev { &mut self.token_cursor.frame.last_token <ins> } else if self.token_cursor.stack.get(prev).is_none() { // This can happen due to a bad interaction of two unrelated recovery mechanisms with // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(` // (#62881). return Ok((ret?, TokenStream::new(vec![]))); </ins> } else { &mut self.token_cursor.stack[prev].last_token };


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

// Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { LastToken::Collecting(ref mut v) => mem::take(v), <del> LastToken::Was(_) => panic!("our vector went away?"), </del> <ins> LastToken::Was(ref was) => { let msg = format!("our vector went away? - found Was({:?})", was); debug!("collect_tokens: {}", msg); self.sess.span_diagnostic.delay_span_bug(self.token.span, &msg); // This can happen due to a bad interaction of two unrelated recovery mechanisms // with mismatched delimiters *and* recovery lookahead on the likely typo // `pub ident(` (#62895, different but similar to the case above). return Ok((ret?, TokenStream::new(vec![]))); } </ins> }; // If we're not at EOF our current token wasn't actually consumed by


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

<ins> fn main() {} fn f() -> isize { fn f() -> isize {} pub f< //~^ ERROR missing `fn` or `struct` for function or struct definition //~| ERROR mismatched types //~ ERROR this file contains an un-closed delimiter </ins>


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

<ins> error: this file contains an un-closed delimiter --> $DIR/issue-62881.rs:6:53 | LL | fn f() -> isize { fn f() -> isize {} pub f< |                 - un-closed delimiter ... LL | |                                                     ^ error: missing `fn` or `struct` for function or struct definition --> $DIR/issue-62881.rs:3:41 | LL | fn f() -> isize { fn f() -> isize {} pub f< |                                         ^ error[E0308]: mismatched types --> $DIR/issue-62881.rs:3:29 | LL | fn f() -> isize { fn f() -> isize {} pub f< |                      -      ^^^^^ expected isize, found () |                      | |                      this function's body doesn't return | = note: expected type `isize` found type `()` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

<ins> fn main() {} fn v() -> isize { //~ ERROR mismatched types mod _ { //~ ERROR expected identifier pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope mod _ { //~ ERROR expected identifier pub    g() -> is //~ ERROR missing `fn` for function definition (), w20); } (), w20); //~ ERROR expected item, found `;` } </ins>


Question: I'm getting an internal compiler error on the following program (found by ): I'm seeing the error on stable, beta, and nightly. As with , the error occurs on () but not on (). , the proposed fix for , does not fix this error. cc

<ins> error: expected identifier, found reserved identifier `_` --> $DIR/issue-62895.rs:4:5 | LL | mod _ { |     ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` --> $DIR/issue-62895.rs:6:5 | LL | mod _ { |     ^ expected identifier, found reserved identifier error: missing `fn` for function definition --> $DIR/issue-62895.rs:7:4 | LL | pub    g() -> is |    ^^^^ help: add `fn` here to parse `g` as a public function | LL | pub fn g() -> is |     ^^ error: expected item, found `;` --> $DIR/issue-62895.rs:10:9 | LL | (), w20); |         ^ help: remove this semicolon error[E0412]: cannot find type `isizee` in this scope --> $DIR/issue-62895.rs:5:15 | LL | pub fn g() -> isizee { |               ^^^^^^ help: a builtin type with a similar name exists: `isize` error[E0308]: mismatched types --> $DIR/issue-62895.rs:3:11 | LL | fn v() -> isize { |    -      ^^^^^ expected isize, found () |    | |    this function's body doesn't return | = note: expected type `isize` found type `()` error: aborting due to 6 previous errors Some errors have detailed explanations: E0308, E0412. For more information about an error, try `rustc --explain E0308`. </ins>


Question:
This fails with: I believe this should compile because: non-async function with the same signature does compile; insignificant tweaks, like adding a wrapper struct, make it compile. Mentioning who fixed a similar error message in . Mentioning who touched this error message in and . rustc 1.38.0-nightly ( 2019-07-26) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Check-in from WG-async-await meeting: I agree this is a bug -- it doesn't necessarily block stabilization (no fwd compat risk) but would definitely be a good one to fix. Marking as blocking + unclear for the moment and will return to it.
I did a bit of investigation. The error results because we have an inference variable () that seems to have no constraints, but must be equal to one of the captured regions (e.g., ). I haven't 100% figured out where this variable comes from, I imagine it's related to though? In any case, the resolver basically winds up in a situation where it could pick any of the lifetimes but has no reason to prefer one over the other, and hence it reports an error.
OK, I think I see what's going on. It doesn't actually have much to do with the unused lifetime per se. What happens is this: The type of the generated result is something like -- i.e., it includes the types of the parameters, though with region variables in place of the known regions. Those types must be supertypes of the actual parameter types. We capture the argument of type -- per the subtyping rules, we create the type for the type of this captured value, with the requirement that -- as it happens, this is always true, so there is effectively no constraint on . We do impose the constraint that and must both be equal to one of the free regions -- in this case, or the anonymous lifetime of (which I'll call ). So thus the region solvers get in a state where must be equal to , , or -- but any one of them would be a reasonable choice. Removing the unused lifetime () makes this an easy choice -- it can pick , which is smaller than . (Per the "least choice" rules we usually use.) Removing the type and putting it into a struct () removes the lifetime variable altogether, as then we have , and there are no lifetime parameters involved. I'm not sure what I think is the best fix. It would be nice for the solver to pick , though it complicates the algorithm. You could certainly imagine a tweak that picks if the value is legal and otherwise looks for a least choice. That might indeed be superior to the current approach, though I'd want to think about the full implications -- in particular, when is used in places outside of the fn return type (e.g., in a statement), picking might lead to unnecessary borrow check errors. (The alternative would be to only look for when there is no least choice; that seems safer.) (Interestingly, at some point at least I thought that a polonius-like approach sidesteps a lot of the challenges here-- if we had confidence that we would transition that might ease some of my concerns.)
Now that I understand better what is happening, I don't feel this has to block stabilization -- in particular, I don't think that there is a forward compatibility risk from us improving the region inference algorithm. I don't think we would choose an algorithm that makes existing code illegal. =) As such, I'm going to mark this as Deferred.
Here's another example of the same problem that doesn't have an unused lifetime (AFAIKT): Removing any of the three arguments to the function allows it to compile.
I am also affected by this bug, where having both a reference and a box as parameters to a function causes the cryptic "hidden type for captures lifetime that does not appear in bounds" : () Is there a resolution in sight ?
is unused in that function - if you remove the it compiles.
Ok, let me change it to something closer to what I had in my original code: ()
I think I found another example of this: () This example more or less represents what I met in my code (when I tried to pass a structure with a type parameter to an async function with the default value for this type parameter being a trait object), but it can be simplified by removing the default parameter assignment and passing the argument to explicitly: () Curiously, if you replace with , the error goes away: () It is important to note that the function has two additional arguments. If you remove one or both of them, it starts compiling again: ()
's comment is a minimal reproduction of what I ran into. I had a function . If I remove two of the cache arguments it compiles. As soon as I add one back in it gives me the title error.
Hmm, it is probably worth revisiting this problem now that stabilization has happened.
Any word on this? I'm getting this error as well. Changing to fixes the issue. Only problem is that I actually want to move that vector in because I want to each call to .
No progress or major updates. The is still accurate as to the root cause, but I think we don't yet know the best fix.
this is going to become a problem now that is merged. It makes it impossible to implement for types with lifetimes, when the future that's returned is unnameable. consider
Here's another very simple example: Removing any of the 3 parameters makes the code compile. Alternatively, removing the static lifetime of (→ ) makes it compile as well.
Hi. I get the following error that matches what everyone is also getting:
I have the following case triggering this error message:
Got the error in the following: Removing helps. rustc 1.50.0-nightly ( 2020-12-09)
I know I am late to the game, but this issue still hunted us down with a Rust 1.48 compiler. The workaround is simple, but it pollutes all the callers with extra lifetime parameters. Basically, wherever saved us from introducing a lifetime parameter, we have to introduce it in s, s, everywhere. () If someone wants to workaround this issue without polluting the callers, they could use an async block inside a regular function: () Maybe if you treat special in the async function implementation, like in other parts of the language, that would cover most of the cases where this issue is hit.
Another short example based on reducing code from a discord question:
And 2 workarounds for the issue:
Found this after pulling my hair out for a few hours. At least I've got a workaround now, but I'd have to say this behavior is really unexpected. Of those two workarounds mentions only the first seems to be actually usable if you actually want to do something with those parameters: // Compiles async fn foo<'a(x: &'static str, y: &'a str, z: &'a str) { println!("{} {}", y, z); } // Doesn't compile: // error[E0759]: has an anonymous lifetime but it needs to satisfy a lifetime requirement fn bar(x: &'static str, y: &str, z: &str) -impl Future<Output=(){ async { println!("{} {}", y, z); } }
I'm going to remove the "async await triaged" label so that we take a second look at this. Maybe worth reprioritizing. I'll see if I can post some mentoring instructions.
Just hit this as well.
claim I'm claiming this to write some mentoring instructions
FWIW, in the meantime, and also to help solve the issue with manual capturing a potentially bigger invariant lifetime, I have published a helper proc-macro-attribute crate that automatically appends the necessary hacks:
Coming to this too, a little google drives me here. This thread is almost 2 years old, is there any solution or plan to fix this?
explicit lifetimes on references should fix the issue for you until compiler is smart enough to figure that out on its own
release-assignment I haven't had time to write up any mentoring instructions here, I'm afraid. :(
Big sad. I wish I was more into the compiler details. I love what async-await did to learnability for newbies and this issue hunts down them after getting their first successes.
I want to ensure that, is it because the readloop function might execute after the scope of self reference? If so, how can I explicitly set the lifetime of readloop is greater than the reference?
note that your code can be automatically fixed by the tool I mentioned in : ! A reliable fix that doesn't change the semantics of the function You can even query that attribute with the extra parameter fed to the attribute, and the eponymous Cargo feature, to get: <img width="681" alt="Screen Shot 2021-07-05 at 14 36 38" src="https://user-"For the specific case of usage, you can try changing the signature of the function to one using , that is, with the bound on the trait object explicitly spelled out: This leads to a simpler signature regarding / / TAIT unsugaring, and circumvents the issue of this thread. _ I'd like to experiment with unsugared's TAIT being automatically generic over all the lifetime parameters in scope of the return type. This is what achieves by using the hack for each and every such lifetime, and I've never encountered cases where this would be an error. If that approach seems fine to you, I can try to implement this new unsugaring on the compiler myself, although I may not be very fast since I'll need to experiment a bit to get acquainted with the related compiler internals
thanks, I will try that.
I just got bitten by this and I'm a beginner. 's workarround worked but a proper fix would be desirable.
are you saying you want to change how works for all cases? That would certainly be a breaking change, so I don't think we can do that. However, it would be good to talk about a better fix than the hack. One thing we talked about in the very beginning was having a syntax like to be very explicit about what things are captured and what are not. But that would, I think, require a lang-team proposal.
claim
When I thought about this I struggled to come up with an instance of this, so I'm genuinely curious about it. In other words: could annotating a function with / add lead to breakage somewhere along the way? If so, such an example could help us evaluate the different options at our disposal
OK, I've read up on this issue again. The basic diagnosis I had is correct. The fact that some of the lifetimes are unused isn't really especially relevant. For example, in the , the problem is simply that there are two lifetimes (from and ) along with the . This still gets us into the situation where the inferencer must pick between , , or . Let me run this through the compiler and take a look at the constraints. I also want to think about how polonius affects this.
I just read over . The reason that this "desugared" version works is because it introduces a new lifetime, , and this lifetime has a relationship to every other lifetime. So when we have to pick between , , and , we now also haev the choice of , which is strictly less than all of those choices. So we pick that. Now I realize that the reason that this whole situation is a non-issue in polonius is basically that the polonius representation permits lifetimes that are the intersection of a set of lifetimes. So you could infer the result to be , which is effectively the same as . But in the current implementation, we don't have anything like that.
I'm not sure if I understand exactly what you were proposing here, I thought at first that it meant: would be able to capture (because it would capture that lifetime). That would be a breaking change, but is that what you meant?
Fix in
, effectively defining it, for all intents and purposes, as the intersection lifetime! (which indeed meets the bounds) Ah yes, I see now how there are definitely two distinct issues at hand, here, and that my fix for one just happened to fix the other as a byproduct _ So, while your PR will fix the one, I'm personally still concerned about the case of the existential capturing both , and it's to tackle that one that I was suggesting that existentials were, internally, allowed to be generic over all the lifetime parameters in scope. That is, what I meant, or what I'm basically qualifying as a bug, is the fact that and don't have the same semantics, lifetime-wise (so, to clarify, I am definitely not talking about changing the rules for lifetime elision in function signatures): In the same fashion that stands for , and can thus not capture since it is -bound,then stands for and can thus not capture yadda yadda. And in the case, the is not needed, so it can be skipped if the implementation doesn't need it. But the key change I am suggesting is the definition of that existential. Currently, it would be defined as something like , and then unified. What I'm suggesting is that it be defined as , much like what adding a would achieve. This would be meaningful, for instance, in all the cases with a captured invariant lifetime which is not equal to the lower bound. Take , and . In that case, if instead of we had , the signature would work. But in the case, we have a , and such a type definition cannot be unified with the actual type of the implementor, , since there is no in scope of that definition. My observation is that I believe it cannot hurt to have too many lifetime parameters "in scope" / reachable for an existential's type definition. In that regard, the hack, be it manual or automated through the attribute, is just a way to test my theory: the attribute currently adds bounds for every lifetime it meets, without asking further questions, and that suffices to make the existential type definition be generic over all of them, and this whole thing has, empirically, solved the compilation problems without any problems on its own, thus allowing for and to remain quite interchangeable (lifetime-wise, barring obvious safety caveats).<sub<sup(Slight aside: I've noticed that this , so it's really just the lifetime parameters that it's being (overly) picky around, it seems)</sup</sub
Just hit this as well.
Encountered this today. Though the original error was this, which I couldn't reproduce it in playground. Removing any of the parameters the error is gone rustc 1.66.0-nightly ( 2022-10-01)

} debug!(?choice_regions, "after ub"); <del> // If we ruled everything out, we're done. if choice_regions.is_empty() { return false; } // Otherwise, we need to find the minimum remaining choice, if // any, and take that. debug!("choice_regions remaining are {:#?}", choice_regions); let Some(&min_choice) = choice_regions.iter().find(|&r1| { </del> <ins> // At this point we can pick any member of `choice_regions`, but to avoid potential // non-determinism we will pick the *unique minimum* choice. // // Because universal regions are only partially ordered (i.e, not every two regions are // comparable), we will ignore any region that doesn't compare to all others when picking // the minimum choice. // For example, consider `choice_regions = ['static, 'a, 'b, 'c, 'd, 'e]`, where // `'static: 'a, 'static: 'b, 'a: 'c, 'b: 'c, 'c: 'd, 'c: 'e`. // `['d, 'e]` are ignored because they do not compare - the same goes for `['a, 'b]`. let totally_ordered_subset = choice_regions.iter().copied().filter(|&r1| { </ins> choice_regions.iter().all(|&r2| { <del> self.universal_region_relations.outlives(r2, *r1) </del> <ins> self.universal_region_relations.outlives(r1, r2) || self.universal_region_relations.outlives(r2, r1) </ins> }) <ins> }); // Now we're left with `['static, 'c]`. Pick `'c` as the minimum! let Some(min_choice) = totally_ordered_subset.reduce(|r1, r2| { let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2); let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1); match (r1_outlives_r2, r2_outlives_r1) { (true, true) => r1.min(r2), (true, false) => r2, (false, true) => r1, (false, false) => bug!("incomparable regions in total order"), } </ins> }) else { <del> debug!("no choice region outlived by all others"); </del> <ins> debug!("no unique minimum choice"); </ins> return false; };


Question:
This fails with: I believe this should compile because: non-async function with the same signature does compile; insignificant tweaks, like adding a wrapper struct, make it compile. Mentioning who fixed a similar error message in . Mentioning who touched this error message in and . rustc 1.38.0-nightly ( 2019-07-26) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Check-in from WG-async-await meeting: I agree this is a bug -- it doesn't necessarily block stabilization (no fwd compat risk) but would definitely be a good one to fix. Marking as blocking + unclear for the moment and will return to it.
I did a bit of investigation. The error results because we have an inference variable () that seems to have no constraints, but must be equal to one of the captured regions (e.g., ). I haven't 100% figured out where this variable comes from, I imagine it's related to though? In any case, the resolver basically winds up in a situation where it could pick any of the lifetimes but has no reason to prefer one over the other, and hence it reports an error.
OK, I think I see what's going on. It doesn't actually have much to do with the unused lifetime per se. What happens is this: The type of the generated result is something like -- i.e., it includes the types of the parameters, though with region variables in place of the known regions. Those types must be supertypes of the actual parameter types. We capture the argument of type -- per the subtyping rules, we create the type for the type of this captured value, with the requirement that -- as it happens, this is always true, so there is effectively no constraint on . We do impose the constraint that and must both be equal to one of the free regions -- in this case, or the anonymous lifetime of (which I'll call ). So thus the region solvers get in a state where must be equal to , , or -- but any one of them would be a reasonable choice. Removing the unused lifetime () makes this an easy choice -- it can pick , which is smaller than . (Per the "least choice" rules we usually use.) Removing the type and putting it into a struct () removes the lifetime variable altogether, as then we have , and there are no lifetime parameters involved. I'm not sure what I think is the best fix. It would be nice for the solver to pick , though it complicates the algorithm. You could certainly imagine a tweak that picks if the value is legal and otherwise looks for a least choice. That might indeed be superior to the current approach, though I'd want to think about the full implications -- in particular, when is used in places outside of the fn return type (e.g., in a statement), picking might lead to unnecessary borrow check errors. (The alternative would be to only look for when there is no least choice; that seems safer.) (Interestingly, at some point at least I thought that a polonius-like approach sidesteps a lot of the challenges here-- if we had confidence that we would transition that might ease some of my concerns.)
Now that I understand better what is happening, I don't feel this has to block stabilization -- in particular, I don't think that there is a forward compatibility risk from us improving the region inference algorithm. I don't think we would choose an algorithm that makes existing code illegal. =) As such, I'm going to mark this as Deferred.
Here's another example of the same problem that doesn't have an unused lifetime (AFAIKT): Removing any of the three arguments to the function allows it to compile.
I am also affected by this bug, where having both a reference and a box as parameters to a function causes the cryptic "hidden type for captures lifetime that does not appear in bounds" : () Is there a resolution in sight ?
is unused in that function - if you remove the it compiles.
Ok, let me change it to something closer to what I had in my original code: ()
I think I found another example of this: () This example more or less represents what I met in my code (when I tried to pass a structure with a type parameter to an async function with the default value for this type parameter being a trait object), but it can be simplified by removing the default parameter assignment and passing the argument to explicitly: () Curiously, if you replace with , the error goes away: () It is important to note that the function has two additional arguments. If you remove one or both of them, it starts compiling again: ()
's comment is a minimal reproduction of what I ran into. I had a function . If I remove two of the cache arguments it compiles. As soon as I add one back in it gives me the title error.
Hmm, it is probably worth revisiting this problem now that stabilization has happened.
Any word on this? I'm getting this error as well. Changing to fixes the issue. Only problem is that I actually want to move that vector in because I want to each call to .
No progress or major updates. The is still accurate as to the root cause, but I think we don't yet know the best fix.
this is going to become a problem now that is merged. It makes it impossible to implement for types with lifetimes, when the future that's returned is unnameable. consider
Here's another very simple example: Removing any of the 3 parameters makes the code compile. Alternatively, removing the static lifetime of (→ ) makes it compile as well.
Hi. I get the following error that matches what everyone is also getting:
I have the following case triggering this error message:
Got the error in the following: Removing helps. rustc 1.50.0-nightly ( 2020-12-09)
I know I am late to the game, but this issue still hunted us down with a Rust 1.48 compiler. The workaround is simple, but it pollutes all the callers with extra lifetime parameters. Basically, wherever saved us from introducing a lifetime parameter, we have to introduce it in s, s, everywhere. () If someone wants to workaround this issue without polluting the callers, they could use an async block inside a regular function: () Maybe if you treat special in the async function implementation, like in other parts of the language, that would cover most of the cases where this issue is hit.
Another short example based on reducing code from a discord question:
And 2 workarounds for the issue:
Found this after pulling my hair out for a few hours. At least I've got a workaround now, but I'd have to say this behavior is really unexpected. Of those two workarounds mentions only the first seems to be actually usable if you actually want to do something with those parameters: // Compiles async fn foo<'a(x: &'static str, y: &'a str, z: &'a str) { println!("{} {}", y, z); } // Doesn't compile: // error[E0759]: has an anonymous lifetime but it needs to satisfy a lifetime requirement fn bar(x: &'static str, y: &str, z: &str) -impl Future<Output=(){ async { println!("{} {}", y, z); } }
I'm going to remove the "async await triaged" label so that we take a second look at this. Maybe worth reprioritizing. I'll see if I can post some mentoring instructions.
Just hit this as well.
claim I'm claiming this to write some mentoring instructions
FWIW, in the meantime, and also to help solve the issue with manual capturing a potentially bigger invariant lifetime, I have published a helper proc-macro-attribute crate that automatically appends the necessary hacks:
Coming to this too, a little google drives me here. This thread is almost 2 years old, is there any solution or plan to fix this?
explicit lifetimes on references should fix the issue for you until compiler is smart enough to figure that out on its own
release-assignment I haven't had time to write up any mentoring instructions here, I'm afraid. :(
Big sad. I wish I was more into the compiler details. I love what async-await did to learnability for newbies and this issue hunts down them after getting their first successes.
I want to ensure that, is it because the readloop function might execute after the scope of self reference? If so, how can I explicitly set the lifetime of readloop is greater than the reference?
note that your code can be automatically fixed by the tool I mentioned in : ! A reliable fix that doesn't change the semantics of the function You can even query that attribute with the extra parameter fed to the attribute, and the eponymous Cargo feature, to get: <img width="681" alt="Screen Shot 2021-07-05 at 14 36 38" src="https://user-"For the specific case of usage, you can try changing the signature of the function to one using , that is, with the bound on the trait object explicitly spelled out: This leads to a simpler signature regarding / / TAIT unsugaring, and circumvents the issue of this thread. _ I'd like to experiment with unsugared's TAIT being automatically generic over all the lifetime parameters in scope of the return type. This is what achieves by using the hack for each and every such lifetime, and I've never encountered cases where this would be an error. If that approach seems fine to you, I can try to implement this new unsugaring on the compiler myself, although I may not be very fast since I'll need to experiment a bit to get acquainted with the related compiler internals
thanks, I will try that.
I just got bitten by this and I'm a beginner. 's workarround worked but a proper fix would be desirable.
are you saying you want to change how works for all cases? That would certainly be a breaking change, so I don't think we can do that. However, it would be good to talk about a better fix than the hack. One thing we talked about in the very beginning was having a syntax like to be very explicit about what things are captured and what are not. But that would, I think, require a lang-team proposal.
claim
When I thought about this I struggled to come up with an instance of this, so I'm genuinely curious about it. In other words: could annotating a function with / add lead to breakage somewhere along the way? If so, such an example could help us evaluate the different options at our disposal
OK, I've read up on this issue again. The basic diagnosis I had is correct. The fact that some of the lifetimes are unused isn't really especially relevant. For example, in the , the problem is simply that there are two lifetimes (from and ) along with the . This still gets us into the situation where the inferencer must pick between , , or . Let me run this through the compiler and take a look at the constraints. I also want to think about how polonius affects this.
I just read over . The reason that this "desugared" version works is because it introduces a new lifetime, , and this lifetime has a relationship to every other lifetime. So when we have to pick between , , and , we now also haev the choice of , which is strictly less than all of those choices. So we pick that. Now I realize that the reason that this whole situation is a non-issue in polonius is basically that the polonius representation permits lifetimes that are the intersection of a set of lifetimes. So you could infer the result to be , which is effectively the same as . But in the current implementation, we don't have anything like that.
I'm not sure if I understand exactly what you were proposing here, I thought at first that it meant: would be able to capture (because it would capture that lifetime). That would be a breaking change, but is that what you meant?
Fix in
, effectively defining it, for all intents and purposes, as the intersection lifetime! (which indeed meets the bounds) Ah yes, I see now how there are definitely two distinct issues at hand, here, and that my fix for one just happened to fix the other as a byproduct _ So, while your PR will fix the one, I'm personally still concerned about the case of the existential capturing both , and it's to tackle that one that I was suggesting that existentials were, internally, allowed to be generic over all the lifetime parameters in scope. That is, what I meant, or what I'm basically qualifying as a bug, is the fact that and don't have the same semantics, lifetime-wise (so, to clarify, I am definitely not talking about changing the rules for lifetime elision in function signatures): In the same fashion that stands for , and can thus not capture since it is -bound,then stands for and can thus not capture yadda yadda. And in the case, the is not needed, so it can be skipped if the implementation doesn't need it. But the key change I am suggesting is the definition of that existential. Currently, it would be defined as something like , and then unified. What I'm suggesting is that it be defined as , much like what adding a would achieve. This would be meaningful, for instance, in all the cases with a captured invariant lifetime which is not equal to the lower bound. Take , and . In that case, if instead of we had , the signature would work. But in the case, we have a , and such a type definition cannot be unified with the actual type of the implementor, , since there is no in scope of that definition. My observation is that I believe it cannot hurt to have too many lifetime parameters "in scope" / reachable for an existential's type definition. In that regard, the hack, be it manual or automated through the attribute, is just a way to test my theory: the attribute currently adds bounds for every lifetime it meets, without asking further questions, and that suffices to make the existential type definition be generic over all of them, and this whole thing has, empirically, solved the compilation problems without any problems on its own, thus allowing for and to remain quite interchangeable (lifetime-wise, barring obvious safety caveats).<sub<sup(Slight aside: I've noticed that this , so it's really just the lifetime parameters that it's being (overly) picky around, it seems)</sup</sub
Just hit this as well.
Encountered this today. Though the original error was this, which I couldn't reproduce it in playground. Removing any of the parameters the error is gone rustc 1.66.0-nightly ( 2022-10-01)

<ins> // Regression test for #63033. // check-pass // edition: 2018 async fn test1(_: &'static u8, _: &'_ u8, _: &'_ u8) {} async fn test2<'s>(_: &'s u8, _: &'_ &'s u8, _: &'_ &'s u8) {} fn main() {} </ins>


Question:
This fails with: I believe this should compile because: non-async function with the same signature does compile; insignificant tweaks, like adding a wrapper struct, make it compile. Mentioning who fixed a similar error message in . Mentioning who touched this error message in and . rustc 1.38.0-nightly ( 2019-07-26) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Check-in from WG-async-await meeting: I agree this is a bug -- it doesn't necessarily block stabilization (no fwd compat risk) but would definitely be a good one to fix. Marking as blocking + unclear for the moment and will return to it.
I did a bit of investigation. The error results because we have an inference variable () that seems to have no constraints, but must be equal to one of the captured regions (e.g., ). I haven't 100% figured out where this variable comes from, I imagine it's related to though? In any case, the resolver basically winds up in a situation where it could pick any of the lifetimes but has no reason to prefer one over the other, and hence it reports an error.
OK, I think I see what's going on. It doesn't actually have much to do with the unused lifetime per se. What happens is this: The type of the generated result is something like -- i.e., it includes the types of the parameters, though with region variables in place of the known regions. Those types must be supertypes of the actual parameter types. We capture the argument of type -- per the subtyping rules, we create the type for the type of this captured value, with the requirement that -- as it happens, this is always true, so there is effectively no constraint on . We do impose the constraint that and must both be equal to one of the free regions -- in this case, or the anonymous lifetime of (which I'll call ). So thus the region solvers get in a state where must be equal to , , or -- but any one of them would be a reasonable choice. Removing the unused lifetime () makes this an easy choice -- it can pick , which is smaller than . (Per the "least choice" rules we usually use.) Removing the type and putting it into a struct () removes the lifetime variable altogether, as then we have , and there are no lifetime parameters involved. I'm not sure what I think is the best fix. It would be nice for the solver to pick , though it complicates the algorithm. You could certainly imagine a tweak that picks if the value is legal and otherwise looks for a least choice. That might indeed be superior to the current approach, though I'd want to think about the full implications -- in particular, when is used in places outside of the fn return type (e.g., in a statement), picking might lead to unnecessary borrow check errors. (The alternative would be to only look for when there is no least choice; that seems safer.) (Interestingly, at some point at least I thought that a polonius-like approach sidesteps a lot of the challenges here-- if we had confidence that we would transition that might ease some of my concerns.)
Now that I understand better what is happening, I don't feel this has to block stabilization -- in particular, I don't think that there is a forward compatibility risk from us improving the region inference algorithm. I don't think we would choose an algorithm that makes existing code illegal. =) As such, I'm going to mark this as Deferred.
Here's another example of the same problem that doesn't have an unused lifetime (AFAIKT): Removing any of the three arguments to the function allows it to compile.
I am also affected by this bug, where having both a reference and a box as parameters to a function causes the cryptic "hidden type for captures lifetime that does not appear in bounds" : () Is there a resolution in sight ?
is unused in that function - if you remove the it compiles.
Ok, let me change it to something closer to what I had in my original code: ()
I think I found another example of this: () This example more or less represents what I met in my code (when I tried to pass a structure with a type parameter to an async function with the default value for this type parameter being a trait object), but it can be simplified by removing the default parameter assignment and passing the argument to explicitly: () Curiously, if you replace with , the error goes away: () It is important to note that the function has two additional arguments. If you remove one or both of them, it starts compiling again: ()
's comment is a minimal reproduction of what I ran into. I had a function . If I remove two of the cache arguments it compiles. As soon as I add one back in it gives me the title error.
Hmm, it is probably worth revisiting this problem now that stabilization has happened.
Any word on this? I'm getting this error as well. Changing to fixes the issue. Only problem is that I actually want to move that vector in because I want to each call to .
No progress or major updates. The is still accurate as to the root cause, but I think we don't yet know the best fix.
this is going to become a problem now that is merged. It makes it impossible to implement for types with lifetimes, when the future that's returned is unnameable. consider
Here's another very simple example: Removing any of the 3 parameters makes the code compile. Alternatively, removing the static lifetime of (→ ) makes it compile as well.
Hi. I get the following error that matches what everyone is also getting:
I have the following case triggering this error message:
Got the error in the following: Removing helps. rustc 1.50.0-nightly ( 2020-12-09)
I know I am late to the game, but this issue still hunted us down with a Rust 1.48 compiler. The workaround is simple, but it pollutes all the callers with extra lifetime parameters. Basically, wherever saved us from introducing a lifetime parameter, we have to introduce it in s, s, everywhere. () If someone wants to workaround this issue without polluting the callers, they could use an async block inside a regular function: () Maybe if you treat special in the async function implementation, like in other parts of the language, that would cover most of the cases where this issue is hit.
Another short example based on reducing code from a discord question:
And 2 workarounds for the issue:
Found this after pulling my hair out for a few hours. At least I've got a workaround now, but I'd have to say this behavior is really unexpected. Of those two workarounds mentions only the first seems to be actually usable if you actually want to do something with those parameters: // Compiles async fn foo<'a(x: &'static str, y: &'a str, z: &'a str) { println!("{} {}", y, z); } // Doesn't compile: // error[E0759]: has an anonymous lifetime but it needs to satisfy a lifetime requirement fn bar(x: &'static str, y: &str, z: &str) -impl Future<Output=(){ async { println!("{} {}", y, z); } }
I'm going to remove the "async await triaged" label so that we take a second look at this. Maybe worth reprioritizing. I'll see if I can post some mentoring instructions.
Just hit this as well.
claim I'm claiming this to write some mentoring instructions
FWIW, in the meantime, and also to help solve the issue with manual capturing a potentially bigger invariant lifetime, I have published a helper proc-macro-attribute crate that automatically appends the necessary hacks:
Coming to this too, a little google drives me here. This thread is almost 2 years old, is there any solution or plan to fix this?
explicit lifetimes on references should fix the issue for you until compiler is smart enough to figure that out on its own
release-assignment I haven't had time to write up any mentoring instructions here, I'm afraid. :(
Big sad. I wish I was more into the compiler details. I love what async-await did to learnability for newbies and this issue hunts down them after getting their first successes.
I want to ensure that, is it because the readloop function might execute after the scope of self reference? If so, how can I explicitly set the lifetime of readloop is greater than the reference?
note that your code can be automatically fixed by the tool I mentioned in : ! A reliable fix that doesn't change the semantics of the function You can even query that attribute with the extra parameter fed to the attribute, and the eponymous Cargo feature, to get: <img width="681" alt="Screen Shot 2021-07-05 at 14 36 38" src="https://user-"For the specific case of usage, you can try changing the signature of the function to one using , that is, with the bound on the trait object explicitly spelled out: This leads to a simpler signature regarding / / TAIT unsugaring, and circumvents the issue of this thread. _ I'd like to experiment with unsugared's TAIT being automatically generic over all the lifetime parameters in scope of the return type. This is what achieves by using the hack for each and every such lifetime, and I've never encountered cases where this would be an error. If that approach seems fine to you, I can try to implement this new unsugaring on the compiler myself, although I may not be very fast since I'll need to experiment a bit to get acquainted with the related compiler internals
thanks, I will try that.
I just got bitten by this and I'm a beginner. 's workarround worked but a proper fix would be desirable.
are you saying you want to change how works for all cases? That would certainly be a breaking change, so I don't think we can do that. However, it would be good to talk about a better fix than the hack. One thing we talked about in the very beginning was having a syntax like to be very explicit about what things are captured and what are not. But that would, I think, require a lang-team proposal.
claim
When I thought about this I struggled to come up with an instance of this, so I'm genuinely curious about it. In other words: could annotating a function with / add lead to breakage somewhere along the way? If so, such an example could help us evaluate the different options at our disposal
OK, I've read up on this issue again. The basic diagnosis I had is correct. The fact that some of the lifetimes are unused isn't really especially relevant. For example, in the , the problem is simply that there are two lifetimes (from and ) along with the . This still gets us into the situation where the inferencer must pick between , , or . Let me run this through the compiler and take a look at the constraints. I also want to think about how polonius affects this.
I just read over . The reason that this "desugared" version works is because it introduces a new lifetime, , and this lifetime has a relationship to every other lifetime. So when we have to pick between , , and , we now also haev the choice of , which is strictly less than all of those choices. So we pick that. Now I realize that the reason that this whole situation is a non-issue in polonius is basically that the polonius representation permits lifetimes that are the intersection of a set of lifetimes. So you could infer the result to be , which is effectively the same as . But in the current implementation, we don't have anything like that.
I'm not sure if I understand exactly what you were proposing here, I thought at first that it meant: would be able to capture (because it would capture that lifetime). That would be a breaking change, but is that what you meant?
Fix in
, effectively defining it, for all intents and purposes, as the intersection lifetime! (which indeed meets the bounds) Ah yes, I see now how there are definitely two distinct issues at hand, here, and that my fix for one just happened to fix the other as a byproduct _ So, while your PR will fix the one, I'm personally still concerned about the case of the existential capturing both , and it's to tackle that one that I was suggesting that existentials were, internally, allowed to be generic over all the lifetime parameters in scope. That is, what I meant, or what I'm basically qualifying as a bug, is the fact that and don't have the same semantics, lifetime-wise (so, to clarify, I am definitely not talking about changing the rules for lifetime elision in function signatures): In the same fashion that stands for , and can thus not capture since it is -bound,then stands for and can thus not capture yadda yadda. And in the case, the is not needed, so it can be skipped if the implementation doesn't need it. But the key change I am suggesting is the definition of that existential. Currently, it would be defined as something like , and then unified. What I'm suggesting is that it be defined as , much like what adding a would achieve. This would be meaningful, for instance, in all the cases with a captured invariant lifetime which is not equal to the lower bound. Take , and . In that case, if instead of we had , the signature would work. But in the case, we have a , and such a type definition cannot be unified with the actual type of the implementor, , since there is no in scope of that definition. My observation is that I believe it cannot hurt to have too many lifetime parameters "in scope" / reachable for an existential's type definition. In that regard, the hack, be it manual or automated through the attribute, is just a way to test my theory: the attribute currently adds bounds for every lifetime it meets, without asking further questions, and that suffices to make the existential type definition be generic over all of them, and this whole thing has, empirically, solved the compilation problems without any problems on its own, thus allowing for and to remain quite interchangeable (lifetime-wise, barring obvious safety caveats).<sub<sup(Slight aside: I've noticed that this , so it's really just the lifetime parameters that it's being (overly) picky around, it seems)</sup</sub
Just hit this as well.
Encountered this today. Though the original error was this, which I couldn't reproduce it in playground. Removing any of the parameters the error is gone rustc 1.66.0-nightly ( 2022-10-01)

<ins> // ... continued from ./min-choice.rs // check-fail trait Cap<'a> {} impl<T> Cap<'_> for T {} fn type_test<'a, T: 'a>() -> &'a u8 { &0 } // Make sure we don't pick `'b`. fn test_b<'a, 'b, 'c, T>() -> impl Cap<'a> + Cap<'b> + Cap<'c> where 'a: 'b, 'a: 'c, T: 'b, { type_test::<'_, T>() // This should pass if we pick 'b. //~^ ERROR the parameter type `T` may not live long enough } // Make sure we don't pick `'c`. fn test_c<'a, 'b, 'c, T>() -> impl Cap<'a> + Cap<'b> + Cap<'c> where 'a: 'b, 'a: 'c, T: 'c, { type_test::<'_, T>() // This should pass if we pick 'c. //~^ ERROR the parameter type `T` may not live long enough } // We need to pick min_choice from `['b, 'c]`, but it's ambiguous which one to pick because // they're incomparable. fn test_ambiguous<'a, 'b, 'c>(s: &'a u8) -> impl Cap<'b> + Cap<'c> where 'a: 'b, 'a: 'c, { s //~^ ERROR captures lifetime that does not appear in bounds } fn main() {} </ins>


Question:
This fails with: I believe this should compile because: non-async function with the same signature does compile; insignificant tweaks, like adding a wrapper struct, make it compile. Mentioning who fixed a similar error message in . Mentioning who touched this error message in and . rustc 1.38.0-nightly ( 2019-07-26) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Check-in from WG-async-await meeting: I agree this is a bug -- it doesn't necessarily block stabilization (no fwd compat risk) but would definitely be a good one to fix. Marking as blocking + unclear for the moment and will return to it.
I did a bit of investigation. The error results because we have an inference variable () that seems to have no constraints, but must be equal to one of the captured regions (e.g., ). I haven't 100% figured out where this variable comes from, I imagine it's related to though? In any case, the resolver basically winds up in a situation where it could pick any of the lifetimes but has no reason to prefer one over the other, and hence it reports an error.
OK, I think I see what's going on. It doesn't actually have much to do with the unused lifetime per se. What happens is this: The type of the generated result is something like -- i.e., it includes the types of the parameters, though with region variables in place of the known regions. Those types must be supertypes of the actual parameter types. We capture the argument of type -- per the subtyping rules, we create the type for the type of this captured value, with the requirement that -- as it happens, this is always true, so there is effectively no constraint on . We do impose the constraint that and must both be equal to one of the free regions -- in this case, or the anonymous lifetime of (which I'll call ). So thus the region solvers get in a state where must be equal to , , or -- but any one of them would be a reasonable choice. Removing the unused lifetime () makes this an easy choice -- it can pick , which is smaller than . (Per the "least choice" rules we usually use.) Removing the type and putting it into a struct () removes the lifetime variable altogether, as then we have , and there are no lifetime parameters involved. I'm not sure what I think is the best fix. It would be nice for the solver to pick , though it complicates the algorithm. You could certainly imagine a tweak that picks if the value is legal and otherwise looks for a least choice. That might indeed be superior to the current approach, though I'd want to think about the full implications -- in particular, when is used in places outside of the fn return type (e.g., in a statement), picking might lead to unnecessary borrow check errors. (The alternative would be to only look for when there is no least choice; that seems safer.) (Interestingly, at some point at least I thought that a polonius-like approach sidesteps a lot of the challenges here-- if we had confidence that we would transition that might ease some of my concerns.)
Now that I understand better what is happening, I don't feel this has to block stabilization -- in particular, I don't think that there is a forward compatibility risk from us improving the region inference algorithm. I don't think we would choose an algorithm that makes existing code illegal. =) As such, I'm going to mark this as Deferred.
Here's another example of the same problem that doesn't have an unused lifetime (AFAIKT): Removing any of the three arguments to the function allows it to compile.
I am also affected by this bug, where having both a reference and a box as parameters to a function causes the cryptic "hidden type for captures lifetime that does not appear in bounds" : () Is there a resolution in sight ?
is unused in that function - if you remove the it compiles.
Ok, let me change it to something closer to what I had in my original code: ()
I think I found another example of this: () This example more or less represents what I met in my code (when I tried to pass a structure with a type parameter to an async function with the default value for this type parameter being a trait object), but it can be simplified by removing the default parameter assignment and passing the argument to explicitly: () Curiously, if you replace with , the error goes away: () It is important to note that the function has two additional arguments. If you remove one or both of them, it starts compiling again: ()
's comment is a minimal reproduction of what I ran into. I had a function . If I remove two of the cache arguments it compiles. As soon as I add one back in it gives me the title error.
Hmm, it is probably worth revisiting this problem now that stabilization has happened.
Any word on this? I'm getting this error as well. Changing to fixes the issue. Only problem is that I actually want to move that vector in because I want to each call to .
No progress or major updates. The is still accurate as to the root cause, but I think we don't yet know the best fix.
this is going to become a problem now that is merged. It makes it impossible to implement for types with lifetimes, when the future that's returned is unnameable. consider
Here's another very simple example: Removing any of the 3 parameters makes the code compile. Alternatively, removing the static lifetime of (→ ) makes it compile as well.
Hi. I get the following error that matches what everyone is also getting:
I have the following case triggering this error message:
Got the error in the following: Removing helps. rustc 1.50.0-nightly ( 2020-12-09)
I know I am late to the game, but this issue still hunted us down with a Rust 1.48 compiler. The workaround is simple, but it pollutes all the callers with extra lifetime parameters. Basically, wherever saved us from introducing a lifetime parameter, we have to introduce it in s, s, everywhere. () If someone wants to workaround this issue without polluting the callers, they could use an async block inside a regular function: () Maybe if you treat special in the async function implementation, like in other parts of the language, that would cover most of the cases where this issue is hit.
Another short example based on reducing code from a discord question:
And 2 workarounds for the issue:
Found this after pulling my hair out for a few hours. At least I've got a workaround now, but I'd have to say this behavior is really unexpected. Of those two workarounds mentions only the first seems to be actually usable if you actually want to do something with those parameters: // Compiles async fn foo<'a(x: &'static str, y: &'a str, z: &'a str) { println!("{} {}", y, z); } // Doesn't compile: // error[E0759]: has an anonymous lifetime but it needs to satisfy a lifetime requirement fn bar(x: &'static str, y: &str, z: &str) -impl Future<Output=(){ async { println!("{} {}", y, z); } }
I'm going to remove the "async await triaged" label so that we take a second look at this. Maybe worth reprioritizing. I'll see if I can post some mentoring instructions.
Just hit this as well.
claim I'm claiming this to write some mentoring instructions
FWIW, in the meantime, and also to help solve the issue with manual capturing a potentially bigger invariant lifetime, I have published a helper proc-macro-attribute crate that automatically appends the necessary hacks:
Coming to this too, a little google drives me here. This thread is almost 2 years old, is there any solution or plan to fix this?
explicit lifetimes on references should fix the issue for you until compiler is smart enough to figure that out on its own
release-assignment I haven't had time to write up any mentoring instructions here, I'm afraid. :(
Big sad. I wish I was more into the compiler details. I love what async-await did to learnability for newbies and this issue hunts down them after getting their first successes.
I want to ensure that, is it because the readloop function might execute after the scope of self reference? If so, how can I explicitly set the lifetime of readloop is greater than the reference?
note that your code can be automatically fixed by the tool I mentioned in : ! A reliable fix that doesn't change the semantics of the function You can even query that attribute with the extra parameter fed to the attribute, and the eponymous Cargo feature, to get: <img width="681" alt="Screen Shot 2021-07-05 at 14 36 38" src="https://user-"For the specific case of usage, you can try changing the signature of the function to one using , that is, with the bound on the trait object explicitly spelled out: This leads to a simpler signature regarding / / TAIT unsugaring, and circumvents the issue of this thread. _ I'd like to experiment with unsugared's TAIT being automatically generic over all the lifetime parameters in scope of the return type. This is what achieves by using the hack for each and every such lifetime, and I've never encountered cases where this would be an error. If that approach seems fine to you, I can try to implement this new unsugaring on the compiler myself, although I may not be very fast since I'll need to experiment a bit to get acquainted with the related compiler internals
thanks, I will try that.
I just got bitten by this and I'm a beginner. 's workarround worked but a proper fix would be desirable.
are you saying you want to change how works for all cases? That would certainly be a breaking change, so I don't think we can do that. However, it would be good to talk about a better fix than the hack. One thing we talked about in the very beginning was having a syntax like to be very explicit about what things are captured and what are not. But that would, I think, require a lang-team proposal.
claim
When I thought about this I struggled to come up with an instance of this, so I'm genuinely curious about it. In other words: could annotating a function with / add lead to breakage somewhere along the way? If so, such an example could help us evaluate the different options at our disposal
OK, I've read up on this issue again. The basic diagnosis I had is correct. The fact that some of the lifetimes are unused isn't really especially relevant. For example, in the , the problem is simply that there are two lifetimes (from and ) along with the . This still gets us into the situation where the inferencer must pick between , , or . Let me run this through the compiler and take a look at the constraints. I also want to think about how polonius affects this.
I just read over . The reason that this "desugared" version works is because it introduces a new lifetime, , and this lifetime has a relationship to every other lifetime. So when we have to pick between , , and , we now also haev the choice of , which is strictly less than all of those choices. So we pick that. Now I realize that the reason that this whole situation is a non-issue in polonius is basically that the polonius representation permits lifetimes that are the intersection of a set of lifetimes. So you could infer the result to be , which is effectively the same as . But in the current implementation, we don't have anything like that.
I'm not sure if I understand exactly what you were proposing here, I thought at first that it meant: would be able to capture (because it would capture that lifetime). That would be a breaking change, but is that what you meant?
Fix in
, effectively defining it, for all intents and purposes, as the intersection lifetime! (which indeed meets the bounds) Ah yes, I see now how there are definitely two distinct issues at hand, here, and that my fix for one just happened to fix the other as a byproduct _ So, while your PR will fix the one, I'm personally still concerned about the case of the existential capturing both , and it's to tackle that one that I was suggesting that existentials were, internally, allowed to be generic over all the lifetime parameters in scope. That is, what I meant, or what I'm basically qualifying as a bug, is the fact that and don't have the same semantics, lifetime-wise (so, to clarify, I am definitely not talking about changing the rules for lifetime elision in function signatures): In the same fashion that stands for , and can thus not capture since it is -bound,then stands for and can thus not capture yadda yadda. And in the case, the is not needed, so it can be skipped if the implementation doesn't need it. But the key change I am suggesting is the definition of that existential. Currently, it would be defined as something like , and then unified. What I'm suggesting is that it be defined as , much like what adding a would achieve. This would be meaningful, for instance, in all the cases with a captured invariant lifetime which is not equal to the lower bound. Take , and . In that case, if instead of we had , the signature would work. But in the case, we have a , and such a type definition cannot be unified with the actual type of the implementor, , since there is no in scope of that definition. My observation is that I believe it cannot hurt to have too many lifetime parameters "in scope" / reachable for an existential's type definition. In that regard, the hack, be it manual or automated through the attribute, is just a way to test my theory: the attribute currently adds bounds for every lifetime it meets, without asking further questions, and that suffices to make the existential type definition be generic over all of them, and this whole thing has, empirically, solved the compilation problems without any problems on its own, thus allowing for and to remain quite interchangeable (lifetime-wise, barring obvious safety caveats).<sub<sup(Slight aside: I've noticed that this , so it's really just the lifetime parameters that it's being (overly) picky around, it seems)</sup</sub
Just hit this as well.
Encountered this today. Though the original error was this, which I couldn't reproduce it in playground. Removing any of the parameters the error is gone rustc 1.66.0-nightly ( 2022-10-01)

<ins> error[E0309]: the parameter type `T` may not live long enough --> $DIR/min-choice-reject-ambiguous.rs:17:5 | LL |     type_test::<'_, T>() // This should pass if we pick 'b. |     ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | LL |     T: 'b + 'a, |           ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/min-choice-reject-ambiguous.rs:28:5 | LL |     type_test::<'_, T>() // This should pass if we pick 'c. |     ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | LL |     T: 'c + 'a, |           ++++ error[E0700]: hidden type for `impl Cap<'b> + Cap<'c>` captures lifetime that does not appear in bounds --> $DIR/min-choice-reject-ambiguous.rs:39:5 | LL | fn test_ambiguous<'a, 'b, 'c>(s: &'a u8) -> impl Cap<'b> + Cap<'c> |                   -- hidden type `&'a u8` captures the lifetime `'a` as defined here ... LL |     s |     ^ | help: to declare that `impl Cap<'b> + Cap<'c>` captures `'a`, you can add an explicit `'a` lifetime bound | LL | fn test_ambiguous<'a, 'b, 'c>(s: &'a u8) -> impl Cap<'b> + Cap<'c> + 'a |                                                                    ++++ error: aborting due to 3 previous errors Some errors have detailed explanations: E0309, E0700. For more information about an error, try `rustc --explain E0309`. </ins>