-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking issue for future-incompatibility lint late_bound_lifetime_arguments
#42868
Comments
error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> /home/travis/build/servo/servo-with-rust-nightly/servo/components/style/stylesheets/stylesheet.rs:243:27
|
243 | self.iter_rules::<'a, 'b, EffectiveRules>(device, guard)
| ^^
|
note: lint level defined here
--> /home/travis/build/servo/servo-with-rust-nightly/servo/components/style/lib.rs:26:9
|
26 | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> What does "late bound" mean in this context? What should we do instead? |
Well, that's a good question, but not something that can be explained in an error message. This issue should have a description, and @nikomatsakis is probably the best person to write it, but I can try as well.
Remove |
The error and lint should probably have an extra note pointing to one of these late bound lifetime parameters. EDIT: Done in #43343 |
This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version.
Remove explicit lifetime arguments on a method call. This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17785) <!-- Reviewable:end -->
…call (from servo:future-break); r=nox This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. Source-Repo: https://github.com/servo/servo Source-Revision: 9597fec9fa82f4e64c2f28889d6865722cadcd5d --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 730cca773decf44383059e9631f37461443aeca4
…call (from servo:future-break); r=nox This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. Source-Repo: https://github.com/servo/servo Source-Revision: 9597fec9fa82f4e64c2f28889d6865722cadcd5d
…call (from servo:future-break); r=nox This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. Source-Repo: https://github.com/servo/servo Source-Revision: 9597fec9fa82f4e64c2f28889d6865722cadcd5d
Add an extra note to `late_bound_lifetime_arguments` error/lint Fixes rust-lang#42868 (comment)
Add an extra note to `late_bound_lifetime_arguments` error/lint Fixes #42868 (comment)
…call (from servo:future-break); r=nox This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. Source-Repo: https://github.com/servo/servo Source-Revision: 9597fec9fa82f4e64c2f28889d6865722cadcd5d
…call (from servo:future-break); r=nox This causes a warning it today’s Nightly: rust-lang/rust#42868 … which makes the build fail because we use `#![deny(warnings)]`. This warning is planned to become a hard error in a future Rust version. Source-Repo: https://github.com/servo/servo Source-Revision: 9597fec9fa82f4e64c2f28889d6865722cadcd5d
That’s not true in the case of #42508, where it is necessary to make something compile at all. |
One possible solution for the problem of intermixed late- and early-bound parameters is to support explicit for<'late> fn f<'early1, 'early2>(a: &'late u8, b: &'early1 u8, c: &/*'elided*/u8) -> &'early2 u8 { ... } If type F<'early1, 'early2> = for<'late> fn(&'late u8, &'early1 u8, &/*'elided*/u8) -> &'early2 u8; The function could then be called with explicitly specified lifetime arguments, despite the presence of late-bound parameters: f::<'arg_early1, 'arg_early2>() |
I believe there exists a workaround to force early-bound lifetimes at a time when they are appropriate. Are you blocked on this point? In particular, you could do something like The definition of late bound lifetimes, mechanically at least, is that they are those lifetimes that both:
All other lifetimes bound on a function are early-bound. So if you have a dummy where clause like (The reason that the early- vs late-bound distinction exists is something else, of course.) I do hope we can clean this up in the future -- perhaps in another epoch -- but for now that is how it works. There are some annoying interactions with inference that make this all hard to alter in a totally backwards compatible way. |
I am blocked in the sense that I have warnings that I don’t know how to work around, don’t understand in the first place, and that say “it will become a hard error in a future release”. |
I think you could use something like |
Nope, that doesn't work for some reason. |
@petrochenkov wrote (in the description):
While each of these paragraphs made sense to me when I read them on my own, I am curious about the conclusion that it leads to. Consider a case like this: fn all_explicits_are_early<'a, 'b>(arg: &Foo<'a, 'b>) -> Bar<'a, 'b> where 'a: 'a, 'b: 'b { ... } I would think that a call expression But unfortunately, the above function definition actually desugars into something with a hidden late-bound lifetime parameter, due to lifetime elision on the
Would it be possible to loosen the error checking here so that if all the explicitly listed lifetime parameters are early-bound, then one still gets to specify the lifetimes explicitly at the call-site, regardless of any hidden late bound lifetimes introduced due to the elision rules? |
=== stdout === === stderr === error[E0601]: `main` function not found in crate `72278` --> /home/runner/work/glacier/glacier/ices/72278.rs:1:1 | 1 | / pub struct RefAny { } 2 | | 3 | | impl RefAny { 4 | | pub fn downcast_mut<'a, U: 'static>(&'a mut self) -> Option<&'a mut U> { ... | 10 | | } 11 | | } | |_^ consider adding a `main` function to `/home/runner/work/glacier/glacier/ices/72278.rs` warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> /home/runner/work/glacier/glacier/ices/72278.rs:5:48 | 5 | unsafe { self.downcast_mut_unchecked::<'a, U>() } // <- panic here in lifetime resolution | ^^ ... 8 | unsafe fn downcast_mut_unchecked<'a, U>(&'a mut self) -> Option<&'a mut U> { | -- the late bound lifetime parameter is introduced here | = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 <rust-lang/rust#42868> error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0601`. ==============
It seems this shows up as either a warn-level lint or a hard error depending on the code. Example that triggers a warning (on stable and nightly): static X: u8 = 0;
fn f<'a, 'b>(_x: &'b u8) -> &'a u8 { &X }
fn main() { let _ = f::<'static>; } Example that triggers a hard error (what led me to open #80618; again, stable or nightly), with no mention of the tracking issue: fn f<'a>() {}
fn main() { let _ = f::<'static>; } Is this expected? |
@cole-miller |
@petrochenkov Thanks, understood. So I can go ahead and assign an error number and |
=== stdout === === stderr === warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> /home/runner/work/glacier/glacier/ices/83466.rs:8:14 | 3 | fn func<'a, U>(self) -> U { | -- the late bound lifetime parameter is introduced here ... 8 | S.func::<'a, dont_crash>() | ^^ | = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 <rust-lang/rust#42868> error[E0747]: constant provided when a type was expected --> /home/runner/work/glacier/glacier/ices/83466.rs:8:18 | 8 | S.func::<'a, dont_crash>() | ^^^^^^^^^^ | = help: `dont_crash` is a function item, not a type = help: function item types cannot be named directly error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0747`. ==============
How do I solve something like
I get
I have spent a few hours on this and am pretty stumpped |
For anyone else finding things like this you might find this helpful It was actually solved at the call sight rather than the function -lister::<'a, T>(buffer, element.clone(), project);
+lister::<T>(buffer, element.clone(), project); Normally rustc gives the most excellent tips but i think in this case we could do better.. |
I have to say I am quite confused by the issue description here, and I don't understand what the underlying issue is. The core of my confusion seems to be captured by this (repeated) statement
I strongly disagree! The function is parameterized by Taking a step back: The fact that some lifetime parameters are type system fictions while others are actually relevant for monomorphization is very confusing and surprising. (I have never fully understood why this is the case; I'll need to dig into this some time.) This will clearly incur some friction when creating function pointers since monomorphization-relevant ("early-bound") lifetime parameters need to be chosen the moment the function pointer is created. I can see that we might want to improve that situation. But reading just this issue I really don't understand the motivation for the current change, since there's a big gap between "unfortunately some lifetime parameters actually matter for monomorphization" and "other lifetime parameters (that don't matter for monomorphization) don't make sense and we should disallow people from explicitly stating them". Which problem is being solved here? |
- This fixes a newer compiler lifetime issue (rust-lang/rust#42868) and requires concrete types in trait methods for object safety (`ContentsStorage` and slices for item lists). - Since item list slots can't be remapped, we need to include an offset with the context for section contents. - Section contents now requires the item list be sorted by slot and `section_items` no longer clones. - Move inline contents to a new module.
A related Stack Overflow discussion. |
late_bound_lifetime_arguments
compatibility lintlate_bound_lifetime_arguments
What is this lint about
In functions not all lifetime parameters are created equal.
For example, if you have a function like
both
'a
and'b
are listed in the same parameter list, but when stripped from the surface syntax the function looks more likewhere
'b
is a "true" ("early-bound") parameter of the function, and'a
is an "existential" ("late-bound") parameter. This means the function is not parameterized by'a
.To give some more intuition, let's write a type for function pointer to
f
:See more about this distinction in http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/#early--vs-late-bound-lifetimes
When lifetime arguments are provided to a function explicitly, e.g.
the first argument doesn't make much sense because the function is not parameterized by
'a
.Providing arguments for "late-bound" lifetime parameters in general doesn't make sense, while arguments for "early-bound" lifetime parameters can be provided.
It's not clear how to provide arguments for early-bound lifetime parameters if they are intermixed with late-bound parameters in the same list. For now providing any explicit arguments is prohibited if late-bound parameters are present, so in the future we can adopt any solution without hitting backward compatibility issues.
Note that late-bound lifetime parameters can be introduced implicitly through lifetime elision:
The precise rules discerning between early- and late-bound lifetimes can be found here:
rust/src/librustc/middle/resolve_lifetime.rs
Lines 1541 to 1700 in 91aff57
How to fix this warning/error
Just removing the lifetime arguments pointed to by the lint should be enough in most cases.
Current status
late_bound_lifetime_arguments
lint as warn-by-defaultlate_bound_lifetime_arguments
lint deny-by-defaultlate_bound_lifetime_arguments
lint a hard errorThe text was updated successfully, but these errors were encountered: