Skip to content

Commit

Permalink
cstore: return an immutable borrow from visible_parent_map
Browse files Browse the repository at this point in the history
Fixes #41053.
  • Loading branch information
arielb1 committed Apr 4, 2017
1 parent 5309a3e commit 60381cd
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/librustc/middle/cstore.rs
Expand Up @@ -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>;
Expand Down Expand Up @@ -302,7 +302,7 @@ impl CrateStore for DummyCrateStore {
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
Expand Down
16 changes: 12 additions & 4 deletions src/librustc_metadata/cstore_impl.rs
Expand Up @@ -507,12 +507,19 @@ impl CrateStore for cstore::CStore {
/// 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);

Expand Down Expand Up @@ -556,6 +563,7 @@ impl CrateStore for cstore::CStore {
}
}

visible_parent_map
drop(visible_parent_map);
self.visible_parent_map.borrow()
}
}
11 changes: 11 additions & 0 deletions src/test/run-pass/auxiliary/issue_41053.rs
@@ -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;
30 changes: 30 additions & 0 deletions src/test/run-pass/issue-41053.rs
@@ -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();
}

0 comments on commit 60381cd

Please sign in to comment.