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

Fix SGX RWLock representation for UnsafeCell niche fix #1

Conversation

jethrogb
Copy link

@jethrogb jethrogb commented Jan 31, 2020

Also pulls in fortanix/llvm-project#8

@jethrogb
Copy link
Author

cc @Goirad @mzohreva @parthsane

@@ -239,7 +241,7 @@ mod tests {
zero_stack();
let mut init = MaybeUninit::<RWLock>::zeroed();
rwlock_new(&mut init);
assert_eq!(mem::transmute::<_, [u8; 128]>(init.assume_init()).as_slice(), RWLOCK_INIT)
assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT)
Copy link

@eddyb eddyb Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand this test, and it's "zero the stack" thing - if some bytes are uninitialized, the comparison is UB, and there's no real way around that (without the proposed LLVM freeze operation), AFAIK.

And MaybeUninit::<RWLock>::zeroed() has the same semantics as [0u8; 144], doesn't it? So there's no way any bytes wouldn't be zeroed.

I know this is offtopic, but I'm a bit worried this test (and perhaps more like it?) isn't actually testing what it's supposed to (cc @RalfJung)

Copy link
Author

@jethrogb jethrogb Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand this test, and it's "zero the stack" thing

transmute::<_, RWLock>(*RWLOCK_INIT) needs to be equivalent to RWLock::new(). This test tries to assert that. Since part of the representation of RWLock::new() may contain uninitialized memory, some trickery (and UB) is needed, but this (trying very hard to get the uninitialized memory to be 0) is the best we can do.

if some bytes are uninitialized, the comparison is UB, and there's no real way around that (without the proposed LLVM freeze operation), AFAIK.

Yes, this is exactly what the comment just above this code block tries to explain (“issue with the test code”). However, this test has been working fine and this is the best we can do (I think? Happy to hear alternatives!). If changes to codegen are made that make this test fail, we can consider other options at that time. Note that UB only occurs during the execution of this test, normal use of this primitive never uses uninitialized memory.

And MaybeUninit::::zeroed() has the same semantics as [0u8; 144], doesn't it? So there's no way any bytes wouldn't be zeroed.

I'm not sure what you mean by this. Where are we using [0u8; 144]?

Copy link

@RalfJung RalfJung Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And MaybeUninit::::zeroed() has the same semantics as [0u8; 144], doesn't it?

It's not; the former resets any padding to Undef as happens any time a struct is copied.

Note that UB only occurs during the execution of this test, normal use of this primitive never uses uninitialized memory.

If the test deliberately causes UB, it should have a comment saying that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not; the former resets any padding to Undef as happens any time a struct is copied.

