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

Rustc bug:cannot convert ReEmpty to a region vid #68550

Closed
lispc opened this issue Jan 26, 2020 · 4 comments · Fixed by #70950
Closed

Rustc bug:cannot convert ReEmpty to a region vid #68550

lispc opened this issue Jan 26, 2020 · 4 comments · Fixed by #70950
Assignees
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@lispc
Copy link

lispc commented Jan 26, 2020

When compiling my code, I saw cargo/rustc panicked.

I tried this code:

pub struct Data<A> {
    pub a: A,
}

impl<A> Data<A>
where
    A: 'static,
    &'static A: ,
{
    pub fn run() {
        let mut entries: Vec<A> = Vec::new();
        if !entries.is_empty() {}
    }
}

pub type DataA = Data<i32>;

fn main() {
    println!("Hello, world!");
}

The output is

 $ cargo build
   Compiling rustc-crash v0.1.0 (/Users/zhangzhuo/repos/personal/rustc-crash)
error: internal compiler error: src/librustc_mir/borrow_check/universal_regions.rs:729: cannot convert `ReEmpty` to a region vid

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:883:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

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.42.0-nightly (6d3f4e0aa 2020-01-25) running on x86_64-apple-darwin

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

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

error: aborting due to previous error

error: could not compile `rustc-crash`.

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

Meta

rustc --version --verbose:

rustc 1.42.0-nightly (6d3f4e0aa 2020-01-25)
binary: rustc
commit-hash: 6d3f4e0aab3e36ceb8b83d1e9467514685f6b751
commit-date: 2020-01-25
host: x86_64-apple-darwin
release: 1.42.0-nightly
LLVM version: 9.0
@jonas-schievink jonas-schievink added A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 26, 2020
@Centril
Copy link
Contributor

Centril commented Jan 26, 2020

Reduced:

fn run<'a, A>(x: A)
where
    A: 'static,
    &'static A: ,
{
    let _: &'a A = &x;
}

fn main() {}

backtrace:

   Compiling playground v0.0.1 (/playground)
error: internal compiler error: src/librustc_mir/borrow_check/universal_regions.rs:729: cannot convert `ReEmpty` to a region vid

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:883:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1052
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1426
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:204
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:224
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:476
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::bug
  14: rustc_errors::Handler::bug
  15: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc::ty::context::tls::with_opt::{{closure}}
  17: rustc::ty::context::tls::with_opt
  18: rustc::util::bug::opt_span_bug_fmt
  19: rustc::util::bug::bug_fmt
  20: rustc_mir::borrow_check::universal_regions::UniversalRegionIndices::to_region_vid::{{closure}}
  21: rustc_mir::borrow_check::universal_regions::UniversalRegionIndices::to_region_vid
  22: rustc_mir::borrow_check::region_infer::RegionInferenceContext::eval_verify_bound
  23: rustc_mir::borrow_check::region_infer::RegionInferenceContext::eval_verify_bound
  24: rustc_mir::borrow_check::nll::compute_regions
  25: rustc_mir::borrow_check::do_mir_borrowck
  26: rustc::ty::context::GlobalCtxt::enter_local
  27: rustc_mir::borrow_check::mir_borrowck
  28: rustc::ty::query::__query_compute::mir_borrowck
  29: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_borrowck>::compute
  30: rustc::dep_graph::graph::DepGraph::with_task_impl
  31: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  32: rustc::ty::<impl rustc::ty::context::TyCtxt>::par_body_owners
  33: rustc_session::utils::<impl rustc_session::session::Session>::time
  34: rustc_interface::passes::analysis
  35: rustc::ty::query::__query_compute::analysis
  36: rustc::dep_graph::graph::DepGraph::with_task_impl
  37: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  38: rustc::ty::context::tls::enter_global
  39: rustc_interface::interface::run_compiler_in_existing_thread_pool
  40: scoped_tls::ScopedKey<T>::set
  41: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

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.42.0-nightly (6d3f4e0aa 2020-01-25) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin

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

