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> // Assuming that the hidden type in these tests is `&'_#15r u8`, // we have a member constraint: `'_#15r member ['static, 'a, 'b, 'c]`. // // Make sure we pick up the minimum non-ambiguous region among them. // We will have to exclude `['b, 'c]` because they're incomparable, // and then we should pick `'a` because we know `'static: 'a`. // check-pass trait Cap<'a> {} impl<T> Cap<'_> for T {} fn type_test<'a, T: 'a>() -> &'a u8 { &0 } // Basic test: make sure we don't bail out because 'b and 'c are incomparable. fn basic<'a, 'b, 'c>() -> impl Cap<'a> + Cap<'b> + Cap<'c> where 'a: 'b, 'a: 'c, { &0 } // Make sure we don't pick `'static`. fn test_static<'a, 'b, 'c, T>() -> impl Cap<'a> + Cap<'b> + Cap<'c> where 'a: 'b, 'a: 'c, T: 'a, { type_test::<'_, T>() // This will fail if we pick 'static } 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> // Nested impl-traits can impose different member constraints on the same region variable. // check-fail trait Cap<'a> {} impl<T> Cap<'_> for T {} // Assuming the hidden type is `[&'_#15r u8; 1]`, we have two distinct member constraints: // - '_#15r member ['static, 'a, 'b] // from outer impl-trait // - '_#15r member ['static, 'a, 'b] // from inner impl-trait // To satisfy both we can choose 'a or 'b, so it's a failure due to ambiguity. fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> where 's: 'a, 's: 'b, { [a] //~^ E0700 //~| E0700 } // Same as the above but with late-bound regions. fn fail_late_bound<'s, 'a, 'b>( a: &'s u8, _: &'a &'s u8, _: &'b &'s u8, ) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> { [a] //~^ E0700 //~| E0700 } 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[E0700]: hidden type for `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures lifetime that does not appear in bounds --> $DIR/nested-impl-trait-fail.rs:17:5 | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> |                     -- hidden type `[&'s u8; 1]` captures the lifetime `'s` as defined here ... LL |     [a] |     ^^^ | help: to declare that `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> + 's |                                                                                ++++ help: to declare that `impl Cap<'a> + Cap<'b>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b> + 's> |                                                                                ++++ error[E0700]: hidden type for `impl Cap<'a> + Cap<'b>` captures lifetime that does not appear in bounds --> $DIR/nested-impl-trait-fail.rs:17:5 | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> |                     -- hidden type `&'s u8` captures the lifetime `'s` as defined here ... LL |     [a] |     ^^^ | help: to declare that `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> + 's |                                                                                ++++ help: to declare that `impl Cap<'a> + Cap<'b>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b> + 's> |                                                                                ++++ error[E0700]: hidden type for `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures lifetime that does not appear in bounds --> $DIR/nested-impl-trait-fail.rs:28:5 | LL | fn fail_late_bound<'s, 'a, 'b>( |                    -- hidden type `[&'s u8; 1]` captures the lifetime `'s` as defined here ... LL |     [a] |     ^^^ | help: to declare that `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | ) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> + 's { |                                                       ++++ help: to declare that `impl Cap<'a> + Cap<'b>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | ) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b> + 's> { |                                                      ++++ error[E0700]: hidden type for `impl Cap<'a> + Cap<'b>` captures lifetime that does not appear in bounds --> $DIR/nested-impl-trait-fail.rs:28:5 | LL | fn fail_late_bound<'s, 'a, 'b>( |                    -- hidden type `&'s u8` captures the lifetime `'s` as defined here ... LL |     [a] |     ^^^ | help: to declare that `impl IntoIterator<Item = impl Cap<'a> + Cap<'b>>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | ) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> + 's { |                                                       ++++ help: to declare that `impl Cap<'a> + Cap<'b>` captures `'s`, you can add an explicit `'s` lifetime bound | LL | ) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b> + 's> { |                                                      ++++ error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0700`. </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> // Nested impl-traits can impose different member constraints on the same region variable. // check-pass trait Cap<'a> {} impl<T> Cap<'_> for T {} // Assuming the hidden type is `[&'_#15r u8; 1]`, we have two distinct member constraints: // - '_#15r member ['static, 'a, 'b] // from outer impl-trait // - '_#15r member ['static, 'a]     // from inner impl-trait // To satisfy both we can only choose 'a. fn pass_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a>> + Cap<'b> where 's: 'a, 's: 'b, { [a] } // Same as the above but with late-bound regions. fn pass_late_bound<'s, 'a, 'b>( a: &'s u8, _: &'a &'s u8, _: &'b &'s u8, ) -> impl IntoIterator<Item = impl Cap<'a>> + Cap<'b> { [a] } fn main() {} </ins>


