]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #41061 - arielb1:parent-lock, r=eddyb
authorCorey Farwell <coreyf@rwell.org>
Fri, 7 Apr 2017 13:20:06 +0000 (09:20 -0400)
committerGitHub <noreply@github.com>
Fri, 7 Apr 2017 13:20:06 +0000 (09:20 -0400)
cstore: return an immutable borrow from `visible_parent_map`

This prevents an ICE when `visible_parent_map` is called multiple times, for example when an item referenced in an impl signature is imported from an  `extern crate` statement occurs within an impl.

Fixes #41053.

r? @eddyb

src/librustc/middle/cstore.rs
src/librustc_metadata/cstore_impl.rs
src/test/run-pass/auxiliary/issue_41053.rs [new file with mode: 0644]
src/test/run-pass/issue-41053.rs [new file with mode: 0644]

index ee0635ac9a179b7e02ea6fea51eb69703bc697b7..694321812836b2b943cebea312515ab54118ec5a 100644 (file)
@@ -172,7 +172,7 @@ pub trait CrateStore {
     fn stability(&self, def: DefId) -> Option<attr::Stability>;
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
     fn visibility(&self, def: DefId) -> ty::Visibility;
-    fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
+    fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
@@ -303,7 +303,7 @@ fn def_span(&self, sess: &Session, def: DefId) -> Span { bug!("def_span") }
     fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
     fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
-    fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
+    fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
         bug!("visible_parent_map")
     }
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics
index efcd2f007d66c5944466dcf6dabe541dc47be8eb..37984e4c3718fd96231832ea22bae1f8f47e409d 100644 (file)
@@ -511,12 +511,19 @@ fn metadata_encoding_version(&self) -> &[u8]
     /// Returns a map from a sufficiently visible external item (i.e. an external item that is
     /// visible from at least one local module) to a sufficiently visible parent (considering
     /// modules that re-export the external item to be parents).
-    fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
-        let mut visible_parent_map = self.visible_parent_map.borrow_mut();
-        if !visible_parent_map.is_empty() { return visible_parent_map; }
+    fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
+        {
+            let visible_parent_map = self.visible_parent_map.borrow();
+            if !visible_parent_map.is_empty() {
+                return visible_parent_map;
+            }
+        }
 
         use std::collections::vec_deque::VecDeque;
         use std::collections::hash_map::Entry;
+
+        let mut visible_parent_map = self.visible_parent_map.borrow_mut();
+
         for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
             let cdata = self.get_crate_data(cnum);
 
@@ -560,6 +567,7 @@ fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>
             }
         }
 
-        visible_parent_map
+        drop(visible_parent_map);
+        self.visible_parent_map.borrow()
     }
 }
diff --git a/src/test/run-pass/auxiliary/issue_41053.rs b/src/test/run-pass/auxiliary/issue_41053.rs
new file mode 100644 (file)
index 0000000..68e92b1
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Test;
diff --git a/src/test/run-pass/issue-41053.rs b/src/test/run-pass/issue-41053.rs
new file mode 100644 (file)
index 0000000..769d841
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue_41053.rs
+
+pub trait Trait { fn foo(&self) {} }
+
+pub struct Foo;
+
+impl Iterator for Foo {
+    type Item = Box<Trait>;
+    fn next(&mut self) -> Option<Box<Trait>> {
+        extern crate issue_41053;
+        impl ::Trait for issue_41053::Test {
+            fn foo(&self) {}
+        }
+        Some(Box::new(issue_41053::Test))
+    }
+}
+
+fn main() {
+    Foo.next().unwrap().foo();
+}