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 panic due to reference passed instead of mut reference #61623

Closed
daniel-tud opened this issue Jun 7, 2019 · 4 comments · Fixed by #61947
Closed

rustc panic due to reference passed instead of mut reference #61623

daniel-tud opened this issue Jun 7, 2019 · 4 comments · Fixed by #61947
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@daniel-tud
Copy link

The following code causes a panic in rustc nightly and stable 2018 Edition:

use std::collections::HashMap;
use std::marker::PhantomData;
use std::str::FromStr;

struct Value<'a, T : FromStr + ToString + Clone, P : HasTree> {
    subkey : String,
    parent : &'a mut P,
    default : T,
    phantom : PhantomData<T>
}

pub trait HasTree {
    fn get_tree(&mut self) -> &mut Tree;
}

impl<'a, T : FromStr + ToString + Clone, P : HasTree> Value<'a, T, P> {
    fn from (subkey : String, parent : &'a mut P, default : T) -> Value<'a, T, P> {
        Value {
            subkey : subkey,
            parent : parent,
            default : default,
            phantom : PhantomData {}
        }
    }

    fn get(&self) -> T {
        let default = || { self.default.clone() };
        self.parent.get_tree().enter(&self.subkey).map_or_else(default, |subkey|
            subkey.data.as_ref().map_or_else(default, |str|
            str.parse::<T>().ok().unwrap_or_else(default)))
    }
}


#[derive(Clone)]
pub struct Tree {
    branches : HashMap<String, Tree>,
    pub data : Option<String>
}

impl Tree {
    pub fn new() -> Tree {
        Tree {
            branches : HashMap::new(),
            data : None
        }
    }

    fn enter(&self, s : &String) -> Option<&Tree> {
        self.branches.get(s)
    }
}

I do not expect this to compile, as get_tree requires a mut reference, which is not provided by get. When changing get_tree to fn get_tree(&self) -> &Tree;, the code compiles properly.

Backtrace
   Compiling playground v0.0.1 (/playground)
thread 'rustc' panicked at 'no entry found for key', src/libcore/option.rs:1036:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:212
   6: rustc::util::common::panic_hook
   7: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:479
   8: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:382
   9: rust_begin_unwind
             at src/libstd/panicking.rs:309
  10: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  11: core::option::expect_failed
             at src/libcore/option.rs:1036
  12: rustc_mir::borrow_check::path_utils::each_borrow_involving_path
  13: rustc_mir::borrow_check::MirBorrowckCtxt::access_place
  14: ::visit_statement_entry
  15: rustc_mir::borrow_check::do_mir_borrowck
  16: rustc::ty::context::GlobalCtxt::enter_local
  17: rustc_mir::borrow_check::mir_borrowck
  18: rustc::ty::query::__query_compute::mir_borrowck
  19: rustc::ty::query::::compute
  20: rustc::dep_graph::graph::DepGraph::with_task_impl
  21: rustc::ty::query::plumbing::::get_query
  22: rustc::ty::::par_body_owners
  23: rustc::util::common::time
  24: rustc_interface::passes::analysis
  25: rustc::ty::query::__query_compute::analysis
  26: rustc::dep_graph::graph::DepGraph::with_task_impl
  27: rustc::ty::query::plumbing::::get_query
  28: rustc::ty::context::tls::enter_global
  29: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  30: rustc_interface::passes::create_global_ctxt::{{closure}}
  31: rustc_interface::interface::run_compiler_in_existing_thread_pool
  32: std::thread::local::LocalKey::with
  33: scoped_tls::ScopedKey::set
  34: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
query stack during panic:
#0 [mir_borrowck] processing `Value::<'a, T, P>::get`
#1 [analysis] running analysis passes on this crate
end of query stack

error: internal compiler error: unexpected panic

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

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

note: rustc 1.37.0-nightly (5eeb567a2 2019-06-06) running on x86_64-unknown-linux-gnu

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

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

error: Could not compile playground.

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

@jonas-schievink jonas-schievink added 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. A-NLL Area: Non-lexical lifetimes (NLL) labels Jun 7, 2019
@Centril
Copy link
Contributor

Centril commented Jun 7, 2019

Reduction:

fn f1<'a>(_: &'a mut ()) {}

fn f2<P>(_: P, _: ()) {}

fn f3<'a>(x: &'a ((), &'a mut ())) {
    f2(|| x.0, f1(x.1))
}

@Centril Centril added the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label Jun 7, 2019
@Centril
Copy link
Contributor

Centril commented Jun 7, 2019

cc @matthewjasper

@matthewjasper
Copy link
Contributor

The issue is here:

let bi = this.borrow_set.location_map[&location];

if location_map doesn't have location we should not take this arm, and should take the next one.

Another couple of test cases:

fn f1<'a>(_: &'a mut ()) {}

unsafe fn f3<'a>(x: *mut ((), &'a mut ())) {
    (&x, f1((*x).1));
}
trait A {
    fn f1<'a>(&'a mut self) {}
}

impl<T> A for T {}

unsafe fn f3<'a>(x: *mut ()) {
    (&x, (*x).f1());
}

@pnkfelix
Copy link
Member

triage: P-high, assigning to @matthewjasper , removing I-nominated label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. 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.

5 participants