Question:
It took a colleague explaining to me that the return type of a function returning an impl Trait is unique across function definitions for me to understand the following error: This becomes more important for async/await because of the automatic translation of to : In the first case, can the error maybe call out that the opaque types are different due to how the compiler treats them? And for the second error, can this be called out in async-specific language. That error happens when you forget to call .
How about?: In the second case I think we should suggest that the s be moved into the branches tho this may be complicated to encode as a diagnostic. cc
Agreed, this is definitely a bit trickier. I'll defer to you on the best way to message this error.
In the first case, can the error maybe call out that the opaque types are different due to how the compiler treats them? Doesn't it already does so?
what is the correct nomenclature for a regular, non-opaque type that we could use here? With that we could say something like "consider materializing to an explicit type in both branches from the opaque type" and "for you can them on both branches to unify the types". This is rough wording, but gives an idea of what I'm thinking.
The antonym of opaque is transparent but I'm not sure that is situationally good to use here. ISTM you'd want to say something like "use an enum with variants for both cases" (at least that's the advice I'd give in person). I'd go for a non-actionable description as a first pass at this problem and consider an improvement later.
Are opaque types the same as anonymous types in C#/Java? If so I think 'anonymous' is clearer than opaque (pardon the pun!).
This is a real gotcha of rust and needs a great error message. We could show the definition sites of the opaque types so it's clear which type is expected in this position: Something like:
It doesn't matter where the resides in. Two uses will result in two distinct types from the POV of the type system. Only by naming an through a type alias can you refer to the same inferred type. Adding the qualification "in function signatures" does not enlighten. As for "anonymous", the closest equivalent Java's anonymous classes, which conjure new types, in Rust are closures. Also, with Java's anonymous classes you can recover the type identity at runtime using but you cannot name them. However, in Rust can be named (using a alias), they do not representationally create new types (although they do nominally), and they do not leak their type identities. Rather, is about hiding the underlying type (think of as a coercion that hides the type). The is most similar to Stanard ML's opaque matching (see section G.2 in the ) All in all, opacity is therefore the most appropriate description rather than anonymity.
I'll get used to :-) You're refering here to ? Most of the time when someone gets this error they're assuming they can do this but don't realise they need to make the two impl Traits be the same type. We could hint that there's an unstabilised feature that could help? But if they weren't trying to bind both impl Traits to be the same type, then given both types textually look the same it would be great if the error message could point out the difference between those two types. Currently the error says: As a nubie I need to see something different between the two types that I can get my teeth into. How about: Somehow it would be great to distinguish these two opaque types (or does the compiler at this point has no knowledge of where these two opaque types came from - only that they are not the same?).
Fwiw, we desire to keep jargon to minimum.
was removed from the language in in favor of just . We could hint towards that on nightly. Seems like a nice improvement.
Thanks Centril - hadn't seen that switch. If people are ok with adding line numbers to pinpoint the different impl Traits I'll have a go at rolling a PR?
With all the various improvements that we've done, is there more we could do? or shall we close this issue for now?

