diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs
index 3c10c3545bf..efe1d47563e 100644
--- a/src/libextra/arena.rs
+++ b/src/libextra/arena.rs
@@ -116,7 +116,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
     let fill = chunk.fill;
 
     while idx < fill {
-        let tydesc_data: *uint = transmute(ptr::offset(buf, idx));
+        let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
         let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
         let (size, align) = ((*tydesc).size, (*tydesc).align);
 
@@ -127,7 +127,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
         //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
         //       start, size, align, is_done);
         if is_done {
-            ((*tydesc).drop_glue)(ptr::offset(buf, start) as *i8);
+            ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
         }
 
         // Find where the next tydesc lives
@@ -176,7 +176,7 @@ impl Arena {
             //debug!("idx = %u, size = %u, align = %u, fill = %u",
             //       start, n_bytes, align, head.fill);
 
-            ptr::offset(vec::raw::to_ptr(this.pod_head.data), start)
+            ptr::offset(vec::raw::to_ptr(this.pod_head.data), start as int)
         }
     }
 
@@ -233,7 +233,7 @@ impl Arena {
             //       start, n_bytes, align, head.fill);
 
             let buf = vec::raw::to_ptr(self.head.data);
-            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
+            return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
         }
     }
 
diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs
index f72d3ee694f..e656360aa5a 100644
--- a/src/libextra/c_vec.rs
+++ b/src/libextra/c_vec.rs
@@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
 pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T {
     assert!(ofs < len(t));
     return unsafe {
-        (*ptr::mut_offset(t.base, ofs)).clone()
+        (*ptr::mut_offset(t.base, ofs as int)).clone()
     };
 }
 
