-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
codegen generates vtables for a variable's supertype when unsizing sometimes #107205
Comments
This might be the shortest code sample* I've seen cause a link error. Bravo! Marginally reduced: https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=e4cd76a3ddf3068e0d71ea19247915a9 * aside from obviously broken code, |
The following reproduction reproduces on stable but not on nightly: use std::fmt;
pub struct Wrapper(for<'b> fn(&'b ()));
impl fmt::Debug for Wrapper {
fn fmt<'a>(&'a self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let dyn_debug: &dyn fmt::Debug = &self.0 as &fn(&'static ());
fmt::Debug::fmt(&dyn_debug, f)
}
}
fn useful(_: &()) {}
fn main() {
println!("{:?}", Wrapper(useful));
} searched nightlies: from nightly-2023-02-01 to nightly-2023-03-16 bisected with cargo-bisect-rustc v0.6.5Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc 2023-02-01 --end 2023-03-16 --access github --regress success Bisection points at a new optimization, so I guess the problematic code is simply optimized away. Using |
Here is a code snippet that segfaults on stable because of this bug: #![allow(coherence_leak_check)]
struct Foo<T: 'static>(T);
fn useful<'a>(_: &'a u8) {}
pub struct Wrapper(for<'b> fn(&'b u8));
trait GetInner {
type Assoc;
fn muahaha(&mut self) -> Self::Assoc;
}
impl GetInner for Foo<fn(&'static u8)> {
type Assoc = String;
fn muahaha(&mut self) -> String {
panic!("cant do it boss")
}
}
impl GetInner for Foo<for<'a> fn(&'a u8)> {
type Assoc = [usize; 3];
fn muahaha(&mut self) -> [usize; 3] {
[100; 3]
}
}
fn main() {
let wrapper = Wrapper(useful);
drop(Box::new(Foo(useful as fn(&'static u8))) as Box<dyn GetInner<Assoc = String>>);
drop(Box::new(Foo(useful as fn(&u8))) as Box<dyn GetInner<Assoc = [usize; 3]>>);
let hr_fnptr = Box::new(Foo::<for<'a> fn(&'a u8)>(wrapper.0));
let lr_fnptr = hr_fnptr as Box<Foo<fn(&'static u8)>>;
let mut any = lr_fnptr as Box<dyn GetInner<Assoc = String>>;
let evil_string = any.muahaha();
drop(evil_string);
} if you remove the two statements that are |
Here is also a super minimal repro of a linker error, although note that it requires pub struct Wrapper(for<'b> fn(&'b ()));
fn useful(_: &()) {}
fn main() {
let wrapper = Wrapper(useful);
let dyn_debug = &wrapper.0 as &fn(&'static ()) as &dyn std::fmt::Debug;
println!("{:?}", dyn_debug);
} |
This comment was marked as outdated.
This comment was marked as outdated.
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-critical |
this regressed in 1.17, the bug probably existed ever since we added mir: https://godbolt.org/z/a3b5Er71c |
an even more minimal linker error happens with // rustc src/main.rs -Zmir-opt-level=0
const X: for<'b> fn(&'b ()) = |&()| ();
fn main() {
let dyn_debug = &X as &fn(&'static ()) as &dyn Send;
drop(dyn_debug)
} the bug here is caused by This causes unsoundness when we do trait solving using the type of the https://github.com/rust-lang/rust/compare/master...lcnr:rust:operand-ref?expand=1 tries to deal with that in some locals which is enough for that minimal linker error repro but does not yet fix the unsoudness as the status quo is very worrying to me:
Going to keep looking a bit more into this and may write some mentoring instructions or will look into fixing this myself. Also, thanks @BoxyUwU for guiding me towards my current understanding here |
Make subtyping explicit in MIR This adds new mir-opt that pushes new `ProjectionElem` called `ProjectionElem::Subtype(T)` to `Rvalue` of a subtyped assignment so we can unsoundness issues like rust-lang#107205 Addresses rust-lang#112651 r? `@lcnr`
Make subtyping explicit in MIR This adds new mir-opt that pushes new `ProjectionElem` called `ProjectionElem::Subtype(T)` to `Rvalue` of a subtyped assignment so we can unsoundness issues like rust-lang#107205 Addresses rust-lang#112651 r? `@lcnr`
Make subtyping explicit in MIR This adds new mir-opt that pushes new `ProjectionElem` called `ProjectionElem::Subtype(T)` to `Rvalue` of a subtyped assignment so we can unsoundness issues like rust-lang/rust#107205 Addresses rust-lang/rust#112651 r? `@lcnr`
Make subtyping explicit in MIR This adds new mir-opt that pushes new `ProjectionElem` called `ProjectionElem::Subtype(T)` to `Rvalue` of a subtyped assignment so we can unsoundness issues like rust-lang/rust#107205 Addresses rust-lang/rust#112651 r? `@lcnr`
Make subtyping explicit in MIR This adds new mir-opt that pushes new `ProjectionElem` called `ProjectionElem::Subtype(T)` to `Rvalue` of a subtyped assignment so we can unsoundness issues like rust-lang/rust#107205 Addresses rust-lang/rust#112651 r? `@lcnr`
I was putting
&
's here and there to make my program compile as beginners supposed to do and finally ended with:To assure myself that this is unrelated to native/rosetta mess I've ran this in docker and in rust playground with the same outcome.
This particular code breaks the linker
I've come up with that since deriving
Debug
or implementing it manually like thatleads to following type/borrow check error:
Expected behavior: program prints
Actual behavior: see above
rustc --version --verbose
:I've tried both beta
1.67.0-beta.9
and nightly1.68.0-nighlty
at rust playground and both are failing during linking.Edit
I've bruteforced working program 😂 :
The text was updated successfully, but these errors were encountered: