From 6d478fd49d7dac8c7a01c30a34995519d4484f6e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Aug 2022 09:59:44 +1000 Subject: [PATCH] Remove the span from `ast::Lit`. In the most common case, the `Lit` is stored within an `Expr`, which records the same span. For other cases, we can store the span next to the `Lit`. --- compiler/rustc_ast/src/ast.rs | 21 +++--- compiler/rustc_ast/src/attr/mod.rs | 69 ++++++++++--------- compiler/rustc_ast/src/mut_visit.rs | 6 +- compiler/rustc_ast/src/util/literal.rs | 18 ++--- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 5 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 20 +++--- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 2 +- compiler/rustc_attr/src/builtin.rs | 24 +++---- compiler/rustc_builtin_macros/src/asm.rs | 2 +- compiler/rustc_builtin_macros/src/derive.rs | 10 +-- compiler/rustc_expand/src/base.rs | 4 +- compiler/rustc_expand/src/build.rs | 2 +- .../rustc_expand/src/proc_macro_server.rs | 6 +- compiler/rustc_interface/src/interface.rs | 2 +- compiler/rustc_interface/src/util.rs | 9 ++- compiler/rustc_lint/src/builtin.rs | 5 +- .../src/hidden_unicode_codepoints.rs | 8 +-- compiler/rustc_lint/src/levels.rs | 8 +-- compiler/rustc_lint/src/nonstandard_style.rs | 12 ++-- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_parse/src/parser/attr.rs | 13 ++-- compiler/rustc_parse/src/parser/expr.rs | 24 +++---- compiler/rustc_parse/src/parser/mod.rs | 6 +- compiler/rustc_parse/src/validate_attr.rs | 10 +-- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_typeck/src/collect.rs | 4 +- src/librustdoc/clean/cfg.rs | 8 +-- src/tools/clippy/clippy_lints/src/attrs.rs | 4 +- .../src/literal_representation.rs | 21 +++--- .../src/misc_early/literal_suffix.rs | 14 ++-- .../src/misc_early/mixed_case_hex_literals.rs | 6 +- .../clippy/clippy_lints/src/misc_early/mod.rs | 14 ++-- .../src/misc_early/zero_prefixed_literal.rs | 10 +-- .../clippy/clippy_lints/src/octal_escapes.rs | 4 +- .../clippy/clippy_utils/src/ast_utils.rs | 2 +- src/tools/rustfmt/src/attr.rs | 16 +++-- src/tools/rustfmt/src/expr.rs | 25 ++++--- src/tools/rustfmt/src/utils.rs | 2 +- 41 files changed, 226 insertions(+), 206 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f25fdc942b085..cd4e92a1ab625 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -521,7 +521,7 @@ pub enum NestedMetaItem { /// A literal. /// /// E.g., `"foo"`, `64`, `true`. - Literal(Lit), + Literal(Lit, Span), } /// A spanned compile-time attribute item. @@ -550,7 +550,9 @@ pub enum MetaItemKind { /// Name value meta item. /// /// E.g., `feature = "foo"` as in `#[feature = "foo"]`. - NameValue(Lit), + /// + /// The span is that of the literal on the RHS. + NameValue(Lit, Span), } /// A block (`{ .. }`). @@ -1605,7 +1607,7 @@ pub enum MacArgs { #[derive(Clone, Encodable, Decodable, Debug)] pub enum MacArgsEq { Ast(P), - Hir(Lit), + Hir(Lit, Span), } impl MacArgs { @@ -1621,7 +1623,7 @@ impl MacArgs { MacArgs::Empty => None, MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(lit, _)) => { unreachable!("in literal form when getting span: {:?}", lit); } } @@ -1634,7 +1636,7 @@ impl MacArgs { MacArgs::Empty => TokenStream::default(), MacArgs::Delimited(.., tokens) => tokens.clone(), MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(lit, _)) => { unreachable!("in literal form when getting inner tokens: {:?}", lit) } } @@ -1663,9 +1665,10 @@ where MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => { unreachable!("hash_stable {:?}", expr); } - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(eq_span, MacArgsEq::Hir(lit, lit_span)) => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); + lit_span.hash_stable(ctx, hasher); } } } @@ -1717,6 +1720,8 @@ pub enum StrStyle { } /// An AST literal. +/// +/// Consult the enclosing type for the span (e.g. `ExprKind::Lit`). #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct Lit { /// The original literal token as written in source code. @@ -1725,7 +1730,6 @@ pub struct Lit { /// Strings are unescaped, hexadecimal forms are eliminated, etc. /// FIXME: Remove this and only create the semantic representation during lowering to HIR. pub kind: LitKind, - pub span: Span, } /// Same as `Lit`, but restricted to string literals. @@ -1749,7 +1753,6 @@ impl StrLit { }; Lit { token_lit: token::Lit::new(token_kind, self.symbol, self.suffix), - span: self.span, kind: LitKind::Str(self.symbol_unescaped, self.style), } } @@ -3084,7 +3087,7 @@ mod size_asserts { static_assert_size!(Impl, 200); static_assert_size!(Item, 184); static_assert_size!(ItemKind, 112); - static_assert_size!(Lit, 48); + static_assert_size!(Lit, 40); static_assert_size!(LitKind, 24); static_assert_size!(Local, 72); static_assert_size!(Param, 40); diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 5b72ec2b6015c..b5d546e0c07da 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -49,7 +49,7 @@ impl NestedMetaItem { /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s. pub fn literal(&self) -> Option<&Lit> { match *self { - NestedMetaItem::Literal(ref lit) => Some(lit), + NestedMetaItem::Literal(ref lit, _) => Some(lit), _ => None, } } @@ -174,10 +174,24 @@ impl MetaItem { // Example: // #[attribute(name = "value")] - // ^^^^^^^^^^^^^^ + // ^^^^^^^ pub fn name_value_literal(&self) -> Option<&Lit> { match &self.kind { - MetaItemKind::NameValue(v) => Some(v), + MetaItemKind::NameValue(v, _) => Some(v), + _ => None, + } + } + + pub fn name_value_literal_and_span(&self) -> Option<(&Lit, Span)> { + match &self.kind { + MetaItemKind::NameValue(v, v_span) => Some((v, *v_span)), + _ => None, + } + } + + pub fn name_value_literal_span(&self) -> Option { + match self.kind { + MetaItemKind::NameValue(_, v_span) => Some(v_span), _ => None, } } @@ -200,17 +214,6 @@ impl MetaItem { pub fn has_name(&self, name: Symbol) -> bool { self.path == name } - - /// This is used in case you want the value span instead of the whole attribute. Example: - /// - /// ```text - /// #[doc(alias = "foo")] - /// ``` - /// - /// In here, it'll return a span for `"foo"`. - pub fn name_value_literal_span(&self) -> Option { - Some(self.name_value_literal()?.span) - } } impl AttrItem { @@ -320,9 +323,9 @@ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> Meta } pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { - let lit = Lit::from_lit_kind(lit_kind, lit_span); + let lit = Lit::from_lit_kind(lit_kind); let span = ident.span.to(lit_span); - MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) } + MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit, lit_span) } } pub fn mk_list_item(ident: Ident, items: Vec) -> MetaItem { @@ -458,7 +461,7 @@ impl MetaItem { let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi()); let kind = MetaItemKind::from_tokens(tokens)?; let hi = match kind { - MetaItemKind::NameValue(ref lit) => lit.span.hi(), + MetaItemKind::NameValue(_, lit_span) => lit_span.hi(), MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), _ => path.span.hi(), }; @@ -470,7 +473,7 @@ impl MetaItem { impl MetaItemKind { pub fn value_str(&self) -> Option { match self { - MetaItemKind::NameValue(ref v) => match v.kind { + MetaItemKind::NameValue(ref v, _) => match v.kind { LitKind::Str(ref s, _) => Some(*s), _ => None, }, @@ -481,11 +484,11 @@ impl MetaItemKind { pub fn mac_args(&self, span: Span) -> MacArgs { match self { MetaItemKind::Word => MacArgs::Empty, - MetaItemKind::NameValue(lit) => { + MetaItemKind::NameValue(lit, lit_span) => { let expr = P(ast::Expr { id: ast::DUMMY_NODE_ID, kind: ast::ExprKind::Lit(lit.clone()), - span: lit.span, + span: *lit_span, attrs: ast::AttrVec::new(), tokens: None, }); @@ -511,10 +514,10 @@ impl MetaItemKind { fn token_trees(&self, span: Span) -> Vec { match *self { MetaItemKind::Word => vec![], - MetaItemKind::NameValue(ref lit) => { + MetaItemKind::NameValue(ref lit, lit_span) => { vec![ TokenTree::token_alone(token::Eq, span), - TokenTree::Token(lit.to_token(), Spacing::Alone), + TokenTree::Token(lit.to_token(lit_span), Spacing::Alone), ] } MetaItemKind::List(ref list) => { @@ -555,9 +558,9 @@ impl MetaItemKind { Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees()) } - Some(TokenTree::Token(token, _)) => { - Lit::from_token(&token).ok().map(MetaItemKind::NameValue) - } + Some(TokenTree::Token(token, _)) => Lit::from_token(&token) + .ok() + .map(|(lit, lit_span)| MetaItemKind::NameValue(lit, lit_span)), _ => None, } } @@ -570,10 +573,12 @@ impl MetaItemKind { } MacArgs::Delimited(..) => None, MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match &expr.kind { - ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.clone())), + ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.clone(), expr.span)), _ => None, }, - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + MacArgs::Eq(_, MacArgsEq::Hir(lit, span)) => { + Some(MetaItemKind::NameValue(lit.clone(), *span)) + } } } @@ -600,15 +605,15 @@ impl NestedMetaItem { pub fn span(&self) -> Span { match *self { NestedMetaItem::MetaItem(ref item) => item.span, - NestedMetaItem::Literal(ref lit) => lit.span, + NestedMetaItem::Literal(_, lit_span) => lit_span, } } fn token_trees(&self) -> Vec { match *self { NestedMetaItem::MetaItem(ref item) => item.token_trees(), - NestedMetaItem::Literal(ref lit) => { - vec![TokenTree::Token(lit.to_token(), Spacing::Alone)] + NestedMetaItem::Literal(ref lit, lit_span) => { + vec![TokenTree::Token(lit.to_token(lit_span), Spacing::Alone)] } } } @@ -619,10 +624,10 @@ impl NestedMetaItem { { match tokens.peek() { Some(TokenTree::Token(token, _)) - if let Ok(lit) = Lit::from_token(token) => + if let Ok((lit, lit_span)) = Lit::from_token(token) => { tokens.next(); - return Some(NestedMetaItem::Literal(lit)); + return Some(NestedMetaItem::Literal(lit, lit_span)); } Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { let inner_tokens = inner_tokens.clone(); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 458d1156ec251..e8352dcb3b7a7 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -372,7 +372,7 @@ pub fn visit_mac_args(args: &mut MacArgs, vis: &mut T) { vis.visit_span(eq_span); vis.visit_expr(expr); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(lit, _)) => { unreachable!("in literal form when visiting mac args eq: {:?}", lit) } } @@ -617,7 +617,7 @@ pub fn noop_visit_macro_def(macro_def: &mut MacroDef, vis: &mut T pub fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T) { match li { NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), - NestedMetaItem::Literal(_lit) => {} + NestedMetaItem::Literal(_lit, _lit_span) => {} } } @@ -626,7 +626,7 @@ pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { match kind { MetaItemKind::Word => {} MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), - MetaItemKind::NameValue(_s) => {} + MetaItemKind::NameValue(_s, _) => {} } vis.visit_span(span); } diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 6a1578498e689..c17e7e4dca0f7 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -209,14 +209,14 @@ impl LitKind { impl Lit { /// Converts literal token into an AST literal. - pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result { - Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span }) + pub fn from_token_lit(token_lit: token::Lit) -> Result { + Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)? }) } /// Converts arbitrary token into an AST literal. /// /// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation. - pub fn from_token(token: &Token) -> Result { + pub fn from_token(token: &Token) -> Result<(Lit, Span), LitError> { let lit = match token.uninterpolate().kind { token::Ident(name, false) if name.is_bool_lit() => { token::Lit::new(token::Bool, name, None) @@ -226,30 +226,30 @@ impl Lit { if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt && let ast::ExprKind::Lit(lit) = &expr.kind { - return Ok(lit.clone()); + return Ok((lit.clone(), expr.span)); } return Err(LitError::NotLiteral); } _ => return Err(LitError::NotLiteral), }; - Lit::from_token_lit(lit, token.span) + Ok((Lit::from_token_lit(lit)?, token.span)) } /// Attempts to recover an AST literal from semantic literal. /// This function is used when the original token doesn't exist (e.g. the literal is created /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing). - pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit { - Lit { token_lit: kind.to_token_lit(), kind, span } + pub fn from_lit_kind(kind: LitKind) -> Lit { + Lit { token_lit: kind.to_token_lit(), kind } } /// Losslessly convert an AST literal into a token. - pub fn to_token(&self) -> Token { + pub fn to_token(&self, span: Span) -> Token { let kind = match self.token_lit.kind { token::Bool => token::Ident(self.token_lit.symbol, false), _ => token::Literal(self.token_lit), }; - Token::new(kind, self.span) + Token::new(kind, span) } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index f687bfeced841..c9fae622aaff9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -939,7 +939,7 @@ pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) { MacArgs::Empty => {} MacArgs::Delimited(_dspan, _delim, _tokens) => {} MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(lit, _)) => { unreachable!("in literal form when walking mac args eq: {:?}", lit) } } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 77babeb5d39d1..975507fa3de9f 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -85,7 +85,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Unary(op, ohs) } ExprKind::Lit(ref l) => { - hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone())) + hir::ExprKind::Lit(respan(self.lower_span(e.span), l.kind.clone())) } ExprKind::Cast(ref expr, ref ty) => { let expr = self.lower_expr(expr); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3a94c7a91b23f..df33223c069de 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -928,12 +928,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Lit { token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None), kind: LitKind::Err, - span: DUMMY_SP, } }; - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) + MacArgs::Eq(eq_span, MacArgsEq::Hir(lit, expr.span)) } - MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(ref lit, _)) => { unreachable!("in literal form when lowering mac args eq: {:?}", lit) } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index ed5e7dace4bc4..ec5e3d459b553 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -370,8 +370,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } } - fn print_literal(&mut self, lit: &ast::Lit) { - self.maybe_print_comment(lit.span.lo()); + fn print_literal(&mut self, lit: &ast::Lit, span: Span) { + self.maybe_print_comment(span.lo()); self.word(lit.token_lit.to_string()) } @@ -479,11 +479,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere let token_str = self.expr_to_string(expr); self.word(token_str); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + MacArgs::Eq(_, MacArgsEq::Hir(lit, lit_span)) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); - let token_str = self.literal_to_string(lit); + let token_str = self.literal_to_string(lit, *lit_span); self.word(token_str); } } @@ -493,7 +493,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { match item { ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), - ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit), + ast::NestedMetaItem::Literal(ref lit, lit_span) => self.print_literal(lit, *lit_span), } } @@ -501,11 +501,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.ibox(INDENT_UNIT); match item.kind { ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), - ast::MetaItemKind::NameValue(ref value) => { + ast::MetaItemKind::NameValue(ref lit, lit_span) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); - self.print_literal(value); + self.print_literal(lit, lit_span); } ast::MetaItemKind::List(ref items) => { self.print_path(&item.path, false, 0); @@ -825,8 +825,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere Self::to_string(|s| s.print_expr(e)) } - fn literal_to_string(&self, lit: &ast::Lit) -> String { - Self::to_string(|s| s.print_literal(lit)) + fn literal_to_string(&self, lit: &ast::Lit, span: Span) -> String { + Self::to_string(|s| s.print_literal(lit, span)) } fn tt_to_string(&self, tt: &TokenTree) -> String { @@ -1733,7 +1733,7 @@ impl<'a> State<'a> { } ast::Extern::Explicit(abi, _) => { self.word_nbsp("extern"); - self.print_literal(&abi.as_lit()); + self.print_literal(&abi.as_lit(), abi.span); self.nbsp(); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index bcefa8ce0b9ce..c58e74e4c38d5 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -320,7 +320,7 @@ impl<'a> State<'a> { self.print_expr_addr_of(k, m, expr); } ast::ExprKind::Lit(ref lit) => { - self.print_literal(lit); + self.print_literal(lit, expr.span); } ast::ExprKind::Cast(ref expr, ref ty) => { let prec = AssocOp::As.precedence() as i8; diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 54bac29a6cee0..f128b8eb230f3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -207,7 +207,7 @@ impl<'a> State<'a> { s.word("extern"); })); if let Some(abi) = nmod.abi { - self.print_literal(&abi.as_lit()); + self.print_literal(&abi.as_lit(), abi.span); self.nbsp(); } self.bopen(); diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index e1404ab15efa3..aa99415ce878d 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -480,10 +480,10 @@ where continue 'outer; } }, - NestedMetaItem::Literal(lit) => { + NestedMetaItem::Literal(_, lit_span) => { handle_errors( &sess.parse_sess, - lit.span, + *lit_span, AttrError::UnsupportedLiteral( UnsupportedLiteralReason::Generic, false, @@ -654,11 +654,11 @@ pub fn eval_condition( ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => { try_gate_cfg(sym::version, cfg.span, sess, features); let (min_version, span) = match &mis[..] { - [NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => { - (sym, span) + [NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), .. }, lit_span)] => { + (sym, lit_span) } [ - NestedMetaItem::Literal(Lit { span, .. }) + NestedMetaItem::Literal(_, span) | NestedMetaItem::MetaItem(MetaItem { span, .. }), ] => { sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); @@ -755,10 +755,10 @@ pub fn eval_condition( sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); true } - MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => { + MetaItemKind::NameValue(ref lit, lit_span) if !lit.kind.is_str() => { handle_errors( sess, - lit.span, + lit_span, AttrError::UnsupportedLiteral( UnsupportedLiteralReason::CfgString, lit.kind.is_bytestr(), @@ -834,10 +834,10 @@ where *item = Some(v); true } else { - if let Some(lit) = meta.name_value_literal() { + if let Some((lit, lit_span)) = meta.name_value_literal_and_span() { handle_errors( &sess.parse_sess, - lit.span, + lit_span, AttrError::UnsupportedLiteral( UnsupportedLiteralReason::DeprecatedString, lit.kind.is_bytestr(), @@ -895,10 +895,10 @@ where continue 'outer; } }, - NestedMetaItem::Literal(lit) => { + NestedMetaItem::Literal(_, lit_span) => { handle_errors( &sess.parse_sess, - lit.span, + *lit_span, AttrError::UnsupportedLiteral( UnsupportedLiteralReason::DeprecatedKvPair, false, @@ -1032,7 +1032,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { }); } } else if let Some(meta_item) = item.meta_item() { - if let MetaItemKind::NameValue(ref value) = meta_item.kind { + if let MetaItemKind::NameValue(ref value, _) = meta_item.kind { if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { let name = meta_item.name_or_empty().to_ident_string(); recognised = true; diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index a1051d990b14b..9b405e0486860 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -457,7 +457,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { break; } - let span = opt_lit.map_or(p.token.span, |lit| lit.span); + let span = opt_lit.map_or(p.token.span, |(_lit, span)| span); let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal"); err.span_label(span, "not a string literal"); diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 467ac34ded942..c502499fb19cf 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -46,9 +46,9 @@ impl MultiItemModifier for Expander { .into_iter() .filter_map(|nested_meta| match nested_meta { NestedMetaItem::MetaItem(meta) => Some(meta), - NestedMetaItem::Literal(lit) => { + NestedMetaItem::Literal(lit, lit_span) => { // Reject `#[derive("Debug")]`. - report_unexpected_literal(sess, &lit); + report_unexpected_literal(sess, &lit, lit_span); None } }) @@ -125,15 +125,15 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool { bad_target } -fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) { +fn report_unexpected_literal(sess: &Session, lit: &ast::Lit, span: Span) { let help_msg = match lit.token_lit.kind { token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => { format!("try using `#[derive({})]`", lit.token_lit.symbol) } _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(), }; - struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal",) - .span_label(lit.span, "not a trait") + struct_span_err!(sess, span, E0777, "expected path to a trait, found literal",) + .span_label(span, "not a trait") .help(&help_msg) .emit(); } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 2bb522caa2d41..5ccc508a833c8 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1218,7 +1218,7 @@ pub fn expr_to_spanned_string<'a>( ast::ExprKind::Lit(ref l) => match l.kind { ast::LitKind::Str(s, style) => return Ok((s, style, expr.span)), ast::LitKind::ByteStr(_) => { - let mut err = cx.struct_span_err(l.span, err_msg); + let mut err = cx.struct_span_err(expr.span, err_msg); err.span_suggestion( expr.span.shrink_to_lo(), "consider removing the leading `b`", @@ -1228,7 +1228,7 @@ pub fn expr_to_spanned_string<'a>( Some((err, true)) } ast::LitKind::Err => None, - _ => Some((cx.struct_span_err(l.span, err_msg), false)), + _ => Some((cx.struct_span_err(expr.span, err_msg), false)), }, ast::ExprKind::Err => None, _ => Some((cx.struct_span_err(expr.span, err_msg), false)), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index cf2c023c2f89f..ee78a44335fec 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -330,7 +330,7 @@ impl<'a> ExtCtxt<'a> { } fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { - let lit = ast::Lit::from_lit_kind(lit_kind, span); + let lit = ast::Lit::from_lit_kind(lit_kind); self.expr(span, ast::ExprKind::Lit(lit)) } diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 59a7b668a83ce..96cabc54c375c 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -502,11 +502,11 @@ impl server::TokenStream for Rustc<'_, '_> { ast::ExprKind::Lit(l) if l.token_lit.kind == token::Bool => { Ok(tokenstream::TokenStream::token_alone( token::Ident(l.token_lit.symbol, false), - l.span, + expr.span, )) } ast::ExprKind::Lit(l) => { - Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token_lit), l.span)) + Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token_lit), expr.span)) } ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind { ast::ExprKind::Lit(l) => match l.token_lit { @@ -517,7 +517,7 @@ impl server::TokenStream for Rustc<'_, '_> { tokenstream::TokenTree::token_alone(token::BinOp(token::Minus), e.span), tokenstream::TokenTree::token_alone( token::Literal(l.token_lit), - l.span, + e.span, ), ])) } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 949bd02ad6839..133e0790ad588 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -109,7 +109,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option {} - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { + MetaItemKind::NameValue(lit, _) if !lit.kind.is_str() => { error!("argument value must be a string"); } MetaItemKind::NameValue(..) | MetaItemKind::Word => { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f7e70d355cf86..31e063e4a8e6a 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -473,8 +473,7 @@ pub(crate) fn check_attr_crate_type( return; } - if let ast::MetaItemKind::NameValue(spanned) = a.meta_kind().unwrap() { - let span = spanned.span; + if let ast::MetaItemKind::NameValue(_lit, lit_span) = a.meta_kind().unwrap() { let lev_candidate = find_best_match_for_name( &CRATE_TYPES.iter().map(|(k, _)| *k).collect::>(), n, @@ -484,10 +483,10 @@ pub(crate) fn check_attr_crate_type( lint_buffer.buffer_lint_with_diagnostic( lint::builtin::UNKNOWN_CRATE_TYPES, ast::CRATE_NODE_ID, - span, + lit_span, "invalid `crate_type` value", BuiltinLintDiagnostics::UnknownCrateTypes( - span, + lit_span, "did you mean".to_string(), format!("\"{}\"", candidate), ), @@ -496,7 +495,7 @@ pub(crate) fn check_attr_crate_type( lint_buffer.buffer_lint( lint::builtin::UNKNOWN_CRATE_TYPES, ast::CRATE_NODE_ID, - span, + lit_span, "invalid `crate_type` value", ); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f06bfa912ca53..06bff00b25d31 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -99,9 +99,10 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { impl EarlyLintPass for WhileTrue { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::While(cond, _, label) = &e.kind { - if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind { + let pierced_expr = pierce_parens(cond); + if let ast::ExprKind::Lit(ref lit) = pierced_expr.kind { if let ast::LitKind::Bool(true) = lit.kind { - if !lit.span.from_expansion() { + if !pierced_expr.span.from_expansion() { let condition_span = e.span.with_hi(cond.span.hi()); cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| { lint.build(fluent::lint::builtin_while_true) diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs index 8f22221324a6e..4cc66ce9378be 100644 --- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs +++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs @@ -119,8 +119,8 @@ impl EarlyLintPass for HiddenUnicodeCodepoints { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { // byte strings are already handled well enough by `EscapeError::NonAsciiCharInByteString` - let (text, span, padding) = match &expr.kind { - ast::ExprKind::Lit(ast::Lit { token_lit, kind, span }) => { + let (text, padding) = match &expr.kind { + ast::ExprKind::Lit(ast::Lit { token_lit, kind }) => { let text = token_lit.symbol; if !contains_text_flow_control_chars(text.as_str()) { return; @@ -132,10 +132,10 @@ impl EarlyLintPass for HiddenUnicodeCodepoints { ast::LitKind::Str(_, ast::StrStyle::Raw(val)) => *val as u32 + 2, _ => return, }; - (text, span, padding) + (text, padding) } _ => return, }; - self.lint_text_direction_codepoint(cx, text, *span, padding, true, "literal"); + self.lint_text_direction_codepoint(cx, text, expr.span, padding, true, "literal"); } } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index f1d8ef2e47d31..5e4b02dcac131 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -316,7 +316,7 @@ impl<'s> LintLevelsBuilder<'s> { if let Some(item) = tail_li.meta_item() { match item.kind { ast::MetaItemKind::Word => {} // actual lint names handled later - ast::MetaItemKind::NameValue(ref name_value) => { + ast::MetaItemKind::NameValue(ref name_value, name_value_span) => { if item.path == sym::reason { if let ast::LitKind::Str(rationale, _) = name_value.kind { if !self.sess.features_untracked().lint_reasons { @@ -331,9 +331,9 @@ impl<'s> LintLevelsBuilder<'s> { reason = Some(rationale); } else { sess.emit_err(MalformedAttribute { - span: name_value.span, + span: name_value_span, sub: MalformedAttributeSub::ReasonMustBeStringLiteral( - name_value.span, + name_value_span, ), }); } @@ -369,7 +369,7 @@ impl<'s> LintLevelsBuilder<'s> { ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item, _ => { if let Some(item) = li.meta_item() { - if let ast::MetaItemKind::NameValue(_) = item.kind { + if let ast::MetaItemKind::NameValue(..) = item.kind { if item.path == sym::reason { sess.emit_err(MalformedAttribute { span: sp, diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 2868aabfa07e2..728173ed20b4b 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -345,13 +345,13 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { .find_by_name(&cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) .and_then(|attr| attr.meta()) .and_then(|meta| { - meta.name_value_literal().and_then(|lit| { + meta.name_value_literal_and_span().and_then(|(lit, lit_span)| { if let ast::LitKind::Str(name, ..) = lit.kind { // Discard the double quotes surrounding the literal. let sp = cx .sess() .source_map() - .span_to_snippet(lit.span) + .span_to_snippet(lit_span) .ok() .and_then(|snippet| { let left = snippet.find('"')?; @@ -359,12 +359,12 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { snippet.rfind('"').map(|pos| snippet.len() - pos)?; Some( - lit.span - .with_lo(lit.span.lo() + BytePos(left as u32 + 1)) - .with_hi(lit.span.hi() - BytePos(right as u32)), + lit_span + .with_lo(lit_span.lo() + BytePos(left as u32 + 1)) + .with_hi(lit_span.hi() - BytePos(right as u32)), ) }) - .unwrap_or(lit.span); + .unwrap_or(lit_span); Some(Ident::new(name, sp)) } else { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 262d59f8ff8a7..df2f960d8d4a3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1205,11 +1205,7 @@ impl<'tcx> TyCtxt<'tcx> { }; debug!("layout_scalar_valid_range: attr={:?}", attr); if let Some( - &[ - ast::NestedMetaItem::Literal(ast::Lit { - kind: ast::LitKind::Int(a, _), .. - }), - ], + &[ast::NestedMetaItem::Literal(ast::Lit { kind: ast::LitKind::Int(a, _), .. }, _)], ) = attr.meta_item_list().as_deref() { Bound::Included(a) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 77a6bde1c164e..95b6f2ce6cb30 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -319,12 +319,12 @@ impl<'a> Parser<'a> { Ok(attrs) } - pub(crate) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> { - let lit = self.parse_lit()?; + pub(crate) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, (ast::Lit, Span)> { + let (lit, lit_span) = self.parse_lit()?; debug!("checking if {:?} is unusuffixed", lit); if !lit.kind.is_unsuffixed() { - self.struct_span_err(lit.span, "suffixed literals are not allowed in attributes") + self.struct_span_err(lit_span, "suffixed literals are not allowed in attributes") .help( "instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \ use an unsuffixed version (`1`, `1.0`, etc.)", @@ -332,7 +332,7 @@ impl<'a> Parser<'a> { .emit(); } - Ok(lit) + Ok((lit, lit_span)) } /// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited. @@ -400,7 +400,8 @@ impl<'a> Parser<'a> { pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { Ok(if self.eat(&token::Eq) { - ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?) + let (lit, lit_span) = self.parse_unsuffixed_lit()?; + ast::MetaItemKind::NameValue(lit, lit_span) } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Matches `meta_seq = ( COMMASEP(meta_item_inner) )`. let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?; @@ -413,7 +414,7 @@ impl<'a> Parser<'a> { /// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`. fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> { match self.parse_unsuffixed_lit() { - Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)), + Ok((lit, lit_span)) => return Ok(ast::NestedMetaItem::Literal(lit, lit_span)), Err(err) => err.cancel(), } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7addf519872f0..eaaae8e1e6d01 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1402,7 +1402,7 @@ impl<'a> Parser<'a> { fn parse_lit_expr(&mut self) -> PResult<'a, P> { let lo = self.token.span; match self.parse_opt_lit() { - Some(literal) => { + Some((literal, _)) => { let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal)); self.maybe_recover_from_bad_qpath(expr) } @@ -1718,23 +1718,23 @@ impl<'a> Parser<'a> { /// Returns a string literal if the next token is a string literal. /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind, /// and returns `None` if the next token is not literal at all. - pub fn parse_str_lit(&mut self) -> Result> { + pub fn parse_str_lit(&mut self) -> Result> { match self.parse_opt_lit() { - Some(lit) => match lit.kind { + Some((lit, span)) => match lit.kind { ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit { style, symbol: lit.token_lit.symbol, suffix: lit.token_lit.suffix, - span: lit.span, + span: span, symbol_unescaped, }), - _ => Err(Some(lit)), + _ => Err(Some((lit, span))), }, None => Err(None), } } - pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> { + pub(super) fn parse_lit(&mut self) -> PResult<'a, (Lit, Span)> { self.parse_opt_lit().ok_or_else(|| { if let token::Interpolated(inner) = &self.token.kind { let expr = match inner.as_ref() { @@ -1759,7 +1759,7 @@ impl<'a> Parser<'a> { /// Matches `lit = true | false | token_lit`. /// Returns `None` if the next token is not a literal. - pub(super) fn parse_opt_lit(&mut self) -> Option { + pub(super) fn parse_opt_lit(&mut self) -> Option<(Lit, Span)> { let mut recovered = None; if self.token == token::Dot { // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where @@ -1784,9 +1784,9 @@ impl<'a> Parser<'a> { let token = recovered.as_ref().unwrap_or(&self.token); match Lit::from_token(token) { - Ok(lit) => { + Ok((lit, span)) => { self.bump(); - Some(lit) + Some((lit, span)) } Err(LitError::NotLiteral) => None, Err(err) => { @@ -1801,7 +1801,7 @@ impl<'a> Parser<'a> { let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None); let symbol = Symbol::intern(&suffixless_lit.to_string()); let lit = token::Lit::new(token::Err, symbol, lit.suffix); - Some(Lit::from_token_lit(lit, span).unwrap_or_else(|_| unreachable!())) + Some((Lit::from_token_lit(lit).unwrap_or_else(|_| unreachable!()), span)) } } } @@ -1929,8 +1929,8 @@ impl<'a> Parser<'a> { let lo = self.token.span; let minus_present = self.eat(&token::BinOp(token::Minus)); - let lit = self.parse_lit()?; - let expr = self.mk_expr(lit.span, ExprKind::Lit(lit)); + let (lit, span) = self.parse_lit()?; + let expr = self.mk_expr(span, ExprKind::Lit(lit)); if minus_present { Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_unary(UnOp::Neg, expr))) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 5c8f374255c7f..da4a9da186c43 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1381,12 +1381,12 @@ impl<'a> Parser<'a> { fn parse_abi(&mut self) -> Option { match self.parse_str_lit() { Ok(str_lit) => Some(str_lit), - Err(Some(lit)) => match lit.kind { + Err(Some((lit, span))) => match lit.kind { ast::LitKind::Err => None, _ => { - self.struct_span_err(lit.span, "non-string ABI literal") + self.struct_span_err(span, "non-string ABI literal") .span_suggestion( - lit.span, + span, "specify the ABI with a string literal", "\"C\"", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 47477898b240e..752644808693d 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -52,7 +52,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta if let ast::ExprKind::Lit(lit) = &expr.kind { if !lit.kind.is_unsuffixed() { let mut err = sess.span_diagnostic.struct_span_err( - lit.span, + expr.span, "suffixed literals are not allowed in attributes", ); err.help( @@ -61,7 +61,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta ); return Err(err); } else { - MetaItemKind::NameValue(lit.clone()) + MetaItemKind::NameValue(lit.clone(), expr.span) } } else { // The non-error case can happen with e.g. `#[foo = 1+1]`. The error case can @@ -76,7 +76,9 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta return Err(err); } } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), + MacArgs::Eq(_, MacArgsEq::Hir(lit, lit_span)) => { + MetaItemKind::NameValue(lit.clone(), *lit_span) + } }, }) } @@ -101,7 +103,7 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte match meta { MetaItemKind::Word => template.word, MetaItemKind::List(..) => template.list.is_some(), - MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(), + MetaItemKind::NameValue(lit, _) if lit.kind.is_str() => template.name_value_str.is_some(), MetaItemKind::NameValue(..) => false, } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a63af4159e8cb..84e57d2338379 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1327,7 +1327,7 @@ impl CheckAttrVisitor<'_> { return false; }; - if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) { + if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. }, _)]) { true } else { self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span }); @@ -1995,7 +1995,7 @@ impl CheckAttrVisitor<'_> { ) && let Some(meta) = attr.meta_item_list() && meta.len() == 1 && let Some(item) = meta[0].meta_item() - && let MetaItemKind::NameValue(_) = &item.kind + && let MetaItemKind::NameValue(..) = &item.kind && item.path == sym::reason { errors::UnusedNote::NoLints { name: attr.name_or_empty() } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 6236ad370df60..34fece0dd8d00 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -3126,7 +3126,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { InlineAttr::None } } - Some(MetaItemKind::NameValue(_)) => ia, + Some(MetaItemKind::NameValue(..)) => ia, None => ia, } }); @@ -3155,7 +3155,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { OptimizeAttr::None } } - Some(MetaItemKind::NameValue(_)) => ia, + Some(MetaItemKind::NameValue(..)) => ia, None => ia, } }); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index f33f5d27d1a9f..5f8557c3d45a0 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -50,8 +50,8 @@ impl Cfg { ) -> Result, InvalidCfgError> { match nested_cfg { NestedMetaItem::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude), - NestedMetaItem::Literal(ref lit) => { - Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) + NestedMetaItem::Literal(_, lit_span) => { + Err(InvalidCfgError { msg: "unexpected literal", span: *lit_span }) } } } @@ -74,7 +74,7 @@ impl Cfg { let cfg = Cfg::Cfg(name, None); if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) } } - MetaItemKind::NameValue(ref lit) => match lit.kind { + MetaItemKind::NameValue(ref lit, lit_span) => match lit.kind { LitKind::Str(value, _) => { let cfg = Cfg::Cfg(name, Some(value)); if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) } @@ -83,7 +83,7 @@ impl Cfg { // FIXME: if the main #[cfg] syntax decided to support non-string literals, // this should be changed as well. msg: "value of cfg option should be a string literal", - span: lit.span, + span: lit_span, }), }, MetaItemKind::List(ref items) => { diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 4bcbeacf9feb5..10ec0c882d64e 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -318,7 +318,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { for item in items { if_chain! { if let NestedMetaItem::MetaItem(mi) = &item; - if let MetaItemKind::NameValue(lit) = &mi.kind; + if let MetaItemKind::NameValue(lit, _) = &mi.kind; if mi.has_name(sym::since); then { check_semver(cx, item.span(), lit); @@ -457,7 +457,7 @@ fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem // Check if the reason is present if let Some(item) = items.last().and_then(NestedMetaItem::meta_item) - && let MetaItemKind::NameValue(_) = &item.kind + && let MetaItemKind::NameValue(..) = &item.kind && item.path == sym::reason { return; diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs index fb2104861c87f..208ed6061997e 100644 --- a/src/tools/clippy/clippy_lints/src/literal_representation.rs +++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs @@ -10,6 +10,7 @@ use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::Span; use std::iter; declare_clippy_lint! { @@ -237,7 +238,7 @@ impl EarlyLintPass for LiteralDigitGrouping { } if let ExprKind::Lit(ref lit) = expr.kind { - self.check_lit(cx, lit); + self.check_lit(cx, lit, expr.span); } } } @@ -252,12 +253,12 @@ impl LiteralDigitGrouping { } } - fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) { + fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit, span: Span) { if_chain! { - if let Some(src) = snippet_opt(cx, lit.span); + if let Some(src) = snippet_opt(cx, span); if let Some(mut num_lit) = NumericLiteral::from_lit(&src, lit); then { - if !Self::check_for_mistyped_suffix(cx, lit.span, &mut num_lit) { + if !Self::check_for_mistyped_suffix(cx, span, &mut num_lit) { return; } @@ -293,14 +294,14 @@ impl LiteralDigitGrouping { | WarningType::InconsistentDigitGrouping | WarningType::UnusualByteGroupings | WarningType::LargeDigitGroups => { - !lit.span.from_expansion() + !span.from_expansion() } WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => { true } }; if should_warn { - warning_type.display(num_lit.format(), cx, lit.span); + warning_type.display(num_lit.format(), cx, span); } } } @@ -459,7 +460,7 @@ impl EarlyLintPass for DecimalLiteralRepresentation { } if let ExprKind::Lit(ref lit) = expr.kind { - self.check_lit(cx, lit); + self.check_lit(cx, lit, expr.span); } } } @@ -469,11 +470,11 @@ impl DecimalLiteralRepresentation { pub fn new(threshold: u64) -> Self { Self { threshold } } - fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) { + fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit, span: Span) { // Lint integral literals. if_chain! { if let LitKind::Int(val, _) = lit.kind; - if let Some(src) = snippet_opt(cx, lit.span); + if let Some(src) = snippet_opt(cx, span); if let Some(num_lit) = NumericLiteral::from_lit(&src, lit); if num_lit.radix == Radix::Decimal; if val >= u128::from(self.threshold); @@ -481,7 +482,7 @@ impl DecimalLiteralRepresentation { let hex = format!("{:#X}", val); let num_lit = NumericLiteral::new(&hex, num_lit.suffix, false); let _ = Self::do_lint(num_lit.integer).map_err(|warning_type| { - warning_type.display(num_lit.format(), cx, lit.span); + warning_type.display(num_lit.format(), cx, span); }); } } diff --git a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs index 1165c19a0cf0b..c906dbd2ccce8 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs @@ -1,11 +1,17 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_ast::ast::Lit; use rustc_errors::Applicability; use rustc_lint::EarlyContext; +use rustc_span::Span; use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX}; -pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) { +pub(super) fn check( + cx: &EarlyContext<'_>, + lit_span: Span, + lit_snip: &str, + suffix: &str, + sugg_type: &str +) { let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) { val } else { @@ -17,7 +23,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s span_lint_and_sugg( cx, SEPARATED_LITERAL_SUFFIX, - lit.span, + lit_span, &format!("{} type suffix should not be separated by an underscore", sugg_type), "remove the underscore", format!("{}{}", &lit_snip[..maybe_last_sep_idx], suffix), @@ -27,7 +33,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s span_lint_and_sugg( cx, UNSEPARATED_LITERAL_SUFFIX, - lit.span, + lit_span, &format!("{} type suffix should be separated by an underscore", sugg_type), "add an underscore", format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix), diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs index 80e2421310078..283f6990955f4 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint; -use rustc_ast::ast::Lit; use rustc_lint::EarlyContext; +use rustc_span::Span; use super::MIXED_CASE_HEX_LITERALS; -pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &str) { +pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_snip: &str) { let maybe_last_sep_idx = if let Some(val) = lit_snip.len().checked_sub(suffix.len() + 1) { val } else { @@ -25,7 +25,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &s span_lint( cx, MIXED_CASE_HEX_LITERALS, - lit.span, + lit_span, "inconsistent casing in hexadecimal literal", ); break; diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs index 704918c0b979b..2b5db6e4bf143 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs @@ -376,20 +376,20 @@ impl EarlyLintPass for MiscEarlyLints { } if let ExprKind::Lit(ref lit) = expr.kind { - MiscEarlyLints::check_lit(cx, lit); + MiscEarlyLints::check_lit(cx, lit, expr.span); } double_neg::check(cx, expr); } } impl MiscEarlyLints { - fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) { + fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span) { // We test if first character in snippet is a number, because the snippet could be an expansion // from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`. // Note that this check also covers special case that `line!()` is eagerly expanded by compiler. // See for a regression. // FIXME: Find a better way to detect those cases. - let lit_snip = match snippet_opt(cx, lit.span) { + let lit_snip = match snippet_opt(cx, span) { Some(snip) if snip.chars().next().map_or(false, |c| c.is_ascii_digit()) => snip, _ => return, }; @@ -400,17 +400,17 @@ impl MiscEarlyLints { LitIntType::Unsigned(ty) => ty.name_str(), LitIntType::Unsuffixed => "", }; - literal_suffix::check(cx, lit, &lit_snip, suffix, "integer"); + literal_suffix::check(cx, span, &lit_snip, suffix, "integer"); if lit_snip.starts_with("0x") { - mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip); + mixed_case_hex_literals::check(cx, span, suffix, &lit_snip); } else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") { // nothing to do } else if value != 0 && lit_snip.starts_with('0') { - zero_prefixed_literal::check(cx, lit, &lit_snip); + zero_prefixed_literal::check(cx, span, &lit_snip); } } else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind { let suffix = float_ty.name_str(); - literal_suffix::check(cx, lit, &lit_snip, suffix, "float"); + literal_suffix::check(cx, span, &lit_snip, suffix, "float"); } } } diff --git a/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs b/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs index 4963bba82f2da..660b8d013bea2 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs @@ -1,25 +1,25 @@ use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::ast::Lit; use rustc_errors::Applicability; use rustc_lint::EarlyContext; +use rustc_span::Span; use super::ZERO_PREFIXED_LITERAL; -pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str) { +pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) { span_lint_and_then( cx, ZERO_PREFIXED_LITERAL, - lit.span, + lit_span, "this is a decimal constant", |diag| { diag.span_suggestion( - lit.span, + lit_span, "if you mean to use a decimal constant, remove the `0` to avoid confusion", lit_snip.trim_start_matches(|c| c == '_' || c == '0').to_string(), Applicability::MaybeIncorrect, ); diag.span_suggestion( - lit.span, + lit_span, "if you mean to use an octal constant, use `0o`", format!("0o{}", lit_snip.trim_start_matches(|c| c == '_' || c == '0')), Applicability::MaybeIncorrect, diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs index bffbf20b4d289..6463b2a58b663 100644 --- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs +++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs @@ -58,9 +58,9 @@ impl EarlyLintPass for OctalEscapes { if let ExprKind::Lit(lit) = &expr.kind { if matches!(lit.token_lit.kind, LitKind::Str) { - check_lit(cx, &lit.token_lit, lit.span, true); + check_lit(cx, &lit.token_lit, expr.span, true); } else if matches!(lit.token_lit.kind, LitKind::ByteStr) { - check_lit(cx, &lit.token_lit, lit.span, false); + check_lit(cx, &lit.token_lit, expr.span, false); } } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 493991f30e872..cd07a63ddf1b7 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -706,7 +706,7 @@ pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool { (Empty, Empty) => true, (Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts), (Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re), - (Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind, + (Eq(_, MacArgsEq::Hir(ll, _)), Eq(_, MacArgsEq::Hir(rl, _))) => ll.kind == rl.kind, _ => false, } } diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index f5c1ee5fdd121..fb8e53635c55c 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -259,8 +259,10 @@ fn rewrite_initial_doc_comments( impl Rewrite for ast::NestedMetaItem { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match self { - ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape), - ast::NestedMetaItem::Literal(ref l) => rewrite_literal(context, l, shape), + ast::NestedMetaItem::MetaItem(meta_item) => meta_item.rewrite(context, shape), + ast::NestedMetaItem::Literal(lit, lit_span) => { + rewrite_literal(context, lit, *lit_span, shape) + } } } } @@ -308,7 +310,7 @@ impl Rewrite for ast::MetaItem { }), )? } - ast::MetaItemKind::NameValue(ref literal) => { + ast::MetaItemKind::NameValue(ref lit, lit_span) => { let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?; // 3 = ` = ` let lit_shape = shape.shrink_left(path.len() + 3)?; @@ -318,8 +320,8 @@ impl Rewrite for ast::MetaItem { // we might be better off ignoring the fact that the attribute // is longer than the max width and continue on formatting. // See #2479 for example. - let value = rewrite_literal(context, literal, lit_shape) - .unwrap_or_else(|| context.snippet(literal.span).to_owned()); + let value = rewrite_literal(context, lit, lit_span, lit_shape) + .unwrap_or_else(|| context.snippet(lit_span).to_owned()); format!("{} = {}", path, value) } }) @@ -509,7 +511,7 @@ pub(crate) trait MetaVisitor<'ast> { match meta_item.kind { ast::MetaItemKind::Word => self.visit_meta_word(meta_item), ast::MetaItemKind::List(ref list) => self.visit_meta_list(meta_item, list), - ast::MetaItemKind::NameValue(ref lit) => self.visit_meta_name_value(meta_item, lit), + ast::MetaItemKind::NameValue(ref lit, _) => self.visit_meta_name_value(meta_item, lit), } } @@ -530,7 +532,7 @@ pub(crate) trait MetaVisitor<'ast> { fn visit_nested_meta_item(&mut self, nm: &'ast ast::NestedMetaItem) { match nm { ast::NestedMetaItem::MetaItem(ref meta_item) => self.visit_meta_item(meta_item), - ast::NestedMetaItem::Literal(ref lit) => self.visit_literal(lit), + ast::NestedMetaItem::Literal(ref lit, _) => self.visit_literal(lit), } } diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 3105882e2d308..f2b76fe1c1bc6 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -76,11 +76,11 @@ pub(crate) fn format_expr( None, ), ast::ExprKind::Lit(ref l) => { - if let Some(expr_rw) = rewrite_literal(context, l, shape) { + if let Some(expr_rw) = rewrite_literal(context, l, expr.span, shape) { Some(expr_rw) } else { if let LitKind::StrRaw(_) = l.token_lit.kind { - Some(context.snippet(l.span).trim().into()) + Some(context.snippet(expr.span).trim().into()) } else { None } @@ -276,7 +276,7 @@ pub(crate) fn format_expr( match lhs.kind { ast::ExprKind::Lit(ref lit) => match lit.kind { ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => { - context.snippet(lit.span).ends_with('.') + context.snippet(lhs.span).ends_with('.') } _ => false, }, @@ -1184,14 +1184,15 @@ pub(crate) fn is_unsafe_block(block: &ast::Block) -> bool { pub(crate) fn rewrite_literal( context: &RewriteContext<'_>, - l: &ast::Lit, + lit: &ast::Lit, + span: Span, shape: Shape, ) -> Option { - match l.kind { - ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape), - ast::LitKind::Int(..) => rewrite_int_lit(context, l, shape), + match lit.kind { + ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, span, shape), + ast::LitKind::Int(..) => rewrite_int_lit(context, lit, span, shape), _ => wrap_str( - context.snippet(l.span).to_owned(), + context.snippet(span).to_owned(), context.config.max_width(), shape, ), @@ -1224,8 +1225,12 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> ) } -fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option { - let span = lit.span; +fn rewrite_int_lit( + context: &RewriteContext<'_>, + lit: &ast::Lit, + span: Span, + shape: Shape, +) -> Option { let symbol = lit.token_lit.symbol.as_str(); if let Some(symbol_stripped) = symbol.strip_prefix("0x") { diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index cd852855602e8..01f57f08c2d7a 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -263,7 +263,7 @@ fn is_skip(meta_item: &MetaItem) -> bool { fn is_skip_nested(meta_item: &NestedMetaItem) -> bool { match meta_item { NestedMetaItem::MetaItem(ref mi) => is_skip(mi), - NestedMetaItem::Literal(_) => false, + NestedMetaItem::Literal(..) => false, } }