Auto merge of #147842 - matthiaskrgr:rollup-b4gp4p4, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang/rust#146509 (Result/Option layout guarantee clarifications) - rust-lang/rust#147494 (std::thread spawn: Docs: Link to Builder::spawn; Make same.) - rust-lang/rust#147532 ( Port `#[cfg_attr]` to the new attribute parsing infrastructure) - rust-lang/rust#147783 (bootstrap: migrate to object 0.37) - rust-lang/rust#147792 (Fix autodiff incorrectly applying fat-lto to proc-macro crates ) - rust-lang/rust#147809 (rustdoc: Fix passes order so intra-doc links are collected after stripping passes) Failed merges: - rust-lang/rust#147813 (Warn on unused_attributes in uitests ) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -4,6 +4,8 @@ attr_parsing_as_needed_compatibility =
|
||||
attr_parsing_bundle_needs_static =
|
||||
linking modifier `bundle` is only compatible with `static` linking kind
|
||||
|
||||
attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters
|
||||
|
||||
attr_parsing_cfg_predicate_identifier =
|
||||
`cfg` predicate key must be an identifier
|
||||
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
use rustc_ast::{LitKind, NodeId};
|
||||
use rustc_ast::token::Delimiter;
|
||||
use rustc_ast::tokenstream::DelimSpan;
|
||||
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_feature::{AttributeTemplate, Features, template};
|
||||
use rustc_hir::RustcVersion;
|
||||
use rustc_hir::attrs::CfgEntry;
|
||||
use rustc_hir::{AttrPath, RustcVersion};
|
||||
use rustc_parse::parser::{ForceCollect, Parser};
|
||||
use rustc_parse::{exp, parse_in};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::ExpectedValues;
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::parse::{ParseSess, feature_err};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::context::{AcceptContext, ShouldEmit, Stage};
|
||||
use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser};
|
||||
use crate::session_diagnostics::{
|
||||
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
|
||||
};
|
||||
use crate::{
|
||||
CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, try_gate_cfg,
|
||||
AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
|
||||
try_gate_cfg,
|
||||
};
|
||||
|
||||
pub const CFG_TEMPLATE: AttributeTemplate = template!(
|
||||
@@ -21,7 +30,12 @@ pub const CFG_TEMPLATE: AttributeTemplate = template!(
|
||||
"https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute"
|
||||
);
|
||||
|
||||
pub fn parse_cfg_attr<'c, S: Stage>(
|
||||
const CFG_ATTR_TEMPLATE: AttributeTemplate = template!(
|
||||
List: &["predicate, attr1, attr2, ..."],
|
||||
"https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute"
|
||||
);
|
||||
|
||||
pub fn parse_cfg<'c, S: Stage>(
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
args: &'c ArgParser<'_>,
|
||||
) -> Option<CfgEntry> {
|
||||
@@ -70,9 +84,7 @@ pub(crate) fn parse_cfg_entry<S: Stage>(
|
||||
},
|
||||
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
|
||||
let Some(name) = meta.path().word_sym() else {
|
||||
cx.emit_err(session_diagnostics::CfgPredicateIdentifier {
|
||||
span: meta.path().span(),
|
||||
});
|
||||
cx.expected_identifier(meta.path().span());
|
||||
return None;
|
||||
};
|
||||
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
|
||||
@@ -81,7 +93,7 @@ pub(crate) fn parse_cfg_entry<S: Stage>(
|
||||
MetaItemOrLitParser::Lit(lit) => match lit.kind {
|
||||
LitKind::Bool(b) => CfgEntry::Bool(b, lit.span),
|
||||
_ => {
|
||||
cx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: lit.span });
|
||||
cx.expected_identifier(lit.span);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
@@ -149,9 +161,7 @@ fn parse_cfg_entry_target<S: Stage>(
|
||||
|
||||
// Then, parse it as a name-value item
|
||||
let Some(name) = sub_item.path().word_sym() else {
|
||||
cx.emit_err(session_diagnostics::CfgPredicateIdentifier {
|
||||
span: sub_item.path().span(),
|
||||
});
|
||||
cx.expected_identifier(sub_item.path().span());
|
||||
return None;
|
||||
};
|
||||
let name = Symbol::intern(&format!("target_{name}"));
|
||||
@@ -300,3 +310,120 @@ impl EvalConfigResult {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_cfg_attr(
|
||||
cfg_attr: &Attribute,
|
||||
sess: &Session,
|
||||
features: Option<&Features>,
|
||||
) -> Option<(CfgEntry, Vec<(AttrItem, Span)>)> {
|
||||
match cfg_attr.get_normal_item().args {
|
||||
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
|
||||
if !tokens.is_empty() =>
|
||||
{
|
||||
check_cfg_attr_bad_delim(&sess.psess, dspan, delim);
|
||||
match parse_in(&sess.psess, tokens.clone(), "`cfg_attr` input", |p| {
|
||||
parse_cfg_attr_internal(p, sess, features, cfg_attr)
|
||||
}) {
|
||||
Ok(r) => return Some(r),
|
||||
Err(e) => {
|
||||
let suggestions = CFG_ATTR_TEMPLATE.suggestions(cfg_attr.style, sym::cfg_attr);
|
||||
e.with_span_suggestions(
|
||||
cfg_attr.span,
|
||||
"must be of the form",
|
||||
suggestions,
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.with_note(format!(
|
||||
"for more information, visit <{}>",
|
||||
CFG_ATTR_TEMPLATE.docs.expect("cfg_attr has docs")
|
||||
))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let (span, reason) = if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) =
|
||||
cfg_attr.get_normal_item().args
|
||||
{
|
||||
(dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument)
|
||||
} else {
|
||||
(cfg_attr.span, AttributeParseErrorReason::ExpectedList)
|
||||
};
|
||||
|
||||
sess.dcx().emit_err(AttributeParseError {
|
||||
span,
|
||||
attr_span: cfg_attr.span,
|
||||
template: CFG_ATTR_TEMPLATE,
|
||||
attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
|
||||
reason,
|
||||
attr_style: cfg_attr.style,
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim: Delimiter) {
|
||||
if let Delimiter::Parenthesis = delim {
|
||||
return;
|
||||
}
|
||||
psess.dcx().emit_err(CfgAttrBadDelim {
|
||||
span: span.entire(),
|
||||
sugg: MetaBadDelimSugg { open: span.open, close: span.close },
|
||||
});
|
||||
}
|
||||
|
||||
/// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited.
|
||||
fn parse_cfg_attr_internal<'a>(
|
||||
parser: &mut Parser<'a>,
|
||||
sess: &'a Session,
|
||||
features: Option<&Features>,
|
||||
attribute: &Attribute,
|
||||
) -> PResult<'a, (CfgEntry, Vec<(ast::AttrItem, Span)>)> {
|
||||
// Parse cfg predicate
|
||||
let pred_start = parser.token.span;
|
||||
let meta = MetaItemOrLitParser::parse_single(parser, ShouldEmit::ErrorsAndLints)?;
|
||||
let pred_span = pred_start.with_hi(parser.token.span.hi());
|
||||
|
||||
let cfg_predicate = AttributeParser::parse_single_args(
|
||||
sess,
|
||||
attribute.span,
|
||||
attribute.style,
|
||||
AttrPath {
|
||||
segments: attribute
|
||||
.ident_path()
|
||||
.expect("cfg_attr is not a doc comment")
|
||||
.into_boxed_slice(),
|
||||
span: attribute.span,
|
||||
},
|
||||
pred_span,
|
||||
CRATE_NODE_ID,
|
||||
features,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
&meta,
|
||||
parse_cfg_entry,
|
||||
&CFG_ATTR_TEMPLATE,
|
||||
)
|
||||
.ok_or_else(|| {
|
||||
let mut diag = sess.dcx().struct_err(
|
||||
"cfg_entry parsing failing with `ShouldEmit::ErrorsAndLints` should emit a error.",
|
||||
);
|
||||
diag.downgrade_to_delayed_bug();
|
||||
diag
|
||||
})?;
|
||||
|
||||
parser.expect(exp!(Comma))?;
|
||||
|
||||
// Presumably, the majority of the time there will only be one attr.
|
||||
let mut expanded_attrs = Vec::with_capacity(1);
|
||||
while parser.token != token::Eof {
|
||||
let lo = parser.token.span;
|
||||
let item = parser.parse_attr_item(ForceCollect::Yes)?;
|
||||
expanded_attrs.push((item, lo.to(parser.prev_token.span)));
|
||||
if !parser.eat(exp!(Comma)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((cfg_predicate, expanded_attrs))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_ast::{AttrStyle, NodeId};
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_feature::{AttributeTemplate, Features};
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
@@ -62,7 +62,8 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Usually you want `parse_limited`, which defaults to no errors.
|
||||
/// This does the same as `parse_limited`, except it has a `should_emit` parameter which allows it to emit errors.
|
||||
/// Usually you want `parse_limited`, which emits no errors.
|
||||
pub fn parse_limited_should_emit(
|
||||
sess: &'sess Session,
|
||||
attrs: &[ast::Attribute],
|
||||
@@ -86,6 +87,13 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
parsed.pop()
|
||||
}
|
||||
|
||||
/// This method allows you to parse a list of attributes *before* `rustc_ast_lowering`.
|
||||
/// This can be used for attributes that would be removed before `rustc_ast_lowering`, such as attributes on macro calls.
|
||||
///
|
||||
/// Try to use this as little as possible. Attributes *should* be lowered during
|
||||
/// `rustc_ast_lowering`. Some attributes require access to features to parse, which would
|
||||
/// crash if you tried to do so through [`parse_limited_all`](Self::parse_limited_all).
|
||||
/// Therefore, if `parse_only` is None, then features *must* be provided.
|
||||
pub fn parse_limited_all(
|
||||
sess: &'sess Session,
|
||||
attrs: &[ast::Attribute],
|
||||
@@ -111,6 +119,8 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
)
|
||||
}
|
||||
|
||||
/// This method parses a single attribute, using `parse_fn`.
|
||||
/// This is useful if you already know what exact attribute this is, and want to parse it.
|
||||
pub fn parse_single<T>(
|
||||
sess: &'sess Session,
|
||||
attr: &ast::Attribute,
|
||||
@@ -121,13 +131,6 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> Option<T>,
|
||||
template: &AttributeTemplate,
|
||||
) -> Option<T> {
|
||||
let mut parser = Self {
|
||||
features,
|
||||
tools: Vec::new(),
|
||||
parse_only: None,
|
||||
sess,
|
||||
stage: Early { emit_errors },
|
||||
};
|
||||
let ast::AttrKind::Normal(normal_attr) = &attr.kind else {
|
||||
panic!("parse_single called on a doc attr")
|
||||
};
|
||||
@@ -136,6 +139,43 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
let meta_parser = MetaItemParser::from_attr(normal_attr, &parts, &sess.psess, emit_errors)?;
|
||||
let path = meta_parser.path();
|
||||
let args = meta_parser.args();
|
||||
Self::parse_single_args(
|
||||
sess,
|
||||
attr.span,
|
||||
attr.style,
|
||||
path.get_attribute_path(),
|
||||
target_span,
|
||||
target_node_id,
|
||||
features,
|
||||
emit_errors,
|
||||
args,
|
||||
parse_fn,
|
||||
template,
|
||||
)
|
||||
}
|
||||
|
||||
/// This method is equivalent to `parse_single`, but parses arguments using `parse_fn` using manually created `args`.
|
||||
/// This is useful when you want to parse other things than attributes using attribute parsers.
|
||||
pub fn parse_single_args<T, I>(
|
||||
sess: &'sess Session,
|
||||
attr_span: Span,
|
||||
attr_style: AttrStyle,
|
||||
attr_path: AttrPath,
|
||||
target_span: Span,
|
||||
target_node_id: NodeId,
|
||||
features: Option<&'sess Features>,
|
||||
emit_errors: ShouldEmit,
|
||||
args: &I,
|
||||
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> Option<T>,
|
||||
template: &AttributeTemplate,
|
||||
) -> Option<T> {
|
||||
let mut parser = Self {
|
||||
features,
|
||||
tools: Vec::new(),
|
||||
parse_only: None,
|
||||
sess,
|
||||
stage: Early { emit_errors },
|
||||
};
|
||||
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
|
||||
shared: SharedContext {
|
||||
cx: &mut parser,
|
||||
@@ -145,10 +185,10 @@ impl<'sess> AttributeParser<'sess, Early> {
|
||||
crate::lints::emit_attribute_lint(&lint, sess);
|
||||
},
|
||||
},
|
||||
attr_span: attr.span,
|
||||
attr_style: attr.style,
|
||||
attr_span,
|
||||
attr_style,
|
||||
template,
|
||||
attr_path: path.get_attribute_path(),
|
||||
attr_path,
|
||||
};
|
||||
parse_fn(&mut cx, args)
|
||||
}
|
||||
|
||||
@@ -105,7 +105,9 @@ mod session_diagnostics;
|
||||
mod target_checking;
|
||||
pub mod validate_attr;
|
||||
|
||||
pub use attributes::cfg::{CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg_attr};
|
||||
pub use attributes::cfg::{
|
||||
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr,
|
||||
};
|
||||
pub use attributes::cfg_old::*;
|
||||
pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version};
|
||||
pub use context::{Early, Late, OmitDoc, ShouldEmit};
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::fmt::{Debug, Display};
|
||||
|
||||
use rustc_ast::token::{self, Delimiter, MetaVarKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path};
|
||||
use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Diag, PResult};
|
||||
use rustc_hir::{self as hir, AttrPath};
|
||||
@@ -124,7 +124,11 @@ impl<'a> ArgParser<'a> {
|
||||
return None;
|
||||
}
|
||||
|
||||
Self::List(MetaItemListParser::new(args, psess, should_emit)?)
|
||||
Self::List(
|
||||
MetaItemListParser::new(&args.tokens, args.dspan.entire(), psess, should_emit)
|
||||
.map_err(|e| should_emit.emit_err(e))
|
||||
.ok()?,
|
||||
)
|
||||
}
|
||||
AttrArgs::Eq { eq_span, expr } => Self::NameValue(NameValueParser {
|
||||
eq_span: *eq_span,
|
||||
@@ -186,7 +190,15 @@ pub enum MetaItemOrLitParser<'a> {
|
||||
Err(Span, ErrorGuaranteed),
|
||||
}
|
||||
|
||||
impl<'a> MetaItemOrLitParser<'a> {
|
||||
impl<'sess> MetaItemOrLitParser<'sess> {
|
||||
pub fn parse_single(
|
||||
parser: &mut Parser<'sess>,
|
||||
should_emit: ShouldEmit,
|
||||
) -> PResult<'sess, MetaItemOrLitParser<'static>> {
|
||||
let mut this = MetaItemListParserContext { parser, should_emit };
|
||||
this.parse_meta_item_inner()
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
MetaItemOrLitParser::MetaItemParser(generic_meta_item_parser) => {
|
||||
@@ -204,7 +216,7 @@ impl<'a> MetaItemOrLitParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item(&self) -> Option<&MetaItemParser<'a>> {
|
||||
pub fn meta_item(&self) -> Option<&MetaItemParser<'sess>> {
|
||||
match self {
|
||||
MetaItemOrLitParser::MetaItemParser(parser) => Some(parser),
|
||||
_ => None,
|
||||
@@ -542,23 +554,13 @@ pub struct MetaItemListParser<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MetaItemListParser<'a> {
|
||||
fn new<'sess>(
|
||||
delim: &'a DelimArgs,
|
||||
pub(crate) fn new<'sess>(
|
||||
tokens: &'a TokenStream,
|
||||
span: Span,
|
||||
psess: &'sess ParseSess,
|
||||
should_emit: ShouldEmit,
|
||||
) -> Option<Self> {
|
||||
match MetaItemListParserContext::parse(
|
||||
delim.tokens.clone(),
|
||||
psess,
|
||||
delim.dspan.entire(),
|
||||
should_emit,
|
||||
) {
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
should_emit.emit_err(e);
|
||||
None
|
||||
}
|
||||
}
|
||||
) -> Result<Self, Diag<'sess>> {
|
||||
MetaItemListParserContext::parse(tokens.clone(), psess, span, should_emit)
|
||||
}
|
||||
|
||||
/// Lets you pick and choose as what you want to parse each element in the list
|
||||
|
||||
@@ -971,3 +971,12 @@ pub(crate) struct LimitInvalid<'a> {
|
||||
pub value_span: Span,
|
||||
pub error_str: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_cfg_attr_bad_delim)]
|
||||
pub(crate) struct CfgAttrBadDelim {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: MetaBadDelimSugg,
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use rustc_ast::{
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::validate_attr::deny_builtin_meta_unsafety;
|
||||
use rustc_attr_parsing::{
|
||||
AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg_attr,
|
||||
AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg,
|
||||
validate_attr,
|
||||
};
|
||||
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||
@@ -303,7 +303,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
let trace_attr = attr_into_trace(cfg_attr.clone(), sym::cfg_attr_trace);
|
||||
|
||||
let Some((cfg_predicate, expanded_attrs)) =
|
||||
rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)
|
||||
rustc_attr_parsing::parse_cfg_attr(cfg_attr, &self.sess, self.features)
|
||||
else {
|
||||
return vec![trace_attr];
|
||||
};
|
||||
@@ -318,7 +318,15 @@ impl<'a> StripUnconfigured<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {
|
||||
if !attr::eval_config_entry(
|
||||
self.sess,
|
||||
&cfg_predicate,
|
||||
ast::CRATE_NODE_ID,
|
||||
self.features,
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
)
|
||||
.as_bool()
|
||||
{
|
||||
return vec![trace_attr];
|
||||
}
|
||||
|
||||
@@ -428,7 +436,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
node,
|
||||
self.features,
|
||||
emit_errors,
|
||||
parse_cfg_attr,
|
||||
parse_cfg,
|
||||
&CFG_TEMPLATE,
|
||||
) else {
|
||||
// Cfg attribute was not parsable, give up
|
||||
@@ -488,7 +496,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
}
|
||||
|
||||
/// FIXME: Still used by Rustdoc, should be removed after
|
||||
pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItemInner> {
|
||||
pub fn parse_cfg_old<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItemInner> {
|
||||
let span = meta_item.span;
|
||||
match meta_item.meta_item_list() {
|
||||
None => {
|
||||
|
||||
@@ -814,7 +814,7 @@ fn get_nullable_type<'tcx>(
|
||||
|
||||
/// A type is niche-optimization candidate iff:
|
||||
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
|
||||
/// - Has no fields.
|
||||
/// - Is either a struct/tuple with no fields, or an enum with no variants.
|
||||
/// - Does not have the `#[non_exhaustive]` attribute.
|
||||
fn is_niche_optimization_candidate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@@ -828,7 +828,7 @@ fn is_niche_optimization_candidate<'tcx>(
|
||||
match ty.kind() {
|
||||
ty::Adt(ty_def, _) => {
|
||||
let non_exhaustive = ty_def.is_variant_list_non_exhaustive();
|
||||
let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none())
|
||||
let empty = (ty_def.is_struct() && ty_def.non_enum_variant().fields.is_empty())
|
||||
|| (ty_def.is_enum() && ty_def.variants().is_empty());
|
||||
|
||||
!non_exhaustive && empty
|
||||
|
||||
@@ -122,7 +122,6 @@ parse_cannot_be_raw_lifetime = `{$ident}` cannot be a raw lifetime
|
||||
parse_catch_after_try = keyword `catch` cannot follow a `try` block
|
||||
.help = try using `match` on the result of the `try` block instead
|
||||
|
||||
parse_cfg_attr_bad_delim = wrong `cfg_attr` delimiters
|
||||
parse_colon_as_semi = statements are terminated with a semicolon
|
||||
.suggestion = use a semicolon instead
|
||||
|
||||
@@ -573,10 +572,6 @@ parse_macro_rules_missing_bang = expected `!` after `macro_rules`
|
||||
parse_macro_rules_visibility = can't qualify macro_rules invocation with `{$vis}`
|
||||
.suggestion = try exporting the macro
|
||||
|
||||
parse_malformed_cfg_attr = malformed `cfg_attr` attribute input
|
||||
.suggestion = missing condition and attribute
|
||||
.note = for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
parse_malformed_loop_label = malformed loop label
|
||||
.suggestion = use the correct loop label format
|
||||
|
||||
@@ -610,8 +605,6 @@ parse_maybe_report_ambiguous_plus =
|
||||
ambiguous `+` in a type
|
||||
.suggestion = use parentheses to disambiguate
|
||||
|
||||
parse_meta_bad_delim_suggestion = the delimiters should be `(` and `)`
|
||||
|
||||
parse_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}`
|
||||
.label_unmatched = mismatched closing delimiter
|
||||
.label_opening_candidate = closing delimiter possibly meant for this
|
||||
|
||||
@@ -3351,34 +3351,6 @@ pub(crate) struct KwBadCase<'a> {
|
||||
pub kw: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_cfg_attr_bad_delim)]
|
||||
pub(crate) struct CfgAttrBadDelim {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: MetaBadDelimSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(parse_meta_bad_delim_suggestion, applicability = "machine-applicable")]
|
||||
pub(crate) struct MetaBadDelimSugg {
|
||||
#[suggestion_part(code = "(")]
|
||||
pub open: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub close: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_malformed_cfg_attr)]
|
||||
#[note]
|
||||
pub(crate) struct MalformedCfgAttr {
|
||||
#[primary_span]
|
||||
#[suggestion(style = "verbose", code = "{sugg}")]
|
||||
pub span: Span,
|
||||
pub sugg: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_unknown_builtin_construct)]
|
||||
pub(crate) struct UnknownBuiltinConstruct {
|
||||
|
||||
@@ -18,8 +18,8 @@ use std::str::Utf8Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||
use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Diag, EmissionGuarantee, FatalError, PResult, pluralize};
|
||||
use rustc_session::parse::ParseSess;
|
||||
@@ -32,7 +32,6 @@ pub const MACRO_ARGUMENTS: Option<&str> = Some("macro arguments");
|
||||
#[macro_use]
|
||||
pub mod parser;
|
||||
use parser::Parser;
|
||||
use rustc_ast::token::Delimiter;
|
||||
|
||||
use crate::lexer::StripTokens;
|
||||
|
||||
@@ -230,45 +229,3 @@ pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> Tok
|
||||
Some(krate.spans.inner_span),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn parse_cfg_attr(
|
||||
cfg_attr: &Attribute,
|
||||
psess: &ParseSess,
|
||||
) -> Option<(MetaItemInner, Vec<(AttrItem, Span)>)> {
|
||||
const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
|
||||
const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
|
||||
<https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
|
||||
|
||||
match cfg_attr.get_normal_item().args {
|
||||
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
|
||||
if !tokens.is_empty() =>
|
||||
{
|
||||
check_cfg_attr_bad_delim(psess, dspan, delim);
|
||||
match parse_in(psess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
|
||||
Ok(r) => return Some(r),
|
||||
Err(e) => {
|
||||
e.with_help(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`"))
|
||||
.with_note(CFG_ATTR_NOTE_REF)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
psess.dcx().emit_err(errors::MalformedCfgAttr {
|
||||
span: cfg_attr.span,
|
||||
sugg: CFG_ATTR_GRAMMAR_HELP,
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim: Delimiter) {
|
||||
if let Delimiter::Parenthesis = delim {
|
||||
return;
|
||||
}
|
||||
psess.dcx().emit_err(errors::CfgAttrBadDelim {
|
||||
span: span.entire(),
|
||||
sugg: errors::MetaBadDelimSugg { open: span.open, close: span.close },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -377,27 +377,6 @@ impl<'a> Parser<'a> {
|
||||
Ok(lit)
|
||||
}
|
||||
|
||||
/// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited.
|
||||
pub fn parse_cfg_attr(
|
||||
&mut self,
|
||||
) -> PResult<'a, (ast::MetaItemInner, Vec<(ast::AttrItem, Span)>)> {
|
||||
let cfg_predicate = self.parse_meta_item_inner()?;
|
||||
self.expect(exp!(Comma))?;
|
||||
|
||||
// Presumably, the majority of the time there will only be one attr.
|
||||
let mut expanded_attrs = Vec::with_capacity(1);
|
||||
while self.token != token::Eof {
|
||||
let lo = self.token.span;
|
||||
let item = self.parse_attr_item(ForceCollect::Yes)?;
|
||||
expanded_attrs.push((item, lo.to(self.prev_token.span)));
|
||||
if !self.eat(exp!(Comma)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((cfg_predicate, expanded_attrs))
|
||||
}
|
||||
|
||||
/// Matches `COMMASEP(meta_item_inner)`.
|
||||
pub fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::MetaItemInner>> {
|
||||
// Presumably, the majority of the time there will only be one attr.
|
||||
|
||||
@@ -603,7 +603,8 @@ impl Session {
|
||||
// Autodiff currently requires fat-lto to have access to the llvm-ir of all (indirectly) used functions and types.
|
||||
// fat-lto is the easiest solution to this requirement, but quite expensive.
|
||||
// FIXME(autodiff): Make autodiff also work with embed-bc instead of fat-lto.
|
||||
if self.opts.autodiff_enabled() {
|
||||
// Don't apply fat-lto to proc-macro crates as they cannot use fat-lto without -Zdylib-lto
|
||||
if self.opts.autodiff_enabled() && !self.opts.crate_types.contains(&CrateType::ProcMacro) {
|
||||
return config::Lto::Fat;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,9 +118,14 @@
|
||||
//!
|
||||
//! # Representation
|
||||
//!
|
||||
//! Rust guarantees to optimize the following types `T` such that
|
||||
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
|
||||
//! of these cases, Rust further guarantees the following:
|
||||
//! Rust guarantees to optimize the following types `T` such that [`Option<T>`]
|
||||
//! has the same size, alignment, and [function call ABI] as `T`. It is
|
||||
//! therefore sound, when `T` is one of these types, to transmute a value `t` of
|
||||
//! type `T` to type `Option<T>` (producing the value `Some(t)`) and to
|
||||
//! transmute a value `Some(t)` of type `Option<T>` to type `T` (producing the
|
||||
//! value `t`).
|
||||
//!
|
||||
//! In some of these cases, Rust further guarantees the following:
|
||||
//! - `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and produces
|
||||
//! `Option::<T>::None`
|
||||
//! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
|
||||
|
||||
@@ -230,24 +230,31 @@
|
||||
//!
|
||||
//! # Representation
|
||||
//!
|
||||
//! In some cases, [`Result<T, E>`] will gain the same size, alignment, and ABI
|
||||
//! guarantees as [`Option<U>`] has. One of either the `T` or `E` type must be a
|
||||
//! type that qualifies for the `Option` [representation guarantees][opt-rep],
|
||||
//! and the *other* type must meet all of the following conditions:
|
||||
//! * Is a zero-sized type with alignment 1 (a "1-ZST").
|
||||
//! * Has no fields.
|
||||
//! * Does not have the `#[non_exhaustive]` attribute.
|
||||
//! In some cases, [`Result<T, E>`] comes with size, alignment, and ABI
|
||||
//! guarantees. Specifically, one of either the `T` or `E` type must be a type
|
||||
//! that qualifies for the `Option` [representation guarantees][opt-rep] (let's
|
||||
//! call that type `I`), and the *other* type is a zero-sized type with
|
||||
//! alignment 1 (a "1-ZST").
|
||||
//!
|
||||
//! If that is the case, then `Result<T, E>` has the same size, alignment, and
|
||||
//! [function call ABI] as `I` (and therefore, as `Option<I>`). If `I` is `T`,
|
||||
//! it is therefore sound to transmute a value `t` of type `I` to type
|
||||
//! `Result<T, E>` (producing the value `Ok(t)`) and to transmute a value
|
||||
//! `Ok(t)` of type `Result<T, E>` to type `I` (producing the value `t`). If `I`
|
||||
//! is `E`, the same applies with `Ok` replaced by `Err`.
|
||||
//!
|
||||
//! For example, `NonZeroI32` qualifies for the `Option` representation
|
||||
//! guarantees, and `()` is a zero-sized type with alignment 1, no fields, and
|
||||
//! it isn't `non_exhaustive`. This means that both `Result<NonZeroI32, ()>` and
|
||||
//! `Result<(), NonZeroI32>` have the same size, alignment, and ABI guarantees
|
||||
//! as `Option<NonZeroI32>`. The only difference is the implied semantics:
|
||||
//! guarantees and `()` is a zero-sized type with alignment 1. This means that
|
||||
//! both `Result<NonZeroI32, ()>` and `Result<(), NonZeroI32>` have the same
|
||||
//! size, alignment, and ABI as `NonZeroI32` (and `Option<NonZeroI32>`). The
|
||||
//! only difference between these is in the implied semantics:
|
||||
//!
|
||||
//! * `Option<NonZeroI32>` is "a non-zero i32 might be present"
|
||||
//! * `Result<NonZeroI32, ()>` is "a non-zero i32 success result, if any"
|
||||
//! * `Result<(), NonZeroI32>` is "a non-zero i32 error result, if any"
|
||||
//!
|
||||
//! [opt-rep]: ../option/index.html#representation "Option Representation"
|
||||
//! [function call ABI]: ../primitive.fn.html#abi-compatibility
|
||||
//!
|
||||
//! # Method overview
|
||||
//!
|
||||
|
||||
@@ -620,9 +620,8 @@ impl Builder {
|
||||
/// (It is the responsibility of the program to either eventually join threads it
|
||||
/// creates or detach them; otherwise, a resource leak will result.)
|
||||
///
|
||||
/// This call will create a thread using default parameters of [`Builder`], if you
|
||||
/// want to specify the stack size or the name of the thread, use this API
|
||||
/// instead.
|
||||
/// This function creates a thread with the default parameters of [`Builder`].
|
||||
/// To specify the new thread's stack size or the name, use [`Builder::spawn`].
|
||||
///
|
||||
/// As you can see in the signature of `spawn` there are two constraints on
|
||||
/// both the closure given to `spawn` and its return value, let's explain them:
|
||||
|
||||
@@ -181,9 +181,8 @@ impl<'scope, 'env> Scope<'scope, 'env> {
|
||||
/// end of the scope. In that case, if the spawned thread panics, [`scope`] will
|
||||
/// panic after all threads are joined.
|
||||
///
|
||||
/// This call will create a thread using default parameters of [`Builder`].
|
||||
/// If you want to specify the stack size or the name of the thread, use
|
||||
/// [`Builder::spawn_scoped`] instead.
|
||||
/// This function creates a thread with the default parameters of [`Builder`].
|
||||
/// To specify the new thread's stack size or the name, use [`Builder::spawn_scoped`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
|
||||
@@ -491,9 +491,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.5"
|
||||
version = "0.37.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@@ -41,7 +41,7 @@ clap_complete = "4.4"
|
||||
home = "0.5"
|
||||
ignore = "0.4"
|
||||
libc = "0.2"
|
||||
object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "std", "unaligned"] }
|
||||
object = { version = "0.37", default-features = false, features = ["archive", "coff", "read_core", "std", "unaligned"] }
|
||||
opener = "0.8"
|
||||
semver = "1.0"
|
||||
serde = "1.0"
|
||||
|
||||
@@ -751,7 +751,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
|
||||
}
|
||||
for attr in doc_cfg {
|
||||
if let Some(cfg_mi) =
|
||||
attr.meta_item().and_then(|attr| rustc_expand::config::parse_cfg(attr, sess))
|
||||
attr.meta_item().and_then(|attr| rustc_expand::config::parse_cfg_old(attr, sess))
|
||||
{
|
||||
match Cfg::parse(cfg_mi) {
|
||||
Ok(new_cfg) => cfg_info.current_cfg &= new_cfg,
|
||||
|
||||
@@ -94,11 +94,11 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[
|
||||
ConditionalPass::always(COLLECT_TRAIT_IMPLS),
|
||||
ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY),
|
||||
ConditionalPass::always(CHECK_DOC_CFG),
|
||||
ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
|
||||
ConditionalPass::always(STRIP_ALIASED_NON_LOCAL),
|
||||
ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
|
||||
ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
|
||||
ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate),
|
||||
ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
|
||||
ConditionalPass::always(PROPAGATE_DOC_CFG),
|
||||
ConditionalPass::always(PROPAGATE_STABILITY),
|
||||
ConditionalPass::always(RUN_LINTS),
|
||||
|
||||
14
tests/rustdoc-ui/intra-doc/hidden-check.rs
Normal file
14
tests/rustdoc-ui/intra-doc/hidden-check.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
// This test ensures that `doc(hidden)` items intra-doc links are checked whereas private
|
||||
// items are ignored.
|
||||
|
||||
//@ compile-flags: -Zunstable-options --document-hidden-items
|
||||
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
|
||||
/// [not::exist]
|
||||
//~^ ERROR unresolved link to `not::exist`
|
||||
#[doc(hidden)]
|
||||
pub struct X;
|
||||
|
||||
/// [not::exist]
|
||||
struct Y;
|
||||
14
tests/rustdoc-ui/intra-doc/hidden-check.stderr
Normal file
14
tests/rustdoc-ui/intra-doc/hidden-check.stderr
Normal file
@@ -0,0 +1,14 @@
|
||||
error: unresolved link to `not::exist`
|
||||
--> $DIR/hidden-check.rs:8:6
|
||||
|
|
||||
LL | /// [not::exist]
|
||||
| ^^^^^^^^^^ no item named `not` in scope
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/hidden-check.rs:6:9
|
||||
|
|
||||
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
14
tests/rustdoc-ui/intra-doc/private-check.rs
Normal file
14
tests/rustdoc-ui/intra-doc/private-check.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
// This test ensures that private items intra-doc links are checked whereas `doc(hidden)`
|
||||
// items are ignored.
|
||||
|
||||
//@ compile-flags: -Zunstable-options --document-private-items
|
||||
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
|
||||
/// [not::exist]
|
||||
#[doc(hidden)]
|
||||
pub struct X;
|
||||
|
||||
/// [not::exist]
|
||||
//~^ ERROR unresolved link to `not::exist`
|
||||
struct Y;
|
||||
14
tests/rustdoc-ui/intra-doc/private-check.stderr
Normal file
14
tests/rustdoc-ui/intra-doc/private-check.stderr
Normal file
@@ -0,0 +1,14 @@
|
||||
error: unresolved link to `not::exist`
|
||||
--> $DIR/private-check.rs:12:6
|
||||
|
|
||||
LL | /// [not::exist]
|
||||
| ^^^^^^^^^^ no item named `not` in scope
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/private-check.rs:6:9
|
||||
|
|
||||
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -16,11 +16,11 @@ Default passes for rustdoc:
|
||||
collect-trait-impls
|
||||
check_doc_test_visibility
|
||||
check-doc-cfg
|
||||
collect-intra-doc-links
|
||||
strip-aliased-non-local
|
||||
strip-hidden (when not --document-hidden-items)
|
||||
strip-private (when not --document-private-items)
|
||||
strip-priv-imports (when --document-private-items)
|
||||
collect-intra-doc-links
|
||||
propagate-doc-cfg
|
||||
propagate-stability
|
||||
run-lints
|
||||
|
||||
@@ -9,17 +9,16 @@ LL | #[cfg]
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: malformed `cfg_attr` attribute input
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/malformed-attrs.rs:103:1
|
||||
|
|
||||
LL | #[cfg_attr]
|
||||
| ^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be a list
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
help: missing condition and attribute
|
||||
|
|
||||
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
|
||||
| ++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0463]: can't find crate for `wloop`
|
||||
--> $DIR/malformed-attrs.rs:209:1
|
||||
|
||||
@@ -3,19 +3,27 @@
|
||||
#![allow(unexpected_cfgs)] // invalid cfgs
|
||||
|
||||
#[cfg(any(foo, foo::bar))]
|
||||
//~^ERROR `cfg` predicate key must be an identifier
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
fn foo1() {}
|
||||
|
||||
#[cfg(any(foo::bar, foo))]
|
||||
//~^ERROR `cfg` predicate key must be an identifier
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
fn foo2() {}
|
||||
|
||||
#[cfg(all(foo, foo::bar))]
|
||||
//~^ERROR `cfg` predicate key must be an identifier
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
fn foo3() {}
|
||||
|
||||
#[cfg(all(foo::bar, foo))]
|
||||
//~^ERROR `cfg` predicate key must be an identifier
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
fn foo4() {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,26 +1,47 @@
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-path-error.rs:5:16
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-path-error.rs:5:1
|
||||
|
|
||||
LL | #[cfg(any(foo, foo::bar))]
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^--------^^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-path-error.rs:9:11
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-path-error.rs:11:1
|
||||
|
|
||||
LL | #[cfg(any(foo::bar, foo))]
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^^^--------^^^^^^^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-path-error.rs:13:16
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-path-error.rs:17:1
|
||||
|
|
||||
LL | #[cfg(all(foo, foo::bar))]
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^--------^^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-path-error.rs:17:11
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-path-error.rs:23:1
|
||||
|
|
||||
LL | #[cfg(all(foo::bar, foo))]
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^^^--------^^^^^^^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
||||
@@ -19,7 +19,7 @@ fn three() {}
|
||||
fn four() {}
|
||||
|
||||
#[cfg(target(clippy::os = "linux"))]
|
||||
//~^ ERROR `cfg` predicate key must be an identifier
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
fn five() {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -42,11 +42,16 @@ LL | #[cfg(target(true))]
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-target-compact-errors.rs:21:14
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-target-compact-errors.rs:21:1
|
||||
|
|
||||
LL | #[cfg(target(clippy::os = "linux"))]
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^----------^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
||||
@@ -1,49 +1,56 @@
|
||||
error: malformed `cfg_attr` attribute input
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg-attr-parse.rs:4:1
|
||||
|
|
||||
LL | #[cfg_attr()]
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^--^
|
||||
| | |
|
||||
| | expected at least 1 argument here
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
help: missing condition and attribute
|
||||
|
|
||||
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
|
||||
| ++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: expected `,`, found end of `cfg_attr` input
|
||||
--> $DIR/cfg-attr-parse.rs:8:17
|
||||
|
|
||||
LL | #[cfg_attr(all())]
|
||||
| ^ expected `,`
|
||||
| ----------------^-
|
||||
| | |
|
||||
| | expected `,`
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: expected identifier, found `,`
|
||||
--> $DIR/cfg-attr-parse.rs:16:18
|
||||
|
|
||||
LL | #[cfg_attr(all(),,)]
|
||||
| ^ expected identifier
|
||||
| -----------------^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: expected identifier, found `,`
|
||||
--> $DIR/cfg-attr-parse.rs:28:28
|
||||
|
|
||||
LL | #[cfg_attr(all(), must_use,,)]
|
||||
| ^ expected identifier
|
||||
| ---------------------------^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: expected identifier, found `,`
|
||||
--> $DIR/cfg-attr-parse.rs:40:40
|
||||
|
|
||||
LL | #[cfg_attr(all(), must_use, deprecated,,)]
|
||||
| ^ expected identifier
|
||||
| ---------------------------------------^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: wrong `cfg_attr` delimiters
|
||||
@@ -62,9 +69,11 @@ error: expected identifier, found `,`
|
||||
--> $DIR/cfg-attr-parse.rs:44:18
|
||||
|
|
||||
LL | #[cfg_attr[all(),,]]
|
||||
| ^ expected identifier
|
||||
| -----------------^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: wrong `cfg_attr` delimiters
|
||||
@@ -83,10 +92,13 @@ error: expected identifier, found `,`
|
||||
--> $DIR/cfg-attr-parse.rs:50:18
|
||||
|
|
||||
LL | #[cfg_attr{all(),,}]
|
||||
| ^ expected identifier
|
||||
| -----------------^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
||||
@@ -22,10 +22,16 @@ struct S3;
|
||||
//~| NOTE for more information, visit
|
||||
struct S4;
|
||||
|
||||
#[cfg("str")] //~ ERROR `cfg` predicate key must be an identifier
|
||||
#[cfg("str")]
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
struct S5;
|
||||
|
||||
#[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier
|
||||
#[cfg(a::b)]
|
||||
//~^ ERROR malformed `cfg` attribute input
|
||||
//~| NOTE expected a valid identifier here
|
||||
//~| NOTE for more information, visit
|
||||
struct S6;
|
||||
|
||||
#[cfg(a())] //~ ERROR invalid predicate `a`
|
||||
|
||||
@@ -42,26 +42,36 @@ LL | #[cfg(a, b)]
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:25:7
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:25:1
|
||||
|
|
||||
LL | #[cfg("str")]
|
||||
| ^^^^^
|
||||
| ^^^^^^-----^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:28:7
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:31:1
|
||||
|
|
||||
LL | #[cfg(a::b)]
|
||||
| ^^^^
|
||||
| ^^^^^^----^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg(predicate)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error[E0537]: invalid predicate `a`
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:31:7
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:37:7
|
||||
|
|
||||
LL | #[cfg(a())]
|
||||
| ^^^
|
||||
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:34:1
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:40:1
|
||||
|
|
||||
LL | #[cfg(a = 10)]
|
||||
| ^^^^^^^^^^--^^
|
||||
@@ -72,7 +82,7 @@ LL | #[cfg(a = 10)]
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:39:1
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:45:1
|
||||
|
|
||||
LL | #[cfg(a = b"hi")]
|
||||
| ^^^^^^^^^^-^^^^^^
|
||||
@@ -82,7 +92,7 @@ LL | #[cfg(a = b"hi")]
|
||||
= note: expected a normal string literal, not a byte string literal
|
||||
|
||||
error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:45:25
|
||||
--> $DIR/cfg-attr-syntax-validation.rs:51:25
|
||||
|
|
||||
LL | #[cfg(feature = $expr)]
|
||||
| ^^^^^
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#[cfg_attr]
|
||||
//~^ ERROR malformed `cfg_attr` attribute
|
||||
struct S1;
|
||||
|
||||
#[cfg_attr = 10]
|
||||
//~^ ERROR malformed `cfg_attr` attribute
|
||||
struct S2;
|
||||
|
||||
#[cfg_attr()]
|
||||
//~^ ERROR malformed `cfg_attr` attribute
|
||||
struct S3;
|
||||
|
||||
#[cfg_attr("str")] //~ ERROR malformed `cfg_attr` attribute input
|
||||
struct S5;
|
||||
|
||||
#[cfg_attr(a::b)] //~ ERROR malformed `cfg_attr` attribute input
|
||||
struct S6;
|
||||
|
||||
#[cfg_attr(a())] //~ ERROR invalid predicate `a`
|
||||
struct S7;
|
||||
|
||||
#[cfg_attr(a = 10)] //~ ERROR malformed `cfg_attr` attribute input
|
||||
struct S8;
|
||||
|
||||
#[cfg_attr(a = b"hi")] //~ ERROR malformed `cfg_attr` attribute input
|
||||
struct S9;
|
||||
|
||||
macro_rules! generate_s10 {
|
||||
($expr: expr) => {
|
||||
#[cfg_attr(feature = $expr)]
|
||||
//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable
|
||||
struct S10;
|
||||
}
|
||||
}
|
||||
|
||||
generate_s10!(concat!("nonexistent"));
|
||||
|
||||
#[cfg_attr(true)] //~ ERROR expected `,`, found end of `cfg_attr` input
|
||||
struct S11;
|
||||
|
||||
#[cfg_attr(true, unknown_attribute)] //~ ERROR cannot find attribute `unknown_attribute` in this scope
|
||||
struct S12;
|
||||
|
||||
#[cfg_attr(true, link_section)] //~ ERROR malformed `link_section` attribute input
|
||||
struct S13;
|
||||
|
||||
#[cfg_attr(true, inline())] //~ ERROR malformed `inline` attribute input
|
||||
fn f1() {}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,144 @@
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:1:1
|
||||
|
|
||||
LL | #[cfg_attr]
|
||||
| ^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be a list
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:5:1
|
||||
|
|
||||
LL | #[cfg_attr = 10]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be a list
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:9:1
|
||||
|
|
||||
LL | #[cfg_attr()]
|
||||
| ^^^^^^^^^^--^
|
||||
| | |
|
||||
| | expected at least 1 argument here
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:13:1
|
||||
|
|
||||
LL | #[cfg_attr("str")]
|
||||
| ^^^^^^^^^^^-----^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:16:1
|
||||
|
|
||||
LL | #[cfg_attr(a::b)]
|
||||
| ^^^^^^^^^^^----^^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0537]: invalid predicate `a`
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:19:12
|
||||
|
|
||||
LL | #[cfg_attr(a())]
|
||||
| ^^^
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:22:1
|
||||
|
|
||||
LL | #[cfg_attr(a = 10)]
|
||||
| ^^^^^^^^^^^^^^^--^^
|
||||
| | |
|
||||
| | expected a string literal here
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:25:1
|
||||
|
|
||||
LL | #[cfg_attr(a = b"hi")]
|
||||
| ^^^^^^^^^^^^^^^-^^^^^^
|
||||
| |
|
||||
| help: consider removing the prefix
|
||||
|
|
||||
= note: expected a normal string literal, not a byte string literal
|
||||
|
||||
error: expected `,`, found end of `cfg_attr` input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:38:16
|
||||
|
|
||||
LL | #[cfg_attr(true)]
|
||||
| ---------------^-
|
||||
| | |
|
||||
| | expected `,`
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:30:30
|
||||
|
|
||||
LL | #[cfg_attr(feature = $expr)]
|
||||
| ---------------------^^^^^-- help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
...
|
||||
LL | generate_s10!(concat!("nonexistent"));
|
||||
| ------------------------------------- in this macro invocation
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
= note: this error originates in the macro `generate_s10` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: cannot find attribute `unknown_attribute` in this scope
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:41:18
|
||||
|
|
||||
LL | #[cfg_attr(true, unknown_attribute)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0539]: malformed `link_section` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:44:18
|
||||
|
|
||||
LL | #[cfg_attr(true, link_section)]
|
||||
| ^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute>
|
||||
|
||||
error[E0805]: malformed `inline` attribute input
|
||||
--> $DIR/cfg_attr-attr-syntax-validation.rs:47:18
|
||||
|
|
||||
LL | #[cfg_attr(true, inline())]
|
||||
| ^^^^^^--
|
||||
| |
|
||||
| expected a single argument here
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute>
|
||||
help: try changing it to one of the following valid forms of the attribute
|
||||
|
|
||||
LL - #[cfg_attr(true, inline())]
|
||||
LL + #[cfg_attr(true, #[inline(always)])]
|
||||
|
|
||||
LL - #[cfg_attr(true, inline())]
|
||||
LL + #[cfg_attr(true, #[inline(never)])]
|
||||
|
|
||||
LL - #[cfg_attr(true, inline())]
|
||||
LL + #[cfg_attr(true, #[inline])]
|
||||
|
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0537, E0539, E0805.
|
||||
For more information about an error, try `rustc --explain E0537`.
|
||||
@@ -1,6 +1,6 @@
|
||||
#[link(name = "foo", cfg("rlib"))]
|
||||
//~^ ERROR link cfg is unstable
|
||||
//~| ERROR `cfg` predicate key must be an identifier
|
||||
//~| ERROR malformed `link` attribute input
|
||||
extern "C" {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -7,12 +7,32 @@ LL | #[link(name = "foo", cfg("rlib"))]
|
||||
= help: add `#![feature(link_cfg)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/issue-43925.rs:1:26
|
||||
error[E0539]: malformed `link` attribute input
|
||||
--> $DIR/issue-43925.rs:1:1
|
||||
|
|
||||
LL | #[link(name = "foo", cfg("rlib"))]
|
||||
| ^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^------^^^
|
||||
| |
|
||||
| expected a valid identifier here
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
|
||||
help: try changing it to one of the following valid forms of the attribute
|
||||
|
|
||||
LL - #[link(name = "foo", cfg("rlib"))]
|
||||
LL + #[link(name = "...")]
|
||||
|
|
||||
LL - #[link(name = "foo", cfg("rlib"))]
|
||||
LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
|
||||
|
|
||||
LL - #[link(name = "foo", cfg("rlib"))]
|
||||
LL + #[link(name = "...", kind = "dylib|static|...")]
|
||||
|
|
||||
LL - #[link(name = "foo", cfg("rlib"))]
|
||||
LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
|
||||
|
|
||||
= and 1 other candidate
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
Some errors have detailed explanations: E0539, E0658.
|
||||
For more information about an error, try `rustc --explain E0539`.
|
||||
|
||||
@@ -22,7 +22,7 @@ extern "C" {}
|
||||
#[link(name = "...", modifiers())] //~ ERROR malformed `link` attribute input
|
||||
#[link(name = "...", cfg)] //~ ERROR malformed `link` attribute input
|
||||
#[link(name = "...", cfg = "literal")] //~ ERROR malformed `link` attribute input
|
||||
#[link(name = "...", cfg("literal"))] //~ ERROR `cfg` predicate key must be an identifier
|
||||
#[link(name = "...", cfg("literal"))] //~ ERROR malformed `link` attribute input
|
||||
#[link(name = "...", wasm_import_module)] //~ ERROR malformed `link` attribute input
|
||||
#[link(name = "...", wasm_import_module())] //~ ERROR malformed `link` attribute input
|
||||
extern "C" {}
|
||||
|
||||
@@ -367,11 +367,30 @@ LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...",
|
||||
|
|
||||
= and 1 other candidate
|
||||
|
||||
error: `cfg` predicate key must be an identifier
|
||||
--> $DIR/link-attr-validation-late.rs:25:26
|
||||
error[E0539]: malformed `link` attribute input
|
||||
--> $DIR/link-attr-validation-late.rs:25:1
|
||||
|
|
||||
LL | #[link(name = "...", cfg("literal"))]
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^
|
||||
| |
|
||||
| expected a valid identifier here
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
|
||||
help: try changing it to one of the following valid forms of the attribute
|
||||
|
|
||||
LL - #[link(name = "...", cfg("literal"))]
|
||||
LL + #[link(name = "...")]
|
||||
|
|
||||
LL - #[link(name = "...", cfg("literal"))]
|
||||
LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
|
||||
|
|
||||
LL - #[link(name = "...", cfg("literal"))]
|
||||
LL + #[link(name = "...", kind = "dylib|static|...")]
|
||||
|
|
||||
LL - #[link(name = "...", cfg("literal"))]
|
||||
LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
|
||||
|
|
||||
= and 1 other candidate
|
||||
|
||||
error[E0539]: malformed `link` attribute input
|
||||
--> $DIR/link-attr-validation-late.rs:26:1
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
error: malformed `cfg_attr` attribute input
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/malformed-special-attrs.rs:1:1
|
||||
|
|
||||
LL | #[cfg_attr]
|
||||
| ^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be a list
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
help: missing condition and attribute
|
||||
|
|
||||
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
|
||||
| ++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: malformed `cfg_attr` attribute input
|
||||
error[E0539]: malformed `cfg_attr` attribute input
|
||||
--> $DIR/malformed-special-attrs.rs:4:1
|
||||
|
|
||||
LL | #[cfg_attr = ""]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be a list
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
help: missing condition and attribute
|
||||
|
|
||||
LL - #[cfg_attr = ""]
|
||||
LL + #[cfg_attr(condition, attribute, other_attribute, ...)]
|
||||
|
|
||||
|
||||
error: malformed `derive` attribute input
|
||||
--> $DIR/malformed-special-attrs.rs:7:1
|
||||
@@ -37,3 +34,4 @@ LL | #[derive = ""]
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//@ edition:2018
|
||||
//@ aux-build: remove-extern-crate.rs
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//@ edition:2018
|
||||
//@ aux-build: remove-extern-crate.rs
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
error: expected identifier, found `"macro_use"`
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:7:18
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:8:18
|
||||
|
|
||||
LL | #[cfg_attr(test, "macro_use")]
|
||||
| ^^^^^^^^^^^ expected identifier
|
||||
| -----------------^^^^^^^^^^^--
|
||||
| | |
|
||||
| | expected identifier
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
error: expected one of `(`, `,`, `::`, or `=`, found `<eof>`
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:12:16
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:13:16
|
||||
|
|
||||
LL | #[cfg_attr(test)]
|
||||
| ^^^^ expected one of `(`, `,`, `::`, or `=`
|
||||
| -----------^^^^--
|
||||
| | |
|
||||
| | expected one of `(`, `,`, `::`, or `=`
|
||||
| help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
|
||||
|
|
||||
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:8:1
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:9:1
|
||||
|
|
||||
LL | extern crate remove_extern_crate as foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unused
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:5:9
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:6:9
|
||||
|
|
||||
LL | #![warn(rust_2018_idioms)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
@@ -36,7 +40,7 @@ LL +
|
||||
|
|
||||
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:9:1
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:10:1
|
||||
|
|
||||
LL | extern crate core;
|
||||
| ^^^^^^^^^^^^^^^^^^ unused
|
||||
@@ -48,7 +52,7 @@ LL +
|
||||
|
|
||||
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:13:5
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:14:5
|
||||
|
|
||||
LL | extern crate remove_extern_crate as foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unused
|
||||
@@ -61,7 +65,7 @@ LL +
|
||||
|
|
||||
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:14:5
|
||||
--> $DIR/removing-extern-crate-malformed-cfg.rs:15:5
|
||||
|
|
||||
LL | extern crate core;
|
||||
| ^^^^^^^^^^^^^^^^^^ unused
|
||||
|
||||
Reference in New Issue
Block a user