mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 11:04:03 +00:00
Span::resolved_at and Span::located_at to combine behavior of two spans
Proc macro spans serve two mostly unrelated purposes: controlling name
resolution and controlling error messages. It can be useful to mix the
name resolution behavior of one span with the line/column error message
locations of a different span.
In particular, consider the case of a trait brought into scope within
the def_site of a custom derive. I want to invoke trait methods on the
fields of the user's struct. If the field type does not implement the
right trait, I want the error message to underline the corresponding
struct field.
Generating the method call with the def_site span is not ideal -- it
compiles and runs but error messages sadly always point to the derive
attribute like we saw with Macros 1.1.
```
|
4 | #[derive(HeapSize)]
| ^^^^^^^^
```
Generating the method call with the same span as the struct field's
ident or type is not correct -- it shows the right underlines but fails
to resolve to the trait in scope at the def_site.
```
|
7 | bad: std:🧵:Thread,
| ^^^^^^^^^^^^^^^^^^^^^^^^
```
The correct span for the method call is one that combines the def_site's
name resolution with the struct field's line/column.
```
field.span.resolved_at(Span::def_site())
// equivalently
Span::def_site().located_at(field.span)
```
Adding both because which one is more natural will depend on context.
This commit is contained in:
parent
0f4ebf9f0a
commit
000e907c1f
@ -254,6 +254,20 @@ impl Span {
|
||||
Some(Span(self.0.to(other.0)))
|
||||
}
|
||||
|
||||
/// Creates a new span with the same line/column information as `self` but
|
||||
/// that resolves symbols as though it were at `other`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
pub fn resolved_at(&self, other: Span) -> Span {
|
||||
Span(self.0.with_ctxt(other.0.ctxt()))
|
||||
}
|
||||
|
||||
/// Creates a new span with the same name resolution behavior as `self` but
|
||||
/// with the line/column information of `other`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
pub fn located_at(&self, other: Span) -> Span {
|
||||
other.resolved_at(*self)
|
||||
}
|
||||
|
||||
diagnostic_method!(error, Level::Error);
|
||||
diagnostic_method!(warning, Level::Warning);
|
||||
diagnostic_method!(note, Level::Note);
|
||||
|
Loading…
Reference in New Issue
Block a user