Oh right I forgot about that (sadly we don't tell LLVM about this, since we just use a plain memcpy).

Wouldn't that also imply that it's impossible for RWLock::new() to guarantee the padding bytes of RWLock are initialized to 0, which this tests tries to prove (and arguably fails because its comparison of undef bytes is UB)?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't that also imply that it's impossible for RWLock::new() to guarantee the padding bytes of RWLock are initialized to 0

Yes. (I am not sure if RwLock has any padding bytes, though.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to test for "no padding bytes", I wonder if this test should rely on const-eval instead, e.g. transmuting to [u8; 144] in a const, in a way that would cause an error if any of the bytes were undef.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jethrogb is it crucial that RwLock::new() returns something all-0, or is it just crucial that using something all-0 instead of RwLock::new() must be fine? If the answer is the latter, when padding wouldn't actually be a problem (except for the test).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay turns out I was very misled by the "try hard to make sure" comment - it doesn't describe what is being tested, but specifically the zero_stack() call.

What this test appears to be checking is that the hardcoded bytes in RWLOCK_INIT (which presumably are also hardcoded on the C side) are the same as RWLock::new() ignoring padding.

But there's no way to automatically ignore padding, so what's being done here is trying to zero the stack space where RWLock::new() (and all of its transitive callers) writes every part of the RWLock, so that the padding likely stays zeroed.

I'm less worried about the test, but the comment could probably be improved to make it clearer that RWLock::new() having padding left uninitialized is not an issue, it just makes testing the initialized bytes harder.

I think the simplest way to get zeroed data (although I don't know how UB it is) is to use a static, e.g.: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3abaa186579b5522baad9f492a784087 (that works even on stable, heh).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it crucial that RwLock::new() returns something all-0, or is it just crucial that using something all-0 instead of RwLock::new() must be fine?

The latter

the comment could probably be improved

@eddyb I think you and @RalfJung have a pretty good idea of what I'm trying to achieve here, and you also have a better understanding of undef than I have, would you mind drafting a comment that makes sense to you?

I think the simplest way to get zeroed data (although I don't know how UB it is) is to use a static

Neat, I think this is a pretty good way.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind drafting a comment that makes sense to you?

Well, if the static works, it's easier to explain that the undef parts will get zero-initialized in practice.

To be honest, one of the most confusing things to me was that zero_stack(); didn't have an empty line after it, which made me assume incorrectly what the comment referred to (if I remove the zero_stack() call, the test fails, and I think when I saw that I understood what the comment meant).

A static should be clearer from the start compared to zeroing the stack in an unguaranteed way.

@pnkfelix pnkfelix merged this pull request into pnkfelix:hide-niches-under-unsafe-cell Feb 3, 2020
pnkfelix pushed a commit that referenced this pull request Jun 3, 2020
…ing opaque return type

Go from

```
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> file8.rs:22:5
   |
22 | /     move || {
23 | |         *dest = g.get();
24 | |     }
   | |_____^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 18:1...
  --> file8.rs:18:1
   |
18 | / fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
19 | | where
20 | |     G: Get<T>
21 | | {
...  |
24 | |     }
25 | | }
   | |_^
note: ...so that the types are compatible
  --> file8.rs:22:5
   |
22 | /     move || { //~ ERROR cannot infer an appropriate lifetime
23 | |         *dest = g.get();
24 | |     }
   | |_____^
   = note: expected  `&mut T`
              found  `&mut T`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 18:8...
  --> file8.rs:18:8
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |        ^^
note: ...so that return value is valid for the call
  --> file8.rs:18:45
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |                                             ^^^^^^^^^^^^^^^^^^^^^^^
```

to

```
error[E0621]: explicit lifetime required in the type of `dest`
  --> file8.rs:18:45
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |                                  ------     ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
   |                                  |
   |                                  help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
   ```
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 14, 2020
…ark-Simulacrum

Improve SGX RWLock initializer test

r? `@eddyb`

This addresses pnkfelix#1 (comment)

Fixes fortanix/rust-sgx#213
pnkfelix pushed a commit that referenced this pull request Feb 19, 2021
HWAddressSanitizer support

#  Motivation
Compared to regular ASan, HWASan has a [smaller overhead](https://source.android.com/devices/tech/debug/hwasan). The difference in practice is that HWASan'ed code is more usable, e.g. Android device compiled with HWASan can be used as a daily driver.

# Example
```
fn main() {
    let xs = vec![0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
```
```
==223==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdeffff0050 at pc 0xaaaad00b3468
READ of size 4 at 0xefdeffff0050 tags: e5/00 (ptr/mem) in thread T0
    #0 0xaaaad00b3464  (/root/main+0x53464)
    #1 0xaaaad00b39b4  (/root/main+0x539b4)
    #2 0xaaaad00b3dd0  (/root/main+0x53dd0)
    rust-lang#3 0xaaaad00b61dc  (/root/main+0x561dc)
    rust-lang#4 0xaaaad00c0574  (/root/main+0x60574)
    rust-lang#5 0xaaaad00b6290  (/root/main+0x56290)
    rust-lang#6 0xaaaad00b6170  (/root/main+0x56170)
    rust-lang#7 0xaaaad00b3578  (/root/main+0x53578)
    rust-lang#8 0xffff81345e70  (/lib64/libc.so.6+0x20e70)
    rust-lang#9 0xaaaad0096310  (/root/main+0x36310)

[0xefdeffff0040,0xefdeffff0060) is a small allocated heap chunk; size: 32 offset: 16
0xefdeffff0050 is located 0 bytes to the right of 16-byte region [0xefdeffff0040,0xefdeffff0050)
allocated here:
    #0 0xaaaad009bcdc  (/root/main+0x3bcdc)
    #1 0xaaaad00b1eb0  (/root/main+0x51eb0)
    #2 0xaaaad00b20d4  (/root/main+0x520d4)
    rust-lang#3 0xaaaad00b2800  (/root/main+0x52800)
    rust-lang#4 0xaaaad00b1cf4  (/root/main+0x51cf4)
    rust-lang#5 0xaaaad00b33d4  (/root/main+0x533d4)
    rust-lang#6 0xaaaad00b39b4  (/root/main+0x539b4)
    rust-lang#7 0xaaaad00b61dc  (/root/main+0x561dc)
    rust-lang#8 0xaaaad00b3578  (/root/main+0x53578)
    rust-lang#9 0xaaaad0096310  (/root/main+0x36310)

Thread: T0 0xeffe00002000 stack: [0xffffc0590000,0xffffc0d90000) sz: 8388608 tls: [0xffff81521020,0xffff815217d0)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0xfefcefffef80: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffef90: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefa0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefb0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefc0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefd0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffefe0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefcefffeff0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
=>0xfefceffff000: a2  a2  05  00  e5 [00] 00  00  00  00  00  00  00  00  00  00
  0xfefceffff010: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff020: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff030: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff040: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff050: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff060: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff070: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0xfefceffff080: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0xfefcefffeff0: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0xfefceffff000: ..  ..  c5  ..  .. [..] ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
  0xfefceffff010: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
Registers where the failure occurred (pc 0xaaaad00b3468):
    x0  e500efdeffff0050  x1  0000000000000004  x2  0000ffffc0d8f5a0  x3  0200efff00000000
    x4  0000ffffc0d8f4c0  x5  000000000000004f  x6  00000ffffc0d8f36  x7  0000efff00000000
    x8  e500efdeffff0050  x9  0200efff00000000  x10 0000000000000000  x11 0200efff00000000
    x12 0200effe000006b0  x13 0200effe000006b0  x14 0000000000000008  x15 00000000c00000cf
    x16 0000aaaad00a0afc  x17 0000000000000003  x18 0000000000000001  x19 0000ffffc0d8f718
    x20 ba00ffffc0d8f7a0  x21 0000aaaad00962e0  x22 0000000000000000  x23 0000000000000000
    x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
    x28 0000000000000000  x29 0000ffffc0d8f650  x30 0000aaaad00b3468
```

# Comments/Caveats
* HWASan is only supported on arm64.
* I'm not sure if I should add a feature gate or piggyback on the existing one for sanitizers.
* HWASan requires `-C target-feature=+tagged-globals`. That flag should probably be set transparently to the user. Not sure how to go about that.

# TODO
* Need more tests.
* Update documentation.
* Fix symbolization.
* Integrate with CI
pnkfelix pushed a commit that referenced this pull request Mar 15, 2021
bypass auto_da_alloc for metadata files

This saves about 0.7% when rerunning the UI test suite. I.e. when the metadata files exist and will be overwritten. No improvements expected for a clean build. So it might show up in incr-patched perf results.
```
regular rename:

Benchmark #1: touch src/tools/compiletest/src/main.rs ; RUSTC_WRAPPER="" schedtool -B -e ./x.py test src/test/ui
  Time (mean ± σ):     47.305 s ±  0.170 s    [User: 1631.540 s, System: 412.648 s]
  Range (min … max):   47.125 s … 47.856 s    20 runs

non-durable rename:

Benchmark #1: touch src/tools/compiletest/src/main.rs ; RUSTC_WRAPPER="" schedtool -B -e ./x.py test src/test/ui
  Time (mean ± σ):     46.930 s ±  0.064 s    [User: 1634.344 s, System: 396.038 s]
  Range (min … max):   46.759 s … 47.043 s    20 runs
```

There are more places that trigger auto_da_alloc behavior by overwriting existing files with O_TRUNC, but those are much harder to locate because `O_TRUNC` is set on `open()` but the writeback is triggered on `close()`. The latter is the part which shows up in profiles.
pnkfelix pushed a commit that referenced this pull request May 11, 2021
…nt, r=Mark-Simulacrum

Show nicer error when an 'unstable fingerprints' error occurs

An example of the error produced by this PR:

```
error: internal compiler error: encountered incremental compilation error with evaluate_obligation(9f2ad55260c30262-c36667639674ad83)
  |
  = help: This is a known issue with the compiler. Run `cargo clean -p syn` or `cargo clean` to allow your project to compile
  = note: Please follow the instructions below to create a bug report with the provided information

thread 'rustc' panicked at 'Found unstable fingerprints for evaluate_obligation(9f2ad55260c30262-c36667639674ad83): Ok(EvaluatedToOk)', /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:595:9
stack backtrace:
   0: rust_begin_unwind
             at /home/aaron/repos/rust/library/std/src/panicking.rs:493:5
   1: std::panicking::begin_panic_fmt
             at /home/aaron/repos/rust/library/std/src/panicking.rs:435:5
   2: rustc_query_system::query::plumbing::incremental_verify_ich
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:595:9
   3: rustc_query_system::query::plumbing::load_from_disk_and_cache_in_memory
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:557:9
   4: rustc_query_system::query::plumbing::try_execute_query::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:473:21
   5: core::option::Option<T>::map
             at /home/aaron/repos/rust/library/core/src/option.rs:487:29
   6: rustc_query_system::query::plumbing::try_execute_query::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:471:13
   7: stacker::maybe_grow
             at /home/aaron/.cargo/registry/src/github.com-1ecc6299db9ec823/stacker-0.1.12/src/lib.rs:55:9
   8: rustc_data_structures::stack::ensure_sufficient_stack
             at /home/aaron/repos/rust/compiler/rustc_data_structures/src/stack.rs:16:5
   9: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:169:17
  10: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:50
  11: rustc_middle::ty::context::tls::set_tlv
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1720:9
  12: rustc_middle::ty::context::tls::enter_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:9
  13: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:168:13
  14: rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1780:13
  15: rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:40
  16: rustc_middle::ty::context::tls::with_context_opt
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1753:22
  17: rustc_middle::ty::context::tls::with_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:9
  18: rustc_middle::ty::context::tls::with_related_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1777:9
  19: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:157:9
  20: rustc_query_system::query::plumbing::try_execute_query
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:469:22
  21: rustc_query_system::query::plumbing::get_query_impl
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:674:5
  22: rustc_query_system::query::plumbing::get_query
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:785:9
  23: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::evaluate_obligation
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:603:17
  24: rustc_middle::ty::query::TyCtxtAt::evaluate_obligation
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/query/mod.rs:204:17
  25: rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::evaluate_obligation
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/query/mod.rs:185:17
  26: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt>::evaluate_obligation
             at /home/aaron/repos/rust/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:72:9
  27: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt>::evaluate_obligation_no_overflow
             at /home/aaron/repos/rust/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:82:15
  28: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt>::predicate_must_hold_modulo_regions
             at /home/aaron/repos/rust/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:58:9
  29: rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions
             at /home/aaron/repos/rust/compiler/rustc_trait_selection/src/traits/mod.rs:146:18
  30: rustc_ty_utils::common_traits::is_item_raw::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_ty_utils/src/common_traits.rs:33:9
  31: rustc_infer::infer::InferCtxtBuilder::enter
             at /home/aaron/repos/rust/compiler/rustc_infer/src/infer/mod.rs:582:9
  32: rustc_ty_utils::common_traits::is_item_raw
             at /home/aaron/repos/rust/compiler/rustc_ty_utils/src/common_traits.rs:32:5
  33: rustc_query_system::query::config::QueryVtable<CTX,K,V>::compute
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/config.rs:44:9
  34: rustc_query_system::query::plumbing::load_from_disk_and_cache_in_memory::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:544:67
  35: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:77:46
  36: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:50
  37: rustc_middle::ty::context::tls::set_tlv
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1720:9
  38: rustc_middle::ty::context::tls::enter_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:9
  39: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:77:13
  40: rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:40
  41: rustc_middle::ty::context::tls::with_context_opt
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1753:22
  42: rustc_middle::ty::context::tls::with_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:9
  43: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:74:9
  44: rustc_query_system::dep_graph::graph::DepGraph<K>::with_ignore
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:167:9
  45: rustc_query_system::query::plumbing::load_from_disk_and_cache_in_memory
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:544:22
  46: rustc_query_system::query::plumbing::try_execute_query::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:473:21
  47: core::option::Option<T>::map
             at /home/aaron/repos/rust/library/core/src/option.rs:487:29
  48: rustc_query_system::query::plumbing::try_execute_query::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:471:13
  49: stacker::maybe_grow
             at /home/aaron/.cargo/registry/src/github.com-1ecc6299db9ec823/stacker-0.1.12/src/lib.rs:55:9
  50: rustc_data_structures::stack::ensure_sufficient_stack
             at /home/aaron/repos/rust/compiler/rustc_data_structures/src/stack.rs:16:5
  51: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:169:17
  52: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:50
  53: rustc_middle::ty::context::tls::set_tlv
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1720:9
  54: rustc_middle::ty::context::tls::enter_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:9
  55: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:168:13
  56: rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1780:13
  57: rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:40
  58: rustc_middle::ty::context::tls::with_context_opt
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1753:22
  59: rustc_middle::ty::context::tls::with_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:9
  60: rustc_middle::ty::context::tls::with_related_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1777:9
  61: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::start_query
             at /home/aaron/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:157:9
  62: rustc_query_system::query::plumbing::try_execute_query
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:469:22
  63: rustc_query_system::query::plumbing::get_query_impl
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:674:5
  64: rustc_query_system::query::plumbing::get_query
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/query/plumbing.rs:785:9
  65: rustc_middle::ty::query::TyCtxtAt::is_unpin_raw
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/query/mod.rs:204:17
  66: rustc_middle::ty::util::<impl rustc_middle::ty::TyS>::is_unpin
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/util.rs:727:38
  67: rustc_middle::ty::layout::<impl rustc_target::abi::TyAndLayoutMethods<C> for &rustc_middle::ty::TyS>::pointee_info_at
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2341:32
  68: rustc_target::abi::TyAndLayout<Ty>::pointee_info_at
             at /home/aaron/repos/rust/compiler/rustc_target/src/abi/mod.rs:1164:9
  69: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::new_internal::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2781:36
  70: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::new_internal::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2840:17
  71: rustc_target::abi::call::ArgAbi<Ty>::new
             at /home/aaron/repos/rust/compiler/rustc_target/src/abi/call/mod.rs:457:53
  72: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::new_internal::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2838:27
  73: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::new_internal::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2870:32
  74: core::iter::adapters::map::map_fold::{{closure}}
             at /home/aaron/repos/rust/library/core/src/iter/adapters/map.rs:82:28
  75: <core::iter::adapters::enumerate::Enumerate<I> as core::iter::traits::iterator::Iterator>::fold::enumerate::{{closure}}
             at /home/aaron/repos/rust/library/core/src/iter/adapters/enumerate.rs:104:27
  76: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /home/aaron/repos/rust/library/core/src/ops/function.rs:269:13
  77: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /home/aaron/repos/rust/library/core/src/ops/function.rs:269:13
  78: core::iter::adapters::map::map_fold::{{closure}}
             at /home/aaron/repos/rust/library/core/src/iter/adapters/map.rs:82:21
  79: core::iter::traits::iterator::Iterator::fold
             at /home/aaron/repos/rust/library/core/src/iter/traits/iterator.rs:2146:21
  80: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/map.rs:122:9
  81: <core::iter::adapters::cloned::Cloned<I> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/cloned.rs:58:9
  82: <core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/chain.rs:119:19
  83: <core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/chain.rs:119:19
  84: <core::iter::adapters::enumerate::Enumerate<I> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/enumerate.rs:110:9
  85: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /home/aaron/repos/rust/library/core/src/iter/adapters/map.rs:122:9
  86: core::iter::traits::iterator::Iterator::for_each
             at /home/aaron/repos/rust/library/core/src/iter/traits/iterator.rs:776:9
  87: <alloc::vec::Vec<T,A> as alloc::vec::spec_extend::SpecExtend<T,I>>::spec_extend
             at /home/aaron/repos/rust/library/alloc/src/vec/spec_extend.rs:40:17
  88: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
             at /home/aaron/repos/rust/library/alloc/src/vec/spec_from_iter_nested.rs:56:9
  89: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
             at /home/aaron/repos/rust/library/alloc/src/vec/spec_from_iter.rs:36:9
  90: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /home/aaron/repos/rust/library/alloc/src/vec/mod.rs:2448:9
  91: core::iter::traits::iterator::Iterator::collect
             at /home/aaron/repos/rust/library/core/src/iter/traits/iterator.rs:1788:9
  92: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::new_internal
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2864:19
  93: <rustc_target::abi::call::FnAbi<&rustc_middle::ty::TyS> as rustc_middle::ty::layout::FnAbiExt<C>>::of_instance
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/layout.rs:2670:9
  94: rustc_codegen_llvm::mono_item::<impl rustc_codegen_ssa::traits::declare::PreDefineMethods for rustc_codegen_llvm::context::CodegenCx>::predefine_fn
             at /home/aaron/repos/rust/compiler/rustc_codegen_llvm/src/mono_item.rs:57:22
  95: <rustc_middle::mir::mono::MonoItem as rustc_codegen_ssa::mono_item::MonoItemExt>::predefine
             at /home/aaron/repos/rust/compiler/rustc_codegen_ssa/src/mono_item.rs:76:17
  96: rustc_codegen_llvm::base::compile_codegen_unit::module_codegen
             at /home/aaron/repos/rust/compiler/rustc_codegen_llvm/src/base.rs:122:17
  97: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:235:62
  98: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:77:46
  99: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:50
 100: rustc_middle::ty::context::tls::set_tlv
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1720:9
 101: rustc_middle::ty::context::tls::enter_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:9
 102: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:77:13
 103: rustc_middle::ty::context::tls::with_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:40
 104: rustc_middle::ty::context::tls::with_context_opt
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1753:22
 105: rustc_middle::ty::context::tls::with_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1764:9
 106: rustc_middle::dep_graph::<impl rustc_query_system::dep_graph::DepKind for rustc_middle::dep_graph::dep_node::DepKind>::with_deps
             at /home/aaron/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:74:9
 107: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:235:26
 108: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
             at /home/aaron/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:205:9
 109: rustc_codegen_llvm::base::compile_codegen_unit
             at /home/aaron/repos/rust/compiler/rustc_codegen_llvm/src/base.rs:103:9
 110: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::ExtraBackendMethods>::compile_codegen_unit
             at /home/aaron/repos/rust/compiler/rustc_codegen_llvm/src/lib.rs:109:9
 111: rustc_codegen_ssa::base::codegen_crate
             at /home/aaron/repos/rust/compiler/rustc_codegen_ssa/src/base.rs:655:38
 112: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
             at /home/aaron/repos/rust/compiler/rustc_codegen_llvm/src/lib.rs:270:18
 113: rustc_interface::passes::start_codegen::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/passes.rs:1021:9
 114: rustc_data_structures::profiling::VerboseTimingGuard::run
             at /home/aaron/repos/rust/compiler/rustc_data_structures/src/profiling.rs:573:9
 115: rustc_session::utils::<impl rustc_session::session::Session>::time
             at /home/aaron/repos/rust/compiler/rustc_session/src/utils.rs:16:9
 116: rustc_interface::passes::start_codegen
             at /home/aaron/repos/rust/compiler/rustc_interface/src/passes.rs:1020:19
 117: rustc_interface::queries::Queries::ongoing_codegen::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/queries.rs:296:20
 118: rustc_interface::passes::QueryContext::enter::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/passes.rs:755:42
 119: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:50
 120: rustc_middle::ty::context::tls::set_tlv
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1720:9
 121: rustc_middle::ty::context::tls::enter_context
             at /home/aaron/repos/rust/compiler/rustc_middle/src/ty/context.rs:1736:9
 122: rustc_interface::passes::QueryContext::enter
             at /home/aaron/repos/rust/compiler/rustc_interface/src/passes.rs:755:9
 123: rustc_interface::queries::Queries::ongoing_codegen::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/queries.rs:287:13
 124: rustc_interface::queries::Query<T>::compute
             at /home/aaron/repos/rust/compiler/rustc_interface/src/queries.rs:40:28
 125: rustc_interface::queries::Queries::ongoing_codegen
             at /home/aaron/repos/rust/compiler/rustc_interface/src/queries.rs:285:9
 126: rustc_driver::run_compiler::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_driver/src/lib.rs:442:13
 127: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
             at /home/aaron/repos/rust/compiler/rustc_interface/src/queries.rs:428:19
 128: rustc_driver::run_compiler::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_driver/src/lib.rs:337:22
 129: rustc_interface::interface::create_compiler_and_run::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/interface.rs:208:13
 130: rustc_span::with_source_map
             at /home/aaron/repos/rust/compiler/rustc_span/src/lib.rs:788:5
 131: rustc_interface::interface::create_compiler_and_run
             at /home/aaron/repos/rust/compiler/rustc_interface/src/interface.rs:202:5
 132: rustc_interface::interface::run_compiler::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/interface.rs:224:12
 133: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/util.rs:155:13
 134: scoped_tls::ScopedKey<T>::set
             at /home/aaron/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137:9
 135: rustc_span::with_session_globals
             at /home/aaron/repos/rust/compiler/rustc_span/src/lib.rs:105:5
 136: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/util.rs:153:9
 137: rustc_interface::util::scoped_thread::{{closure}}
             at /home/aaron/repos/rust/compiler/rustc_interface/src/util.rs:128:24
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.54.0-dev running on x86_64-unknown-linux-gnu

note: compiler flags: -C opt-level=3 -C embed-bitcode=no -C incremental --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `quote::Tokens: std::marker::Unpin`
#1 [is_unpin_raw] computing whether `quote::Tokens` is `Unpin`
end of query stack
error: aborting due to previous error

error: could not compile `syn`

To learn more, run the command again with --verbose.
```

I've left in the panic and ICE following the pretty error, so that we still have all of the debug information available in a bug report.

This message can be reproduced by cloning the repository `https://github.com/Aaron1011/syn-crash`, and running the following shell script (with a `rustup override` set in the directory):

```
set -xe
cargo clean -p syn
cargo clean --release -p syn

git checkout minimize
cargo build --release -j 1

git checkout minimize-change
cargo build --release -j 1
```

r? ``@Mark-Simulacrum``
pnkfelix pushed a commit that referenced this pull request Sep 9, 2021
Otherwise, we can get into a situation where you have
a subtype obligation `#1 <: #2` pending, #1 is constrained
by `check_casts`, but #2` is unaffected.

Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
pnkfelix pushed a commit that referenced this pull request Jan 31, 2023
…u-se

Implement `SpecOptionPartialEq` for `cmp::Ordering`

Noticed as I continue to explore options for having code using `partial_cmp` optimize better.

Before:
```llvm
; Function Attrs: mustprogress nofree nosync nounwind willreturn uwtable
define noundef zeroext i1 `@ordering_eq(i8` noundef %0, i8 noundef %1) unnamed_addr #0 {
start:
  %2 = icmp eq i8 %0, 2
  br i1 %2, label %bb1.i, label %bb3.i

bb1.i:                                            ; preds = %start
  %3 = icmp eq i8 %1, 2
  br label %"_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit"

bb3.i:                                            ; preds = %start
  %.not.i = icmp ne i8 %1, 2
  %4 = icmp eq i8 %0, %1
  %spec.select.i = and i1 %.not.i, %4
  br label %"_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit"

"_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit": ; preds = %bb1.i, %bb3.i
  %.0.i = phi i1 [ %3, %bb1.i ], [ %spec.select.i, %bb3.i ]
  ret i1 %.0.i
}
```

After:
```llvm
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable
define noundef zeroext i1 `@ordering_eq(i8` noundef %0, i8 noundef %1) unnamed_addr #1 {
start:
  %2 = icmp eq i8 %0, %1
  ret i1 %2
}
```

(Which <https://alive2.llvm.org/ce/z/-rop5r> says LLVM *could* just do itself, but there's probably an issue already open for that problem from when this was originally looked at for `Option<NonZeroU8>` and friends.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants