about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/comm.rs4
-rw-r--r--src/libcore/core.rc4
-rw-r--r--src/libcore/num/strconv.rs7
-rw-r--r--src/libcore/str.rs7
-rw-r--r--src/libfuzzer/fuzzer.rc4
-rw-r--r--src/librust/rust.rc1
-rw-r--r--src/librustc/middle/astencode.rs14
-rw-r--r--src/librustc/middle/borrowck/gather_loans.rs18
-rw-r--r--src/librustc/middle/borrowck/mod.rs17
-rw-r--r--src/librustc/middle/mem_categorization.rs46
-rw-r--r--src/librustc/middle/moves.rs4
-rw-r--r--src/librustc/middle/trans/callee.rs29
-rw-r--r--src/librustc/middle/trans/common.rs6
-rw-r--r--src/librustc/middle/trans/expr.rs137
-rw-r--r--src/librustc/middle/trans/type_of.rs11
-rw-r--r--src/librustc/middle/ty.rs38
-rw-r--r--src/librustc/middle/typeck/check/method.rs18
-rw-r--r--src/librustc/middle/typeck/check/mod.rs4
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs52
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs24
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs22
-rw-r--r--src/librustc/rustc.rc4
-rw-r--r--src/librustdoc/rustdoc.rc4
-rw-r--r--src/librusti/rusti.rc3
-rw-r--r--src/librustpkg/rustpkg.rc3
-rw-r--r--src/libstd/std.rc4
-rw-r--r--src/libsyntax/ext/auto_encode.rs4
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs10
-rw-r--r--src/libsyntax/opt_vec.rs18
-rw-r--r--src/libsyntax/parse/parser.rs12
-rw-r--r--src/libsyntax/syntax.rc3
-rw-r--r--src/rt/rust_upcall.cpp2
-rw-r--r--src/snapshots.txt2
33 files changed, 370 insertions, 166 deletions
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index b0825816626..238207f12b6 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -17,8 +17,8 @@ use vec;
 
 use pipes::{recv, try_recv, wait_many, peek, PacketHeader};
 
-// NOTE Making this public exposes some plumbing from pipes. Needs
-// some refactoring
+// FIXME #5160: Making this public exposes some plumbing from
+// pipes. Needs some refactoring
 pub use pipes::Selectable;
 
 /// A trait for things that can send multiple messages.
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 91eb61e342e..3e514ce249f 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -41,7 +41,7 @@ Implicitly, all crates behave as if they included the following prologue:
        url = "https://github.com/mozilla/rust/tree/master/src/libcore")];
 
 #[comment = "The Rust core library"];
-#[license = "MIT"];
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 
diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs
index 4322ea40428..50fc1b03ccc 100644
--- a/src/libcore/num/strconv.rs
+++ b/src/libcore/num/strconv.rs
@@ -478,17 +478,16 @@ pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
         }
     }
 
-    // XXX: Bytevector constant from str
     if special {
-        if buf == str::to_bytes("inf") || buf == str::to_bytes("+inf") {
+        if buf == str::inf_buf || buf == str::positive_inf_buf {
             return NumStrConv::inf();
-        } else if buf == str::to_bytes("-inf") {
+        } else if buf == str::negative_inf_buf {
             if negative {
                 return NumStrConv::neg_inf();
             } else {
                 return None;
             }
-        } else if buf == str::to_bytes("NaN") {
+        } else if buf == str::nan_buf {
             return NumStrConv::NaN();
         }
     }
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 6ee6d282841..7dfc52c458a 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -1832,6 +1832,13 @@ const tag_five_b: uint = 248u;
 const max_five_b: uint = 67108864u;
 const tag_six_b: uint = 252u;
 
+// Constants used for converting strs to floats
+pub const inf_buf: [u8*3] = ['i' as u8, 'n' as u8, 'f' as u8];
+pub const positive_inf_buf: [u8*4] = ['+' as u8, 'i' as u8,
+                                      'n' as u8, 'f' as u8];
+pub const negative_inf_buf: [u8*4] = ['-' as u8, 'i' as u8,
+                                      'n' as u8, 'f' as u8];
+pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8];
 
 /**
  * Work with the byte buffer of a string.
diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc
index 97ac8cf2d50..c16a7cf8d3e 100644
--- a/src/libfuzzer/fuzzer.rc
+++ b/src/libfuzzer/fuzzer.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,7 +15,7 @@
        url = "https://github.com/mozilla/rust/tree/master/src/libfuzzer")];
 
 #[comment = "The Rust fuzzer library"];
-#[license = "MIT"];
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 #[no_core];
 
diff --git a/src/librust/rust.rc b/src/librust/rust.rc
index 950623b8760..e60f2bfaa50 100644
--- a/src/librust/rust.rc
+++ b/src/librust/rust.rc
@@ -17,6 +17,7 @@
        uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
        url = "https://github.com/mozilla/rust/tree/master/src/rust")];
 
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 extern mod core(vers = "0.6");
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 222931d1829..d5cb2f8726d 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -451,9 +451,17 @@ impl tr for ast::def {
 
 impl tr for ty::AutoAdjustment {
     fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
-        ty::AutoAdjustment {
-            autoderefs: self.autoderefs,
-            autoref: self.autoref.map(|ar| ar.tr(xcx)),
+        match self {
+            &ty::AutoAddEnv(r, s) => {
+                ty::AutoAddEnv(r.tr(xcx), s)
+            }
+
+            &ty::AutoDerefRef(ref adr) => {
+                ty::AutoDerefRef(ty::AutoDerefRef {
+                    autoderefs: adr.autoderefs,
+                    autoref: adr.autoref.map(|ar| ar.tr(xcx)),
+                })
+            }
         }
     }
 }
diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs
index c6f4f04fe71..ab343456ef4 100644
--- a/src/librustc/middle/borrowck/gather_loans.rs
+++ b/src/librustc/middle/borrowck/gather_loans.rs
@@ -299,17 +299,27 @@ pub impl GatherLoanCtxt {
                expr_repr(self.tcx(), expr), adjustment);
         let _i = indenter();
 
-        match adjustment.autoref {
-            None => {
+        match *adjustment {
+            ty::AutoAddEnv(*) => {
+                debug!("autoaddenv -- no autoref");
+                return;
+            }
+
+            ty::AutoDerefRef(
+                ty::AutoDerefRef {
+                    autoref: None, _ }) => {
                 debug!("no autoref");
                 return;
             }
 
-            Some(ref autoref) => {
+            ty::AutoDerefRef(
+                ty::AutoDerefRef {
+                    autoref: Some(ref autoref),
+                    autoderefs: autoderefs}) => {
                 let mcx = &mem_categorization_ctxt {
                     tcx: self.tcx(),
                     method_map: self.bccx.method_map};
-                let mut cmt = mcx.cat_expr_autoderefd(expr, adjustment);
+                let mut cmt = mcx.cat_expr_autoderefd(expr, autoderefs);
                 debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt));
 
                 match autoref.kind {
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 9bdf69f4c88..e0f3aad4bc2 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -480,9 +480,20 @@ pub impl BorrowckCtxt {
     }
 
     fn cat_expr_autoderefd(&self, expr: @ast::expr,
-                           adj: @ty::AutoAdjustment)
-                        -> cmt {
-        cat_expr_autoderefd(self.tcx, self.method_map, expr, adj)
+                           adj: @ty::AutoAdjustment) -> cmt {
+        match *adj {
+            ty::AutoAddEnv(*) => {
+                // no autoderefs
+                cat_expr_unadjusted(self.tcx, self.method_map, expr)
+            }
+
+            ty::AutoDerefRef(
+                ty::AutoDerefRef {
+                    autoderefs: autoderefs, _}) => {
+                cat_expr_autoderefd(self.tcx, self.method_map, expr,
+                                    autoderefs)
+            }
+        }
     }
 
     fn cat_def(&self,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 227d262a79e..7a6a434c41f 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -241,12 +241,12 @@ pub fn cat_expr_autoderefd(
     tcx: ty::ctxt,
     method_map: typeck::method_map,
     expr: @ast::expr,
-    adj: @ty::AutoAdjustment) -> cmt {
-
+    autoderefs: uint) -> cmt
+{
     let mcx = &mem_categorization_ctxt {
         tcx: tcx, method_map: method_map
     };
-    return mcx.cat_expr_autoderefd(expr, adj);
+    return mcx.cat_expr_autoderefd(expr, autoderefs);
 }
 
 pub fn cat_def(
@@ -361,28 +361,38 @@ pub impl mem_categorization_ctxt {
                 self.cat_expr_unadjusted(expr)
             }
 
-            Some(adjustment) => {
-                match adjustment.autoref {
-                    Some(_) => {
-                        // Equivalent to &*expr or something similar.
-                        // This is an rvalue, effectively.
-                        let expr_ty = ty::expr_ty(self.tcx, expr);
-                        self.cat_rvalue(expr, expr_ty)
-                    }
-                    None => {
-                        // Equivalent to *expr or something similar.
-                        self.cat_expr_autoderefd(expr, adjustment)
-                    }
-                }
+            Some(@ty::AutoAddEnv(*)) => {
+                // Convert a bare fn to a closure by adding NULL env.
+                // Result is an rvalue.
+                let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
+                self.cat_rvalue(expr, expr_ty)
+            }
+
+            Some(
+                @ty::AutoDerefRef(
+                    ty::AutoDerefRef {
+                        autoref: Some(_), _})) => {
+                // Equivalent to &*expr or something similar.
+                // Result is an rvalue.
+                let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
+                self.cat_rvalue(expr, expr_ty)
+            }
+
+            Some(
+                @ty::AutoDerefRef(
+                    ty::AutoDerefRef {
+                        autoref: None, autoderefs: autoderefs})) => {
+                // Equivalent to *expr or something similar.
+                self.cat_expr_autoderefd(expr, autoderefs)
             }
         }
     }
 
     fn cat_expr_autoderefd(&self,
                            expr: @ast::expr,
-                           adjustment: &ty::AutoAdjustment) -> cmt {
+                           autoderefs: uint) -> cmt {
         let mut cmt = self.cat_expr_unadjusted(expr);
-        for uint::range(1, adjustment.autoderefs+1) |deref| {
+        for uint::range(1, autoderefs+1) |deref| {
             cmt = self.cat_deref(expr, cmt, deref);
         }
         return cmt;
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index d5adfee65af..b9f35af37e0 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -410,7 +410,9 @@ pub impl VisitContext {
         // those adjustments is to take a reference, then it's only
         // reading the underlying expression, not moving it.
         let comp_mode = match self.tcx.adjustments.find(&expr.id) {
-            Some(adj) if adj.autoref.is_some() => Read,
+            Some(@ty::AutoDerefRef(
+                ty::AutoDerefRef {
+                    autoref: Some(_), _})) => Read,
             _ => expr_mode.component_mode(expr)
         };
 
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 3a68e8e94c6..12864f12abd 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -39,6 +39,7 @@ use middle::trans::inline;
 use middle::trans::meth;
 use middle::trans::monomorphize;
 use middle::trans::type_of;
+use middle::ty::ty_to_str;
 use middle::ty;
 use middle::typeck;
 use util::common::indenter;
@@ -94,10 +95,25 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
     }
 
     // any other expressions are closures:
-    return closure_callee(&expr::trans_to_datum(bcx, expr));
-
-    fn closure_callee(db: &DatumBlock) -> Callee {
-        return Callee {bcx: db.bcx, data: Closure(db.datum)};
+    return datum_callee(bcx, expr);
+
+    fn datum_callee(bcx: block, expr: @ast::expr) -> Callee {
+        let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
+        match ty::get(datum.ty).sty {
+            ty::ty_bare_fn(*) => {
+                let llval = datum.to_appropriate_llval(bcx);
+                return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
+            }
+            ty::ty_closure(*) => {
+                return Callee {bcx: bcx, data: Closure(datum)};
+            }
+            _ => {
+                bcx.tcx().sess.span_bug(
+                    expr.span,
+                    fmt!("Type of callee is neither bare-fn nor closure: %s",
+                         bcx.ty_to_str(datum.ty)));
+            }
+        }
     }
 
     fn fn_callee(bcx: block, fd: FnData) -> Callee {
@@ -129,7 +145,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
             ast::def_binding(*) |
             ast::def_upvar(*) |
             ast::def_self(*) => {
-                closure_callee(&expr::trans_to_datum(bcx, ref_expr))
+                datum_callee(bcx, ref_expr)
             }
             ast::def_mod(*) | ast::def_foreign_mod(*) |
             ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
@@ -392,7 +408,6 @@ pub fn trans_lang_call_with_type_params(bcx: block,
                                                     fty);
                     let mut llfnty = type_of::type_of(callee.bcx.ccx(),
                                                       substituted);
-                    llfnty = lib::llvm::struct_tys(llfnty)[0];
                     new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
                 }
                 _ => fail!()
@@ -715,6 +730,8 @@ pub fn trans_arg_expr(bcx: block,
                     }
 
                     ast::by_copy => {
+                        debug!("by copy arg with type %s, storing to scratch",
+                               bcx.ty_to_str(arg_datum.ty));
                         let scratch = scratch_datum(bcx, arg_datum.ty, false);
 
                         arg_datum.store_to_datum(bcx, arg_expr.id,
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 97f8ec84a1d..c2a7abe747b 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -1344,6 +1344,12 @@ pub fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
     node_id_type(bcx, ex.id)
 }
 
+pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t {
+    let tcx = bcx.tcx();
+    let t = ty::expr_ty_adjusted(tcx, ex);
+    monomorphize_type(bcx, t)
+}
+
 pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
     let tcx = bcx.tcx();
     let params = ty::node_id_to_type_params(tcx, id);
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index c6ed190c7c3..7fe2bd605e9 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -144,7 +144,8 @@ use middle::trans::tvec;
 use middle::trans::type_of;
 use middle::ty;
 use middle::ty::struct_mutable_fields;
-use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
+use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
+                 AutoDerefRef, AutoAddEnv};
 use util::common::indenter;
 use util::ppaux::ty_to_str;
 
@@ -197,7 +198,14 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
         None => {
             trans_to_datum_unadjusted(bcx, expr)
         }
-        Some(adj) => {
+        Some(@AutoAddEnv(*)) => {
+            let mut bcx = bcx;
+            let mut datum = unpack_datum!(bcx, {
+                trans_to_datum_unadjusted(bcx, expr)
+            });
+            add_env(bcx, expr, datum)
+        }
+        Some(@AutoDerefRef(ref adj)) => {
             let mut bcx = bcx;
             let mut datum = unpack_datum!(bcx, {
                 trans_to_datum_unadjusted(bcx, expr)
@@ -266,6 +274,25 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
         DatumBlock {bcx: bcx, datum: scratch}
     }
 
+    fn add_env(bcx: block, expr: @ast::expr, datum: Datum) -> DatumBlock {
+        // This is not the most efficient thing possible; since closures
+        // are two words it'd be better if this were compiled in
+        // 'dest' mode, but I can't find a nice way to structure the
+        // code and keep it DRY that accommodates that use case at the
+        // moment.
+
+        let tcx = bcx.tcx();
+        let closure_ty = expr_ty_adjusted(bcx, expr);
+        debug!("add_env(closure_ty=%s)", ty_to_str(tcx, closure_ty));
+        let scratch = scratch_datum(bcx, closure_ty, false);
+        let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
+        assert datum.appropriate_mode() == ByValue;
+        Store(bcx, datum.to_appropriate_llval(bcx), llfn);
+        let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
+        Store(bcx, base::null_env_ptr(bcx), llenv);
+        DatumBlock {bcx: bcx, datum: scratch}
+    }
+
     fn auto_slice_and_ref(bcx: block, datum: Datum) -> DatumBlock {
         let DatumBlock { bcx, datum } = auto_slice(bcx, datum);
         auto_ref(bcx, datum)
@@ -420,6 +447,9 @@ 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(_) => {
+            return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
+        }
         ast::expr_vstore(contents, ast::expr_vstore_box) |
         ast::expr_vstore(contents, ast::expr_vstore_mut_box) => {
             return tvec::trans_uniq_or_managed_vstore(bcx, heap_managed,
@@ -685,22 +715,13 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
     };
 
     match def {
-        ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
-            let fn_data = callee::trans_fn_ref(bcx, did, ref_expr.id);
-            return fn_data_to_datum(bcx, did, fn_data, lldest);
-        }
-        ast::def_static_method(impl_did, Some(trait_did), _) => {
-            let fn_data = meth::trans_static_method_callee(bcx, impl_did,
-                                                           trait_did,
-                                                           ref_expr.id);
-            return fn_data_to_datum(bcx, impl_did, fn_data, lldest);
-        }
         ast::def_variant(tid, vid) => {
             let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
             if variant_info.args.len() > 0u {
                 // N-ary variant.
                 let fn_data = callee::trans_fn_ref(bcx, vid, ref_expr.id);
-                return fn_data_to_datum(bcx, vid, fn_data, lldest);
+                Store(bcx, fn_data.llfn, lldest);
+                return bcx;
             } else if !ty::enum_is_univariant(ccx.tcx, tid) {
                 // Nullary variant.
                 let lldiscrimptr = GEPi(bcx, lldest, [0u, 0u]);
@@ -725,6 +746,66 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
     }
 }
 
+fn trans_def_datum_unadjusted(bcx: block,
+                              ref_expr: @ast::expr,
+                              def: ast::def) -> DatumBlock
+{
+    let _icx = bcx.insn_ctxt("trans_def_datum_unadjusted");
+
+    match def {
+        ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
+            let fn_data = callee::trans_fn_ref(bcx, did, ref_expr.id);
+            return fn_data_to_datum(bcx, ref_expr, did, fn_data);
+        }
+        ast::def_static_method(impl_did, Some(trait_did), _) => {
+            let fn_data = meth::trans_static_method_callee(bcx, impl_did,
+                                                           trait_did,
+                                                           ref_expr.id);
+            return fn_data_to_datum(bcx, ref_expr, impl_did, fn_data);
+        }
+        _ => {
+            bcx.tcx().sess.span_bug(ref_expr.span, fmt!(
+                "Non-DPS def %? referened by %s",
+                def, bcx.node_id_to_str(ref_expr.id)));
+        }
+    }
+
+    fn fn_data_to_datum(bcx: block,
+                        ref_expr: @ast::expr,
+                        def_id: ast::def_id,
+                        fn_data: callee::FnData) -> DatumBlock {
+        /*!
+        *
+        * Translates a reference to a top-level fn item into a rust
+        * value.  This is just a fn pointer.
+        */
+
+        let is_extern = {
+            let fn_tpt = ty::lookup_item_type(bcx.tcx(), def_id);
+            ty::ty_fn_purity(fn_tpt.ty) == ast::extern_fn
+        };
+        let (rust_ty, llval) = if is_extern {
+            let rust_ty = ty::mk_ptr(
+                bcx.tcx(),
+                ty::mt {
+                    ty: ty::mk_mach_uint(bcx.tcx(), ast::ty_u8),
+                    mutbl: ast::m_imm
+                }); // *u8
+            (rust_ty, PointerCast(bcx, fn_data.llfn, T_ptr(T_i8())))
+        } else {
+            let fn_ty = expr_ty(bcx, ref_expr);
+            (fn_ty, fn_data.llfn)
+        };
+        return DatumBlock {
+            bcx: bcx,
+            datum: Datum {val: llval,
+                          ty: rust_ty,
+                          mode: ByValue,
+                          source: RevokeClean}
+        };
+    }
+}
+
 fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
     /*!
      *
@@ -1012,36 +1093,6 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
     }
 }
 
-fn fn_data_to_datum(bcx: block,
-                    def_id: ast::def_id,
-                    fn_data: callee::FnData,
-                    lldest: ValueRef) -> block {
-    //!
-    //
-    // Translates a reference to a top-level fn item into a rust
-    // value.  This is generally a Rust closure pair: (fn ptr, env)
-    // where the environment is NULL.  However, extern functions for
-    // interfacing with C are represted as just the fn ptr with type
-    // *u8.
-    //
-    // Strictly speaking, references to extern fns ought to be
-    // RvalueDatumExprs, but it's not worth the complexity to avoid the
-    // extra stack slot that LLVM probably optimizes away anyhow.
-
-    let fn_tpt = ty::lookup_item_type(bcx.tcx(), def_id);
-    if ty::ty_fn_purity(fn_tpt.ty) == ast::extern_fn {
-        let val = PointerCast(bcx, fn_data.llfn, T_ptr(T_i8()));
-        Store(bcx, val, lldest);
-        return bcx;
-    }
-
-    let llfn = GEPi(bcx, lldest, [0u, abi::fn_field_code]);
-    Store(bcx, fn_data.llfn, llfn);
-    let llenv = GEPi(bcx, lldest, [0u, abi::fn_field_box]);
-    Store(bcx, base::null_env_ptr(bcx), llenv);
-    return bcx;
-}
-
 // The optional node ID here is the node ID of the path identifying the enum
 // variant in use. If none, this cannot possibly an enum variant (so, if it
 // is and `node_id_opt` is none, this function fails).
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 7d3aa4c24f4..fdb5e94559f 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -134,8 +134,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
             T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())])
         }
 
-        // FIXME(#4804) Bare fn repr
-        ty::ty_bare_fn(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
+        ty::ty_bare_fn(*) => T_ptr(T_i8()),
         ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
         ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
 
@@ -173,7 +172,9 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
         ty::ty_enum(def_id, _) => T_struct(enum_body_types(cx, def_id, t)),
 
         ty::ty_self | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
-            cx.tcx.sess.bug(~"fictitious type in sizing_type_of()")
+            cx.tcx.sess.bug(
+                fmt!("fictitious type %? in sizing_type_of()",
+                     ty::get(t).sty))
         }
     };
 
@@ -270,9 +271,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
         T_struct(~[T_struct(tys)])
       }
 
-      // FIXME(#4804) Bare fn repr
-      // ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
-      ty::ty_bare_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
+      ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
       ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
       ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
       ty::ty_type => T_ptr(cx.tydesc_type),
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 90f97a939ad..cabda54eeea 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -172,7 +172,14 @@ impl cmp::Eq for region_variance {
 
 #[auto_encode]
 #[auto_decode]
-pub struct AutoAdjustment {
+pub enum AutoAdjustment {
+    AutoAddEnv(ty::Region, ast::Sigil),
+    AutoDerefRef(AutoDerefRef)
+}
+
+#[auto_encode]
+#[auto_decode]
+pub struct AutoDerefRef {
     autoderefs: uint,
     autoref: Option<AutoRef>
 }
@@ -198,7 +205,7 @@ pub enum AutoRefKind {
     AutoBorrowVecRef,
 
     /// Convert from @fn()/~fn() to &fn()
-    AutoBorrowFn,
+    AutoBorrowFn
 }
 
 // Stores information about provided methods (a.k.a. default methods) in
@@ -1475,7 +1482,6 @@ pub fn type_is_structural(ty: t) -> bool {
     match get(ty).sty {
       ty_rec(_) | ty_struct(*) | ty_tup(_) | ty_enum(*) |
       ty_closure(_) |
-      ty_bare_fn(_) | // FIXME(#4804) Bare fn repr
       ty_trait(*) |
       ty_evec(_, vstore_fixed(_)) | ty_estr(vstore_fixed(_)) |
       ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_))
@@ -1585,7 +1591,7 @@ pub pure fn type_is_scalar(ty: t) -> bool {
     match get(ty).sty {
       ty_nil | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
       ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_type |
-      ty_ptr(_) => true,
+      ty_bare_fn(*) | ty_ptr(_) => true,
       _ => false
     }
 }
@@ -2882,7 +2888,25 @@ pub fn expr_ty_adjusted(cx: ctxt, expr: @ast::expr) -> t {
     return match cx.adjustments.find(&expr.id) {
         None => unadjusted_ty,
 
-        Some(adj) => {
+        Some(@AutoAddEnv(r, s)) => {
+            match ty::get(unadjusted_ty).sty {
+                ty::ty_bare_fn(ref b) => {
+                    ty::mk_closure(
+                        cx,
+                        ty::ClosureTy {purity: b.purity,
+                                       sigil: s,
+                                       onceness: ast::Many,
+                                       region: r,
+                                       sig: copy b.sig})
+                }
+                ref b => {
+                    cx.sess.bug(
+                        fmt!("add_env adjustment on non-bare-fn: %?", b));
+                }
+            }
+        }
+
+        Some(@AutoDerefRef(ref adj)) => {
             let mut adjusted_ty = unadjusted_ty;
 
             for uint::range(0, adj.autoderefs) |i| {
@@ -3064,9 +3088,11 @@ pub fn expr_kind(tcx: ctxt,
     match expr.node {
         ast::expr_path(*) => {
             match resolve_expr(tcx, expr) {
-                ast::def_fn(*) | ast::def_static_method(*) |
                 ast::def_variant(*) | ast::def_struct(*) => RvalueDpsExpr,
 
+                // Fn pointers are just scalar values.
+                ast::def_fn(*) | ast::def_static_method(*) => RvalueDatumExpr,
+
                 // Note: there is actually a good case to be made that
                 // def_args, particularly those of immediate type, ought to
                 // considered rvalues.
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 34b650aa180..63d09d88f52 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -799,26 +799,28 @@ pub impl LookupContext {
                 let region = self.infcx().next_region_var(self.expr.span,
                                                           self.expr.id);
                 (ty::mk_rptr(tcx, region, self_mt),
-                 ty::AutoAdjustment {
+                 ty::AutoDerefRef(ty::AutoDerefRef {
                      autoderefs: autoderefs+1,
                      autoref: Some(ty::AutoRef {kind: AutoPtr,
                                                 region: region,
-                                                mutbl: self_mt.mutbl})})
+                                                mutbl: self_mt.mutbl})}))
             }
             ty::ty_evec(self_mt, vstore_slice(_))
             if self_mt.mutbl == m_mutbl => {
                 let region = self.infcx().next_region_var(self.expr.span,
                                                           self.expr.id);
                 (ty::mk_evec(tcx, self_mt, vstore_slice(region)),
-                 ty::AutoAdjustment {
+                 ty::AutoDerefRef(ty::AutoDerefRef {
                     autoderefs: autoderefs,
                     autoref: Some(ty::AutoRef {kind: AutoBorrowVec,
                                                region: region,
-                                               mutbl: self_mt.mutbl})})
+                                               mutbl: self_mt.mutbl})}))
             }
             _ => {
-                (self_ty, ty::AutoAdjustment {autoderefs: autoderefs,
-                                              autoref: None})
+                (self_ty,
+                 ty::AutoDerefRef(ty::AutoDerefRef {
+                     autoderefs: autoderefs,
+                     autoref: None}))
             }
         };
     }
@@ -947,14 +949,14 @@ pub impl LookupContext {
                 Some(mme) => {
                     self.fcx.write_adjustment(
                         self.self_expr.id,
-                        @ty::AutoAdjustment {
+                        @ty::AutoDerefRef(ty::AutoDerefRef {
                             autoderefs: autoderefs,
                             autoref: Some(ty::AutoRef {
                                 kind: kind,
                                 region: region,
                                 mutbl: *mutbl,
                             }),
-                        });
+                        }));
                     return Some(mme);
                 }
             }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 3bf474b2bed..9ca8268171b 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -749,7 +749,9 @@ pub impl FnCtxt {
         if derefs == 0 { return; }
         self.write_adjustment(
             node_id,
-            @ty::AutoAdjustment { autoderefs: derefs, autoref: None }
+            @ty::AutoDerefRef(ty::AutoDerefRef {
+                autoderefs: derefs,
+                autoref: None })
         );
     }
 
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index bf6ddc4f542..1f2dfe7192f 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -184,8 +184,13 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
     debug!("visit_expr(e=%s)", rcx.fcx.expr_to_str(expr));
 
     for rcx.fcx.inh.adjustments.find(&expr.id).each |adjustment| {
-        for adjustment.autoref.each |autoref| {
-            guarantor::for_autoref(rcx, expr, *adjustment, autoref);
+        match *adjustment {
+            @ty::AutoDerefRef(
+                ty::AutoDerefRef {
+                    autoderefs: autoderefs, autoref: Some(ref autoref)}) => {
+                guarantor::for_autoref(rcx, expr, autoderefs, autoref);
+            }
+            _ => {}
         }
     }
 
@@ -329,9 +334,11 @@ pub fn constrain_auto_ref(rcx: @mut Rcx, expr: @ast::expr) {
 
     let adjustment = rcx.fcx.inh.adjustments.find(&expr.id);
     let region = match adjustment {
-        Some(@ty::AutoAdjustment { autoref: Some(ref auto_ref), _ }) => {
+        Some(@ty::AutoDerefRef(
+            ty::AutoDerefRef {
+                autoref: Some(ref auto_ref), _})) => {
             auto_ref.region
-        },
+        }
         _ => { return; }
     };
 
@@ -563,7 +570,7 @@ pub mod guarantor {
 
     pub fn for_autoref(rcx: @mut Rcx,
                        expr: @ast::expr,
-                       adjustment: &ty::AutoAdjustment,
+                       autoderefs: uint,
                        autoref: &ty::AutoRef) {
         /*!
          *
@@ -578,7 +585,7 @@ pub mod guarantor {
 
         let mut expr_ct = categorize_unadjusted(rcx, expr);
         expr_ct = apply_autoderefs(
-            rcx, expr, adjustment.autoderefs, expr_ct);
+            rcx, expr, autoderefs, expr_ct);
         for expr_ct.cat.guarantor.each |g| {
             infallibly_mk_subr(rcx, true, expr.span, autoref.region, *g);
         }
@@ -723,19 +730,32 @@ pub mod guarantor {
         let mut expr_ct = categorize_unadjusted(rcx, expr);
         debug!("before adjustments, cat=%?", expr_ct.cat);
 
-        for rcx.fcx.inh.adjustments.find(&expr.id).each |adjustment| {
-            debug!("adjustment=%?", adjustment);
+        match rcx.fcx.inh.adjustments.find(&expr.id) {
+            Some(@ty::AutoAddEnv(*)) => {
+                // This is basically an rvalue, not a pointer, no regions
+                // involved.
+                expr_ct.cat = ExprCategorization {
+                    guarantor: None,
+                    pointer: NotPointer
+                };
+            }
+
+            Some(@ty::AutoDerefRef(ref adjustment)) => {
+                debug!("adjustment=%?", adjustment);
 
-            expr_ct = apply_autoderefs(
-                rcx, expr, adjustment.autoderefs, expr_ct);
+                expr_ct = apply_autoderefs(
+                    rcx, expr, adjustment.autoderefs, expr_ct);
 
-            for adjustment.autoref.each |autoref| {
-                // If there is an autoref, then the result of this
-                // expression will be some sort of borrowed pointer.
-                expr_ct.cat.guarantor = None;
-                expr_ct.cat.pointer = BorrowedPointer(autoref.region);
-                debug!("autoref, cat=%?", expr_ct.cat);
+                for adjustment.autoref.each |autoref| {
+                    // If there is an autoref, then the result of this
+                    // expression will be some sort of borrowed pointer.
+                    expr_ct.cat.guarantor = None;
+                    expr_ct.cat.pointer = BorrowedPointer(autoref.region);
+                    debug!("autoref, cat=%?", expr_ct.cat);
+                }
             }
+
+            None => {}
         }
 
         debug!("result=%?", expr_ct.cat);
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 7fb896a902c..e5aca315dd1 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -79,7 +79,24 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: span, id: ast::node_id)
     // Resolve any borrowings for the node with id `id`
     match fcx.inh.adjustments.find(&id) {
         None => (),
-        Some(adj) => {
+
+        Some(@ty::AutoAddEnv(r, s)) => {
+            match resolve_region(fcx.infcx(), r, resolve_all | force_all) {
+                Err(e) => {
+                    // This should not, I think, happen:
+                    fcx.ccx.tcx.sess.span_err(
+                        sp, fmt!("cannot resolve bound for closure: %s",
+                                 infer::fixup_err_to_str(e)));
+                }
+                Ok(r1) => {
+                    let resolved_adj = @ty::AutoAddEnv(r1, s);
+                    debug!("Adjustments for node %d: %?", id, resolved_adj);
+                    fcx.tcx().adjustments.insert(id, resolved_adj);
+                }
+            }
+        }
+
+        Some(@ty::AutoDerefRef(adj)) => {
             let resolved_autoref = match adj.autoref {
                 Some(ref autoref) => {
                     match resolve_region(fcx.infcx(), autoref.region,
@@ -99,9 +116,10 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: span, id: ast::node_id)
                 None => None
             };
 
-            let resolved_adj = @ty::AutoAdjustment {
+            let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef {
+                autoderefs: adj.autoderefs,
                 autoref: resolved_autoref,
-                ..*adj};
+            });
             debug!("Adjustments for node %d: %?", id, resolved_adj);
             fcx.tcx().adjustments.insert(id, resolved_adj);
         }
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index 6ad58bc5d4f..9ee0b848176 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -67,7 +67,7 @@ we may want to adjust precisely when coercions occur.
 use core::prelude::*;
 
 use middle::ty::{TyVar, AutoPtr, AutoBorrowVec, AutoBorrowFn};
-use middle::ty::{AutoAdjustment, AutoRef};
+use middle::ty::{AutoAdjustment, AutoDerefRef, AutoRef};
 use middle::ty::{vstore_slice, vstore_box, vstore_uniq, vstore_fixed};
 use middle::ty::{mt};
 use middle::ty;
@@ -206,14 +206,14 @@ pub impl Coerce {
                                      r_borrow,
                                      mt {ty: inner_ty, mutbl: mt_b.mutbl});
         if_ok!(sub.tys(a_borrowed, b));
-        Ok(Some(@AutoAdjustment {
+        Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 1,
             autoref: Some(AutoRef {
                 kind: AutoPtr,
                 region: r_borrow,
                 mutbl: mt_b.mutbl
             })
-        }))
+        })))
     }
 
     fn coerce_borrowed_string(&self,
@@ -236,14 +236,14 @@ pub impl Coerce {
         let r_a = self.infcx.next_region_var_nb(self.span);
         let a_borrowed = ty::mk_estr(self.infcx.tcx, vstore_slice(r_a));
         if_ok!(self.subtype(a_borrowed, b));
-        Ok(Some(@AutoAdjustment {
+        Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
             autoref: Some(AutoRef {
                 kind: AutoBorrowVec,
                 region: r_a,
                 mutbl: m_imm
             })
-        }))
+        })))
     }
 
     fn coerce_borrowed_vector(&self,
@@ -269,14 +269,14 @@ pub impl Coerce {
                                      mt {ty: ty_inner, mutbl: mt_b.mutbl},
                                      vstore_slice(r_borrow));
         if_ok!(sub.tys(a_borrowed, b));
-        Ok(Some(@AutoAdjustment {
+        Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
             autoref: Some(AutoRef {
                 kind: AutoBorrowVec,
                 region: r_borrow,
                 mutbl: mt_b.mutbl
             })
-        }))
+        })))
     }
 
     fn coerce_borrowed_fn(&self,
@@ -309,14 +309,14 @@ pub impl Coerce {
             });
 
         if_ok!(self.subtype(a_borrowed, b));
-        Ok(Some(@AutoAdjustment {
+        Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
             autoref: Some(AutoRef {
                 kind: AutoBorrowFn,
                 region: r_borrow,
                 mutbl: m_imm
             })
-        }))
+        })))
     }
 
     fn coerce_from_bare_fn(&self,
@@ -347,10 +347,12 @@ pub impl Coerce {
 
         // for now, bare fn and closures have the same
         // representation
+        let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
         let a_closure = ty::mk_closure(
             self.infcx.tcx,
             ty::ClosureTy {sig: copy fn_ty_a.sig, ..fn_ty_b});
-        self.subtype(a_closure, b)
+        if_ok!(self.subtype(a_closure, b));
+        Ok(Some(adj))
     }
 
     fn coerce_unsafe_ptr(&self,
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index 56ad56c3ae6..140b52f03aa 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,7 +15,7 @@
        url = "https://github.com/mozilla/rust/tree/master/src/rustc")];
 
 #[comment = "The Rust compiler"];
-#[license = "MIT"];
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[legacy_modes];
diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc
index 7d94352cc82..fc0ea4ce396 100644
--- a/src/librustdoc/rustdoc.rc
+++ b/src/librustdoc/rustdoc.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -16,7 +16,7 @@
        url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")];
 
 #[comment = "The Rust documentation generator"];
-#[license = "MIT"];
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[no_core];
diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc
index 0fe533e3dd9..56375ca5bfb 100644
--- a/src/librusti/rusti.rc
+++ b/src/librusti/rusti.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,6 +15,7 @@
        uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc",
        url = "https://github.com/mozilla/rust/tree/master/src/rusti")];
 
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[no_core];
diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc
index c16a56249ff..b58b5977f97 100644
--- a/src/librustpkg/rustpkg.rc
+++ b/src/librustpkg/rustpkg.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,6 +15,7 @@
        uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
        url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
 
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 #[no_core];
 #[allow(vecs_implicitly_copyable,
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 854abfdd112..2f6c4e3f190 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -23,7 +23,7 @@ not required in or otherwise suitable for the core library.
        url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
 
 #[comment = "The Rust standard library"];
-#[license = "MIT"];
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[allow(vecs_implicitly_copyable)];
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 8cebe3cd187..0e2f3c2c856 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -469,8 +469,8 @@ fn mk_impl(
     let ty = cx.ty_path(
         span,
         ~[ident],
-        generics.ty_params.map(
-            |tp| cx.ty_path(span, ~[tp.ident], ~[])).to_vec()
+        opt_vec::take_vec(generics.ty_params.map(
+            |tp| cx.ty_path(span, ~[tp.ident], ~[])))
     );
 
     let generics = ast::Generics {
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 40d0e2c5db2..3b885b7a7b9 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -434,13 +434,15 @@ impl ext_ctxt_ast_builder for ext_ctxt {
     }
 
     fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
-        ty_params.map(|p| self.ty_path_ast_builder(
-            path(~[p.ident], dummy_sp()))).to_vec()
+        opt_vec::take_vec(
+            ty_params.map(|p| self.ty_path_ast_builder(
+                path(~[p.ident], dummy_sp()))))
     }
 
     fn ty_vars_global(&self,
                       ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
-        ty_params.map(|p| self.ty_path_ast_builder(
-            path(~[p.ident], dummy_sp()))).to_vec()
+        opt_vec::take_vec(
+            ty_params.map(|p| self.ty_path_ast_builder(
+                path(~[p.ident], dummy_sp()))))
     }
 }
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index 052a3e48791..16db384bb06 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -31,6 +31,14 @@ pub fn with<T>(+t: T) -> OptVec<T> {
     Vec(~[t])
 }
 
+pub fn from<T>(+t: ~[T]) -> OptVec<T> {
+    if t.len() == 0 {
+        Empty
+    } else {
+        Vec(t)
+    }
+}
+
 impl<T> OptVec<T> {
     fn push(&mut self, +t: T) {
         match *self {
@@ -70,12 +78,12 @@ impl<T> OptVec<T> {
             Vec(ref v) => v.len()
         }
     }
+}
 
-    pure fn to_vec(self) -> ~[T] {
-        match self {
-            Empty => ~[],
-            Vec(v) => v
-        }
+pub fn take_vec<T>(+v: OptVec<T>) -> ~[T] {
+    match v {
+        Empty => ~[],
+        Vec(v) => v
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b0b2107703c..127af5b73ac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1195,7 +1195,7 @@ pub impl Parser {
                         &token::RBRACKET,
                         seq_sep_trailing_allowed(token::COMMA),
                         |p| p.parse_expr()
-                    ).to_vec();
+                    );
                     ex = expr_vec(~[first_expr] + remaining_exprs, mutbl);
                 } else {
                     // Vector with one element.
@@ -1478,7 +1478,7 @@ pub impl Parser {
                                 &ket,
                                 seq_sep_none(),
                                 |p| p.parse_token_tree()
-                            ).to_vec(),
+                            ),
                             // the close delimiter:
                             ~[parse_any_tt_tok(&self)]
                         )
@@ -2806,7 +2806,7 @@ pub impl Parser {
         let result = self.parse_seq_to_gt(
             Some(token::COMMA),
             |p| p.parse_ty(false));
-        result.to_vec()
+        opt_vec::take_vec(result)
     }
 
     fn parse_fn_decl(parse_arg_fn: fn(&Parser) -> arg_or_capture_item)
@@ -2908,7 +2908,7 @@ pub impl Parser {
                         &token::RPAREN,
                         sep,
                         parse_arg_fn
-                    ).to_vec();
+                    );
                 }
                 token::RPAREN => {
                     args_or_capture_items = ~[];
@@ -2928,7 +2928,7 @@ pub impl Parser {
                 &token::RPAREN,
                 sep,
                 parse_arg_fn
-            ).to_vec();
+            );
         }
 
         self.expect(&token::RPAREN);
@@ -3130,7 +3130,7 @@ pub impl Parser {
             ket,
             seq_sep_none(),
             |p| p.parse_trait_ref()
-        ).to_vec()
+        )
     }
 
     fn parse_item_struct() -> item_info {
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
index 9eb7507f3d0..f6e358e535f 100644
--- a/src/libsyntax/syntax.rc
+++ b/src/libsyntax/syntax.rc
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,6 +14,7 @@
 
 
 
+#[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[legacy_modes];
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index b0e13717b82..9f39e1433fc 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -120,7 +120,7 @@ upcall_fail(char const *expr,
             size_t line) {
     rust_task *task = rust_try_get_current_task();
     if (task == NULL) {
-        // NOTE: Need to think about what to do here
+        // FIXME #5161: Need to think about what to do here
         printf("failure outside of a task");
         abort();
     }
diff --git a/src/snapshots.txt b/src/snapshots.txt
index fc72551e7dd..31acfa81100 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,5 +1,5 @@
 S 2013-02-27 a6d9689
-  freebsd-x86_64 d33b5ebbf3335f6a8a5cc23572f630ad66539830
+  freebsd-x86_64 683f329fe589af854f9a375405468691d98015ac
   linux-i386 22f5c2a91941735007ed804586fc0f0e82fc3601
   linux-x86_64 328fb144edbed8cabb8c2c6306304e3d8460ef60
   macos-i386 5dda51347f9aba4c70a0890d3ec084d98a49c015