Skip to content

Commit

Permalink
Merge pull request #39 from rust-lang/attributes
Browse files Browse the repository at this point in the history
some smaller edits and prerequisites added
  • Loading branch information
yoshuawuyts authored Jan 24, 2024
2 parents 85853a0 + ac98d55 commit 1e3784a
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions explainer/effect-generic-trait-declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,20 @@ evolving to our needs.
Evolving a programming language and stdlib is pretty difficult. We have to pay
close attention to details. And in Rust specifically: once we make a mistake
it's pretty hard to roll back. And we've made mistakes with effects in the past,
which we now have to work with.
which we now have to work with [^1].

In Rust 1.34 we stabilized a new trait: `TryInto`. This was supposed to be the
fallible version of the `Into` trait, containing a new associated type `Error`.
However since Rust 1.0 we've also had the
[`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait, which
*also* provides a fallible conversion, but has an associated type `Err`. This
means that when writing a fallible conversion trait, it's unclear whether the
associated type should be called `Err` or `Error`.
[^1]: In Rust 1.34 we stabilized a new trait: `TryInto`. This was supposed to be the
fallible version of the `Into` trait, containing a new associated type `Error`.
However since Rust 1.0 we've also had the
[`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) trait, which
*also* provides a fallible conversion, but has an associated type `Err`. This
means that when writing a fallible conversion trait, it's unclear whether the
associated type should be called `Err` or `Error`.

This might seem minor, but without automation these subtle
similar-but-not-quite-the-same kinds of differences stand out. The only way to
ensure that different APIs in different contexts work consistently is via
automation. And the best automation we have for this is the type system.
This might seem minor, but without automation these subtle
similar-but-not-quite-the-same kinds of differences stand out. The only way to
ensure that different APIs in different contexts work consistently is via
automation. And the best automation we have for this is the type system.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation
Expand Down Expand Up @@ -180,7 +180,7 @@ pub trait Read {
## Effect lowering

At the MIR level the lowering of `#[maybe(effect)]` is shared with `const`, and
is essentially implemented via const bools. Take the following maybe-async
is essentially implemented via const generic bools. Take the following maybe-async
definition of `Into`:

```rust
Expand All @@ -192,19 +192,19 @@ trait Into<T>: Sized {
}
```

At the MIR level the `#[maybe(async)]` system is lowered to a const bool which
At the type level the `#[maybe(async)]` system is lowered to a const bool which
determines whether the function should be async. If the trait is implemented as
async, the bool is set to true. If it isn't, it's set to false.

```rust
// Lowered trait definition
trait Into<T, const IS_ASYNC: bool>: Sized {
trait Into<T, const IS_ASYNC: bool = false>: Sized {
type Ret = T;
fn into(self) -> Self::Ret;
}
```

By default the const bool should be set to false. The return type of the
By default the const bool is set to false. The return type of the
function here is the base return type of the definition:

```rust
Expand Down Expand Up @@ -275,11 +275,11 @@ where
}

/// The lowering of the trait definition
pub trait AsRef<T, const IS_ASYNC: bool>
pub trait AsRef<T, const IS_ASYNC: bool = false>
where
T: ?Sized,
{
type Ret<'a>
type Ret<'a> = &'a T
where Self: 'a;
fn as_ref(&self) -> Self::Ret<'_>;
}
Expand Down Expand Up @@ -470,7 +470,10 @@ trait Into<T>: Sized { .. }

## TODO: prerequisites

- ask oli about which compiler features we're missing to implement this
- associated type defaults
- complex where bounds on associated items removing the need for them to get implemented
- a working demo of the constness effect
- T-types buy-in (not before the old solver got removed)

# Drawbacks
[drawbacks]: #drawbacks
Expand Down Expand Up @@ -511,6 +514,8 @@ TODO:
# Unresolved questions
[unresolved-questions]: #unresolved-questions

* may want to use an associated const instead of a const generic

## TODO: Syntax

- `#[maybe(async)]` is a placeholder
Expand Down

0 comments on commit 1e3784a

Please sign in to comment.