diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3645ab88d552f..07b1aef337fdc 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2622,27 +2622,23 @@ impl<'a> State<'a> { self.s.word("<"); self.commasep(Inconsistent, &generic_params, |s, param| { + s.print_outer_attributes_inline(¶m.attrs); + match param.kind { ast::GenericParamKind::Lifetime => { - s.print_outer_attributes_inline(¶m.attrs); let lt = ast::Lifetime { id: param.id, ident: param.ident }; s.print_lifetime_bounds(lt, ¶m.bounds) } ast::GenericParamKind::Type { ref default } => { - s.print_outer_attributes_inline(¶m.attrs); s.print_ident(param.ident); s.print_type_bounds(":", ¶m.bounds); - match default { - Some(ref default) => { - s.s.space(); - s.word_space("="); - s.print_type(default) - } - _ => {} + if let Some(ref default) = default { + s.s.space(); + s.word_space("="); + s.print_type(default) } } ast::GenericParamKind::Const { ref ty } => { - s.print_outer_attributes_inline(¶m.attrs); s.word_space("const"); s.print_ident(param.ident); s.s.space(); @@ -2743,6 +2739,9 @@ impl<'a> State<'a> { crate fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) { self.ibox(INDENT_UNIT); + + self.print_outer_attributes_inline(&input.attrs); + match input.ty.node { ast::TyKind::Infer if is_closure => self.print_pat(&input.pat), _ => { diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs new file mode 100644 index 0000000000000..71815e3c08974 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs @@ -0,0 +1,34 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +macro_rules! checker { + ($attr_name:ident, $expected:literal) => { + #[proc_macro_attribute] + pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(input.to_string(), $expected); + TokenStream::new() + } + } +} + +checker!(attr_extern, r#"extern "C" { + fn ffi(#[a1] arg1: i32, #[a2] ...); +}"#); +checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) { }"#); +checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...);"); +checker!(attr_free, "fn free(#[a1] arg1: u8) { let lam = |#[a2] W(x), #[a3] y| (); }"); +checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }"); +checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) { }"); +checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);"); +checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);"); +checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);"); +checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);"); diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs new file mode 100644 index 0000000000000..1a7e948174506 --- /dev/null +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs @@ -0,0 +1,56 @@ +// aux-build:param-attrs.rs + +// check-pass + +#![feature(param_attrs)] +#![feature(c_variadic)] + +extern crate param_attrs; + +use param_attrs::*; + +struct W(u8); + +#[attr_extern] +extern "C" { fn ffi(#[a1] arg1: i32, #[a2] ...); } + +#[attr_extern_cvar] +unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) {} + +#[attr_alias] +type Alias = fn(#[a1] u8, #[a2] ...); + +#[attr_free] +fn free(#[a1] arg1: u8) { + let lam = |#[a2] W(x), #[a3] y| (); +} + +impl W { + #[attr_inherent_1] + fn inherent1(#[a1] self, #[a2] arg1: u8) {} + + #[attr_inherent_2] + fn inherent2(#[a1] &self, #[a2] arg1: u8) {} + + #[attr_inherent_3] + fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) {} + + #[attr_inherent_4] + fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) {} +} + +trait A { + #[attr_trait_1] + fn trait1(#[a1] self, #[a2] arg1: u8); + + #[attr_trait_2] + fn trait2(#[a1] &self, #[a2] arg1: u8); + + #[attr_trait_3] + fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8); + + #[attr_trait_4] + fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec); +} + +fn main() {}