if let Some((expected, found)) = expected_found { match (terr, is_simple_error, expected == found) { (&TypeError::Sorts(ref values), false, true) => { <ins> let sort_string = | a_type: Ty<'tcx> | if let ty::Opaque(def_id, _) = a_type.sty { format!(" (opaque type at {})", self.tcx.sess.source_map() .mk_substr_filename(self.tcx.def_span(def_id))) } else { format!(" ({})", a_type.sort_string(self.tcx)) }; </ins> diag.note_expected_found_extra( &"type", expected, found, <del> &format!(" ({})", values.expected.sort_string(self.tcx)), &format!(" ({})", values.found.sort_string(self.tcx)), </del> <ins> &sort_string(values.expected), &sort_string(values.found), </ins> ); } (_, false, _) => {


Question:
It took a colleague explaining to me that the return type of a function returning an impl Trait is unique across function definitions for me to understand the following error: This becomes more important for async/await because of the automatic translation of to : In the first case, can the error maybe call out that the opaque types are different due to how the compiler treats them? And for the second error, can this be called out in async-specific language. That error happens when you forget to call .
How about?: In the second case I think we should suggest that the s be moved into the branches tho this may be complicated to encode as a diagnostic. cc
Agreed, this is definitely a bit trickier. I'll defer to you on the best way to message this error.
In the first case, can the error maybe call out that the opaque types are different due to how the compiler treats them? Doesn't it already does so?
what is the correct nomenclature for a regular, non-opaque type that we could use here? With that we could say something like "consider materializing to an explicit type in both branches from the opaque type" and "for you can them on both branches to unify the types". This is rough wording, but gives an idea of what I'm thinking.
The antonym of opaque is transparent but I'm not sure that is situationally good to use here. ISTM you'd want to say something like "use an enum with variants for both cases" (at least that's the advice I'd give in person). I'd go for a non-actionable description as a first pass at this problem and consider an improvement later.
Are opaque types the same as anonymous types in C#/Java? If so I think 'anonymous' is clearer than opaque (pardon the pun!).
This is a real gotcha of rust and needs a great error message. We could show the definition sites of the opaque types so it's clear which type is expected in this position: Something like:
It doesn't matter where the resides in. Two uses will result in two distinct types from the POV of the type system. Only by naming an through a type alias can you refer to the same inferred type. Adding the qualification "in function signatures" does not enlighten. As for "anonymous", the closest equivalent Java's anonymous classes, which conjure new types, in Rust are closures. Also, with Java's anonymous classes you can recover the type identity at runtime using but you cannot name them. However, in Rust can be named (using a alias), they do not representationally create new types (although they do nominally), and they do not leak their type identities. Rather, is about hiding the underlying type (think of as a coercion that hides the type). The is most similar to Stanard ML's opaque matching (see section G.2 in the ) All in all, opacity is therefore the most appropriate description rather than anonymity.
I'll get used to :-) You're refering here to ? Most of the time when someone gets this error they're assuming they can do this but don't realise they need to make the two impl Traits be the same type. We could hint that there's an unstabilised feature that could help? But if they weren't trying to bind both impl Traits to be the same type, then given both types textually look the same it would be great if the error message could point out the difference between those two types. Currently the error says: As a nubie I need to see something different between the two types that I can get my teeth into. How about: Somehow it would be great to distinguish these two opaque types (or does the compiler at this point has no knowledge of where these two opaque types came from - only that they are not the same?).
Fwiw, we desire to keep jargon to minimum.
was removed from the language in in favor of just . We could hint towards that on nightly. Seems like a nice improvement.
Thanks Centril - hadn't seen that switch. If people are ok with adding line numbers to pinpoint the different impl Traits I'll have a go at rolling a PR?
With all the various improvements that we've done, is there more we could do? or shall we close this issue for now?

LL | |     }.await | |_____- if and else have incompatible types | <del> = note: expected type `impl std::future::Future` (opaque type) found type `impl std::future::Future` (opaque type) </del> <ins> = note: expected type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:8:19>) found type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:12:19>) </ins> = note: distinct uses of `impl Trait` result in different opaque types = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them


Question:
As seen in , when running the tests on Windows there are slightly different things in scope than when the tests are run normally. per
see also
Part of .
Closing, removed check-fast

