//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
//! - [`EnumDef`] and [`Variant`]: Enum declaration.
-//! - [`Lit`] and [`LitKind`]: Literal expressions.
+//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation.
//! - [`Attribute`]: Metadata associated with item.
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
/// A literal.
///
/// E.g., `"foo"`, `64`, `true`.
- Literal(Lit),
+ Literal(MetaItemLit),
}
/// A spanned compile-time attribute item.
/// Name value meta item.
///
/// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
- NameValue(Lit),
+ NameValue(MetaItemLit),
}
/// A block (`{ .. }`).
}
// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
-// expansion is completed, all cases end up either as a literal, which is the
-// form used after lowering to HIR, or as an error.
+// expansion is completed, all cases end up either as a meta item literal,
+// which is the form used after lowering to HIR, or as an error.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AttrArgsEq {
Ast(P<Expr>),
- Hir(Lit),
+ Hir(MetaItemLit),
}
impl AttrArgs {
Raw(u8),
}
-/// An AST literal.
+/// A literal in a meta item.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
-pub struct Lit {
+pub struct MetaItemLit {
/// The original literal token as written in source code.
pub token_lit: token::Lit,
/// The "semantic" representation of the literal lowered from the original tokens.
/// 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,
}
Unsuffixed,
}
+/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
+///
/// Note that the entire literal (including the suffix) is considered when
/// deciding the `LitKind`. This means that float literals like `1f32` are
/// classified by this type as `Float`. This is different to `token::LitKind`
static_assert_size!(Impl, 184);
static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112);
- static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72);
+ static_assert_size!(MetaItemLit, 48);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 88);
static_assert_size!(Path, 24);
use crate::ast;
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
-use crate::ast::{DelimArgs, Lit, LitKind};
+use crate::ast::{DelimArgs, LitKind, MetaItemLit};
use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
use crate::ast::{Path, PathSegment};
use crate::ptr::P;
}
}
- /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s.
- pub fn literal(&self) -> Option<&Lit> {
+ /// Returns the `MetaItemLit` if `self` is a `NestedMetaItem::Literal`s.
+ pub fn literal(&self) -> Option<&MetaItemLit> {
match self {
NestedMetaItem::Literal(lit) => Some(lit),
_ => None,
}
/// Returns a name and single literal value tuple of the `MetaItem`.
- pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> {
+ pub fn name_value_literal(&self) -> Option<(Symbol, &MetaItemLit)> {
self.meta_item().and_then(|meta_item| {
meta_item.meta_item_list().and_then(|meta_item_list| {
if meta_item_list.len() == 1
/// #[attribute(name = "value")]
/// ^^^^^^^^^^^^^^
/// ```
- pub fn name_value_literal(&self) -> Option<&Lit> {
+ pub fn name_value_literal(&self) -> Option<&MetaItemLit> {
match &self.kind {
MetaItemKind::NameValue(v) => Some(v),
_ => None,
}
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 = MetaItemLit::from_lit_kind(lit_kind, lit_span);
let span = ident.span.to(lit_span);
MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) }
}
MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees())
}
Some(TokenTree::Token(token, _)) => {
- Lit::from_token(&token).map(MetaItemKind::NameValue)
+ MetaItemLit::from_token(&token).map(MetaItemKind::NameValue)
}
_ => None,
}
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
ast::ExprKind::Lit(token_lit) => {
// Turn failures to `None`, we'll get parse errors elsewhere.
- Lit::from_token_lit(token_lit, expr.span)
+ MetaItemLit::from_token_lit(token_lit, expr.span)
.ok()
.map(|lit| MetaItemKind::NameValue(lit))
}
{
match tokens.peek() {
Some(TokenTree::Token(token, _))
- if let Some(lit) = Lit::from_token(token) =>
+ if let Some(lit) = MetaItemLit::from_token(token) =>
{
tokens.next();
return Some(NestedMetaItem::Literal(lit));
//! Code related to parsing literals.
-use crate::ast::{self, Lit, LitKind};
+use crate::ast::{self, LitKind, MetaItemLit};
use crate::token::{self, Token};
use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
use rustc_span::symbol::{kw, sym, Symbol};
}
}
-impl Lit {
- /// Converts literal token into an AST literal.
- pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> {
- Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
+impl MetaItemLit {
+ /// Converts token literal into a meta item literal.
+ pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<MetaItemLit, LitError> {
+ Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
}
- /// Converts an arbitrary token into an AST literal.
- pub fn from_token(token: &Token) -> Option<Lit> {
+ /// Converts an arbitrary token into meta item literal.
+ pub fn from_token(token: &Token) -> Option<MetaItemLit> {
token::Lit::from_token(token)
- .and_then(|token_lit| Lit::from_token_lit(token_lit, token.span).ok())
+ .and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok())
}
- /// Attempts to recover an AST literal from semantic literal.
+ /// Attempts to create a meta item literal from a `LitKind`.
/// 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, span: Span) -> MetaItemLit {
+ MetaItemLit { token_lit: kind.to_token_lit(), kind, span }
}
- /// Losslessly convert an AST literal into a token.
+ /// Losslessly convert a meta item literal into a token.
pub fn to_token(&self) -> Token {
let kind = match self.token_lit.kind {
token::Bool => token::Ident(self.token_lit.symbol, false),
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
// In valid code the value always ends up as a single literal. Otherwise, a dummy
// literal suffices because the error is handled elsewhere.
- let lit = if let ExprKind::Lit(token_lit) = expr.kind
- && let Ok(lit) = Lit::from_token_lit(token_lit, expr.span)
+ let lit = if let ExprKind::Lit(token_lit) = expr.kind
+ && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
{
lit
} else {
- Lit {
+ MetaItemLit {
token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
kind: LitKind::Err,
span: DUMMY_SP,
}
}
- fn print_literal(&mut self, lit: &ast::Lit) {
+ fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) {
self.print_token_literal(lit.token_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.meta_item_lit_to_string(lit);
self.word(token_str);
}
}
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) => self.print_meta_item_lit(lit),
}
}
self.print_path(&item.path, false, 0);
self.space();
self.word_space("=");
- self.print_literal(value);
+ self.print_meta_item_lit(value);
}
ast::MetaItemKind::List(ref items) => {
self.print_path(&item.path, false, 0);
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 meta_item_lit_to_string(&self, lit: &ast::MetaItemLit) -> String {
+ Self::to_string(|s| s.print_meta_item_lit(lit))
}
fn tt_to_string(&self, tt: &TokenTree) -> String {
//! Parsing and validation of builtin attributes
use rustc_ast as ast;
-use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId};
+use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
use rustc_ast_pretty::pprust;
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic;
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 { span, .. })
+ NestedMetaItem::Literal(MetaItemLit {
+ kind: LitKind::Str(sym, ..), span, ..
+ }),
+ ] => (sym, span),
+ [
+ NestedMetaItem::Literal(MetaItemLit { span, .. })
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
] => {
sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
NestedMetaItem::MetaItem(meta) => Some(meta),
NestedMetaItem::Literal(lit) => {
// Reject `#[derive("Debug")]`.
- report_unexpected_literal(sess, &lit);
+ report_unexpected_meta_item_lit(sess, &lit);
None
}
})
bad_target
}
-fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
+fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
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)
}
ast::ExprKind::IncludedBytes(bytes) => {
let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit();
- Ok(tokenstream::TokenStream::token_alone(
- token::TokenKind::Literal(lit),
- expr.span,
- ))
+ Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span))
}
ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {
ast::ExprKind::Lit(token_lit) => match token_lit {
}
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
- use rustc_ast::{Lit, LitIntType, LitKind};
+ use rustc_ast::{LitIntType, LitKind, MetaItemLit};
if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" {
feature_err(
&tcx.sess.parse_sess,
}
_ => None,
};
- if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list {
+ if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
+ sole_meta_list
+ {
// According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
debug!("layout_scalar_valid_range: attr={:?}", attr);
if let Some(
&[
- ast::NestedMetaItem::Literal(ast::Lit {
- kind: ast::LitKind::Int(a, _), ..
+ ast::NestedMetaItem::Literal(ast::MetaItemLit {
+ kind: ast::LitKind::Int(a, _),
+ ..
}),
],
) = attr.meta_item_list().as_deref()
Ok(attrs)
}
- pub(crate) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
- let lit = self.parse_ast_lit()?;
+ // Note: must be unsuffixed.
+ pub(crate) fn parse_unsuffixed_meta_item_lit(&mut self) -> PResult<'a, ast::MetaItemLit> {
+ let lit = self.parse_meta_item_lit()?;
debug!("checking if {:?} is unsuffixed", lit);
if !lit.kind.is_unsuffixed() {
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()?)
+ ast::MetaItemKind::NameValue(self.parse_unsuffixed_meta_item_lit()?)
} 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())?;
/// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`.
fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
- match self.parse_unsuffixed_lit() {
+ match self.parse_unsuffixed_meta_item_lit() {
Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)),
Err(err) => err.cancel(),
}
use rustc_ast::util::classify;
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
use rustc_ast::visit::Visitor;
-use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID};
+use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID};
use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
-use rustc_ast::{ClosureBinder, StmtKind};
+use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
use rustc_ast_pretty::pprust;
use rustc_errors::{
Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
&self,
lifetime: Ident,
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>,
- ) -> ast::Lit {
+ ) -> ast::MetaItemLit {
if let Some(mut diag) =
self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
{
.emit();
}
let name = lifetime.without_first_quote().name;
- ast::Lit {
+ ast::MetaItemLit {
token_lit: token::Lit::new(token::LitKind::Char, name, None),
kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
span: lifetime.span,
/// 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<ast::StrLit, Option<Lit>> {
- match self.parse_opt_ast_lit() {
+ pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<MetaItemLit>> {
+ match self.parse_opt_meta_item_lit() {
Some(lit) => match lit.kind {
ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
style,
}
}
- fn handle_missing_lit(&mut self) -> PResult<'a, Lit> {
+ fn handle_missing_lit(&mut self) -> PResult<'a, MetaItemLit> {
if let token::Interpolated(inner) = &self.token.kind {
let expr = match inner.as_ref() {
token::NtExpr(expr) => Some(expr),
.or_else(|()| self.handle_missing_lit().map(|lit| (lit.token_lit, lit.span)))
}
- pub(super) fn parse_ast_lit(&mut self) -> PResult<'a, Lit> {
- self.parse_opt_ast_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
+ pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> {
+ self.parse_opt_meta_item_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
}
fn recover_after_dot(&mut self) -> Option<Token> {
/// Matches `lit = true | false | token_lit`.
/// Returns `None` if the next token is not a literal.
- pub(super) fn parse_opt_ast_lit(&mut self) -> Option<Lit> {
+ pub(super) fn parse_opt_meta_item_lit(&mut self) -> Option<MetaItemLit> {
let recovered = self.recover_after_dot();
let token = recovered.as_ref().unwrap_or(&self.token);
match token::Lit::from_token(token) {
Some(token_lit) => {
- match Lit::from_token_lit(token_lit, token.span) {
+ match MetaItemLit::from_token_lit(token_lit, token.span) {
Ok(lit) => {
self.bump();
Some(lit)
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(
+ MetaItemLit::from_token_lit(lit, span)
+ .unwrap_or_else(|_| unreachable!()),
+ )
}
}
}
/// report error for `let 1x = 123`
pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> {
if let token::Literal(lit) = self.token.uninterpolate().kind &&
- rustc_ast::Lit::from_token(&self.token).is_none() &&
+ rustc_ast::MetaItemLit::from_token(&self.token).is_none() &&
(lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) &&
self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) {
return Err(self.sess.create_err(InvalidIdentiferStartsWithNumber { span: self.token.span }));
}
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
if let ast::ExprKind::Lit(token_lit) = expr.kind
- && let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span)
+ && let Ok(lit) = ast::MetaItemLit::from_token_lit(token_lit, expr.span)
{
if token_lit.suffix.is_some() {
let mut err = sess.span_diagnostic.struct_span_err(
self, AttrApplication, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel, ObjectLifetimeErr,
OnlyHasEffectOn, TransparentIncompatible, UnrecognizedReprHint,
};
-use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{fluent, Applicability, MultiSpan};
use rustc_expand::base::resolve_path;
return false;
};
- if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) {
+ if matches!(
+ &list[..],
+ &[NestedMetaItem::Literal(MetaItemLit { kind: LitKind::Int(..), .. })]
+ ) {
true
} else {
self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span });
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
use clippy_utils::{extract_msrv_attr, meets_msrv};
use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
use rustc_errors::Applicability;
use rustc_hir::{
Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
}
}
-fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) {
+fn check_semver(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
if let LitKind::Str(is, _) = lit.kind {
if Version::parse(is.as_str()).is_ok() {
return;
fn visit_meta_word(&mut self, _meta_item: &'ast ast::MetaItem) {}
- fn visit_meta_name_value(&mut self, _meta_item: &'ast ast::MetaItem, _lit: &'ast ast::Lit) {}
+ fn visit_meta_name_value(
+ &mut self,
+ _meta_item: &'ast ast::MetaItem,
+ _lit: &'ast ast::MetaItemLit,
+ ) {
+ }
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_meta_item_lit(lit),
}
}
- fn visit_literal(&mut self, _lit: &'ast ast::Lit) {}
+ fn visit_meta_item_lit(&mut self, _lit: &'ast ast::MetaItemLit) {}
}
}
impl<'ast> MetaVisitor<'ast> for PathVisitor {
- fn visit_meta_name_value(&mut self, meta_item: &'ast ast::MetaItem, lit: &'ast ast::Lit) {
+ fn visit_meta_name_value(
+ &mut self,
+ meta_item: &'ast ast::MetaItem,
+ lit: &'ast ast::MetaItemLit,
+ ) {
if meta_item.has_name(Symbol::intern("path")) && lit.kind.is_str() {
- self.paths.push(lit_to_str(lit));
+ self.paths.push(meta_item_lit_to_str(lit));
}
}
}
#[cfg(not(windows))]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
match lit.kind {
ast::LitKind::Str(symbol, ..) => symbol.to_string(),
_ => unreachable!(),
}
#[cfg(windows)]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
match lit.kind {
ast::LitKind::Str(symbol, ..) => symbol.as_str().replace("/", "\\"),
_ => unreachable!(),