From b7435cf44783c9ab6cf16bc387299ed9891ae90d Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 12 Sep 2013 01:01:59 -0400 Subject: [PATCH] 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. --- src/librustc/middle/ty.rs | 5 ++- src/libstd/ptr.rs | 68 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 0e57bdc5321..f5bb5dab41e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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)]; } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index fafb1511973..6e90e2a1070 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -383,7 +383,7 @@ impl RawPtr for *mut T { } // Equality for pointers -#[cfg(not(test))] +#[cfg(stage0, not(test))] impl Eq for *T { #[inline] fn eq(&self, other: &*T) -> bool { @@ -393,7 +393,17 @@ impl Eq for *T { fn ne(&self, other: &*T) -> bool { !self.eq(other) } } -#[cfg(not(test))] +#[cfg(not(stage0), not(test))] +impl 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 Eq for *mut T { #[inline] fn eq(&self, other: &*mut T) -> bool { @@ -403,6 +413,16 @@ impl Eq for *mut T { fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } } +#[cfg(not(stage0), not(test))] +impl 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 Equiv<*mut T> for *T { @@ -460,7 +480,7 @@ mod externfnpointers { } // Comparison for pointers -#[cfg(not(test))] +#[cfg(stage0, not(test))] impl Ord for *T { #[inline] fn lt(&self, other: &*T) -> bool { @@ -480,7 +500,27 @@ impl Ord for *T { } } -#[cfg(not(test))] +#[cfg(not(stage0), not(test))] +impl 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 Ord for *mut T { #[inline] fn lt(&self, other: &*mut T) -> bool { @@ -500,6 +540,26 @@ impl Ord for *mut T { } } +#[cfg(not(stage0), not(test))] +impl 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::*;