query stack during panic:
#0 [mir_borrowck] processing `run`
#1 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

error: could not compile `playground`.

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

Problem occurs in:

pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReVar(..) = r {
r.to_region_vid()
} else {
*self
.indices
.get(&r)
.unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r))
}
}

which does not account for ReEmpty (which it presumably shouldn't).

cc @matthewjasper

@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Jan 29, 2020
@pnkfelix
Copy link
Member

pnkfelix commented Feb 6, 2020

triage: P-high, assigning to self, removing nomination label.

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Feb 6, 2020
@pnkfelix pnkfelix self-assigned this Feb 6, 2020
@pnkfelix
Copy link
Member

@rustbot assign @nikomatsakis

reassigning to niko because they told me that they are doing work that should address the issue here.

@rustbot rustbot assigned nikomatsakis and unassigned pnkfelix Mar 31, 2020
@izik1
Copy link

izik1 commented Apr 1, 2020

Possibly interesting variant of this:

fn spawn<T: Send>(_: T) {}

async fn fetch(_: &()) {
    fn f<T>() {}
    spawn(f);
}

pub async fn spawn_fetch() {
    spawn(fetch(&()));
}

which outputs the following:
output.txt

RalfJung added a commit to RalfJung/rust that referenced this issue Apr 30, 2020
…tthewjasper

extend NLL checker to understand `'empty` combined with universes

This PR extends the NLL region checker to understand `'empty` combined with universes. In particular, it means that the NLL region checker no longer considers `exists<R2> { forall<R1> { R1: R2 } }` to be provable. This is work towards rust-lang#59490, but we're not all the way there. One thing in particular it does not address is error messages.

The modifications to the NLL region inference code turned out to be simpler than expected. The main change is to require that if `R1: R2` then `universe(R1) <= universe(R2)`.

This constraint follows from the region lattice (shown below), because we assume then that `R2` is "at least" `empty(Universe(R2))`, and hence if `R1: R2` (i.e., `R1 >= R2` on the lattice) then `R1` must be in some universe that can name `'empty(Universe(R2))`, which requires that `Universe(R1) <= Universe(R2)`.

```
static ----------+-----...------+       (greatest)
|                |              |
early-bound and  |              |
free regions     |              |
|                |              |
scope regions    |              |
|                |              |
empty(root)   placeholder(U1)   |
|            /                  |
|           /         placeholder(Un)
empty(U1) --         /
|                   /
...                /
|                 /
empty(Un) --------                      (smallest)
```

I also made what turned out to be a somewhat unrelated change to add a special region to represent `'empty(U0)`, which we use (somewhat hackily) to indicate well-formedness checks in some parts of the compiler. This fixes rust-lang#68550.

I did some investigation into fixing the error message situation. That's a bit trickier: the existing "nice region error" code around placeholders relies on having better error tracing than NLL currently provides, so that it knows (e.g.) that the constraint arose from applying a trait impl and things like that. I feel like I was hoping *not* to do such fine-grained tracing in NLL, and it seems like we...largely...got away with that. I'm not sure yet if we'll have to add more tracing information or if there is some sort of alternative.

It's worth pointing out though that I've not kind of shifted my opinion on whose job it should be to enforce lifetimes: I tend to think we ought to be moving back towards *something like* the leak-check (just not the one we *had*). If we took that approach, it would actually resolve this aspect of the error message problem, because we would be resolving 'higher-ranked errors' in the trait solver itself, and hence we wouldn't have to thread as much causal information back to the region checker. I think it would also help us with removing the leak check while not breaking some of the existing crates out there.

Regardless, I think it's worth landing this change, because it was relatively simple and it aligns the set of programs that NLL accepts with those that are accepted by the main region checker, and hence should at least *help* us in migration (though I guess we still also have to resolve the existing crates that rely on leak check for coherence).

r? @matthewjasper
@bors bors closed this as completed in 09f3c90 Apr 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants