Skip to content
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

Implement `MaybeUninit` #53508

Merged
merged 19 commits into from Sep 23, 2018

Conversation

@japaric
Copy link
Member

japaric commented Aug 19, 2018

This PR:

  • Adds MaybeUninit (see #53491) to {core,std}::mem.
  • Makes mem::{uninitialized,zeroed} panic when they are used to instantiate an uninhabited type.
  • Does not deprecate mem::{uninitialized,zeroed} just yet. As per #53491 (comment), we should not deprecate them until MaybeUninit is stabilized.
  • It replaces uses of mem::{uninitialized,zeroed} in core and alloc with MaybeUninit.

There are still several instances of mem::{uninitialized,zeroed} in std that this PR doesn't address.

r? @RalfJung
cc @eddyb you may want to look at the new panicking logic

@Mark-Simulacrum
Copy link
Member

Mark-Simulacrum left a comment

Looks like there might be a few cases where we're not performing the right change here?

/// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
#[unstable(feature = "maybe_uninit", issue = "53491")]
pub const fn uninitialized() -> MaybeUninit<T> {

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

Do we need a rustc_const_unstable attribute here as well? Or at least make a note to do so eventually?

This comment has been minimized.

@RalfJung

RalfJung Aug 21, 2018

Member

Why not stabilize as const fn?


// Perform the swap
copy_nonoverlapping(x, &mut tmp, 1);
copy_nonoverlapping(x, tmp.get_mut(), 1);

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

Shouldn't this be using as_mut_ptr?

copy_nonoverlapping(src, &mut tmp, 1);
tmp
let mut tmp = MaybeUninit::<T>::uninitialized();
copy_nonoverlapping(src, tmp.get_mut(), 1);

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

This also looks like it should be as_mut_ptr? tmp is not initialized at this point.

let rawarray = RawArray::new();
let buf = rawarray.ptr();
let rawarray = MaybeUninit::<RawArray<T>>::uninitialized();
let buf = rawarray.get_ref().ptr();

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

Isn't this also not legitimate code? get_ref is only defined as far as I can tell on initialized memory, but it's not initialized here.

start_l = offsets_l.as_mut_ptr();
end_l = offsets_l.as_mut_ptr();
start_l = unsafe { offsets_l.get_mut().as_mut_ptr() };
end_l = unsafe { offsets_l.get_mut().as_mut_ptr() };

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

Isn't this also invalid? I believe offsets_l is uninitialized at this point?

@@ -288,8 +288,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize

if start_r == end_r {
// Trace `block_r` elements from the right side.
start_r = offsets_r.as_mut_ptr();
end_r = offsets_r.as_mut_ptr();
start_r = unsafe { offsets_r.get_mut().as_mut_ptr() };

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Aug 19, 2018

Member

This code also looks like this should be invalid? At least, offsets_r is not necessarily initialized, right?

keys: [K; CAPACITY],
vals: [V; CAPACITY],
keys: MaybeUninit<[K; CAPACITY]>,
vals: MaybeUninit<[V; CAPACITY]>,

This comment has been minimized.

@scottmcm

scottmcm Aug 19, 2018

Member

Based on the comment above, should this instead be [MaybeUninit<V>; CAPACITY]?

(That might be a pain, though, and this is no worse than before, so might not be this PR.)

This comment has been minimized.

@RalfJung

RalfJung Aug 21, 2018

Member

That seems like a pretty equivalent type to me. Which comment above?

This comment has been minimized.

@eddyb

eddyb Aug 22, 2018

Member

Should we document that you can partially-initialize MaybeUninit, i.e. that it "distributes over products"?

This comment has been minimized.

@RalfJung

RalfJung Aug 22, 2018

Member

I guess this is forth saying, yes.

Unfortunately actually implementing this is not easy, same problem as for Cell (which also distributes over products).

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Aug 19, 2018

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:52:51] ....................................................................................................
[00:52:54] ....................................................................................................
[00:52:57] .....i..............................................................................................
[00:53:00] ....................................................................................................
[00:53:03] ......................................................iiiiiiiii.....................................
[00:53:08] ....................................................................................................
[00:53:12] ....................................................................................................
[00:53:15] ...................................i................................................................
[00:53:17] .....................................................................................i.i..ii........
---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-gdb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:01:01] 
[01:01:01] running 110 tests
[01:01:12] iiii.......i..i........i..i.i.............i..........iiii...........i.F..i....F.....ii.i.i.......ii.
[01:01:13] failures:
[01:01:13] 
[01:01:13] ---- [debuginfo-gdb] debuginfo/nil-enum.rs stdout ----
[01:01:13] ---- [debuginfo-gdb] debuginfo/nil-enum.rs stdout ----
[01:01:13] NOTE: compiletest thinks it is using GDB without native rust support
[01:01:13] NOTE: compiletest thinks it is using GDB version 7011001
[01:01:13] 
[01:01:13] error: line not found in debugger output: $1 = {<No data fields>}
[01:01:13] status: exit code: 0
[01:01:13] command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/checkout/obj/build/x86_64-unknown-linux-gnu/test/debuginfo/nil-enum/nil-enum.debugger.script"
[01:01:13] ------------------------------------------
[01:01:13] GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
[01:01:13] Copyright (C) 2016 Free Software Foundation, Inc.
[01:01:13] Copyright (C) 2016 Free Software Foundation, Inc.
[01:01:13] License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[01:01:13] This is free software: you are free to change and redistribute it.
[01:01:13] There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[01:01:13] and "show warranty" for details.
[01:01:13] This GDB was configured as "x86_64-linux-gnu".
[01:01:13] Type "show configuration" for configuration details.
[01:01:13] For bug reporting instructions, please see:
[01:01:13] <http://www.gnu.org/software/gdb/bugs/>.
[01:01:13] Find the GDB manual and other documentation resources online at:
[01:01:13] <http://www.gnu.org/software/gdb/documentation/>.
[01:01:13] For help, type "help".
[01:01:13] Type "apropos word" to search for commands related to "word".
[01retty-std-collections.debugger.script"
[01:01:13] ------------------------------------------
[01:01:13] GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
[01:01:13] Copyright (C) 2016 Free Software Foundation, Inc.
[01:01:13] Copyright (C) 2016 Free Software Foundation, Inc.
[01:01:13] License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[01:01:13] This is free software: you are free to change and redistribute it.
[01:01:13] There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[01:01:13] and "show warranty" for details.
[01:01:13] This GDB was configured as "x86_64-linux-gnu".
[01:01:13] Type "show configuration" for configuration details.
[01:01:13] For bug reporting instructions, please see:
[01:01:13] <http://www.gnu.org/software/gdb/bugs/>.
[01:01:13] Find the GDB manual and other documentation resources online at:
[01:01:13] <http://www.gnu.org/software/gdb/documentation/>.
[01:01:13] For help, type "help".
[01:01:13] Type "apropos word" to search for commands related to "word".
[01:01:13] Breakpoint 1 at 0x144f6: file /checkout/src/test/debuginfo/pretty-std-collections.rs, line 57.
[01:01:13] [Thread debugging using libthread_db enabled]
[01:01:13] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[01:01:13] 
[01:01:13] Breakpoint 1, pretty_std_collections::main::h617474859dc5b54e () at /checkout/src/test/debuginfo/pretty-std-collections.rs:57
[01:01:13] 57     zzz(); // #break
[01:01:13] $1 = BTreeSet<i32>(len: 3)
[01:01:13] $2 = BTreeMap<i32, i32>(len: 3)
[01:01:13] $3 = VecDeque<i32>(len: 3, cap: 8) = {5, 3, 7}
[01:01:13] A debugging session is active.
[01:01:13] 
[01:01:13]  Inferior 1 [process 15246] will be killed.
[01:01:13] 
[01:01:13] Quit anyway? (y or n) [answered Y; input not from terminal]
[01:01:13] ------------------------------------------
[01:01:13] stderr:
[01:01:13] ------------------------------------------
[01:01:13] ------------------------------------------
[01:01:13] Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
[01:01:13] Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
[01:01:13] ------------------------------------------
[01:01:13] 
[01:01:13] thread '[debuginfo-gdb] debuginfo/pretty-std-collections.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:3189:9
[01:01:13] 
---
[01:01:13] 
[01:01:13] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:497:22
[01:01:13] 
[01:01:13] 
[01:01:13] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/debuginfo" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/debuginfo" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "debuginfo-gdb" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-5.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "5.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:01:13] 
[01:01:13] 
[01:01:13] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:01:13] Build completed unsuccessfully in 0:12:31
[01:01:13] Build completed unsuccessfully in 0:12:31
[01:01:13] make: *** [check] Error 1
[01:01:13] Makefile:58: recipe for target 'check' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0ef71254
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
The command "date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
" exited with 0.
travis_fold:start:after_failure.1
travis_time:start:0aaf1540
$ echo/bootstrap-1v3ifugz4t07z/s-f40eeanft4-1h7wppw-1iplbejydu42a
128740 ./obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release
128648 ./obj/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu
128644 ./obj/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release
125880 ./obj/build/x86_64-unknown-linux-gnu/stage1-rustc/x86_64-unknown-linux-gnu/release/deps

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@@ -784,6 +784,14 @@ impl Abi {
_ => false,
}
}

/// Returns true if this is an uninhabited type
pub fn is_uninhabited(&self) -> bool {

This comment has been minimized.

@eddyb

eddyb Aug 20, 2018

Member

For some reason I would've avoided this but I guess it's fine.
Could you also go through rg '==.*::Uninhabited' and change all of those to use is_uninhabited?

} else {
"Attempted to instantiate an uninhabited type (e.g. `!`) \
using mem::uninitialized()"
};

This comment has been minimized.

@eddyb

eddyb Aug 20, 2018

Member

You can actually use format!("... uninhabited type {} using ...", sig.output()) here, heh.

@@ -462,6 +462,55 @@ impl FunctionCx<'a, 'll, 'tcx> {
return;
}

if (intrinsic == Some("init") || intrinsic == Some("uninit")) &&
bx.cx.layout_of(sig.output()).abi.is_uninhabited()

This comment has been minimized.

@eddyb

eddyb Aug 20, 2018

Member

Can you move this below let fn_ty? Then you can use fn_ty.ret.layout instead of calling layout_of.

panic::catch_unwind(|| mem::zeroed::<!>()).is_err();

panic::catch_unwind(|| mem::uninitialized::<Foo>()).is_err();
panic::catch_unwind(|| mem::zeroed::<Foo>()).is_err();

