auto merge of #19388 : nick29581/rust/rc-show, r=alexcrichto

r? @huonw or @alexcrichton

Apparently, we have previously rejected an RFC like this. However, since then we removed `{:?}` and so without this debugging gets really difficult as soon as there is a RefCell anywhere, so I believe there is more benefit to adding these impls than there was before. By using "try_borrow" we can avoid panicing in `Show` (I think).

@ huon in response to a comment in #19254: I noticed that `drop()` checks for the ptr being null, so I checked here too. Now I am checking for both, if you're confident I can change to only checking `strong()`.
This commit is contained in:
bors 2015-01-01 06:36:24 +00:00
commit c594959cdf
3 changed files with 36 additions and 5 deletions

View File

@ -719,6 +719,13 @@ impl<T> Clone for Weak<T> {
} }
} }
#[experimental = "Show is experimental."]
impl<T: fmt::Show> fmt::Show for Weak<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(Weak)")
}
}
#[doc(hidden)] #[doc(hidden)]
trait RcBoxPtr<T> { trait RcBoxPtr<T> {
fn inner(&self) -> &RcBox<T>; fn inner(&self) -> &RcBox<T>;

View File

@ -158,6 +158,7 @@
use clone::Clone; use clone::Clone;
use cmp::PartialEq; use cmp::PartialEq;
use default::Default; use default::Default;
use fmt;
use kinds::{Copy, Send}; use kinds::{Copy, Send};
use ops::{Deref, DerefMut, Drop}; use ops::{Deref, DerefMut, Drop};
use option::Option; use option::Option;
@ -365,6 +366,16 @@ impl<T: PartialEq> PartialEq for RefCell<T> {
} }
} }
#[unstable]
impl<T:fmt::Show> fmt::Show for RefCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.try_borrow() {
Some(val) => write!(f, "{}", val),
None => write!(f, "<borrowed RefCell>")
}
}
}
struct BorrowRef<'b> { struct BorrowRef<'b> {
_borrow: &'b Cell<BorrowFlag>, _borrow: &'b Cell<BorrowFlag>,
} }

View File

@ -88,6 +88,7 @@ use syntax::visit::{mod, Visitor};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::fmt;
use std::mem::replace; use std::mem::replace;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::uint; use std::uint;
@ -178,7 +179,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
} }
/// Contains data for specific types of import directives. /// Contains data for specific types of import directives.
#[deriving(Copy)] #[deriving(Copy,Show)]
enum ImportDirectiveSubclass { enum ImportDirectiveSubclass {
SingleImport(Name /* target */, Name /* source */), SingleImport(Name /* target */, Name /* source */),
GlobImport GlobImport
@ -309,6 +310,7 @@ enum Shadowable {
} }
/// One import directive. /// One import directive.
#[deriving(Show)]
struct ImportDirective { struct ImportDirective {
module_path: Vec<Name>, module_path: Vec<Name>,
subclass: ImportDirectiveSubclass, subclass: ImportDirectiveSubclass,
@ -338,7 +340,7 @@ impl ImportDirective {
} }
/// The item that an import resolves to. /// The item that an import resolves to.
#[deriving(Clone)] #[deriving(Clone,Show)]
struct Target { struct Target {
target_module: Rc<Module>, target_module: Rc<Module>,
bindings: Rc<NameBindings>, bindings: Rc<NameBindings>,
@ -359,6 +361,7 @@ impl Target {
} }
/// An ImportResolution represents a particular `use` directive. /// An ImportResolution represents a particular `use` directive.
#[deriving(Show)]
struct ImportResolution { struct ImportResolution {
/// Whether this resolution came from a `use` or a `pub use`. Note that this /// Whether this resolution came from a `use` or a `pub use`. Note that this
/// should *not* be used whenever resolution is being performed, this is /// should *not* be used whenever resolution is being performed, this is
@ -438,7 +441,7 @@ impl ImportResolution {
} }
/// The link from a module up to its nearest parent node. /// The link from a module up to its nearest parent node.
#[deriving(Clone)] #[deriving(Clone,Show)]
enum ParentLink { enum ParentLink {
NoParentLink, NoParentLink,
ModuleParentLink(Weak<Module>, Name), ModuleParentLink(Weak<Module>, Name),
@ -446,7 +449,7 @@ enum ParentLink {
} }
/// The type of module this is. /// The type of module this is.
#[deriving(Copy, PartialEq)] #[deriving(Copy, PartialEq, Show)]
enum ModuleKind { enum ModuleKind {
NormalModuleKind, NormalModuleKind,
TraitModuleKind, TraitModuleKind,
@ -528,6 +531,15 @@ impl Module {
} }
} }
impl fmt::Show for Module {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}, kind: {}, {}",
self.def_id,
self.kind,
if self.is_public { "public" } else { "private" } )
}
}
bitflags! { bitflags! {
#[deriving(Show)] #[deriving(Show)]
flags DefModifiers: u8 { flags DefModifiers: u8 {
@ -537,7 +549,7 @@ bitflags! {
} }
// Records a possibly-private type definition. // Records a possibly-private type definition.
#[deriving(Clone)] #[deriving(Clone,Show)]
struct TypeNsDef { struct TypeNsDef {
modifiers: DefModifiers, // see note in ImportResolution about how to use this modifiers: DefModifiers, // see note in ImportResolution about how to use this
module_def: Option<Rc<Module>>, module_def: Option<Rc<Module>>,
@ -555,6 +567,7 @@ struct ValueNsDef {
// Records the definitions (at most one for each namespace) that a name is // Records the definitions (at most one for each namespace) that a name is
// bound to. // bound to.
#[deriving(Show)]
struct NameBindings { struct NameBindings {
type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace. type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace. value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.