diff --git a/Cargo.lock b/Cargo.lock index ffa33393c3025..c930b628f4b37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,7 +169,7 @@ dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -463,7 +463,7 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -484,7 +484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -974,7 +974,7 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1989,7 +1989,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2008,7 +2008,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3095,7 +3095,7 @@ dependencies = [ "dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3522,7 +3522,7 @@ dependencies = [ name = "test" version = "0.0.0" dependencies = [ - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "term 0.0.0", ] @@ -3532,7 +3532,7 @@ name = "tester" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4132,7 +4132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34dd4c507af68d37ffef962063dfa1944ce0dd4d5b82043dbab1dabe088610c3" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450" "checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" "checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 9a410c339bf5f..3151b56d8e84e 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 0719eb701a984..91256385232a9 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -140,7 +140,7 @@ pub enum Res { 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 3a98c4ea06121..1e357e1341710 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 { - /// The variable being accessed free. +pub struct Upvar { + /// The variable being captured. pub res: Res, // First span where it is accessed (there can be multiple). pub span: Span } -impl Freevar { - pub fn map_id(self, map: impl FnMut(Id) -> R) -> Freevar { - Freevar { +impl Upvar { + pub fn map_id(self, map: impl FnMut(Id) -> R) -> Upvar { + Upvar { res: self.res.map_id(map), span: self.span, } @@ -2497,12 +2497,12 @@ impl Freevar { 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>>; +pub type UpvarMap = NodeMap>>; pub type CaptureModeMap = NodeMap; diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index c05c6567bbefa..9eb46aa3779d9 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 2044e5ddae90e..5846e604cfc09 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 cf3f613b08eb5..93ba4241c4725 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> { // 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 15736218a7923..4b458e474b299 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 09e2b523fae83..bd67aabfe8e5f 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 e1e115cfe177b..0e7b66b744499 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>> { + query upvars(_: DefId) -> Option>> { eval_always } query maybe_unused_trait_import(_: DefId) -> bool { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ad80e5d74bd2a..084a5429f26fa 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 fddae02409126..19440d0bc64ea 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>>, + upvars: FxHashMap>>, maybe_unused_trait_imports: FxHashSet, 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 feedf5741f65b..cb92e4b7470a5 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(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 e09dcd16bd3dc..8e98d4d85b9cc 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 6d3115c621343..8543cca1dd545 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 ed42326d7d520..8aa6456ebe77b 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 5ac1ccd8fade2..5e646a49e0e42 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 772cbcf9447ef..1ab612a2f7dd7 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 b6e2aacd55954..0f651fafcd2ac 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 3775dbb79c6fd..cb6f8ebd82e4e 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 a2d30de9da117..f8f6e5b1cd012 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, - pub freevars: FreevarMap, - freevars_seen: NodeMap>, + pub upvars: UpvarMap, + upvars_seen: NodeMap>, pub export_map: ExportMap, 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 85eb0f9d49966..d21ceb983f8f4 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 dc66c6c93d0e0..c3861f964e453 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 = Vec::with_capacity(freevars.len()); - for freevar in freevars { + if let Some(upvars) = self.tcx.upvars(closure_def_id) { + let mut upvar_list: Vec = 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 ed8ac89912c12..4185999fdd6d7 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("").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 f4af362a55702..472192a646492 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, "
{0}
", v)? + write!(w, "{0}", v)? } } Ok(()) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 358549117a307..4204d20498d70 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 94fece10e0fbc..24f728158c472 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 2e836b6772fda..a72e4c7050289 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 0000000000000..bea610eeb9fd1 --- /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 0000000000000..f328e4d9d04c3 --- /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 c561269cf9a85..6060bc0a6fd5c 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; }