This comment has been minimized.

@eddyb

eddyb Aug 20, 2018

Member

I think you can also do:

assert_eq!(....downcast_ref::<&'static str>(), Some("panic message"));
@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Aug 20, 2018

Looks like the gdb pretty-printing scripts make assumptions about the fields of libstd datastructures:

def extract_length_and_ptr_from_std_btreemap(vec_val):
assert vec_val.type.get_type_kind() == TYPE_KIND_STD_BTREEMAP
root = vec_val.get_child_at_index(0)
length = vec_val.get_child_at_index(1).as_integer()
node = root.get_child_at_index(0)
ptr = node.get_child_at_index(0)
unique_ptr_val = ptr.get_child_at_index(0)
data_ptr = unique_ptr_val.get_child_at_index(0)
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
return (length, data_ptr)

@@ -567,7 +567,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
// the node, which is allowed by LLVM.
unsafe {
slice::from_raw_parts(
self.as_leaf().keys.as_ptr(),
self.as_leaf().keys.get_ref().as_ptr(),

This comment has been minimized.

@RalfJung

RalfJung Aug 21, 2018

Member

Here and below, can't you use MaybeUninit::as_ptr/MaybeUninit::as_mut_ptr?

let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
false, &mut buf, &mut parts);
false, buf.get_mut(), parts.get_mut());

This comment has been minimized.

@RalfJung

RalfJung Aug 21, 2018

Member

Another case of using &mut as &out.

struct Foo {
x: u8,
y: !,
}

This comment has been minimized.

@RalfJung

RalfJung Aug 21, 2018

Member

Could you add a test for an empty enum?

Also, AFAIK Foo is NOT layout-uninhabited, because of #49298?

This comment has been minimized.

@eddyb

eddyb Aug 22, 2018

Member

Correct, you need to change x's type to ().

This comment has been minimized.

@eddyb

eddyb Aug 22, 2018

Member

Wait, no, check this out:

#![feature(never_type)]
pub struct Foo { x: u8, y: ! }
pub fn foo() -> Foo { loop {} }

That gets noreturn in the LLVM IR, with u8 or () in the first field, but if you change the ! to (), you lose the noreturn.

What happened in the first for #49298 is we kept the layout-uninhabited property propagated, but it wouldn't affect type sizes the same.

Which means we can use the check here to detect noreturn UB in all relevant cases!

This comment has been minimized.

@RalfJung

RalfJung Aug 22, 2018

Member

nocall would be more correct than noreturn though :P

Which "check here"?

This comment has been minimized.

@eddyb

eddyb Aug 22, 2018

Member

I mean the panicking intrinsics.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Aug 21, 2018

☔️ The latest upstream changes (presumably #53530) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Aug 22, 2018

I finally wrote that blog post about whether and when &mut T must be initialized.

@japaric japaric force-pushed the japaric:maybe-uninit branch from c9fe28f to a56ee4e Aug 23, 2018

@japaric

This comment has been minimized.

Copy link
Member Author

japaric commented Aug 23, 2018

I believe I have addressed all the review comments, except for the one about gdb scripts -- I'll check that one later.

Let me know if I missed something!

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Aug 23, 2018

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:49:22] ....................................................................................................
[00:49:25] ....................................................................................................
[00:49:28] ........i...........................................................................................
[00:49:31] ....................................................................................................
[00:49:34] .........................................................iiiiiiiii..................................
[00:49:39] ....................................................................................................
[00:49:43] ....................................................................................................
[00:49:46] ......................................i.............................................................
[00:49:49] ........................................................................................i.i..ii.....
---
travis_time:start:test_debuginfo
Check compiletest suite=debuginfo mode=debuginfo-gdb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[00:57:19] 
[00:57:19] running 110 tests
[00:57:30] iiii.......i..i........i..i.i.............i...........iiii..........i.F..i....F.....ii.i.i.......ii.
[00:57:31] failures:
[00:57:31] 
[00:57:31] ---- [debuginfo-gdb] debuginfo/nil-enum.rs stdout ----
[00:57:31] ---- [debuginfo-gdb] debuginfo/nil-enum.rs stdout ----
[00:57:31] NOTE: compiletest thinks it is using GDB without native rust support
[00:57:31] NOTE: compiletest thinks it is using GDB version 7011001
[00:57:31] 
[00:57:31] error: line not found in debugger output: $1 = {<No data fields>}
[00:57:31] status: exit code: 0
[00:57:31] command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/checkout/obj/build/x86_64-unknown-linux-gnu/test/debuginfo/nil-enum/nil-enum.debugger.script"
[00:57:31] ------------------------------------------
[00:57:31] GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
[00:57:31] Copyright (C) 2016 Free Software Foundation, Inc.
[00:57:31] Copyright (C) 2016 Free Software Foundation, Inc.
[00:57:31] License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[00:57:31] This is free software: you are free to change and redistribute it.
[00:57:31] There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
[00:57:31] and "show warranty" for details.
[00:57:31] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:497:22
[00:57:31] This GDB was configured as "x86_64-linux-gnu".
[00:57:31] Type "show configuration" for configuration details.
[00:57:31] For bug reporting instructions, please see:
[00:57:31] <http://www.gnu.org/software/gdb/bugs/>.
[00:57:31] Find the GDB manual and other documentation resources online at:
[00:57:31] <http://www.gnu.org/software/gdb/documentation/>.
[00:57:31] For help, type "help".
[00:57:31] Type "apropos word" to search for commands related to "word".
[00:57:31] Breakpoint 1 at 0xb5e: file /checkout/src/test/debuginfo/nil-enum.rs, line 41.
[00:57:31] [Thread debugging using libthread_db enabled]
[00:57:31] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[00:57:31] [Inferior 1 (process 15233) exited with code 0145]
[00:57:31] ------------------------------------------
[00:57:31] stderr:
[00:57:31] ------------------------------------------
[00:57:31] ------------------------------------------
[00:57:31] thread 'main' panicked at 'Attempted to instantiate uninhabited type ANilEnum using mem::zeroed', /checkout/src/libcore/mem.rs:526:5
[00:57:31] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:57:31] /checkout/obj/build/x86_64-unknown-linux-gnu/test/debuginfo/nil-enum/nil-enum.debugger.script:9: Error in sourced command file:
[00:57:31] No symbol "first" in current context.
[00:57:31] ------------------------------------------
[00:57:31] 
[00:57:31] thread '[debuginfo-gdb] debuginfo/nil-enum.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:3196:9
[00:57:31] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:57:31] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:57:31] 
[00:57:31] ---- [debuginfo-gdb] debuginfo/pretty-std-collections.rs stdout ----
[00:57:31] NOTE: compiletest thinks it is using GDB without native rust support
[00:57:31] NOTE: compiletest thinks it is using GDB version 7011001
[00:57:31] 
[00:57:31] error: line not found in debugger output: $1 = BTreeSet<i32>(len: 3) = {3, 5, 7}
[00:57:31] status: exit code: 0
[00:57:31] command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-com32>(len: 3, cap: 8) = {5, 3, 7}
[00:57:31] A debugging session is active.
[00:57:31] 
[00:57:31]  Inferior 1 [process 15413] will be killed.
[00:57:31] 
[00:57:31] Quit anyway? (y or n) [answered Y; input not from terminal]
[00:57:31] ------------------------------------------
[00:57:31] stderr:
[00:57:31] ------------------------------------------
[00:57:31] ------------------------------------------
[00:57:31] Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
[00:57:31] Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
[00:57:31] ------------------------------------------
[00:57:31] 
[00:57:31] thread '[debuginfo-gdb] debuginfo/pretty-std-collections.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:3196:9
[00:57:31] 
---
[00:57:31] test result: FAILED. 84 passed; 2 failed; 24 ignored; 0 measured; 0 filtered out
[00:57:31] 
[00:57:31] 
[00:57:31] 
[00:57:31] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/debuginfo" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/debuginfo" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "debuginfo-gdb" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-5.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "5.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:57:31] 
[00:57:31] 
[00:57:31] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:57:31] Build completed unsuccessfully in 0:12:10
[00:57:31] Build completed unsuccessfully in 0:12:10
[00:57:31] Makefile:58: recipe for target 'check' failed
[00:57:31] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:1f3abcda
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:298d5800:start=1535045034615376822,finish=1535045034696368596,duration=80991774
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0b1189f0
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:01bf1338
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@pietroalbini

