1
Fork 0

librustc: Implement explicit self for Add and Index; add a hack in the borrow checker to support this. r=nmatsakis

This commit is contained in:
Patrick Walton 2012-11-28 13:51:50 -08:00
parent 56ece46f7d
commit d1ebdbeb6c
10 changed files with 128 additions and 15 deletions

View file

@ -145,12 +145,22 @@ pub pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
#[cfg(notest)] #[cfg(notest)]
pub mod traits { pub mod traits {
#[cfg(stage0)]
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> { pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
#[inline(always)] #[inline(always)]
pure fn add(rhs: & &self/[const T]) -> @[T] { pure fn add(rhs: & &self/[const T]) -> @[T] {
append(self, (*rhs)) append(self, (*rhs))
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
#[inline(always)]
pure fn add(&self, rhs: & &self/[const T]) -> @[T] {
append(*self, (*rhs))
}
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -358,10 +358,19 @@ impl<A: Copy> DVec<A> {
} }
} }
#[cfg(stage0)]
impl<A:Copy> DVec<A>: Index<uint,A> { impl<A:Copy> DVec<A>: Index<uint,A> {
#[inline(always)] #[inline(always)]
pure fn index(idx: uint) -> A { pure fn index(idx: uint) -> A {
self.get_elt(idx) self.get_elt(idx)
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl<A:Copy> DVec<A>: Index<uint,A> {
#[inline(always)]
pure fn index(&self, idx: uint) -> A {
self.get_elt(idx)
}
}

View file

@ -18,11 +18,19 @@ pub trait Drop {
fn finalize(&self); // XXX: Rename to "drop"? --pcwalton fn finalize(&self); // XXX: Rename to "drop"? --pcwalton
} }
#[cfg(stage0)]
#[lang="add"] #[lang="add"]
pub trait Add<RHS,Result> { pub trait Add<RHS,Result> {
pure fn add(rhs: &RHS) -> Result; pure fn add(rhs: &RHS) -> Result;
} }
#[cfg(stage1)]
#[cfg(stage2)]
#[lang="add"]
pub trait Add<RHS,Result> {
pure fn add(&self, rhs: &RHS) -> Result;
}
#[lang="sub"] #[lang="sub"]
pub trait Sub<RHS,Result> { pub trait Sub<RHS,Result> {
pure fn sub(&self, rhs: &RHS) -> Result; pure fn sub(&self, rhs: &RHS) -> Result;
@ -73,8 +81,16 @@ pub trait Shr<RHS,Result> {
pure fn shr(&self, rhs: &RHS) -> Result; pure fn shr(&self, rhs: &RHS) -> Result;
} }
#[cfg(stage0)]
#[lang="index"] #[lang="index"]
pub trait Index<Index,Result> { pub trait Index<Index,Result> {
pure fn index(index: Index) -> Result; pure fn index(index: Index) -> Result;
} }
#[cfg(stage1)]
#[cfg(stage2)]
#[lang="index"]
pub trait Index<Index,Result> {
pure fn index(&self, index: Index) -> Result;
}

View file

@ -2107,12 +2107,21 @@ impl ~str: Trimmable {
#[cfg(notest)] #[cfg(notest)]
pub mod traits { pub mod traits {
#[cfg(stage0)]
impl ~str : Add<&str,~str> { impl ~str : Add<&str,~str> {
#[inline(always)] #[inline(always)]
pure fn add(rhs: & &self/str) -> ~str { pure fn add(rhs: & &self/str) -> ~str {
append(copy self, (*rhs)) append(copy self, (*rhs))
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl ~str : Add<&str,~str> {
#[inline(always)]
pure fn add(&self, rhs: & &self/str) -> ~str {
append(copy *self, (*rhs))
}
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1438,18 +1438,37 @@ impl<T: Ord> @[T] : Ord {
} }
#[cfg(notest)] #[cfg(notest)]
impl<T: Copy> ~[T] : Add<&[const T],~[T]> { pub mod traits {
#[inline(always)] #[cfg(stage0)]
pure fn add(rhs: & &self/[const T]) -> ~[T] { impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
append(copy self, (*rhs)) #[inline(always)]
pure fn add(rhs: & &self/[const T]) -> ~[T] {
append(copy self, (*rhs))
}
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
#[inline(always)]
pure fn add(&self, rhs: & &self/[const T]) -> ~[T] {
append(copy *self, (*rhs))
}
} }
}
#[cfg(notest)] #[cfg(stage0)]
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> { impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
#[inline(always)] #[inline(always)]
pure fn add(rhs: & &self/[const T]) -> ~[mut T] { pure fn add(rhs: & &self/[const T]) -> ~[mut T] {
append_mut(copy self, (*rhs)) append_mut(copy self, (*rhs))
}
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
#[inline(always)]
pure fn add(&self, rhs: & &self/[const T]) -> ~[mut T] {
append_mut(copy *self, (*rhs))
}
} }
} }

View file

@ -20,6 +20,8 @@ use mem_categorization::{mem_categorization_ctxt, opt_deref_kind};
use preserve::{preserve_condition, pc_ok, pc_if_pure}; use preserve::{preserve_condition, pc_ok, pc_if_pure};
use ty::{ty_region}; use ty::{ty_region};
use core::send_map::linear::LinearMap;
export gather_loans; export gather_loans;
/// Context used while gathering loans: /// Context used while gathering loans:
@ -53,14 +55,16 @@ export gather_loans;
enum gather_loan_ctxt = @{bccx: borrowck_ctxt, enum gather_loan_ctxt = @{bccx: borrowck_ctxt,
req_maps: req_maps, req_maps: req_maps,
mut item_ub: ast::node_id, mut item_ub: ast::node_id,
mut root_ub: ast::node_id}; mut root_ub: ast::node_id,
mut ignore_adjustments: LinearMap<ast::node_id,()>};
fn gather_loans(bccx: borrowck_ctxt, crate: @ast::crate) -> req_maps { fn gather_loans(bccx: borrowck_ctxt, crate: @ast::crate) -> req_maps {
let glcx = gather_loan_ctxt(@{bccx: bccx, let glcx = gather_loan_ctxt(@{bccx: bccx,
req_maps: {req_loan_map: HashMap(), req_maps: {req_loan_map: HashMap(),
pure_map: HashMap()}, pure_map: HashMap()},
mut item_ub: 0, mut item_ub: 0,
mut root_ub: 0}); mut root_ub: 0,
mut ignore_adjustments: LinearMap()});
let v = visit::mk_vt(@{visit_expr: req_loans_in_expr, let v = visit::mk_vt(@{visit_expr: req_loans_in_expr,
visit_fn: req_loans_in_fn, visit_fn: req_loans_in_fn,
.. *visit::default_visitor()}); .. *visit::default_visitor()});
@ -104,8 +108,10 @@ fn req_loans_in_expr(ex: @ast::expr,
ex.id, pprust::expr_to_str(ex, tcx.sess.intr())); ex.id, pprust::expr_to_str(ex, tcx.sess.intr()));
// If this expression is borrowed, have to ensure it remains valid: // If this expression is borrowed, have to ensure it remains valid:
for tcx.adjustments.find(ex.id).each |adjustments| { if !self.ignore_adjustments.contains_key(&ex.id) {
self.guarantee_adjustments(ex, *adjustments); for tcx.adjustments.find(ex.id).each |adjustments| {
self.guarantee_adjustments(ex, *adjustments);
}
} }
// Special checks for various kinds of expressions: // Special checks for various kinds of expressions:
@ -179,7 +185,8 @@ fn req_loans_in_expr(ex: @ast::expr,
ast::expr_index(rcvr, _) | ast::expr_index(rcvr, _) |
ast::expr_binary(_, rcvr, _) | ast::expr_binary(_, rcvr, _) |
ast::expr_unary(_, rcvr) ast::expr_unary(_, rcvr) |
ast::expr_assign_op(_, rcvr, _)
if self.bccx.method_map.contains_key(ex.id) => { if self.bccx.method_map.contains_key(ex.id) => {
// Receivers in method calls are always passed by ref. // Receivers in method calls are always passed by ref.
// //
@ -193,6 +200,11 @@ fn req_loans_in_expr(ex: @ast::expr,
let scope_r = ty::re_scope(ex.id); let scope_r = ty::re_scope(ex.id);
let rcvr_cmt = self.bccx.cat_expr(rcvr); let rcvr_cmt = self.bccx.cat_expr(rcvr);
self.guarantee_valid(rcvr_cmt, m_imm, scope_r); self.guarantee_valid(rcvr_cmt, m_imm, scope_r);
// FIXME (#3387): Total hack: Ignore adjustments for the left-hand
// side. Their regions will be inferred to be too large.
self.ignore_adjustments.insert(rcvr.id, ());
visit::visit_expr(ex, self, vt); visit::visit_expr(ex, self, vt);
} }

View file

@ -565,11 +565,19 @@ pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; }
pure fn right(_w0: uint, w1: uint) -> uint { return w1; } pure fn right(_w0: uint, w1: uint) -> uint { return w1; }
#[cfg(stage0)]
impl Bitv: ops::Index<uint,bool> { impl Bitv: ops::Index<uint,bool> {
pure fn index(i: uint) -> bool { pure fn index(i: uint) -> bool {
self.get(i) self.get(i)
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl Bitv: ops::Index<uint,bool> {
pure fn index(&self, i: uint) -> bool {
self.get(i)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -57,6 +57,7 @@ pub mod Reader {
// ebml reading // ebml reading
#[cfg(stage0)]
impl Doc: ops::Index<uint,Doc> { impl Doc: ops::Index<uint,Doc> {
pure fn index(tag: uint) -> Doc { pure fn index(tag: uint) -> Doc {
unsafe { unsafe {
@ -64,6 +65,15 @@ pub mod Reader {
} }
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl Doc: ops::Index<uint,Doc> {
pure fn index(&self, tag: uint) -> Doc {
unsafe {
get_doc(*self, tag)
}
}
}
fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
let a = data[start]; let a = data[start];

View file

@ -429,6 +429,7 @@ pub mod chained {
} }
} }
#[cfg(stage0)]
impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: ops::Index<K, V> { impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: ops::Index<K, V> {
pure fn index(k: K) -> V { pure fn index(k: K) -> V {
unsafe { unsafe {
@ -436,6 +437,15 @@ pub mod chained {
} }
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: ops::Index<K, V> {
pure fn index(&self, k: K) -> V {
unsafe {
self.get(k)
}
}
}
fn chains<K,V>(nchains: uint) -> ~[mut Option<@Entry<K,V>>] { fn chains<K,V>(nchains: uint) -> ~[mut Option<@Entry<K,V>>] {
vec::to_mut(vec::from_elem(nchains, None)) vec::to_mut(vec::from_elem(nchains, None))

View file

@ -150,6 +150,7 @@ impl<V: Copy> SmallIntMap<V>: map::Map<uint, V> {
} }
} }
#[cfg(stage0)]
impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> { impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
pure fn index(key: uint) -> V { pure fn index(key: uint) -> V {
unsafe { unsafe {
@ -157,6 +158,15 @@ impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
} }
} }
} }
#[cfg(stage1)]
#[cfg(stage2)]
impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
pure fn index(&self, key: uint) -> V {
unsafe {
get(*self, key)
}
}
}
/// Cast the given smallintmap to a map::map /// Cast the given smallintmap to a map::map
pub fn as_map<V: Copy>(s: SmallIntMap<V>) -> map::Map<uint, V> { pub fn as_map<V: Copy>(s: SmallIntMap<V>) -> map::Map<uint, V> {