Skip to content

can't store static references in a Unique indirectly #22655

Closed
@blaenk

Description

@blaenk

EDIT: Removed talk of variance, since it doesn't seem to be the cause and it was unnecessarily longer due to it.

It seems to me like 801bc48 is an attempt to introduce the second approach from the unresolved questions of RFC 738.

Rewrite safe abstractions to use *const (or even usize) instead of *mut, casting to *mut only they have a &mut self method. This is probably the most conservative option.

It seems to me that the commit is actually a breaking change, because it broke my code without my changing it. Consider this reduced example (thanks to @p1start for helping me to reduce it further).

pub struct Node<V> {
    vals: V,
    edges: ::std::ptr::Unique<Node<V>>,
}

fn is_send<T: Send>() {}

fn main() {
    is_send::<Node<&'static ()>>();
}

This overflows on the recursive requirement evaluation:

<anon>:16:5: 16:33 error: overflow evaluating the requirement `Node<&()> : core::marker::Send` [E0275]
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: consider adding a `#![recursion_limit="128"]` attribute to your crate
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: required because it appears within the type `Node<&()>`
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: required because it appears within the type `Node<&()>`
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: required because it appears within the type `Node<&()>`
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: required because it appears within the type `Node<&()>`
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:16:5: 16:33 note: required because it appears within the type `Node<&()>`
<anon>:16     is_send::<Node<&'static ()>>();
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
[... truncated ...]

I attempted to bump the recursion limit to 2046 even and it just told me to try again with 4096, so I figure it's just going to infinitely recurse if allowed.

This only seems to happen if I use a &'static reference, so I think that has something to do with it.

@p1start came up with an example that actually hangs rustc completely when using a recursive type:

pub struct Node<V> {
    vals: V,
    edges: ::std::ptr::Unique<Node<V>>,
}

struct Foo<'a> {
    x: Box<Option<Node<(&'a (), Foo<'a>)>>>
}

fn is_send<T: Send>() {}

fn main() {
    is_send::<Foo>();
}

The real-world scenario that led me to this bug was a BTreeMap with &'static str keys:

use std::collections::BTreeMap;

fn is_send<T: Send>() {}

fn main() {
    is_send::<BTreeMap<&'static (), ()>>();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions