diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 3af1d7ea35b..eee0a48ec67 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -76,7 +76,7 @@ fn kind_to_str(k: Kind) -> ~str {
     if ty::kind_can_be_sent(k) {
         kinds.push(~"owned");
     } else if ty::kind_is_durable(k) {
-        kinds.push(~"durable");
+        kinds.push(~"&static");
     }
 
     str::connect(kinds, ~" ")
@@ -571,7 +571,7 @@ fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool {
         match ty::get(ty).sty {
           ty::ty_param(*) => {
             tcx.sess.span_err(sp, ~"value may contain borrowed \
-                                    pointers; use `durable` bound");
+                                    pointers; use `&static` bound");
           }
           _ => {
             tcx.sess.span_err(sp, ~"value may contain borrowed \
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 3dce81df5f3..e2a5c7ca9f9 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -22,8 +22,8 @@ use middle::pat_util::{pat_bindings};
 use core::cmp;
 use core::str;
 use core::vec;
-use syntax::ast::{_mod, add, arm, binding_mode, bitand, bitor, bitxor, blk};
-use syntax::ast::{capture_clause};
+use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
+use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk, capture_clause};
 use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
 use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
 use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
@@ -4117,8 +4117,11 @@ impl Resolver {
     fn resolve_type_parameters(type_parameters: ~[ty_param],
                                visitor: ResolveVisitor) {
         for type_parameters.each |type_parameter| {
-            for type_parameter.bounds.each |bound| {
-                self.resolve_type(**bound, visitor);
+            for type_parameter.bounds.each |&bound| {
+                match bound {
+                    TraitTyParamBound(ty) => self.resolve_type(ty, visitor),
+                    RegionTyParamBound => {}
+                }
             }
         }
     }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index d29858e1fa4..b4cbc6c3f0e 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1591,7 +1591,7 @@ fn substs_to_str(cx: ctxt, substs: &substs) -> ~str {
 fn param_bound_to_str(cx: ctxt, pb: &param_bound) -> ~str {
     match *pb {
         bound_copy => ~"copy",
-        bound_durable => ~"durable",
+        bound_durable => ~"&static",
         bound_owned => ~"owned",
         bound_const => ~"const",
         bound_trait(t) => ::util::ppaux::ty_to_str(cx, t)
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index db99689f0ad..3743a5e0129 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -50,6 +50,7 @@ use util::ppaux::bound_to_str;
 use core::dvec;
 use core::option;
 use core::vec;
+use syntax::ast::{RegionTyParamBound, TraitTyParamBound};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, split_trait_methods};
@@ -908,36 +909,42 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
     }
 }
 
-// Translate the AST's notion of ty param bounds (which are just newtyped Tys)
-// to ty's notion of ty param bounds, which can either be user-defined traits,
-// or one of the four built-in traits (formerly known as kinds): Const, Copy,
-// Durable, and Send.
+// Translate the AST's notion of ty param bounds (which are an enum consisting
+// of a newtyped Ty or a region) to ty's notion of ty param bounds, which can
+// either be user-defined traits, or one of the four built-in traits (formerly
+// known as kinds): Const, Copy, Durable, and Send.
 fn compute_bounds(ccx: @crate_ctxt,
-                  ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds {
+                  ast_bounds: @~[ast::ty_param_bound])
+               -> ty::param_bounds {
     @do vec::flat_map(*ast_bounds) |b| {
-        let li = &ccx.tcx.lang_items;
-        let ity = ast_ty_to_ty(ccx, empty_rscope, **b);
-        match ty::get(ity).sty {
-            ty::ty_trait(did, _, _) => {
-                if did == li.owned_trait() {
-                    ~[ty::bound_owned]
-                } else if did == li.copy_trait() {
-                    ~[ty::bound_copy]
-                } else if did == li.const_trait() {
-                    ~[ty::bound_const]
-                } else if did == li.durable_trait() {
-                    ~[ty::bound_durable]
-                } else {
-                    // Must be a user-defined trait
-                    ~[ty::bound_trait(ity)]
+        match b {
+            &TraitTyParamBound(b) => {
+                let li = &ccx.tcx.lang_items;
+                let ity = ast_ty_to_ty(ccx, empty_rscope, b);
+                match ty::get(ity).sty {
+                    ty::ty_trait(did, _, _) => {
+                        if did == li.owned_trait() {
+                            ~[ty::bound_owned]
+                        } else if did == li.copy_trait() {
+                            ~[ty::bound_copy]
+                        } else if did == li.const_trait() {
+                            ~[ty::bound_const]
+                        } else if did == li.durable_trait() {
+                            ~[ty::bound_durable]
+                        } else {
+                            // Must be a user-defined trait
+                            ~[ty::bound_trait(ity)]
+                        }
+                    }
+                    _ => {
+                        ccx.tcx.sess.span_err(
+                            (*b).span, ~"type parameter bounds must be \
+                                         trait types");
+                        ~[]
+                    }
                 }
             }
-            _ => {
-                ccx.tcx.sess.span_err(
-                    (*b).span, ~"type parameter bounds must be \
-                                 trait types");
-                ~[]
-            }
+            &RegionTyParamBound => ~[ty::bound_durable]
         }
     }
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 072a7e94fe9..2cd873414c4 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -110,7 +110,10 @@ const crate_node_id: node_id = 0;
 // typeck::collect::compute_bounds matches these against
 // the "special" built-in traits (see middle::lang_items) and
 // detects Copy, Send, Owned, and Const.
-enum ty_param_bound = @Ty;
+enum ty_param_bound {
+    TraitTyParamBound(@Ty),
+    RegionTyParamBound
+}
 
 #[auto_encode]
 #[auto_decode]
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 90df6fde8e3..2b3fefd6e51 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -245,7 +245,7 @@ priv impl ext_ctxt {
         path: @ast::path,
         bounds: @~[ast::ty_param_bound]
     ) -> ast::ty_param {
-        let bound = ast::ty_param_bound(@{
+        let bound = ast::TraitTyParamBound(@{
             id: self.next_id(),
             node: ast::ty_path(path, self.next_id()),
             span: span,
@@ -397,7 +397,7 @@ fn mk_impl(
     let mut trait_tps = vec::append(
         ~[ty_param],
          do tps.map |tp| {
-            let t_bound = ast::ty_param_bound(@{
+            let t_bound = ast::TraitTyParamBound(@{
                 id: cx.next_id(),
                 node: ast::ty_path(path, cx.next_id()),
                 span: span,
diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs
index 8e36dc01e2a..afce1edf158 100644
--- a/src/libsyntax/ext/deriving.rs
+++ b/src/libsyntax/ext/deriving.rs
@@ -13,13 +13,13 @@
 
 use core::prelude::*;
 
-use ast::{Ty, and, bind_by_ref, binop, deref, enum_def, enum_variant_kind};
-use ast::{expr, expr_match, ident, item, item_, item_struct, item_enum};
-use ast::{item_impl, m_imm, meta_item, method, named_field, or, pat};
-use ast::{pat_ident, pat_wild, public, pure_fn, re_anon, spanned, stmt};
-use ast::{struct_def, struct_variant_kind, sty_by_ref, sty_region};
-use ast::{tuple_variant_kind, ty_nil, ty_param, ty_param_bound, ty_path};
-use ast::{ty_rptr, unnamed_field, variant};
+use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
+use ast::{enum_variant_kind, expr, expr_match, ident, item, item_};
+use ast::{item_enum, item_impl, item_struct, m_imm, meta_item, method};
+use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
+use ast::{re_anon, spanned, stmt, struct_def, struct_variant_kind};
+use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, ty_param};
+use ast::{ty_param_bound, ty_path, ty_rptr, unnamed_field, variant};
 use ext::base::ext_ctxt;
 use ext::build;
 use codemap::span;
@@ -211,7 +211,7 @@ fn create_derived_impl(cx: ext_ctxt,
         let bound = build::mk_ty_path_global(cx,
                                              span,
                                              trait_path.map(|x| *x));
-        let bounds = @~[ ty_param_bound(bound) ];
+        let bounds = @~[ TraitTyParamBound(bound) ];
         let impl_ty_param = build::mk_ty_param(cx, ty_param.ident, bounds);
         impl_ty_params.push(move impl_ty_param);
     }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 272ad3456e5..bca2336bc8c 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -141,7 +141,10 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
 }
 
 fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
-    ty_param_bound(fld.fold_ty(*tpb))
+    match tpb {
+        TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_ty(ty)),
+        RegionTyParamBound => RegionTyParamBound
+    }
 }
 
 fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1a549fc93d5..6974ac508aa 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -10,7 +10,8 @@
 
 use core::prelude::*;
 
-use ast::{ProtoBox, ProtoUniq, provided, public, pure_fn, purity, re_static};
+use ast::{ProtoBox, ProtoUniq, RegionTyParamBound, TraitTyParamBound};
+use ast::{provided, public, pure_fn, purity, re_static};
 use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
 use ast::{bind_by_value, bind_by_move, bitand, bitor, bitxor, blk};
 use ast::{blk_check_mode, box, by_copy, by_move, by_ref, by_val};
@@ -2401,8 +2402,16 @@ impl Parser {
     fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
         let mut bounds = ~[];
         if self.eat(token::COLON) {
-            while is_ident(self.token) {
-                if is_ident(self.token) {
+            loop {
+                if self.eat(token::BINOP(token::AND)) {
+                    if self.eat_keyword(~"static") {
+                        bounds.push(RegionTyParamBound);
+                    } else {
+                        self.span_err(copy self.span,
+                                      ~"`&static` is the only permissible \
+                                        region bound here");
+                    }
+                } else if is_ident(self.token) {
                     let maybe_bound = match self.token {
                       token::IDENT(copy sid, _) => {
                         match *self.id_to_str(sid) {
@@ -2415,7 +2424,7 @@ impl Parser {
                                           ObsoleteLowerCaseKindBounds);
                             // Bogus value, but doesn't matter, since
                             // is an error
-                            Some(ty_param_bound(self.mk_ty_path(sid)))
+                            Some(TraitTyParamBound(self.mk_ty_path(sid)))
                           }
 
                           _ => None
@@ -2430,11 +2439,12 @@ impl Parser {
                             bounds.push(bound);
                         }
                         None => {
-                            bounds.push(ty_param_bound(self.parse_ty(false)));
+                            let ty = self.parse_ty(false);
+                            bounds.push(TraitTyParamBound(ty));
                         }
                     }
                 } else {
-                    bounds.push(ty_param_bound(self.parse_ty(false)));
+                    break;
                 }
             }
         }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 272c35152bb..f7117cc7043 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -10,7 +10,7 @@
 
 use core::prelude::*;
 
-use ast::{required, provided};
+use ast::{RegionTyParamBound, TraitTyParamBound, required, provided};
 use ast;
 use ast_util;
 use ast_util::{operator_prec};
@@ -1791,9 +1791,12 @@ fn print_arg_mode(s: ps, m: ast::mode) {
 fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
     if bounds.is_not_empty() {
         word(s.s, ~":");
-        for vec::each(*bounds) |bound| {
+        for vec::each(*bounds) |&bound| {
             nbsp(s);
-            print_type(s, **bound);
+            match bound {
+                TraitTyParamBound(ty) => print_type(s, ty),
+                RegionTyParamBound => word(s.s, ~"&static"),
+            }
         }
     }
 }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 0da6396253e..25ea76d9b51 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -288,8 +288,11 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
 }
 
 fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
-    for vec::each(*bounds) |bound| {
-        (v.visit_ty)(**bound, e, v)
+    for bounds.each |&bound| {
+        match bound {
+            TraitTyParamBound(ty) => (v.visit_ty)(ty, e, v),
+            RegionTyParamBound => ()
+        }
     }
 }
 
diff --git a/src/test/compile-fail/kindck-owned-trait-scoped.rs b/src/test/compile-fail/kindck-owned-trait-scoped.rs
index d1eae60ac9d..b160ffe2ecd 100644
--- a/src/test/compile-fail/kindck-owned-trait-scoped.rs
+++ b/src/test/compile-fail/kindck-owned-trait-scoped.rs
@@ -35,7 +35,7 @@ fn to_foo_2<T:Copy>(t: T) -> foo {
     {f:t} as foo //~ ERROR value may contain borrowed pointers; use `durable` bound
 }
 
-fn to_foo_3<T:Copy Durable>(t: T) -> foo {
+fn to_foo_3<T:Copy &static>(t: T) -> foo {
     // OK---T may escape as part of the returned foo value, but it is
     // owned and hence does not contain borrowed ptrs
     {f:t} as foo
diff --git a/src/test/compile-fail/kindck-owned-trait.rs b/src/test/compile-fail/kindck-owned-trait.rs
index 35dc066e320..63d8212f41d 100644
--- a/src/test/compile-fail/kindck-owned-trait.rs
+++ b/src/test/compile-fail/kindck-owned-trait.rs
@@ -14,7 +14,7 @@ fn to_foo<T: Copy foo>(t: T) -> foo {
     t as foo //~ ERROR value may contain borrowed pointers; use `durable` bound
 }
 
-fn to_foo2<T: Copy foo Durable>(t: T) -> foo {
+fn to_foo2<T: Copy foo &static>(t: T) -> foo {
     t as foo
 }
 
diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs
index 111b621c5a0..9cd7b36095f 100644
--- a/src/test/compile-fail/kindck-owned.rs
+++ b/src/test/compile-fail/kindck-owned.rs
@@ -12,7 +12,7 @@ fn copy1<T: Copy>(t: T) -> fn@() -> T {
     fn@() -> T { t } //~ ERROR value may contain borrowed pointers
 }
 
-fn copy2<T: Copy Durable>(t: T) -> fn@() -> T {
+fn copy2<T: Copy &static>(t: T) -> fn@() -> T {
     fn@() -> T { t }
 }
 
diff --git a/src/test/compile-fail/static-region-bound.rs b/src/test/compile-fail/static-region-bound.rs
new file mode 100644
index 00000000000..b70b0cdf881
--- /dev/null
+++ b/src/test/compile-fail/static-region-bound.rs
@@ -0,0 +1,9 @@
+fn f<T:&static>(_: T) {}
+
+fn main() {
+    let x = @3;
+    f(x);
+    let x = &3;
+    f(x);   //~ ERROR instantiating a type parameter with an incompatible type
+}
+
diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs
index 8acbee4400c..a880b50d628 100644
--- a/src/test/run-pass/alignment-gep-tup-like-1.rs
+++ b/src/test/run-pass/alignment-gep-tup-like-1.rs
@@ -12,7 +12,7 @@ type pair<A,B> = {
     a: A, b: B
 };
 
-fn f<A:Copy Durable>(a: A, b: u16) -> fn@() -> (A, u16) {
+fn f<A:Copy &static>(a: A, b: u16) -> fn@() -> (A, u16) {
     fn@() -> (A, u16) { (a, b) }
 }
 
diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs
index a0b55a1ea8d..a2a97f531de 100644
--- a/src/test/run-pass/close-over-big-then-small-data.rs
+++ b/src/test/run-pass/close-over-big-then-small-data.rs
@@ -16,7 +16,7 @@ type pair<A,B> = {
     a: A, b: B
 };
 
-fn f<A:Copy Durable>(a: A, b: u16) -> fn@() -> (A, u16) {
+fn f<A:Copy &static>(a: A, b: u16) -> fn@() -> (A, u16) {
     fn@() -> (A, u16) { (a, b) }
 }
 
diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs
index a00afd8c6d9..f01b2b082d0 100644
--- a/src/test/run-pass/fixed-point-bind-unique.rs
+++ b/src/test/run-pass/fixed-point-bind-unique.rs
@@ -11,11 +11,11 @@
 // xfail-fast
 #[legacy_modes];
 
-fn fix_help<A: Durable, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B, x: A) -> B {
+fn fix_help<A: &static, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B, x: A) -> B {
     return f({|a|fix_help(f, a)}, x);
 }
 
-fn fix<A: Durable, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
+fn fix<A: &static, B: Owned>(f: extern fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
     return {|a|fix_help(f, a)};
 }
 
diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs
index 7156e015473..0ab6c630ac8 100644
--- a/src/test/run-pass/issue-2734.rs
+++ b/src/test/run-pass/issue-2734.rs
@@ -11,7 +11,7 @@
 trait hax { } 
 impl <A> A: hax { } 
 
-fn perform_hax<T: Durable>(x: @T) -> hax {
+fn perform_hax<T: &static>(x: @T) -> hax {
     x as hax 
 }
 
diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs
index 360e7b3c241..675397a0881 100644
--- a/src/test/run-pass/issue-2735.rs
+++ b/src/test/run-pass/issue-2735.rs
@@ -11,7 +11,7 @@
 trait hax { } 
 impl <A> A: hax { } 
 
-fn perform_hax<T: Durable>(x: @T) -> hax {
+fn perform_hax<T: &static>(x: @T) -> hax {
     x as hax 
 }
 
diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs
index 33e5e386e39..5e66d2c7c19 100644
--- a/src/test/run-pass/issue-2904.rs
+++ b/src/test/run-pass/issue-2904.rs
@@ -59,7 +59,7 @@ fn square_from_char(c: char) -> square {
     }
 }
 
-fn read_board_grid<rdr: Durable io::Reader>(+in: rdr) -> ~[~[square]] {
+fn read_board_grid<rdr: &static io::Reader>(+in: rdr) -> ~[~[square]] {
     let in = (move in) as io::Reader;
     let mut grid = ~[];
     for in.each_line |line| {