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

Amend #911 const-fn to allow unsafe const functions #1245

Merged
merged 1 commit into from
Oct 9, 2015
Merged
Changes from all commits
Commits
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
20 changes: 18 additions & 2 deletions text/0911-const-fn.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ const fn arithmetic_ops<T: Int>() -> [fn(T, T) -> T; 4] {
}
```

`const` functions can also be unsafe, allowing construction of types that require
invariants to be maintained (e.g. `std::ptr::Unique` requires a non-null pointer)
```rust
struct OptionalInt(u32);
impl OptionalInt {
/// Value must be non-zero
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't NonZero::new_unchecked be a better example here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly, however Unique is more directly related to the collection types (as that's the libcore type they're built on)

unsafe const fn new(val: u32) -> OptionalInt {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since const is not a part of function type and unsafe is, I'd prefer this to be const unsafe fn and not unsafe const fn

Copy link
Member

Choose a reason for hiding this comment

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

“unsafe constant function” sounds more “right” to me than “constant unsafe function”, though your point is also valid.

Either way, I think it should be possible to put these in any order. I’ve already had some trouble remembering which goes first in pub extern fn x and now I’ll have to think what order pub, const and unsafe go in pub unsafe const fn x. pub is pretty easy since it “always goes first”, but there’s no such obvious rule for unsafe and const.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 @petrochenkov's order.

Copy link
Member

Choose a reason for hiding this comment

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

I prefer unsafe const fn because I see const fn as something different from fn, while unsafe is a mere qualifier.
There's no real reason why there aren't const fn() pointer types, they just weren't implemented.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for @nagisa: allow both orders
There's no good reason to force users to learn a particular order.

If we decide on a preferred order, that can still be enforced by rustfmt. No need to make rustc overly strict.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm... both could be allowed, but would complicate the parser (if it is to correctly disallow unsafe const unsafe fn). I'll yeild to the language team on the final decision, but I'm leaning towards keeping a fixed order.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @petrochenkov: unsafe fn feels like a more fundamental concept/thing than const fn. (const on a function doesn't outlaw it from being used as a non-const function, while unsafe does outlaw it from being used as a non-unsafe one.)

Copy link
Contributor

Choose a reason for hiding this comment

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

@eddyb I see how a const fn ptr could allow for higher order functions at compile-time, I am not sure that is the right means to achieve that.

OptionalInt(val)
}
}
```

# Drawbacks

* A design that is not conservative enough risks creating backwards compatibility
Expand Down Expand Up @@ -211,8 +223,6 @@ that a certain method of that trait is implemented as `const`.

# Unresolved questions

* Allow `unsafe const fn`? The implementation cost is negligible, but I am not
certain it needs to exist.
* Keep recursion or disallow it for now? The conservative choice of having no
recursive `const fn`s would not affect the usecases intended for this RFC.
If we do allow it, we probably need a recursion limit, and/or an evaluation
Expand All @@ -226,3 +236,9 @@ cannot be taken for granted, at least `if`/`else` should eventually work.
- This RFC was accepted on 2015-04-06. The primary concerns raised in
the discussion concerned CTFE, and whether the `const fn` strategy
locks us into an undesirable plan there.

# Updates since being accepted

Since it was accepted, the RFC has been updated as follows:

1. Allowed `unsafe const fn`