about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-05-05 21:11:47 +0000
committerbors <bors@rust-lang.org>2019-05-05 21:11:47 +0000
commit40bd145cbef28d279aacc903907c3945f83a6296 (patch)
tree482b6a07004b00963ca608ac27e1e6d4ed1bfde0 /src
parentd628c2e642c6f8f85f24dd5d7f49de89b95bf682 (diff)
parentff7ef116fbe4698f9df0370021d398dc345b832b (diff)
downloadrust-40bd145cbef28d279aacc903907c3945f83a6296.tar.gz
rust-40bd145cbef28d279aacc903907c3945f83a6296.zip
Auto merge of #60567 - Manishearth:rollup-rjagqnw, r=Manishearth
Rollup of 5 pull requests

Successful merges:

 - #60131 (Fix broken link in rustc_plugin doc)
 - #60426 (Stop `-O`/`-C opt-level` and `-g`/`-C debuginfo` conflicting)
 - #60515 (use span instead of div for since version)
 - #60530 (rustc: rename all occurences of "freevar" to "upvar".)
 - #60536 (Correct code points to match their textual description)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/librustc/hir/def.rs2
-rw-r--r--src/librustc/hir/mod.rs16
-rw-r--r--src/librustc/infer/error_reporting/note.rs4
-rw-r--r--src/librustc/infer/mod.rs6
-rw-r--r--src/librustc/middle/expr_use_visitor.rs16
-rw-r--r--src/librustc/middle/liveness.rs19
-rw-r--r--src/librustc/mir/mod.rs16
-rw-r--r--src/librustc/query/mod.rs2
-rw-r--r--src/librustc/session/config.rs31
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc/ty/mod.rs18
-rw-r--r--src/librustc/ty/print/pretty.rs12
-rw-r--r--src/librustc_interface/passes.rs4
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs41
-rw-r--r--src/librustc_mir/hair/cx/expr.rs23
-rw-r--r--src/librustc_mir/interpret/validity.rs2
-rw-r--r--src/librustc_passes/rvalue_promotion.rs3
-rw-r--r--src/librustc_plugin/lib.rs5
-rw-r--r--src/librustc_resolve/lib.rs16
-rw-r--r--src/librustc_typeck/check/coercion.rs3
-rw-r--r--src/librustc_typeck/check/upvar.rs48
-rw-r--r--src/librustc_typeck/collect.rs6
-rw-r--r--src/librustdoc/html/render.rs2
-rw-r--r--src/librustdoc/html/static/rustdoc.css2
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/libtest/Cargo.toml2
-rw-r--r--src/test/run-make-fulldeps/override-aliased-flags/Makefile22
-rw-r--r--src/test/run-make-fulldeps/override-aliased-flags/main.rs1
-rw-r--r--src/test/rustdoc/assoc-consts-version.rs5
30 files changed, 178 insertions, 161 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 9a410c339bf..3151b56d8e8 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -39,7 +39,7 @@ build_helper = { path = "../build_helper" }
 cmake = "0.1.38"
 filetime = "0.2"
 num_cpus = "1.0"
-getopts = "0.2.18"
+getopts = "0.2.19"
 cc = "1.0.35"
 libc = "0.2"
 serde = "1.0.8"
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 0719eb701a9..91256385232 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -140,7 +140,7 @@ pub enum Res<Id = hir::HirId> {
     SelfCtor(DefId /* impl */),  // `DefId` refers to the impl
     Local(Id),
     Upvar(Id,           // `HirId` of closed over local
-          usize,        // index in the `freevars` list of the closure
+          usize,        // index in the `upvars` list of the closure
           ast::NodeId), // expr node that creates the closure
 
     // Macro namespace
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 3a98c4ea061..1e357e13417 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2476,19 +2476,19 @@ impl ForeignItemKind {
     }
 }
 
-/// A free variable referred to in a function.
+/// A variable captured by a closure.
 #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Freevar<Id = HirId> {
-    /// The variable being accessed free.
+pub struct Upvar<Id = HirId> {
+    /// The variable being captured.
     pub res: Res<Id>,
 
     // First span where it is accessed (there can be multiple).
     pub span: Span
 }
 
