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
This commit is contained in:
commit
40bd145cbe
31 changed files with 188 additions and 171 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 = ", ";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue