about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-05-10 15:15:06 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-05-12 16:35:18 -0700
commit5d3559e6455757c5508bba5b5add69477ebac53e (patch)
tree71e166364df7f828c4c98c5853597d2c62c37fac
parent06ef889cdc77db862d526bf6a607ecdf3ee80beb (diff)
downloadrust-5d3559e6455757c5508bba5b5add69477ebac53e.tar.gz
rust-5d3559e6455757c5508bba5b5add69477ebac53e.zip
librustc: Make `self` and `static` into keywords
-rw-r--r--src/libcore/cell.rs12
-rw-r--r--src/libcore/old_iter.rs64
-rw-r--r--src/libcore/rt/sched/mod.rs40
-rw-r--r--src/libcore/rt/uv/net.rs4
-rw-r--r--src/libcore/rt/uvio.rs4
-rw-r--r--src/librustc/driver/driver.rs4
-rw-r--r--src/librustc/driver/session.rs4
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs97
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs77
-rw-r--r--src/librustc/middle/borrowck/mod.rs12
-rw-r--r--src/librustc/middle/dataflow.rs3
-rw-r--r--src/librustc/middle/freevars.rs2
-rw-r--r--src/librustc/middle/liveness.rs146
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc/middle/moves.rs2
-rw-r--r--src/librustc/middle/region.rs6
-rw-r--r--src/librustc/middle/resolve.rs61
-rw-r--r--src/librustc/middle/resolve_stage0.rs61
-rw-r--r--src/librustc/middle/trans/_match.rs6
-rw-r--r--src/librustc/middle/trans/common.rs10
-rw-r--r--src/librustc/middle/trans/expr.rs6
-rw-r--r--src/librustc/middle/trans/meth.rs19
-rw-r--r--src/librustc/middle/trans/type_use.rs2
-rw-r--r--src/librustc/middle/ty.rs2
-rw-r--r--src/librustc/middle/typeck/astconv.rs148
-rw-r--r--src/librustc/middle/typeck/check/mod.rs6
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs2
-rw-r--r--src/librustc/middle/typeck/collect.rs8
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs206
-rw-r--r--src/librustc/middle/typeck/infer/glb.rs22
-rw-r--r--src/librustc/middle/typeck/infer/lattice.rs72
-rw-r--r--src/librustc/middle/typeck/infer/lub.rs8
-rw-r--r--src/librustc/middle/typeck/infer/region_inference.rs24
-rw-r--r--src/librustc/middle/typeck/rscope.rs4
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ext/auto_encode.rs24
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs12
-rw-r--r--src/libsyntax/ext/deriving/mod.rs3
-rw-r--r--src/libsyntax/ext/deriving/ty.rs4
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs4
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/common.rs3
-rw-r--r--src/libsyntax/parse/mod.rs6
-rw-r--r--src/libsyntax/parse/parser.rs65
-rw-r--r--src/libsyntax/parse/token.rs27
-rw-r--r--src/libsyntax/print/pprust.rs1
-rw-r--r--src/libsyntax/visit.rs1
-rw-r--r--src/test/compile-fail/issue-5099.rs2
-rw-r--r--src/test/compile-fail/use-after-move-self-based-on-type.rs2
-rw-r--r--src/test/compile-fail/use-after-move-self.rs2
51 files changed, 700 insertions, 610 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 18e75fb1aa9..6f0e03fb895 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -44,21 +44,21 @@ pub fn empty_cell<T>() -> Cell<T> {
 pub impl<T> Cell<T> {
     /// Yields the value, failing if the cell is empty.
     fn take(&self) -> T {
-        let self = unsafe { transmute_mut(self) };
-        if self.is_empty() {
+        let this = unsafe { transmute_mut(self) };
+        if this.is_empty() {
             fail!(~"attempt to take an empty cell");
         }
 
-        replace(&mut self.value, None).unwrap()
+        replace(&mut this.value, None).unwrap()
     }
 
     /// Returns the value, failing if the cell is full.
     fn put_back(&self, value: T) {
-        let self = unsafe { transmute_mut(self) };
-        if !self.is_empty() {
+        let this = unsafe { transmute_mut(self) };
+        if !this.is_empty() {
             fail!(~"attempt to put a value back into a full cell");
         }
-        self.value = Some(value);
+        this.value = Some(value);
     }
 
     /// Returns true if the cell is empty and false if the cell is full.
diff --git a/src/libcore/old_iter.rs b/src/libcore/old_iter.rs
index a596b07dc78..95bc8872c91 100644
--- a/src/libcore/old_iter.rs
+++ b/src/libcore/old_iter.rs
@@ -116,10 +116,12 @@ pub trait Buildable<A> {
 }
 
 #[inline(always)]
-pub fn _eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
+pub fn _eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
     let mut i = 0;
-    for self.each |a| {
-        if !blk(i, a) { return false; }
+    for this.each |a| {
+        if !blk(i, a) {
+            return false;
+        }
         i += 1;
     }
     return true;
@@ -135,47 +137,47 @@ pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
 }
 
 #[inline(always)]
-pub fn all<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
-    for self.each |a| {
+pub fn all<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
+    for this.each |a| {
         if !blk(a) { return false; }
     }
     return true;
 }
 
 #[inline(always)]
-pub fn any<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
-    for self.each |a| {
+pub fn any<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
+    for this.each |a| {
         if blk(a) { return true; }
     }
     return false;
 }
 
 #[inline(always)]
-pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA,
+pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(this: &IA,
                                             prd: &fn(&A) -> bool)
                                          -> ~[A] {
-    do vec::build_sized_opt(self.size_hint()) |push| {
-        for self.each |a| {
+    do vec::build_sized_opt(this.size_hint()) |push| {
+        for this.each |a| {
             if prd(a) { push(*a); }
         }
     }
 }
 
 #[inline(always)]
-pub fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA, op: &fn(&A) -> B) -> ~[B] {
-    do vec::build_sized_opt(self.size_hint()) |push| {
-        for self.each |a| {
+pub fn map_to_vec<A,B,IA:BaseIter<A>>(this: &IA, op: &fn(&A) -> B) -> ~[B] {
+    do vec::build_sized_opt(this.size_hint()) |push| {
+        for this.each |a| {
             push(op(a));
         }
     }
 }
 
 #[inline(always)]
-pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
+pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(this: &IA,
                                                           op: &fn(&A) -> IB)
                                                        -> ~[B] {
     do vec::build |push| {
-        for self.each |a| {
+        for this.each |a| {
             for op(a).each |&b| {
                 push(b);
             }
@@ -184,31 +186,31 @@ pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
 }
 
 #[inline(always)]
-pub fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B, blk: &fn(&B, &A) -> B)
+pub fn foldl<A,B,IA:BaseIter<A>>(this: &IA, b0: B, blk: &fn(&B, &A) -> B)
                               -> B {
     let mut b = b0;
-    for self.each |a| {
+    for this.each |a| {
         b = blk(&b, a);
     }
     b
 }
 
 #[inline(always)]
-pub fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
-    map_to_vec(self, |&x| x)
+pub fn to_vec<A:Copy,IA:BaseIter<A>>(this: &IA) -> ~[A] {
+    map_to_vec(this, |&x| x)
 }
 
 #[inline(always)]
-pub fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool {
-    for self.each |a| {
+pub fn contains<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> bool {
+    for this.each |a| {
         if *a == *x { return true; }
     }
     return false;
 }
 
 #[inline(always)]
-pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
-    do foldl(self, 0) |count, value| {
+pub fn count<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> uint {
+    do foldl(this, 0) |count, value| {
         if *value == *x {
             *count + 1
         } else {
@@ -218,10 +220,10 @@ pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
 }
 
 #[inline(always)]
-pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
+pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
                                -> Option<uint> {
     let mut i = 0;
-    for self.each |a| {
+    for this.each |a| {
         if f(a) { return Some(i); }
         i += 1;
     }
@@ -253,8 +255,8 @@ pub fn repeat(times: uint, blk: &fn() -> bool) -> bool {
 }
 
 #[inline(always)]
-pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
-    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
+pub fn min<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
+    match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
         match a {
           &Some(ref a_) if *a_ < *b => {
              *(a)
@@ -268,8 +270,8 @@ pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
 }
 
 #[inline(always)]
-pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
-    match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
+pub fn max<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
+    match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
         match a {
           &Some(ref a_) if *a_ > *b => {
               *(a)
@@ -283,9 +285,9 @@ pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
 }
 
 #[inline(always)]
-pub fn find<A:Copy,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
+pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
                                 -> Option<A> {
-    for self.each |i| {
+    for this.each |i| {
         if f(i) { return Some(*i) }
     }
     return None;
diff --git a/src/libcore/rt/sched/mod.rs b/src/libcore/rt/sched/mod.rs
index 663fe3e62d0..ba057254583 100644
--- a/src/libcore/rt/sched/mod.rs
+++ b/src/libcore/rt/sched/mod.rs
@@ -118,15 +118,15 @@ pub impl Scheduler {
     fn resume_task_from_queue(~self) -> bool {
         assert!(!self.in_task_context());
 
-        let mut self = self;
-        match self.task_queue.pop_front() {
+        let mut this = self;
+        match this.task_queue.pop_front() {
             Some(task) => {
-                self.resume_task_immediately(task);
+                this.resume_task_immediately(task);
                 return true;
             }
             None => {
                 rtdebug!("no tasks in queue");
-                local_sched::put(self);
+                local_sched::put(this);
                 return false;
             }
         }
@@ -165,16 +165,16 @@ pub impl Scheduler {
     // Core scheduling ops
 
     fn resume_task_immediately(~self, task: ~Task) {
-        let mut self = self;
-        assert!(!self.in_task_context());
+        let mut this = self;
+        assert!(!this.in_task_context());
 
         rtdebug!("scheduling a task");
 
         // Store the task in the scheduler so it can be grabbed later
-        self.current_task = Some(task);
-        self.enqueue_cleanup_job(DoNothing);
+        this.current_task = Some(task);
+        this.enqueue_cleanup_job(DoNothing);
 
-        local_sched::put(self);
+        local_sched::put(this);
 
         // Take pointers to both the task and scheduler's saved registers.
         unsafe {
@@ -203,17 +203,17 @@ pub impl Scheduler {
     /// running task.  It gets transmuted to the scheduler's lifetime
     /// and called while the task is blocked.
     fn deschedule_running_task_and_then(~self, f: &fn(~Task)) {
-        let mut self = self;
-        assert!(self.in_task_context());
+        let mut this = self;
+        assert!(this.in_task_context());
 
         rtdebug!("blocking task");
 
-        let blocked_task = self.current_task.swap_unwrap();
+        let blocked_task = this.current_task.swap_unwrap();
         let f_fake_region = unsafe { transmute::<&fn(~Task), &fn(~Task)>(f) };
         let f_opaque = ClosureConverter::from_fn(f_fake_region);
-        self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque));
+        this.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque));
 
-        local_sched::put(self);
+        local_sched::put(this);
 
         let sched = unsafe { local_sched::unsafe_borrow() };
         let (sched_context, last_task_context, _) = sched.get_contexts();
@@ -229,18 +229,18 @@ pub impl Scheduler {
     /// You would want to think hard about doing this, e.g. if there are
     /// pending I/O events it would be a bad idea.
     fn switch_running_tasks_and_then(~self, next_task: ~Task, f: &fn(~Task)) {
-        let mut self = self;
-        assert!(self.in_task_context());
+        let mut this = self;
+        assert!(this.in_task_context());
 
         rtdebug!("switching tasks");
 
-        let old_running_task = self.current_task.swap_unwrap();
+        let old_running_task = this.current_task.swap_unwrap();
         let f_fake_region = unsafe { transmute::<&fn(~Task), &fn(~Task)>(f) };
         let f_opaque = ClosureConverter::from_fn(f_fake_region);
-        self.enqueue_cleanup_job(GiveTask(old_running_task, f_opaque));
-        self.current_task = Some(next_task);
+        this.enqueue_cleanup_job(GiveTask(old_running_task, f_opaque));
+        this.current_task = Some(next_task);
 
-        local_sched::put(self);
+        local_sched::put(this);
 
         unsafe {
             let sched = local_sched::unsafe_borrow();
diff --git a/src/libcore/rt/uv/net.rs b/src/libcore/rt/uv/net.rs
index 068d6db2a43..376231e3b27 100644
--- a/src/libcore/rt/uv/net.rs
+++ b/src/libcore/rt/uv/net.rs
@@ -141,8 +141,8 @@ pub impl StreamWatcher {
 
     fn close(self, cb: NullCallback) {
         {
-            let mut self = self;
-            let data = get_watcher_data(&mut self);
+            let mut this = self;
+            let data = get_watcher_data(&mut this);
             assert!(data.close_cb.is_none());
             data.close_cb = Some(cb);
         }
diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs
index 62a165b6d77..8f1a6ea0d34 100644
--- a/src/libcore/rt/uvio.rs
+++ b/src/libcore/rt/uvio.rs
@@ -43,10 +43,10 @@ pub impl UvEventLoop {
 impl Drop for UvEventLoop {
     fn finalize(&self) {
         // XXX: Need mutable finalizer
-        let self = unsafe {
+        let this = unsafe {
             transmute::<&UvEventLoop, &mut UvEventLoop>(self)
         };
-        self.uvio.uv_loop().close();
+        this.uvio.uv_loop().close();
     }
 }
 
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 904a7ccb13f..f54879b36bd 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -632,7 +632,7 @@ pub fn build_session_options(binary: @~str,
     let extra_debuginfo = debugging_opts & session::extra_debug_info != 0;
     let debuginfo = debugging_opts & session::debug_info != 0 ||
         extra_debuginfo;
-    let static = debugging_opts & session::static != 0;
+    let statik = debugging_opts & session::statik != 0;
     let target =
         match target_opt {
             None => host_triple(),
@@ -660,7 +660,7 @@ pub fn build_session_options(binary: @~str,
 
     let sopts = @session::options {
         crate_type: crate_type,
-        is_static: static,
+        is_static: statik,
         gc: gc,
         optimize: opt_level,
         debuginfo: debuginfo,
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 92cdcff65d5..16eec0b10de 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -62,7 +62,7 @@ pub static gc: uint = 1 << 18;
 pub static jit: uint = 1 << 19;
 pub static debug_info: uint = 1 << 20;
 pub static extra_debug_info: uint = 1 << 21;
-pub static static: uint = 1 << 22;
+pub static statik: uint = 1 << 22;
 pub static print_link_args: uint = 1 << 23;
 
 pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
@@ -98,7 +98,7 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
       extra_debug_info),
      (~"debug-info", ~"Produce debug info (experimental)", debug_info),
      (~"static", ~"Use or produce static libraries or binaries " +
-      "(experimental)", static)
+      "(experimental)", statik)
     ]
 }
 
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 2f116cb1b28..2f24a8ceb24 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -359,7 +359,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
                 self, expr, cmt);
         }
 
-        fn mark_variable_as_used_mut(self: &CheckLoanCtxt,
+        fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
                                      cmt: mc::cmt) {
             //! If the mutability of the `cmt` being written is inherited
             //! from a local variable, liveness will
@@ -370,12 +370,12 @@ pub impl<'self> CheckLoanCtxt<'self> {
             let mut cmt = cmt;
             loop {
                 debug!("mark_writes_through_upvars_as_used_mut(cmt=%s)",
-                       cmt.repr(self.tcx()));
+                       cmt.repr(this.tcx()));
                 match cmt.cat {
                     mc::cat_local(id) |
                     mc::cat_arg(id) |
                     mc::cat_self(id) => {
-                        self.tcx().used_mut_nodes.insert(id);
+                        this.tcx().used_mut_nodes.insert(id);
                         return;
                     }
 
@@ -411,14 +411,14 @@ pub impl<'self> CheckLoanCtxt<'self> {
             }
         }
 
-        fn check_for_aliasable_mutable_writes(self: &CheckLoanCtxt,
+        fn check_for_aliasable_mutable_writes(this: &CheckLoanCtxt,
                                               expr: @ast::expr,
                                               cmt: mc::cmt) -> bool {
             //! Safety checks related to writes to aliasable, mutable locations
 
             let guarantor = cmt.guarantor();
             debug!("check_for_aliasable_mutable_writes(cmt=%s, guarantor=%s)",
-                   cmt.repr(self.tcx()), guarantor.repr(self.tcx()));
+                   cmt.repr(this.tcx()), guarantor.repr(this.tcx()));
             match guarantor.cat {
                 mc::cat_deref(b, _, mc::region_ptr(m_mutbl, _)) => {
                     // Statically prohibit writes to `&mut` when aliasable
@@ -426,7 +426,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
                     match b.freely_aliasable() {
                         None => {}
                         Some(cause) => {
-                            self.bccx.report_aliasability_violation(
+                            this.bccx.report_aliasability_violation(
                                 expr.span,
                                 MutabilityViolation,
                                 cause);
@@ -442,7 +442,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
                         derefs: deref_count
                     };
                     debug!("Inserting write guard at %?", key);
-                    self.bccx.write_guard_map.insert(key);
+                    this.bccx.write_guard_map.insert(key);
                 }
 
                 _ => {}
@@ -452,7 +452,7 @@ pub impl<'self> CheckLoanCtxt<'self> {
         }
 
         fn check_for_assignment_to_restricted_or_frozen_location(
-            self: &CheckLoanCtxt,
+            this: &CheckLoanCtxt,
             expr: @ast::expr,
             cmt: mc::cmt) -> bool
         {
@@ -494,11 +494,11 @@ pub impl<'self> CheckLoanCtxt<'self> {
             // `RESTR_MUTATE` restriction whenever the contents of an
             // owned pointer are borrowed, and hence while `v[*]` is not
             // restricted from being written, `v` is.
-            for self.each_in_scope_restriction(expr.id, loan_path)
+            for this.each_in_scope_restriction(expr.id, loan_path)
                 |loan, restr|
             {
                 if restr.set.intersects(RESTR_MUTATE) {
-                    self.report_illegal_mutation(expr, loan_path, loan);
+                    this.report_illegal_mutation(expr, loan_path, loan);
                     return false;
                 }
             }
@@ -557,9 +557,9 @@ pub impl<'self> CheckLoanCtxt<'self> {
                 }
 
                 // Check for a non-const loan of `loan_path`
-                for self.each_in_scope_loan(expr.id) |loan| {
+                for this.each_in_scope_loan(expr.id) |loan| {
                     if loan.loan_path == loan_path && loan.mutbl != m_const {
-                        self.report_illegal_mutation(expr, full_loan_path, loan);
+                        this.report_illegal_mutation(expr, full_loan_path, loan);
                         return false;
                     }
                 }
@@ -674,7 +674,7 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
                          body: &ast::blk,
                          sp: span,
                          id: ast::node_id,
-                         self: @mut CheckLoanCtxt<'a>,
+                         this: @mut CheckLoanCtxt<'a>,
                          visitor: visit::vt<@mut CheckLoanCtxt<'a>>) {
     match *fk {
         visit::fk_item_fn(*) |
@@ -685,48 +685,48 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
 
         visit::fk_anon(*) |
         visit::fk_fn_block(*) => {
-            let fty = ty::node_id_to_type(self.tcx(), id);
+            let fty = ty::node_id_to_type(this.tcx(), id);
             let fty_sigil = ty::ty_closure_sigil(fty);
-            check_moves_from_captured_variables(self, id, fty_sigil);
+            check_moves_from_captured_variables(this, id, fty_sigil);
         }
     }
 
-    visit::visit_fn(fk, decl, body, sp, id, self, visitor);
+    visit::visit_fn(fk, decl, body, sp, id, this, visitor);
 
-    fn check_moves_from_captured_variables(self: @mut CheckLoanCtxt,
+    fn check_moves_from_captured_variables(this: @mut CheckLoanCtxt,
                                            id: ast::node_id,
                                            fty_sigil: ast::Sigil) {
         match fty_sigil {
             ast::ManagedSigil | ast::OwnedSigil => {
-                let cap_vars = self.bccx.capture_map.get(&id);
+                let cap_vars = this.bccx.capture_map.get(&id);
                 for cap_vars.each |cap_var| {
                     match cap_var.mode {
                         moves::CapRef | moves::CapCopy => { loop; }
                         moves::CapMove => { }
                     }
                     let def_id = ast_util::def_id_of_def(cap_var.def).node;
-                    let ty = ty::node_id_to_type(self.tcx(), def_id);
-                    let cmt = self.bccx.cat_def(id, cap_var.span,
+                    let ty = ty::node_id_to_type(this.tcx(), def_id);
+                    let cmt = this.bccx.cat_def(id, cap_var.span,
                                                 ty, cap_var.def);
-                    let move_err = self.analyze_move_out_from_cmt(cmt);
+                    let move_err = this.analyze_move_out_from_cmt(cmt);
                     match move_err {
                         MoveOk => {}
                         MoveFromIllegalCmt(move_cmt) => {
-                            self.bccx.span_err(
+                            this.bccx.span_err(
                                 cap_var.span,
                                 fmt!("illegal by-move capture of %s",
-                                     self.bccx.cmt_to_str(move_cmt)));
+                                     this.bccx.cmt_to_str(move_cmt)));
                         }
                         MoveWhileBorrowed(loan_path, loan_span) => {
-                            self.bccx.span_err(
+                            this.bccx.span_err(
                                 cap_var.span,
                                 fmt!("cannot move `%s` into closure \
                                       because it is borrowed",
-                                     self.bccx.loan_path_to_str(loan_path)));
-                            self.bccx.span_note(
+                                     this.bccx.loan_path_to_str(loan_path)));
+                            this.bccx.span_note(
                                 loan_span,
                                 fmt!("borrow of `%s` occurs here",
-                                     self.bccx.loan_path_to_str(loan_path)));
+                                     this.bccx.loan_path_to_str(loan_path)));
                         }
                     }
                 }
@@ -738,48 +738,48 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
 }
 
 fn check_loans_in_local<'a>(local: @ast::local,
-                            self: @mut CheckLoanCtxt<'a>,
+                            this: @mut CheckLoanCtxt<'a>,
                             vt: visit::vt<@mut CheckLoanCtxt<'a>>) {
-    visit::visit_local(local, self, vt);
+    visit::visit_local(local, this, vt);
 }
 
 fn check_loans_in_expr<'a>(expr: @ast::expr,
-                           self: @mut CheckLoanCtxt<'a>,
+                           this: @mut CheckLoanCtxt<'a>,
                            vt: visit::vt<@mut CheckLoanCtxt<'a>>) {
     debug!("check_loans_in_expr(expr=%s)",
-           expr.repr(self.tcx()));
+           expr.repr(this.tcx()));
 
-    visit::visit_expr(expr, self, vt);
+    visit::visit_expr(expr, this, vt);
 
-    self.check_for_conflicting_loans(expr.id);
+    this.check_for_conflicting_loans(expr.id);
 
-    if self.bccx.moves_map.contains(&expr.id) {
-        self.check_move_out_from_expr(expr);
+    if this.bccx.moves_map.contains(&expr.id) {
+        this.check_move_out_from_expr(expr);
     }
 
     match expr.node {
       ast::expr_assign(dest, _) |
       ast::expr_assign_op(_, dest, _) => {
-        self.check_assignment(dest);
+        this.check_assignment(dest);
       }
       ast::expr_call(f, ref args, _) => {
-        self.check_call(expr, Some(f), f.id, f.span, *args);
+        this.check_call(expr, Some(f), f.id, f.span, *args);
       }
       ast::expr_method_call(_, _, _, ref args, _) => {
-        self.check_call(expr, None, expr.callee_id, expr.span, *args);
+        this.check_call(expr, None, expr.callee_id, expr.span, *args);
       }
       ast::expr_index(_, rval) |
       ast::expr_binary(_, _, rval)
-      if self.bccx.method_map.contains_key(&expr.id) => {
-        self.check_call(expr,
+      if this.bccx.method_map.contains_key(&expr.id) => {
+        this.check_call(expr,
                         None,
                         expr.callee_id,
                         expr.span,
                         ~[rval]);
       }
       ast::expr_unary(*) | ast::expr_index(*)
-      if self.bccx.method_map.contains_key(&expr.id) => {
-        self.check_call(expr,
+      if this.bccx.method_map.contains_key(&expr.id) => {
+        this.check_call(expr,
                         None,
                         expr.callee_id,
                         expr.span,
@@ -790,10 +790,10 @@ fn check_loans_in_expr<'a>(expr: @ast::expr,
 }
 
 fn check_loans_in_pat<'a>(pat: @ast::pat,
-                          self: @mut CheckLoanCtxt<'a>,
+                          this: @mut CheckLoanCtxt<'a>,
                           vt: visit::vt<@mut CheckLoanCtxt<'a>>)
 {
-    self.check_for_conflicting_loans(pat.id);
+    this.check_for_conflicting_loans(pat.id);
 
     // Note: moves out of pattern bindings are not checked by
     // the borrow checker, at least not directly.  What happens
@@ -806,13 +806,14 @@ fn check_loans_in_pat<'a>(pat: @ast::pat,
     // rewalk the patterns and rebuild the pattern
     // categorizations.
 
-    visit::visit_pat(pat, self, vt);
+    visit::visit_pat(pat, this, vt);
 }
 
 fn check_loans_in_block<'a>(blk: &ast::blk,
-                            self: @mut CheckLoanCtxt<'a>,
+                            this: @mut CheckLoanCtxt<'a>,
                             vt: visit::vt<@mut CheckLoanCtxt<'a>>)
 {
-    visit::visit_block(blk, self, vt);
-    self.check_for_conflicting_loans(blk.node.id);
+    visit::visit_block(blk, this, vt);
+    this.check_for_conflicting_loans(blk.node.id);
 }
+
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 94a029911a8..64d32d713d0 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -90,14 +90,14 @@ pub fn gather_loans(bccx: @BorrowckCtxt,
 }
 
 fn add_pat_to_id_range(p: @ast::pat,
-                       self: @mut GatherLoanCtxt,
+                       this: @mut GatherLoanCtxt,
                        v: visit::vt<@mut GatherLoanCtxt>) {
     // NB: This visitor function just adds the pat ids into the id
     // range. We gather loans that occur in patterns using the
     // `gather_pat()` method below. Eventually these two should be
     // brought together.
-    self.id_range.add(p.id);
-    visit::visit_pat(p, self, v);
+    this.id_range.add(p.id);
+    visit::visit_pat(p, this, v);
 }
 
 fn gather_loans_in_fn(fk: &visit::fn_kind,
@@ -105,7 +105,7 @@ fn gather_loans_in_fn(fk: &visit::fn_kind,
                       body: &ast::blk,
                       sp: span,
                       id: ast::node_id,
-                      self: @mut GatherLoanCtxt,
+                      this: @mut GatherLoanCtxt,
                       v: visit::vt<@mut GatherLoanCtxt>) {
     match fk {
         // Do not visit items here, the outer loop in borrowck/mod
@@ -116,95 +116,95 @@ fn gather_loans_in_fn(fk: &visit::fn_kind,
 
         // Visit closures as part of the containing item.
         &visit::fk_anon(*) | &visit::fk_fn_block(*) => {
-            self.push_repeating_id(body.node.id);
-            visit::visit_fn(fk, decl, body, sp, id, self, v);
-            self.pop_repeating_id(body.node.id);
+            this.push_repeating_id(body.node.id);
+            visit::visit_fn(fk, decl, body, sp, id, this, v);
+            this.pop_repeating_id(body.node.id);
         }
     }
 }
 
 fn gather_loans_in_block(blk: &ast::blk,
-                         self: @mut GatherLoanCtxt,
+                         this: @mut GatherLoanCtxt,
                          vt: visit::vt<@mut GatherLoanCtxt>) {
-    self.id_range.add(blk.node.id);
-    visit::visit_block(blk, self, vt);
+    this.id_range.add(blk.node.id);
+    visit::visit_block(blk, this, vt);
 }
 
 fn gather_loans_in_expr(ex: @ast::expr,
-                        self: @mut GatherLoanCtxt,
+                        this: @mut GatherLoanCtxt,
                         vt: visit::vt<@mut GatherLoanCtxt>) {
-    let bccx = self.bccx;
+    let bccx = this.bccx;
     let tcx = bccx.tcx;
 
     debug!("gather_loans_in_expr(expr=%?/%s)",
            ex.id, pprust::expr_to_str(ex, tcx.sess.intr()));
 
-    self.id_range.add(ex.id);
-    self.id_range.add(ex.callee_id);
+    this.id_range.add(ex.id);
+    this.id_range.add(ex.callee_id);
 
     // If this expression is borrowed, have to ensure it remains valid:
     for tcx.adjustments.find(&ex.id).each |&adjustments| {
-        self.guarantee_adjustments(ex, *adjustments);
+        this.guarantee_adjustments(ex, *adjustments);
     }
 
     // Special checks for various kinds of expressions:
     match ex.node {
       ast::expr_addr_of(mutbl, base) => {
-        let base_cmt = self.bccx.cat_expr(base);
+        let base_cmt = this.bccx.cat_expr(base);
 
         // make sure that the thing we are pointing out stays valid
         // for the lifetime `scope_r` of the resulting ptr:
         let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex));
-        self.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
-        visit::visit_expr(ex, self, vt);
+        this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
+        visit::visit_expr(ex, this, vt);
       }
 
       ast::expr_match(ex_v, ref arms) => {
-        let cmt = self.bccx.cat_expr(ex_v);
+        let cmt = this.bccx.cat_expr(ex_v);
         for arms.each |arm| {
             for arm.pats.each |pat| {
-                self.gather_pat(cmt, *pat, arm.body.node.id, ex.id);
+                this.gather_pat(cmt, *pat, arm.body.node.id, ex.id);
             }
         }
-        visit::visit_expr(ex, self, vt);
+        visit::visit_expr(ex, this, vt);
       }
 
       ast::expr_index(_, arg) |
       ast::expr_binary(_, _, arg)
-      if self.bccx.method_map.contains_key(&ex.id) => {
+      if this.bccx.method_map.contains_key(&ex.id) => {
           // Arguments in method calls are always passed by ref.
           //
           // Currently these do not use adjustments, so we have to
           // hardcode this check here (note that the receiver DOES use
           // adjustments).
           let scope_r = ty::re_scope(ex.id);
-          let arg_cmt = self.bccx.cat_expr(arg);
-          self.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
-          visit::visit_expr(ex, self, vt);
+          let arg_cmt = this.bccx.cat_expr(arg);
+          this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
+          visit::visit_expr(ex, this, vt);
       }
 
       // see explanation attached to the `root_ub` field:
       ast::expr_while(cond, ref body) => {
           // during the condition, can only root for the condition
-          self.push_repeating_id(cond.id);
-          (vt.visit_expr)(cond, self, vt);
-          self.pop_repeating_id(cond.id);
+          this.push_repeating_id(cond.id);
+          (vt.visit_expr)(cond, this, vt);
+          this.pop_repeating_id(cond.id);
 
           // during body, can only root for the body
-          self.push_repeating_id(body.node.id);
-          (vt.visit_block)(body, self, vt);
-          self.pop_repeating_id(body.node.id);
+          this.push_repeating_id(body.node.id);
+          (vt.visit_block)(body, this, vt);
+          this.pop_repeating_id(body.node.id);
       }
 
       // see explanation attached to the `root_ub` field:
       ast::expr_loop(ref body, _) => {
-          self.push_repeating_id(body.node.id);
-          visit::visit_expr(ex, self, vt);
-          self.pop_repeating_id(body.node.id);
+          this.push_repeating_id(body.node.id);
+          visit::visit_expr(ex, this, vt);
+          this.pop_repeating_id(body.node.id);
       }
 
       _ => {
-        visit::visit_expr(ex, self, vt);
+        visit::visit_expr(ex, this, vt);
       }
     }
 }
@@ -624,13 +624,14 @@ pub impl GatherLoanCtxt {
 // Setting up info that preserve needs.
 // This is just the most convenient place to do it.
 fn add_stmt_to_map(stmt: @ast::stmt,
-                   self: @mut GatherLoanCtxt,
+                   this: @mut GatherLoanCtxt,
                    vt: visit::vt<@mut GatherLoanCtxt>) {
     match stmt.node {
         ast::stmt_expr(_, id) | ast::stmt_semi(_, id) => {
-            self.bccx.stmt_map.insert(id);
+            this.bccx.stmt_map.insert(id);
         }
         _ => ()
     }
-    visit::visit_stmt(stmt, self, vt);
+    visit::visit_stmt(stmt, this, vt);
 }
+
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index fbc186a6fd4..0f01b2b1e41 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -110,7 +110,7 @@ fn borrowck_fn(fk: &visit::fn_kind,
                body: &ast::blk,
                sp: span,
                id: ast::node_id,
-               self: @BorrowckCtxt,
+               this: @BorrowckCtxt,
                v: visit::vt<@BorrowckCtxt>) {
     match fk {
         &visit::fk_anon(*) |
@@ -124,11 +124,11 @@ fn borrowck_fn(fk: &visit::fn_kind,
 
             // Check the body of fn items.
             let (id_range, all_loans) =
-                gather_loans::gather_loans(self, body);
+                gather_loans::gather_loans(this, body);
             let all_loans: &~[Loan] = &*all_loans; // FIXME(#5074)
             let mut dfcx =
-                DataFlowContext::new(self.tcx,
-                                     self.method_map,
+                DataFlowContext::new(this.tcx,
+                                     this.method_map,
                                      LoanDataFlowOperator,
                                      id_range,
                                      all_loans.len());
@@ -137,11 +137,11 @@ fn borrowck_fn(fk: &visit::fn_kind,
                 dfcx.add_kill(loan.kill_scope, loan_idx);
             }
             dfcx.propagate(body);
-            check_loans::check_loans(self, &dfcx, *all_loans, body);
+            check_loans::check_loans(this, &dfcx, *all_loans, body);
         }
     }
 
-    visit::visit_fn(fk, decl, body, sp, id, self, v);
+    visit::visit_fn(fk, decl, body, sp, id, this, v);
 }
 
 // ----------------------------------------------------------------------
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index dc08fb39ad9..31d22b76800 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -753,7 +753,8 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
             }
 
             ast::expr_lit(*) |
-            ast::expr_path(*) => {
+            ast::expr_path(*) |
+            ast::expr_self => {
             }
 
             ast::expr_addr_of(_, e) |
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index 419b75a2ad9..98cc8cc014f 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -45,7 +45,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk)
         |expr, depth, v| {
             match expr.node {
               ast::expr_fn_block(*) => visit::visit_expr(expr, depth + 1, v),
-              ast::expr_path(*) => {
+              ast::expr_path(*) | ast::expr_self => {
                   let mut i = 0;
                   match def_map.find(&expr.id) {
                     None => fail!(~"path not found"),
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 52274f3d305..171048eac55 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -341,11 +341,11 @@ pub impl IrMaps {
     }
 }
 
-fn visit_item(item: @item, self: @mut IrMaps, v: vt<@mut IrMaps>) {
-    let old_cur_item = self.cur_item;
-    self.cur_item = item.id;
-    visit::visit_item(item, self, v);
-    self.cur_item = old_cur_item;
+fn visit_item(item: @item, this: @mut IrMaps, v: vt<@mut IrMaps>) {
+    let old_cur_item = this.cur_item;
+    this.cur_item = item.id;
+    visit::visit_item(item, this, v);
+    this.cur_item = old_cur_item;
 }
 
 fn visit_fn(fk: &visit::fn_kind,
@@ -353,24 +353,24 @@ fn visit_fn(fk: &visit::fn_kind,
             body: &blk,
             sp: span,
             id: node_id,
-            self: @mut IrMaps,
+            this: @mut IrMaps,
             v: vt<@mut IrMaps>) {
     debug!("visit_fn: id=%d", id);
     let _i = ::util::common::indenter();
 
     // swap in a new set of IR maps for this function body:
-    let fn_maps = @mut IrMaps(self.tcx,
-                              self.method_map,
-                              self.variable_moves_map,
-                              self.capture_map,
-                              self.cur_item);
+    let fn_maps = @mut IrMaps(this.tcx,
+                              this.method_map,
+                              this.variable_moves_map,
+                              this.capture_map,
+                              this.cur_item);
 
     unsafe {
         debug!("creating fn_maps: %x", transmute(&*fn_maps));
     }
 
     for decl.inputs.each |arg| {
-        do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
+        do pat_util::pat_bindings(this.tcx.def_map, arg.pat)
                 |_bm, arg_id, _x, path| {
             debug!("adding argument %d", arg_id);
             let ident = ast_util::path_to_ident(path);
@@ -378,7 +378,7 @@ fn visit_fn(fk: &visit::fn_kind,
         }
     };
 
-    // Add `self`, whether explicit or implicit.
+    // Add `this`, whether explicit or implicit.
     match *fk {
         fk_method(_, _, method) => {
             match method.self_ty.node {
@@ -423,35 +423,35 @@ fn visit_fn(fk: &visit::fn_kind,
     lsets.warn_about_unused_args(decl, entry_ln);
 }
 
-fn visit_local(local: @local, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
-    let def_map = self.tcx.def_map;
+fn visit_local(local: @local, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
+    let def_map = this.tcx.def_map;
     do pat_util::pat_bindings(def_map, local.node.pat) |_bm, p_id, sp, path| {
         debug!("adding local variable %d", p_id);
         let name = ast_util::path_to_ident(path);
-        self.add_live_node_for_node(p_id, VarDefNode(sp));
+        this.add_live_node_for_node(p_id, VarDefNode(sp));
         let kind = match local.node.init {
           Some(_) => FromLetWithInitializer,
           None => FromLetNoInitializer
         };
-        self.add_variable(Local(LocalInfo {
+        this.add_variable(Local(LocalInfo {
           id: p_id,
           ident: name,
           is_mutbl: local.node.is_mutbl,
           kind: kind
         }));
     }
-    visit::visit_local(local, self, vt);
+    visit::visit_local(local, this, vt);
 }
 
-fn visit_arm(arm: &arm, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
-    let def_map = self.tcx.def_map;
+fn visit_arm(arm: &arm, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
+    let def_map = this.tcx.def_map;
     for arm.pats.each |pat| {
         do pat_util::pat_bindings(def_map, *pat) |bm, p_id, sp, path| {
             debug!("adding local variable %d from match with bm %?",
                    p_id, bm);
             let name = ast_util::path_to_ident(path);
-            self.add_live_node_for_node(p_id, VarDefNode(sp));
-            self.add_variable(Local(LocalInfo {
+            this.add_live_node_for_node(p_id, VarDefNode(sp));
+            this.add_variable(Local(LocalInfo {
                 id: p_id,
                 ident: name,
                 is_mutbl: false,
@@ -459,35 +459,35 @@ fn visit_arm(arm: &arm, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
             }));
         }
     }
-    visit::visit_arm(arm, self, vt);
+    visit::visit_arm(arm, this, vt);
 }
 
-fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
+fn visit_expr(expr: @expr, this: @mut IrMaps, vt: vt<@mut IrMaps>) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
-      expr_path(_) => {
-        let def = self.tcx.def_map.get_copy(&expr.id);
+      expr_path(_) | expr_self => {
+        let def = this.tcx.def_map.get_copy(&expr.id);
         debug!("expr %d: path that leads to %?", expr.id, def);
         if moves::moved_variable_node_id_from_def(def).is_some() {
-            self.add_live_node_for_node(expr.id, ExprNode(expr.span));
+            this.add_live_node_for_node(expr.id, ExprNode(expr.span));
         }
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
       expr_fn_block(*) => {
         // Interesting control flow (for loops can contain labeled
         // breaks or continues)
-        self.add_live_node_for_node(expr.id, ExprNode(expr.span));
+        this.add_live_node_for_node(expr.id, ExprNode(expr.span));
 
         // Make a live_node for each captured variable, with the span
         // being the location that the variable is used.  This results
         // in better error messages than just pointing at the closure
         // construction site.
-        let cvs = self.capture_map.get(&expr.id);
+        let cvs = this.capture_map.get(&expr.id);
         let mut call_caps = ~[];
         for cvs.each |cv| {
             match moves::moved_variable_node_id_from_def(cv.def) {
               Some(rv) => {
-                let cv_ln = self.add_live_node(FreeVarNode(cv.span));
+                let cv_ln = this.add_live_node(FreeVarNode(cv.span));
                 let is_move = match cv.mode {
                     // var must be dead afterwards
                     moves::CapMove => true,
@@ -502,19 +502,19 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
               None => {}
             }
         }
-        self.set_captures(expr.id, call_caps);
+        this.set_captures(expr.id, call_caps);
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       // live nodes required for interesting control flow:
       expr_if(*) | expr_match(*) | expr_while(*) | expr_loop(*) => {
-        self.add_live_node_for_node(expr.id, ExprNode(expr.span));
-        visit::visit_expr(expr, self, vt);
+        this.add_live_node_for_node(expr.id, ExprNode(expr.span));
+        visit::visit_expr(expr, this, vt);
       }
       expr_binary(op, _, _) if ast_util::lazy_binop(op) => {
-        self.add_live_node_for_node(expr.id, ExprNode(expr.span));
-        visit::visit_expr(expr, self, vt);
+        this.add_live_node_for_node(expr.id, ExprNode(expr.span));
+        visit::visit_expr(expr, this, vt);
       }
 
       // otherwise, live nodes are not required:
@@ -526,7 +526,7 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
       expr_assign(*) | expr_assign_op(*) | expr_mac(*) |
       expr_struct(*) | expr_repeat(*) | expr_paren(*) |
       expr_inline_asm(*) => {
-          visit::visit_expr(expr, self, vt);
+          visit::visit_expr(expr, this, vt);
       }
     }
 }
@@ -1006,7 +1006,7 @@ pub impl Liveness {
         match expr.node {
           // Interesting cases with control flow or which gen/kill
 
-          expr_path(_) => {
+          expr_path(_) | expr_self => {
               self.access_path(expr, succ, ACC_READ | ACC_USE)
           }
 
@@ -1409,13 +1409,13 @@ pub impl Liveness {
 // _______________________________________________________________________
 // Checking for error conditions
 
-fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
+fn check_local(local: @local, this: @Liveness, vt: vt<@Liveness>) {
     match local.node.init {
       Some(_) => {
 
         // Initializer:
-        self.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
-        self.check_for_reassignments_in_pat(local.node.pat,
+        this.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
+        this.check_for_reassignments_in_pat(local.node.pat,
                                             local.node.is_mutbl);
       }
       None => {
@@ -1424,12 +1424,12 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
         // should not be live at this point.
 
         debug!("check_local() with no initializer");
-        do self.pat_bindings(local.node.pat) |ln, var, sp, id| {
-            if !self.warn_about_unused(sp, id, ln, var) {
-                match self.live_on_exit(ln, var) {
+        do this.pat_bindings(local.node.pat) |ln, var, sp, id| {
+            if !this.warn_about_unused(sp, id, ln, var) {
+                match this.live_on_exit(ln, var) {
                   None => { /* not live: good */ }
                   Some(lnk) => {
-                    self.report_illegal_read(
+                    this.report_illegal_read(
                         local.span, lnk, var,
                         PossiblyUninitializedVariable);
                   }
@@ -1439,77 +1439,77 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
       }
     }
 
-    visit::visit_local(local, self, vt);
+    visit::visit_local(local, this, vt);
 }
 
-fn check_arm(arm: &arm, self: @Liveness, vt: vt<@Liveness>) {
-    do self.arm_pats_bindings(arm.pats) |ln, var, sp, id| {
-        self.warn_about_unused(sp, id, ln, var);
+fn check_arm(arm: &arm, this: @Liveness, vt: vt<@Liveness>) {
+    do this.arm_pats_bindings(arm.pats) |ln, var, sp, id| {
+        this.warn_about_unused(sp, id, ln, var);
     }
-    visit::visit_arm(arm, self, vt);
+    visit::visit_arm(arm, this, vt);
 }
 
-fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) {
+fn check_expr(expr: @expr, this: @Liveness, vt: vt<@Liveness>) {
     match expr.node {
-      expr_path(_) => {
-        for self.variable_from_def_map(expr.id, expr.span).each |var| {
-            let ln = self.live_node(expr.id, expr.span);
+      expr_path(_) | expr_self => {
+        for this.variable_from_def_map(expr.id, expr.span).each |var| {
+            let ln = this.live_node(expr.id, expr.span);
 
-            match self.ir.variable_moves_map.find(&expr.id) {
+            match this.ir.variable_moves_map.find(&expr.id) {
                 None => {}
                 Some(&entire_expr) => {
                     debug!("(checking expr) is a move: `%s`",
-                           expr_to_str(expr, self.tcx.sess.intr()));
-                    self.check_move_from_var(ln, *var, entire_expr);
+                           expr_to_str(expr, this.tcx.sess.intr()));
+                    this.check_move_from_var(ln, *var, entire_expr);
                 }
             }
         }
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       expr_fn_block(*) => {
-        let caps = self.ir.captures(expr);
+        let caps = this.ir.captures(expr);
         for caps.each |cap| {
-            let var = self.variable(cap.var_nid, expr.span);
+            let var = this.variable(cap.var_nid, expr.span);
             if cap.is_move {
-                self.check_move_from_var(cap.ln, var, expr);
+                this.check_move_from_var(cap.ln, var, expr);
             }
         }
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       expr_assign(l, r) => {
-        self.check_lvalue(l, vt);
-        (vt.visit_expr)(r, self, vt);
+        this.check_lvalue(l, vt);
+        (vt.visit_expr)(r, this, vt);
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       expr_assign_op(_, l, _) => {
-        self.check_lvalue(l, vt);
+        this.check_lvalue(l, vt);
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       expr_inline_asm(ref ia) => {
         for ia.inputs.each |&(_, in)| {
-          (vt.visit_expr)(in, self, vt);
+          (vt.visit_expr)(in, this, vt);
         }
 
         // Output operands must be lvalues
         for ia.outputs.each |&(_, out)| {
           match out.node {
             expr_addr_of(_, inner) => {
-              self.check_lvalue(inner, vt);
+              this.check_lvalue(inner, vt);
             }
             _ => {}
           }
-          (vt.visit_expr)(out, self, vt);
+          (vt.visit_expr)(out, this, vt);
         }
 
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
 
       // no correctness conditions related to liveness
@@ -1521,7 +1521,7 @@ fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) {
       expr_again(*) | expr_lit(_) | expr_block(*) |
       expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
       expr_paren(*) => {
-        visit::visit_expr(expr, self, vt);
+        visit::visit_expr(expr, this, vt);
       }
     }
 }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 436905f9a53..95ed7fe8efc 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -406,7 +406,7 @@ pub impl mem_categorization_ctxt {
             self.cat_index(expr, base_cmt, 0)
           }
 
-          ast::expr_path(_) => {
+          ast::expr_path(_) | ast::expr_self => {
             let def = self.tcx.def_map.get_copy(&expr.id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 2471e383bca..3a2fb654006 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -435,7 +435,7 @@ pub impl VisitContext {
         debug!("comp_mode = %?", comp_mode);
 
         match expr.node {
-            expr_path(*) => {
+            expr_path(*) | expr_self => {
                 match comp_mode {
                     MoveInPart(entire_expr) => {
                         self.move_maps.variable_moves_map.insert(
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 76d35527104..74082c02f6d 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -310,14 +310,14 @@ pub impl RegionMaps {
             }
         }
 
-        fn ancestors_of(self: &RegionMaps, scope: ast::node_id)
+        fn ancestors_of(this: &RegionMaps, scope: ast::node_id)
             -> ~[ast::node_id]
         {
             // debug!("ancestors_of(scope=%d)", scope);
             let mut result = ~[scope];
             let mut scope = scope;
             loop {
-                match self.scope_map.find(&scope) {
+                match this.scope_map.find(&scope) {
                     None => return result,
                     Some(&superscope) => {
                         result.push(superscope);
@@ -685,7 +685,7 @@ pub impl DetermineRpCtxt {
             None => {
                 self.anon_implies_rp
             }
-            Some(ref l) if l.ident == special_idents::static => {
+            Some(ref l) if l.ident == special_idents::statik => {
                 false
             }
             Some(ref l) if l.ident == special_idents::self_ => {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 515ebc0e8db..9a37f65f470 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -35,7 +35,7 @@ use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
 use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
 use syntax::ast::{expr, expr_again, expr_assign_op};
 use syntax::ast::{expr_index, expr_loop};
-use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
+use syntax::ast::{expr_path, expr_self, expr_struct, expr_unary, fn_decl};
 use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
 use syntax::ast::Generics;
 use syntax::ast::{gt, ident, inherited, item, item_struct};
@@ -326,12 +326,14 @@ pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
 /// One local scope.
 pub struct Rib {
     bindings: @mut HashMap<ident,def_like>,
+    self_binding: @mut Option<def_like>,
     kind: RibKind,
 }
 
 pub fn Rib(kind: RibKind) -> Rib {
     Rib {
         bindings: @mut HashMap::new(),
+        self_binding: @mut None,
         kind: kind
     }
 }
@@ -762,7 +764,7 @@ pub fn Resolver(session: Session,
 
     let current_module = graph_root.get_module();
 
-    let self = Resolver {
+    let this = Resolver {
         session: @session,
         lang_items: copy lang_items,
         crate: crate,
@@ -800,7 +802,7 @@ pub fn Resolver(session: Session,
         intr: session.intr()
     };
 
-    self
+    this
 }
 
 /// The main resolver class.
@@ -3655,8 +3657,7 @@ pub impl Resolver {
                 HasSelfBinding(self_node_id, is_implicit) => {
                     let def_like = dl_def(def_self(self_node_id,
                                                    is_implicit));
-                    (*function_value_rib).bindings.insert(self.self_ident,
-                                                          def_like);
+                    *function_value_rib.self_binding = Some(def_like);
                 }
             }
 
@@ -4562,7 +4563,7 @@ pub impl Resolver {
                                         ident: ident,
                                         namespace: Namespace,
                                         span: span)
-                                     -> Option<def> {
+                                        -> Option<def> {
         // Check the local set of ribs.
         let search_result;
         match namespace {
@@ -4591,6 +4592,35 @@ pub impl Resolver {
         }
     }
 
+    fn resolve_self_value_in_local_ribs(@mut self, span: span)
+                                        -> Option<def> {
+        // FIXME #4950: This should not use a while loop.
+        let ribs = &mut self.value_ribs;
+        let mut i = ribs.len();
+        while i != 0 {
+            i -= 1;
+            match *ribs[i].self_binding {
+                Some(def_like) => {
+                    match self.upvarify(*ribs,
+                                        i,
+                                        def_like,
+                                        span,
+                                        DontAllowCapturingSelf) {
+                        Some(dl_def(def)) => return Some(def),
+                        _ => {
+                            self.session.span_bug(span,
+                                                  ~"self wasn't mapped to a \
+                                                    def?!")
+                        }
+                    }
+                }
+                None => {}
+            }
+        }
+
+        None
+    }
+
     fn resolve_item_by_identifier_in_lexical_scope(@mut self,
                                                    ident: ident,
                                                    namespace: Namespace)
@@ -4805,12 +4835,25 @@ pub impl Resolver {
                                                    `%s`",
                                                    *self.session.str_of(
                                                        label))),
-                    Some(dl_def(def @ def_label(_))) =>
-                        self.record_def(expr.id, def),
-                    Some(_) =>
+                    Some(dl_def(def @ def_label(_))) => {
+                        self.record_def(expr.id, def)
+                    }
+                    Some(_) => {
                         self.session.span_bug(expr.span,
                                               ~"label wasn't mapped to a \
                                                 label def!")
+                    }
+                }
+            }
+
+            expr_self => {
+                match self.resolve_self_value_in_local_ribs(expr.span) {
+                    None => {
+                        self.session.span_err(expr.span,
+                                              ~"`self` is not allowed in \
+                                                this context")
+                    }
+                    Some(def) => self.record_def(expr.id, def),
                 }
             }
 
diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs
index 4fd2e967083..de6a4452da1 100644
--- a/src/librustc/middle/resolve_stage0.rs
+++ b/src/librustc/middle/resolve_stage0.rs
@@ -36,7 +36,7 @@ use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
 use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
 use syntax::ast::{expr, expr_again, expr_assign_op};
 use syntax::ast::{expr_index, expr_loop};
-use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
+use syntax::ast::{expr_path, expr_self, expr_struct, expr_unary, fn_decl};
 use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
 use syntax::ast::Generics;
 use syntax::ast::{gt, ident, inherited, item, item_struct};
@@ -327,12 +327,14 @@ pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
 /// One local scope.
 pub struct Rib {
     bindings: @mut HashMap<ident,def_like>,
+    self_binding: @mut Option<def_like>,
     kind: RibKind,
 }
 
 pub fn Rib(kind: RibKind) -> Rib {
     Rib {
         bindings: @mut HashMap::new(),
+        self_binding: @mut None,
         kind: kind
     }
 }
@@ -763,7 +765,7 @@ pub fn Resolver(session: Session,
 
     let current_module = graph_root.get_module();
 
-    let self = Resolver {
+    let this = Resolver {
         session: @session,
         lang_items: copy lang_items,
         crate: crate,
@@ -806,7 +808,7 @@ pub fn Resolver(session: Session,
         intr: session.intr()
     };
 
-    self
+    this
 }
 
 /// The main resolver class.
@@ -3695,8 +3697,7 @@ pub impl Resolver {
                 HasSelfBinding(self_node_id, is_implicit) => {
                     let def_like = dl_def(def_self(self_node_id,
                                                    is_implicit));
-                    (*function_value_rib).bindings.insert(self.self_ident,
-                                                          def_like);
+                    *function_value_rib.self_binding = Some(def_like);
                 }
             }
 
@@ -4603,7 +4604,7 @@ pub impl Resolver {
                                         ident: ident,
                                         namespace: Namespace,
                                         span: span)
-                                     -> Option<def> {
+                                        -> Option<def> {
         // Check the local set of ribs.
         let search_result;
         match namespace {
@@ -4632,6 +4633,35 @@ pub impl Resolver {
         }
     }
 
+    fn resolve_self_value_in_local_ribs(@mut self, span: span)
+                                        -> Option<def> {
+        // FIXME #4950: This should not use a while loop.
+        let ribs = &mut self.value_ribs;
+        let mut i = ribs.len();
+        while i != 0 {
+            i -= 1;
+            match *ribs[i].self_binding {
+                Some(def_like) => {
+                    match self.upvarify(ribs,
+                                        i,
+                                        def_like,
+                                        span,
+                                        DontAllowCapturingSelf) {
+                        Some(dl_def(def)) => return Some(def),
+                        _ => {
+                            self.session.span_bug(span,
+                                                  ~"self wasn't mapped to a \
+                                                    def?!")
+                        }
+                    }
+                }
+                None => {}
+            }
+        }
+
+        None
+    }
+
     fn resolve_item_by_identifier_in_lexical_scope(@mut self,
                                                    ident: ident,
                                                    namespace: Namespace)
@@ -4845,12 +4875,25 @@ pub impl Resolver {
                                                    `%s`",
                                                    *self.session.str_of(
                                                        label))),
-                    Some(dl_def(def @ def_label(_))) =>
-                        self.record_def(expr.id, def),
-                    Some(_) =>
+                    Some(dl_def(def @ def_label(_))) => {
+                        self.record_def(expr.id, def)
+                    }
+                    Some(_) => {
                         self.session.span_bug(expr.span,
                                               ~"label wasn't mapped to a \
                                                 label def!")
+                    }
+                }
+            }
+
+            expr_self => {
+                match self.resolve_self_value_in_local_ribs(expr.span) {
+                    None => {
+                        self.session.span_err(expr.span,
+                                              ~"`self` is not allowed in \
+                                                this context")
+                    }
+                    Some(def) => self.record_def(expr.id, def),
                 }
             }
 
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index e05f9d5f290..b24e88698af 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -426,10 +426,10 @@ pub fn enter_match<'r>(bcx: block,
                         vec::append(sub, vec::slice(br.pats, 0u, col)),
                         vec::slice(br.pats, col + 1u, br.pats.len()));
 
-                let self = br.pats[col];
-                match self.node {
+                let this = br.pats[col];
+                match this.node {
                     ast::pat_ident(_, path, None) => {
-                        if pat_is_binding(dm, self) {
+                        if pat_is_binding(dm, this) {
                             let binding_info =
                                 br.data.bindings_map.get(
                                     &path_to_ident(path));
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index aff45cbb993..8000484c055 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -256,13 +256,11 @@ pub impl param_substs {
     }
 }
 
-fn param_substs_to_str(self: &param_substs,
-                       tcx: ty::ctxt) -> ~str
-{
+fn param_substs_to_str(this: &param_substs, tcx: ty::ctxt) -> ~str {
     fmt!("param_substs {tys:%s, vtables:%s, type_param_defs:%s}",
-         self.tys.repr(tcx),
-         self.vtables.repr(tcx),
-         self.type_param_defs.repr(tcx))
+         this.tys.repr(tcx),
+         this.vtables.repr(tcx),
+         this.type_param_defs.repr(tcx))
 }
 
 impl Repr for param_substs {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index ed3dfdc07c3..59526ffbe49 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -451,7 +451,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
     trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr)));
 
     match expr.node {
-        ast::expr_path(_) => {
+        ast::expr_path(_) | ast::expr_self => {
             return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
         }
         ast::expr_vstore(contents, ast::expr_vstore_box) |
@@ -558,7 +558,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
         ast::expr_paren(e) => {
             return trans_rvalue_dps_unadjusted(bcx, e, dest);
         }
-        ast::expr_path(_) => {
+        ast::expr_path(_) | ast::expr_self => {
             return trans_def_dps_unadjusted(bcx, expr,
                                             bcx.def(expr.id), dest);
         }
@@ -810,7 +810,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
         ast::expr_paren(e) => {
             trans_lvalue_unadjusted(bcx, e)
         }
-        ast::expr_path(_) => {
+        ast::expr_path(_) | ast::expr_self => {
             trans_def_lvalue(bcx, expr, bcx.def(expr.id))
         }
         ast::expr_field(base, ident, _) => {
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index ffe414ab5b5..02afbbdb11f 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -174,14 +174,15 @@ pub fn trans_self_arg(bcx: block,
 
 pub fn trans_method_callee(bcx: block,
                            callee_id: ast::node_id,
-                           self: @ast::expr,
+                           this: @ast::expr,
                            mentry: typeck::method_map_entry)
-                        -> Callee {
+                           -> Callee {
     let _icx = bcx.insn_ctxt("impl::trans_method_callee");
     let tcx = bcx.tcx();
 
-    debug!("trans_method_callee(callee_id=%?, self=%s, mentry=%s)",
-           callee_id, bcx.expr_to_str(self),
+    debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)",
+           callee_id,
+           bcx.expr_to_str(this),
            mentry.repr(bcx.tcx()));
 
     // Replace method_self with method_static here.
@@ -202,7 +203,7 @@ pub fn trans_method_callee(bcx: block,
         }
         typeck::method_super(trait_id, method_index) => {
             // <self_ty> is the self type for this method call
-            let self_ty = node_id_type(bcx, self.id);
+            let self_ty = node_id_type(bcx, this.id);
             // <impl_id> is the ID of the implementation of
             // trait <trait_id> for type <self_ty>
             let impl_id = ty::get_impl_id(tcx, trait_id, self_ty);
@@ -232,13 +233,13 @@ pub fn trans_method_callee(bcx: block,
     match origin {
         typeck::method_static(did) => {
             let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
-            let Result {bcx, val} = trans_self_arg(bcx, self, mentry);
+            let Result {bcx, val} = trans_self_arg(bcx, this, mentry);
             Callee {
                 bcx: bcx,
                 data: Method(MethodData {
                     llfn: callee_fn.llfn,
                     llself: val,
-                    self_ty: node_id_type(bcx, self.id),
+                    self_ty: node_id_type(bcx, this.id),
                     self_mode: mentry.self_mode,
                 })
             }
@@ -252,7 +253,7 @@ pub fn trans_method_callee(bcx: block,
             match bcx.fcx.param_substs {
                 Some(substs) => {
                     let vtbl = find_vtable(bcx.tcx(), substs, p, b);
-                    trans_monomorphized_callee(bcx, callee_id, self, mentry,
+                    trans_monomorphized_callee(bcx, callee_id, this, mentry,
                                                trait_id, off, vtbl)
                 }
                 // how to get rid of this?
@@ -263,7 +264,7 @@ pub fn trans_method_callee(bcx: block,
             trans_trait_callee(bcx,
                                callee_id,
                                off,
-                               self,
+                               this,
                                store,
                                mentry.explicit_self)
         }
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 3c2738d3ae8..cd1b89d7ffa 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -293,7 +293,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
           _ => ()
         }
       }
-      expr_path(_) => {
+      expr_path(_) | expr_self => {
         let opt_ts = cx.ccx.tcx.node_type_substs.find_copy(&e.id);
         for opt_ts.each |ts| {
             let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get_copy(&e.id));
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f5adb2fe108..5eaa6478ecf 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3383,7 +3383,7 @@ pub fn expr_kind(tcx: ctxt,
     }
 
     match expr.node {
-        ast::expr_path(*) => {
+        ast::expr_path(*) | ast::expr_self => {
             match resolve_expr(tcx, expr) {
                 ast::def_variant(*) | ast::def_struct(*) => RvalueDpsExpr,
 
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 0baad7e7b7a..469e31d0c49 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -102,7 +102,7 @@ pub fn get_region_reporting_err(
 }
 
 pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     default_span: span,
     opt_lifetime: Option<@ast::Lifetime>) -> ty::Region
@@ -111,7 +111,7 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
         None => {
             (default_span, rscope.anon_region(default_span))
         }
-        Some(ref lifetime) if lifetime.ident == special_idents::static => {
+        Some(ref lifetime) if lifetime.ident == special_idents::statik => {
             (lifetime.span, Ok(ty::re_static))
         }
         Some(ref lifetime) if lifetime.ident == special_idents::self_ => {
@@ -123,11 +123,11 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + 'static>(
         }
     };
 
-    get_region_reporting_err(self.tcx(), span, opt_lifetime, res)
+    get_region_reporting_err(this.tcx(), span, opt_lifetime, res)
 }
 
 fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     def_id: ast::def_id,
     decl_generics: &ty::Generics,
@@ -141,9 +141,9 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
      * set of substitutions for this particular reference to `I`.
      */
 
-    let tcx = self.tcx();
+    let tcx = this.tcx();
 
-    // If the type is parameterized by the self region, then replace self
+    // If the type is parameterized by the this region, then replace this
     // region with the current anon region binding (in other words,
     // whatever & would get replaced with).
     let self_r = match (&decl_generics.region_param, &path.rp) {
@@ -160,55 +160,55 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Copy + 'static>(
       }
       (&Some(_), &None) => {
         let res = rscope.anon_region(path.span);
-        let r = get_region_reporting_err(self.tcx(), path.span, None, res);
+        let r = get_region_reporting_err(this.tcx(), path.span, None, res);
         Some(r)
       }
       (&Some(_), &Some(_)) => {
-        Some(ast_region_to_region(self, rscope, path.span, path.rp))
+        Some(ast_region_to_region(this, rscope, path.span, path.rp))
       }
     };
 
     // Convert the type parameters supplied by the user.
     if !vec::same_length(*decl_generics.type_param_defs, path.types) {
-        self.tcx().sess.span_fatal(
+        this.tcx().sess.span_fatal(
             path.span,
             fmt!("wrong number of type arguments: expected %u but found %u",
                  decl_generics.type_param_defs.len(), path.types.len()));
     }
-    let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t));
+    let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, *a_t));
 
     substs {self_r:self_r, self_ty:self_ty, tps:tps}
 }
 
 pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     did: ast::def_id,
     path: @ast::Path) -> ty_param_substs_and_ty
 {
-    let tcx = self.tcx();
+    let tcx = this.tcx();
     let ty::ty_param_bounds_and_ty {
         generics: generics,
         ty: decl_ty
-    } = self.get_item_ty(did);
+    } = this.get_item_ty(did);
 
-    let substs = ast_path_substs(self, rscope, did, &generics, None, path);
+    let substs = ast_path_substs(this, rscope, did, &generics, None, path);
     let ty = ty::subst(tcx, &substs, decl_ty);
     ty_param_substs_and_ty { substs: substs, ty: ty }
 }
 
 pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     trait_def_id: ast::def_id,
     self_ty: Option<ty::t>,
     path: @ast::Path) -> @ty::TraitRef
 {
     let trait_def =
-        self.get_trait_def(trait_def_id);
+        this.get_trait_def(trait_def_id);
     let substs =
         ast_path_substs(
-            self,
+            this,
             rscope,
             trait_def.trait_ref.def_id,
             &trait_def.generics,
@@ -222,7 +222,7 @@ pub fn ast_path_to_trait_ref<AC:AstConv,RS:region_scope + Copy + 'static>(
 
 
 pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
-        self: &AC,
+        this: &AC,
         rscope: &RS,
         did: ast::def_id,
         path: @ast::Path)
@@ -233,7 +233,7 @@ pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
     let ty::ty_param_substs_and_ty {
         substs: substs,
         ty: ty
-    } = ast_path_to_substs_and_ty(self, rscope, did, path);
+    } = ast_path_to_substs_and_ty(this, rscope, did, path);
     ty_param_substs_and_ty { substs: substs, ty: ty }
 }
 
@@ -244,29 +244,29 @@ pub static NO_TPS: uint = 2;
 // internal notion of a type. `getter` is a function that returns the type
 // corresponding to a definition ID:
 pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
-    self: &AC, rscope: &RS, ast_ty: @ast::Ty) -> ty::t {
+    this: &AC, rscope: &RS, ast_ty: @ast::Ty) -> ty::t {
 
     fn ast_mt_to_mt<AC:AstConv, RS:region_scope + Copy + 'static>(
-        self: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
+        this: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt {
 
-        ty::mt {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl}
+        ty::mt {ty: ast_ty_to_ty(this, rscope, mt.ty), mutbl: mt.mutbl}
     }
 
     // Handle @, ~, and & being able to mean estrs and evecs.
     // If a_seq_ty is a str or a vec, make it an estr/evec.
     // Also handle first-class trait types.
     fn mk_pointer<AC:AstConv,RS:region_scope + Copy + 'static>(
-        self: &AC,
+        this: &AC,
         rscope: &RS,
         a_seq_ty: &ast::mt,
         vst: ty::vstore,
         constr: &fn(ty::mt) -> ty::t) -> ty::t
     {
-        let tcx = self.tcx();
+        let tcx = this.tcx();
 
         match a_seq_ty.ty.node {
             ast::ty_vec(ref mt) => {
-                let mut mt = ast_mt_to_mt(self, rscope, mt);
+                let mut mt = ast_mt_to_mt(this, rscope, mt);
                 if a_seq_ty.mutbl == ast::m_mutbl ||
                         a_seq_ty.mutbl == ast::m_const {
                     mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl };
@@ -281,7 +281,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
                     }
                     Some(&ast::def_trait(trait_def_id)) => {
                         let result = ast_path_to_trait_ref(
-                            self, rscope, trait_def_id, None, path);
+                            this, rscope, trait_def_id, None, path);
                         let trait_store = match vst {
                             ty::vstore_box => ty::BoxTraitStore,
                             ty::vstore_uniq => ty::UniqTraitStore,
@@ -308,7 +308,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
             _ => {}
         }
 
-        let seq_ty = ast_mt_to_mt(self, rscope, a_seq_ty);
+        let seq_ty = ast_mt_to_mt(this, rscope, a_seq_ty);
         return constr(seq_ty);
     }
 
@@ -332,7 +332,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
         }
     }
 
-    let tcx = self.tcx();
+    let tcx = this.tcx();
 
     match tcx.ast_ty_to_ty_cache.find(&ast_ty.id) {
       Some(&ty::atttce_resolved(ty)) => return ty,
@@ -348,36 +348,36 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
       ast::ty_nil => ty::mk_nil(),
       ast::ty_bot => ty::mk_bot(),
       ast::ty_box(ref mt) => {
-        mk_pointer(self, rscope, mt, ty::vstore_box,
+        mk_pointer(this, rscope, mt, ty::vstore_box,
                    |tmt| ty::mk_box(tcx, tmt))
       }
       ast::ty_uniq(ref mt) => {
-        mk_pointer(self, rscope, mt, ty::vstore_uniq,
+        mk_pointer(this, rscope, mt, ty::vstore_uniq,
                    |tmt| ty::mk_uniq(tcx, tmt))
       }
       ast::ty_vec(ref mt) => {
         tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
         // return /something/ so they can at least get more errors
-        ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, mt), ty::vstore_uniq)
+        ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, mt), ty::vstore_uniq)
       }
       ast::ty_ptr(ref mt) => {
-        ty::mk_ptr(tcx, ast_mt_to_mt(self, rscope, mt))
+        ty::mk_ptr(tcx, ast_mt_to_mt(this, rscope, mt))
       }
       ast::ty_rptr(region, ref mt) => {
-        let r = ast_region_to_region(self, rscope, ast_ty.span, region);
-        mk_pointer(self, rscope, mt, ty::vstore_slice(r),
+        let r = ast_region_to_region(this, rscope, ast_ty.span, region);
+        mk_pointer(this, rscope, mt, ty::vstore_slice(r),
                    |tmt| ty::mk_rptr(tcx, r, tmt))
       }
       ast::ty_tup(ref fields) => {
-        let flds = fields.map(|t| ast_ty_to_ty(self, rscope, *t));
+        let flds = fields.map(|t| ast_ty_to_ty(this, rscope, *t));
         ty::mk_tup(tcx, flds)
       }
       ast::ty_bare_fn(ref bf) => {
-          ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity,
+          ty::mk_bare_fn(tcx, ty_of_bare_fn(this, rscope, bf.purity,
                                             bf.abis, &bf.lifetimes, &bf.decl))
       }
       ast::ty_closure(ref f) => {
-          let fn_decl = ty_of_closure(self,
+          let fn_decl = ty_of_closure(this,
                                       rscope,
                                       f.sigil,
                                       f.purity,
@@ -407,7 +407,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
               ty::mk_err()
           }
           ast::def_ty(did) | ast::def_struct(did) => {
-            ast_path_to_ty(self, rscope, did, path).ty
+            ast_path_to_ty(this, rscope, did, path).ty
           }
           ast::def_prim_ty(nty) => {
             match nty {
@@ -440,7 +440,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
             ty::mk_param(tcx, n, id)
           }
           ast::def_self_ty(id) => {
-            // n.b.: resolve guarantees that the self type only appears in a
+            // n.b.: resolve guarantees that the this type only appears in a
             // trait, which we rely upon in various places when creating
             // substs
             check_path_args(tcx, path, NO_TPS | NO_REGIONS);
@@ -458,10 +458,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
           Ok(ref r) => {
             match *r {
               const_eval::const_int(i) =>
-                ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
+                ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, a_mt),
                             ty::vstore_fixed(i as uint)),
               const_eval::const_uint(i) =>
-                ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
+                ty::mk_evec(tcx, ast_mt_to_mt(this, rscope, a_mt),
                             ty::vstore_fixed(i as uint)),
               _ => {
                 tcx.sess.span_fatal(
@@ -482,7 +482,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
         // values in a fn_expr, or as the type of local variables.  Both of
         // these cases are handled specially and should not descend into this
         // routine.
-        self.tcx().sess.span_bug(
+        this.tcx().sess.span_bug(
             ast_ty.span,
             "found `ty_infer` in unexpected place");
       }
@@ -498,15 +498,15 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
 
 pub fn ty_of_arg<AC:AstConv,
                  RS:region_scope + Copy + 'static>(
-                 self: &AC,
+                 this: &AC,
                  rscope: &RS,
                  a: ast::arg,
                  expected_ty: Option<ty::arg>)
                  -> ty::arg {
     let ty = match a.ty.node {
         ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
-        ast::ty_infer => self.ty_infer(a.ty.span),
-        _ => ast_ty_to_ty(self, rscope, a.ty),
+        ast::ty_infer => this.ty_infer(a.ty.span),
+        _ => ast_ty_to_ty(this, rscope, a.ty),
     };
 
     arg {
@@ -515,28 +515,28 @@ pub fn ty_of_arg<AC:AstConv,
 }
 
 pub fn bound_lifetimes<AC:AstConv>(
-    self: &AC,
+    this: &AC,
     ast_lifetimes: &OptVec<ast::Lifetime>) -> OptVec<ast::ident>
 {
     /*!
      *
      * Converts a list of lifetimes into a list of bound identifier
-     * names.  Does not permit special names like 'static or 'self to
+     * names.  Does not permit special names like 'static or 'this to
      * be bound.  Note that this function is for use in closures,
-     * methods, and fn definitions.  It is legal to bind 'self in a
+     * methods, and fn definitions.  It is legal to bind 'this in a
      * type.  Eventually this distinction should go away and the same
-     * rules should apply everywhere ('self would not be a special name
+     * rules should apply everywhere ('this would not be a special name
      * at that point).
      */
 
-    let special_idents = [special_idents::static, special_idents::self_];
+    let special_idents = [special_idents::statik, special_idents::self_];
     let mut bound_lifetime_names = opt_vec::Empty;
     ast_lifetimes.map_to_vec(|ast_lifetime| {
         if special_idents.any(|&i| i == ast_lifetime.ident) {
-            self.tcx().sess.span_err(
+            this.tcx().sess.span_err(
                 ast_lifetime.span,
                 fmt!("illegal lifetime parameter name: `%s`",
-                     lifetime_to_str(ast_lifetime, self.tcx().sess.intr())));
+                     lifetime_to_str(ast_lifetime, this.tcx().sess.intr())));
         } else {
             bound_lifetime_names.push(ast_lifetime.ident);
         }
@@ -550,7 +550,7 @@ struct SelfInfo {
 }
 
 pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     purity: ast::purity,
     lifetimes: &OptVec<ast::Lifetime>,
@@ -563,12 +563,12 @@ pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + 'static>(
         self_transform: self_transform
     };
     let (a, b) = ty_of_method_or_bare_fn(
-        self, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
+        this, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
     (a.get(), b)
 }
 
 pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     purity: ast::purity,
     abi: AbiSet,
@@ -576,12 +576,12 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
     decl: &ast::fn_decl) -> ty::BareFnTy
 {
     let (_, b) = ty_of_method_or_bare_fn(
-        self, rscope, purity, abi, lifetimes, None, decl);
+        this, rscope, purity, abi, lifetimes, None, decl);
     b
 }
 
 fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
-    self: &AC,
+    this: &AC,
     rscope: &RS,
     purity: ast::purity,
     abi: AbiSet,
@@ -593,18 +593,18 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
-    let bound_lifetime_names = bound_lifetimes(self, lifetimes);
+    let bound_lifetime_names = bound_lifetimes(this, lifetimes);
     let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
 
     let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
-        transform_self_ty(self, &rb, self_info)
+        transform_self_ty(this, &rb, self_info)
     });
 
-    let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
+    let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, *a, None));
 
     let output_ty = match decl.output.node {
-        ast::ty_infer => self.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(self, &rb, decl.output)
+        ast::ty_infer => this.ty_infer(decl.output.span),
+        _ => ast_ty_to_ty(this, &rb, decl.output)
     };
 
     return (opt_transformed_self_ty,
@@ -617,7 +617,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
             });
 
     fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + 'static>(
-        self: &AC,
+        this: &AC,
         rscope: &RS,
         self_info: &SelfInfo) -> Option<ty::t>
     {
@@ -628,20 +628,20 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
             }
             ast::sty_region(lifetime, mutability) => {
                 let region =
-                    ast_region_to_region(self, rscope,
+                    ast_region_to_region(this, rscope,
                                          self_info.self_transform.span,
                                          lifetime);
-                Some(ty::mk_rptr(self.tcx(), region,
+                Some(ty::mk_rptr(this.tcx(), region,
                                  ty::mt {ty: self_info.untransformed_self_ty,
                                          mutbl: mutability}))
             }
             ast::sty_box(mutability) => {
-                Some(ty::mk_box(self.tcx(),
+                Some(ty::mk_box(this.tcx(),
                                 ty::mt {ty: self_info.untransformed_self_ty,
                                         mutbl: mutability}))
             }
             ast::sty_uniq(mutability) => {
-                Some(ty::mk_uniq(self.tcx(),
+                Some(ty::mk_uniq(this.tcx(),
                                  ty::mt {ty: self_info.untransformed_self_ty,
                                          mutbl: mutability}))
             }
@@ -650,7 +650,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + 'static>(
 }
 
 pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
-        self: &AC,
+        this: &AC,
         rscope: &RS,
         sigil: ast::Sigil,
         purity: ast::purity,
@@ -674,7 +674,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
     // scope `rscope`, not the scope of the function parameters
     let bound_region = match opt_lifetime {
         Some(_) => {
-            ast_region_to_region(self, rscope, span, opt_lifetime)
+            ast_region_to_region(this, rscope, span, opt_lifetime)
         }
         None => {
             match sigil {
@@ -685,7 +685,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
                 }
                 ast::BorrowedSigil => {
                     // &fn() defaults as normal for an omitted lifetime:
-                    ast_region_to_region(self, rscope, span, opt_lifetime)
+                    ast_region_to_region(this, rscope, span, opt_lifetime)
                 }
             }
         }
@@ -693,7 +693,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
-    let bound_lifetime_names = bound_lifetimes(self, lifetimes);
+    let bound_lifetime_names = bound_lifetimes(this, lifetimes);
     let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
 
     let input_tys = do decl.inputs.mapi |i, a| {
@@ -702,14 +702,14 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
             // were supplied
             if i < e.inputs.len() {Some(e.inputs[i])} else {None}
         };
-        ty_of_arg(self, &rb, *a, expected_arg_ty)
+        ty_of_arg(this, &rb, *a, expected_arg_ty)
     };
 
     let expected_ret_ty = expected_sig.map(|e| e.output);
     let output_ty = match decl.output.node {
         ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
-        ast::ty_infer => self.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(self, &rb, decl.output)
+        ast::ty_infer => this.ty_infer(decl.output.span),
+        _ => ast_ty_to_ty(this, &rb, decl.output)
     };
 
     ty::ClosureTy {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 7c79693a8b2..498e5c9d200 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -2391,6 +2391,12 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
         instantiate_path(fcx, pth, tpt, expr.span, expr.id);
       }
+      ast::expr_self => {
+        let definition = lookup_def(fcx, expr.span, id);
+        let ty_param_bounds_and_ty =
+            ty_param_bounds_and_ty_for_def(fcx, expr.span, definition);
+        fcx.write_ty(id, ty_param_bounds_and_ty.ty);
+      }
       ast::expr_inline_asm(ref ia) => {
           fcx.require_unsafe(expr.span, ~"use of inline assembly");
 
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 55c1f03b330..ecec07ec512 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -993,7 +993,7 @@ pub mod guarantor {
                 guarantor(rcx, e)
             }
 
-            ast::expr_path(*) => {
+            ast::expr_path(*) | ast::expr_self => {
                 // Either a variable or constant and hence resides
                 // in constant memory or on the stack frame.  Either way,
                 // not guaranteed by a region pointer.
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 6de87762031..03601a716c0 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -370,7 +370,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
                           });
     }
 
-    fn ty_method_of_trait_method(self: &CrateCtxt,
+    fn ty_method_of_trait_method(this: &CrateCtxt,
                                  trait_id: ast::node_id,
                                  trait_rp: Option<ty::region_variance>,
                                  trait_generics: &ast::Generics,
@@ -381,15 +381,15 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
                                  m_purity: &ast::purity,
                                  m_decl: &ast::fn_decl) -> ty::method
     {
-        let trait_self_ty = ty::mk_self(self.tcx, local_def(trait_id));
+        let trait_self_ty = ty::mk_self(this.tcx, local_def(trait_id));
         let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
         let (transformed_self_ty, fty) =
-            astconv::ty_of_method(self, &rscope, *m_purity, &m_generics.lifetimes,
+            astconv::ty_of_method(this, &rscope, *m_purity, &m_generics.lifetimes,
                                   trait_self_ty, *m_self_ty, m_decl);
         let num_trait_type_params = trait_generics.ty_params.len();
         ty::method {
             ident: *m_ident,
-            generics: ty_generics(self, None, m_generics, num_trait_type_params),
+            generics: ty_generics(this, None, m_generics, num_trait_type_params),
             transformed_self_ty: transformed_self_ty,
             fty: fty,
             self_ty: m_self_ty.node,
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 362104e98b0..a845d6fe9d0 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -120,31 +120,31 @@ pub struct CombineFields {
 }
 
 pub fn expected_found<C:Combine,T>(
-        self: &C, a: T, b: T) -> ty::expected_found<T> {
-    if self.a_is_expected() {
+        this: &C, a: T, b: T) -> ty::expected_found<T> {
+    if this.a_is_expected() {
         ty::expected_found {expected: a, found: b}
     } else {
         ty::expected_found {expected: b, found: a}
     }
 }
 
-pub fn eq_tys<C:Combine>(self: &C, a: ty::t, b: ty::t) -> ures {
-    let suber = self.sub();
-    do self.infcx().try {
+pub fn eq_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> ures {
+    let suber = this.sub();
+    do this.infcx().try {
         do suber.tys(a, b).chain |_ok| {
             suber.contratys(a, b)
         }.to_ures()
     }
 }
 
-pub fn eq_regions<C:Combine>(self: &C, a: ty::Region, b: ty::Region)
+pub fn eq_regions<C:Combine>(this: &C, a: ty::Region, b: ty::Region)
                           -> ures {
     debug!("eq_regions(%s, %s)",
-           a.inf_str(self.infcx()),
-           b.inf_str(self.infcx()));
-    let sub = self.sub();
+           a.inf_str(this.infcx()),
+           b.inf_str(this.infcx()));
+    let sub = this.sub();
     do indent {
-        self.infcx().try(|| {
+        this.infcx().try(|| {
             do sub.regions(a, b).chain |_r| {
                 sub.contraregions(a, b)
             }
@@ -161,7 +161,7 @@ pub fn eq_regions<C:Combine>(self: &C, a: ty::Region, b: ty::Region)
 }
 
 pub fn eq_opt_regions<C:Combine>(
-    self: &C,
+    this: &C,
     a: Option<ty::Region>,
     b: Option<ty::Region>) -> cres<Option<ty::Region>> {
 
@@ -170,7 +170,7 @@ pub fn eq_opt_regions<C:Combine>(
         Ok(None)
       }
       (Some(a), Some(b)) => {
-        do eq_regions(self, a, b).then {
+        do eq_regions(this, a, b).then {
             Ok(Some(a))
         }
       }
@@ -179,21 +179,21 @@ pub fn eq_opt_regions<C:Combine>(
         // they should be), then the type should either
         // consistently have a region parameter or not have a
         // region parameter.
-        self.infcx().tcx.sess.bug(
+        this.infcx().tcx.sess.bug(
             fmt!("substitution a had opt_region %s and \
                   b had opt_region %s",
-                 a.inf_str(self.infcx()),
-                 b.inf_str(self.infcx())));
+                 a.inf_str(this.infcx()),
+                 b.inf_str(this.infcx())));
       }
     }
 }
 
 pub fn super_substs<C:Combine>(
-    self: &C, generics: &ty::Generics,
+    this: &C, generics: &ty::Generics,
     a: &ty::substs, b: &ty::substs) -> cres<ty::substs> {
 
     fn relate_region_param<C:Combine>(
-        self: &C,
+        this: &C,
         generics: &ty::Generics,
         a: Option<ty::Region>,
         b: Option<ty::Region>)
@@ -204,17 +204,17 @@ pub fn super_substs<C:Combine>(
             Ok(None)
           }
           (&Some(ty::rv_invariant), &Some(a), &Some(b)) => {
-            do eq_regions(self, a, b).then {
+            do eq_regions(this, a, b).then {
                 Ok(Some(a))
             }
           }
           (&Some(ty::rv_covariant), &Some(a), &Some(b)) => {
-            do self.regions(a, b).chain |r| {
+            do this.regions(a, b).chain |r| {
                 Ok(Some(r))
             }
           }
           (&Some(ty::rv_contravariant), &Some(a), &Some(b)) => {
-            do self.contraregions(a, b).chain |r| {
+            do this.contraregions(a, b).chain |r| {
                 Ok(Some(r))
             }
           }
@@ -224,19 +224,19 @@ pub fn super_substs<C:Combine>(
             // consistently have a region parameter or not have a
             // region parameter, and that should match with the
             // polytype.
-            self.infcx().tcx.sess.bug(
+            this.infcx().tcx.sess.bug(
                 fmt!("substitution a had opt_region %s and \
                       b had opt_region %s with variance %?",
-                      a.inf_str(self.infcx()),
-                      b.inf_str(self.infcx()),
+                      a.inf_str(this.infcx()),
+                      b.inf_str(this.infcx()),
                      generics.region_param));
           }
         }
     }
 
-    do self.tps(a.tps, b.tps).chain |tps| {
-        do self.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
-            do relate_region_param(self, generics,
+    do this.tps(a.tps, b.tps).chain |tps| {
+        do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
+            do relate_region_param(this, generics,
                                    a.self_r, b.self_r).chain |self_r|
             {
                 Ok(substs {
@@ -250,7 +250,7 @@ pub fn super_substs<C:Combine>(
 }
 
 pub fn super_tps<C:Combine>(
-    self: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
+    this: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
 
     // Note: type parameters are always treated as *invariant*
     // (otherwise the type system would be unsound).  In the
@@ -259,16 +259,16 @@ pub fn super_tps<C:Combine>(
 
     if vec::same_length(as_, bs) {
         iter_vec2(as_, bs, |a, b| {
-            eq_tys(self, *a, *b)
+            eq_tys(this, *a, *b)
         }).then(|| Ok(as_.to_vec()) )
     } else {
         Err(ty::terr_ty_param_size(
-            expected_found(self, as_.len(), bs.len())))
+            expected_found(this, as_.len(), bs.len())))
     }
 }
 
 pub fn super_self_tys<C:Combine>(
-    self: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
+    this: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
 
     match (a, b) {
       (None, None) => {
@@ -276,8 +276,8 @@ pub fn super_self_tys<C:Combine>(
       }
       (Some(a), Some(b)) => {
           // FIXME(#5781) this should be eq_tys
-          // eq_tys(self, a, b).then(|| Ok(Some(a)) )
-          self.contratys(a, b).chain(|t| Ok(Some(t)))
+          // eq_tys(this, a, b).then(|| Ok(Some(a)) )
+          this.contratys(a, b).chain(|t| Ok(Some(t)))
       }
       (None, Some(_)) |
       (Some(_), None) => {
@@ -290,46 +290,46 @@ pub fn super_self_tys<C:Combine>(
 }
 
 pub fn super_sigils<C:Combine>(
-    self: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
+    this: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
     if p1 == p2 {
         Ok(p1)
     } else {
-        Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2)))
+        Err(ty::terr_sigil_mismatch(expected_found(this, p1, p2)))
     }
 }
 
 pub fn super_flds<C:Combine>(
-    self: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
+    this: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
 
     if a.ident == b.ident {
-        self.mts(&a.mt, &b.mt)
+        this.mts(&a.mt, &b.mt)
             .chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
             .chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
     } else {
         Err(ty::terr_record_fields(
-            expected_found(self, a.ident, b.ident)))
+            expected_found(this, a.ident, b.ident)))
     }
 }
 
-pub fn super_args<C:Combine>(self: &C, a: ty::arg, b: ty::arg)
+pub fn super_args<C:Combine>(this: &C, a: ty::arg, b: ty::arg)
                              -> cres<ty::arg> {
-    do self.contratys(a.ty, b.ty).chain |t| {
+    do this.contratys(a.ty, b.ty).chain |t| {
         Ok(arg {
             ty: t
         })
     }
 }
 
-pub fn super_vstores<C:Combine>(self: &C,
+pub fn super_vstores<C:Combine>(this: &C,
                                 vk: ty::terr_vstore_kind,
                                 a: ty::vstore,
                                 b: ty::vstore)
                                 -> cres<ty::vstore> {
-    debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
+    debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
 
     match (a, b) {
       (ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
-        do self.contraregions(a_r, b_r).chain |r| {
+        do this.contraregions(a_r, b_r).chain |r| {
             Ok(ty::vstore_slice(r))
         }
       }
@@ -339,21 +339,21 @@ pub fn super_vstores<C:Combine>(self: &C,
       }
 
       _ => {
-        Err(ty::terr_vstores_differ(vk, expected_found(self, a, b)))
+        Err(ty::terr_vstores_differ(vk, expected_found(this, a, b)))
       }
     }
 }
 
-pub fn super_trait_stores<C:Combine>(self: &C,
+pub fn super_trait_stores<C:Combine>(this: &C,
                                      vk: ty::terr_vstore_kind,
                                      a: ty::TraitStore,
                                      b: ty::TraitStore)
                                   -> cres<ty::TraitStore> {
-    debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
+    debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
 
     match (a, b) {
       (ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
-        do self.contraregions(a_r, b_r).chain |r| {
+        do this.contraregions(a_r, b_r).chain |r| {
             Ok(ty::RegionTraitStore(r))
         }
       }
@@ -363,19 +363,19 @@ pub fn super_trait_stores<C:Combine>(self: &C,
       }
 
       _ => {
-        Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
+        Err(ty::terr_trait_stores_differ(vk, expected_found(this, a, b)))
       }
     }
 }
 
 pub fn super_closure_tys<C:Combine>(
-    self: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
+    this: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
 {
-    let p = if_ok!(self.sigils(a_f.sigil, b_f.sigil));
-    let r = if_ok!(self.contraregions(a_f.region, b_f.region));
-    let purity = if_ok!(self.purities(a_f.purity, b_f.purity));
-    let onceness = if_ok!(self.oncenesses(a_f.onceness, b_f.onceness));
-    let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig));
+    let p = if_ok!(this.sigils(a_f.sigil, b_f.sigil));
+    let r = if_ok!(this.contraregions(a_f.region, b_f.region));
+    let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
+    let onceness = if_ok!(this.oncenesses(a_f.onceness, b_f.onceness));
+    let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
     Ok(ty::ClosureTy {purity: purity,
                       sigil: p,
                       onceness: onceness,
@@ -384,43 +384,43 @@ pub fn super_closure_tys<C:Combine>(
 }
 
 pub fn super_abis<C:Combine>(
-    self: &C, a: AbiSet, b: AbiSet) -> cres<AbiSet>
+    this: &C, a: AbiSet, b: AbiSet) -> cres<AbiSet>
 {
     if a == b {
         Ok(a)
     } else {
-        Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
+        Err(ty::terr_abi_mismatch(expected_found(this, a, b)))
     }
 }
 
 pub fn super_bare_fn_tys<C:Combine>(
-    self: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres<ty::BareFnTy>
+    this: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres<ty::BareFnTy>
 {
-    let purity = if_ok!(self.purities(a_f.purity, b_f.purity));
-    let abi = if_ok!(self.abis(a_f.abis, b_f.abis));
-    let sig = if_ok!(self.fn_sigs(&a_f.sig, &b_f.sig));
+    let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
+    let abi = if_ok!(this.abis(a_f.abis, b_f.abis));
+    let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
     Ok(ty::BareFnTy {purity: purity,
                      abis: abi,
                      sig: sig})
 }
 
 pub fn super_fn_sigs<C:Combine>(
-    self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
+    this: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
 {
-    fn argvecs<C:Combine>(self: &C,
+    fn argvecs<C:Combine>(this: &C,
                           a_args: &[ty::arg],
                           b_args: &[ty::arg]) -> cres<~[ty::arg]>
     {
         if vec::same_length(a_args, b_args) {
-            map_vec2(a_args, b_args, |a, b| self.args(*a, *b))
+            map_vec2(a_args, b_args, |a, b| this.args(*a, *b))
         } else {
             Err(ty::terr_arg_count)
         }
     }
 
-    do argvecs(self, a_f.inputs, b_f.inputs)
+    do argvecs(this, a_f.inputs, b_f.inputs)
             .chain |inputs| {
-        do self.tys(a_f.output, b_f.output).chain |output| {
+        do this.tys(a_f.output, b_f.output).chain |output| {
             Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
                       inputs: /*bad*/copy inputs,
                       output: output})
@@ -429,8 +429,8 @@ pub fn super_fn_sigs<C:Combine>(
 }
 
 pub fn super_tys<C:Combine>(
-    self: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
-    let tcx = self.infcx().tcx;
+    this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
+    let tcx = this.infcx().tcx;
     return match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
       // The "subtype" ought to be handling cases involving bot or var:
       (ty::ty_bot, _) |
@@ -439,45 +439,45 @@ pub fn super_tys<C:Combine>(
       (_, ty::ty_infer(TyVar(_))) => {
         tcx.sess.bug(
             fmt!("%s: bot and var types should have been handled (%s,%s)",
-                 self.tag(),
-                 a.inf_str(self.infcx()),
-                 b.inf_str(self.infcx())));
+                 this.tag(),
+                 a.inf_str(this.infcx()),
+                 b.inf_str(this.infcx())));
       }
 
         // Relate integral variables to other types
         (ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => {
-            if_ok!(self.infcx().simple_vars(self.a_is_expected(),
+            if_ok!(this.infcx().simple_vars(this.a_is_expected(),
                                             a_id, b_id));
             Ok(a)
         }
         (ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) => {
-            unify_integral_variable(self, self.a_is_expected(),
+            unify_integral_variable(this, this.a_is_expected(),
                                     v_id, IntType(v))
         }
         (ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => {
-            unify_integral_variable(self, !self.a_is_expected(),
+            unify_integral_variable(this, !this.a_is_expected(),
                                     v_id, IntType(v))
         }
         (ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) => {
-            unify_integral_variable(self, self.a_is_expected(),
+            unify_integral_variable(this, this.a_is_expected(),
                                     v_id, UintType(v))
         }
         (ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => {
-            unify_integral_variable(self, !self.a_is_expected(),
+            unify_integral_variable(this, !this.a_is_expected(),
                                     v_id, UintType(v))
         }
 
         // Relate floating-point variables to other types
         (ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => {
-            if_ok!(self.infcx().simple_vars(self.a_is_expected(),
+            if_ok!(this.infcx().simple_vars(this.a_is_expected(),
                                             a_id, b_id));
             Ok(a)
         }
         (ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) => {
-            unify_float_variable(self, self.a_is_expected(), v_id, v)
+            unify_float_variable(this, this.a_is_expected(), v_id, v)
         }
         (ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => {
-            unify_float_variable(self, !self.a_is_expected(), v_id, v)
+            unify_float_variable(this, !this.a_is_expected(), v_id, v)
         }
 
       (ty::ty_nil, _) |
@@ -488,7 +488,7 @@ pub fn super_tys<C:Combine>(
         if ty::get(a).sty == ty::get(b).sty {
             Ok(a)
         } else {
-            Err(ty::terr_sorts(expected_found(self, a, b)))
+            Err(ty::terr_sorts(expected_found(this, a, b)))
         }
       }
 
@@ -500,7 +500,7 @@ pub fn super_tys<C:Combine>(
        ty::ty_enum(b_id, ref b_substs))
       if a_id == b_id => {
           let type_def = ty::lookup_item_type(tcx, a_id);
-          do self.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
+          do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
               Ok(ty::mk_enum(tcx, a_id, substs))
           }
       }
@@ -509,8 +509,8 @@ pub fn super_tys<C:Combine>(
        ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl))
       if a_id == b_id && a_mutbl == b_mutbl => {
           let trait_def = ty::lookup_trait_def(tcx, a_id);
-          do self.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
-              do self.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
+          do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| {
+              do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| {
                   Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl))
               }
           }
@@ -519,76 +519,76 @@ pub fn super_tys<C:Combine>(
       (ty::ty_struct(a_id, ref a_substs), ty::ty_struct(b_id, ref b_substs))
       if a_id == b_id => {
           let type_def = ty::lookup_item_type(tcx, a_id);
-          do self.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
+          do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| {
               Ok(ty::mk_struct(tcx, a_id, substs))
           }
       }
 
       (ty::ty_box(ref a_mt), ty::ty_box(ref b_mt)) => {
-        do self.mts(a_mt, b_mt).chain |mt| {
+        do this.mts(a_mt, b_mt).chain |mt| {
             Ok(ty::mk_box(tcx, mt))
         }
       }
 
       (ty::ty_uniq(ref a_mt), ty::ty_uniq(ref b_mt)) => {
-        do self.mts(a_mt, b_mt).chain |mt| {
+        do this.mts(a_mt, b_mt).chain |mt| {
             Ok(ty::mk_uniq(tcx, mt))
         }
       }
 
       (ty::ty_ptr(ref a_mt), ty::ty_ptr(ref b_mt)) => {
-        do self.mts(a_mt, b_mt).chain |mt| {
+        do this.mts(a_mt, b_mt).chain |mt| {
             Ok(ty::mk_ptr(tcx, mt))
         }
       }
 
       (ty::ty_rptr(a_r, ref a_mt), ty::ty_rptr(b_r, ref b_mt)) => {
-          let r = if_ok!(self.contraregions(a_r, b_r));
-          let mt = if_ok!(self.mts(a_mt, b_mt));
+          let r = if_ok!(this.contraregions(a_r, b_r));
+          let mt = if_ok!(this.mts(a_mt, b_mt));
           Ok(ty::mk_rptr(tcx, r, mt))
       }
 
       (ty::ty_evec(ref a_mt, vs_a), ty::ty_evec(ref b_mt, vs_b)) => {
-        do self.mts(a_mt, b_mt).chain |mt| {
-            do self.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| {
+        do this.mts(a_mt, b_mt).chain |mt| {
+            do this.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| {
                 Ok(ty::mk_evec(tcx, mt, vs))
             }
         }
       }
 
       (ty::ty_estr(vs_a), ty::ty_estr(vs_b)) => {
-        do self.vstores(ty::terr_str, vs_a, vs_b).chain |vs| {
+        do this.vstores(ty::terr_str, vs_a, vs_b).chain |vs| {
             Ok(ty::mk_estr(tcx,vs))
         }
       }
 
       (ty::ty_tup(ref as_), ty::ty_tup(ref bs)) => {
         if as_.len() == bs.len() {
-            map_vec2(*as_, *bs, |a, b| self.tys(*a, *b) )
+            map_vec2(*as_, *bs, |a, b| this.tys(*a, *b) )
                 .chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
         } else {
             Err(ty::terr_tuple_size(
-                expected_found(self, as_.len(), bs.len())))
+                expected_found(this, as_.len(), bs.len())))
         }
       }
 
       (ty::ty_bare_fn(ref a_fty), ty::ty_bare_fn(ref b_fty)) => {
-        do self.bare_fn_tys(a_fty, b_fty).chain |fty| {
+        do this.bare_fn_tys(a_fty, b_fty).chain |fty| {
             Ok(ty::mk_bare_fn(tcx, fty))
         }
       }
 
       (ty::ty_closure(ref a_fty), ty::ty_closure(ref b_fty)) => {
-        do self.closure_tys(a_fty, b_fty).chain |fty| {
+        do this.closure_tys(a_fty, b_fty).chain |fty| {
             Ok(ty::mk_closure(tcx, fty))
         }
       }
 
-      _ => Err(ty::terr_sorts(expected_found(self, a, b)))
+      _ => Err(ty::terr_sorts(expected_found(this, a, b)))
     };
 
     fn unify_integral_variable<C:Combine>(
-        self: &C,
+        this: &C,
         vid_is_expected: bool,
         vid: ty::IntVid,
         val: ty::IntVarValue) -> cres<ty::t>
@@ -596,7 +596,7 @@ pub fn super_tys<C:Combine>(
         if val == IntType(ast::ty_char) {
             Err(ty::terr_integer_as_char)
         } else {
-            if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
+            if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
             match val {
                 IntType(v) => Ok(ty::mk_mach_int(v)),
                 UintType(v) => Ok(ty::mk_mach_uint(v))
@@ -605,18 +605,18 @@ pub fn super_tys<C:Combine>(
     }
 
     fn unify_float_variable<C:Combine>(
-        self: &C,
+        this: &C,
         vid_is_expected: bool,
         vid: ty::FloatVid,
         val: ast::float_ty) -> cres<ty::t>
     {
-        if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
+        if_ok!(this.infcx().simple_var_t(vid_is_expected, vid, val));
         Ok(ty::mk_mach_float(val))
     }
 }
 
 pub fn super_trait_refs<C:Combine>(
-    self: &C, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>
+    this: &C, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>
 {
     // Different traits cannot be related
 
@@ -624,11 +624,11 @@ pub fn super_trait_refs<C:Combine>(
 
     if a.def_id != b.def_id {
         Err(ty::terr_traits(
-            expected_found(self, a.def_id, b.def_id)))
+            expected_found(this, a.def_id, b.def_id)))
     } else {
-        let tcx = self.infcx().tcx;
+        let tcx = this.infcx().tcx;
         let trait_def = ty::lookup_trait_def(tcx, a.def_id);
-        let substs = if_ok!(self.substs(&trait_def.generics, &a.substs, &b.substs));
+        let substs = if_ok!(this.substs(&trait_def.generics, &a.substs, &b.substs));
         Ok(ty::TraitRef {
             def_id: a.def_id,
             substs: substs
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index c195454b532..462d7a003f4 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -198,7 +198,7 @@ impl Combine for Glb {
         debug!("sig1 = %s", sig1.inf_str(self.infcx));
         return Ok(sig1);
 
-        fn generalize_region(self: &Glb,
+        fn generalize_region(this: &Glb,
                              snapshot: uint,
                              new_vars: &[RegionVid],
                              a_isr: isr_alist,
@@ -209,19 +209,19 @@ impl Combine for Glb {
                 return r0;
             }
 
-            let tainted = self.infcx.region_vars.tainted(snapshot, r0);
+            let tainted = this.infcx.region_vars.tainted(snapshot, r0);
 
             let mut a_r = None, b_r = None, only_new_vars = true;
             for tainted.each |r| {
                 if is_var_in_set(a_vars, *r) {
                     if a_r.is_some() {
-                        return fresh_bound_variable(self);
+                        return fresh_bound_variable(this);
                     } else {
                         a_r = Some(*r);
                     }
                 } else if is_var_in_set(b_vars, *r) {
                     if b_r.is_some() {
-                        return fresh_bound_variable(self);
+                        return fresh_bound_variable(this);
                     } else {
                         b_r = Some(*r);
                     }
@@ -246,17 +246,17 @@ impl Combine for Glb {
 
             if a_r.is_some() && b_r.is_some() && only_new_vars {
                 // Related to exactly one bound variable from each fn:
-                return rev_lookup(self, a_isr, a_r.get());
+                return rev_lookup(this, a_isr, a_r.get());
             } else if a_r.is_none() && b_r.is_none() {
                 // Not related to bound variables from either fn:
                 return r0;
             } else {
                 // Other:
-                return fresh_bound_variable(self);
+                return fresh_bound_variable(this);
             }
         }
 
-        fn rev_lookup(self: &Glb,
+        fn rev_lookup(this: &Glb,
                       a_isr: isr_alist,
                       r: ty::Region) -> ty::Region
         {
@@ -267,13 +267,13 @@ impl Combine for Glb {
                 }
             }
 
-            self.infcx.tcx.sess.span_bug(
-                self.span,
+            this.infcx.tcx.sess.span_bug(
+                this.span,
                 fmt!("could not find original bound region for %?", r));
         }
 
-        fn fresh_bound_variable(self: &Glb) -> ty::Region {
-            self.infcx.region_vars.new_bound()
+        fn fresh_bound_variable(this: &Glb) -> ty::Region {
+            this.infcx.region_vars.new_bound()
         }
     }
 
diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs
index b9344724f60..3c48e09c057 100644
--- a/src/librustc/middle/typeck/infer/lattice.rs
+++ b/src/librustc/middle/typeck/infer/lattice.rs
@@ -330,27 +330,27 @@ impl TyLatticeDir for Glb {
 }
 
 pub fn super_lattice_tys<L:LatticeDir + TyLatticeDir + Combine>(
-    self: &L,
+    this: &L,
     a: ty::t,
     b: ty::t) -> cres<ty::t> {
-    debug!("%s.lattice_tys(%s, %s)", self.tag(),
-           a.inf_str(self.infcx()),
-           b.inf_str(self.infcx()));
+    debug!("%s.lattice_tys(%s, %s)", this.tag(),
+           a.inf_str(this.infcx()),
+           b.inf_str(this.infcx()));
     let _r = indenter();
 
     if a == b {
         return Ok(a);
     }
 
-    let tcx = self.infcx().tcx;
+    let tcx = this.infcx().tcx;
 
     match (&ty::get(a).sty, &ty::get(b).sty) {
-        (&ty::ty_bot, _) => { return self.ty_bot(b); }
-        (_, &ty::ty_bot) => { return self.ty_bot(a); }
+        (&ty::ty_bot, _) => { return this.ty_bot(b); }
+        (_, &ty::ty_bot) => { return this.ty_bot(a); }
 
         (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
-            let r = if_ok!(lattice_vars(self, a_id, b_id,
-                                        |x, y| self.tys(*x, *y)));
+            let r = if_ok!(lattice_vars(this, a_id, b_id,
+                                        |x, y| this.tys(*x, *y)));
             return match r {
                 VarResult(v) => Ok(ty::mk_var(tcx, v)),
                 ValueResult(t) => Ok(t)
@@ -358,17 +358,17 @@ pub fn super_lattice_tys<L:LatticeDir + TyLatticeDir + Combine>(
         }
 
         (&ty::ty_infer(TyVar(a_id)), _) => {
-            return lattice_var_and_t(self, a_id, &b,
-                                     |x, y| self.tys(*x, *y));
+            return lattice_var_and_t(this, a_id, &b,
+                                     |x, y| this.tys(*x, *y));
         }
 
         (_, &ty::ty_infer(TyVar(b_id))) => {
-            return lattice_var_and_t(self, b_id, &a,
-                                     |x, y| self.tys(*x, *y));
+            return lattice_var_and_t(this, b_id, &a,
+                                     |x, y| this.tys(*x, *y));
         }
 
         _ => {
-            return super_tys(self, a, b);
+            return super_tys(this, a, b);
         }
     }
 }
@@ -398,22 +398,22 @@ pub enum LatticeVarResult<V,T> {
 pub fn lattice_vars<L:LatticeDir + Combine,
                     T:Copy + InferStr + LatticeValue,
                     V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
-    self: &L,                           // defines whether we want LUB or GLB
+    this: &L,                           // defines whether we want LUB or GLB
     a_vid: V,                          // first variable
     b_vid: V,                          // second variable
     lattice_dir_op: LatticeDirOp<T>)    // LUB or GLB operation on types
     -> cres<LatticeVarResult<V,T>> {
-    let nde_a = self.infcx().get(a_vid);
-    let nde_b = self.infcx().get(b_vid);
+    let nde_a = this.infcx().get(a_vid);
+    let nde_b = this.infcx().get(b_vid);
     let a_vid = nde_a.root;
     let b_vid = nde_b.root;
     let a_bounds = &nde_a.possible_types;
     let b_bounds = &nde_b.possible_types;
 
     debug!("%s.lattice_vars(%s=%s <: %s=%s)",
-           self.tag(),
-           a_vid.to_str(), a_bounds.inf_str(self.infcx()),
-           b_vid.to_str(), b_bounds.inf_str(self.infcx()));
+           this.tag(),
+           a_vid.to_str(), a_bounds.inf_str(this.infcx()),
+           b_vid.to_str(), b_bounds.inf_str(this.infcx()));
 
     // Same variable: the easy case.
     if a_vid == b_vid {
@@ -422,10 +422,10 @@ pub fn lattice_vars<L:LatticeDir + Combine,
 
     // If both A and B have an UB type, then we can just compute the
     // LUB of those types:
-    let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
+    let a_bnd = this.bnd(a_bounds), b_bnd = this.bnd(b_bounds);
     match (a_bnd, b_bnd) {
         (Some(ref a_ty), Some(ref b_ty)) => {
-            match self.infcx().try(|| lattice_dir_op(a_ty, b_ty) ) {
+            match this.infcx().try(|| lattice_dir_op(a_ty, b_ty) ) {
                 Ok(t) => return Ok(ValueResult(t)),
                 Err(_) => { /*fallthrough */ }
             }
@@ -435,7 +435,7 @@ pub fn lattice_vars<L:LatticeDir + Combine,
 
     // Otherwise, we need to merge A and B into one variable.  We can
     // then use either variable as an upper bound:
-    let cf = self.combine_fields();
+    let cf = this.combine_fields();
     do cf.var_sub_var(a_vid, b_vid).then {
         Ok(VarResult(a_vid))
     }
@@ -444,12 +444,12 @@ pub fn lattice_vars<L:LatticeDir + Combine,
 pub fn lattice_var_and_t<L:LatticeDir + Combine,
                          T:Copy + InferStr + LatticeValue,
                          V:Copy + Eq + ToStr + Vid + UnifyVid<Bounds<T>>>(
-    self: &L,
+    this: &L,
     a_id: V,
     b: &T,
     lattice_dir_op: LatticeDirOp<T>)
     -> cres<T> {
-    let nde_a = self.infcx().get(a_id);
+    let nde_a = this.infcx().get(a_id);
     let a_id = nde_a.root;
     let a_bounds = &nde_a.possible_types;
 
@@ -457,24 +457,24 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
     // apply equally well to GLB if you inverse upper/lower/sub/super/etc.
 
     debug!("%s.lattice_var_and_t(%s=%s <: %s)",
-           self.tag(),
+           this.tag(),
            a_id.to_str(),
-           a_bounds.inf_str(self.infcx()),
-           b.inf_str(self.infcx()));
+           a_bounds.inf_str(this.infcx()),
+           b.inf_str(this.infcx()));
 
-    match self.bnd(a_bounds) {
+    match this.bnd(a_bounds) {
         Some(ref a_bnd) => {
             // If a has an upper bound, return the LUB(a.ub, b)
-            debug!("bnd=Some(%s)", a_bnd.inf_str(self.infcx()));
+            debug!("bnd=Some(%s)", a_bnd.inf_str(this.infcx()));
             lattice_dir_op(a_bnd, b)
         }
         None => {
             // If a does not have an upper bound, make b the upper bound of a
             // and then return b.
             debug!("bnd=None");
-            let a_bounds = self.with_bnd(a_bounds, *b);
-            do self.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
-                self.infcx().set(a_id, Root(a_bounds, nde_a.rank));
+            let a_bounds = this.with_bnd(a_bounds, *b);
+            do this.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
+                this.infcx().set(a_id, Root(a_bounds, nde_a.rank));
                 Ok(*b)
             }
         }
@@ -485,14 +485,14 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
 // Random utility functions used by LUB/GLB when computing LUB/GLB of
 // fn types
 
-pub fn var_ids<T:Combine>(self: &T, isr: isr_alist) -> ~[RegionVid] {
+pub fn var_ids<T:Combine>(this: &T, isr: isr_alist) -> ~[RegionVid] {
     let mut result = ~[];
     for list::each(isr) |pair| {
         match pair.second() {
             ty::re_infer(ty::ReVar(r)) => { result.push(r); }
             r => {
-                self.infcx().tcx.sess.span_bug(
-                    self.span(),
+                this.infcx().tcx.sess.span_bug(
+                    this.span(),
                     fmt!("Found non-region-vid: %?", r));
             }
         }
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index 34e006c9615..bd5821873d2 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -149,7 +149,7 @@ impl Combine for Lub {
                                               a_isr, r));
         return Ok(sig1);
 
-        fn generalize_region(self: &Lub,
+        fn generalize_region(this: &Lub,
                              snapshot: uint,
                              new_vars: &[RegionVid],
                              a_isr: isr_alist,
@@ -160,7 +160,7 @@ impl Combine for Lub {
                 return r0;
             }
 
-            let tainted = self.infcx.region_vars.tainted(snapshot, r0);
+            let tainted = this.infcx.region_vars.tainted(snapshot, r0);
 
             // Variables created during LUB computation which are
             // *related* to regions that pre-date the LUB computation
@@ -187,8 +187,8 @@ impl Combine for Lub {
                 }
             }
 
-            self.infcx.tcx.sess.span_bug(
-                self.span,
+            this.infcx.tcx.sess.span_bug(
+                this.span,
                 fmt!("Region %? is not associated with \
                       any bound region from A!", r0));
         }
diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs
index 96e289bc497..a5e8b42dee5 100644
--- a/src/librustc/middle/typeck/infer/region_inference.rs
+++ b/src/librustc/middle/typeck/infer/region_inference.rs
@@ -876,7 +876,7 @@ pub impl RegionVarBindings {
                     a: Region,
                     b: Region,
                     span: span,
-                    relate: &fn(self: &mut RegionVarBindings,
+                    relate: &fn(this: &mut RegionVarBindings,
                                 old_r: Region,
                                 new_r: Region) -> cres<()>)
                  -> cres<Region> {
@@ -1103,11 +1103,11 @@ priv impl RegionVarBindings {
             Equal => ty::re_free(*a)
         };
 
-        fn helper(self: &RegionVarBindings,
+        fn helper(this: &RegionVarBindings,
                   a: &FreeRegion,
                   b: &FreeRegion) -> ty::Region
         {
-            let rm = self.tcx.region_maps;
+            let rm = this.tcx.region_maps;
             if rm.sub_free_region(*a, *b) {
                 ty::re_free(*b)
             } else if rm.sub_free_region(*b, *a) {
@@ -1198,17 +1198,17 @@ priv impl RegionVarBindings {
             Equal => Ok(ty::re_free(*a))
         };
 
-        fn helper(self: &RegionVarBindings,
+        fn helper(this: &RegionVarBindings,
                   a: &FreeRegion,
                   b: &FreeRegion) -> cres<ty::Region>
         {
-            let rm = self.tcx.region_maps;
+            let rm = this.tcx.region_maps;
             if rm.sub_free_region(*a, *b) {
                 Ok(ty::re_free(*a))
             } else if rm.sub_free_region(*b, *a) {
                 Ok(ty::re_free(*b))
             } else {
-                self.intersect_scopes(ty::re_free(*a), ty::re_free(*b),
+                this.intersect_scopes(ty::re_free(*a), ty::re_free(*b),
                                       a.scope_id, b.scope_id)
             }
         }
@@ -1461,13 +1461,13 @@ pub impl RegionVarBindings {
             }
         };
 
-        fn check_node(self: &mut RegionVarBindings,
+        fn check_node(this: &mut RegionVarBindings,
                       a_vid: RegionVid,
                       a_node: &mut GraphNode,
                       a_region: Region,
                       b_region: Region)
                    -> bool {
-            if !self.is_subregion_of(a_region, b_region) {
+            if !this.is_subregion_of(a_region, b_region) {
                 debug!("Setting %? to ErrorValue: %? not subregion of %?",
                        a_vid, a_region, b_region);
                 a_node.value = ErrorValue;
@@ -1475,13 +1475,13 @@ pub impl RegionVarBindings {
             false
         }
 
-        fn adjust_node(self: &mut RegionVarBindings,
+        fn adjust_node(this: &mut RegionVarBindings,
                        a_vid: RegionVid,
                        a_node: &mut GraphNode,
                        a_region: Region,
                        b_region: Region)
                     -> bool {
-            match self.glb_concrete_regions(a_region, b_region) {
+            match this.glb_concrete_regions(a_region, b_region) {
                 Ok(glb) => {
                     if glb == a_region {
                         false
@@ -1744,14 +1744,14 @@ pub impl RegionVarBindings {
         let WalkState {result, dup_found, _} = state;
         return (result, dup_found);
 
-        fn process_edges(self: &mut RegionVarBindings,
+        fn process_edges(this: &mut RegionVarBindings,
                          state: &mut WalkState,
                          graph: &Graph,
                          source_vid: RegionVid,
                          dir: Direction) {
             debug!("process_edges(source_vid=%?, dir=%?)", source_vid, dir);
 
-            for self.each_edge(graph, source_vid, dir) |edge| {
+            for this.each_edge(graph, source_vid, dir) |edge| {
                 match edge.constraint {
                     ConstrainVarSubVar(from_vid, to_vid) => {
                         let opp_vid =
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs
index 316792f688f..e5ed2efa4c2 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc/middle/typeck/rscope.rs
@@ -267,10 +267,10 @@ pub struct binding_rscope {
 }
 
 pub fn in_binding_rscope<RS:region_scope + Copy + 'static>(
-        self: &RS,
+        this: &RS,
         region_param_names: RegionParamNames)
      -> binding_rscope {
-    let base = @copy *self;
+    let base = @copy *this;
     let base = base as @region_scope;
     binding_rscope {
         base: base,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 5daa0de2272..f98cbe2e5b9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -572,6 +572,9 @@ pub enum expr_ {
     expr_field(@expr, ident, ~[@Ty]),
     expr_index(@expr, @expr),
     expr_path(@Path),
+
+    /// The special identifier `self`.
+    expr_self,
     expr_addr_of(mutability, @expr),
     expr_break(Option<ident>),
     expr_again(Option<ident>),
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 1d3af61be70..e1416230720 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -245,6 +245,7 @@ trait ExtCtxtMethods {
     fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
     fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
     fn expr_var(&self, span: span, var: &str) -> @ast::expr;
+    fn expr_self(&self, span: span) -> @ast::expr;
     fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
                   -> @ast::expr;
     fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
@@ -450,6 +451,10 @@ impl ExtCtxtMethods for @ext_ctxt {
         self.expr_path(span, ~[self.ident_of(var)])
     }
 
+    fn expr_self(&self, span: span) -> @ast::expr {
+        self.expr(span, ast::expr_self)
+    }
+
     fn expr_field(
         &self,
         span: span,
@@ -790,12 +795,8 @@ fn mk_struct_ser_impl(
         let expr_lambda = cx.lambda_expr_1(
             cx.expr_method_call(
                 span,
-                cx.expr_field(
-                    span,
-                    cx.expr_var(span, "self"),
-                    field.ident
-                ),
-                cx.ident_of("encode"),
+                cx.expr_field(span, cx.expr_self(span), field.ident),
+                cx.ident_of(~"encode"),
                 ~[cx.expr_var(span, "__s")]
             ),
             cx.ident_of("__s")
@@ -1062,13 +1063,10 @@ fn mk_enum_ser_body(
     // ast for `match *self { $(arms) }`
     let match_expr = cx.expr(
         span,
-        ast::expr_match(
-            cx.expr(
-                span,
-                ast::expr_unary(ast::deref, cx.expr_var(span, "self"))
-            ),
-            arms
-        )
+        ast::expr_match(cx.expr(span,
+                                ast::expr_unary(ast::deref,
+                                                cx.expr_self(span))),
+                        arms)
     );
 
     // ast for `__s.emit_enum($(name), || $(match_expr))`
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 3bfb93b34b3..3f90fd6267b 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -518,6 +518,10 @@ pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm {
     mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span))
 }
 
+pub fn make_self(cx: @ext_ctxt, span: span) -> @ast::expr {
+    build::mk_expr(cx, span, ast::expr_self)
+}
+
 //
 // Duplication functions
 //
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 2786c9c6eb5..a5edd92022f 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -204,8 +204,6 @@ fn expand_deriving_encodable_struct_method(
     type_ident: ident,
     struct_def: &struct_def
 ) -> @method {
-    let self_ident = cx.ident_of("self");
-
     // Create the body of the method.
     let mut idx = 0;
     let mut statements = ~[];
@@ -213,12 +211,10 @@ fn expand_deriving_encodable_struct_method(
         match struct_field.node.kind {
             named_field(ident, _) => {
                 // Create the accessor for this field.
-                let self_field = build::mk_access(
-                    cx,
-                    span,
-                    ~[self_ident],
-                    ident
-                );
+                let self_field = build::mk_access_(cx,
+                                                   span,
+                                                   build::make_self(cx, span),
+                                                   ident);
 
                 // Call the substructure method.
                 let encode_expr = call_substructure_encode_method(
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 78eacafe3d7..3b94a95dfe0 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -371,8 +371,7 @@ pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
                                span: span,
                                arms: ~[ ast::arm ])
                             -> @expr {
-    let self_ident = cx.ident_of("self");
-    let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
+    let self_expr = build::make_self(cx, span);
     let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
     let self_match_expr = ast::expr_match(self_expr, arms);
     build::mk_expr(cx, span, self_match_expr)
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 08947efa7b7..0bb88dae26b 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -191,7 +191,7 @@ fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Gene
     }
 }
 
-/// Lifetimes and bounds on type paramers
+/// Lifetimes and bounds on type parameters
 pub struct LifetimeBounds {
     lifetimes: ~[~str],
     bounds: ~[(~str, ~[Path])]
@@ -218,7 +218,7 @@ pub impl LifetimeBounds {
 
 pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: Option<PtrTy>)
     -> (@expr, ast::self_ty) {
-    let self_path = build::mk_path(cx, span, ~[cx.ident_of("self")]);
+    let self_path = build::make_self(cx, span);
     match self_ptr {
         None => {
             (self_path, respan(span, ast::sty_value))
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index f9346f49b61..5c99ddc9040 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -32,7 +32,7 @@ impl proto_parser for parser::Parser {
                 sep: None,
                 trailing_sep_allowed: false,
             },
-            |self| self.parse_state(proto)
+            |this| this.parse_state(proto)
         );
 
         return proto;
@@ -70,7 +70,7 @@ impl proto_parser for parser::Parser {
                 sep: Some(token::COMMA),
                 trailing_sep_allowed: true,
             },
-            |self| self.parse_message(state)
+            |this| this.parse_message(state)
         );
     }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 338b9b29f00..842f9e9ab33 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -524,6 +524,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
             expr_index(fld.fold_expr(el), fld.fold_expr(er))
         }
         expr_path(pth) => expr_path(fld.fold_path(pth)),
+        expr_self => expr_self,
         expr_break(ref opt_ident) => {
             expr_break(opt_ident.map(|x| fld.fold_ident(*x)))
         }
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 1df6860fede..322f294836b 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -222,7 +222,8 @@ pub impl Parser {
     // signal an error if the given string is a strict keyword
     fn check_strict_keywords_(&self, w: &~str) {
         if self.is_strict_keyword(w) {
-            self.fatal(fmt!("found `%s` in ident position", *w));
+            self.span_err(*self.last_span,
+                          fmt!("found `%s` in ident position", *w));
         }
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index ce41d377346..bbd93b71d36 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -475,10 +475,12 @@ mod test {
                               span:sp(0,6)})
     }
 
-    #[should_fail]
+    // FIXME (#6416): For some reason, this fails and causes a test failure, even though it's
+    // marked as `#[should_fail]`.
+    /*#[should_fail]
     #[test] fn bad_path_expr_1() {
         string_to_expr(@~"::abc::def::return");
-    }
+    }*/
 
     #[test] fn string_to_tts_1 () {
         let (tts,ps) = string_to_tts_t(@~"fn a (b : int) { b; }");
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6b0d5e3d384..a8870eeee22 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -26,7 +26,7 @@ use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
 use ast::{expr_field, expr_fn_block, expr_if, expr_index};
 use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
 use ast::{expr_method_call, expr_paren, expr_path, expr_repeat};
-use ast::{expr_ret, expr_struct, expr_tup, expr_unary};
+use ast::{expr_ret, expr_self, expr_struct, expr_tup, expr_unary};
 use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
 use ast::{expr_vstore_slice, expr_vstore_box};
 use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
@@ -430,8 +430,12 @@ pub impl Parser {
             lifetimes: lifetimes,
         });
 
-        fn parse_onceness(self: &Parser) -> Onceness {
-            if self.eat_keyword(&~"once") { Once } else { Many }
+        fn parse_onceness(this: &Parser) -> Onceness {
+            if this.eat_keyword(&~"once") {
+                Once
+            } else {
+                Many
+            }
         }
     }
 
@@ -1224,6 +1228,9 @@ pub impl Parser {
                                  expr_block(blk));
         } else if token::is_bar(&*self.token) {
             return self.parse_lambda_expr();
+        } else if self.eat_keyword(&~"self") {
+            ex = expr_self;
+            hi = self.span.hi;
         } else if self.eat_keyword(&~"if") {
             return self.parse_if_expr();
         } else if self.eat_keyword(&~"for") {
@@ -2984,9 +2991,7 @@ pub impl Parser {
             }
         }
 
-        fn maybe_parse_borrowed_self_ty(
-            self: &Parser
-        ) -> ast::self_ty_ {
+        fn maybe_parse_borrowed_self_ty(this: &Parser) -> ast::self_ty_ {
             // The following things are possible to see here:
             //
             //     fn(&self)
@@ -2996,37 +3001,29 @@ pub impl Parser {
             //
             // We already know that the current token is `&`.
 
-            if (
-                self.token_is_keyword(&~"self", &self.look_ahead(1)))
-            {
-                self.bump();
-                self.expect_self_ident();
+            if (this.token_is_keyword(&~"self", &this.look_ahead(1))) {
+                this.bump();
+                this.expect_self_ident();
                 sty_region(None, m_imm)
-            } else if (
-                self.token_is_mutability(&self.look_ahead(1)) &&
-                self.token_is_keyword(&~"self", &self.look_ahead(2)))
-            {
-                self.bump();
-                let mutability = self.parse_mutability();
-                self.expect_self_ident();
+            } else if (this.token_is_mutability(&this.look_ahead(1)) &&
+                       this.token_is_keyword(&~"self", &this.look_ahead(2))) {
+                this.bump();
+                let mutability = this.parse_mutability();
+                this.expect_self_ident();
                 sty_region(None, mutability)
-            } else if (
-                self.token_is_lifetime(&self.look_ahead(1)) &&
-                self.token_is_keyword(&~"self", &self.look_ahead(2)))
-            {
-                self.bump();
-                let lifetime = @self.parse_lifetime();
-                self.expect_self_ident();
+            } else if (this.token_is_lifetime(&this.look_ahead(1)) &&
+                       this.token_is_keyword(&~"self", &this.look_ahead(2))) {
+                this.bump();
+                let lifetime = @this.parse_lifetime();
+                this.expect_self_ident();
                 sty_region(Some(lifetime), m_imm)
-            } else if (
-                self.token_is_lifetime(&self.look_ahead(1)) &&
-                self.token_is_mutability(&self.look_ahead(2)) &&
-                self.token_is_keyword(&~"self", &self.look_ahead(3)))
-            {
-                self.bump();
-                let lifetime = @self.parse_lifetime();
-                let mutability = self.parse_mutability();
-                self.expect_self_ident();
+            } else if (this.token_is_lifetime(&this.look_ahead(1)) &&
+                       this.token_is_mutability(&this.look_ahead(2)) &&
+                       this.token_is_keyword(&~"self", &this.look_ahead(3))) {
+                this.bump();
+                let lifetime = @this.parse_lifetime();
+                let mutability = this.parse_mutability();
+                this.expect_self_ident();
                 sty_region(Some(lifetime), mutability)
             } else {
                 sty_static
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 5688678b06a..fde383b445c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -340,7 +340,7 @@ pub mod special_idents {
     pub static main : ident = ident { repr: 26, ctxt: 0};
     pub static opaque : ident = ident { repr: 27, ctxt: 0};
     pub static blk : ident = ident { repr: 28, ctxt: 0};
-    pub static static : ident = ident { repr: 29, ctxt: 0};
+    pub static statik : ident = ident { repr: 29, ctxt: 0};
     pub static intrinsic : ident = ident { repr: 30, ctxt: 0};
     pub static clownshoes_foreign_mod: ident = ident { repr: 31, ctxt: 0};
     pub static unnamed_field: ident = ident { repr: 32, ctxt: 0};
@@ -504,26 +504,17 @@ pub fn mk_fake_ident_interner() -> @ident_interner {
  */
 pub fn keyword_table() -> HashSet<~str> {
     let mut keywords = HashSet::new();
-    let mut tmp = temporary_keyword_table();
     let mut strict = strict_keyword_table();
     let mut reserved = reserved_keyword_table();
 
-    do tmp.consume |word|      { keywords.insert(word); }
-    do strict.consume |word|   { keywords.insert(word); }
-    do reserved.consume |word| { keywords.insert(word); }
-    return keywords;
-}
-
-/// Keywords that may be used as identifiers
-pub fn temporary_keyword_table() -> HashSet<~str> {
-    let mut words = HashSet::new();
-    let keys = ~[
-        ~"self", ~"static",
-    ];
-    do vec::consume(keys) |_, s| {
-        words.insert(s);
+    do strict.consume |word| {
+        keywords.insert(word);
     }
-    return words;
+    do reserved.consume |word| {
+        keywords.insert(word);
+    }
+
+    keywords
 }
 
 /// Full keywords. May not appear anywhere else.
@@ -542,7 +533,7 @@ pub fn strict_keyword_table() -> HashSet<~str> {
         ~"once",
         ~"priv", ~"pub", ~"pure",
         ~"ref", ~"return",
-        ~"struct", ~"super",
+        ~"static", ~"self", ~"struct", ~"super",
         ~"true", ~"trait", ~"type",
         ~"unsafe", ~"use",
         ~"while"
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 9d2927eb74f..2e7c35807e5 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1352,6 +1352,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) {
         word(s.s, ~"]");
       }
       ast::expr_path(path) => print_path(s, path, true),
+      ast::expr_self => word(s.s, ~"self"),
       ast::expr_break(opt_ident) => {
         word(s.s, ~"break");
         space(s.s);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index dcc94c92a88..ea02d84ddac 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -529,6 +529,7 @@ pub fn visit_expr<E: Copy>(ex: @expr, e: E, v: vt<E>) {
             (v.visit_expr)(b, e, v);
         }
         expr_path(p) => visit_path(p, e, v),
+        expr_self => (),
         expr_break(_) => (),
         expr_again(_) => (),
         expr_ret(eo) => visit_expr_opt(eo, e, v),
diff --git a/src/test/compile-fail/issue-5099.rs b/src/test/compile-fail/issue-5099.rs
index 80720f9e863..c2e1fc615cc 100644
--- a/src/test/compile-fail/issue-5099.rs
+++ b/src/test/compile-fail/issue-5099.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 
-trait B < A > { fn a() -> A { self.a} } //~ ERROR unresolved name
+trait B < A > { fn a() -> A { this.a } } //~ ERROR unresolved name
 
 fn main() {}
diff --git a/src/test/compile-fail/use-after-move-self-based-on-type.rs b/src/test/compile-fail/use-after-move-self-based-on-type.rs
index 627b8924b67..d19b4dfbd57 100644
--- a/src/test/compile-fail/use-after-move-self-based-on-type.rs
+++ b/src/test/compile-fail/use-after-move-self-based-on-type.rs
@@ -9,7 +9,7 @@ impl Drop for S {
 pub impl S {
     fn foo(self) -> int {
         self.bar();
-        return self.x;  //~ ERROR use of moved value
+        return self.x;  //~ ERROR use of partially moved value
     }
 
     fn bar(self) {}
diff --git a/src/test/compile-fail/use-after-move-self.rs b/src/test/compile-fail/use-after-move-self.rs
index 11f37df4541..b2eaffdd066 100644
--- a/src/test/compile-fail/use-after-move-self.rs
+++ b/src/test/compile-fail/use-after-move-self.rs
@@ -5,7 +5,7 @@ struct S {
 pub impl S {
     fn foo(self) -> int {
         self.bar();
-        return *self.x;  //~ ERROR use of moved value
+        return *self.x;  //~ ERROR use of partially moved value
     }
 
     fn bar(self) {}