Skip to content

Commit 8f3d7c8

Browse files
committed
rustc_ast: Introduce Token::uninterpolated_span
1 parent f8ab126 commit 8f3d7c8

File tree

6 files changed

+49
-12
lines changed

6 files changed

+49
-12
lines changed

src/librustc_ast/attr/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,10 @@ impl MetaItem {
286286
}
287287

288288
impl AttrItem {
289+
pub fn span(&self) -> Span {
290+
self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span))
291+
}
292+
289293
pub fn meta(&self, span: Span) -> Option<MetaItem> {
290294
Some(MetaItem {
291295
path: self.path.clone(),

src/librustc_ast/token.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,18 @@ impl Token {
328328
mem::replace(self, Token::dummy())
329329
}
330330

331+
/// For interpolated tokens returns a span of the fragment to which the interpolated
332+
/// token refers, for all other tokens this is just a regular span.
333+
/// It is particularly important to use this for identifiers and lifetimes
334+
/// for which spans affect name resolution. This also includes edition checks
335+
/// for edition-specific keyword identifiers.
336+
pub fn uninterpolated_span(&self) -> Span {
337+
match &self.kind {
338+
Interpolated(nt) => nt.span(),
339+
_ => self.span,
340+
}
341+
}
342+
331343
pub fn is_op(&self) -> bool {
332344
match self.kind {
333345
OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
@@ -714,6 +726,24 @@ pub enum Nonterminal {
714726
#[cfg(target_arch = "x86_64")]
715727
rustc_data_structures::static_assert_size!(Nonterminal, 40);
716728

729+
impl Nonterminal {
730+
fn span(&self) -> Span {
731+
match self {
732+
NtItem(item) => item.span,
733+
NtBlock(block) => block.span,
734+
NtStmt(stmt) => stmt.span,
735+
NtPat(pat) => pat.span,
736+
NtExpr(expr) | NtLiteral(expr) => expr.span,
737+
NtTy(ty) => ty.span,
738+
NtIdent(ident, _) | NtLifetime(ident) => ident.span,
739+
NtMeta(attr_item) => attr_item.span(),
740+
NtPath(path) => path.span,
741+
NtVis(vis) => vis.span,
742+
NtTT(tt) => tt.span(),
743+
}
744+
}
745+
}
746+
717747
impl PartialEq for Nonterminal {
718748
fn eq(&self, rhs: &Self) -> bool {
719749
match (self, rhs) {

src/librustc_parse/parser/expr.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ impl<'a> Parser<'a> {
849849

850850
/// Assuming we have just parsed `.`, continue parsing into an expression.
851851
fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
852-
if self.normalized_token.span.rust_2018() && self.eat_keyword(kw::Await) {
852+
if self.token.uninterpolated_span().rust_2018() && self.eat_keyword(kw::Await) {
853853
return self.mk_await_expr(self_arg, lo);
854854
}
855855

@@ -963,7 +963,7 @@ impl<'a> Parser<'a> {
963963
// | ^ expected expression
964964
self.bump();
965965
Ok(self.mk_expr_err(self.token.span))
966-
} else if self.normalized_token.span.rust_2018() {
966+
} else if self.token.uninterpolated_span().rust_2018() {
967967
// `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
968968
if self.check_keyword(kw::Async) {
969969
if self.is_async_block() {
@@ -1396,11 +1396,14 @@ impl<'a> Parser<'a> {
13961396
let movability =
13971397
if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
13981398

1399-
let asyncness =
1400-
if self.normalized_token.span.rust_2018() { self.parse_asyncness() } else { Async::No };
1401-
if asyncness.is_async() {
1399+
let asyncness = if self.token.uninterpolated_span().rust_2018() {
1400+
self.parse_asyncness()
1401+
} else {
1402+
Async::No
1403+
};
1404+
if let Async::Yes { span, .. } = asyncness {
14021405
// Feature-gate `async ||` closures.
1403-
self.sess.gated_spans.gate(sym::async_closure, self.normalized_prev_token.span);
1406+
self.sess.gated_spans.gate(sym::async_closure, span);
14041407
}
14051408

14061409
let capture_clause = self.parse_capture_clause();
@@ -1756,7 +1759,7 @@ impl<'a> Parser<'a> {
17561759
fn is_try_block(&self) -> bool {
17571760
self.token.is_keyword(kw::Try) &&
17581761
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
1759-
self.normalized_token.span.rust_2018() &&
1762+
self.token.uninterpolated_span().rust_2018() &&
17601763
// Prevent `while try {} {}`, `if try {} {} else {}`, etc.
17611764
!self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
17621765
}

src/librustc_parse/parser/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ impl<'a> Parser<'a> {
574574
&& self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As))
575575
{
576576
self.bump(); // `default`
577-
Defaultness::Default(self.normalized_prev_token.span)
577+
Defaultness::Default(self.prev_token.uninterpolated_span())
578578
} else {
579579
Defaultness::Final
580580
}

src/librustc_parse/parser/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ impl<'a> Parser<'a> {
884884
/// Parses asyncness: `async` or nothing.
885885
fn parse_asyncness(&mut self) -> Async {
886886
if self.eat_keyword(kw::Async) {
887-
let span = self.normalized_prev_token.span;
887+
let span = self.prev_token.uninterpolated_span();
888888
Async::Yes { span, closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID }
889889
} else {
890890
Async::No
@@ -894,7 +894,7 @@ impl<'a> Parser<'a> {
894894
/// Parses unsafety: `unsafe` or nothing.
895895
fn parse_unsafety(&mut self) -> Unsafe {
896896
if self.eat_keyword(kw::Unsafe) {
897-
Unsafe::Yes(self.normalized_prev_token.span)
897+
Unsafe::Yes(self.prev_token.uninterpolated_span())
898898
} else {
899899
Unsafe::No
900900
}
@@ -903,7 +903,7 @@ impl<'a> Parser<'a> {
903903
/// Parses constness: `const` or nothing.
904904
fn parse_constness(&mut self) -> Const {
905905
if self.eat_keyword(kw::Const) {
906-
Const::Yes(self.normalized_prev_token.span)
906+
Const::Yes(self.prev_token.uninterpolated_span())
907907
} else {
908908
Const::No
909909
}

src/librustc_parse/parser/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<'a> Parser<'a> {
323323
/// Is a `dyn B0 + ... + Bn` type allowed here?
324324
fn is_explicit_dyn_type(&mut self) -> bool {
325325
self.check_keyword(kw::Dyn)
326-
&& (self.normalized_token.span.rust_2018()
326+
&& (self.token.uninterpolated_span().rust_2018()
327327
|| self.look_ahead(1, |t| {
328328
t.can_begin_bound() && !can_continue_type_after_non_fn_ident(t)
329329
}))

0 commit comments

Comments
 (0)