Description
Thank you for filing a bug report! 🐛
Thank you for continuing to improve Rust!
Given the following code: playground
trait Irrelevant {}
struct Buffer {
ptr: Option<&'static dyn Irrelevant>,
}
impl Buffer {
pub const fn new() -> Self {
Buffer {
ptr: None,
}
}
}
The current output is:
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> src/lib.rs:10:18
|
10 | ptr: None,
| ^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
After reading this message and reading #57563, I'm not sure what trait bound is a problem. The code that is literally written here does not have any trait bounds - no syntax R: T
; nor does it have any (explicit) generic const fn
.
I assume there is a good reason why this doesn't immediately work - I know the Rust team has put tons of work into making all this analysis correct, so this is not a complaint about the analysis. :-) I'm just not sure how to go from the compiler's message to an action other than "switch to nightly".
(I can confirm that switching to nightly and enabling #![feature(const_fn_trait_bounds)]
does quiet the warning. It's not clear to me what more-specific issue than #57563 is tracking it?)
Experiments / speculation:
I'm assuming there's some sort of desugaring here that's causing a trait bound to appear - e.g. the None
constructor becoming a const fn
(per #61456) , and something in the Option
's generic argument turning into a trait bound. However, Option<T>
itself doesn't have any trait bounds on T
(...other than the default Sized
, which the error message says is OK), so I'm not sure what to change.
Some experimenting shows that Option<&static T>
its OK for a built-in T
:
trait Irrelevant {}
struct Buffer {
ptr: Option<&'static usize>,
}
impl Buffer {
pub const fn new() -> Self {
Buffer {
ptr: None,
}
}
}
And even using a different ?Sized
type - [u8]
- works out alright:
trait Irrelevant {}
struct Buffer {
ptr: Option<&'static [u8]>,
}
impl Buffer {
pub const fn new() -> Self {
Buffer {
ptr: None,
}
}
}
That's based on a not-great understanding of Sized
- if I understand correctly both dyn T
and [u8]
are ?Sized
.