Closed adamritter closed 11 months ago
MIRI claims undefined behavior here:
error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free)
--> src/lib.rs:21:38
|
21 | self.listeners().listen(|m| r.send(f(m)));
| ^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside closure at src/lib.rs:21:38
= note: inside `<std::boxed::Box<dyn std::ops::FnMut(())> as std::ops::FnMut<((),)>>::call_mut` at /Users/cognite/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2016:9
note: inside `MessageListeners::<'_>::send` at src/lib.rs:16:13
--> src/lib.rs:16:13
|
16 | (*listener)(message.clone());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `test_message_listeners_map0` at src/lib.rs:43:5
--> src/lib.rs:43:5
|
43 | ml.send(());
| ^^^^^^^^^^^
note: inside closure at src/lib.rs:38:34
--> src/lib.rs:38:34
|
37 | #[test]
| ------- in this procedural macro expansion
38 | fn test_message_listeners_map0() {
| ^
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
Given that this code only consists of safe code, that smells like a compiler bug.
First crashes in nightly-2020-10-07.
Earlier versions report a lifetime error:
Was that lifetime error correct?
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-critical
Was that lifetime error correct?
Yes, the lifetime error is correct fn(&self) -> &'a _
is incompatible with the definition in the trait: fn(&self) -> &_
.
Looks like it may be a bug in compare_predicate_entailment
(trait<=>impl method compatibility checking). I'll take a look at this today, and if I can't find a root cause + fix in a few hours, I'll give it back.
@rustbot claim
found 6 bors merge commits in the specified range
commit[0] 2020-10-05UTC: Auto merge of #77080 - richkadel:llvm-coverage-counters-2, r=tmandry
commit[1] 2020-10-06UTC: Auto merge of #77606 - JohnTitor:rollup-7rgahdt, r=JohnTitor
commit[2] 2020-10-06UTC: Auto merge of #77594 - timvermeulen:chain_advance_by, r=scottmcm
commit[3] 2020-10-06UTC: Auto merge of #73905 - matthewjasper:projection-bounds-2, r=nikomatsakis
commit[4] 2020-10-06UTC: Auto merge of #76356 - caass:hooks, r=jyn514
commit[5] 2020-10-06UTC: Auto merge of #77386 - joshtriplett:static-glibc, r=petrochenkov
Almost certainly due to #73905.
The issue is minimized to this basically:
pub struct Listeners<'a> {
listeners: RefCell<Vec<Box<dyn FnMut(()) + 'a>>>
}
pub trait ListenersInterface {
fn listeners<'b>(&'b self) -> &'b Listeners<'b>;
}
impl<'a> ListenersInterface for Listeners<'a> {
fn listeners<'b>(&'b self) -> &'a Listeners<'b> {
self
}
}
The fact that the impl
compiles is incorrect, I think.
Basically, for this to be sound, given the assumptions of the impl
+ the assumptions from the trait's method's where clauses (and assuming the trait's method's types are well-formed), we should be able to prove that the impl
's method's types are well-formed.
This boils down to: given WellFormed(&'b Listeners<'a>) + WellFormed(&'b Listeners<'b>)
(i.e. given 'a: 'b
), proving that WellFormed(&'a Listeners<'b>)
(i.e. 'b: 'a
), which is not possible.
edit: Oh it's already a runtime error. I thought it was an ICE :eyes:.
An exploit of this bug for an actual ub:
trait Trait {
fn get<'s>(s: &'s str, _: &'static &'static ()) -> &'static str;
}
impl Trait for () {
fn get<'s>(s: &'s str, _: &'static &'s ()) -> &'static str {
s
}
}
fn main() {
let val = <() as Trait>::get(&String::from("blah blah blah"), &&());
println!("{}", val);
}
An exploit of this bug for an actual ub:
trait Trait { fn get<'s>(s: &'s str, _: &'static &'static str) -> &'static str; } impl Trait for () { fn get<'s>(s: &'s str, _: &'static &'s str) -> &'static str { s } } fn main() { let val = <() as Trait>::get(&String::from("blah blah blah"), &""); println!("{}", val); }
This reminds me of #25860
Visiting during T-compiler meeting, reprioritizing.
@rustbot label -P-critical +P-high
closing as a duplicate of #80176, currently have a deny by default future-compat lint here. We'll convert that lint to a hard error soon-ish
I tried this code:
I expected to see this happen: the two tests do the same thing
Instead, this happened: the first unit test SEG faults, the second succeeds
Meta
rustc --version --verbose
:Caused by: process didn't exit successfully:
/Users/adamritter/Documents/GitHub/synced_collection/target/debug/deps/synccollection-9d89a83a383169be
(signal: 11, SIGSEGV: invalid memory reference)```