<ins> // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // check that the derived impls for the comparison traits shortcircuit // where possible, by having a type that fails when compared as the // second element, so this passes iff the instances shortcircuit. pub struct FailCmp; impl Eq for FailCmp { fn eq(&self, _: &FailCmp) -> bool { fail!("eq") } } impl Ord for FailCmp { fn lt(&self, _: &FailCmp) -> bool { fail!("lt") } } impl TotalEq for FailCmp { fn equals(&self, _: &FailCmp) -> bool { fail!("equals") } } impl TotalOrd for FailCmp { fn cmp(&self, _: &FailCmp) -> Ordering { fail!("cmp") } } #[deriving(Eq,Ord,TotalEq,TotalOrd)] struct ShortCircuit { x: int, y: FailCmp } fn main() { let a = ShortCircuit { x: 1, y: FailCmp }; let b = ShortCircuit { x: 2, y: FailCmp }; assert!(a != b); assert!(a < b); assert!(!a.equals(&b)); assert_eq!(a.cmp(&b), ::std::cmp::Less); } </ins>


Question:
Any crate that uses fails to compile with a link error saying Test case on outputs: or from a bigger project: Nightly / works totally fine.
Is this reproducible after ?
Yes, happens on a fresh project I made for testing () and after
is the full commit range, which notably includes an LLVM upgrade -- cc Could you check with if is fine and is broken for you?
I can confirm that works fine but is broken. Also, that's a nifty tool.
Okay, LLVM update is then definitely at fault, cc
With default settings I'm not reproducing this locally with on . Do you have any rustflags set in your cargo config or environment variable? What is the full output of ?
Here is the full failing output from <details</detailsIndeed, my are set to Testing again without does not error, and compiles/runs fine.
If it helps, I'm on AMD Zen v1, or , and it looks like was introduced in the LLVM upgrade.
Fails the same way on Linux (GNU and musl) and Windows GNU using on Ryzen 2700X platform so it probably affects all the OSes. <details<summaryDetails</summary</details modify labels: -E-needs-bisection -O-windows-msvc +O-linux +O-windows +A-LLVM
This seems like LLVM's auto-detection of what CPU is on the host or what the target features your native CPU has may be broken. The next step for this is to probably use a build of Clang to reproduce and then report this upstream to LLVM itself.
Er sorry I have a guess as to where this is but I do not have time to investigate this right now, so I'm going to unassign myself since I can't take care of this.
Minimised: IR: I cannot build Clang/LLVM from master right now so I'm attaching IR from my code above. I'll try to find time tomorrow or somewhere next week.
Confirming that produces a call instead of a under .
I believe the cause is that the znver feature spec is missing (the 16B variant is listed).
LLVM bug reported at

<del> Subproject commit f2b0c67661f19bb2564225d47aca424ad0449791 </del> <ins> Subproject commit 48818e9f5d0f2d5978a9b43ad1a2e8d0b83f6aa0 </ins>


Question:
The idea behind was that it should only show a backtrace (of where a Miri error originates) when an error is actually shown to the user. And that worked fine when I implemented it. But since then, something changed in constprop, and now I get thousands of backtraces even for crates with no errors, making the env var basically unusable. That is a big problem for debugging of the Miri engine. Even shouldn't show so many errors, but that will be harder to do for constprop which runs the CTFE engine on broken and non-monomorphized MIR (causing tons of problems, not just this). AFAIK you did a bunch of const_prop changes over the last few weeks/months; likely some of what you did is the culprit here. Any ideas?
Well. Const prop tries to eval things and if it fails it doesn't prop. The reason why there are many errors now is that we are actually using the interpcx instead of reimplementing its logic
I'm not sure how to reduce your noise. Maybe we can disable the env var before const prop and reenable after?
only prints when  is explicitly called -- somehow constprop must be triggering that. If that was fixed, things would still be slow because so many backtraces are captured, but at least the result should be readable.
The really fancy solution, but probably too magic, would be to determine if we are running inside a const_prop query and let that alter the behavior. AFAIK rustc uses thread-local storage so this could actually be done, but it might not be how that TLS is supposed to be used.
my guess is that the printing originates here: calls , but that line does not always result in an error to be shown, right?