This comment has been minimized.

Copy link
Member

pietroalbini commented Aug 27, 2018

Ping from triage @RalfJung! This PR needs your review.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Aug 28, 2018

☔️ The latest upstream changes (presumably #53227) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Aug 28, 2018

There are still several uses of &mut as &out in src/libcore/fmt/float.rs -- if the rules in the MaybeUninit doc are strictly applied, that could would be UB. However, it is certainly no more UB than it was before this PR, so I am included to accept anyway. What would be interesting to know (as a data point for the unsafe code guidelines around &mut) is how hard it would be to change that code to use stretch the (current) rules. @japaric can you have a look?

Otherwise, r=me once Travis is happy with the gdb stuff.

@japaric

This comment has been minimized.

Copy link
Member Author

japaric commented Sep 1, 2018

Sorry for the delay! I'm looking again at this. This is one of the debuginfo tests that's failing:

enum ANilEnum {}
enum AnotherNilEnum {}
// This test relies on gdbg printing the string "{<No data fields>}" for empty
// structs (which may change some time)
// The error from gdbr is expected since nil enums are not supposed to exist.
fn main() {
unsafe {
let first: ANilEnum = ::std::mem::zeroed();
let second: AnotherNilEnum = ::std::mem::zeroed();
zzz(); // #break
}
}

The test is instantiating nil enums and then inspecting them in GDB. The program now panics with the changes mode in this PR so the test broke.

I'm not quite sure what to do here. Should I instantiate MaybeUninit<ANilEnum> and inspect that? (Would that make the test moot since it would become a union test?). Should I continue to instantiate ANilEnum using MaybeUninit::zeroed().into_inner()? (Sounds bad because UB) Or should I just remove the test? (because no one should be instantiating nil enums anyway).

cc @michaelwoerister

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Sep 1, 2018

Yeah that test is definitely UB. It might still be worth seeing how gbd displays that.

So maybe add a comment saying it is UB, and then use MaybeUninit::uninitialized().into_inner()? That replicates the previous code as closely as possible.

@japaric japaric force-pushed the japaric:maybe-uninit branch from a56ee4e to 2327942 Sep 1, 2018

@japaric

This comment has been minimized.

Copy link
Member Author

japaric commented Sep 1, 2018

Rebased and fixed the debuginfo tests in the last two commits. Regarding using MaybeUninit in fmt/float.rs I see two ways to replace &mut [T] in argument position where the passed buffer is uninitialized:

I have explored the two options by re-implementing one function using both approaches. I have pushed my work in two branches which are linked above.

Neither feels ergonomic (the first approach actually feels wrong because it constrains the argument) but the second option is slightly better except for the fact that instantiating [MaybeUninit<T>; N] requires writing MaybeUninit::uninitialized() N times. Could we make the compiler accept [MaybeUninit<T>; N]?

@abonander

This comment has been minimized.

Copy link
Contributor

abonander commented Sep 1, 2018

Is it UB to transmute MaybeUninit<[T; N]> to [MaybeUninit<T>; N]? That'd be a more convenient way to get the latter.

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Sep 23, 2018

No, definitely not.

@nnethercote

This comment has been minimized.

Copy link
Contributor

nnethercote commented Sep 25, 2018

It's a significant perf regression:

tokio-webpush-simple-opt
	avg: 14.3%	min: 1.5%	max: 37.6%
issue-46449-opt
	avg: 8.4%	min: 1.3%	max: 13.1%
script-servo-opt
	avg: 4.1%	min: 0.8%	max: 6.4%
issue-46449-debug
	avg: 4.1%	min: 1.0%	max: 4.8%
cargo-opt
	avg: 3.5%	min: 1.4%	max: 4.7%
webrender-opt
	avg: 2.4%	min: 1.1%	max: 3.5%
ripgrep-opt
	avg: 1.8%	min: 1.0%	max: 3.4%
futures-opt
	avg: 1.8%	min: 0.4%	max: 3.4%
script-servo-debug
	avg: 1.8%	min: 1.1%	max: 3.3%
sentry-cli-opt
	avg: 2.3%	min: 1.0%	max: 3.0%
regex-opt
	avg: 1.7%	min: 0.5%	max: 2.9%
tokio-webpush-simple-debug
	avg: 2.3%	min: 2.0%	max: 2.8%
inflate-opt
	avg: -0.9%?	min: -2.3%?	max: 0.7%?
clap-rs-debug
	avg: 0.9%	min: 0.5%	max: 2.1%
ctfe-stress-opt
	avg: -0.8%?	min: -2.1%?	max: 0.5%?
hyper-opt
	avg: 1.2%	min: 0.5%	max: 2.1%
ripgrep-debug
	avg: 1.7%	min: 1.2%	max: 2.0%
futures-debug
	avg: 1.1%	min: 0.4%	max: 2.0%
crates.io-opt
	avg: 1.2%	min: 0.5%	max: 1.9%
html5ever-opt
	avg: 0.6%	min: -0.1%	max: 1.8%
sentry-cli-debug
	avg: 1.2%	min: 0.8%	max: 1.8%
clap-rs-check
	avg: 1.0%	min: 0.6%	max: 1.7%
deeply-nested-check
	avg: 1.2%	min: 0.0%	max: 1.7%
piston-image-opt
	avg: 1.2%	min: 1.0%	max: 1.7%
serde-debug
	avg: 1.1%	min: 0.4%	max: 1.7%
serde-check
	avg: 1.2%	min: 0.2%	max: 1.6%
serde-opt
	avg: 1.0%	min: 0.3%	max: 1.6%
encoding-opt
	avg: 1.0%	min: 0.3%	max: 1.6%

@japaric: can you investigate? Here are docs on benchmarking and profiling. Cachegrind can be particularly useful for examining the difference between two compiler versions.

@nnethercote

This comment has been minimized.

Copy link
Contributor

nnethercote commented Sep 25, 2018

On second thought, this regression is bad enough that I think we should consider backing the changes out.

@nnethercote

This comment has been minimized.

Copy link
Contributor

nnethercote commented Sep 25, 2018

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented Sep 25, 2018

I support backing this change out to investigate performance losses.

@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Sep 25, 2018

Fine for me. I assume the regression comes from one of the places where mem::uninitialized was replaced by MaybeUninit, so we could then land the new union separately from the part which starts to make use of it in the compiler.

RalfJung added a commit to RalfJung/rust that referenced this pull request Sep 25, 2018

Revert "Auto merge of rust-lang#53508 - japaric:maybe-uninit, r=RalfJ…
…ung"

This reverts commit c6e3d7f, reversing
changes made to 4591a24.
@RalfJung

This comment has been minimized.

Copy link
Member

RalfJung commented Sep 25, 2018

Revert submitted as #54554

RalfJung added a commit to RalfJung/rust that referenced this pull request Sep 29, 2018

Revert "Auto merge of rust-lang#53508 - japaric:maybe-uninit, r=RalfJ…
…ung"

This reverts commit c6e3d7f, reversing
changes made to 4591a24.

bors added a commit that referenced this pull request Sep 29, 2018

Auto merge of #54554 - RalfJung:maybe-uninit, r=nagisa
Revert most of MaybeUninit, except for the new API itself

This reverts most of #53508 for perf reasons (first commit reverts that entire PR), except for the new API itself (added back in 2nd commit).

bors added a commit that referenced this pull request Sep 29, 2018

Auto merge of #54667 - RalfJung:maybe-uninit, r=<try>
Panic when using mem::uninitialized or mem::zeroed on an uninhabited type

All code by @japaric. This re-submits one half of #53508. This is likely not the one that introduced the perf regression, but just to be sure I'll do a perf run anyway.

bors added a commit that referenced this pull request Sep 29, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit

This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Sep 29, 2018

Auto merge of #54667 - RalfJung:maybe-uninit, r=<try>
Panic when using mem::uninitialized or mem::zeroed on an uninhabited type

All code by @japaric. This re-submits one half of #53508. This is likely not the one that introduced the perf regression, but just to be sure I'll do a perf run anyway.

bors added a commit that referenced this pull request Oct 1, 2018

Auto merge of #54667 - RalfJung:maybe-uninit, r=oli-obk
Panic when using mem::uninitialized or mem::zeroed on an uninhabited type

All code by @japaric. This re-submits one half of #53508. This is likely not the one that introduced the perf regression, but just to be sure I'll do a perf run anyway.

bors added a commit that referenced this pull request Oct 1, 2018

Auto merge of #54667 - RalfJung:maybe-uninit, r=pnkfelix
Panic when using mem::uninitialized or mem::zeroed on an uninhabited type

All code by @japaric. This re-submits one half of #53508. This is likely not the one that introduced the perf regression, but just to be sure I'll do a perf run anyway.

bors added a commit that referenced this pull request Oct 8, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Oct 9, 2018

Auto merge of #54924 - RalfJung:use-maybe-uninit2, r=<try>
Use MaybeUninit in liballoc

All code by @japaric. This is a re-submission of a part of #53508 that hopefully does not regress performance.

bors added a commit that referenced this pull request Oct 10, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Oct 12, 2018

Auto merge of #54924 - RalfJung:use-maybe-uninit2, r=cramertj
Use MaybeUninit in liballoc

All code by @japaric. This is a re-submission of a part of #53508 that hopefully does not regress performance.

bors added a commit that referenced this pull request Nov 19, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Nov 20, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Nov 20, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Nov 20, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Nov 21, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=<try>
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.

bors added a commit that referenced this pull request Nov 26, 2018

Auto merge of #54668 - RalfJung:use-maybe-uninit, r=SimonSapin
Use MaybeUninit in libcore

All code by @japaric. This re-submits the second half of #53508 (the first half is at #54667). This is likely the one containing the perf regression.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.