Skip to content

Trait inheritance for bounded type parameters #4070

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/libcore/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ pub pure fn logarithm(n: f32, b: f32) -> f32 {
return log2(n) / log2(b);
}

impl f32 : cmp::Eq {
pure fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
pure fn ne(&self, other: &f32) -> bool { (*self) != (*other) }
}

impl f32 : cmp::Ord {
pure fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
pure fn le(&self, other: &f32) -> bool { (*self) <= (*other) }
pure fn ge(&self, other: &f32) -> bool { (*self) >= (*other) }
pure fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
}

impl f32: num::Num {
pure fn add(other: &f32) -> f32 { return self + *other; }
pure fn sub(other: &f32) -> f32 { return self - *other; }
Expand Down
12 changes: 12 additions & 0 deletions src/libcore/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ pub pure fn logarithm(n: f64, b: f64) -> f64 {
return log2(n) / log2(b);
}

impl f64 : cmp::Eq {
pure fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
pure fn ne(&self, other: &f64) -> bool { (*self) != (*other) }
}

impl f64 : cmp::Ord {
pure fn lt(&self, other: &f64) -> bool { (*self) < (*other) }
pure fn le(&self, other: &f64) -> bool { (*self) <= (*other) }
pure fn ge(&self, other: &f64) -> bool { (*self) >= (*other) }
pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
}

impl f64: num::Num {
pure fn add(other: &f64) -> f64 { return self + *other; }
pure fn sub(other: &f64) -> f64 { return self - *other; }
Expand Down
1 change: 1 addition & 0 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub trait Times {
pub trait CopyableIter<A:Copy> {
pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A];
pure fn map_to_vec<B>(op: fn(v: A) -> B) -> ~[B];
pure fn flat_map_to_vec<B:Copy,IB: BaseIter<B>>(op: fn(A) -> IB) -> ~[B];
pure fn to_vec() -> ~[A];
pure fn find(p: fn(a: A) -> bool) -> Option<A>;
}
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub trait GenericPath {
pure fn with_filestem((&str)) -> self;
pure fn with_filetype((&str)) -> self;

pure fn dir_path() -> self;
pure fn file_path() -> self;

pure fn push((&str)) -> self;
pure fn push_rel((&self)) -> self;
pure fn push_many((&[~str])) -> self;
Expand Down
23 changes: 14 additions & 9 deletions src/libcore/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,13 +811,22 @@ pub struct RecvPacketBuffered<T: Send, Tbuffer: Send> {
}
}

impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> {
fn unwrap() -> *Packet<T> {
let mut p = None;
p <-> self.p;
option::unwrap(move p)
}

fn reuse_buffer() -> BufferResource<Tbuffer> {
//error!("recv reuse_buffer");
let mut tmp = None;
tmp <-> self.buffer;
option::unwrap(move tmp)
}
}

impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
pure fn header() -> *PacketHeader {
match self.p {
Some(packet) => unsafe {
Expand All @@ -829,13 +838,6 @@ impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
None => fail ~"packet already consumed"
}
}

fn reuse_buffer() -> BufferResource<Tbuffer> {
//error!("recv reuse_buffer");
let mut tmp = None;
tmp <-> self.buffer;
option::unwrap(move tmp)
}
}

pub fn RecvPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
Expand Down Expand Up @@ -1046,7 +1048,7 @@ pub fn PortSet<T: Send>() -> PortSet<T>{
}
}

impl<T: Send> PortSet<T> : Recv<T> {
impl<T: Send> PortSet<T> {

fn add(port: pipes::Port<T>) {
self.ports.push(move port)
Expand All @@ -1057,6 +1059,9 @@ impl<T: Send> PortSet<T> : Recv<T> {
self.add(move po);
move ch
}
}

impl<T: Send> PortSet<T> : Recv<T> {

fn try_recv() -> Option<T> {
let mut result = None;
Expand Down
7 changes: 4 additions & 3 deletions src/libcore/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ pub fn MovePtrAdaptor<V: TyVisitor MovePtr>(v: V) -> MovePtrAdaptor<V> {
MovePtrAdaptor { inner: move v }
}

/// Abstract type-directed pointer-movement using the MovePtr trait
impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {

impl<V: TyVisitor MovePtr> MovePtrAdaptor<V> {
#[inline(always)]
fn bump(sz: uint) {
do self.inner.move_ptr() |p| {
Expand All @@ -60,7 +58,10 @@ impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
fn bump_past<T>() {
self.bump(sys::size_of::<T>());
}
}

/// Abstract type-directed pointer-movement using the MovePtr trait
impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
fn visit_bot() -> bool {
self.align_to::<()>();
if ! self.inner.visit_bot() { return false; }
Expand Down
12 changes: 4 additions & 8 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1330,16 +1330,12 @@ fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
debug!("find_vtable_in_fn_ctxt(n_param=%u, n_bound=%u, ps=%?)",
n_param, n_bound, param_substs_to_str(tcx, ps));

let mut vtable_off = n_bound, i = 0u;
// Vtables are stored in a flat array, finding the right one is
// somewhat awkward
for vec::each(*ps.bounds) |bounds| {
if i >= n_param { break; }
for vec::each(**bounds) |bound| {
match *bound { ty::bound_trait(_) => vtable_off += 1u, _ => () }
}
i += 1u;
}
let first_n_bounds = ps.bounds.view(0, n_param);
let vtables_to_skip =
ty::count_traits_and_supertraits(tcx, first_n_bounds);
let vtable_off = vtables_to_skip + n_bound;
ps.vtables.get()[vtable_off]
}

Expand Down
12 changes: 1 addition & 11 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,7 @@ fn trans_static_method_callee(bcx: block,
// one we are interested in.
let bound_index = {
let trait_polyty = ty::lookup_item_type(bcx.tcx(), trait_id);
let mut index = 0;
for trait_polyty.bounds.each |param_bounds| {
for param_bounds.each |param_bound| {
match *param_bound {
ty::bound_trait(_) => { index += 1; }
ty::bound_copy | ty::bound_owned |
ty::bound_send | ty::bound_const => {}
}
}
}
index
ty::count_traits_and_supertraits(bcx.tcx(), *trait_polyty.bounds)
};

let mname = if method_id.crate == ast::local_crate {
Expand Down
60 changes: 60 additions & 0 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ export DerivedFieldInfo;
export AutoAdjustment;
export AutoRef;
export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowFn;
export iter_bound_traits_and_supertraits;
export count_traits_and_supertraits;

// Data types

Expand Down Expand Up @@ -4530,6 +4532,64 @@ pure fn determine_inherited_purity(parent_purity: ast::purity,
}
}

// Iterate over a type parameter's bounded traits and any supertraits
// of those traits, ignoring kinds.
fn iter_bound_traits_and_supertraits(tcx: ctxt,
bounds: param_bounds,
f: &fn(t) -> bool) {
for bounds.each |bound| {

let bound_trait_ty = match *bound {
ty::bound_trait(bound_t) => bound_t,

ty::bound_copy | ty::bound_send |
ty::bound_const | ty::bound_owned => {
loop; // skip non-trait bounds
}
};

let mut worklist = ~[];

let init_trait_ty = bound_trait_ty;

worklist.push(init_trait_ty);

let mut i = 0;
while i < worklist.len() {
let init_trait_ty = worklist[i];
i += 1;

let init_trait_id = match ty_to_def_id(init_trait_ty) {
Some(id) => id,
None => tcx.sess.bug(
~"trait type should have def_id")
};

// Add supertraits to worklist
let supertraits = trait_supertraits(tcx,
init_trait_id);
for supertraits.each |supertrait| {
worklist.push(supertrait.tpt.ty);
}

if !f(init_trait_ty) {
return;
}
}
}
}

fn count_traits_and_supertraits(tcx: ctxt,
boundses: &[param_bounds]) -> uint {
let mut total = 0;
for boundses.each |bounds| {
for iter_bound_traits_and_supertraits(tcx, *bounds) |_trait_ty| {
total += 1;
}
}
return total;
}

impl mt : cmp::Eq {
pure fn eq(&self, other: &mt) -> bool {
(*self).ty == (*other).ty && (*self).mutbl == (*other).mutbl
Expand Down
Loading