{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/53639","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/53639/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/53639/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/53639/events","html_url":"https://github.com/rust-lang/rust/issues/53639","id":353434959,"node_id":"MDU6SXNzdWUzNTM0MzQ5NTk=","number":53639,"title":"Consider removing UB-happy `static mut` in Rust 2018.","user":{"login":"eddyb","id":77424,"node_id":"MDQ6VXNlcjc3NDI0","avatar_url":"https://avatars2.githubusercontent.com/u/77424?v=4","gravatar_id":"","url":"https://api.github.com/users/eddyb","html_url":"https://github.com/eddyb","followers_url":"https://api.github.com/users/eddyb/followers","following_url":"https://api.github.com/users/eddyb/following{/other_user}","gists_url":"https://api.github.com/users/eddyb/gists{/gist_id}","starred_url":"https://api.github.com/users/eddyb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eddyb/subscriptions","organizations_url":"https://api.github.com/users/eddyb/orgs","repos_url":"https://api.github.com/users/eddyb/repos","events_url":"https://api.github.com/users/eddyb/events{/privacy}","received_events_url":"https://api.github.com/users/eddyb/received_events","type":"User","site_admin":false},"labels":[{"id":31942528,"node_id":"MDU6TGFiZWwzMTk0MjUyOA==","url":"https://api.github.com/repos/rust-lang/rust/labels/I-nominated","name":"I-nominated","color":"e10c02","default":false},{"id":211668019,"node_id":"MDU6TGFiZWwyMTE2NjgwMTk=","url":"https://api.github.com/repos/rust-lang/rust/labels/T-lang","name":"T-lang","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":18,"created_at":"2018-08-23T15:27:18Z","updated_at":"2018-08-23T18:17:24Z","closed_at":null,"author_association":"MEMBER","body":"`static mut` is almost impossible to use correctly, see https://github.com/rust-lang-nursery/lazy-static.rs/issues/117 for an example in the widely-used `lazy-static`.\r\n\r\nYou **must** be able to show that *every borrow* of the `static mut` is **not reentrant** (as opposed to regular interior mutability, which only requires reentrance-freedom when accessing data), which is almost entirely impossible in real-world scenarios.\r\n\r\n<hr/>\r\n\r\nWe have a chance at removing it from Rust2018 and force people to use a proper synchronization abstraction (e.g. `lazy_static!` + `Mutex`), *or in lieu of one*,  `thread_local!` / `scoped_thread_local!`.\r\n\r\nIf they were using `static mut` with *custom* synchronization logic, they should do this:\r\n```rust\r\npub struct CustomSynchronizingAbstraction<T> {\r\n    /* UnsafeCell / Cell / RefCell / etc. around data, e.g. `T` */\r\n}\r\n// Promise that proper synchronization exists *around accesses*.\r\nunsafe impl<T: Sync> Sync for CustomSynchronizingAbstraction<T> {}\r\n```\r\nAnd then use `CustomSynchronizingAbstraction` with regular `static`s, safely.\r\n\r\nThis matches the \"soundness boundary\" of Rust APIs, whereas `static mut` is more like C.\r\n\r\ncc @RalfJung @rust-lang/compiler  @rust-lang/lang"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/415517875","html_url":"https://github.com/rust-lang/rust/issues/53639#issuecomment-415517875","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/53639","id":415517875,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNTUxNzg3NQ==","user":{"login":"japaric","id":5018213,"node_id":"MDQ6VXNlcjUwMTgyMTM=","avatar_url":"https://avatars3.githubusercontent.com/u/5018213?v=4","gravatar_id":"","url":"https://api.github.com/users/japaric","html_url":"https://github.com/japaric","followers_url":"https://api.github.com/users/japaric/followers","following_url":"https://api.github.com/users/japaric/following{/other_user}","gists_url":"https://api.github.com/users/japaric/gists{/gist_id}","starred_url":"https://api.github.com/users/japaric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japaric/subscriptions","organizations_url":"https://api.github.com/users/japaric/orgs","repos_url":"https://api.github.com/users/japaric/repos","events_url":"https://api.github.com/users/japaric/events{/privacy}","received_events_url":"https://api.github.com/users/japaric/received_events","type":"User","site_admin":false},"created_at":"2018-08-23T18:17:24Z","updated_at":"2018-08-23T18:17:24Z","author_association":"MEMBER","body":"@eddyb \r\n\r\nIn embedded we use `static mut` variables with interrupt handlers. These\r\nhandlers are invoked by the hardware and non-reentrant by hardware design (while\r\nexecuting an interrupt handler the same handler will *not* be invoked again if\r\nthe interrupt signal is received. Also the devices are single core). So we have a\r\npattern like to let users add state to their interrupt handlers:\r\n\r\n``` rust\r\n// we generate this function using macros\r\n#[export_name = \"SOME_KNOWN_NAME_TO_HAVE_THE_LINKER_PUT_THIS_IN_THE_RIGHT_PLACE\"]\r\npub unsafe extern \"C\" fn interrupt_handler_that_has_some_random_name_unknown_to_the_user() {\r\n    static mut STATE: usize = 0; // initial value provided by the user\r\n\r\n    on_button_pressed(&mut STATE);\r\n}\r\n\r\n// the user provides this function along with the initial value for the state\r\nfn on_button_pressed(count: &mut usize) {\r\n    *count += 1;\r\n    println!(\"Button has been pressed {} times\", *count);\r\n}\r\n```\r\n\r\nThis way the end user indirectly uses `static mut` variables in a non-reentrant\r\nfashion. The user can't call the interrupt handler themselves because the name\r\nof the function is an implementation detail and if they call `on_button_pressed`\r\nthemselves there's still no problem because that won't operate on the hidden\r\n`static mut` variable.\r\n\r\nAs there are no newtypes involved the user can use primitives and types\r\nthe define themselves (e.g. structs with `pub(crate)` fields) without requiring\r\nthe unstable `const fn` feature.\r\n\r\nI'm not against this feature as long as the above pattern continues to work on stable Rust 2018."}}
{"actor":{"display_login":"japaric"}}