mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-17 05:25:37 +03:00
rustc_attr_parsing: add AcceptContext::expect_string_literal
This commit is contained in:
@@ -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>;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user