Uh oh!
There was an error while loading. Please reload this page.
Distinguish fn item types to allow reification from nothing to fn pointers. - #31710
Conversation
rust-highfive
commented
Feb 16, 2016
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
nikomatsakis
commented
Feb 16, 2016
nikomatsakis
commented
Feb 16, 2016
Triggering a crater run. |
nikomatsakis
commented
Feb 16, 2016
Crater run results: https://gist.github.com/nikomatsakis/0902ea970301a841231e One regression ( |
12fa405 to
dd04d6aComparebors
commented
Feb 18, 2016
☔ The latest upstream changes (presumably #31394) made this pull request unmergeable. Please resolve the merge conflicts. |
e9fe0fc to
8d806beCompareeddyb
commented
Feb 23, 2016
The regression should be handled by the unify-coerce logic, however I wish I could enable the full extent of it without triggering LLVM asserts 😞. |
eddyb
commented
Feb 23, 2016
Turns out that using The problem in question starts with My code was mistakenly assigning What usually happens is I've come up with this testcase, which should trigger the same sequence of events, but does not: fnmain(){letmut x = unsafe{std::mem::zeroed()};letmut y = &[1,2,3][x];
y = &vec![];
x = ..;}It errors with "type mismatch resolving cc @rust-lang/compiler Even though my PR appears to work now, I dread leaving an obligation-dropping bug around. |
eddyb
commented
Feb 23, 2016
Found the culprit: it's this let resolved_t = match unresolved_type_action {UnresolvedTypeAction::Error => {structurally_resolved_type(fcx, sp, t)}UnresolvedTypeAction::Ignore => {// We can continue even when the type cannot be resolved// (i.e. it is an inference variable) because `Ty::builtin_deref`// and `try_overloaded_deref` both simply return `None`// in such a case without producing spurious errors.
fcx.resolve_type_vars_if_possible(t)}};
Usually that's not an issue because a failed coercion is fatal, so at worst you get an ICE after a legitimate error. But I had code which tried coercions and continued in a different manner, resulting in projection obligations successfully selected but then their effects completely rolled back and thus The fix is very simple: replace that line with However, I would like a permanent solution, that doesn't allow access to |
307dabf to
4d44144Compareeddyb
commented
Feb 23, 2016
@nikomatsakis Tests appear to pass, can I get another crater run? If we see any regressions caused by the scheme I chose, we'll have to tone it down, perhaps limit it to two function item types (although I really like this scheme, especially now that I've plucked the bugs out and it seems to "just work"). |
nikomatsakis
commented
Feb 23, 2016
OK, I've reviewed as far as ea2510c9eaf1fe3d1fc87b30b643a51e8662d13d (though I'm still reading through d619ebedbbaef7ec0a5c3aabf72edc9a7a165f3b, which seems to be the "meaty" commit) -- it all seems quite nice thus far. |
nikomatsakis
commented
Feb 25, 2016
@eddyb the crater run seems to have results now, maybe it just wasn't done before: https://gist.github.com/nikomatsakis/54fbfe9a0d09b8f51cc6
|
nikomatsakis
commented
Mar 1, 2016
@eddyb so we were talking about this in the @rust-lang/lang meeting -- if we want to abide by our usual policies, we may want to think about a compatibility mode for transmute where we permit transmutes from a (zero-sized) fn to a ptr but issue a "forward compatibility" lint warning about phasing this change out. I wish there was something more ergonomic than |
eddyb
commented
Mar 9, 2016
@bors r=nikomatsakis |
bors
commented
Mar 9, 2016
📌 Commit 3855fa9 has been approved by |
bors
commented
Mar 9, 2016
⌛ Testing commit 3855fa9 with merge 3dc9398... |
bors
commented
Mar 10, 2016
⛄ The build was interrupted to prioritize another pull request. |
bors
commented
Mar 10, 2016
Distinguish fn item types to allow reification from nothing to fn pointers. The first commit is a rebase of #26284, except for files that have moved since. This is a [breaking-change], due to: * each FFI function has a distinct type, like all other functions currently do * all generic parameters on functions are recorded in their item types, e.g.: `size_of::<u8>` & `size_of::<i8>`'s types differ despite their identical signature. * function items are zero-sized, which will stop transmutes from working on them The first two cases are handled in most cases with the new coerce-unify logic, which will combine incompatible function item types into function pointers, at the outer-most level of if-else chains, match arms and array literals. The last case is specially handled during type-checking such that transmutes from a function item type to a pointer or integer type will continue to work for another release cycle, but are being linted against. To get rid of warnings and ensure your code will continue to compile, cast to a pointer before transmuting.
bors
commented
Mar 10, 2016
This fixes the warning appearing from rust-lang/rust#31710. The objc_msgSend functions aren't intended to be used directly, so since OSX 10.8 they are defined empty like this as long as you don't define OBJC_OLD_DISPATCH_PROTOTYPES.
This fixes the warning appearing from rust-lang/rust#31710.
SSheldon
commented
Jun 25, 2016
FYI, special casing the transmute from functions did not prevent all regressions. I had some code that started segfaulting in 1.9.0, fixed by SSheldon/rust-objc-foundation@f918819. Basically, it boils down to looking like this: #[link(name = "objc", kind = "dylib")]extern{fnobjc_msgSend();}unsafefnmsg_send<T>(t:T){let f:unsafeexternfn() = objc_msgSend;let f:unsafeexternfn(T) = ::std::mem::transmute(f);f(t)}fnhello(){println!("hello");}fnmain(){unsafe{msg_send(hello);}}That's a case where what used to be a function pointer silently becomes a 0-sized type. Anyways, fixed now, hopefully no one else is writing code like this! But figured I'd make it known in case anyone else runs into something similar. |
Type-checking and translation of zero-sized function item types (fixes#19925).
The first commit is a rebase of #26284, except for files that have moved since.
This is a [breaking-change], due to:
size_of::<u8>&size_of::<i8>'s types differ despite their identical signature.The first two cases are handled in most cases with the new coerce-unify logic,
which will combine incompatible function item types into function pointers,
at the outer-most level of if-else chains, match arms and array literals.
The last case is specially handled during type-checking such that transmutes
from a function item type to a pointer or integer type will continue to work for
another release cycle, but are being linted against. To get rid of warnings and
ensure your code will continue to compile, cast to a pointer before transmuting.