Rust: Tracking issue for attributes on generic parameters (`generic_param_attrs`)

Created on 8 Mar 2018  路  14Comments  路  Source: rust-lang/rust

Attributes on generic parameters (both types and lifetimes) were introduced in https://github.com/rust-lang/rust/pull/34764. Extensive tests for them were added in the same PR.

// Example
fn f<#[my_type_attr] T, #[my_lifetime_attr] 'a>() {}

Notable build-in attribute accepted in this position is #[may_dangle] (https://github.com/rust-lang/rust/issues/34761) supplying information for drop checking.
However, custom attributes interpreted in custom ways by procedural macros can be used in this position as well.

Stabilization PR: https://github.com/rust-lang/rust/pull/48851

C-tracking-issue T-lang final-comment-period

Most helpful comment

There's no real ambiguity, and they feel to me like a "declaration of a thing" that can have properties

This is convincing. There is something about the 'deepness' of them that still irks, but I think it is not worse than fields, for example.

Rather than look in the abstract, perhaps you could comment on the "derive" use case (rust-lang/rfcs#2353) and if you find that confusing?

I do, but I think that is mostly because of the formatting?

With:

#[derive(Clone, PartialEq)]
struct MyArc<
    #[derive_no_bound(Clone)]
    T,
>(Arc<T>);

It feels fine (although it is arguably worse formatting in that it is ugly and uses a lot of vertical space).

Given that I wouldn't want to block an RFC on how to format the code, I think it's fine.

All 14 comments

@rfcbot fcp merge

ping @nikomatsakis

rfcbot doesn't listen to me

@rfcbot fcp merge

Team member @cramertj has proposed to merge this. The next step is review by the rest of the tagged teams:

  • [x] @aturon
  • [x] @cramertj
  • [x] @eddyb
  • [x] @nikomatsakis
  • [x] @nrc
  • [x] @pnkfelix
  • [ ] @withoutboats

No concerns currently listed.

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

My gut instinct is that this is a bad idea - I think attributes work pretty well for item-like things, but are pretty confusing for expression-like things (the technical issue is scoping, but I at least have mental model issues too). So, I'd prefer not to stabilise and instead deprecate, however, it seems like may_dangle is something we want to keep long term and that attributes on formal generics is a prereq for that? (@pnkfelix could you confirm?) In which case, I guess we should stabilise.

My intuition so far is that any part of source code may require annotations of some kind (aka passive attributes), so we eventually end up with attributes permitted almost anywhere, like C++.
As a recent example, https://github.com/rust-lang-nursery/stdsimd/pull/319 would benefit from attributes on function parameters.

Aside from may_dangle: I believe the concrete impetus for requesting this stabilizations were attributes on ADT type parameters to guide derives (https://github.com/rust-lang/rfcs/pull/2353). @petrochenkov makes a good case for even more attribute positions, though. I'm not a huge fan of how it winds up looking (puts a lot of noise into the angle brackets), but as they say, we need some way to add annotations to these things.

@nrc

but are pretty confusing for expression-like things

In what way are generic parameters expression-like? They seem more analagous to item-like -- that is, they are declarations.

In what way are generic parameters expression-like?

This is all very vague and non-technical, but:

  • they can only appear within items (not at 'module scope') and can't contain items themselves
  • they are 'small' - they can only contain sequences of types, not sequences of statements

@nrc It seems to me that there are a few things which can make attributes on expressions confusing. The most important of course is precedence. But I think attributes in general tend also to make the most sense when attached to "declarations", since those often have other "properties" to them and you can think of attributes as being one of those properties. (Hence I suppose something like #[foo] (x + 3) could be sort of confusing -- what is #[foo] annotating? The result? The computation?)

But neither of these concerns seem to apply to type parameters. There's no real ambiguity, and they feel to me like a "declaration of a thing" that can have properties (e.g., it has a list of bounds attached to it).

Rather than look in the abstract, perhaps you could comment on the "derive" use case (https://github.com/rust-lang/rfcs/pull/2353) and if you find that confusing?

There's no real ambiguity, and they feel to me like a "declaration of a thing" that can have properties

This is convincing. There is something about the 'deepness' of them that still irks, but I think it is not worse than fields, for example.

Rather than look in the abstract, perhaps you could comment on the "derive" use case (rust-lang/rfcs#2353) and if you find that confusing?

I do, but I think that is mostly because of the formatting?

With:

#[derive(Clone, PartialEq)]
struct MyArc<
    #[derive_no_bound(Clone)]
    T,
>(Arc<T>);

It feels fine (although it is arguably worse formatting in that it is ugly and uses a lot of vertical space).

Given that I wouldn't want to block an RFC on how to format the code, I think it's fine.

:bell: This is now entering its final comment period, as per the review above. :bell:

The final comment period is now complete.

I tried this today on 1.27-beta and found that #[cfg] is ignored. Is this expected for stabilization?

struct Foo<#[cfg(not(unix))] H>(H);
fn main() {
    let _: Foo<u32> = Foo::<u32>(1);
}
warning: unused attribute
 --> src/main.rs:1:12
  |
1 | struct Foo<#[cfg(not(unix))] H>(H);
  |            ^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_attributes)] on by default

    Finished dev [unoptimized + debuginfo] target(s) in 0.65s
     Running `target/debug/playground`
Was this page helpful?
0 / 5 - 0 ratings