@@ -133,7 +133,7 @@ pub fn get<T:Clone>(t: CVec<T>, ofs: uint) -> T {
  */
 pub fn set<T>(t: CVec<T>, ofs: uint, v: T) {
     assert!(ofs < len(t));
-    unsafe { *ptr::mut_offset(t.base, ofs) = v };
+    unsafe { *ptr::mut_offset(t.base, ofs as int) = v };
 }
 
 /*
diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs
index c9b0cbb2753..f66677c21f7 100644
--- a/src/libextra/ebml.rs
+++ b/src/libextra/ebml.rs
@@ -150,7 +150,7 @@ pub mod reader {
 
         unsafe {
             let (ptr, _): (*u8, uint) = transmute(data);
-            let ptr = offset(ptr, start);
+            let ptr = offset(ptr, start as int);
             let ptr: *i32 = transmute(ptr);
             let val = bswap32(*ptr);
             let val: u32 = transmute(val);
diff --git a/src/libextra/par.rs b/src/libextra/par.rs
index f462a0cfae7..4069c68e71c 100644
--- a/src/libextra/par.rs
+++ b/src/libextra/par.rs
@@ -58,7 +58,7 @@ fn map_slices<A:Clone + Send,B:Clone + Send>(
                 let f = do future_spawn() || {
                     unsafe {
                         let len = end - base;
-                        let slice = (ptr::offset(p, base),
+                        let slice = (ptr::offset(p, base as int),
                                      len * sys::size_of::<A>());
                         info!("pre-slice: %?", (base, slice));
                         let slice : &[A] =
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 481d27f6944..1037e3a7628 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -215,7 +215,7 @@ fn get_metadata_section(os: os,
                 }
                 if !version_ok { return None; }
 
-                let cvbuf1 = ptr::offset(cvbuf, vlen);
+                let cvbuf1 = ptr::offset(cvbuf, vlen as int);
                 debug!("inflating %u bytes of compressed metadata",
                        csz - vlen);
                 do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| {
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index a6fc2066910..30034d76670 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -884,6 +884,11 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
             let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to());
             Ret(bcx, morestack_addr);
         }
+        "offset" => {
+            let ptr = get_param(decl, first_real_arg);
+            let offset = get_param(decl, first_real_arg + 1);
+            Ret(bcx, GEP(bcx, ptr, [offset]));
+        }
         "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
         "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
         "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 003bf458bf1..3df91844dda 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -149,7 +149,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
                     "visit_tydesc"  | "forget" | "frame_address" |
                     "morestack_addr" => 0,
 
-                    "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
+                    "offset" | "memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
                     "memset32" | "memset64" => use_repr,
 
                     "sqrtf32" | "sqrtf64" | "powif32" | "powif64" |
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 3c12b9b294f..97469937340 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3606,6 +3606,20 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
             "morestack_addr" => {
               (0u, ~[], ty::mk_nil_ptr(ccx.tcx))
             }
+            "offset" => {
+              (1,
+               ~[
+                  ty::mk_ptr(tcx, ty::mt {
+                      ty: param(ccx, 0),
+                      mutbl: ast::m_imm
+                  }),
+                  ty::mk_int()
+               ],
+               ty::mk_ptr(tcx, ty::mt {
+                   ty: param(ccx, 0),
+                   mutbl: ast::m_imm
+               }))
+            }
             "memcpy32" => {
               (1,
                ~[
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 0b2519e6fb4..8e5b6b93111 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -233,7 +233,7 @@ pub mod raw {
         let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
         let amt = v.len();
         (*repr).data.fill += sys::size_of::<T>();
-        let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T;
+        let p = ptr::offset(&(*repr).data.data as *T, amt as int) as *mut T;
         move_val_init(&mut(*p), initval);
     }
 
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs
index 4feec26a2d9..ee270b553e6 100644
--- a/src/libstd/gc.rs
+++ b/src/libstd/gc.rs
@@ -74,7 +74,7 @@ pub mod rustrt {
 }
 
 unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
-    return ptr::offset(ptr, count) as *U;
+    return ptr::offset(ptr, count as int) as *U;
 }
 
 unsafe fn align_to_pointer<T>(ptr: *T) -> *T {
@@ -140,11 +140,11 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
     // Stack roots
     let mut sri = 0;
     while sri < num_stack_roots {
-        if *ptr::offset(addrspaces, sri) >= 1 {
+        if *ptr::offset(addrspaces, sri as int) >= 1 {
             let root =
-                ptr::offset(fp_bytes, *ptr::offset(stack_roots, sri) as Word)
+                ptr::offset(fp_bytes, *ptr::offset(stack_roots, sri as int) as int)
                 as **Word;
-            let tydescpp = ptr::offset(tydescs, sri);
+            let tydescpp = ptr::offset(tydescs, sri as int);
             let tydesc = if ptr::is_not_null(tydescpp) &&
                 ptr::is_not_null(*tydescpp) {
                 **tydescpp
@@ -159,7 +159,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
     // Register roots
     let mut rri = 0;
     while rri < num_reg_roots {
-        if *ptr::offset(addrspaces, num_stack_roots + rri) == 1 {
+        if *ptr::offset(addrspaces, (num_stack_roots + rri) as int) == 1 {
             // FIXME(#2997): Need to find callee saved registers on the stack.
         }
         rri += 1;
@@ -246,7 +246,7 @@ unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> boo
         // for this second return address is 3 greater than the
         // return address for morestack.
         let ret_offset = if boundary { 4 } else { 1 };
-        last_ret = *ptr::offset(frame.fp, ret_offset) as *Word;
+        last_ret = *ptr::offset(frame.fp, ret_offset as int) as *Word;
 
         if ptr::is_null(pc) {
             loop;
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 1865dc5dece..1a92e5e07c7 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1213,7 +1213,7 @@ impl Writer for fd_t {
             let mut count = 0u;
             do v.as_imm_buf |vbuf, len| {
                 while count < len {
-                    let vb = ptr::offset(vbuf, count) as *c_void;
+                    let vb = ptr::offset(vbuf, count as int) as *c_void;
                     let nout = libc::write(*self, vb, len as size_t);
                     if nout < 0 as ssize_t {
                         error!("error writing buffer");
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 142021be471..ac03735894a 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -1114,7 +1114,7 @@ pub fn set_exit_status(code: int) {
 unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
     let mut args = ~[];
     for uint::range(0, argc as uint) |i| {
-        args.push(str::raw::from_c_str(*argv.offset(i)));
+        args.push(str::raw::from_c_str(*argv.offset(i as int)));
     }
     args
 }
@@ -1165,9 +1165,9 @@ pub fn real_args() -> ~[~str] {
     for uint::range(0, nArgs as uint) |i| {
         unsafe {
             // Determine the length of this argument.
-            let ptr = *szArgList.offset(i);
+            let ptr = *szArgList.offset(i as int);
             let mut len = 0;
-            while *ptr.offset(len) != 0 { len += 1; }
+            while *ptr.offset(len as int) != 0 { len += 1; }
 
             // Push it onto the list.
             args.push(vec::raw::buf_as_slice(ptr, len,
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 29564bd9728..3af4769fcdb 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -13,6 +13,7 @@
 use cast;
 use clone::Clone;
 use option::{Option, Some, None};
+#[cfg(stage0)]
 use sys;
 use unstable::intrinsics;
 use util::swap;
@@ -25,20 +26,44 @@ use uint;
 
 /// Calculate the offset from a pointer
 #[inline]
-pub fn offset<T>(ptr: *T, count: uint) -> *T {
-    (ptr as uint + count * sys::size_of::<T>()) as *T
+#[cfg(stage0)]
+pub fn offset<T>(ptr: *T, count: int) -> *T {
+    (ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
 }
 
 /// Calculate the offset from a const pointer
 #[inline]
-pub fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
-    (ptr as uint + count * sys::size_of::<T>()) as *T
+#[cfg(stage0)]
+pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
+    (ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
 }
 
 /// Calculate the offset from a mut pointer
 #[inline]
-pub fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
-    (ptr as uint + count * sys::size_of::<T>()) as *mut T
+#[cfg(stage0)]
+pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
+    (ptr as uint + (count as uint) * sys::size_of::<T>()) as *mut T
+}
+
+/// Calculate the offset from a pointer
+#[inline]
+#[cfg(not(stage0))]
+pub fn offset<T>(ptr: *T, count: int) -> *T {
+    unsafe { intrinsics::offset(ptr, count) }
+}
+
+/// Calculate the offset from a const pointer
+#[inline]
+#[cfg(not(stage0))]
+pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
+    unsafe { intrinsics::offset(ptr as *T, count) }
+}
+
+/// Calculate the offset from a mut pointer
+#[inline]
+#[cfg(not(stage0))]
+pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
+    unsafe { intrinsics::offset(ptr as *T, count) as *mut T }
 }
 
 /// Return the offset of the first null pointer in `buf`.
@@ -58,7 +83,7 @@ impl<T> Clone for *T {
 pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
     let mut i = 0;
     loop {
-        if f(&(*offset(buf, i))) { return i; }
+        if f(&(*offset(buf, i as int))) { return i; }
         else { i += 1; }
     }
 }
@@ -242,7 +267,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: &fn(*T)) {
     }
     //let start_ptr = *arr;
     uint::iterate(0, len, |e| {
-        let n = offset(arr, e);
+        let n = offset(arr, e as int);
         cb(*n);
         true
     });
@@ -273,7 +298,7 @@ pub trait RawPtr<T> {
     fn is_null(&self) -> bool;
     fn is_not_null(&self) -> bool;
     unsafe fn to_option(&self) -> Option<&T>;
-    fn offset(&self, count: uint) -> Self;
+    fn offset(&self, count: int) -> Self;
 }
 
 /// Extension methods for immutable pointers
@@ -305,7 +330,7 @@ impl<T> RawPtr<T> for *T {
 
     /// Calculates the offset from a pointer.
     #[inline]
-    fn offset(&self, count: uint) -> *T { offset(*self, count) }
+    fn offset(&self, count: int) -> *T { offset(*self, count) }
 }
 
 /// Extension methods for mutable pointers
@@ -337,7 +362,7 @@ impl<T> RawPtr<T> for *mut T {
 
     /// Calculates the offset from a mutable pointer.
     #[inline]
-    fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) }
+    fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) }
 }
 
 // Equality for pointers
@@ -378,7 +403,7 @@ impl<T, I: Int> Add<I, *T> for *T {
     /// Is calculated according to the size of the type pointed to.
     #[inline]
     pub fn add(&self, rhs: &I) -> *T {
-        self.offset(rhs.to_int() as uint)
+        self.offset(rhs.to_int() as int)
     }
 }
 
@@ -388,7 +413,7 @@ impl<T, I: Int> Sub<I, *T> for *T {
     /// Is calculated according to the size of the type pointed to.
     #[inline]
     pub fn sub(&self, rhs: &I) -> *T {
-        self.offset(-rhs.to_int() as uint)
+        self.offset(-rhs.to_int() as int)
     }
 }
 
@@ -398,7 +423,7 @@ impl<T, I: Int> Add<I, *mut T> for *mut T {
     /// Is calculated according to the size of the type pointed to.
     #[inline]
     pub fn add(&self, rhs: &I) -> *mut T {
-        self.offset(rhs.to_int() as uint)
+        self.offset(rhs.to_int() as int)
     }
 }
 
@@ -408,7 +433,7 @@ impl<T, I: Int> Sub<I, *mut T> for *mut T {
     /// Is calculated according to the size of the type pointed to.
     #[inline]
     pub fn sub(&self, rhs: &I) -> *mut T {
-        self.offset(-rhs.to_int() as uint)
+        self.offset(-rhs.to_int() as int)
     }
 }
 
@@ -445,14 +470,14 @@ pub mod ptr_tests {
             let v0 = ~[32000u16, 32001u16, 32002u16];
             let mut v1 = ~[0u16, 0u16, 0u16];
 
-            copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1u),
-                        offset(vec::raw::to_ptr(v0), 1u), 1u);
+            copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 1),
+                        offset(vec::raw::to_ptr(v0), 1), 1);
             assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
             copy_memory(vec::raw::to_mut_ptr(v1),
-                        offset(vec::raw::to_ptr(v0), 2u), 1u);
+                        offset(vec::raw::to_ptr(v0), 2), 1);
             assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
                      v1[2] == 0u16));
-            copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 2u),
+            copy_memory(mut_offset(vec::raw::to_mut_ptr(v1), 2),
                         vec::raw::to_ptr(v0), 1u);
             assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
                      v1[2] == 32000u16));
@@ -495,7 +520,7 @@ pub mod ptr_tests {
         assert!(p.is_null());
         assert!(!p.is_not_null());
 
-        let q = offset(p, 1u);
+        let q = offset(p, 1);
         assert!(!q.is_null());
         assert!(q.is_not_null());
 
@@ -503,7 +528,7 @@ pub mod ptr_tests {
         assert!(mp.is_null());
         assert!(!mp.is_not_null());
 
-        let mq = mp.offset(1u);
+        let mq = mp.offset(1);
         assert!(!mq.is_null());
         assert!(mq.is_not_null());
     }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index eb4e1918add..60bd30bbee8 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -212,7 +212,7 @@ impl ReprVisitor {
                 self.writer.write_str(", ");
             }
             self.visit_ptr_inner(p as *c_void, inner);
-            p = align(ptr::offset(p, sz) as uint, al) as *u8;
+            p = align(ptr::offset(p, sz as int) as uint, al) as *u8;
             left -= dec;
         }
         self.writer.write_char(']');
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 85cdb9fc941..cd950471286 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -114,7 +114,7 @@ mod imp {
     unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
         let mut args = ~[];
         for uint::range(0, argc as uint) |i| {
-            args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
+            args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int)));
         }
         return args;
     }
diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs
index fbb516b2df4..a1269968921 100644
--- a/src/libstd/rt/stack.rs
+++ b/src/libstd/rt/stack.rs
@@ -44,7 +44,7 @@ impl StackSegment {
 
     /// Point one word beyond the high end of the allocated stack
     pub fn end(&self) -> *uint {
-        vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint
+        vec::raw::to_ptr(self.buf).offset(self.buf.len() as int) as *uint
     }
 }
 
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 311b22ad620..6981005ed2f 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -182,7 +182,7 @@ impl<'self, S: Str> StrVector for &'self [S] {
                     do ss.as_slice().as_imm_buf |ssbuf, sslen| {
                         let sslen = sslen - 1;
                         ptr::copy_memory(buf, ssbuf, sslen);
-                        buf = buf.offset(sslen);
+                        buf = buf.offset(sslen as int);
                     }
                 }
             }
@@ -218,10 +218,10 @@ impl<'self, S: Str> StrVector for &'self [S] {
                                 first = false;
                             } else {
                                 ptr::copy_memory(buf, sepbuf, seplen);
-                                buf = buf.offset(seplen);
+                                buf = buf.offset(seplen as int);
                             }
                             ptr::copy_memory(buf, ssbuf, sslen);
-                            buf = buf.offset(sslen);
+                            buf = buf.offset(sslen as int);
                         }
                     }
                 }
@@ -755,7 +755,7 @@ pub mod raw {
         let mut i = 0u;
         while *curr != 0u8 {
             i += 1u;
-            curr = ptr::offset(buf, i);
+            curr = ptr::offset(buf, i as int);
         }
         return from_buf_len(buf, i);
     }
@@ -816,7 +816,7 @@ pub mod raw {
         let mut len = 0u;
         while *curr != 0u8 {
             len += 1u;
-            curr = ptr::offset(s, len);
+            curr = ptr::offset(s, len as int);
         }
         let v = Slice { data: s, len: len + 1 };
         assert!(is_utf8(cast::transmute(v)));
@@ -838,7 +838,7 @@ pub mod raw {
              assert!((end <= n));
 
              cast::transmute(Slice {
-                 data: ptr::offset(sbuf, begin),
+                 data: ptr::offset(sbuf, begin as int),
                  len: end - begin + 1,
              })
         }
@@ -849,7 +849,7 @@ pub mod raw {
         let new_len = s.len() + 1;
         s.reserve_at_least(new_len);
         do s.as_mut_buf |buf, len| {
-            *ptr::mut_offset(buf, len) = b;
+            *ptr::mut_offset(buf, len as int) = b;
         }
         set_len(&mut *s, new_len);
     }
@@ -885,7 +885,7 @@ pub mod raw {
         let v: **mut String = cast::transmute(v);
         let repr = *v;
         (*repr).fill = new_len + 1u;
-        let null = ptr::mut_offset(&mut ((*repr).data), new_len);
+        let null = ptr::mut_offset(&mut ((*repr).data), new_len as int);
         *null = 0u8;
     }
 
@@ -1802,7 +1802,7 @@ impl<'self> StrSlice<'self> for &'self str {
 
                     for nn.times {
                         ptr::copy_memory(rbuf, buf, len);
-                        rbuf = rbuf.offset(len);
+                        rbuf = rbuf.offset(len as int);
                     }
                 }
                 raw::set_len(&mut ret, nn * len);
@@ -1932,7 +1932,7 @@ impl<'self> StrSlice<'self> for &'self str {
         do self.as_imm_buf |buf, len| {
             // NB: len includes the trailing null.
             assert!(len > 0);
-            if unsafe { *(ptr::offset(buf, len - 1)) != 0 } {
+            if unsafe { *(ptr::offset(buf, (len - 1) as int)) != 0 } {
                 self.to_owned().as_c_str(|s| f(s))
             } else {
                 f(buf as *libc::c_char)
@@ -2005,7 +2005,7 @@ impl OwnedStr for ~str {
             self.reserve(llen + rlen);
             do self.as_imm_buf |lbuf, _llen| {
                 do rhs.as_imm_buf |rbuf, _rlen| {
-                    let dst = ptr::offset(lbuf, llen);
+                    let dst = ptr::offset(lbuf, llen as int);
                     let dst = cast::transmute_mut_unsafe(dst);
                     ptr::copy_memory(dst, rbuf, rlen);
                 }
@@ -2023,7 +2023,7 @@ impl OwnedStr for ~str {
             self.reserve_at_least(llen + rlen);
             do self.as_imm_buf |lbuf, _llen| {
                 do rhs.as_imm_buf |rbuf, _rlen| {
-                    let dst = ptr::offset(lbuf, llen);
+                    let dst = ptr::offset(lbuf, llen as int);
                     let dst = cast::transmute_mut_unsafe(dst);
                     ptr::copy_memory(dst, rbuf, rlen);
                 }
@@ -2045,7 +2045,7 @@ impl OwnedStr for ~str {
             let len = self.len();
             let new_len = len + nb;
             self.reserve_at_least(new_len);
-            let off = len;
+            let off = len as int;
             do self.as_mut_buf |buf, _len| {
                 match nb {
                     1u => {
@@ -2053,18 +2053,18 @@ impl OwnedStr for ~str {
                     }
                     2u => {
                         *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8;
-                        *ptr::mut_offset(buf, off + 1u) = (code & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 1) = (code & 63u | TAG_CONT) as u8;
                     }
                     3u => {
                         *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8;
-                        *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 2u) = (code & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 1) = (code >> 6u & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 2) = (code & 63u | TAG_CONT) as u8;
                     }
                     4u => {
                         *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8;
-                        *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 3u) = (code & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 1) = (code >> 12u & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 2) = (code >> 6u & 63u | TAG_CONT) as u8;
+                        *ptr::mut_offset(buf, off + 3) = (code & 63u | TAG_CONT) as u8;
                     }
                     _ => {}
                 }
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 655ede6b4eb..5d6cd594f48 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -321,6 +321,13 @@ extern "rust-intrinsic" {
     /// Get the address of the `__morestack` stack growth function.
     pub fn morestack_addr() -> *();
 
+    /// Adjust a pointer by an offset.
+    ///
+    /// This is implemented as an intrinsic to avoid converting to and from an
+    /// integer, since the conversion would throw away aliasing information.
+    #[cfg(not(stage0))]
+    pub fn offset<T>(dst: *T, offset: int) -> *T;
+
     /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
     pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 19d1d1b1ad0..db57d7bac68 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -98,7 +98,7 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
         let p = raw::to_mut_ptr(v);
         let mut i: uint = 0u;
         while i < n_elts {
-            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
+            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), op(i));
             i += 1u;
         }
         raw::set_len(&mut v, n_elts);
@@ -122,7 +122,7 @@ pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
         let p = raw::to_mut_ptr(v);
         let mut i = 0u;
         while i < n_elts {
-            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), t.clone());
+            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), t.clone());
             i += 1u;
         }
         raw::set_len(&mut v, n_elts);
@@ -781,7 +781,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         do self.as_imm_buf |p, _len| {
             unsafe {
                 cast::transmute(Slice {
-                    data: ptr::offset(p, start),
+                    data: ptr::offset(p, start as int),
                     len: (end - start) * sys::nonzero_size_of::<T>(),
                 })
             }
@@ -993,7 +993,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     /// bounds checking.
     #[inline]
     unsafe fn unsafe_ref(&self, index: uint) -> *T {
-        self.repr().data.offset(index)
+        self.repr().data.offset(index as int)
     }
 
     /**
@@ -1283,14 +1283,14 @@ impl<T> OwnedVector<T> for ~[T] {
             let fill = (**repr).data.fill;
             (**repr).data.fill += sys::nonzero_size_of::<T>();
             let p = to_unsafe_ptr(&((**repr).data.data));
-            let p = ptr::offset(p, fill) as *mut T;
+            let p = ptr::offset(p, fill as int) as *mut T;
             intrinsics::move_val_init(&mut(*p), t);
         } else {
             let repr: **mut Vec<u8> = cast::transmute(self);
             let fill = (**repr).fill;
             (**repr).fill += sys::nonzero_size_of::<T>();
             let p = to_unsafe_ptr(&((**repr).data));
-            let p = ptr::offset(p, fill) as *mut T;
+            let p = ptr::offset(p, fill as int) as *mut T;
             intrinsics::move_val_init(&mut(*p), t);
         }
     }
@@ -1316,7 +1316,7 @@ impl<T> OwnedVector<T> for ~[T] {
         unsafe { // Note: infallible.
             let self_p = vec::raw::to_mut_ptr(*self);
             let rhs_p = vec::raw::to_ptr(rhs);
-            ptr::copy_memory(ptr::mut_offset(self_p, self_len), rhs_p, rhs_len);
+            ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len);
             raw::set_len(self, new_len);
             raw::set_len(&mut rhs, 0);
         }
@@ -1397,7 +1397,7 @@ impl<T> OwnedVector<T> for ~[T] {
 
             // Swap out the element we want from the end
             let vp = raw::to_mut_ptr(*self);
-            let vp = ptr::mut_offset(vp, next_ln - 1);
+            let vp = ptr::mut_offset(vp, (next_ln - 1) as int);
 
             Some(ptr::replace_ptr(vp, work_elt))
         }
@@ -1461,7 +1461,7 @@ impl<T> OwnedVector<T> for ~[T] {
             unsafe {
                 // This loop is optimized out for non-drop types.
                 for uint::range(newlen, oldlen) |i| {
-                    ptr::read_and_zero_ptr(ptr::mut_offset(p, i));
+                    ptr::read_and_zero_ptr(ptr::mut_offset(p, i as int));
                 }
             }
         }
@@ -1680,8 +1680,8 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
             let mut w = 1;
 
             while r < ln {
-                let p_r = ptr::mut_offset(p, r);
-                let p_wm1 = ptr::mut_offset(p, w - 1);
+                let p_r = ptr::mut_offset(p, r as int);
+                let p_wm1 = ptr::mut_offset(p, (w - 1) as int);
                 if *p_r != *p_wm1 {
                     if r != w {
                         let p_w = ptr::mut_offset(p_wm1, 1);
@@ -1748,7 +1748,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
         do self.as_mut_buf |p, _len| {
             unsafe {
                 cast::transmute(Slice {
-                    data: ptr::mut_offset(p, start) as *T,
+                    data: ptr::mut_offset(p, start as int) as *T,
                     len: (end - start) * sys::nonzero_size_of::<T>()
                 })
             }
@@ -1839,7 +1839,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
 
     #[inline]
     unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T {
-        ptr::mut_offset(self.repr().data as *mut T, index)
+        ptr::mut_offset(self.repr().data as *mut T, index as int)
     }
 
     #[inline]
@@ -1969,7 +1969,7 @@ pub mod raw {
      */
     #[inline]
     pub unsafe fn get<T:Clone>(v: &[T], i: uint) -> T {
-        v.as_imm_buf(|p, _len| (*ptr::offset(p, i)).clone())
+        v.as_imm_buf(|p, _len| (*ptr::offset(p, i as int)).clone())
     }
 
     /**
@@ -1981,7 +1981,7 @@ pub mod raw {
     pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
         let mut box = Some(val);
         do v.as_mut_buf |p, _len| {
-            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)),
+            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)),
                                       box.take_unwrap());
         }
     }
@@ -2191,7 +2191,7 @@ impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
     fn idx(&self, index: uint) -> Option<&'self T> {
         unsafe {
             if index < self.indexable() {
-                cast::transmute(self.ptr.offset(index))
+                cast::transmute(self.ptr.offset(index as int))
             } else {
                 None
             }