ecx.read_discriminant(op).unwrap().1 } <ins> /// Turn an interpreter error into something to report to the user. /// As a side-effect, if RUSTC_CTFE_BACKTRACE is set, this prints the backtrace. /// Should be called only if the error is actually going to to be reported! </ins> pub fn error_to_const_error<'mir, 'tcx>( ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, mut error: InterpErrorInfo<'tcx>,


Question:
The idea behind was that it should only show a backtrace (of where a Miri error originates) when an error is actually shown to the user. And that worked fine when I implemented it. But since then, something changed in constprop, and now I get thousands of backtraces even for crates with no errors, making the env var basically unusable. That is a big problem for debugging of the Miri engine. Even shouldn't show so many errors, but that will be harder to do for constprop which runs the CTFE engine on broken and non-monomorphized MIR (causing tons of problems, not just this). AFAIK you did a bunch of const_prop changes over the last few weeks/months; likely some of what you did is the culprit here. Any ideas?
Well. Const prop tries to eval things and if it fails it doesn't prop. The reason why there are many errors now is that we are actually using the interpcx instead of reimplementing its logic
I'm not sure how to reduce your noise. Maybe we can disable the env var before const prop and reenable after?
only prints when  is explicitly called -- somehow constprop must be triggering that. If that was fixed, things would still be slow because so many backtraces are captured, but at least the result should be readable.
The really fancy solution, but probably too magic, would be to determine if we are running inside a const_prop query and let that alter the behavior. AFAIK rustc uses thread-local storage so this could actually be done, but it might not be how that TLS is supposed to be used.
my guess is that the printing originates here: calls , but that line does not always result in an error to be shown, right?

