Skip to content

Commit cf0b8ec

Browse files
author
Hero Bird
authored
Create 2540-formal-function-parameter-attributes.md
1 parent eecc3f5 commit cf0b8ec

File tree

1 file changed

+242
-0
lines changed

1 file changed

+242
-0
lines changed
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
- Feature Name: formal_function_param_attrs
2+
- Start Date: 2018-10-14
3+
- RFC PR:
4+
- Rust Issue:
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
This RFC proposes to allow attributes in formal function parameter position.
10+
11+
# Motivation
12+
[motivation]: #motivation
13+
14+
Having attributes on formal function parameters allows for certain different use cases.
15+
16+
## Example: Handling of unused parameter
17+
18+
In today's Rust it is possible to prefix the name of an identifier to silence the compiler about it being unused.
19+
With attributes in formal function parameter position we could have an attribute like `#[unused]` that explicitely states this for a given parameter.
20+
21+
```rust
22+
fn foo(#[unused] bar: u32) -> bool;
23+
```
24+
25+
Instead of
26+
27+
```rust
28+
fn foo(_bar: u32) -> bool
29+
```
30+
31+
This would better reflect the explicit nature of Rust compared to the underscore prefix as of today.
32+
33+
## Example: Low-level code
34+
35+
For raw pointers that are oftentimes used when operating with C code one could provide the compiler with additional information about the set of parameters.
36+
You could for example mirror C's restrict keyword or even be more explicit by stating what pointer argument might overlap.
37+
38+
```rust
39+
fn foo(#[overlaps_with(in_b) in_a: *const u8, #[overlaps_with(in_a)] in_b: *const u8, #[restrict] out: *mut u8);
40+
```
41+
42+
Which might state that the pointers `in_a` and `in_b` might overlap but `out` is non overlapping.
43+
Please note that I am *not* proposing to actually add this to the language!
44+
45+
## Example: Procedural Macros
46+
47+
Also procedural macros could greatly benefit from having their own defined custom attributes on formal parameters.
48+
49+
# Guide-level explanation
50+
[guide-level-explanation]: #guide-level-explanation
51+
52+
Formal parameters of functions, methods, closures and functions in trait definitions may have attributes attached to them.
53+
This allows to provide additional information to a given formal parameter.
54+
55+
To reify this we introduce the `#[unused]` attribute that states that the attributed parameter is unused in the associated implementation.
56+
57+
## Examples
58+
59+
The syntax for this is demonstrated by the code below:
60+
61+
```rust
62+
// Function
63+
fn foo(#[unused] bar: u32) { .. }
64+
65+
// Methods & trait & definitions:
66+
// - `self` can also be attributed
67+
fn foo(#[unused] self, ..) { .. }
68+
fn foo(#[unused] &self, ..) { .. }
69+
fn foo(#[unused] &mut self, ..) { .. }
70+
71+
// Closures & Lamdas
72+
|#[unused] x| { .. }
73+
```
74+
75+
### Trait declarations
76+
77+
```rust
78+
fn foo(#[unused] self);
79+
```
80+
81+
Note that while the `#[unused]` attribute is syntactically
82+
possible to put here it doesn't actually make sense semantically
83+
since method declarations have no implementation.
84+
Other attributes might be very useful as for formal parameters in a method declaration.
85+
86+
## Errors & Warnings
87+
88+
There are two errornous situations when it comes to
89+
90+
### Warning: Unused attribute
91+
92+
When using an non-defined attribute that is not used by either the language or a custom defined procedural macro.
93+
94+
```
95+
warning: unused attribute
96+
--> src/main.rs:2
97+
|
98+
2 | #[foo] bar: u32
99+
| ^^^^^^^^^
100+
|
101+
= note: #[warn(unused_attributes)] on by default
102+
```
103+
104+
### Error: Malformed attribute
105+
106+
When using a known attribute that is not defined for formal parameters such as when attributing `fn main` with `#[allow]`.
107+
108+
Example shows the usage of the known attribute `#[inline]` used on a formal parameter without being defined for it.
109+
110+
```
111+
error[E0452]: malformed lint attribute
112+
--> src/main.rs:2
113+
|
114+
2 | #[inline] bar: u32
115+
| ^^^^^^^^
116+
```
117+
118+
The same applies for attributes with an incorrect format such as `#[inline(key = value)]` that is handled as its done in other contexts.
119+
120+
121+
# Reference-level explanation
122+
[reference-level-explanation]: #reference-level-explanation
123+
124+
## Description
125+
126+
In accordance to the RFC for [attributes for generic params](https://github.com/frol/rust-rfcs/blob/master/text/1327-dropck-param-eyepatch.md)
127+
this feature is guarded by the `formal_function_param_attrs` feature guard.
128+
129+
The grammar of the following language items has to be adjusted to allow that
130+
constructions like the following will become legal.
131+
132+
- Function definitions
133+
- Method definitions
134+
- Trait function declarations and defnitions (with or without default impl)
135+
- Lambda & closure definitions
136+
137+
### Example: A single attributed parameter for function decl or definition
138+
139+
```rust
140+
fn foo(#[bar] baz: bool);
141+
fn bar(#[bar] qux: bool) { println!("hi"); }
142+
```
143+
144+
### Example: For methods or trait function definitions
145+
146+
```rust
147+
fn into_foo(#[bar] self);
148+
fn foo(#[bar] &self);
149+
fn foo_mut(#[bar] &mut self);
150+
```
151+
152+
### Example: Multiple attributed parameters
153+
154+
```rust
155+
// Twice the same attribute
156+
fn fst_foo(#[bar] baz: bool, #[bar] qiz: u32);
157+
158+
// Different attributes
159+
fn snd_foo(#[bar] baz: bool, #[qux] qiz: u32);
160+
```
161+
162+
### Example: Any structured attribute
163+
164+
```rust
165+
fn foo(#[bar(Hello)] baz: bool);
166+
fn bar(#[qux(qiz = World)] baz: bool);
167+
```
168+
169+
### Example: Lambdas & closures
170+
171+
```rust
172+
let mut v = [5, 4, 1, 3, 2];
173+
v.sort_by(|#[bar] a, #[baz] b| a.cmp(b));
174+
```
175+
176+
## Errors
177+
178+
Users can encounter two different errorneous situations.
179+
180+
### Unknown attribute used
181+
182+
When a user is using an attribute that is not known at the point of its invokation
183+
a warning is generated similar to other usages of unknown attributes in the language.
184+
185+
This may for example happen in the context of a procedural macros.
186+
187+
### Malformed attribute
188+
189+
When a user is using a known or language defined attribute at a non supported location
190+
an error is generated like in other usages of malformed attributes in the language.
191+
An example can be seen in the previous section.
192+
193+
194+
# Drawbacks
195+
[drawbacks]: #drawbacks
196+
197+
All drawbacks for attributes in any location also count for this proposal.
198+
199+
Having attributes in many different places of the language complicates its grammar.
200+
201+
# Rationale and alternatives
202+
[rationale-and-alternatives]: #rationale-and-alternatives
203+
204+
## Why is this proposal considered the best in the space of available ideas?
205+
206+
This proposal clearly goes the path of having attributes in more places of the language.
207+
It nicely plays together with the advance of procedural macros and macros 2.0 where users
208+
can define their own attributes for their special purposes.
209+
210+
## Alternatives
211+
212+
An alternative to having attributes for formal parameters might be to just use the current
213+
set of available attributable items to store meta information about formal parameters like
214+
in the following example:
215+
216+
```rust
217+
#[ignore(param = bar)]
218+
fn foo(bar: bool);
219+
```
220+
221+
Note that this does not work in all situations (for example closures) and might invole even
222+
more complexity in user's code than simply allowing formal function parameter attributes.
223+
224+
## Impact
225+
226+
The impact will most certainly be that users might create custom attributes when
227+
designing procedural macros involving formal function parameters.
228+
229+
There should be no breakage of existing code.
230+
231+
# Prior art
232+
[prior-art]: #prior-art
233+
234+
Some example languages that allows for attributes in formal function parameter positions are C# and C++.
235+
236+
Also note that attributes in other parts of the Rust language could be considered prior art to this proposal.
237+
238+
# Unresolved questions
239+
[unresolved-questions]: #unresolved-questions
240+
241+
We might want to introduce new attributes for the language like the mentioned `#[unused]` attribute.
242+
However, this RFC proposes to decide upon this in another RFC.

0 commit comments

Comments
 (0)