CAD97 / CAD97/generativity

`super let` improves diagnostics

Open
#18 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
66
Forks
7
PR merge metrics
No merged PRs in 30d

Description

When `$name:ident` is provided to an expression `guard!` macro using `super let`, we can improve diagnostics to more clearly indicate which two guards are improperly entangled:

```rust
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:242:36
|
9 | let (a, b) = (guard!(guard_a), guard!(guard_b));
| ^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
12 | }
| -
| |
| temporary value is freed at the end of this statement
| borrow might be used here, when `guard_a` is dropped and runs the `Drop` code for type `LifetimeBrand`
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `guard` (in Nightly builds, run with -Z macro-backtrace for more info)
```

Note that `make_guard!(guard_b)` is pointed to and `guard_a` is named. We can get similar from `make_guard!`:

```rust
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:262:5
|
10 | make_guard!(b);
| ^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
13 | }
| -
| |
| temporary value is freed at the end of this statement
| borrow might be used here, when `a` is dropped and runs the `Drop` code for type `LifetimeBrand`
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `make_guard` (in Nightly builds, run with -Z macro-backtrace for more info)
```

even without `super let`, and I will make that improvement, but using the same name for the `Guard` (which the caller can name) and the `LifetimeBrand` (which they can't) makes the error less clear than naming them separately.

`make_guard!` *cannot* easily provide different names for the brand and the guard[^2], as the caller being able to name the brand place would violate soundness. `super let` (currently) does not make the place name in scope of the `super` scope, despite the lifetime continuing.

[^2]: It *could* make the binding and then shadow it with another binding, but I consider that to cause a problematic user experience since the binding is usable with an unexpected type.

blocked on: https://github.com/rust-lang/rust/issues/139076

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.