Repository: rust
Issue: Constructing `Option<&'static dyn T>::None` in a `const fn` requires `const_fn_trait_bounds`
Labels: A-diagnostics,T-compiler

> Thank you for filing a bug report! 🐛

Thank you for continuing to improve Rust!

---

Given the following code: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=368bc1495ce529ba04b340a6b6f4823e)

```rust
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,
        }
    }
}
```

[compiles on stable (1.53.0)](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=32edf652e3306068cbaa4bf3c213ba4a).

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,
        }
    }
}
```

[compiles as well](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a0987889d12cfaeab1682c21f3339267).

That's based on a not-great understanding of `Sized` - if I understand correctly both `dyn T` and `[u8]` are `?Sized`.