-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Better diagnostics with mismatched types due to implicit static lifetime #87244
Conversation
This comment has been minimized.
This comment has been minimized.
0542c18
to
69531a4
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new output is great! I have some nitpicks that I'd like to address before we land this.
Particularly I'd like to tweak the resulting output to be as short and clear as possible to people that might not know what a "requirement" or a "bound" is, or why a 'static
lifetime requirement is involved.
I'm not sure if this diagnostic should get a new error code, or even reuse an existing one.
If we can add a new error code that'd be great, but it is perfectly fine to land things like this without an error code, at least at the beginning, as long as the error itself contains as much information as an error code index entry would.
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
Show resolved
Hide resolved
src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
Outdated
Show resolved
Hide resolved
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
Outdated
Show resolved
Hide resolved
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
Outdated
Show resolved
Hide resolved
LL | pub struct Wrapper<T: Trait>(T); | ||
| ^^^^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the 'static
lifetime obligation is introduced by the type parameter (T: Trait
is implicitly 'sized
). It'd be nice to proactively handle this, detect this case and mention that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is because the lifetime on Ref
in impl Trait for Ref {}
falls back to 'static
in resolution.
The lifetime for Ref
in pub fn repro(_: Wrapper<Ref>)
on the other hand defaults to an anonymous lifetimes.
A diagnostic here still might be useful to say something like "this lifetime is being assumed as 'static'
"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think an extra diagnostic here might make sense for another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think an extra diagnostic here might make sense for another PR?
I would prefer if it was in the same PR, but I'm ready to merge this after addressing my nitpicks if you don't have the time to try and handle that case.
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
Show resolved
Hide resolved
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
Outdated
Show resolved
Hide resolved
Ok @estebank I modified the output just a bit, in order to make it a bit better in cases where there is an explicit static, multiple implicit statics, or when the impl isn't local. I also added a small note to the assumed static in cases of missing lifetimes. This isn't in the implicit static error message, but should maybe be enough for someone to figure out what's going on. I'd rather land this and maybe work more on that another time. |
@@ -336,6 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | |||
insertion_sp, | |||
suggestion, | |||
); | |||
err.note("assuming a `'static` lifetime..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of this new note, but I see your point.
@bors r+ |
📌 Commit ae02491 has been approved by |
☀️ Test successful - checks-actions |
This was flagged as causing a moderate regression with respect to instruction counts in the compiler: perf.rlo link Most of the regressions are under the 1% threshold, but there's a lot of them that exceed the 0.2% threshold we use for non-noisy benchmarks. Was this PR, which I understand adds an extra region error pass, expected to cause that much additional overhead? Skimming, I see a place where a |
@pnkfelix nope that's unexpected; the pass should should only run after a region error has been generated. The only thing that could have possibly had an effect, I think, is https://github.com/rust-lang/rust/pull/87244/files#diff-34d5893dd95fe09f9a0fd3341efacd1c21853bb34ba29d9d79bb9af26bb8a0a0R1906-R1911. Which is...not much of a change. |
Log of investigation work: Selected the most prominent regression, stm32f4-check full. First checked the self-profile view on perf.rlo for any changes in # of queries run. That can point to obvious causes, but not in this case. This means we need some local cachegrind diff'ing.
This generates results/cgout-{before,after}-stm32f4-Check-Full Using the output of cg_diff directly doesn't work well -- the hashes for each compiler are embedded into the paths and that makes cg_diff fail. I usually directly sed the cgout files rather than using the built-in --mod-filename support, since it's more general and works OK anyway. rustfilt is also helpful to avoid any crate hashes and such in mangled names that also interfere with diffing. In this case: cg_diff results/cgout-{before,after}-stm32f4-Check-Full | \
sed 's@da7d405357600a76f2b93b8aa41fe5ee5da7885d@@' | \
sed 's@718d53b0cb7dde93499cb92950d60b412f5a3d05@@' | \
rustfilt | \
cg_annotate /dev/stdin | less This produces:
Overall cachegrind is pretty good at pointing in a vague direction -- inlining and such can obscure a little what the actual effects of a change like this are. That said, it is pretty obvious based on the above that the regression is indeed due to the new ObligationCause being created. The diff above has some more minor changes in other functions - but we can mostly ignore those in this case. The majority of the delta is pretty clearly from extra allocation/deallocation and the creation of the cause code itself. Since the investigation points at an obvious cause and a pretty 'unavoidable' one, I'm going to go ahead and mark this as triaged. I've also gone ahead and filed #89000 with a possible mitigation, but regardless of whether that works, I don't think this needs further triage/investigation. @rustbot label +perf-regression-triaged |
Thank you so much for looking into this @Mark-Simulacrum ♥ |
…enkov Reuse existing shared Lrc for MatchImpl parent This is a small performance win for the hot path, which helps to address this regression: rust-lang#87244 (comment).
Fixes #78113
I think this is my first diagnostics PR...definitely happy to hear thoughts on the direction/implementation here.
I was originally just trying to solve the error above, where the lifetime on a GAT was causing a cryptic "mismatched types" error. But as I was writing this, I realized that this (unintentionally) also applied to a different case:
wf-in-foreign-fn-decls-issue-80468.rs
. I'm not sure if this diagnostic should get a new error code, or even reuse an existing one. And, there might be some ways to make this even more generalized. Also, the error is a bit more lengthy and verbose than probably needed. So thoughts there are welcome too.This PR essentially ended up adding a new nice region error pass that triggers if a type doesn't match the self type of an impl which is selected because of a predicate because of an implicit static bound on that self type.
r? @estebank