mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +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)
|
(**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 rustc_data_structures::fx::FxHashMap;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
|
use syntax::feature_gate::is_builtin_attr;
|
||||||
use syntax::source_map::Spanned;
|
use syntax::source_map::Spanned;
|
||||||
use syntax::symbol::{kw, sym};
|
use syntax::symbol::{kw, sym};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
@ -365,6 +366,29 @@ impl<'a> AstValidator<'a> {
|
|||||||
_ => None,
|
_ => 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 {
|
enum GenericPosition {
|
||||||
@ -470,6 +494,9 @@ fn validate_generics_order<'a>(
|
|||||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
|
ExprKind::Closure(_, _, _, ref fn_decl, _, _) => {
|
||||||
|
self.check_fn_decl(fn_decl);
|
||||||
|
}
|
||||||
ExprKind::IfLet(_, ref expr, _, _) | ExprKind::WhileLet(_, ref expr, _, _) =>
|
ExprKind::IfLet(_, ref expr, _, _) | ExprKind::WhileLet(_, ref expr, _, _) =>
|
||||||
self.while_if_let_ambiguity(&expr),
|
self.while_if_let_ambiguity(&expr),
|
||||||
ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => {
|
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) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
match ty.node {
|
match ty.node {
|
||||||
TyKind::BareFn(ref bfty) => {
|
TyKind::BareFn(ref bfty) => {
|
||||||
|
self.check_fn_decl(&bfty.decl);
|
||||||
self.check_decl_no_pat(&bfty.decl, |span, _| {
|
self.check_decl_no_pat(&bfty.decl, |span, _| {
|
||||||
struct_span_err!(self.session, span, E0561,
|
struct_span_err!(self.session, span, E0561,
|
||||||
"patterns aren't allowed in function pointer types").emit();
|
"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();
|
.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
|
// We currently do not permit const generics in `const fn`, as
|
||||||
// this is tantamount to allowing compile-time dependent typing.
|
// this is tantamount to allowing compile-time dependent typing.
|
||||||
self.visit_fn_header(header);
|
|
||||||
if header.constness.node == Constness::Const {
|
if header.constness.node == Constness::Const {
|
||||||
// Look for const generics and error if we find any.
|
// Look for const generics and error if we find any.
|
||||||
for param in &generics.params {
|
for param in &generics.params {
|
||||||
@ -657,6 +686,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
self.no_questions_in_bounds(bounds, "supertraits", true);
|
self.no_questions_in_bounds(bounds, "supertraits", true);
|
||||||
for trait_item in trait_items {
|
for trait_item in trait_items {
|
||||||
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
|
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_async(trait_item.span, sig.header.asyncness.node);
|
||||||
self.check_trait_fn_not_const(sig.header.constness);
|
self.check_trait_fn_not_const(sig.header.constness);
|
||||||
if block.is_none() {
|
if block.is_none() {
|
||||||
@ -711,6 +741,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||||
match fi.node {
|
match fi.node {
|
||||||
ForeignItemKind::Fn(ref decl, _) => {
|
ForeignItemKind::Fn(ref decl, _) => {
|
||||||
|
self.check_fn_decl(decl);
|
||||||
self.check_decl_no_pat(decl, |span, _| {
|
self.check_decl_no_pat(decl, |span, _| {
|
||||||
struct_span_err!(self.session, span, E0130,
|
struct_span_err!(self.session, span, E0130,
|
||||||
"patterns aren't allowed in foreign function declarations")
|
"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();
|
"`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) {
|
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)`.
|
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Arg {
|
pub struct Arg {
|
||||||
|
pub attrs: ThinVec<Attribute>,
|
||||||
pub ty: P<Ty>,
|
pub ty: P<Ty>,
|
||||||
pub pat: P<Pat>,
|
pub pat: P<Pat>,
|
||||||
pub id: NodeId,
|
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 span = eself.span.to(eself_ident.span);
|
||||||
let infer_ty = P(Ty {
|
let infer_ty = P(Ty {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
@ -1825,6 +1826,7 @@ impl Arg {
|
|||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
let arg = |mutbl, ty| Arg {
|
let arg = |mutbl, ty| Arg {
|
||||||
|
attrs,
|
||||||
pat: P(Pat {
|
pat: P(Pat {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
|
node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
|
||||||
|
@ -724,7 +724,7 @@ macro_rules! derive_has_attrs {
|
|||||||
|
|
||||||
derive_has_attrs! {
|
derive_has_attrs! {
|
||||||
Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
|
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 {
|
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.
|
/// Denies `#[cfg]` on generic parameters until we decide what to do with it.
|
||||||
/// See issue #51279.
|
/// See issue #51279.
|
||||||
pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
|
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);
|
self.configure_pat(pat);
|
||||||
noop_visit_pat(pat, self)
|
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 {
|
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 {
|
fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
|
||||||
let arg_pat = self.pat_ident(span, ident);
|
let arg_pat = self.pat_ident(span, ident);
|
||||||
ast::Arg {
|
ast::Arg {
|
||||||
ty,
|
attrs: ThinVec::default(),
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
pat: arg_pat,
|
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()
|
*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> {
|
pub struct ExpansionConfig<'feat> {
|
||||||
|
@ -560,6 +560,9 @@ declare_features! (
|
|||||||
// Allows the user of associated type bounds.
|
// Allows the user of associated type bounds.
|
||||||
(active, associated_type_bounds, "1.34.0", Some(52662), None),
|
(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`
|
// Allows calling constructor functions in `const fn`
|
||||||
// FIXME Create issue
|
// FIXME Create issue
|
||||||
(active, const_constructor, "1.37.0", Some(61456), None),
|
(active, const_constructor, "1.37.0", Some(61456), None),
|
||||||
@ -2508,6 +2511,18 @@ pub fn check_crate(krate: &ast::Crate,
|
|||||||
parse_sess: sess,
|
parse_sess: sess,
|
||||||
plugin_attributes,
|
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 {
|
let visitor = &mut PostExpansionVisitor {
|
||||||
context: &ctx,
|
context: &ctx,
|
||||||
builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
|
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);
|
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);
|
vis.visit_id(id);
|
||||||
|
visit_thin_attrs(attrs, vis);
|
||||||
vis.visit_pat(pat);
|
vis.visit_pat(pat);
|
||||||
vis.visit_ty(ty);
|
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";
|
permitted in this context";
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
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
|
/// Parse attributes that appear before an item
|
||||||
crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
|
crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
|
||||||
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
||||||
@ -35,7 +43,8 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
let inner_parse_policy =
|
let inner_parse_policy =
|
||||||
InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason };
|
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;
|
just_parsed_doc_comment = false;
|
||||||
}
|
}
|
||||||
token::DocComment(s) => {
|
token::DocComment(s) => {
|
||||||
|
@ -28,7 +28,7 @@ crate fn dummy_arg(ident: Ident) -> Arg {
|
|||||||
span: ident.span,
|
span: ident.span,
|
||||||
id: ast::DUMMY_NODE_ID
|
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 {
|
pub enum Error {
|
||||||
@ -1074,11 +1074,11 @@ impl<'a> Parser<'a> {
|
|||||||
Err(err)
|
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 {
|
if let token::DocComment(_) = self.token.kind {
|
||||||
let mut err = self.diagnostic().struct_span_err(
|
let mut err = self.diagnostic().struct_span_err(
|
||||||
self.token.span,
|
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.span_label(self.token.span, "doc comments are not allowed here");
|
||||||
err.emit();
|
err.emit();
|
||||||
@ -1095,7 +1095,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.bump();
|
self.bump();
|
||||||
let mut err = self.diagnostic().struct_span_err(
|
let mut err = self.diagnostic().struct_span_err(
|
||||||
sp,
|
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.span_label(sp, "attributes are not allowed here");
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -1532,6 +1532,7 @@ mod tests {
|
|||||||
buffered_lints: Lock::new(vec![]),
|
buffered_lints: Lock::new(vec![]),
|
||||||
edition: Edition::from_session(),
|
edition: Edition::from_session(),
|
||||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
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
|
/// operation token that followed it, but that the parser cannot identify without further
|
||||||
/// analysis.
|
/// analysis.
|
||||||
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
|
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
|
||||||
|
pub param_attr_spans: Lock<Vec<Span>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseSess {
|
impl ParseSess {
|
||||||
@ -79,6 +80,7 @@ impl ParseSess {
|
|||||||
buffered_lints: Lock::new(vec![]),
|
buffered_lints: Lock::new(vec![]),
|
||||||
edition: Edition::from_session(),
|
edition: Edition::from_session(),
|
||||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||||
|
param_attr_spans: Lock::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,7 +1188,8 @@ impl<'a> Parser<'a> {
|
|||||||
// definition...
|
// definition...
|
||||||
|
|
||||||
// We don't allow argument names to be left off in edition 2018.
|
// 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()?;
|
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
|
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
|
||||||
/// error.
|
/// error.
|
||||||
/// This version of parse arg doesn't necessarily require identifier names.
|
/// This version of parse arg doesn't necessarily require identifier names.
|
||||||
fn parse_arg_general(
|
fn parse_arg_general<F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
require_name: bool,
|
|
||||||
is_trait_item: bool,
|
is_trait_item: bool,
|
||||||
allow_c_variadic: bool,
|
allow_c_variadic: bool,
|
||||||
) -> PResult<'a, Arg> {
|
is_name_required: F,
|
||||||
if let Ok(Some(arg)) = self.parse_self_arg() {
|
) -> 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);
|
return self.recover_bad_self_arg(arg, is_trait_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (pat, ty) = if require_name || self.is_named_argument() {
|
let is_name_required = is_name_required(&self.token);
|
||||||
debug!("parse_arg_general parse_pat (require_name:{})", require_name);
|
let (pat, ty) = if is_name_required || self.is_named_argument() {
|
||||||
self.eat_incorrect_doc_comment("method arguments");
|
debug!("parse_arg_general parse_pat (is_name_required:{})", is_name_required);
|
||||||
let pat = self.parse_pat(Some("argument name"))?;
|
|
||||||
|
|
||||||
|
let pat = self.parse_pat(Some("argument name"))?;
|
||||||
if let Err(mut err) = self.expect(&token::Colon) {
|
if let Err(mut err) = self.expect(&token::Colon) {
|
||||||
if let Some(ident) = self.argument_without_type(
|
if let Some(ident) = self.argument_without_type(
|
||||||
&mut err,
|
&mut err,
|
||||||
pat,
|
pat,
|
||||||
require_name,
|
is_name_required,
|
||||||
is_trait_item,
|
is_trait_item,
|
||||||
) {
|
) {
|
||||||
err.emit();
|
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)?)
|
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
|
||||||
} else {
|
} else {
|
||||||
debug!("parse_arg_general ident_to_pat");
|
debug!("parse_arg_general ident_to_pat");
|
||||||
let parser_snapshot_before_ty = self.clone();
|
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);
|
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
|
||||||
if ty.is_ok() && self.token != token::Comma &&
|
if ty.is_ok() && self.token != token::Comma &&
|
||||||
self.token != token::CloseDelim(token::Paren) {
|
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|`).
|
/// Parses an argument in a lambda header (e.g., `|arg, arg|`).
|
||||||
fn parse_fn_block_arg(&mut self) -> PResult<'a, 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 pat = self.parse_pat(Some("argument name"))?;
|
||||||
let t = if self.eat(&token::Colon) {
|
let t = if self.eat(&token::Colon) {
|
||||||
self.parse_ty()?
|
self.parse_ty()?
|
||||||
@ -1570,6 +1577,7 @@ impl<'a> Parser<'a> {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
Ok(Arg {
|
Ok(Arg {
|
||||||
|
attrs: attrs.into(),
|
||||||
ty: t,
|
ty: t,
|
||||||
pat,
|
pat,
|
||||||
id: ast::DUMMY_NODE_ID
|
id: ast::DUMMY_NODE_ID
|
||||||
@ -5411,15 +5419,19 @@ impl<'a> Parser<'a> {
|
|||||||
&token::CloseDelim(token::Paren),
|
&token::CloseDelim(token::Paren),
|
||||||
SeqSep::trailing_allowed(token::Comma),
|
SeqSep::trailing_allowed(token::Comma),
|
||||||
|p| {
|
|p| {
|
||||||
// If the argument is a C-variadic argument we should not
|
let do_not_enforce_named_arguments_for_c_variadic =
|
||||||
// enforce named arguments.
|
|token: &token::Token| -> bool {
|
||||||
let enforce_named_args = if p.token == token::DotDotDot {
|
if token == &token::DotDotDot {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
named_args
|
named_args
|
||||||
};
|
}
|
||||||
match p.parse_arg_general(enforce_named_args, false,
|
};
|
||||||
allow_c_variadic) {
|
match p.parse_arg_general(
|
||||||
|
false,
|
||||||
|
allow_c_variadic,
|
||||||
|
do_not_enforce_named_arguments_for_c_variadic
|
||||||
|
) {
|
||||||
Ok(arg) => {
|
Ok(arg) => {
|
||||||
if let TyKind::CVarArgs = arg.ty.node {
|
if let TyKind::CVarArgs = arg.ty.node {
|
||||||
c_variadic = true;
|
c_variadic = true;
|
||||||
@ -5464,7 +5476,6 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
/// Parses the argument list and result type of a function declaration.
|
/// 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>> {
|
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 (args, c_variadic) = self.parse_fn_args(true, allow_c_variadic)?;
|
||||||
let ret_ty = self.parse_ret_ty(true)?;
|
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.
|
/// 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>> {
|
fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
|
||||||
let expect_ident = |this: &mut Self| match this.token.kind {
|
let expect_ident = |this: &mut Self| match this.token.kind {
|
||||||
// Preserve hygienic context.
|
// Preserve hygienic context.
|
||||||
@ -5581,7 +5594,18 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let eself = source_map::respan(eself_lo.to(eself_hi), eself);
|
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.
|
/// 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))?;
|
self.expect(&token::OpenDelim(token::Paren))?;
|
||||||
|
|
||||||
// Parse optional self argument.
|
// 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.
|
// Parse the rest of the function parameter list.
|
||||||
let sep = SeqSep::trailing_allowed(token::Comma);
|
let sep = SeqSep::trailing_allowed(token::Comma);
|
||||||
@ -5865,7 +5889,7 @@ impl<'a> Parser<'a> {
|
|||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
let mut generics = self.parse_generics()?;
|
let mut generics = self.parse_generics()?;
|
||||||
let decl = self.parse_fn_decl_with_self(|p| {
|
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()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
*at_end = true;
|
*at_end = true;
|
||||||
@ -7441,7 +7465,7 @@ impl<'a> Parser<'a> {
|
|||||||
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
|
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
|
||||||
let ident = self.parse_ident().unwrap();
|
let ident = self.parse_ident().unwrap();
|
||||||
self.bump(); // `(`
|
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"
|
"method"
|
||||||
} else {
|
} else {
|
||||||
"function"
|
"function"
|
||||||
@ -7492,7 +7516,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.eat_to_tokens(&[&token::Gt]);
|
self.eat_to_tokens(&[&token::Gt]);
|
||||||
self.bump(); // `>`
|
self.bump(); // `>`
|
||||||
let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
|
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)
|
("fn", "method", false)
|
||||||
} else {
|
} else {
|
||||||
("fn", "function", false)
|
("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) {
|
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
|
||||||
for argument in &function_declaration.inputs {
|
for argument in &function_declaration.inputs {
|
||||||
|
walk_list!(visitor, visit_attribute, argument.attrs.iter());
|
||||||
visitor.visit_pat(&argument.pat);
|
visitor.visit_pat(&argument.pat);
|
||||||
visitor.visit_ty(&argument.ty)
|
visitor.visit_ty(&argument.ty);
|
||||||
}
|
}
|
||||||
visitor.visit_fn_ret_ty(&function_declaration.output)
|
visitor.visit_fn_ret_ty(&function_declaration.output)
|
||||||
}
|
}
|
||||||
|
@ -928,7 +928,7 @@ impl<'a> MethodDef<'a> {
|
|||||||
let args = {
|
let args = {
|
||||||
let self_args = explicit_self.map(|explicit_self| {
|
let self_args = explicit_self.map(|explicit_self| {
|
||||||
let ident = Ident::with_empty_ctxt(kw::SelfLower).with_span_pos(trait_.span);
|
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()
|
let nonself_args = arg_types.into_iter()
|
||||||
.map(|(name, ty)| cx.arg(trait_.span, name, ty));
|
.map(|(name, ty)| cx.arg(trait_.span, name, ty));
|
||||||
|
@ -444,6 +444,7 @@ symbols! {
|
|||||||
panic_implementation,
|
panic_implementation,
|
||||||
panic_runtime,
|
panic_runtime,
|
||||||
partial_cmp,
|
partial_cmp,
|
||||||
|
param_attrs,
|
||||||
PartialOrd,
|
PartialOrd,
|
||||||
passes,
|
passes,
|
||||||
pat,
|
pat,
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
pub fn f(
|
pub fn f(
|
||||||
/// Comment
|
/// 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
|
//~| 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,
|
id: u8,
|
||||||
/// Other
|
/// 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
|
//~| 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,
|
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) {}
|
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
|
//~| NOTE attributes are not allowed here
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -26,10 +26,6 @@ fn main() {
|
|||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
//~| NOTE expected u8, found reference
|
//~| NOTE expected u8, found reference
|
||||||
//~| NOTE expected
|
//~| NOTE expected
|
||||||
foo("");
|
|
||||||
//~^ ERROR mismatched types
|
|
||||||
//~| NOTE expected i32, found reference
|
|
||||||
//~| NOTE expected
|
|
||||||
bar("");
|
bar("");
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| NOTE expected i32, found reference
|
//~| 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
|
--> $DIR/fn-arg-doc-comment.rs:2:5
|
||||||
|
|
|
|
||||||
LL | /// Comment
|
LL | /// Comment
|
||||||
| ^^^^^^^^^^^ doc comments are not allowed here
|
| ^^^^^^^^^^^ doc comments are not allowed here
|
||||||
|
|
||||||
error: documentation comments cannot be applied to method arguments
|
error: documentation comments cannot be applied to function parameters
|
||||||
--> $DIR/fn-arg-doc-comment.rs:6:5
|
--> $DIR/fn-arg-doc-comment.rs:8:5
|
||||||
|
|
|
|
||||||
LL | /// Other
|
LL | /// Other
|
||||||
| ^^^^^^^^^ doc comments are not allowed here
|
| ^^^^^^^^^ doc comments are not allowed here
|
||||||
|
|
||||||
error: attributes cannot be applied to method arguments
|
error[E0658]: attributes on function parameters are unstable
|
||||||
--> $DIR/fn-arg-doc-comment.rs:12:8
|
--> $DIR/fn-arg-doc-comment.rs:2:5
|
||||||
|
|
|
|
||||||
LL | fn foo(#[allow(dead_code)] id: i32) {}
|
LL | /// Comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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
|
error[E0658]: attributes on function parameters are unstable
|
||||||
--> $DIR/fn-arg-doc-comment.rs:16:12
|
--> $DIR/fn-arg-doc-comment.rs:8:5
|
||||||
|
|
|
|
||||||
LL | fn bar(id: #[allow(dead_code)] i32) {}
|
LL | /// Other
|
||||||
| ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= 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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/fn-arg-doc-comment.rs:22:7
|
--> $DIR/fn-arg-doc-comment.rs:22:7
|
||||||
@ -43,15 +55,6 @@ LL | f("", "");
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/fn-arg-doc-comment.rs:29:9
|
--> $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("");
|
LL | bar("");
|
||||||
| ^^ expected i32, found reference
|
| ^^ expected i32, found reference
|
||||||
|
|
|
|
||||||
@ -60,4 +63,5 @@ LL | bar("");
|
|||||||
|
|
||||||
error: aborting due to 8 previous errors
|
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