rustc_attr_parsing: add AcceptContext::expect_string_literal

This commit is contained in:
Sasha Pourcelot
2026-05-08 19:10:24 +00:00
parent 9097f5b67a
commit dcdba78e7e
23 changed files with 116 additions and 177 deletions
+1 -1
View File
@@ -845,7 +845,7 @@ pub fn list_contains_name(items: &[MetaItemInner], name: Symbol) -> bool {
}
impl MetaItemLit {
pub fn value_str(&self) -> Option<Symbol> {
pub fn value_as_str(&self) -> Option<Symbol> {
LitKind::from_token_lit(self.as_token_lit()).ok().and_then(|lit| lit.str())
}
}
@@ -135,12 +135,12 @@ fn parse_cfg_entry_version(
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
);
};
let Some(version_lit) = version.lit() else {
let Some(version_lit) = version.as_lit() else {
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version.span() })
);
};
let Some(version_str) = version_lit.value_str() else {
let Some(version_str) = version_lit.value_as_str() else {
return Err(
cx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: version_lit.span })
);
@@ -13,10 +13,7 @@ impl SingleAttributeParser for CfiEncodingParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::cfi_encoding))?;
let Some(value_str) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(name_value.value_span, None);
return None;
};
let value_str = cx.expect_string_literal(name_value)?;
if value_str.as_str().trim().is_empty() {
cx.adcx().expected_non_empty_string_literal(name_value.value_span);
@@ -119,10 +119,7 @@ impl SingleAttributeParser for ExportNameParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
if name.as_str().contains('\0') {
// `#[export_name = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters.
@@ -478,8 +475,7 @@ fn parse_tf_attribute(
}
// Use value
let Some(value_str) = value.value_as_str() else {
cx.adcx().expected_string_literal(value.value_span, Some(value.value_as_lit()));
let Some(value_str) = cx.expect_string_literal(value) else {
return features;
};
for feature in value_str.as_str().split(",") {
@@ -19,10 +19,7 @@ impl AttributeParser for ConfusablesParser {
}
for param in list.mixed() {
let span = param.span();
let Some(lit) = param.lit().and_then(|i| i.value_str()) else {
cx.adcx().expected_string_literal(span, param.lit());
let Some(lit) = cx.expect_string_literal(param) else {
continue;
};
@@ -17,10 +17,7 @@ impl SingleAttributeParser for CrateNameParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let n = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = n.value_as_str() else {
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(n)?;
Some(AttributeKind::CrateName { name, name_span: n.value_span, attr_span: cx.attr_span })
}
@@ -44,10 +41,7 @@ fn extend(
) -> impl IntoIterator<Item = Self::Item> {
let n = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(crate_type) = n.value_as_str() else {
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
return None;
};
let crate_type = cx.expect_string_literal(n)?;
let Ok(crate_type) = crate_type.try_into() else {
// We don't error on invalid `#![crate_type]` when not applied to a crate
@@ -34,10 +34,7 @@ fn extend(
}
};
let Some(path) = args.value_as_str() else {
cx.adcx().expected_string_literal(args.value_span, Some(args.value_as_lit()));
return None;
};
let path = cx.expect_string_literal(args)?;
Some(DebugVisualizer { span: ident.span.to(args.value_span), visualizer_type, path })
}
@@ -255,8 +255,7 @@ fn parse_alias(
}
ArgParser::List(list) => {
for i in list.mixed() {
let Some(alias) = i.lit().and_then(|i| i.value_str()) else {
cx.adcx().expected_string_literal(i.span(), i.lit());
let Some(alias) = cx.expect_string_literal(i) else {
continue;
};
@@ -264,8 +263,7 @@ fn parse_alias(
}
}
ArgParser::NameValue(nv) => {
let Some(alias) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let Some(alias) = cx.expect_string_literal(nv) else {
return;
};
self.add_alias(cx, alias, nv.value_span);
@@ -77,21 +77,11 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
ArgParser::List(list) => {
let l = cx.expect_single(list)?;
let Some(reason) = l.lit().and_then(|i| i.kind.str()) else {
cx.adcx().expected_string_literal(l.span(), l.lit());
return None;
};
Some(reason)
}
ArgParser::NameValue(v) => {
let Some(reason) = v.value_as_str() else {
cx.adcx().expected_string_literal(v.value_span, Some(v.value_as_lit()));
return None;
};
let reason = cx.expect_string_literal(l)?;
Some(reason)
}
ArgParser::NameValue(v) => cx.expect_string_literal(v),
};
Some(AttributeKind::Inline(
@@ -37,10 +37,7 @@ impl SingleAttributeParser for LinkNameParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
Some(LinkName { name, span: cx.attr_span })
}
@@ -260,8 +257,7 @@ fn parse_link_name(
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::name)) else {
return false;
};
let Some(link_name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.args_span(), Some(nv.value_as_lit()));
let Some(link_name) = cx.expect_string_literal(nv) else {
return false;
};
@@ -286,8 +282,7 @@ fn parse_link_kind(
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::kind)) else {
return true;
};
let Some(link_kind) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_kind) = cx.expect_string_literal(nv) else {
return true;
};
@@ -365,8 +360,7 @@ fn parse_link_modifiers(
let Some(nv) = cx.expect_name_value(item.args(), item.span(), Some(sym::modifiers)) else {
return true;
};
let Some(link_modifiers) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_modifiers) = cx.expect_string_literal(nv) else {
return true;
};
*modifiers = Some((link_modifiers, nv.value_span));
@@ -408,8 +402,7 @@ fn parse_link_wasm_import_module(
else {
return true;
};
let Some(link_wasm_import_module) = nv.value_as_str() else {
cx.adcx().expected_string_literal(item.span(), Some(nv.value_as_lit()));
let Some(link_wasm_import_module) = cx.expect_string_literal(nv) else {
return true;
};
*wasm_import_module = Some((link_wasm_import_module, item.span()));
@@ -429,8 +422,7 @@ fn parse_link_import_name_type(
else {
return true;
};
let Some(link_import_name_type) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let Some(link_import_name_type) = cx.expect_string_literal(nv) else {
return true;
};
if cx.sess().target.arch != Arch::X86 {
@@ -498,10 +490,7 @@ impl SingleAttributeParser for LinkSectionParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
if name.as_str().contains('\0') {
// `#[link_section = ...]` will be converted to a null-terminated string,
// so it may not contain any null characters.
@@ -630,9 +619,7 @@ impl SingleAttributeParser for LinkageParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::linkage))?;
let Some(value) = name_value.value_as_str() else {
cx.adcx()
.expected_string_literal(name_value.value_span, Some(name_value.value_as_lit()));
let Some(value) = cx.expect_string_literal(name_value) else {
return None;
};
@@ -14,13 +14,7 @@ impl SingleAttributeParser for MustNotSuspendParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let reason = match args {
ArgParser::NameValue(reason) => match reason.value_as_str() {
Some(val) => Some(val),
None => {
cx.adcx().expected_nv_or_no_args(reason.value_span);
return None;
}
},
ArgParser::NameValue(reason) => cx.expect_string_literal(reason),
ArgParser::NoArgs => None,
ArgParser::List(list) => {
cx.adcx().expected_nv_or_no_args(list.span);
@@ -30,16 +30,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
span: cx.attr_span,
reason: match args {
ArgParser::NoArgs => None,
ArgParser::NameValue(name_value) => {
let Some(value_str) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(
name_value.value_span,
Some(&name_value.value_as_lit()),
);
return None;
};
Some(value_str)
}
ArgParser::NameValue(name_value) => cx.expect_string_literal(name_value),
ArgParser::List(list) => {
cx.adcx().expected_nv_or_no_args(list.span);
return None;
@@ -14,10 +14,7 @@ impl SingleAttributeParser for PathParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(path) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let path = cx.expect_string_literal(nv)?;
Some(AttributeKind::Path(path))
}
@@ -74,8 +74,7 @@ fn extract_value(
return;
}
let Some(value_sym) = val.value_as_str() else {
cx.adcx().expected_string_literal(val.value_span, Some(val.value_as_lit()));
let Some(value_sym) = cx.expect_string_literal(val) else {
*failed = true;
return;
};
@@ -43,7 +43,7 @@ fn extend(
}
for param in list.mixed() {
if let Some(_) = param.lit() {
if let Some(_) = param.as_lit() {
cx.emit_err(session_diagnostics::ReprIdent { span: cx.attr_span });
continue;
}
@@ -212,7 +212,7 @@ fn parse_repr_align(
return None;
};
let Some(lit) = align.lit() else {
let Some(lit) = align.as_lit() else {
match align_kind {
Packed => {
cx.emit_err(session_diagnostics::IncorrectReprFormatPackedExpectInteger {
@@ -293,7 +293,7 @@ fn parse(&mut self, cx: &mut AcceptContext<'_, '_>, args: &ArgParser) {
return;
};
let Some(lit) = align.lit() else {
let Some(lit) = align.as_lit() else {
cx.emit_err(session_diagnostics::IncorrectReprFormatExpectInteger {
span: align.span(),
});
@@ -27,10 +27,7 @@ impl SingleAttributeParser for RustcAllocatorZeroedVariantParser {
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function");
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
Some(AttributeKind::RustcAllocatorZeroedVariant { name })
}
@@ -152,14 +152,9 @@ impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser {
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let arg = cx.expect_single_element_list(args, cx.attr_span)?;
let lint_message = cx.expect_string_literal(arg)?;
let MetaItemOrLitParser::Lit(MetaItemLit { kind: LitKind::Str(lint_message, _), .. }) = arg
else {
cx.adcx().expected_string_literal(arg.span(), arg.lit());
return None;
};
Some(AttributeKind::RustcLintOptDenyFieldAccess { lint_message: *lint_message })
Some(AttributeKind::RustcLintOptDenyFieldAccess { lint_message })
}
}
@@ -204,10 +199,7 @@ fn parse_cgu_fields(
}
};
let Some(str) = arg.value_as_str() else {
cx.adcx().expected_string_literal(arg.value_span, Some(arg.value_as_lit()));
continue;
};
let str = cx.expect_string_literal(arg)?;
if res.is_some() {
cx.adcx().duplicate_key(ident.span.to(arg.args_span()), ident.name);
@@ -324,10 +316,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
return None;
};
let Some(suggestion) = arg.value_as_str() else {
cx.adcx().expected_string_literal(arg.value_span, Some(arg.value_as_lit()));
return None;
};
let suggestion = cx.expect_string_literal(arg)?;
Some(AttributeKind::RustcDeprecatedSafe2024 { suggestion })
}
@@ -388,10 +377,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
}
};
let Some(field) = arg.value_as_str() else {
cx.adcx().expected_string_literal(arg.value_span, Some(arg.value_as_lit()));
continue;
};
let field = cx.expect_string_literal(arg)?;
if res.is_some() {
cx.adcx().duplicate_key(ident.span, ident.name);
@@ -551,10 +537,7 @@ impl SingleAttributeParser for LangParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
let Some(lang_item) = LangItem::from_name(name) else {
cx.emit_err(UnknownLangItem { span: cx.attr_span, name });
return None;
@@ -649,10 +632,7 @@ fn extend(
mi.span(),
Some(sym::borrowck_graphviz_postflow),
)?;
let Some(path) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, None);
return None;
};
let path = cx.expect_string_literal(nv)?;
let path = PathBuf::from(path.to_string());
if path.file_name().is_some() {
Some(RustcMirKind::BorrowckGraphvizPostflow { path })
@@ -757,8 +737,7 @@ fn extend(
continue;
};
let value_span = value.value_span;
let Some(value) = value.value_as_str() else {
cx.adcx().expected_string_literal(value_span, None);
let Some(value) = cx.expect_string_literal(value) else {
continue;
};
match ident.name {
@@ -983,10 +962,7 @@ impl SingleAttributeParser for RustcDiagnosticItemParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(value) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let value = cx.expect_string_literal(nv)?;
Some(AttributeKind::RustcDiagnosticItem(value))
}
}
@@ -1038,11 +1014,7 @@ impl SingleAttributeParser for RustcReservationImplParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(value_str) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let value_str = cx.expect_string_literal(nv)?;
Some(AttributeKind::RustcReservationImpl(value_str))
}
@@ -1065,11 +1037,7 @@ impl SingleAttributeParser for RustcDocPrimitiveParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
let Some(value_str) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let value_str = cx.expect_string_literal(nv)?;
Some(AttributeKind::RustcDocPrimitive(cx.attr_span, value_str))
}
@@ -105,8 +105,7 @@ impl AttributeParser for StabilityParser {
let Some(nv) = cx.expect_name_value(args, cx.attr_span, None) else {
return;
};
let Some(value_str) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
let Some(value_str) = cx.expect_string_literal(nv) else {
return;
};
this.allowed_through_unstable_modules = Some(value_str);
@@ -292,11 +291,7 @@ fn insert_value_into_option_or_error(
}
let (_ident, arg) = cx.expect_name_value(param, param.span(), Some(name.name))?;
let Some(s) = arg.value_as_str() else {
cx.adcx().expected_string_literal(arg.value_span, Some(arg.value_as_lit()));
return None;
};
let s = cx.expect_string_literal(arg)?;
*item = Some(s);
@@ -60,16 +60,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
Some(AttributeKind::ShouldPanic {
reason: match args {
ArgParser::NoArgs => None,
ArgParser::NameValue(name_value) => {
let Some(str_value) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(
name_value.value_span,
Some(name_value.value_as_lit()),
);
return None;
};
Some(str_value)
}
ArgParser::NameValue(name_value) => cx.expect_string_literal(name_value),
ArgParser::List(list) => {
let single = cx.expect_single(list)?;
let (ident, arg) =
@@ -78,11 +69,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
cx.adcx().expected_specific_argument_strings(list.span, &[sym::expected]);
return None;
}
let Some(expected) = arg.value_as_str() else {
cx.adcx().expected_string_literal(arg.value_span, Some(arg.value_as_lit()));
return None;
};
Some(expected)
cx.expect_string_literal(arg)
}
},
})
@@ -103,10 +90,7 @@ fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<Attribute
Some(sym::reexport_test_harness_main),
)?;
let Some(name) = nv.value_as_str() else {
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let name = cx.expect_string_literal(nv)?;
Some(AttributeKind::ReexportTestHarnessMain(name))
}
@@ -211,11 +195,7 @@ impl SingleAttributeParser for RustcTestMarkerParser {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::rustc_test_marker))?;
let Some(value_str) = name_value.value_as_str() else {
cx.adcx().expected_string_literal(name_value.value_span, None);
return None;
};
let value_str = cx.expect_string_literal(name_value)?;
if value_str.as_str().trim().is_empty() {
cx.adcx().expected_non_empty_string_literal(name_value.value_span);
@@ -41,7 +41,7 @@ pub(crate) fn parse_single_integer(
args: &ArgParser,
) -> Option<u128> {
let single = cx.expect_single_element_list(args, cx.attr_span)?;
let Some(lit) = single.lit() else {
let Some(lit) = single.as_lit() else {
cx.adcx().expected_integer_literal(single.span());
return None;
};
@@ -54,10 +54,7 @@ pub(crate) fn parse_single_integer(
impl AcceptContext<'_, '_> {
pub(crate) fn parse_limit_int(&mut self, nv: &NameValueParser) -> Option<Limit> {
let Some(limit) = nv.value_as_str() else {
self.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
let limit = self.expect_string_literal(nv)?;
let error_str = match limit.as_str().parse() {
Ok(i) => return Some(Limit::new(i)),
@@ -562,6 +562,13 @@ pub(crate) fn expect_name_value<'arg, Arg>(
}
/// Assert that an [`ArgParser`] has no args, or emits an error and return `None`.
///
/// This is a higher-level (and harder to misuse) wrapper over multiple
/// [`ArgParser::as_no_args`]. You may still want to use the lower-level methods for the
/// following reasons:
///
/// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
/// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.
pub(crate) fn expect_no_args<'arg>(&mut self, arg: &'arg ArgParser) -> Option<()> {
if let Err(span) = arg.as_no_args() {
self.adcx().expected_no_args(span);
@@ -570,6 +577,26 @@ pub(crate) fn expect_no_args<'arg>(&mut self, arg: &'arg ArgParser) -> Option<()
Some(())
}
/// Asserts that a node is a string literal, or emits an error and return `None`
///
/// `arg` must be a reference to any node that may contain a name-value pair, that is:
///
/// - [`NameValueParser`],
/// - [`MetaItemOrLitParser`],
///
/// This is a higher-level (and harder to misuse) wrapper over multiple `as_` methods in the
/// [`parser`][crate::parser] module. You may still want to use the lower-level methods for the
/// following reasons:
///
/// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
/// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.
pub(crate) fn expect_string_literal<'arg, Arg>(&mut self, arg: &'arg Arg) -> Option<Symbol>
where
Arg: ExpectStringLiteral,
{
arg.expect_string_literal(self)
}
}
pub(crate) trait ExpectNameValue {
@@ -649,6 +676,44 @@ fn expect_name_value<'a, 'f, 'sess>(
}
}
pub(crate) trait ExpectStringLiteral {
fn expect_string_literal<'f, 'sess>(&self, cx: &mut AcceptContext<'f, 'sess>)
-> Option<Symbol>;
}
impl ExpectStringLiteral for NameValueParser {
fn expect_string_literal<'f, 'sess>(
&self,
cx: &mut AcceptContext<'f, 'sess>,
) -> Option<Symbol> {
let value = self.value_as_str();
if value.is_none() {
cx.adcx().expected_string_literal(self.value_span, Some(self.value_as_lit()));
}
value
}
}
impl ExpectStringLiteral for MetaItemOrLitParser {
fn expect_string_literal<'f, 'sess>(
&self,
cx: &mut AcceptContext<'f, 'sess>,
) -> Option<Symbol> {
let Some(lit) = self.as_lit() else {
cx.adcx().expected_string_literal(self.span(), None);
return None;
};
let str = lit.value_as_str();
if str.is_none() {
cx.adcx().expected_string_literal(self.span(), Some(lit));
}
str
}
}
impl<'f, 'sess> Deref for AcceptContext<'f, 'sess> {
type Target = SharedContext<'f, 'sess>;
+1 -1
View File
@@ -240,7 +240,7 @@ pub fn span(&self) -> Span {
}
}
pub fn lit(&self) -> Option<&MetaItemLit> {
pub fn as_lit(&self) -> Option<&MetaItemLit> {
match self {
MetaItemOrLitParser::Lit(meta_item_lit) => Some(meta_item_lit),
MetaItemOrLitParser::MetaItemParser(_) => None,
+1 -1
View File
@@ -1340,7 +1340,7 @@ fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
#[inline]
fn value_str(&self) -> Option<Symbol> {
self.value_lit().and_then(|x| x.value_str())
self.value_lit().and_then(|x| x.value_as_str())
}
#[inline]