]> git.lizzy.rs Git - rust.git/commit
Span::resolved_at and Span::located_at to combine behavior of two spans
authorDavid Tolnay <dtolnay@gmail.com>
Wed, 3 Jan 2018 07:29:11 +0000 (23:29 -0800)
committerDavid Tolnay <dtolnay@gmail.com>
Wed, 3 Jan 2018 07:43:52 +0000 (23:43 -0800)
commit000e907c1fc73ca249252cba3b2c9b1a20de857d
tree071aea346cf84227361c72c28bbf95a2bce98187
parent0f4ebf9f0a3196420e25cf1558b49ea3f38643c4
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::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.
src/libproc_macro/lib.rs