Skip to content
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

Span that can point to closing delimiter of a delimited group #48187

Closed
dtolnay opened this issue Feb 13, 2018 · 2 comments · Fixed by #53902
Closed

Span that can point to closing delimiter of a delimited group #48187

dtolnay opened this issue Feb 13, 2018 · 2 comments · Fixed by #53902
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@dtolnay
Copy link
Member

dtolnay commented Feb 13, 2018

The proc_macro::TokenTree data structure currently look like this.

enum TokenTree {
    Group(Group),
    Ident(Ident),
    Punct(Punct),
    Literal(Literal),
}

impl Group {
    fn span(&self) -> Span;
}

Every delimited group like (...) [...] {...} has only a single Span that covers the full source location from opening delimiter to closing delimiter. This makes it impossible for a procedural macro to trigger an error pointing to just the opening or closing delimiter. The Rust compiler does not seem to have the same limitation:

mod m {
    type T =
}
error: expected type, found `}`
 --> src/main.rs:3:1
  |
3 | }
  | ^

The best things we can do in a proc macro are point to the last token inside the block, point to the entire block, or point to the next token after the block, none of which is really what you want for an error like above.

@dtolnay dtolnay added the A-macros-2.0 Area: Declarative macros 2.0 (#39412) label Feb 13, 2018
@TimNN TimNN added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Feb 13, 2018
@alexcrichton
Copy link
Member

The recent restructuring of proc_macro has enabled this issue to be implemented, so the OP isn't as accurate as it necessarily was before. This is still unimplemented, however, so I'm leaving it open

@parched
Copy link
Contributor

parched commented Sep 2, 2018

Related to this (or should I raise a separate issue?) is creating a span that points to a subset of the characters of an existing span. For example, when you have a template string like in format! I want the error span to just point to the actual error in the template string, not the whole string. The compiler seems to be able to do this internally.

bors added a commit that referenced this issue Sep 9, 2018
proc_macro::Group::span_open and span_close

Before this addition, every delimited group like `(`...`)` `[`...`]` `{`...`}` has only a single Span that covers the full source location from opening delimiter to closing delimiter. This makes it impossible for a procedural macro to trigger an error pointing to just the opening or closing delimiter. The Rust compiler does not seem to have the same limitation:

```rust
mod m {
    type T =
}
```

```console
error: expected type, found `}`
 --> src/main.rs:3:1
  |
3 | }
  | ^
```

On that same input, a procedural macro would be forced to trigger the error on the last token inside the block, on the entire block, or on the next token after the block, none of which is really what you want for an error like above.

This commit adds `group.span_open()` and `group.span_close()` which access the Span associated with just the opening delimiter and just the closing delimiter of the group. Relevant to Syn as we implement real error messages for when parsing fails in a procedural macro: dtolnay/syn#476.

```diff
  impl Group {
      fn span(&self) -> Span;
+     fn span_open(&self) -> Span;
+     fn span_close(&self) -> Span;
  }
```

Fixes #48187
r? @alexcrichton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants