Skip to content

Commit

Permalink
feat: support parameter attributes (#3793)
Browse files Browse the repository at this point in the history
  • Loading branch information
calebcartwright authored and topecongiro committed Sep 20, 2019
1 parent 4449250 commit 6b0a447
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 15 deletions.
89 changes: 74 additions & 15 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1905,12 +1905,39 @@ fn get_missing_arg_comments(

impl Rewrite for ast::Param {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
let param_attrs_result = self
.attrs
.rewrite(context, Shape::legacy(shape.width, shape.indent))?;
let (span, has_multiple_attr_lines) = if !self.attrs.is_empty() {
let num_attrs = self.attrs.len();
(
mk_sp(self.attrs[num_attrs - 1].span.hi(), self.pat.span.lo()),
param_attrs_result.matches("\n").count() > 0,
)
} else {
(mk_sp(self.span.lo(), self.span.lo()), false)
};

if let Some(ref explicit_self) = self.to_self() {
rewrite_explicit_self(context, explicit_self)
rewrite_explicit_self(
context,
explicit_self,
&param_attrs_result,
span,
shape,
has_multiple_attr_lines,
)
} else if is_named_arg(self) {
let mut result = self
.pat
.rewrite(context, Shape::legacy(shape.width, shape.indent))?;
let mut result = combine_strs_with_missing_comments(
context,
&param_attrs_result,
&self
.pat
.rewrite(context, Shape::legacy(shape.width, shape.indent))?,
span,
shape,
!has_multiple_attr_lines,
)?;

if !is_empty_infer(&*self.ty, self.pat.span) {
let (before_comment, after_comment) =
Expand All @@ -1936,6 +1963,10 @@ impl Rewrite for ast::Param {
fn rewrite_explicit_self(
context: &RewriteContext<'_>,
explicit_self: &ast::ExplicitSelf,
param_attrs: &str,
span: Span,
shape: Shape,
has_multiple_attr_lines: bool,
) -> Option<String> {
match explicit_self.node {
ast::SelfKind::Region(lt, m) => {
Expand All @@ -1946,9 +1977,23 @@ fn rewrite_explicit_self(
context,
Shape::legacy(context.config.max_width(), Indent::empty()),
)?;
Some(format!("&{} {}self", lifetime_str, mut_str))
Some(combine_strs_with_missing_comments(
context,
&param_attrs,
&format!("&{} {}self", lifetime_str, mut_str),
span,
shape,
!has_multiple_attr_lines,
)?)
}
None => Some(format!("&{}self", mut_str)),
None => Some(combine_strs_with_missing_comments(
context,
&param_attrs,
&format!("&{}self", mut_str),
span,
shape,
!has_multiple_attr_lines,
)?),
}
}
ast::SelfKind::Explicit(ref ty, mutability) => {
Expand All @@ -1957,21 +2002,35 @@ fn rewrite_explicit_self(
Shape::legacy(context.config.max_width(), Indent::empty()),
)?;

Some(format!(
"{}self: {}",
format_mutability(mutability),
type_str
))
Some(combine_strs_with_missing_comments(
context,
&param_attrs,
&format!("{}self: {}", format_mutability(mutability), type_str),
span,
shape,
!has_multiple_attr_lines,
)?)
}
ast::SelfKind::Value(mutability) => Some(format!("{}self", format_mutability(mutability))),
ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments(
context,
&param_attrs,
&format!("{}self", format_mutability(mutability)),
span,
shape,
!has_multiple_attr_lines,
)?),
}
}

pub(crate) fn span_lo_for_arg(arg: &ast::Param) -> BytePos {
if is_named_arg(arg) {
arg.pat.span.lo()
if arg.attrs.is_empty() {
if is_named_arg(arg) {
arg.pat.span.lo()
} else {
arg.ty.span.lo()
}
} else {
arg.ty.span.lo()
arg.attrs[0].span.lo()
}
}

Expand Down
57 changes: 57 additions & 0 deletions tests/source/fn-param-attributes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// https://github.com/rust-lang/rustfmt/issues/3623

fn foo(#[cfg(something)] x: i32, y: i32) -> i32 {
x + y
}

fn foo_b(#[cfg(something)]x: i32, y: i32) -> i32 {
x + y
}

fn add(#[cfg(something)]#[deny(C)] x: i32, y: i32) -> i32 {
x + y
}

struct NamedSelfRefStruct {}
impl NamedSelfRefStruct {
fn foo(
#[cfg(something)] self: &Self,
) {}
}

struct MutStruct {}
impl MutStruct {
fn foo(
#[cfg(foo)]&mut self,#[deny(C)] b: i32,
) {}
}

fn main() {
let c = |
#[allow(C)]a: u32,
#[cfg(something)] b: i32,
#[cfg_attr(something, cfg(nothing))]#[deny(C)] c: i32,
| {};
let _ = c(1, 2);
}

pub fn bar(
/// bar
#[test] a: u32,
/// Bar
#[must_use]
/// Baz
#[no_mangle] b: i32,
) {}


fn abc(
#[foo]
#[bar] param: u32,
) {
// ...
}

fn really_really_really_loooooooooooooooooooong(#[cfg(some_even_longer_config_feature_that_keeps_going_and_going_and_going_forever_and_ever_and_ever_on_and_on)] b: i32) {
// ...
}
64 changes: 64 additions & 0 deletions tests/target/fn-param-attributes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// https://github.com/rust-lang/rustfmt/issues/3623

fn foo(#[cfg(something)] x: i32, y: i32) -> i32 {
x + y
}

fn foo_b(#[cfg(something)] x: i32, y: i32) -> i32 {
x + y
}

fn add(
#[cfg(something)]
#[deny(C)]
x: i32,
y: i32,
) -> i32 {
x + y
}

struct NamedSelfRefStruct {}
impl NamedSelfRefStruct {
fn foo(#[cfg(something)] self: &Self) {}
}

struct MutStruct {}
impl MutStruct {
fn foo(#[cfg(foo)] &mut self, #[deny(C)] b: i32) {}
}

fn main() {
let c = |#[allow(C)] a: u32,
#[cfg(something)] b: i32,
#[cfg_attr(something, cfg(nothing))]
#[deny(C)]
c: i32| {};
let _ = c(1, 2);
}

pub fn bar(
/// bar
#[test]
a: u32,
/// Bar
#[must_use]
/// Baz
#[no_mangle]
b: i32,
) {
}

fn abc(
#[foo]
#[bar]
param: u32,
) {
// ...
}

fn really_really_really_loooooooooooooooooooong(
#[cfg(some_even_longer_config_feature_that_keeps_going_and_going_and_going_forever_and_ever_and_ever_on_and_on)]
b: i32,
) {
// ...
}

0 comments on commit 6b0a447

Please sign in to comment.