mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Allow attributes in formal function parameters
This commit is contained in:
parent
5c45343f11
commit
1eaaf440d5
@ -66,3 +66,9 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ThinVec<T> {
|
||||
(**self).hash_stable(hcx, hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for ThinVec<T> {
|
||||
fn default() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ use rustc::session::Session;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast::*;
|
||||
use syntax::attr;
|
||||
use syntax::feature_gate::is_builtin_attr;
|
||||
use syntax::source_map::Spanned;
|
||||
use syntax::symbol::{kw, sym};
|
||||
use syntax::ptr::P;
|
||||
@ -365,6 +366,29 @@ impl<'a> AstValidator<'a> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn_decl(&self, fn_decl: &FnDecl) {
|
||||
fn_decl
|
||||
.inputs
|
||||
.iter()
|
||||
.flat_map(|i| i.attrs.as_ref())
|
||||
.filter(|attr| {
|
||||
let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn];
|
||||
!arr.contains(&attr.name_or_empty()) && is_builtin_attr(attr)
|
||||
})
|
||||
.for_each(|attr| if attr.is_sugared_doc {
|
||||
let mut err = self.err_handler().struct_span_err(
|
||||
attr.span,
|
||||
"documentation comments cannot be applied to function parameters"
|
||||
);
|
||||
err.span_label(attr.span, "doc comments are not allowed here");
|
||||
err.emit();
|
||||
}
|
||||
else {
|
||||
self.err_handler().span_err(attr.span, "allow, cfg, cfg_attr, deny, \
|
||||
forbid, and warn are the only allowed built-in attributes in function parameters")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
enum GenericPosition {
|
||||
@ -470,6 +494,9 @@ fn validate_generics_order<'a>(
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match expr.node {
|
||||
ExprKind::Closure(_, _, _, ref fn_decl, _, _) => {
|
||||
self.check_fn_decl(fn_decl);
|
||||
}
|
||||
ExprKind::IfLet(_, ref expr, _, _) | ExprKind::WhileLet(_, ref expr, _, _) =>
|
||||
self.while_if_let_ambiguity(&expr),
|
||||
ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
|
||||
@ -484,6 +511,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
match ty.node {
|
||||
TyKind::BareFn(ref bfty) => {
|
||||
self.check_fn_decl(&bfty.decl);
|
||||
self.check_decl_no_pat(&bfty.decl, |span, _| {
|
||||
struct_span_err!(self.session, span, E0561,
|
||||
"patterns aren't allowed in function pointer types").emit();
|
||||
@ -601,10 +629,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
.note("only trait implementations may be annotated with default").emit();
|
||||
}
|
||||
}
|
||||
ItemKind::Fn(_, ref header, ref generics, _) => {
|
||||
ItemKind::Fn(ref decl, ref header, ref generics, _) => {
|
||||
self.visit_fn_header(header);
|
||||
self.check_fn_decl(decl);
|
||||
// We currently do not permit const generics in `const fn`, as
|
||||
// this is tantamount to allowing compile-time dependent typing.
|
||||
self.visit_fn_header(header);
|
||||
if header.constness.node == Constness::Const {
|
||||
// Look for const generics and error if we find any.
|
||||
for param in &generics.params {
|
||||
@ -657,6 +686,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||
for trait_item in trait_items {
|
||||
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
|
||||
self.check_fn_decl(&sig.decl);
|
||||
self.check_trait_fn_not_async(trait_item.span, sig.header.asyncness.node);
|
||||
self.check_trait_fn_not_const(sig.header.constness);
|
||||
if block.is_none() {
|
||||
@ -711,6 +741,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||
match fi.node {
|
||||
ForeignItemKind::Fn(ref decl, _) => {
|
||||
self.check_fn_decl(decl);
|
||||
self.check_decl_no_pat(decl, |span, _| {
|
||||
struct_span_err!(self.session, span, E0130,
|
||||
"patterns aren't allowed in foreign function declarations")
|
||||
@ -864,6 +895,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
"`async fn` is not permitted in the 2015 edition").emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
|
||||
match ii.node {
|
||||
ImplItemKind::Method(ref sig, _) => {
|
||||
self.check_fn_decl(&sig.decl);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_impl_item(self, ii);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) {
|
||||
|
@ -1770,6 +1770,7 @@ pub struct InlineAsm {
|
||||
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Arg {
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
pub ty: P<Ty>,
|
||||
pub pat: P<Pat>,
|
||||
pub id: NodeId,
|
||||
@ -1817,7 +1818,7 @@ impl Arg {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_self(eself: ExplicitSelf, eself_ident: Ident) -> Arg {
|
||||
pub fn from_self(attrs: ThinVec<Attribute>, eself: ExplicitSelf, eself_ident: Ident) -> Arg {
|
||||
let span = eself.span.to(eself_ident.span);
|
||||
let infer_ty = P(Ty {
|
||||
id: DUMMY_NODE_ID,
|
||||
@ -1825,6 +1826,7 @@ impl Arg {
|
||||
span,
|
||||
});
|
||||
let arg = |mutbl, ty| Arg {
|
||||
attrs,
|
||||
pat: P(Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
|
||||
|
@ -724,7 +724,7 @@ macro_rules! derive_has_attrs {
|
||||
|
||||
derive_has_attrs! {
|
||||
Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
|
||||
ast::Field, ast::FieldPat, ast::Variant_
|
||||
ast::Field, ast::FieldPat, ast::Variant_, ast::Arg
|
||||
}
|
||||
|
||||
pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
|
||||
|
@ -298,6 +298,10 @@ impl<'a> StripUnconfigured<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
|
||||
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
|
||||
}
|
||||
|
||||
/// Denies `#[cfg]` on generic parameters until we decide what to do with it.
|
||||
/// See issue #51279.
|
||||
pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
|
||||
@ -364,6 +368,11 @@ impl<'a> MutVisitor for StripUnconfigured<'a> {
|
||||
self.configure_pat(pat);
|
||||
noop_visit_pat(pat, self)
|
||||
}
|
||||
|
||||
fn visit_fn_decl(&mut self, mut fn_decl: &mut P<ast::FnDecl>) {
|
||||
self.configure_fn_decl(&mut fn_decl);
|
||||
noop_visit_fn_decl(fn_decl, self);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_cfg(attr: &ast::Attribute) -> bool {
|
||||
|
@ -963,9 +963,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
|
||||
let arg_pat = self.pat_ident(span, ident);
|
||||
ast::Arg {
|
||||
ty,
|
||||
attrs: ThinVec::default(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
pat: arg_pat,
|
||||
id: ast::DUMMY_NODE_ID
|
||||
ty,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1616,6 +1616,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||
*id = self.cx.resolver.next_node_id()
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn_decl(&mut self, mut fn_decl: &mut P<ast::FnDecl>) {
|
||||
self.cfg.configure_fn_decl(&mut fn_decl);
|
||||
noop_visit_fn_decl(fn_decl, self);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExpansionConfig<'feat> {
|
||||
|
@ -560,6 +560,9 @@ declare_features! (
|
||||
// Allows the user of associated type bounds.
|
||||
(active, associated_type_bounds, "1.34.0", Some(52662), None),
|
||||
|
||||
// Attributes on formal function params
|
||||
(active, param_attrs, "1.36.0", Some(60406), None),
|
||||
|
||||
// Allows calling constructor functions in `const fn`
|
||||
// FIXME Create issue
|
||||
(active, const_constructor, "1.37.0", Some(61456), None),
|
||||
@ -2508,6 +2511,18 @@ pub fn check_crate(krate: &ast::Crate,
|
||||
parse_sess: sess,
|
||||
plugin_attributes,
|
||||
};
|
||||
|
||||
sess
|
||||
.param_attr_spans
|
||||
.borrow()
|
||||
.iter()
|
||||
.for_each(|span| gate_feature!(
|
||||
&ctx,
|
||||
param_attrs,
|
||||
*span,
|
||||
"attributes on function parameters are unstable"
|
||||
));
|
||||
|
||||
let visitor = &mut PostExpansionVisitor {
|
||||
context: &ctx,
|
||||
builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
|
||||
|
@ -568,8 +568,9 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty }: &mut Arg, vis: &mut T) {
|
||||
pub fn noop_visit_arg<T: MutVisitor>(Arg { attrs, id, pat, ty }: &mut Arg, vis: &mut T) {
|
||||
vis.visit_id(id);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_ty(ty);
|
||||
}
|
||||
|
@ -18,6 +18,14 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
|
||||
permitted in this context";
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
attrs.iter().for_each(|a|
|
||||
self.sess.param_attr_spans.borrow_mut().push(a.span)
|
||||
);
|
||||
Ok(attrs)
|
||||
}
|
||||
|
||||
/// Parse attributes that appear before an item
|
||||
crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
|
||||
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
||||
@ -35,7 +43,8 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
let inner_parse_policy =
|
||||
InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason };
|
||||
attrs.push(self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?);
|
||||
let attr = self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?;
|
||||
attrs.push(attr);
|
||||
just_parsed_doc_comment = false;
|
||||
}
|
||||
token::DocComment(s) => {
|
||||
|
@ -28,7 +28,7 @@ crate fn dummy_arg(ident: Ident) -> Arg {
|
||||
span: ident.span,
|
||||
id: ast::DUMMY_NODE_ID
|
||||
};
|
||||
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
|
||||
Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, ty: P(ty) }
|
||||
}
|
||||
|
||||
pub enum Error {
|
||||
@ -1074,11 +1074,11 @@ impl<'a> Parser<'a> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
crate fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
|
||||
crate fn eat_incorrect_doc_comment_for_arg_type(&mut self) {
|
||||
if let token::DocComment(_) = self.token.kind {
|
||||
let mut err = self.diagnostic().struct_span_err(
|
||||
self.token.span,
|
||||
&format!("documentation comments cannot be applied to {}", applied_to),
|
||||
"documentation comments cannot be applied to a function parameter's type",
|
||||
);
|
||||
err.span_label(self.token.span, "doc comments are not allowed here");
|
||||
err.emit();
|
||||
@ -1095,7 +1095,7 @@ impl<'a> Parser<'a> {
|
||||
self.bump();
|
||||
let mut err = self.diagnostic().struct_span_err(
|
||||
sp,
|
||||
&format!("attributes cannot be applied to {}", applied_to),
|
||||
"attributes cannot be applied to a function parameter's type",
|
||||
);
|
||||
err.span_label(sp, "attributes are not allowed here");
|
||||
err.emit();
|
||||
|
@ -1532,6 +1532,7 @@ mod tests {
|
||||
buffered_lints: Lock::new(vec![]),
|
||||
edition: Edition::from_session(),
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
param_attr_spans: Lock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ pub struct ParseSess {
|
||||
/// operation token that followed it, but that the parser cannot identify without further
|
||||
/// analysis.
|
||||
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
|
||||
pub param_attr_spans: Lock<Vec<Span>>
|
||||
}
|
||||
|
||||
impl ParseSess {
|
||||
@ -79,6 +80,7 @@ impl ParseSess {
|
||||
buffered_lints: Lock::new(vec![]),
|
||||
edition: Edition::from_session(),
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
param_attr_spans: Lock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1188,8 @@ impl<'a> Parser<'a> {
|
||||
// definition...
|
||||
|
||||
// We don't allow argument names to be left off in edition 2018.
|
||||
p.parse_arg_general(p.token.span.rust_2018(), true, false)
|
||||
let is_name_required = p.token.span.rust_2018();
|
||||
p.parse_arg_general(true, false, |_| is_name_required)
|
||||
})?;
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
|
||||
@ -1487,26 +1488,31 @@ impl<'a> Parser<'a> {
|
||||
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
|
||||
/// error.
|
||||
/// This version of parse arg doesn't necessarily require identifier names.
|
||||
fn parse_arg_general(
|
||||
fn parse_arg_general<F>(
|
||||
&mut self,
|
||||
require_name: bool,
|
||||
is_trait_item: bool,
|
||||
allow_c_variadic: bool,
|
||||
) -> PResult<'a, Arg> {
|
||||
if let Ok(Some(arg)) = self.parse_self_arg() {
|
||||
is_name_required: F,
|
||||
) -> PResult<'a, Arg>
|
||||
where
|
||||
F: Fn(&token::Token) -> bool
|
||||
{
|
||||
let attrs = self.parse_arg_attributes()?;
|
||||
if let Ok(Some(mut arg)) = self.parse_self_arg() {
|
||||
arg.attrs = attrs.into();
|
||||
return self.recover_bad_self_arg(arg, is_trait_item);
|
||||
}
|
||||
|
||||
let (pat, ty) = if require_name || self.is_named_argument() {
|
||||
debug!("parse_arg_general parse_pat (require_name:{})", require_name);
|
||||
self.eat_incorrect_doc_comment("method arguments");
|
||||
let pat = self.parse_pat(Some("argument name"))?;
|
||||
let is_name_required = is_name_required(&self.token);
|
||||
let (pat, ty) = if is_name_required || self.is_named_argument() {
|
||||
debug!("parse_arg_general parse_pat (is_name_required:{})", is_name_required);
|
||||
|
||||
let pat = self.parse_pat(Some("argument name"))?;
|
||||
if let Err(mut err) = self.expect(&token::Colon) {
|
||||
if let Some(ident) = self.argument_without_type(
|
||||
&mut err,
|
||||
pat,
|
||||
require_name,
|
||||
is_name_required,
|
||||
is_trait_item,
|
||||
) {
|
||||
err.emit();
|
||||
@ -1516,12 +1522,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
self.eat_incorrect_doc_comment("a method argument's type");
|
||||
self.eat_incorrect_doc_comment_for_arg_type();
|
||||
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
|
||||
} else {
|
||||
debug!("parse_arg_general ident_to_pat");
|
||||
let parser_snapshot_before_ty = self.clone();
|
||||
self.eat_incorrect_doc_comment("a method argument's type");
|
||||
self.eat_incorrect_doc_comment_for_arg_type();
|
||||
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
|
||||
if ty.is_ok() && self.token != token::Comma &&
|
||||
self.token != token::CloseDelim(token::Paren) {
|
||||
@ -1554,11 +1560,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
|
||||
Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, ty })
|
||||
}
|
||||
|
||||
/// Parses an argument in a lambda header (e.g., `|arg, arg|`).
|
||||
fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
|
||||
let attrs = self.parse_arg_attributes()?;
|
||||
let pat = self.parse_pat(Some("argument name"))?;
|
||||
let t = if self.eat(&token::Colon) {
|
||||
self.parse_ty()?
|
||||
@ -1570,6 +1577,7 @@ impl<'a> Parser<'a> {
|
||||
})
|
||||
};
|
||||
Ok(Arg {
|
||||
attrs: attrs.into(),
|
||||
ty: t,
|
||||
pat,
|
||||
id: ast::DUMMY_NODE_ID
|
||||
@ -5411,15 +5419,19 @@ impl<'a> Parser<'a> {
|
||||
&token::CloseDelim(token::Paren),
|
||||
SeqSep::trailing_allowed(token::Comma),
|
||||
|p| {
|
||||
// If the argument is a C-variadic argument we should not
|
||||
// enforce named arguments.
|
||||
let enforce_named_args = if p.token == token::DotDotDot {
|
||||
false
|
||||
} else {
|
||||
named_args
|
||||
};
|
||||
match p.parse_arg_general(enforce_named_args, false,
|
||||
allow_c_variadic) {
|
||||
let do_not_enforce_named_arguments_for_c_variadic =
|
||||
|token: &token::Token| -> bool {
|
||||
if token == &token::DotDotDot {
|
||||
false
|
||||
} else {
|
||||
named_args
|
||||
}
|
||||
};
|
||||
match p.parse_arg_general(
|
||||
false,
|
||||
allow_c_variadic,
|
||||
do_not_enforce_named_arguments_for_c_variadic
|
||||
) {
|
||||
Ok(arg) => {
|
||||
if let TyKind::CVarArgs = arg.ty.node {
|
||||
c_variadic = true;
|
||||
@ -5464,7 +5476,6 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// Parses the argument list and result type of a function declaration.
|
||||
fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
|
||||
|
||||
let (args, c_variadic) = self.parse_fn_args(true, allow_c_variadic)?;
|
||||
let ret_ty = self.parse_ret_ty(true)?;
|
||||
|
||||
@ -5476,6 +5487,8 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Returns the parsed optional self argument and whether a self shortcut was used.
|
||||
///
|
||||
/// See `parse_self_arg_with_attrs` to collect attributes.
|
||||
fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
|
||||
let expect_ident = |this: &mut Self| match this.token.kind {
|
||||
// Preserve hygienic context.
|
||||
@ -5581,7 +5594,18 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
|
||||
let eself = source_map::respan(eself_lo.to(eself_hi), eself);
|
||||
Ok(Some(Arg::from_self(eself, eself_ident)))
|
||||
Ok(Some(Arg::from_self(ThinVec::default(), eself, eself_ident)))
|
||||
}
|
||||
|
||||
/// Returns the parsed optional self argument with attributes and whether a self
|
||||
/// shortcut was used.
|
||||
fn parse_self_arg_with_attrs(&mut self) -> PResult<'a, Option<Arg>> {
|
||||
let attrs = self.parse_arg_attributes()?;
|
||||
let arg_opt = self.parse_self_arg()?;
|
||||
Ok(arg_opt.map(|mut arg| {
|
||||
arg.attrs = attrs.into();
|
||||
arg
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parses the parameter list and result type of a function that may have a `self` parameter.
|
||||
@ -5591,7 +5615,7 @@ impl<'a> Parser<'a> {
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
|
||||
// Parse optional self argument.
|
||||
let self_arg = self.parse_self_arg()?;
|
||||
let self_arg = self.parse_self_arg_with_attrs()?;
|
||||
|
||||
// Parse the rest of the function parameter list.
|
||||
let sep = SeqSep::trailing_allowed(token::Comma);
|
||||
@ -5865,7 +5889,7 @@ impl<'a> Parser<'a> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
let decl = self.parse_fn_decl_with_self(|p| {
|
||||
p.parse_arg_general(true, true, false)
|
||||
p.parse_arg_general(true, false, |_| true)
|
||||
})?;
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
*at_end = true;
|
||||
@ -7441,7 +7465,7 @@ impl<'a> Parser<'a> {
|
||||
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
|
||||
let ident = self.parse_ident().unwrap();
|
||||
self.bump(); // `(`
|
||||
let kw_name = if let Ok(Some(_)) = self.parse_self_arg() {
|
||||
let kw_name = if let Ok(Some(_)) = self.parse_self_arg_with_attrs() {
|
||||
"method"
|
||||
} else {
|
||||
"function"
|
||||
@ -7492,7 +7516,7 @@ impl<'a> Parser<'a> {
|
||||
self.eat_to_tokens(&[&token::Gt]);
|
||||
self.bump(); // `>`
|
||||
let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
|
||||
if let Ok(Some(_)) = self.parse_self_arg() {
|
||||
if let Ok(Some(_)) = self.parse_self_arg_with_attrs() {
|
||||
("fn", "method", false)
|
||||
} else {
|
||||
("fn", "function", false)
|
||||
|
@ -550,8 +550,9 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
|
||||
|
||||
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
|
||||
for argument in &function_declaration.inputs {
|
||||
walk_list!(visitor, visit_attribute, argument.attrs.iter());
|
||||
visitor.visit_pat(&argument.pat);
|
||||
visitor.visit_ty(&argument.ty)
|
||||
visitor.visit_ty(&argument.ty);
|
||||
}
|
||||
visitor.visit_fn_ret_ty(&function_declaration.output)
|
||||
}
|
||||
|
@ -928,7 +928,7 @@ impl<'a> MethodDef<'a> {
|
||||
let args = {
|
||||
let self_args = explicit_self.map(|explicit_self| {
|
||||
let ident = Ident::with_empty_ctxt(kw::SelfLower).with_span_pos(trait_.span);
|
||||
ast::Arg::from_self(explicit_self, ident)
|
||||
ast::Arg::from_self(ThinVec::default(), explicit_self, ident)
|
||||
});
|
||||
let nonself_args = arg_types.into_iter()
|
||||
.map(|(name, ty)| cx.arg(trait_.span, name, ty));
|
||||
|
@ -444,6 +444,7 @@ symbols! {
|
||||
panic_implementation,
|
||||
panic_runtime,
|
||||
partial_cmp,
|
||||
param_attrs,
|
||||
PartialOrd,
|
||||
passes,
|
||||
pat,
|
||||
|
@ -1,20 +1,20 @@
|
||||
pub fn f(
|
||||
/// Comment
|
||||
//~^ ERROR documentation comments cannot be applied to method arguments
|
||||
//~^ ERROR documentation comments cannot be applied to function parameters
|
||||
//~| NOTE doc comments are not allowed here
|
||||
//~| ERROR attributes on function parameters are unstable
|
||||
//~| NOTE https://github.com/rust-lang/rust/issues/60406
|
||||
id: u8,
|
||||
/// Other
|
||||
//~^ ERROR documentation comments cannot be applied to method arguments
|
||||
//~^ ERROR documentation comments cannot be applied to function parameters
|
||||
//~| NOTE doc comments are not allowed here
|
||||
//~| ERROR attributes on function parameters are unstable
|
||||
//~| NOTE https://github.com/rust-lang/rust/issues/60406
|
||||
a: u8,
|
||||
) {}
|
||||
|
||||
fn foo(#[allow(dead_code)] id: i32) {}
|
||||
//~^ ERROR attributes cannot be applied to method arguments
|
||||
//~| NOTE attributes are not allowed here
|
||||
|
||||
fn bar(id: #[allow(dead_code)] i32) {}
|
||||
//~^ ERROR attributes cannot be applied to a method argument's type
|
||||
//~^ ERROR attributes cannot be applied to a function parameter's type
|
||||
//~| NOTE attributes are not allowed here
|
||||
|
||||
fn main() {
|
||||
@ -26,10 +26,6 @@ fn main() {
|
||||
//~| ERROR mismatched types
|
||||
//~| NOTE expected u8, found reference
|
||||
//~| NOTE expected
|
||||
foo("");
|
||||
//~^ ERROR mismatched types
|
||||
//~| NOTE expected i32, found reference
|
||||
//~| NOTE expected
|
||||
bar("");
|
||||
//~^ ERROR mismatched types
|
||||
//~| NOTE expected i32, found reference
|
||||
|
@ -1,26 +1,38 @@
|
||||
error: documentation comments cannot be applied to method arguments
|
||||
error: attributes cannot be applied to a function parameter's type
|
||||
--> $DIR/fn-arg-doc-comment.rs:16:12
|
||||
|
|
||||
LL | fn bar(id: #[allow(dead_code)] i32) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/fn-arg-doc-comment.rs:2:5
|
||||
|
|
||||
LL | /// Comment
|
||||
| ^^^^^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to method arguments
|
||||
--> $DIR/fn-arg-doc-comment.rs:6:5
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/fn-arg-doc-comment.rs:8:5
|
||||
|
|
||||
LL | /// Other
|
||||
| ^^^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: attributes cannot be applied to method arguments
|
||||
--> $DIR/fn-arg-doc-comment.rs:12:8
|
||||
error[E0658]: attributes on function parameters are unstable
|
||||
--> $DIR/fn-arg-doc-comment.rs:2:5
|
||||
|
|
||||
LL | fn foo(#[allow(dead_code)] id: i32) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
|
||||
LL | /// Comment
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60406
|
||||
= help: add #![feature(param_attrs)] to the crate attributes to enable
|
||||
|
||||
error: attributes cannot be applied to a method argument's type
|
||||
--> $DIR/fn-arg-doc-comment.rs:16:12
|
||||
error[E0658]: attributes on function parameters are unstable
|
||||
--> $DIR/fn-arg-doc-comment.rs:8:5
|
||||
|
|
||||
LL | fn bar(id: #[allow(dead_code)] i32) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
|
||||
LL | /// Other
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60406
|
||||
= help: add #![feature(param_attrs)] to the crate attributes to enable
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-arg-doc-comment.rs:22:7
|
||||
@ -43,15 +55,6 @@ LL | f("", "");
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-arg-doc-comment.rs:29:9
|
||||
|
|
||||
LL | foo("");
|
||||
| ^^ expected i32, found reference
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-arg-doc-comment.rs:33:9
|
||||
|
|
||||
LL | bar("");
|
||||
| ^^ expected i32, found reference
|
||||
|
|
||||
@ -60,4 +63,5 @@ LL | bar("");
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Some errors have detailed explanations: E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
8
src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
Normal file
8
src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(param_attrs)]
|
||||
|
||||
trait Trait2015 { fn foo(#[allow(C)] i32); }
|
||||
//~^ ERROR expected one of `:` or `@`, found `)`
|
||||
|
||||
fn main() {}
|
18
src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
Normal file
18
src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error: expected one of `:` or `@`, found `)`
|
||||
--> $DIR/param-attrs-2018.rs:5:41
|
||||
|
|
||||
LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
|
||||
| ^ expected one of `:` or `@` here
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this was a parameter name, give it a type
|
||||
|
|
||||
LL | trait Trait2015 { fn foo(#[allow(C)] i32: TypeName); }
|
||||
| ^^^^^^^^^^^^^
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | trait Trait2015 { fn foo(#[allow(C)] _: i32); }
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
225
src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
Normal file
225
src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
Normal file
@ -0,0 +1,225 @@
|
||||
// compile-flags: --cfg something
|
||||
// compile-pass
|
||||
|
||||
#![feature(param_attrs)]
|
||||
|
||||
extern "C" {
|
||||
fn ffi(
|
||||
#[allow(C)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(something, cfg(nothing))] c: i32,
|
||||
#[deny(C)] d: i32,
|
||||
#[forbid(C)] #[warn(C)] ...
|
||||
);
|
||||
}
|
||||
|
||||
type FnType = fn(
|
||||
#[allow(C)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(something, cfg(nothing))] c: i32,
|
||||
#[deny(C)] d: i32,
|
||||
#[forbid(C)] #[warn(C)] e: i32
|
||||
);
|
||||
|
||||
pub fn foo(
|
||||
#[allow(C)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(something, cfg(nothing))] c: i32,
|
||||
#[deny(C)] d: i32,
|
||||
#[forbid(C)] #[warn(C)] e: i32
|
||||
) {}
|
||||
|
||||
// self, &self and &mut self
|
||||
|
||||
struct SelfStruct {}
|
||||
impl SelfStruct {
|
||||
fn foo(
|
||||
#[allow(C)] self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
|
||||
struct RefStruct {}
|
||||
impl RefStruct {
|
||||
fn foo(
|
||||
#[allow(C)] &self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait RefTrait {
|
||||
fn foo(
|
||||
#[forbid(C)] &self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl RefTrait for RefStruct {
|
||||
fn foo(
|
||||
#[forbid(C)] &self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
struct MutStruct {}
|
||||
impl MutStruct {
|
||||
fn foo(
|
||||
#[allow(C)] &mut self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait MutTrait {
|
||||
fn foo(
|
||||
#[forbid(C)] &mut self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl MutTrait for MutStruct {
|
||||
fn foo(
|
||||
#[forbid(C)] &mut self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
// self: Self, self: &Self and self: &mut Self
|
||||
|
||||
struct NamedSelfSelfStruct {}
|
||||
impl NamedSelfSelfStruct {
|
||||
fn foo(
|
||||
#[allow(C)] self: Self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
|
||||
struct NamedSelfRefStruct {}
|
||||
impl NamedSelfRefStruct {
|
||||
fn foo(
|
||||
#[allow(C)] self: &Self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait NamedSelfRefTrait {
|
||||
fn foo(
|
||||
#[forbid(C)] self: &Self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl NamedSelfRefTrait for NamedSelfRefStruct {
|
||||
fn foo(
|
||||
#[forbid(C)] self: &Self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
struct NamedSelfMutStruct {}
|
||||
impl NamedSelfMutStruct {
|
||||
fn foo(
|
||||
#[allow(C)] self: &mut Self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait NamedSelfMutTrait {
|
||||
fn foo(
|
||||
#[forbid(C)] self: &mut Self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl NamedSelfMutTrait for NamedSelfMutStruct {
|
||||
fn foo(
|
||||
#[forbid(C)] self: &mut Self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
// &'a self and &'a mut self
|
||||
|
||||
struct NamedLifetimeRefStruct {}
|
||||
impl NamedLifetimeRefStruct {
|
||||
fn foo<'a>(
|
||||
#[allow(C)] self: &'a Self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait NamedLifetimeRefTrait {
|
||||
fn foo<'a>(
|
||||
#[forbid(C)] &'a self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl NamedLifetimeRefTrait for NamedLifetimeRefStruct {
|
||||
fn foo<'a>(
|
||||
#[forbid(C)] &'a self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
struct NamedLifetimeMutStruct {}
|
||||
impl NamedLifetimeMutStruct {
|
||||
fn foo<'a>(
|
||||
#[allow(C)] self: &'a mut Self,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait NamedLifetimeMutTrait {
|
||||
fn foo<'a>(
|
||||
#[forbid(C)] &'a mut self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl NamedLifetimeMutTrait for NamedLifetimeMutStruct {
|
||||
fn foo<'a>(
|
||||
#[forbid(C)] &'a mut self,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
// Box<Self>
|
||||
|
||||
struct BoxSelfStruct {}
|
||||
impl BoxSelfStruct {
|
||||
fn foo(
|
||||
#[allow(C)] self: Box<Self>,
|
||||
#[cfg(something)] a: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] b: i32,
|
||||
) {}
|
||||
}
|
||||
trait BoxSelfTrait {
|
||||
fn foo(
|
||||
#[forbid(C)] self: Box<Self>,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
impl BoxSelfTrait for BoxSelfStruct {
|
||||
fn foo(
|
||||
#[forbid(C)] self: Box<Self>,
|
||||
#[warn(C)] a: i32
|
||||
) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: unsafe extern "C" fn(_, _, _, ...) = ffi;
|
||||
let _: fn(_, _, _, _) = foo;
|
||||
let _: FnType = |_, _, _, _| {};
|
||||
let c = |
|
||||
#[allow(C)] a: u32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(something, cfg(nothing))]
|
||||
#[deny(C)] c: i32,
|
||||
| {};
|
||||
let _ = c(1, 2);
|
||||
}
|
145
src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
Normal file
145
src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
Normal file
@ -0,0 +1,145 @@
|
||||
#![feature(param_attrs)]
|
||||
|
||||
extern "C" {
|
||||
fn ffi(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: i32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
);
|
||||
}
|
||||
|
||||
type FnType = fn(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: u32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
);
|
||||
|
||||
pub fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: u32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
) {}
|
||||
|
||||
struct SelfStruct {}
|
||||
impl SelfStruct {
|
||||
fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
self,
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: i32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Qux
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
) {}
|
||||
}
|
||||
|
||||
struct RefStruct {}
|
||||
impl RefStruct {
|
||||
fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
&self,
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: i32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Qux
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
) {}
|
||||
}
|
||||
trait RefTrait {
|
||||
fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
&self,
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: i32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Qux
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
) {}
|
||||
}
|
||||
impl RefTrait for RefStruct {
|
||||
fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
&self,
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: i32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Qux
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32,
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = |
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[test] a: u32,
|
||||
//~^ ERROR The attribute `test` is currently unknown to the compiler and may have
|
||||
/// Bar
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[must_use]
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
/// Baz
|
||||
//~^ ERROR documentation comments cannot be applied to function
|
||||
#[no_mangle] b: i32
|
||||
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
|
||||
| {};
|
||||
}
|
@ -0,0 +1,339 @@
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:5:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:9:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:11:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:13:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:15:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:21:5
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:25:5
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:27:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:29:5
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:31:5
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:36:5
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:40:5
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:42:5
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:44:5
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:46:5
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:53:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:56:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:60:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:62:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:64:9
|
||||
|
|
||||
LL | /// Qux
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:66:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:74:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:77:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:81:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:83:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:85:9
|
||||
|
|
||||
LL | /// Qux
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:87:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:93:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:96:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:100:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:102:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:104:9
|
||||
|
|
||||
LL | /// Qux
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:106:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:112:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:115:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:119:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:121:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:123:9
|
||||
|
|
||||
LL | /// Qux
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:125:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32,
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:132:9
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:136:9
|
||||
|
|
||||
LL | /// Bar
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:138:9
|
||||
|
|
||||
LL | #[must_use]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:140:9
|
||||
|
|
||||
LL | /// Baz
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:142:9
|
||||
|
|
||||
LL | #[no_mangle] b: i32
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:7:9
|
||||
|
|
||||
LL | #[test] a: i32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:23:5
|
||||
|
|
||||
LL | #[test] a: u32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:38:5
|
||||
|
|
||||
LL | #[test] a: u32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:58:9
|
||||
|
|
||||
LL | #[test] a: i32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:79:9
|
||||
|
|
||||
LL | #[test] a: i32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:98:9
|
||||
|
|
||||
LL | #[test] a: i32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:117:9
|
||||
|
|
||||
LL | #[test] a: i32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: The attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
|
||||
--> $DIR/param-attrs-builtin-attrs.rs:134:9
|
||||
|
|
||||
LL | #[test] a: u32,
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
|
||||
= help: add #![feature(custom_attribute)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 52 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
79
src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
Normal file
79
src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
Normal file
@ -0,0 +1,79 @@
|
||||
// compile-flags: --cfg something
|
||||
|
||||
#![feature(param_attrs)]
|
||||
#![deny(unused_variables)]
|
||||
|
||||
extern "C" {
|
||||
fn ffi(
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(something, cfg(nothing))] c: i32,
|
||||
#[cfg_attr(nothing, cfg(nothing))] ...
|
||||
);
|
||||
}
|
||||
|
||||
type FnType = fn(
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
);
|
||||
|
||||
fn foo(
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
//~^ ERROR unused variable: `b` [unused_variables]
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
//~^ ERROR unused variable: `c` [unused_variables]
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
) {}
|
||||
|
||||
struct RefStruct {}
|
||||
impl RefStruct {
|
||||
fn bar(
|
||||
&self,
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
//~^ ERROR unused variable: `b` [unused_variables]
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
//~^ ERROR unused variable: `c` [unused_variables]
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
) {}
|
||||
}
|
||||
trait RefTrait {
|
||||
fn bar(
|
||||
&self,
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
//~^ ERROR unused variable: `b` [unused_variables]
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
//~^ ERROR unused variable: `c` [unused_variables]
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
) {}
|
||||
}
|
||||
impl RefTrait for RefStruct {
|
||||
fn bar(
|
||||
&self,
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
//~^ ERROR unused variable: `b` [unused_variables]
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
//~^ ERROR unused variable: `c` [unused_variables]
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: unsafe extern "C" fn(_, ...) = ffi;
|
||||
let _: fn(_, _) = foo;
|
||||
let _: FnType = |_, _| {};
|
||||
let c = |
|
||||
#[cfg(nothing)] a: i32,
|
||||
#[cfg(something)] b: i32,
|
||||
//~^ ERROR unused variable: `b` [unused_variables]
|
||||
#[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
//~^ ERROR unused variable: `c` [unused_variables]
|
||||
#[cfg_attr(something, cfg(nothing))] d: i32,
|
||||
| {};
|
||||
let _ = c(1, 2);
|
||||
}
|
68
src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
Normal file
68
src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
Normal file
@ -0,0 +1,68 @@
|
||||
error: unused variable: `b`
|
||||
--> $DIR/param-attrs-cfg.rs:24:23
|
||||
|
|
||||
LL | #[cfg(something)] b: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_b`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/param-attrs-cfg.rs:4:9
|
||||
|
|
||||
LL | #![deny(unused_variables)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused variable: `c`
|
||||
--> $DIR/param-attrs-cfg.rs:26:40
|
||||
|
|
||||
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_c`
|
||||
|
||||
error: unused variable: `b`
|
||||
--> $DIR/param-attrs-cfg.rs:72:27
|
||||
|
|
||||
LL | #[cfg(something)] b: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_b`
|
||||
|
||||
error: unused variable: `c`
|
||||
--> $DIR/param-attrs-cfg.rs:74:44
|
||||
|
|
||||
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_c`
|
||||
|
||||
error: unused variable: `b`
|
||||
--> $DIR/param-attrs-cfg.rs:47:27
|
||||
|
|
||||
LL | #[cfg(something)] b: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_b`
|
||||
|
||||
error: unused variable: `c`
|
||||
--> $DIR/param-attrs-cfg.rs:49:44
|
||||
|
|
||||
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_c`
|
||||
|
||||
error: unused variable: `b`
|
||||
--> $DIR/param-attrs-cfg.rs:36:27
|
||||
|
|
||||
LL | #[cfg(something)] b: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_b`
|
||||
|
||||
error: unused variable: `c`
|
||||
--> $DIR/param-attrs-cfg.rs:38:44
|
||||
|
|
||||
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_c`
|
||||
|
||||
error: unused variable: `b`
|
||||
--> $DIR/param-attrs-cfg.rs:58:27
|
||||
|
|
||||
LL | #[cfg(something)] b: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_b`
|
||||
|
||||
error: unused variable: `c`
|
||||
--> $DIR/param-attrs-cfg.rs:60:44
|
||||
|
|
||||
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
|
||||
| ^ help: consider prefixing with an underscore: `_c`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
14
src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
Normal file
14
src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// gate-test-param_attrs
|
||||
|
||||
fn foo(
|
||||
/// Foo
|
||||
//~^ ERROR documentation comments cannot be applied to function parameters
|
||||
//~| NOTE doc comments are not allowed here
|
||||
//~| ERROR attributes on function parameters are unstable
|
||||
//~| NOTE https://github.com/rust-lang/rust/issues/60406
|
||||
#[allow(C)] a: u8
|
||||
//~^ ERROR attributes on function parameters are unstable
|
||||
//~| NOTE https://github.com/rust-lang/rust/issues/60406
|
||||
) {}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,27 @@
|
||||
error: documentation comments cannot be applied to function parameters
|
||||
--> $DIR/param-attrs-feature-gate.rs:4:5
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^ doc comments are not allowed here
|
||||
|
||||
error[E0658]: attributes on function parameters are unstable
|
||||
--> $DIR/param-attrs-feature-gate.rs:4:5
|
||||
|
|
||||
LL | /// Foo
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60406
|
||||
= help: add #![feature(param_attrs)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: attributes on function parameters are unstable
|
||||
--> $DIR/param-attrs-feature-gate.rs:9:5
|
||||
|
|
||||
LL | #[allow(C)] a: u8
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/60406
|
||||
= help: add #![feature(param_attrs)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user