implement raw pointer comparisons in librustc

This is mostly for consistency, as you can now compare raw pointers in
constant expressions or without the standard library.

It also reduces the number of `ptrtoint` instructions in the IR, making
tracking down culprits of what's usually an anti-pattern easier.
This commit is contained in:
Daniel Micay 2013-09-12 01:01:59 -04:00
parent 62166611e7
commit b7435cf447
2 changed files with 68 additions and 5 deletions

View File

@ -4266,6 +4266,7 @@ pub fn is_binopable(cx: ctxt, ty: t, op: ast::BinOp) -> bool {
static tycat_int: int = 3;
static tycat_float: int = 4;
static tycat_bot: int = 5;
static tycat_raw_ptr: int = 6;
static opcat_add: int = 0;
static opcat_sub: int = 1;
@ -4309,6 +4310,7 @@ pub fn is_binopable(cx: ctxt, ty: t, op: ast::BinOp) -> bool {
ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
ty_bot => tycat_bot,
ty_ptr(_) => tycat_raw_ptr,
_ => tycat_other
}
}
@ -4323,7 +4325,8 @@ pub fn is_binopable(cx: ctxt, ty: t, op: ast::BinOp) -> bool {
/*char*/ [f, f, f, f, t, t, f, f],
/*int*/ [t, t, t, t, t, t, t, f],
/*float*/ [t, t, t, f, t, t, f, f],
/*bot*/ [t, t, t, t, f, f, t, t]];
/*bot*/ [t, t, t, t, f, f, t, t],
/*raw ptr*/ [f, f, f, f, t, t, f, f]];
return tbl[tycat(cx, ty)][opcat(op)];
}

View File

@ -383,7 +383,7 @@ impl<T> RawPtr<T> for *mut T {
}
// Equality for pointers
#[cfg(not(test))]
#[cfg(stage0, not(test))]
impl<T> Eq for *T {
#[inline]
fn eq(&self, other: &*T) -> bool {
@ -393,7 +393,17 @@ impl<T> Eq for *T {
fn ne(&self, other: &*T) -> bool { !self.eq(other) }
}
#[cfg(not(test))]
#[cfg(not(stage0), not(test))]
impl<T> Eq for *T {
#[inline]
fn eq(&self, other: &*T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*T) -> bool { !self.eq(other) }
}
#[cfg(stage0, not(test))]
impl<T> Eq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
@ -403,6 +413,16 @@ impl<T> Eq for *mut T {
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}
#[cfg(not(stage0), not(test))]
impl<T> Eq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}
// Equivalence for pointers
#[cfg(not(test))]
impl<T> Equiv<*mut T> for *T {
@ -460,7 +480,7 @@ mod externfnpointers {
}
// Comparison for pointers
#[cfg(not(test))]
#[cfg(stage0, not(test))]
impl<T> Ord for *T {
#[inline]
fn lt(&self, other: &*T) -> bool {
@ -480,7 +500,27 @@ impl<T> Ord for *T {
}
}
#[cfg(not(test))]
#[cfg(not(stage0), not(test))]
impl<T> Ord for *T {
#[inline]
fn lt(&self, other: &*T) -> bool {
*self < *other
}
#[inline]
fn le(&self, other: &*T) -> bool {
*self <= *other
}
#[inline]
fn ge(&self, other: &*T) -> bool {
*self >= *other
}
#[inline]
fn gt(&self, other: &*T) -> bool {
*self > *other
}
}
#[cfg(stage0, not(test))]
impl<T> Ord for *mut T {
#[inline]
fn lt(&self, other: &*mut T) -> bool {
@ -500,6 +540,26 @@ impl<T> Ord for *mut T {
}
}
#[cfg(not(stage0), not(test))]
impl<T> Ord for *mut T {
#[inline]
fn lt(&self, other: &*mut T) -> bool {
*self < *other
}
#[inline]
fn le(&self, other: &*mut T) -> bool {
*self <= *other
}
#[inline]
fn ge(&self, other: &*mut T) -> bool {
*self >= *other
}
#[inline]
fn gt(&self, other: &*mut T) -> bool {
*self > *other
}
}
#[cfg(test)]
pub mod ptr_tests {
use super::*;