-impl<Id: fmt::Debug + Copy> Freevar<Id> {
-    pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Freevar<R> {
-        Freevar {
+impl<Id: fmt::Debug + Copy> Upvar<Id> {
+    pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Upvar<R> {
+        Upvar {
             res: self.res.map_id(map),
             span: self.span,
         }
@@ -2497,12 +2497,12 @@ impl<Id: fmt::Debug + Copy> Freevar<Id> {
     pub fn var_id(&self) -> Id {
         match self.res {
             Res::Local(id) | Res::Upvar(id, ..) => id,
-            _ => bug!("Freevar::var_id: bad res ({:?})", self.res)
+            _ => bug!("Upvar::var_id: bad res ({:?})", self.res)
         }
     }
 }
 
-pub type FreevarMap = NodeMap<Vec<Freevar<ast::NodeId>>>;
+pub type UpvarMap = NodeMap<Vec<Upvar<ast::NodeId>>>;
 
 pub type CaptureModeMap = NodeMap<CaptureClause>;
 
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index c05c6567bbe..9eb46aa3779 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -46,7 +46,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 err.span_note(span,
                               "...so that pointer is not dereferenced outside its lifetime");
             }
-            infer::FreeVariable(span, id) => {
+            infer::ClosureCapture(span, id) => {
                 err.span_note(span,
                               &format!("...so that captured variable `{}` does not outlive the \
                                         enclosing closure",
@@ -214,7 +214,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     "the reference is only valid for ", sup, "");
                 err
             }
-            infer::FreeVariable(span, id) => {
+            infer::ClosureCapture(span, id) => {
                 let mut err = struct_span_err!(self.tcx.sess,
                                                span,
                                                E0474,
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 2044e5ddae9..5846e604cfc 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -264,8 +264,8 @@ pub enum SubregionOrigin<'tcx> {
     /// Dereference of reference must be within its lifetime
     DerefPointer(Span),
 
-    /// Closure bound must not outlive captured free variables
-    FreeVariable(Span, ast::NodeId),
+    /// Closure bound must not outlive captured variables
+    ClosureCapture(Span, ast::NodeId),
 
     /// Index into slice must be within its lifetime
     IndexSlice(Span),
@@ -1660,7 +1660,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             InfStackClosure(a) => a,
             InvokeClosure(a) => a,
             DerefPointer(a) => a,
-            FreeVariable(a, _) => a,
+            ClosureCapture(a, _) => a,
             IndexSlice(a) => a,
             RelateObjectBound(a) => a,
             RelateParamBound(a, _) => a,
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index cf3f613b08e..93ba4241c47 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -931,9 +931,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
         debug!("walk_captures({:?})", closure_expr);
 
         let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id);
-        self.tcx().with_freevars(closure_expr.hir_id, |freevars| {
-            for freevar in freevars {
-                let var_hir_id = freevar.var_id();
+        if let Some(upvars) = self.tcx().upvars(closure_def_id) {
+            for upvar in upvars.iter() {
+                let var_hir_id = upvar.var_id();
                 let upvar_id = ty::UpvarId {
                     var_path: ty::UpvarPath { hir_id: var_hir_id },
                     closure_expr_id: closure_def_id.to_local(),
@@ -941,14 +941,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                 let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
                 let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.hir_id,
                                                                    fn_decl_span,
-                                                                   freevar));
+                                                                   upvar));
                 match upvar_capture {
                     ty::UpvarCapture::ByValue => {
                         let mode = copy_or_move(&self.mc,
                                                 self.param_env,
                                                 &cmt_var,
                                                 CaptureMove);
-                        self.delegate.consume(closure_expr.hir_id, freevar.span, &cmt_var, mode);
+                        self.delegate.consume(closure_expr.hir_id, upvar.span, &cmt_var, mode);
                     }
                     ty::UpvarCapture::ByRef(upvar_borrow) => {
                         self.delegate.borrow(closure_expr.hir_id,
@@ -956,17 +956,17 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                                              &cmt_var,
                                              upvar_borrow.region,
                                              upvar_borrow.kind,
-                                             ClosureCapture(freevar.span));
+                                             ClosureCapture(upvar.span));
                     }
                 }
             }
-        });
+        }
     }
 
     fn cat_captured_var(&mut self,
                         closure_hir_id: hir::HirId,
                         closure_span: Span,
-                        upvar: &hir::Freevar)
+                        upvar: &hir::Upvar)
                         -> mc::McResult<mc::cmt_<'tcx>> {
         // Create the cmt for the variable being borrowed, from the
         // caller's perspective
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 15736218a79..4b458e474b2 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -144,7 +144,7 @@ impl LiveNode {
 
 #[derive(Copy, Clone, PartialEq, Debug)]
 enum LiveNodeKind {
-    FreeVarNode(Span),
+    UpvarNode(Span),
     ExprNode(Span),
     VarDefNode(Span),
     ExitNode
@@ -153,8 +153,8 @@ enum LiveNodeKind {
 fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_, '_, '_>) -> String {
     let cm = tcx.sess.source_map();
     match lnk {
-        FreeVarNode(s) => {
-            format!("Free var node [{}]", cm.span_to_string(s))
+        UpvarNode(s) => {
+            format!("Upvar node [{}]", cm.span_to_string(s))
         }
         ExprNode(s) => {
             format!("Expr node [{}]", cm.span_to_string(s))
@@ -483,16 +483,17 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        ir.tcx.with_freevars(expr.hir_id, |freevars| {
-            call_caps.extend(freevars.iter().filter_map(|fv| {
-                if let Res::Local(rv) = fv.res {
-                    let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
-                    Some(CaptureInfo { ln: fv_ln, var_hid: rv })
+        let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+        if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
+            call_caps.extend(upvars.iter().filter_map(|upvar| {
+                if let Res::Local(rv) = upvar.res {
+                    let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
+                    Some(CaptureInfo { ln: upvar_ln, var_hid: rv })
                 } else {
                     None
                 }
             }));
-        });
+        }
         ir.set_captures(expr.hir_id, call_caps);
 
         intravisit::walk_expr(ir, expr);
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 09e2b523fae..bd67aabfe8e 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2572,12 +2572,12 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                             };
                             let mut struct_fmt = fmt.debug_struct(&name);
 
-                            tcx.with_freevars(hir_id, |freevars| {
-                                for (freevar, place) in freevars.iter().zip(places) {
-                                    let var_name = tcx.hir().name_by_hir_id(freevar.var_id());
+                            if let Some(upvars) = tcx.upvars(def_id) {
+                                for (upvar, place) in upvars.iter().zip(places) {
+                                    let var_name = tcx.hir().name_by_hir_id(upvar.var_id());
                                     struct_fmt.field(&var_name.as_str(), place);
                                 }
-                            });
+                            }
 
                             struct_fmt.finish()
                         } else {
@@ -2591,12 +2591,12 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                                                tcx.hir().span_by_hir_id(hir_id));
                             let mut struct_fmt = fmt.debug_struct(&name);
 
-                            tcx.with_freevars(hir_id, |freevars| {
-                                for (freevar, place) in freevars.iter().zip(places) {
-                                    let var_name = tcx.hir().name_by_hir_id(freevar.var_id());
+                            if let Some(upvars) = tcx.upvars(def_id) {
+                                for (upvar, place) in upvars.iter().zip(places) {
+                                    let var_name = tcx.hir().name_by_hir_id(upvar.var_id());
                                     struct_fmt.field(&var_name.as_str(), place);
                                 }
-                            });
+                            }
 
                             struct_fmt.finish()
                         } else {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index e1e115cfe17..0e7b66b7444 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -824,7 +824,7 @@ rustc_queries! {
             desc { "generating a postorder list of CrateNums" }
         }
 
-        query freevars(_: DefId) -> Option<Lrc<Vec<hir::Freevar>>> {
+        query upvars(_: DefId) -> Option<Lrc<Vec<hir::Upvar>>> {
             eval_always
         }
         query maybe_unused_trait_import(_: DefId) -> bool {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index ad80e5d74bd..084a5429f26 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -2181,10 +2181,21 @@ pub fn build_session_options_and_crate_config(
         TargetTriple::from_triple(host_triple())
     };
     let opt_level = {
-        if matches.opt_present("O") {
-            if cg.opt_level.is_some() {
-                early_error(error_format, "-O and -C opt-level both provided");
+        // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
+        // to use them interchangeably. However, because they're technically different flags,
+        // we need to work out manually which should take precedence if both are supplied (i.e.
+        // the rightmost flag). We do this by finding the (rightmost) position of both flags and
+        // comparing them. Note that if a flag is not found, its position will be `None`, which
+        // always compared less than `Some(_)`.
+        let max_o = matches.opt_positions("O").into_iter().max();
+        let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
+            if let Some("opt-level") = s.splitn(2, '=').next() {
+                Some(i)
+            } else {
+                None
             }
+        }).max();
+        if max_o > max_c {
             OptLevel::Default
         } else {
             match cg.opt_level.as_ref().map(String::as_ref) {
@@ -2208,11 +2219,19 @@ pub fn build_session_options_and_crate_config(
             }
         }
     };
+    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
+    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
+    // for more details.
     let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
-    let debuginfo = if matches.opt_present("g") {
-        if cg.debuginfo.is_some() {
-            early_error(error_format, "-g and -C debuginfo both provided");
+    let max_g = matches.opt_positions("g").into_iter().max();
+    let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
+        if let Some("debuginfo") = s.splitn(2, '=').next() {
+            Some(i)
+        } else {
+            None
         }
+    }).max();
+    let debuginfo = if max_g > max_c {
         DebugInfo::Full
     } else {
         match cg.debuginfo {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index fddae024091..19440d0bc64 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1071,10 +1071,10 @@ pub struct GlobalCtxt<'tcx> {
 
     pub queries: query::Queries<'tcx>,
 
-    // Records the free variables referenced by every closure
+    // Records the captured variables referenced by every closure
     // expression. Do not track deps for this, just recompute it from
     // scratch every time.
-    freevars: FxHashMap<DefId, Lrc<Vec<hir::Freevar>>>,
+    upvars: FxHashMap<DefId, Lrc<Vec<hir::Upvar>>>,
 
     maybe_unused_trait_imports: FxHashSet<DefId>,
     maybe_unused_extern_crates: Vec<(DefId, Span)>,
@@ -1317,7 +1317,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 }).collect();
                 (k, Lrc::new(exports))
             }).collect(),
-            freevars: resolutions.freevars.into_iter().map(|(k, v)| {
+            upvars: resolutions.upvars.into_iter().map(|(k, v)| {
                 let vars: Vec<_> = v.into_iter().map(|e| {
                     e.map_id(|id| hir.node_to_hir_id(id))
                 }).collect();
@@ -3055,7 +3055,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         assert_eq!(id, LOCAL_CRATE);
         Lrc::new(middle::lang_items::collect(tcx))
     };
-    providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned();
+    providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).cloned();
     providers.maybe_unused_trait_import = |tcx, id| {
         tcx.maybe_unused_trait_imports.contains(&id)
     };
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index feedf5741f6..cb92e4b7470 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -8,8 +8,8 @@ pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
 pub use self::fold::TypeFoldable;
 
-use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap};
-use crate::hir::{HirId, Node};
+use crate::hir::{map as hir_map, UpvarMap, GlobMap, TraitMap};
+use crate::hir::Node;
 use crate::hir::def::{Res, DefKind, CtorOf, CtorKind, ExportMap};
 use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_data_structures::svh::Svh;
@@ -122,7 +122,7 @@ mod sty;
 
 #[derive(Clone)]
 pub struct Resolutions {
-    pub freevars: FreevarMap,
+    pub upvars: UpvarMap,
     pub trait_map: TraitMap,
     pub maybe_unused_trait_imports: NodeSet,
     pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
@@ -3120,18 +3120,6 @@ impl Iterator for AssociatedItemsIterator<'_, '_, '_> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    pub fn with_freevars<T, F>(self, fid: HirId, f: F) -> T where
-        F: FnOnce(&[hir::Freevar]) -> T,
-    {
-        let def_id = self.hir().local_def_id_from_hir_id(fid);
-        match self.freevars(def_id) {
-            None => f(&[]),
-            Some(d) => f(&d),
-        }
-    }
-}
-
 fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let parent_id = tcx.hir().get_parent_item(id);
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index e09dcd16bd3..8e98d4d85b9 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -582,16 +582,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
                 if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
                     p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
                     let mut sep = " ";
-                    for (freevar, upvar_ty) in self.tcx().freevars(did)
+                    for (upvar, upvar_ty) in self.tcx().upvars(did)
                         .as_ref()
-                        .map_or(&[][..], |fv| &fv[..])
+                        .map_or(&[][..], |v| &v[..])
                         .iter()
                         .zip(upvar_tys)
                     {
                         p!(
                             write("{}{}:",
                                     sep,
-                                    self.tcx().hir().name_by_hir_id(freevar.var_id())),
+                                    self.tcx().hir().name_by_hir_id(upvar.var_id())),
                             print(upvar_ty));
                         sep = ", ";
                     }
@@ -625,16 +625,16 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
                         p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
                     }
                     let mut sep = " ";
-                    for (freevar, upvar_ty) in self.tcx().freevars(did)
+                    for (upvar, upvar_ty) in self.tcx().upvars(did)
                         .as_ref()
-                        .map_or(&[][..], |fv| &fv[..])
+                        .map_or(&[][..], |v| &v[..])
                         .iter()
                         .zip(upvar_tys)
                     {
                         p!(
                             write("{}{}:",
                                     sep,
-                                    self.tcx().hir().name_by_hir_id(freevar.var_id())),
+                                    self.tcx().hir().name_by_hir_id(upvar.var_id())),
                             print(upvar_ty));
                         sep = ", ";
                     }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 6d3115c6213..8543cca1dd5 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -180,7 +180,7 @@ impl ExpansionResult {
         ExpansionResult {
             defs: Steal::new(resolver.definitions),
             resolutions: Steal::new(Resolutions {
-                freevars: resolver.freevars,
+                upvars: resolver.upvars,
                 export_map: resolver.export_map,
                 trait_map: resolver.trait_map,
                 glob_map: resolver.glob_map,
@@ -199,7 +199,7 @@ impl ExpansionResult {
         ExpansionResult {
             defs: Steal::new(resolver.definitions.clone()),
             resolutions: Steal::new(Resolutions {
-                freevars: resolver.freevars.clone(),
+                upvars: resolver.upvars.clone(),
                 export_map: resolver.export_map.clone(),
                 trait_map: resolver.trait_map.clone(),
                 glob_map: resolver.glob_map.clone(),
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index ed42326d7d5..8aa6456ebe7 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -1814,16 +1814,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 ty::Array(ty, _) | ty::Slice(ty) =>
                     self.describe_field_from_ty(&ty, field, variant_index),
                 ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
-                    // Convert the def-id into a node-id. node-ids are only valid for
-                    // the local code in the current crate, so this returns an `Option` in case
+                    // `tcx.upvars(def_id)` returns an `Option`, which is `None` in case
                     // the closure comes from another crate. But in that case we wouldn't
                     // be borrowck'ing it, so we can just unwrap:
-                    let hir_id = self.infcx.tcx.hir().as_local_hir_id(def_id).unwrap();
-                    let freevar = self.infcx
-                        .tcx
-                        .with_freevars(hir_id, |fv| fv[field.index()]);
+                    let upvar = self.infcx.tcx.upvars(def_id).unwrap()[field.index()];
 
-                    self.infcx.tcx.hir().name_by_hir_id(freevar.var_id()).to_string()
+                    self.infcx.tcx.hir().name_by_hir_id(upvar.var_id()).to_string()
                 }
                 _ => {
                     // Might need a revision when the fields in trait RFC is implemented
@@ -2613,28 +2609,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         if let hir::ExprKind::Closure(
             .., args_span, _
         ) = expr {
-            let var_span = self.infcx.tcx.with_freevars(
-                hir_id,
-                |freevars| {
-                    for (v, place) in freevars.iter().zip(places) {
-                        match place {
-                            Operand::Copy(place) |
-                            Operand::Move(place) if target_place == place => {
-                                debug!("closure_span: found captured local {:?}", place);
-                                return Some(v.span);
-                            },
-                            _ => {}
-                        }
-                    }
-
-                    None
-                },
-            )?;
+            for (v, place) in self.infcx.tcx.upvars(def_id)?.iter().zip(places) {
+                match place {
+                    Operand::Copy(place) |
+                    Operand::Move(place) if target_place == place => {
+                        debug!("closure_span: found captured local {:?}", place);
+                        return Some((*args_span, v.span));
+                    },
+                    _ => {}
+                }
+            }
 
-            Some((*args_span, var_span))
-        } else {
-            None
         }
+        None
     }
 
     /// Helper to retrieve span(s) of given borrow from the current MIR
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 5ac1ccd8fad..5e646a49e0e 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -516,12 +516,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                     span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
                 }
             };
-            let upvars = cx.tcx.with_freevars(expr.hir_id, |freevars| {
-                freevars.iter()
-                    .zip(substs.upvar_tys(def_id, cx.tcx))
-                    .map(|(fv, ty)| capture_freevar(cx, expr, fv, ty))
-                    .collect()
-            });
+            let upvars = cx.tcx.upvars(def_id).iter()
+                .flat_map(|upvars| upvars.iter())
+                .zip(substs.upvar_tys(def_id, cx.tcx))
+                .map(|(upvar, ty)| capture_upvar(cx, expr, upvar, ty))
+                .collect();
             ExprKind::Closure {
                 closure_id: def_id,
                 substs,
@@ -1185,12 +1184,12 @@ fn overloaded_place<'a, 'gcx, 'tcx>(
     ExprKind::Deref { arg: ref_expr.to_ref() }
 }
 
-fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
+fn capture_upvar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                    closure_expr: &'tcx hir::Expr,
-                                   freevar: &hir::Freevar,
-                                   freevar_ty: Ty<'tcx>)
+                                   upvar: &hir::Upvar,
+                                   upvar_ty: Ty<'tcx>)
                                    -> ExprRef<'tcx> {
-    let var_hir_id = freevar.var_id();
+    let var_hir_id = upvar.var_id();
     let upvar_id = ty::UpvarId {
         var_path: ty::UpvarPath { hir_id: var_hir_id },
         closure_expr_id: cx.tcx.hir().local_def_id_from_hir_id(closure_expr.hir_id).to_local(),
@@ -1202,7 +1201,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         temp_lifetime,
         ty: var_ty,
         span: closure_expr.span,
-        kind: convert_var(cx, closure_expr, freevar.res),
+        kind: convert_var(cx, closure_expr, upvar.res),
     };
     match upvar_capture {
         ty::UpvarCapture::ByValue => captured_var.to_ref(),
@@ -1214,7 +1213,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             };
             Expr {
                 temp_lifetime,
-                ty: freevar_ty,
+                ty: upvar_ty,
                 span: closure_expr.span,
                 kind: ExprKind::Borrow {
                     borrow_kind,
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 772cbcf9447..1ab612a2f7d 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -172,7 +172,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
                 if def_id.is_local() {
                     let tables = self.ecx.tcx.typeck_tables_of(def_id);
                     if let Some(upvars) = tables.upvar_list.get(&def_id) {
-                        // Sometimes the index is beyond the number of freevars (seen
+                        // Sometimes the index is beyond the number of upvars (seen
                         // for a generator).
                         if let Some(upvar_id) = upvars.get(field) {
                             let var_hir_id = upvar_id.var_path.hir_id;
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index b6e2aacd559..0f651fafcd2 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -449,7 +449,8 @@ fn check_expr_kind<'a, 'tcx>(
             let nested_body_promotable = v.check_nested_body(body_id);
             // Paths in constant contexts cannot refer to local variables,
             // as there are none, and thus closures can't have upvars there.
-            if v.tcx.with_freevars(e.hir_id, |fv| !fv.is_empty()) {
+            let closure_def_id = v.tcx.hir().local_def_id_from_hir_id(e.hir_id);
+            if !v.tcx.upvars(closure_def_id).map_or(true, |v| v.is_empty()) {
                 NotPromotable
             } else {
                 nested_body_promotable
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index 3775dbb79c6..cb6f8ebd82e 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -47,8 +47,9 @@
 //! #![plugin(myplugin)]
 //! ```
 //!
-//! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of
-//! the Unstable Book for more examples.
+//! See the [`plugin`
+//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
+//! of the Unstable Book for more examples.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a2d30de9da1..f8f6e5b1cd0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -29,7 +29,7 @@ use rustc::hir::def::{
 };
 use rustc::hir::def::Namespace::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
-use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
+use rustc::hir::{Upvar, UpvarMap, TraitCandidate, TraitMap, GlobMap};
 use rustc::ty::{self, DefIdTree};
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 use rustc::{bug, span_bug};
@@ -1668,8 +1668,8 @@ pub struct Resolver<'a> {
     /// Resolutions for labels (node IDs of their corresponding blocks or loops).
     label_res_map: NodeMap<NodeId>,
 
-    pub freevars: FreevarMap,
-    freevars_seen: NodeMap<NodeMap<usize>>,
+    pub upvars: UpvarMap,
+    upvars_seen: NodeMap<NodeMap<usize>>,
     pub export_map: ExportMap<NodeId>,
     pub trait_map: TraitMap,
 
@@ -2033,8 +2033,8 @@ impl<'a> Resolver<'a> {
             partial_res_map: Default::default(),
             import_res_map: Default::default(),
             label_res_map: Default::default(),
-            freevars: Default::default(),
-            freevars_seen: Default::default(),
+            upvars: Default::default(),
+            upvars_seen: Default::default(),
             export_map: FxHashMap::default(),
             trait_map: Default::default(),
             module_map,
@@ -4054,21 +4054,21 @@ impl<'a> Resolver<'a> {
                         ClosureRibKind(function_id) => {
                             let prev_res = res;
 
-                            let seen = self.freevars_seen
+                            let seen = self.upvars_seen
                                            .entry(function_id)
                                            .or_default();
                             if let Some(&index) = seen.get(&node_id) {
                                 res = Res::Upvar(node_id, index, function_id);
                                 continue;
                             }
-                            let vec = self.freevars
+                            let vec = self.upvars
                                           .entry(function_id)
                                           .or_default();
                             let depth = vec.len();
                             res = Res::Upvar(node_id, depth, function_id);
 
                             if record_used {
-                                vec.push(Freevar {
+                                vec.push(Upvar {
                                     res: prev_res,
                                     span,
                                 });
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 85eb0f9d499..d21ceb983f8 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -721,9 +721,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
 
         let b = self.shallow_resolve(b);
 
-        let hir_id_a = self.tcx.hir().as_local_hir_id(def_id_a).unwrap();
         match b.sty {
-            ty::FnPtr(fn_ty) if self.tcx.with_freevars(hir_id_a, |v| v.is_empty()) => {
+            ty::FnPtr(fn_ty) if self.tcx.upvars(def_id_a).map_or(true, |v| v.is_empty()) => {
                 // We coerce the closure, which has fn type
                 //     `extern "rust-call" fn((arg0,arg1,...)) -> _`
                 // to
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index dc66c6c93d0..c3861f964e4 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -121,28 +121,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             None
         };
 
-        self.tcx.with_freevars(closure_hir_id, |freevars| {
-            let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
-            for freevar in freevars {
+        if let Some(upvars) = self.tcx.upvars(closure_def_id) {
+            let mut upvar_list: Vec<ty::UpvarId> = Vec::with_capacity(upvars.len());
+            for upvar in upvars.iter() {
                 let upvar_id = ty::UpvarId {
                     var_path: ty::UpvarPath {
-                        hir_id: freevar.var_id(),
+                        hir_id: upvar.var_id(),
                     },
                     closure_expr_id: LocalDefId::from_def_id(closure_def_id),
                 };
                 debug!("seed upvar_id {:?}", upvar_id);
                 // Adding the upvar Id to the list of Upvars, which will be added
                 // to the map for the closure at the end of the for loop.
-                freevar_list.push(upvar_id);
+                upvar_list.push(upvar_id);
 
                 let capture_kind = match capture_clause {
                     hir::CaptureByValue => ty::UpvarCapture::ByValue,
                     hir::CaptureByRef => {
                         let origin = UpvarRegion(upvar_id, span);
-                        let freevar_region = self.next_region_var(origin);
+                        let upvar_region = self.next_region_var(origin);
                         let upvar_borrow = ty::UpvarBorrow {
                             kind: ty::ImmBorrow,
-                            region: freevar_region,
+                            region: upvar_region,
                         };
                         ty::UpvarCapture::ByRef(upvar_borrow)
                     }
@@ -153,16 +153,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     .upvar_capture_map
                     .insert(upvar_id, capture_kind);
             }
-            // Add the vector of freevars to the map keyed with the closure id.
+            // Add the vector of upvars to the map keyed with the closure id.
             // This gives us an easier access to them without having to call
-            // with_freevars again..
-            if !freevar_list.is_empty() {
+            // tcx.upvars again..
+            if !upvar_list.is_empty() {
                 self.tables
                     .borrow_mut()
                     .upvar_list
-                    .insert(closure_def_id, freevar_list);
+                    .insert(closure_def_id, upvar_list);
             }
-        });
+        }
 
         let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
         let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id);
@@ -244,38 +244,38 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // This may change if abstract return types of some sort are
         // implemented.
         let tcx = self.tcx;
-        let closure_def_index = tcx.hir().local_def_id_from_hir_id(closure_id);
+        let closure_def_id = tcx.hir().local_def_id_from_hir_id(closure_id);
 
-        tcx.with_freevars(closure_id, |freevars| {
-            freevars
+        tcx.upvars(closure_def_id).iter().flat_map(|upvars| {
+            upvars
                 .iter()
-                .map(|freevar| {
-                    let var_hir_id = freevar.var_id();
-                    let freevar_ty = self.node_ty(var_hir_id);
+                .map(|upvar| {
+                    let var_hir_id = upvar.var_id();
+                    let upvar_ty = self.node_ty(var_hir_id);
                     let upvar_id = ty::UpvarId {
                         var_path: ty::UpvarPath { hir_id: var_hir_id },
-                        closure_expr_id: LocalDefId::from_def_id(closure_def_index),
+                        closure_expr_id: LocalDefId::from_def_id(closure_def_id),
                     };
                     let capture = self.tables.borrow().upvar_capture(upvar_id);
 
                     debug!(
-                        "var_id={:?} freevar_ty={:?} capture={:?}",
-                        var_hir_id, freevar_ty, capture
+                        "var_id={:?} upvar_ty={:?} capture={:?}",
+                        var_hir_id, upvar_ty, capture
                     );
 
                     match capture {
-                        ty::UpvarCapture::ByValue => freevar_ty,
+                        ty::UpvarCapture::ByValue => upvar_ty,
                         ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref(
                             borrow.region,
                             ty::TypeAndMut {
-                                ty: freevar_ty,
+                                ty: upvar_ty,
                                 mutbl: borrow.kind.to_mutbl_lossy(),
                             },
                         ),
                     }
                 })
-                .collect()
         })
+            .collect()
     }
 }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index ed8ac89912c..4185999fdd6 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1093,8 +1093,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
                 }),
         );
 
-        tcx.with_freevars(hir_id, |fv| {
-            params.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
+        if let Some(upvars) = tcx.upvars(def_id) {
+            params.extend(upvars.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
                 ty::GenericParamDef {
                     index: type_start + i,
                     name: Symbol::intern("<upvar>").as_interned_str(),
@@ -1107,7 +1107,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
                     },
                 }
             }));
-        });
+        }
     }
 
     let param_def_id_to_index = params
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f4af362a557..472192a6464 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3410,7 +3410,7 @@ fn render_stability_since_raw<'a, T: fmt::Write>(
 ) -> fmt::Result {
     if let Some(v) = ver {
         if containing_ver != ver && v.len() > 0 {
-            write!(w, "<div class='since' title='Stable since Rust version {0}'>{0}</div>", v)?
+            write!(w, "<span class='since' title='Stable since Rust version {0}'>{0}</span>", v)?
         }
     }
     Ok(())
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 358549117a3..4204d20498d 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -914,7 +914,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
 	height: 12px;
 }
 
-span.since {
+.out-of-band > span.since {
 	position: initial;
 	font-size: 20px;
 	margin-right: 5px;
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 94fece10e0f..24f728158c4 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -279,7 +279,7 @@ mod prim_never { }
 ///
 /// As always, remember that a human intuition for 'character' may not map to
 /// Unicode's definitions. For example, despite looking similar, the 'é'
-/// character is one Unicode code point while 'é' is two Unicode code points:
+/// character is one Unicode code point while 'é' is two Unicode code points:
 ///
 /// ```
 /// let mut chars = "é".chars();
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index 2e836b6772f..a72e4c70502 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-getopts = "0.2.18"
+getopts = "0.2.19"
 term = { path = "../libterm" }
 
 # not actually used but needed to always have proc_macro in the sysroot
diff --git a/src/test/run-make-fulldeps/override-aliased-flags/Makefile b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
new file mode 100644
index 00000000000..bea610eeb9f
--- /dev/null
+++ b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
@@ -0,0 +1,22 @@
+-include ../tools.mk
+
+# FIXME: it would be good to check that it's actually the rightmost flags
+# that are used when multiple flags are specified, but I can't think of a
+# reliable way to check this.
+
+all:
+	# Test that `-O` and `-C opt-level` can be specified multiple times.
+	# The rightmost flag will be used over any previous flags.
+	$(RUSTC) -O -O main.rs
+	$(RUSTC) -O -C opt-level=0 main.rs
+	$(RUSTC) -C opt-level=0 -O main.rs
+	$(RUSTC) -C opt-level=0 -C opt-level=2 main.rs
+	$(RUSTC) -C opt-level=2 -C opt-level=0 main.rs
+
+	# Test that `-g` and `-C debuginfo` can be specified multiple times.
+	# The rightmost flag will be used over any previous flags.
+	$(RUSTC) -g -g main.rs
+	$(RUSTC) -g -C debuginfo=0 main.rs
+	$(RUSTC) -C debuginfo=0 -g main.rs
+	$(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs
+	$(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs
diff --git a/src/test/run-make-fulldeps/override-aliased-flags/main.rs b/src/test/run-make-fulldeps/override-aliased-flags/main.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/src/test/run-make-fulldeps/override-aliased-flags/main.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/test/rustdoc/assoc-consts-version.rs b/src/test/rustdoc/assoc-consts-version.rs
index c561269cf9a..6060bc0a6fd 100644
--- a/src/test/rustdoc/assoc-consts-version.rs
+++ b/src/test/rustdoc/assoc-consts-version.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #![crate_name = "foo"]
 
 #![feature(staged_api)]
@@ -10,7 +8,8 @@
 pub struct SomeStruct;
 
 impl SomeStruct {
-    // @has 'foo/struct.SomeStruct.html' '//*[@id="associatedconstant.SOME_CONST"]//div[@class="since"]' '1.1.2'
+    // @has 'foo/struct.SomeStruct.html' \
+    //   '//*[@id="associatedconstant.SOME_CONST"]//span[@class="since"]' '1.1.2'
     #[stable(since="1.1.2", feature="rust2")]
     pub const SOME_CONST: usize = 0;
 }