let r = match f(self) { Ok(val) => Some(val), Err(error) => { <del> let diagnostic = error_to_const_error(&self.ecx, error); </del> use rustc::mir::interpret::InterpError::*; <del> match diagnostic.error { </del> <ins> match error.kind { </ins> Exit(_) => bug!("the CTFE program cannot exit"), Unsupported(_) | UndefinedBehavior(_)


Question:
The idea behind was that it should only show a backtrace (of where a Miri error originates) when an error is actually shown to the user. And that worked fine when I implemented it. But since then, something changed in constprop, and now I get thousands of backtraces even for crates with no errors, making the env var basically unusable. That is a big problem for debugging of the Miri engine. Even shouldn't show so many errors, but that will be harder to do for constprop which runs the CTFE engine on broken and non-monomorphized MIR (causing tons of problems, not just this). AFAIK you did a bunch of const_prop changes over the last few weeks/months; likely some of what you did is the culprit here. Any ideas?
Well. Const prop tries to eval things and if it fails it doesn't prop. The reason why there are many errors now is that we are actually using the interpcx instead of reimplementing its logic
I'm not sure how to reduce your noise. Maybe we can disable the env var before const prop and reenable after?
only prints when  is explicitly called -- somehow constprop must be triggering that. If that was fixed, things would still be slow because so many backtraces are captured, but at least the result should be readable.
The really fancy solution, but probably too magic, would be to determine if we are running inside a const_prop query and let that alter the behavior. AFAIK rustc uses thread-local storage so this could actually be done, but it might not be how that TLS is supposed to be used.
my guess is that the printing originates here: calls , but that line does not always result in an error to be shown, right?

// Ignore these errors. } Panic(_) => { <ins> let diagnostic = error_to_const_error(&self.ecx, error); </ins> diagnostic.report_as_lint( self.ecx.tcx, "this expression will panic at runtime",


Question:
Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool miri has failing tests. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and -- nominating for prioritization.
introduced an ICE (integer overflow) in the error emitting code, that Miri runs into.
will fix the issue on 's end, which should automatically fix this one.

} else if self.label_right - self.span_left <= self.column_width { // Attempt to fit the code window considering only the spans and labels. let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2; <del> self.computed_left = self.span_left - padding_left; </del> <ins> self.computed_left = self.span_left.saturating_sub(padding_left); </ins> self.computed_right = self.computed_left + self.column_width; } else if self.span_right - self.span_left <= self.column_width { // Attempt to fit the code window considering the spans and labels plus padding. let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2; <del> self.computed_left = self.span_left - padding_left; </del> <ins> self.computed_left = self.span_left.saturating_sub(padding_left); </ins> self.computed_right = self.computed_left + self.column_width; } else { // Mostly give up but still don't show the full line. self.computed_left = self.span_left;


Question:
Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool miri has failing tests. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and -- nominating for prioritization.
introduced an ICE (integer overflow) in the error emitting code, that Miri runs into.
will fix the issue on 's end, which should automatically fix this one.

}; let column_width = if let Some(width) = self.terminal_width { <del> width </del> <ins> width.saturating_sub(code_offset) </ins> } else if self.ui_testing { 140 } else { <del> term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(140) </del> <ins> term_size::dimensions() .map(|(w, _)| w.saturating_sub(code_offset)) .unwrap_or(std::usize::MAX) </ins> }; let margin = Margin::new(


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

// Warn for non-block expressions with diverging children. match expr.node { ExprKind::Block(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {}, <ins> ExprKind::Call(ref callee, _) => self.warn_if_unreachable(expr.hir_id, callee.span, "call"), ExprKind::MethodCall(_, ref span, _) => self.warn_if_unreachable(expr.hir_id, *span, "call"), </ins> _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"), }


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

|         ^^^^^^ = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` <del> warning: unreachable expression </del> <ins> warning: unreachable call </ins> --> $DIR/never-assign-dead-code.rs:10:5 | LL |     drop(x); <del> |     ^^^^^^^ </del> <ins> |     ^^^^ </ins> warning: unused variable: `x` --> $DIR/never-assign-dead-code.rs:9:9


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

LL | #![deny(unreachable_code)] |         ^^^^^^^^^^^^^^^^ <del> error: unreachable expression </del> <ins> error: unreachable call </ins> --> $DIR/expr_call.rs:18:5 | LL |     bar(return); <del> |     ^^^^^^^^^^^ </del> <ins> |     ^^^ </ins> error: aborting due to 2 previous errors


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

LL | #![deny(unreachable_code)] |         ^^^^^^^^^^^^^^^^ <del> error: unreachable expression --> $DIR/expr_method.rs:21:5 </del> <ins> error: unreachable call --> $DIR/expr_method.rs:21:9 </ins> | LL |     Foo.bar(return); <del> |     ^^^^^^^^^^^^^^^ </del> <ins> |         ^^^ </ins> error: aborting due to 2 previous errors


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

get_u8()); //~ ERROR unreachable expression } fn diverge_second() { <del> call( //~ ERROR unreachable expression </del> <ins> call( //~ ERROR unreachable call </ins> get_u8(), diverge()); }


Question:
rustc warns that the entire line is an unreachable expression however the code is clearly executed as can be see If the line was truly unreachable, there would be no panic... This bug appears on stable, beta and nightly
The is the unreachable part, so perhaps the error should be rephrased and pointed at that function call only
Hmm, so the span is wrong?
the order of execution is panic! and then everything else, so in some sense everything but the panic is unreachable. I'm not sure what a good span for that would be.
The method receiver is evaluated first, so the and calls still happen. The span can point just at the .
Ah, hm, I didn't expect that to be the case, but it makes sense. Then this seems relatively straightforward as to what the expected output is at least.
I feel like this should also add a note that the panic is called before everything else. It could also suggest but that seems more like a clippy lint.
Similar case: Maybe we can simply add a note that won't be called because evaluation of its arguments leaves the current code path. I agree that suggestion is indeed too specific and may be better suited to clippy. If this is acceptable, I would like to pick it up! As long as it's fine for me to progress more slowly than normal
GitHub wasn't clever enough to read that the PR said "might close" instead of "close." The PR seems to imply more work can be done on this.

LL | #![deny(unreachable_code)] |         ^^^^^^^^^^^^^^^^ <del> error: unreachable expression </del> <ins> error: unreachable call </ins> --> $DIR/unreachable-in-call.rs:17:5 | <del> LL | /     call( LL | |         get_u8(), LL | |         diverge()); | |__________________^ </del> <ins> LL |     call( |     ^^^^ </ins> error: aborting due to 2 previous errors


Question:
Because is the 's default for application-level logging and should not affect the output of the tools.
eh, it's only recently we've shifted away from using it for tools -- but seems like the trend is definitely to do so. I've filed

32_000_000 // 32MB on other platforms }; rustc_driver::set_sigpipe_handler(); <del> env_logger::init(); </del> <ins> env_logger::init_from_env("RUSTDOC_LOG"); </ins> let res = std::thread::Builder::new().stack_size(thread_stack_size).spawn(move || { get_args().map(|args| main_args(&args)).unwrap_or(1) }).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE);


Question:
I encountered this as well. What project are you trying to build? My theory is that it tries to run something like (in ?) and then fails to parse the output which is a mix of and ...
Way earlier, it runs it right at the start of a compilation to get the rustc version and enabled . Probably
Could someone use to narrow this down to a particular commit?
It looks to be caused by (I would assume it is in that rollup). It is now printing the time-passes information even for .
would you be up for a fix here?
I'll take a look on Monday. In the meantime, here's my best guess: I an extra entry to the output that prints the total time for the compilation. That extra line may not be indented at all, and it's possible this means it isn't ignored the same way as indented lines.
My theory about indentation was wrong. It was indeed a bad interaction between and , as others suggested, because they both print to . has a fix.

impl Callbacks for TimePassesCallbacks { fn config(&mut self, config: &mut interface::Config) { <ins> // If a --prints=... option has been given, we don't print the "total" // time because it will mess up the --prints output. See #64339. </ins> self.time_passes = <del> config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time; </del> <ins> config.opts.prints.is_empty() && (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time); </ins> } }


Question:
Hello, I ran into a problem using lifetime with async struct methods, here is the example: struct Foo<'a{ swag: &'a i32 } impl Foo<'{ async fn bar(&self) -i32 { 1337 } } The error is: '_ Everything is fine if I use explicit lifetime like . Version: 1.39 Nighly (2019-09-19 on playground)
This is happening because the desugaring of uses the lifetime. This is sort of unfortunate, but seems backwards compatible to fix, so I don't think we should block on this.
We decided to focus on this one in the WG meeting -- you still interested in working on it?
Yes, I'm still interested in working on this. I don't think that this should be too hard to fix though if someone else wants it.

/// header, we convert it to an in-band lifetime. fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName { assert!(self.is_collecting_in_band_lifetimes); <del> let index = self.lifetimes_to_define.len(); </del> <ins> let index = self.lifetimes_to_define.len() + self.in_scope_lifetimes.len(); </ins> let hir_name = ParamName::Fresh(index); self.lifetimes_to_define.push((span, hir_name)); hir_name


Question:
Hello, I ran into a problem using lifetime with async struct methods, here is the example: struct Foo<'a{ swag: &'a i32 } impl Foo<'{ async fn bar(&self) -i32 { 1337 } } The error is: '_ Everything is fine if I use explicit lifetime like . Version: 1.39 Nighly (2019-09-19 on playground)
This is happening because the desugaring of uses the lifetime. This is sort of unfortunate, but seems backwards compatible to fix, so I don't think we should block on this.
We decided to focus on this one in the WG meeting -- you still interested in working on it?
Yes, I'm still interested in working on this. I don't think that this should be too hard to fix though if someone else wants it.

<ins> // check-pass // Check that the anonymous lifetimes used here aren't considered to shadow one // another. Note that `async fn` is different to `fn` here because the lifetimes // are numbered by HIR lowering, rather than lifetime resolution. // edition:2018 struct A<'a, 'b>(&'a &'b i32); struct B<'a>(&'a i32); impl A<'_, '_> { async fn assoc(x: &u32, y: B<'_>) { async fn nested(x: &u32, y: A<'_, '_>) {} } async fn assoc2(x: &u32, y: A<'_, '_>) { impl A<'_, '_> { async fn nested_assoc(x: &u32, y: B<'_>) {} } } } fn main() {} </ins>