-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Use smaller def span for functions #75465
Conversation
r? @lcnr (rust_highfive has picked a reviewer for you, use r? to override) |
LL | | } | ||
| |_^ expected `(T, T)`, got `(U, T)` | ||
LL | fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, T)`, got `(U, 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.
This seems slightly worse than the previous message. However, I think this should really be pointing to a value being returned (either an explicit return
or the trailing expression). This is a nightly feature, so I think it's fine to improve this later (e.g. before stabilization) as needed.
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 we probably should do so in general, but that isn't bad enough for me to block this 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.
Hard agree on all points.
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 really like these changes 👍
cc @estebank I would expect that you are also interested in this.
LL | | | ||
... | | ||
LL | | (a, b) | ||
LL | | } |
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.
For impl Trait it would be helpful to see the return expression here
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.
This seems slightly worse than the previous message. However, I think this should really be pointing to a value being returned (either an explicit return or the trailing expression). This is a nightly feature, so I think it's fine to improve this later (e.g. before stabilization) as needed.
pretty much this
@@ -10,11 +10,7 @@ note: `rec` defined here | |||
LL | / fn rec<T>(mut it: T) | |||
LL | | where | |||
LL | | T: Iterator, |
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 personally might even prefer to exclude where bounds from the function signature 🤔
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.
so we only point at fn rec<T>(mut it: T)
here
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 it's better to display the where
clause, so switching from fn<T: Copy>() {}
to fn<T>() where T: Copy {}
doesn't change the diagnostic output.
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 don't fully get what you mean here, wouldn't that change change the diagnostic output from fn<T: Copy>()
to fn<T>() where T: Copy
with this PR?
I think that diagnostics where where bounds are relevant mention the where bound itself, so I think that not mentioning them in the signature is worth it as it can remove noise.
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.
Sorry - I meant that if a user switches from an 'inline' <T: Copy>
to a 'where-clause' where T: Copy
, they should still see the same amount of information in diagnostics.
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.
hmm, I am not sure how often these bounds help and are not explicitly references and put a fairly high value into single line error spans.
But that's just a personal preference and I am fine with landing this as is, so r=me. We may want to wait a day or two in case @estebank want's to look over this but otherwise I am satisfied
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 that the safe approach will be to include them.
LL | | } | ||
| |_^ expected `(T, T)`, got `(U, T)` | ||
LL | fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, T)`, got `(U, 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.
I think we probably should do so in general, but that isn't bad enough for me to block this pr
@estebank: Do you have any objections to this change? |
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.
+100 from me. Left a couple of nitpicks. We need to be carefully going forward to not use this new span when we actually want to point at the body, but it should be fine.
let body = self.parse_fn_body(attrs)?; // `;` or `{ ... }`. | ||
Ok((ident, FnSig { header, decl }, generics, body)) | ||
|
||
let mut sig_hi = self.prev_token.span; |
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.
let mut sig_hi = self.prev_token.span; | |
let sig_hi = if self.check(&token::Semi) { | |
// Include the trailing semicolon in the span of the signature | |
self.token.span | |
} else { | |
self.prev_token.span | |
}; |
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.
This will introduce a duplicate check for token::Semi
- I wanted to make sure that the determination of sig_hi
always stays in sync with the actual parsing logic.
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.
ok, fair enough it's not critical
// Include the trailing semicolon in the span of the signature | ||
*sig_hi = self.token.span; |
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.
// Include the trailing semicolon in the span of the signature | |
*sig_hi = self.token.span; |
fn parse_fn_body( | ||
&mut self, | ||
attrs: &mut Vec<Attribute>, | ||
sig_hi: &mut Span, |
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.
sig_hi: &mut Span, |
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.
Same issue as above
@@ -10,11 +10,7 @@ note: `rec` defined here | |||
LL | / fn rec<T>(mut it: T) | |||
LL | | where | |||
LL | | T: Iterator, |
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 that the safe approach will be to include them.
LL | fn get_ctxt(&self) -> &'a Ctxt { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
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.
This change is slightly unfortunate given the message.
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.
Maybe it should only highlight the part from {
up to and including }
and not the function signature itself?
LL | | } | ||
| |_^ expected `(T, T)`, got `(U, T)` | ||
LL | fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, T)`, got `(U, 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.
Hard agree on all points.
(Sorry about the delay in review, I've been having trouble staying on top of my notification volume lately.) |
2ad6322
to
483540d
Compare
@estebank: I've addressed your comments. My concern with removing |
📌 Commit 8b886a32350739abe63a0f57cac0a7be0092b737 has been approved by |
⌛ Testing commit 8b886a32350739abe63a0f57cac0a7be0092b737 with merge f1e1f6d98a3a41673551f10c462a0c72be3db53e... |
💔 Test failed - checks-actions |
Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
8b886a3
to
e3cd43e
Compare
I needed to bless the NLL tests. @estebank: I've squashed the commits, and updated the |
@bors r+ |
📌 Commit e3cd43e has been approved by |
☀️ Test successful - checks-actions, checks-azure |
This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Record `tcx.def_span` instead of `item.span` in crate metadata This was missed in PR rust-lang#75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
Currently, we serialize the same crate metadata for proc-macro crates as we do for normal crates. This is quite wasteful - almost none of this metadata is ever used, and much of it can't even be deserialized (if it contains a foreign `CrateNum`). This PR changes metadata encoding to skip encoding the majority of crate metadata for proc-macro crates. Most of the `Lazy<[T]>` fields are left completetly empty, while the non-lazy fields are left as-is. Additionally, proc-macros now have a def span that does not include their body. This was done for normal functions in rust-lang#75465, but was missed for proc-macros. As a result of this PR, we should only ever encode local `CrateNum`s when encoding proc-macro crates. I've added a specialized serialization impl for `CrateNum` to assert this.
…data, r=petrochenkov Encode less metadata for proc-macro crates Currently, we serialize the same crate metadata for proc-macro crates as we do for normal crates. This is quite wasteful - almost none of this metadata is ever used, and much of it can't even be deserialized (if it contains a foreign `CrateNum`). This PR changes metadata encoding to skip encoding the majority of crate metadata for proc-macro crates. Most of the `Lazy<[T]>` fields are left completetly empty, while the non-lazy fields are left as-is. Additionally, proc-macros now have a def span that does not include their body. This was done for normal functions in rust-lang#75465, but was missed for proc-macros. As a result of this PR, we should only ever encode local `CrateNum`s when encoding proc-macro crates. I've added a specialized serialization impl for `CrateNum` to assert this.
Currently, the def span of a function encompasses the entire function
signature and body. However, this is usually unnecessarily verbose - when we are
pointing at an entire function in a diagnostic, we almost always want to
point at the signature. The actual contents of the body tends to be
irrelevant to the diagnostic we are emitting, and just takes up
additional screen space.
This commit changes the
def_span
of all function items (freestandingfunctions,
impl
-block methods, andtrait
-block methods) to be thespan of the signature. For example, the function
now has a
def_span
corresponding topub fn foo<T>(val: T) -> T
(everything before the opening curly brace).
Trait methods without a body have a
def_span
which includes thetrailing semicolon. For example:
the function definition
Foo::bar
has adef_span
offn bar();
This makes our diagnostic output much shorter, and emphasizes
information that is relevant to whatever diagnostic we are reporting.
We continue to use the full span (including the body) in a few of
places:
emitted.
#[rustc_on_unimplemented(enclosing_scope="in this scope")]
attribute points the entire scope body.
All of these cases work only with local items, so we don't need to
add anything extra to crate metadata.