rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.5k stars 12.74k forks source link

ICE "anonymous bound region BrAnon(0) in return but not args" #43567

Closed SimonSapin closed 7 years ago

SimonSapin commented 7 years ago

rustc 1.21.0-nightly (aac223f4f 2017-07-30) ICEs on https://github.com/rtbo/rust-xcb (full output below), although 1.20.0-beta.1 and some not-much-older nightlies succeed.

Some more context around the line in the error message:

#[repr(C)]
pub struct xcb_depth_iterator_t<'a> {
    pub data:  *mut xcb_depth_t,
    pub rem:   c_int,
    pub index: c_int,
    _phantom:  std::marker::PhantomData<&'a xcb_depth_t>,
}
// […]
#[link(name="xcb")]
extern {
// […]
    pub fn xcb_screen_allowed_depths_iterator (R: *const xcb_screen_t)
            -> xcb_depth_iterator_t;

So the xcb_depth_iterator_t does have lifetime parameter that’s elided in this function declaration’s return type without any elided lifetime in the parameters. Maybe this code should indeed be rejected, but in that case we need a proper error message rather than a compiler panic. Although it used to be accepted, so this is a breaking change. Adding an explicit lifetime parameter to the function fixes this, but that’s not easy to do properly since this is generated code.

Full output:

% RUST_BACKTRACE=1 cargo +nightly build -v
       Fresh log v0.3.8
       Fresh libc v0.2.28
   Compiling xcb v0.8.0 (file:///home/simon/projects/rust-xcb)
     Running `rustc --crate-name xcb src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=f22742bf239db509 -C extra-filename=-f22742bf239db509 --out-dir /home/simon/projects/rust-xcb/target/debug/deps -L dependency=/home/simon/projects/rust-xcb/target/debug/deps --extern log=/home/simon/projects/rust-xcb/target/debug/deps/liblog-2b956ee286098ab8.rlib --extern libc=/home/simon/projects/rust-xcb/target/debug/deps/liblibc-c727996240879c34.rlib`
error: internal compiler error: /checkout/src/librustc_typeck/astconv.rs:1267: anonymous bound region BrAnon(0) in return but not args
    --> src/ffi/xproto.rs:5654:16
     |
5654 |             -> xcb_depth_iterator_t;
     |                ^^^^^^^^^^^^^^^^^^^^

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.21.0-nightly (aac223f4f 2017-07-30) running on x86_64-unknown-linux-gnu

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:438:8
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:60
             at /checkout/src/libstd/panicking.rs:380
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:390
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:610
   5: std::panicking::begin_panic
   6: rustc_errors::Handler::span_bug
   7: rustc::session::opt_span_bug_fmt::{{closure}}
   8: rustc::session::span_bug_fmt
   9: <rustc_typeck::astconv::AstConv<'gcx, 'tcx> + 'o>::ty_of_fn
  10: rustc_typeck::collect::fn_sig
  11: rustc::dep_graph::graph::DepGraph::with_task
  12: rustc::ty::maps::<impl rustc::ty::maps::queries::fn_sig<'tcx>>::try_get
  13: rustc::ty::maps::TyCtxtAt::fn_sig
  14: rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::fn_sig
  15: <rustc_typeck::collect::CollectItemTypesVisitor<'a, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_item
  16: rustc_typeck::check_crate::{{closure}}::{{closure}}
  17: rustc_typeck::check_crate
  18: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  19: rustc_driver::driver::phase_3_run_analysis_passes
  20: rustc_driver::driver::compile_input
  21: rustc_driver::run_compiler

error: Could not compile `xcb`.

Caused by:
  process didn't exit successfully: `rustc --crate-name xcb src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=f22742bf239db509 -C extra-filename=-f22742bf239db509 --out-dir /home/simon/projects/rust-xcb/target/debug/deps -L dependency=/home/simon/projects/rust-xcb/target/debug/deps --extern log=/home/simon/projects/rust-xcb/target/debug/deps/liblog-2b956ee286098ab8.rlib --extern libc=/home/simon/projects/rust-xcb/target/debug/deps/liblibc-c727996240879c34.rlib` (exit code: 101)
petrochenkov commented 7 years ago

Must be a regression from https://github.com/rust-lang/rust/pull/43543

Looks like https://github.com/rust-lang/rust/issues/32330 wasn't fixed in foreign functions :( I'll prepare a patch.

SimonSapin commented 7 years ago

@petrochenkov Do you mean a patch that would make xcb compile, or produce a better error message?

petrochenkov commented 7 years ago

@SimonSapin Don't know yet, need to look closer. A proper fix may require a warning, deprecation period, etc, but immediate fix for the ICE making xcb compile can always be done by partially reverting https://github.com/rust-lang/rust/pull/43543.

SimonSapin commented 7 years ago

Ok, thanks for looking into it.

Mark-Simulacrum commented 7 years ago

Performance collection for the style crate is also broken because of this.

eddyb commented 7 years ago

cc @nikomatsakis Should we add elision logic to foreign functions?

Manishearth commented 7 years ago

https://github.com/rust-lang/rust/issues/43594 has a simpler testcase that also involves elision.

Also, yes, I think elision should work on FFI. Firstly, it used to, and it's a breaking change otherwise.

Secondly, this is extremely useful when paired with bindgen to have a modicum of safety wrt returning non-owners pointers from FFI. Dereferenced raw pointers yield values of arbitrary lifetime, and guarding against this in FFI-heavy code is extremely tedious. In an FFI-heavy project the risk of introducing unsafety in the FFI layer can outweigh the risk of just writing it all in C++, largely due to things like this.

eddyb commented 7 years ago

@Manishearth Elision never worked, what you were getting was an unbound lifetime in the return.

eddyb commented 7 years ago

@Manishearth It was even you who reported #35851. I found two crates that would break so we didn't go through with adding elision to them.

Manishearth commented 7 years ago

Wait, what? I could swear we've had lifetime errors on this before. Or perhaps they were in nearby FFI wrappers. Hmm.

Manishearth commented 7 years ago

Oh, right, I didn't remember that was all elision.

Opt in would be okay by me too, really. Then again, we also need this on stable.

Can we add elision for the cases where there isn't a function returning a dangling lifetime (and deal with the backcompat hazard separately?). That seems like it can be done a without breaking anyone. As it stands this will break stylo, and it is super nontrivial to fix given the amount of FFI we do.

Manishearth commented 7 years ago

I can also try to fix those crates preemptively.

eddyb commented 7 years ago

If anyone wants to test with the no-elision-in-FFI hack turned off, change this match arm to => None.

SimonSapin commented 7 years ago

I think this is not a case of valid elision. If I add a non-FFI function with the same signature it fails to build with a proper error message because there is no implicit lifetime in the function’s parameters.

    pub fn xcb_screen_allowed_depths_iterator__ (R: *const xcb_screen_t)
            -> xcb_depth_iterator_t { unimplemented!() }
error[E0106]: missing lifetime specifier
 --> src/ffi/xproto.rs:8:16
  |
8 |             -> xcb_depth_iterator_t { unimplemented!() }
  |                ^^^^^^^^^^^^^^^^^^^^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
  = help: consider giving it an explicit bounded or 'static lifetime
Manishearth commented 7 years ago

FWIW the testcase in #43594 is a case of valid elision, even though it's invalid here.

Manishearth commented 7 years ago

Actually, it occurs to me that this bound region bug is going to happen anyway and break all of the crates rely on this anyway, so we should just enable elision for extern fns .. ?

Manishearth commented 7 years ago

PR to fix rust-xcb: https://github.com/rtbo/rust-xcb/pull/41

Manishearth commented 7 years ago

Fixed liquidfun-rust https://github.com/rjanicek/liquidfun-rust/pull/4

Might be worth a fresh crater run.

eddyb commented 7 years ago

cc @Mark-Simulacrum Cargobomb would be helpful.

Mark-Simulacrum commented 7 years ago

I don't have access to cargobomb myself, but @tomprince and @brson do, I believe. A patch would be useful either way.

kornelski commented 7 years ago

I've ran into the same error. Here's a minimal case:

extern "C" {
    fn ice(ice: &mut u32) -> &u32;
}

error: internal compiler error: src/librustc_typeck/astconv.rs:1267: anonymous bound region BrAnon(1) in return but not args

rustc 1.21.0-nightly (1d2a6df38 2017-08-03) running on x86_64-apple-darwin

emilio commented 7 years ago

This also happens on Stylo FWIW.

Manishearth commented 7 years ago

(we know, see #43594)

Manishearth commented 7 years ago

I've fixed up stylo so that the fix for this issue will play nice with it (and the fix for this issue should be in nightly now)

emilio commented 7 years ago

It panics on current master with ./mach cargo-geckolib build, so did you forget to update the bindings? Or is it another instance of the problem?

Manishearth commented 7 years ago

Compiles for me on latest nightly :)

main-- commented 7 years ago

Still failing here: https://travis-ci.org/main--/windows-gaming/jobs/262206955#L1731

SimonSapin commented 7 years ago

I’m also still seeing this failure with rustc 1.21.0-nightly (cbbe17aa7 2017-08-07) (same as @main--) on Servo. @Manishearth, which version did you use, and what did you test?

Manishearth commented 7 years ago

Oh, right, I used stable by accident. Oops.

Looks like it never landed on master, only try.

eddyb commented 7 years ago

@Manishearth I think @tomprince started the cargobomb run only today.

michaelwoerister commented 7 years ago

Discussed in the compiler team meeting. P-high.

petrochenkov commented 7 years ago

In the meantime, could someone fix these issues in xcb/stylo/etc by adding explicit lifetimes? If something ICEs with this message now, there's a good chance it will be an error sooner or later (maybe after deprecation period), so it will need to be fixed anyway.

Manishearth commented 7 years ago

It should be fixed in stylo.

I am unable to fix XCB, they use a pretty weird custom bindings generation setup that uses lifetimes but doesn't carry enough info around for those lifetimes to be used consistently. A maintainer of that crate will have to fix it; I'm just not familiar enough with this custom setup to deal with it.

SimonSapin commented 7 years ago

(~I think Stylo was not affected, only Servo.~ We worked around by forking xcb and modifying manually the generated code. Hopefully this is temporary until someone can figure out a proper fix in the code generation script.)

nox commented 7 years ago

This kind of bug is why mozilla-central should never use the system Rust, and always download its own that it knows will work.

petrochenkov commented 7 years ago

Fixed in https://github.com/rust-lang/rust/pull/43651

SimonSapin commented 7 years ago

Confirmed that Firefox compiles on Rust Nightly, with #43651. Thanks!