# pre-RFC: #\[match\] attribute on functions

**URL:** <https://internals.rust-lang.org/t/pre-rfc-match-attribute-on-functions/8655>\
**Category:** language design\
**Created:** [October 23, 2018, 12:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-match-attribute-on-functions/8655 "2018-10-23T12:00:58Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![earthengine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/earthengine/32/2577_2.png) [@earthengine](https://internals.rust-lang.org/u/earthengine)\
**Post date:** [October 23, 2018, 10:17pm UTC](https://internals.rust-lang.org/t/pre-rfc-match-attribute-on-functions/8655/5 "2018-10-23T22:17:22Z")

</div>

> [@Nemo157](#):
>
> I assume this must also deny a match that binds the entire input value in any way?

Maybe; or may not. If we consider those matches are "reconstructed" it should not be a problem.

> [@Nemo157](#):
>
> ```rust
> #[match]
> fn foo(r: Result<String,()>) {
> match r {
> r => r.is_ok(),
> };
> }
> 
> ```

In this case, I can propose two options: `r.is_ok()` will be called with an reconstructed object, or this is disabled.

> [@Nemo157](#):
>
> Or one that doesn’t bind any sub-fields and re-uses the argument binding:
> 
> ```rust
> #[match]
> fn foo(r: Result<String,()>) {
> match r {
> Ok(_) => r.is_ok(),
> Err(()) => true,
> };
> }
> 
> ```

This can fallback to the previous case: `r` can be considered a re-bind in the match, so it is reconstructed or disabled.

> [@scottmcm](#):
>
> Is there any reason you’d need to enforce this outside the new drop implementations?

No. I didn't see a use yet. And I have said in the RFC already.

So if we decided not to do this it should be fine. But the purpose is to make the features being decoupled so we can discuss them separately.

In the `destruct` method writer point of view, it would be good if I am required to add an attribute to indicate myself (and the code readers) I need to write the function in a specific form. And If I can have such an attribute here, if I were new to the language I must ask why I cannot have it there.

> [@CAD97](#):
>
> Requiring the destructure of the `Drop` type, however, is one way of accomplishing that, and can be relaxed to just the drop glue formulation in the future.

I would include this as an alternative (in the other RFC). I think it is fair to say that in one hand it have one less trait, in the other hand it requires more for that trait and no able to relax E0509.

> [@CAD97](#):
>
> it can be framed as alerting the localized drop glue to only apply the transitive parts of the drop implementation.

In my proposal, `drop` method should not traverse the object structure, at all. All it should do is to apply what it should do in the main object level. The child objects will be dropped later, and will be out of its control.

Then we can look at "auto execute closures" (a future proposal):

```rust
trait FnDrop: Drop + Destruct + FnOnce() -> () {};

// use #[match] in front of a closure indicate the compiler to
// derive `Drop` + `Destruct`, and the `Destruct` method executes the closure
let finally = #[match] || { println!("Leave scope!") };

```

(Note, because the closure takes `self` as its first argument, `#[match]` is applied to its state and so the `#[match]` requirements are always fulfilled, but we require the function not to take any arguments, so we can derive `Destruct` and ignore the unit argument under `rust-call`.)

In the case above, the drop clue of the closure does not do anything. the destruct part does all the thing. This is because there are no external duty for it to do, and we are sure no user code can touch the closure state.

---

_[View the full topic](https://internals.rust-lang.org/t/pre-rfc-match-attribute-on-functions/8655)._
