syntax_pos: Introduce a helper for checking whether a span comes from expansion

This commit is contained in:
Vadim Petrochenkov 2019-08-11 01:08:30 +03:00
parent f7af19c279
commit dfcbe75900
12 changed files with 25 additions and 20 deletions

View file

@ -108,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
.help("try using `Ty` instead")
.emit();
} else {
if ty.span.ctxt().outer_expn_info().is_some() {
if ty.span.from_expansion() {
return;
}
if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {

View file

@ -8,7 +8,7 @@ use crate::base;
use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext};
use crate::traits::*;
use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
use syntax_pos::{DUMMY_SP, BytePos, Span};
use syntax::symbol::kw;
use std::iter;
@ -120,7 +120,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// In order to have a good line stepping behavior in debugger, we overwrite debug
// locations of macro expansions with that of the outermost expansion site
// (unless the crate is being compiled with `-Z debug-macros`).
if source_info.span.ctxt() == NO_EXPANSION ||
if !source_info.span.from_expansion() ||
self.cx.sess().opts.debugging_opts.debug_macros {
let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo());
(scope, source_info.span)

View file

@ -42,7 +42,7 @@ use syntax::source_map::Spanned;
use syntax::edition::Edition;
use syntax::feature_gate::{self, AttributeGate, AttributeType};
use syntax::feature_gate::{Stability, deprecated_attributes};
use syntax_pos::{BytePos, Span, SyntaxContext};
use syntax_pos::{BytePos, Span};
use syntax::symbol::{Symbol, kw, sym};
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
@ -78,7 +78,7 @@ impl EarlyLintPass for WhileTrue {
if let ast::ExprKind::While(cond, ..) = &e.node {
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
if let ast::LitKind::Bool(true) = lit.node {
if lit.span.ctxt() == SyntaxContext::empty() {
if !lit.span.from_expansion() {
let msg = "denote infinite loops with `loop { ... }`";
let condition_span = cx.sess.source_map().def_span(e.span);
cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
if fieldpat.is_shorthand {
continue;
}
if fieldpat.span.ctxt().outer_expn_info().is_some() {
if fieldpat.span.from_expansion() {
// Don't lint if this is a macro expansion: macro authors
// shouldn't have to worry about this kind of style issue
// (Issue #49588)
@ -1012,7 +1012,7 @@ impl UnreachablePub {
let mut applicability = Applicability::MachineApplicable;
match vis.node {
hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
if span.ctxt().outer_expn_info().is_some() {
if span.from_expansion() {
applicability = Applicability::MaybeIncorrect;
}
let def_span = cx.tcx.sess.source_map().def_span(span);

View file

@ -518,7 +518,7 @@ impl EarlyLintPass for UnusedParens {
// when a parenthesized token tree matched in one macro expansion is matched as
// an expression in another and used as a fn/method argument (Issue #47775)
if e.span.ctxt().outer_expn_info()
.map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) {
.map_or(false, |info| info.call_site.from_expansion()) {
return;
}
let msg = format!("{} argument", call_kind);

View file

@ -274,7 +274,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
ItemKind::Use(..) => {
// don't suggest placing a use before the prelude
// import or other generated ones
if item.span.ctxt().outer_expn_info().is_none() {
if !item.span.from_expansion() {
self.span = Some(item.span.shrink_to_lo());
self.found_use = true;
return;
@ -284,7 +284,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
ItemKind::ExternCrate(_) => {}
// but place them before the first other item
_ => if self.span.map_or(true, |span| item.span < span ) {
if item.span.ctxt().outer_expn_info().is_none() {
if !item.span.from_expansion() {
// don't insert between attributes and an item
if item.attrs.is_empty() {
self.span = Some(item.span.shrink_to_lo());

View file

@ -1156,7 +1156,7 @@ fn escape(s: String) -> String {
// Helper function to determine if a span came from a
// macro expansion or syntax extension.
fn generated_code(span: Span) -> bool {
span.ctxt() != NO_EXPANSION || span.is_dummy()
span.from_expansion() || span.is_dummy()
}
// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore

View file

@ -347,9 +347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp,
);
// Check the `expn_info()` to see if this is a macro; if so, it's hard to
// extract the text and make a good suggestion, so don't bother.
let is_macro = sp.ctxt().outer_expn_info().is_some();
// If the span is from a macro, then it's hard to extract the text
// and make a good suggestion, so don't bother.
let is_macro = sp.from_expansion();
match (&expr.node, &expected.sty, &checked_ty.sty) {
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) {

View file

@ -985,7 +985,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
hir::ItemKind::Use(..) => {
// Don't suggest placing a `use` before the prelude
// import or other generated ones.
if item.span.ctxt().outer_expn_info().is_none() {
if !item.span.from_expansion() {
self.span = Some(item.span.shrink_to_lo());
self.found_use = true;
return;
@ -995,7 +995,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
hir::ItemKind::ExternCrate(_) => {}
// ...but do place them before the first other item.
_ => if self.span.map_or(true, |span| item.span < span ) {
if item.span.ctxt().outer_expn_info().is_none() {
if !item.span.from_expansion() {
// Don't insert between attributes and an item.
if item.attrs.is_empty() {
self.span = Some(item.span.shrink_to_lo());

View file

@ -1101,7 +1101,7 @@ impl<'a> Parser<'a> {
crate fn process_potential_macro_variable(&mut self) {
self.token = match self.token.kind {
token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() &&
token::Dollar if self.token.span.from_expansion() &&
self.look_ahead(1, |t| t.is_ident()) => {
self.bump();
let name = match self.token.kind {

View file

@ -255,7 +255,7 @@ impl HygieneData {
}
fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
while span.ctxt() != crate::NO_EXPANSION && span.ctxt() != to {
while span.from_expansion() && span.ctxt() != to {
if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) {
span = info.call_site;
} else {

View file

@ -288,6 +288,12 @@ impl Span {
span.lo.0 == 0 && span.hi.0 == 0
}
/// Returns `true` if this span comes from a macro or desugaring.
#[inline]
pub fn from_expansion(self) -> bool {
self.ctxt() != SyntaxContext::empty()
}
/// Returns a new span representing an empty span at the beginning of this span
#[inline]
pub fn shrink_to_lo(self) -> Span {

View file

@ -14,7 +14,6 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::str;
use crate::hygiene::SyntaxContext;
use crate::{Span, DUMMY_SP, GLOBALS};
#[cfg(test)]
@ -851,7 +850,7 @@ impl fmt::Display for Ident {
impl Encodable for Ident {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
if self.span.ctxt().modern() == SyntaxContext::empty() {
if !self.span.modern().from_expansion() {
s.emit_str(&self.as_str())
} else { // FIXME(jseyfried): intercrate hygiene
let mut string = "#".to_owned();