Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC for trait bounds on generic parameters of const fns #8

Merged
merged 26 commits into from
Feb 5, 2019
Merged
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d424f1d
const generics RFC
oli-obk Oct 5, 2018
58fbcd7
Address review comments
oli-obk Oct 13, 2018
1bd4072
Add question about `Drop::drop` calls
oli-obk Oct 25, 2018
239e6a1
Address review comments
oli-obk Nov 5, 2018
a27e208
Offer a solution for deriving const impls
oli-obk Nov 5, 2018
caea9b4
const impl Drop for 🎤
oli-obk Dec 14, 2018
ae05ba2
Expand on implementation details a little
oli-obk Dec 14, 2018
55f6739
`const impl` -> `impl const`
oli-obk Dec 15, 2018
676988b
Talk more about runtime calls
oli-obk Dec 18, 2018
5890176
Double call
varkor Jan 9, 2019
834a259
Resolve unresolved issues and add implementation instructions
oli-obk Jan 9, 2019
4dea80c
Coevolution is cool
oli-obk Jan 9, 2019
237cdad
Elaborate on `const Drop` fields
oli-obk Jan 14, 2019
5948264
Inferred and opt-out const bounds
oli-obk Jan 14, 2019
7d86f87
Clarify where the `new` function cannot be called
oli-obk Jan 14, 2019
3f38757
Add `const trait` sugar future extension
oli-obk Jan 15, 2019
2c6414e
Link to new blog post about the theoretical discussion
oli-obk Jan 15, 2019
f33fe7a
Explain const bounds on impl blocks and associated types
oli-obk Jan 15, 2019
0293ea7
We need const default bodies for non-breaking changes
oli-obk Jan 15, 2019
ded5c40
Placeholder syntax for method bodies that are const
oli-obk Jan 15, 2019
98e5a3c
Missing keyword
oli-obk Jan 23, 2019
d4637f9
The title is not a question
oli-obk Jan 23, 2019
9c715d7
Explain with effect system syntax
oli-obk Jan 23, 2019
a5e07d8
Rusty effect systems
oli-obk Jan 23, 2019
9edf8ec
`impl const` blocks are not just "similar" to `const fn`, they behave…
oli-obk Jan 23, 2019
56f394b
Integrate centril's review
oli-obk Feb 5, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion const-generic-const-fn-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,46 @@ It might also be desirable to make the automatic `Fn*` impls on function types a
This change should probably go in hand with allowing `const fn` pointers on const functions
that support being called (in contrast to regular function pointers).

## Deriving `const impl`s

```rust
#[derive(Clone)]
pub struct Foo(Bar);

struct Bar;

const impl Clone for Bar {
fn clone(&self) -> Self { Bar }
}
```

could theoretically have a scheme inferring `Foo`'s `Clone` impl to be `const`. If some time
later the `const impl Clone for Bar` (a private type) is changed to just `impl`, `Foo`'s `Clone`
impl would suddenly stop being `const`, without any visible change to the API. This should not
be allowed for the same reason as why we're not inferring `const` on functions: changes to private
things should not affect the constness of public things, because that is not compatible with semver.
oli-obk marked this conversation as resolved.
Show resolved Hide resolved

## RPIT (Return position impl trait)

```rust
const fn foo() -> impl Bar { /* code here */ }
```

does not allow us to call any methods on the result of a call to `foo`, if we are in a
const context. It seems like a natural extension to this RFC to allow

```rust
const fn foo() -> impl const Bar { /* code here */ }
```

which requires that the function only returns types with `const impl Bar` blocks.

## Specialization

Impl specialization is still unstable. There should be a separate RFC for declaring how
const impl blocks and specialization interact. For now one may not have both `default`
and `const` modifiers on `impl` blocks.

# Unresolved questions
[unresolved-questions]: #unresolved-questions

Expand All @@ -148,7 +188,8 @@ const impl<T: Add> Add for Foo<T> {
```

would allow calling `Foo(String::new()) + Foo(String::new())` even though that is (at the time
of writing this RFC) most definitely not const.
of writing this RFC) most definitely not const, because `String` only has an `impl Add for String`
and not a `const impl Add for String`.

This would go in hand with the current scheme for const functions, which may also be called
at runtime with runtime arguments, but are checked for soundness as if they were called in
Expand All @@ -158,3 +199,23 @@ a const context.

Should we also allow `(SomeDropType, 42).1` as an expression if `SomeDropType`'s `Drop` impl
was declared with `const impl Drop`?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! That's literally what it's been waiting for 🎉


## Require `const` bounds on everything inside a `const impl` block?

Instead of inferring `const`ness on all bounds and functions inside a `const impl` block,
we force the user to supply these bounds. This is more consistent with not inferring `const`
on `const` function argument types and generic bounds. The `Hash` example from above would
then look like

```rust
const impl Hash for MyInt {
const fn hash<H>(
&self,
state: &mut H,
)
where H: const Hasher
{
state.write(&[self.0 as u8]);
}
}
```