1
Fork 0

Annotate derived spans and move span suggestion code

* Annotate `derive`d spans from the user's code with the appropciate context
* Add `Span::can_be_used_for_suggestion` to query if the underlying span
  at the users' code
This commit is contained in:
Esteban Kuber 2021-11-20 18:46:36 +00:00
parent 8bee2b88c0
commit 962b2197a5
8 changed files with 112 additions and 90 deletions

View file

@ -17,7 +17,7 @@ use rustc_index::vec::IndexVec;
use rustc_macros::HashStable_Generic;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{def_id::LocalDefId, BytePos, ExpnKind, MacroKind, MultiSpan, Span, DUMMY_SP};
use rustc_span::{def_id::LocalDefId, BytePos, MultiSpan, Span, DUMMY_SP};
use rustc_target::asm::InlineAsmRegOrRegClass;
use rustc_target::spec::abi::Abi;
@ -525,20 +525,21 @@ pub struct GenericParam<'hir> {
}
impl GenericParam<'hir> {
pub fn bounds_span(&self) -> Option<Span> {
self.bounds.iter().fold(None, |span, bound| {
if let ExpnKind::Macro(MacroKind::Derive, _) =
bound.span().ctxt().outer_expn_data().kind
{
// We ignore bounds that come from exclusively from a `#[derive(_)]`, because we
// can't really point at them, and we sometimes use this method to get a span
// appropriate for suggestions.
span
} else {
let span = span.map(|s| s.to(bound.span())).unwrap_or_else(|| bound.span());
Some(span)
}
})
pub fn bounds_span_for_suggestions(&self) -> Option<Span> {
self.bounds
.iter()
.fold(None, |span: Option<Span>, bound| {
// We include bounds that come from a `#[derive(_)]` but point at the user's code,
// as we use this method to get a span appropriate for suggestions.
// FIXME: a more "principled" approach should be taken here.
if !bound.span().can_be_used_for_suggestions() {
None
} else {
let span = span.map(|s| s.to(bound.span())).unwrap_or_else(|| bound.span());
Some(span)
}
})
.map(|sp| sp.shrink_to_hi())
}
}