Remove ReScope
This commit is contained in:
parent
c102312c2b
commit
7d73e4cc47
19 changed files with 27 additions and 455 deletions
|
|
@ -332,7 +332,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
|||
ty::ReStatic
|
||||
| ty::ReEarlyBound(..)
|
||||
| ty::ReFree(_)
|
||||
| ty::ReScope(_)
|
||||
| ty::ReEmpty(_)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||
|
|
|
|||
|
|
@ -619,7 +619,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||
| ty::ReVar(..)
|
||||
| ty::ReEmpty(_)
|
||||
| ty::ReStatic
|
||||
| ty::ReScope(..)
|
||||
| ty::ReEarlyBound(..)
|
||||
| ty::ReFree(..) => {
|
||||
// see common code below
|
||||
|
|
|
|||
|
|
@ -88,51 +88,6 @@ pub(super) fn note_and_explain_region(
|
|||
suffix: &str,
|
||||
) {
|
||||
let (description, span) = match *region {
|
||||
ty::ReScope(scope) => {
|
||||
let new_string;
|
||||
let unknown_scope =
|
||||
|| format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix);
|
||||
let span = scope.span(tcx, region_scope_tree);
|
||||
let hir_id = scope.hir_id(region_scope_tree);
|
||||
let tag = match hir_id.and_then(|hir_id| tcx.hir().find(hir_id)) {
|
||||
Some(Node::Block(_)) => "block",
|
||||
Some(Node::Expr(expr)) => match expr.kind {
|
||||
hir::ExprKind::Call(..) => "call",
|
||||
hir::ExprKind::MethodCall(..) => "method call",
|
||||
hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let",
|
||||
hir::ExprKind::Match(.., hir::MatchSource::WhileLetDesugar) => "while let",
|
||||
hir::ExprKind::Match(.., hir::MatchSource::ForLoopDesugar) => "for",
|
||||
hir::ExprKind::Match(..) => "match",
|
||||
_ => "expression",
|
||||
},
|
||||
Some(Node::Stmt(_)) => "statement",
|
||||
Some(Node::Item(it)) => item_scope_tag(&it),
|
||||
Some(Node::TraitItem(it)) => trait_item_scope_tag(&it),
|
||||
Some(Node::ImplItem(it)) => impl_item_scope_tag(&it),
|
||||
Some(_) | None => {
|
||||
err.span_note(span, &unknown_scope());
|
||||
return;
|
||||
}
|
||||
};
|
||||
let scope_decorated_tag = match scope.data {
|
||||
region::ScopeData::Node => tag,
|
||||
region::ScopeData::CallSite => "scope of call-site for function",
|
||||
region::ScopeData::Arguments => "scope of function body",
|
||||
region::ScopeData::Destruction => {
|
||||
new_string = format!("destruction scope surrounding {}", tag);
|
||||
&new_string[..]
|
||||
}
|
||||
region::ScopeData::Remainder(first_statement_index) => {
|
||||
new_string = format!(
|
||||
"block suffix following statement {}",
|
||||
first_statement_index.index()
|
||||
);
|
||||
&new_string[..]
|
||||
}
|
||||
};
|
||||
explain_span(tcx, scope_decorated_tag, span)
|
||||
}
|
||||
|
||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {
|
||||
msg_span_from_free_region(tcx, region)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
|||
ty::ReStatic
|
||||
| ty::ReEarlyBound(..)
|
||||
| ty::ReFree(_)
|
||||
| ty::ReScope(_)
|
||||
| ty::ReVar(_)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReEmpty(_)
|
||||
|
|
|
|||
|
|
@ -1,253 +0,0 @@
|
|||
//! This module provides linkage between libgraphviz traits and
|
||||
//! `rustc_trait_selection::infer::region_constraints`, generating a
|
||||
//! rendering of the graph represented by the list of `Constraint`
|
||||
//! instances (which make up the edges of the graph), as well as the
|
||||
//! origin for each constraint (which are attached to the labels on
|
||||
//! each edge).
|
||||
|
||||
/// For clarity, rename the graphviz crate locally to dot.
|
||||
use graphviz as dot;
|
||||
|
||||
use super::Constraint;
|
||||
use crate::infer::region_constraints::RegionConstraintData;
|
||||
use crate::infer::RegionRelations;
|
||||
use crate::infer::SubregionOrigin;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::DefIndex;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::ty;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::btree_map::BTreeMap;
|
||||
use std::collections::hash_map::Entry::Vacant;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
fn print_help_message() {
|
||||
println!(
|
||||
"\
|
||||
-Z print-region-graph by default prints a region constraint graph for every \n\
|
||||
function body, to the path `constraints.nodeXXX.dot`, where the XXX is \n\
|
||||
replaced with the node id of the function under analysis. \n\
|
||||
\n\
|
||||
To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`, \n\
|
||||
where XXX is the node id desired. \n\
|
||||
\n\
|
||||
To generate output to some path other than the default \n\
|
||||
`constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`; \n\
|
||||
occurrences of the character `%` in the requested path will be replaced with\n\
|
||||
the node id of the function under analysis. \n\
|
||||
\n\
|
||||
(Since you requested help via RUST_REGION_GRAPH=help, no region constraint \n\
|
||||
graphs will be printed. \n\
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn maybe_print_constraints_for<'a, 'tcx>(
|
||||
region_data: &RegionConstraintData<'tcx>,
|
||||
region_rels: &RegionRelations<'a, 'tcx>,
|
||||
) {
|
||||
let tcx = region_rels.tcx;
|
||||
let context = region_rels.context;
|
||||
|
||||
if !tcx.sess.opts.debugging_opts.print_region_graph {
|
||||
return;
|
||||
}
|
||||
|
||||
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().map(DefIndex::from_u32).ok());
|
||||
|
||||
if requested_node.is_some() && requested_node != Some(context.index) {
|
||||
return;
|
||||
}
|
||||
|
||||
let requested_output = env::var("RUST_REGION_GRAPH");
|
||||
debug!("requested_output: {:?} requested_node: {:?}", requested_output, requested_node);
|
||||
|
||||
let output_path = {
|
||||
let output_template = match requested_output {
|
||||
Ok(ref s) if s == "help" => {
|
||||
static PRINTED_YET: AtomicBool = AtomicBool::new(false);
|
||||
if !PRINTED_YET.load(Ordering::SeqCst) {
|
||||
print_help_message();
|
||||
PRINTED_YET.store(true, Ordering::SeqCst);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Ok(other_path) => other_path,
|
||||
Err(_) => "constraints.node%.dot".to_string(),
|
||||
};
|
||||
|
||||
if output_template.is_empty() {
|
||||
panic!("empty string provided as RUST_REGION_GRAPH");
|
||||
}
|
||||
|
||||
if output_template.contains('%') {
|
||||
let mut new_str = String::new();
|
||||
for c in output_template.chars() {
|
||||
if c == '%' {
|
||||
new_str.push_str(&context.index.as_u32().to_string());
|
||||
} else {
|
||||
new_str.push(c);
|
||||
}
|
||||
}
|
||||
new_str
|
||||
} else {
|
||||
output_template
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = dump_region_data_to(region_rels, ®ion_data.constraints, &output_path) {
|
||||
let msg = format!("io error dumping region constraints: {}", e);
|
||||
tcx.sess.err(&msg)
|
||||
}
|
||||
}
|
||||
|
||||
struct ConstraintGraph<'a, 'tcx> {
|
||||
graph_name: String,
|
||||
region_rels: &'a RegionRelations<'a, 'tcx>,
|
||||
map: &'a BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
|
||||
node_ids: FxHashMap<Node, usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
|
||||
enum Node {
|
||||
RegionVid(ty::RegionVid),
|
||||
Region(ty::RegionKind),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
|
||||
enum Edge<'tcx> {
|
||||
Constraint(Constraint<'tcx>),
|
||||
EnclScope(region::Scope, region::Scope),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
|
||||
fn new(
|
||||
name: String,
|
||||
region_rels: &'a RegionRelations<'a, 'tcx>,
|
||||
map: &'a ConstraintMap<'tcx>,
|
||||
) -> ConstraintGraph<'a, 'tcx> {
|
||||
let mut i = 0;
|
||||
let mut node_ids = FxHashMap::default();
|
||||
{
|
||||
let mut add_node = |node| {
|
||||
if let Vacant(e) = node_ids.entry(node) {
|
||||
e.insert(i);
|
||||
i += 1;
|
||||
}
|
||||
};
|
||||
|
||||
for (n1, n2) in map.keys().map(|c| constraint_to_nodes(c)) {
|
||||
add_node(n1);
|
||||
add_node(n2);
|
||||
}
|
||||
|
||||
region_rels.region_scope_tree.each_encl_scope(|sub, sup| {
|
||||
add_node(Node::Region(ty::ReScope(sub)));
|
||||
add_node(Node::Region(ty::ReScope(sup)));
|
||||
});
|
||||
}
|
||||
|
||||
ConstraintGraph { map, node_ids, region_rels, graph_name: name }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> {
|
||||
type Node = Node;
|
||||
type Edge = Edge<'tcx>;
|
||||
fn graph_id(&self) -> dot::Id<'_> {
|
||||
dot::Id::new(&*self.graph_name).unwrap()
|
||||
}
|
||||
fn node_id(&self, n: &Node) -> dot::Id<'_> {
|
||||
let node_id = match self.node_ids.get(n) {
|
||||
Some(node_id) => node_id,
|
||||
None => bug!("no node_id found for node: {:?}", n),
|
||||
};
|
||||
let name = || format!("node_{}", node_id);
|
||||
|
||||
dot::Id::new(name())
|
||||
.unwrap_or_else(|_| bug!("failed to create graphviz node identified by {}", name()))
|
||||
}
|
||||
fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
|
||||
match *n {
|
||||
Node::RegionVid(n_vid) => dot::LabelText::label(format!("{:?}", n_vid)),
|
||||
Node::Region(n_rgn) => dot::LabelText::label(format!("{:?}", n_rgn)),
|
||||
}
|
||||
}
|
||||
fn edge_label(&self, e: &Edge<'_>) -> dot::LabelText<'_> {
|
||||
match *e {
|
||||
Edge::Constraint(ref c) => {
|
||||
dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap()))
|
||||
}
|
||||
Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn constraint_to_nodes(c: &Constraint<'_>) -> (Node, Node) {
|
||||
match *c {
|
||||
Constraint::VarSubVar(rv_1, rv_2) => (Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
|
||||
Constraint::RegSubVar(r_1, rv_2) => (Node::Region(*r_1), Node::RegionVid(rv_2)),
|
||||
Constraint::VarSubReg(rv_1, r_2) => (Node::RegionVid(rv_1), Node::Region(*r_2)),
|
||||
Constraint::RegSubReg(r_1, r_2) => (Node::Region(*r_1), Node::Region(*r_2)),
|
||||
}
|
||||
}
|
||||
|
||||
fn edge_to_nodes(e: &Edge<'_>) -> (Node, Node) {
|
||||
match *e {
|
||||
Edge::Constraint(ref c) => constraint_to_nodes(c),
|
||||
Edge::EnclScope(sub, sup) => {
|
||||
(Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> {
|
||||
type Node = Node;
|
||||
type Edge = Edge<'tcx>;
|
||||
fn nodes(&self) -> dot::Nodes<'_, Node> {
|
||||
let set = self.node_ids.keys().cloned().collect::<FxHashSet<_>>();
|
||||
debug!("constraint graph has {} nodes", set.len());
|
||||
set.into_iter().collect()
|
||||
}
|
||||
fn edges(&self) -> dot::Edges<'_, Edge<'tcx>> {
|
||||
debug!("constraint graph has {} edges", self.map.len());
|
||||
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
|
||||
self.region_rels
|
||||
.region_scope_tree
|
||||
.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
|
||||
debug!("region graph has {} edges", v.len());
|
||||
Cow::Owned(v)
|
||||
}
|
||||
fn source(&self, edge: &Edge<'tcx>) -> Node {
|
||||
let (n1, _) = edge_to_nodes(edge);
|
||||
debug!("edge {:?} has source {:?}", edge, n1);
|
||||
n1
|
||||
}
|
||||
fn target(&self, edge: &Edge<'tcx>) -> Node {
|
||||
let (_, n2) = edge_to_nodes(edge);
|
||||
debug!("edge {:?} has target {:?}", edge, n2);
|
||||
n2
|
||||
}
|
||||
}
|
||||
|
||||
pub type ConstraintMap<'tcx> = BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
|
||||
|
||||
fn dump_region_data_to<'a, 'tcx>(
|
||||
region_rels: &RegionRelations<'a, 'tcx>,
|
||||
map: &ConstraintMap<'tcx>,
|
||||
path: &str,
|
||||
) -> io::Result<()> {
|
||||
debug!("dump_region_data map (len: {}) path: {}", map.len(), path);
|
||||
let g = ConstraintGraph::new("region_data".to_string(), region_rels, map);
|
||||
debug!("dump_region_data calling render");
|
||||
let mut v = Vec::new();
|
||||
dot::render(&g, &mut v).unwrap();
|
||||
fs::write(path, &v)
|
||||
}
|
||||
|
|
@ -18,13 +18,11 @@ use rustc_index::vec::{Idx, IndexVec};
|
|||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
|
||||
use rustc_middle::ty::{ReLateBound, RePlaceholder, ReScope, ReVar};
|
||||
use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
|
||||
use rustc_middle::ty::{Region, RegionVid};
|
||||
use rustc_span::Span;
|
||||
use std::fmt;
|
||||
|
||||
mod graphviz;
|
||||
|
||||
/// This function performs lexical region resolution given a complete
|
||||
/// set of constraints and variable origins. It performs a fixed-point
|
||||
/// iteration to find region values which satisfy all constraints,
|
||||
|
|
@ -149,7 +147,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
self.region_rels.context,
|
||||
self.dump_constraints(self.region_rels)
|
||||
);
|
||||
graphviz::maybe_print_constraints_for(&self.data, self.region_rels);
|
||||
|
||||
let graph = self.construct_graph();
|
||||
self.expand_givens(&graph);
|
||||
|
|
@ -426,15 +423,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
|
||||
match *b_data {
|
||||
VarValue::Value(cur_region) => {
|
||||
// Identical scopes can show up quite often, if the fixed point
|
||||
// iteration converges slowly. Skip them. This is purely an
|
||||
// optimization.
|
||||
if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) {
|
||||
if a_scope == cur_scope {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This is a specialized version of the `lub_concrete_regions`
|
||||
// check below for a common case, here purely as an
|
||||
// optimization.
|
||||
|
|
@ -528,8 +516,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
self.tcx().lifetimes.re_static
|
||||
}
|
||||
|
||||
(&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)))
|
||||
| (r @ (ReEarlyBound(_) | ReFree(_) | ReScope(_)), &ReEmpty(_)) => {
|
||||
(&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_)))
|
||||
| (r @ (ReEarlyBound(_) | ReFree(_)), &ReEmpty(_)) => {
|
||||
// All empty regions are less than early-bound, free,
|
||||
// and scope regions.
|
||||
r
|
||||
|
|
@ -554,46 +542,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
(&ReEarlyBound(_) | &ReFree(_), &ReScope(s_id))
|
||||
| (&ReScope(s_id), &ReEarlyBound(_) | &ReFree(_)) => {
|
||||
// A "free" region can be interpreted as "some region
|
||||
// at least as big as fr.scope". So, we can
|
||||
// reasonably compare free regions and scopes:
|
||||
let fr_scope = match (a, b) {
|
||||
(&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
|
||||
self.region_rels.region_scope_tree.early_free_scope(self.tcx(), br)
|
||||
}
|
||||
(&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
|
||||
self.region_rels.region_scope_tree.free_scope(self.tcx(), fr)
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
let r_id =
|
||||
self.region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id);
|
||||
if r_id == fr_scope {
|
||||
// if the free region's scope `fr.scope` is bigger than
|
||||
// the scope region `s_id`, then the LUB is the free
|
||||
// region itself:
|
||||
match (a, b) {
|
||||
(_, &ReScope(_)) => return a,
|
||||
(&ReScope(_), _) => return b,
|
||||
_ => bug!(),
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, we don't know what the free region is,
|
||||
// so we must conservatively say the LUB is static:
|
||||
self.tcx().lifetimes.re_static
|
||||
}
|
||||
|
||||
(&ReScope(a_id), &ReScope(b_id)) => {
|
||||
// The region corresponding to an outer block is a
|
||||
// subtype of the region corresponding to an inner
|
||||
// block.
|
||||
let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id);
|
||||
self.tcx().mk_region(ReScope(lub))
|
||||
}
|
||||
|
||||
(&ReEarlyBound(_) | &ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
|
||||
self.region_rels.lub_free_regions(a, b)
|
||||
}
|
||||
|
|
@ -662,7 +610,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
if !self.sub_concrete_regions(a_region, b_region) {
|
||||
debug!(
|
||||
"collect_errors: region error at {:?}: \
|
||||
cannot verify that {:?}={:?} <= {:?}",
|
||||
cannot verify that {:?}={:?} <= {:?}",
|
||||
origin, a_vid, a_region, b_region
|
||||
);
|
||||
*a_data = VarValue::ErrorValue;
|
||||
|
|
|
|||
|
|
@ -758,11 +758,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
|
||||
pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
|
||||
match *region {
|
||||
ty::ReScope(..)
|
||||
| ty::ReStatic
|
||||
| ty::ReErased
|
||||
| ty::ReFree(..)
|
||||
| ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
|
||||
ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
|
||||
ty::UniverseIndex::ROOT
|
||||
}
|
||||
ty::ReEmpty(ui) => ui,
|
||||
ty::RePlaceholder(placeholder) => placeholder.universe,
|
||||
ty::ReVar(vid) => self.var_universe(vid),
|
||||
|
|
|
|||
|
|
@ -87,9 +87,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
|
|||
index.hash_stable(hcx, hasher);
|
||||
name.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReScope(scope) => {
|
||||
scope.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReFree(ref free_region) => {
|
||||
free_region.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::middle::cstore::{ExternCrate, ExternCrateSource};
|
||||
use crate::middle::region;
|
||||
use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar};
|
||||
use crate::ty::layout::IntegerExt;
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
|
|
@ -1588,9 +1587,9 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||
false
|
||||
}
|
||||
|
||||
ty::ReScope(_) | ty::ReVar(_) if identify_regions => true,
|
||||
ty::ReVar(_) if identify_regions => true,
|
||||
|
||||
ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false,
|
||||
ty::ReVar(_) | ty::ReErased => false,
|
||||
|
||||
ty::ReStatic | ty::ReEmpty(_) => true,
|
||||
}
|
||||
|
|
@ -1666,32 +1665,12 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ty::ReScope(scope) if identify_regions => {
|
||||
match scope.data {
|
||||
region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())),
|
||||
region::ScopeData::CallSite => {
|
||||
p!(write("'{}cs", scope.item_local_id().as_usize()))
|
||||
}
|
||||
region::ScopeData::Arguments => {
|
||||
p!(write("'{}as", scope.item_local_id().as_usize()))
|
||||
}
|
||||
region::ScopeData::Destruction => {
|
||||
p!(write("'{}ds", scope.item_local_id().as_usize()))
|
||||
}
|
||||
region::ScopeData::Remainder(first_statement_index) => p!(write(
|
||||
"'{}_{}rs",
|
||||
scope.item_local_id().as_usize(),
|
||||
first_statement_index.index()
|
||||
)),
|
||||
}
|
||||
return Ok(self);
|
||||
}
|
||||
ty::ReVar(region_vid) if identify_regions => {
|
||||
p!(write("{:?}", region_vid));
|
||||
return Ok(self);
|
||||
}
|
||||
ty::ReVar(_) => {}
|
||||
ty::ReScope(_) | ty::ReErased => {}
|
||||
ty::ReErased => {}
|
||||
ty::ReStatic => {
|
||||
p!(write("'static"));
|
||||
return Ok(self);
|
||||
|
|
|
|||
|
|
@ -87,8 +87,6 @@ impl fmt::Debug for ty::RegionKind {
|
|||
|
||||
ty::ReFree(ref fr) => fr.fmt(f),
|
||||
|
||||
ty::ReScope(id) => write!(f, "ReScope({:?})", id),
|
||||
|
||||
ty::ReStatic => write!(f, "ReStatic"),
|
||||
|
||||
ty::ReVar(ref vid) => vid.fmt(f),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use self::InferTy::*;
|
|||
use self::TyKind::*;
|
||||
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::middle::region;
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::mir::interpret::{LitToConstInput, Scalar};
|
||||
use crate::mir::Promoted;
|
||||
|
|
@ -1179,17 +1178,15 @@ rustc_index::newtype_index! {
|
|||
|
||||
pub type Region<'tcx> = &'tcx RegionKind;
|
||||
|
||||
/// Representation of (lexical) regions. Note that the NLL checker
|
||||
/// uses a distinct representation of regions. For this reason, it
|
||||
/// internally replaces all the regions with inference variables --
|
||||
/// the index of the variable is then used to index into internal NLL
|
||||
/// data structures. See `rustc_mir::borrow_check` module for more
|
||||
/// information.
|
||||
/// Representation of regions. Note that the NLL checker uses a distinct
|
||||
/// representation of regions. For this reason, it internally replaces all the
|
||||
/// regions with inference variables -- the index of the variable is then used
|
||||
/// to index into internal NLL data structures. See `rustc_mir::borrow_check`
|
||||
/// module for more information.
|
||||
///
|
||||
/// ## The Region lattice within a given function
|
||||
///
|
||||
/// In general, the (lexical, and hence deprecated) region lattice
|
||||
/// looks like
|
||||
/// In general, the region lattice looks like
|
||||
///
|
||||
/// ```
|
||||
/// static ----------+-----...------+ (greatest)
|
||||
|
|
@ -1197,7 +1194,6 @@ pub type Region<'tcx> = &'tcx RegionKind;
|
|||
/// early-bound and | |
|
||||
/// free regions | |
|
||||
/// | | |
|
||||
/// scope regions | |
|
||||
/// | | |
|
||||
/// empty(root) placeholder(U1) |
|
||||
/// | / |
|
||||
|
|
@ -1212,13 +1208,7 @@ pub type Region<'tcx> = &'tcx RegionKind;
|
|||
/// Early-bound/free regions are the named lifetimes in scope from the
|
||||
/// function declaration. They have relationships to one another
|
||||
/// determined based on the declared relationships from the
|
||||
/// function. They all collectively outlive the scope regions. (See
|
||||
/// `RegionRelations` type, and particularly
|
||||
/// `crate::infer::outlives::free_region_map::FreeRegionMap`.)
|
||||
///
|
||||
/// The scope regions are related to one another based on the AST
|
||||
/// structure. (See `RegionRelations` type, and particularly the
|
||||
/// `rustc_middle::middle::region::ScopeTree`.)
|
||||
/// function.
|
||||
///
|
||||
/// Note that inference variables and bound regions are not included
|
||||
/// in this diagram. In the case of inference variables, they should
|
||||
|
|
@ -1307,11 +1297,6 @@ pub enum RegionKind {
|
|||
/// region parameters.
|
||||
ReFree(FreeRegion),
|
||||
|
||||
/// A concrete region naming some statically determined scope
|
||||
/// (e.g., an expression or sequence of statements) within the
|
||||
/// current function.
|
||||
ReScope(region::Scope),
|
||||
|
||||
/// Static data that has an "infinite" lifetime. Top in the region lattice.
|
||||
ReStatic,
|
||||
|
||||
|
|
@ -1535,7 +1520,6 @@ impl RegionKind {
|
|||
RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
|
||||
RegionKind::ReLateBound(_, br) => br.is_named(),
|
||||
RegionKind::ReFree(fr) => fr.bound_region.is_named(),
|
||||
RegionKind::ReScope(..) => false,
|
||||
RegionKind::ReStatic => true,
|
||||
RegionKind::ReVar(..) => false,
|
||||
RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(),
|
||||
|
|
@ -1616,7 +1600,7 @@ impl RegionKind {
|
|||
flags = flags | TypeFlags::HAS_RE_PARAM;
|
||||
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
|
||||
}
|
||||
ty::ReFree { .. } | ty::ReScope { .. } => {
|
||||
ty::ReFree { .. } => {
|
||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
},
|
||||
|
||||
ty::ReLateBound(..)
|
||||
| ty::ReScope(..)
|
||||
| ty::ReVar(..)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReEmpty(_)
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
// `least_region`. We cannot use `push_outlives_components` because regions in
|
||||
// closure signatures are not included in their outlives components. We need to
|
||||
// ensure all regions outlive the given bound so that we don't end up with,
|
||||
// say, `ReScope` appearing in a return type and causing ICEs when other
|
||||
// say, `ReVar` appearing in a return type and causing ICEs when other
|
||||
// functions end up with region constraints involving regions from other
|
||||
// functions.
|
||||
//
|
||||
|
|
@ -816,7 +816,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
// The regions that we expect from borrow checking.
|
||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
|
||||
|
||||
ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) | ty::ReScope(_) => {
|
||||
ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => {
|
||||
// All of the regions in the type should either have been
|
||||
// erased by writeback, or mapped back to named regions by
|
||||
// borrow checking.
|
||||
|
|
|
|||
|
|
@ -394,7 +394,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
|
|||
ty::BrEnv => unimplemented!(),
|
||||
},
|
||||
ReFree(_) => unimplemented!(),
|
||||
ReScope(_) => unimplemented!(),
|
||||
ReStatic => unimplemented!(),
|
||||
ReVar(_) => unimplemented!(),
|
||||
RePlaceholder(placeholder_region) => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
|
|||
use rustc_infer::infer::{InferOk, InferResult};
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty};
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits::error_reporting::ArgKind;
|
||||
|
|
@ -518,22 +518,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let InferOk { value: (), obligations } =
|
||||
self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?;
|
||||
all_obligations.extend(obligations);
|
||||
|
||||
// Also, require that the supplied type must outlive
|
||||
// the closure body.
|
||||
let closure_body_region = self.tcx.mk_region(ty::ReScope(region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::Node,
|
||||
}));
|
||||
all_obligations.push(Obligation::new(
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::PredicateKind::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
|
||||
supplied_ty,
|
||||
closure_body_region,
|
||||
)))
|
||||
.to_predicate(self.tcx),
|
||||
));
|
||||
}
|
||||
|
||||
let (supplied_output_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars(
|
||||
|
|
|
|||
|
|
@ -106,13 +106,13 @@ use rustc_hir::lang_items::{
|
|||
use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_infer::infer::{self, InferCtxt, InferOk, InferResult, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TyCtxtInferExt};
|
||||
use rustc_middle::hir::map::blocks::FnLikeNode;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
|
||||
|
|
@ -667,13 +667,6 @@ impl Inherited<'a, 'tcx> {
|
|||
let tcx = infcx.tcx;
|
||||
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let body_id = tcx.hir().maybe_body_owned_by(item_id);
|
||||
let implicit_region_bound = body_id.map(|body_id| {
|
||||
let body = tcx.hir().body(body_id);
|
||||
tcx.mk_region(ty::ReScope(region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::CallSite,
|
||||
}))
|
||||
});
|
||||
|
||||
Inherited {
|
||||
tables: MaybeInProgressTables { maybe_tables: infcx.in_progress_tables },
|
||||
|
|
@ -686,7 +679,7 @@ impl Inherited<'a, 'tcx> {
|
|||
deferred_generator_interiors: RefCell::new(Vec::new()),
|
||||
opaque_types: RefCell::new(Default::default()),
|
||||
opaque_types_vars: RefCell::new(Default::default()),
|
||||
implicit_region_bound,
|
||||
implicit_region_bound: None,
|
||||
body_id,
|
||||
}
|
||||
}
|
||||
|
|
@ -1337,12 +1330,9 @@ fn check_fn<'a, 'tcx>(
|
|||
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
|
||||
// (as it's created inside the body itself, not passed in from outside).
|
||||
let maybe_va_list = if fn_sig.c_variadic {
|
||||
let va_list_did =
|
||||
tcx.require_lang_item(VaListTypeLangItem, Some(body.params.last().unwrap().span));
|
||||
let region = tcx.mk_region(ty::ReScope(region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::CallSite,
|
||||
}));
|
||||
let span = body.params.last().unwrap().span;
|
||||
let va_list_did = tcx.require_lang_item(VaListTypeLangItem, Some(span));
|
||||
let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
|
||||
|
||||
Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool {
|
|||
|
||||
// These regions don't appear in types from type declarations:
|
||||
RegionKind::ReErased
|
||||
| RegionKind::ReScope(..)
|
||||
| RegionKind::ReVar(..)
|
||||
| RegionKind::RePlaceholder(..)
|
||||
| RegionKind::ReFree(..) => {
|
||||
|
|
|
|||
|
|
@ -444,7 +444,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ty::ReFree(..)
|
||||
| ty::ReScope(..)
|
||||
| ty::ReVar(..)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReEmpty(_)
|
||||
|
|
|
|||
|
|
@ -447,7 +447,6 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
|
|||
|
||||
ty::ReLateBound(..)
|
||||
| ty::ReFree(..)
|
||||
| ty::ReScope(..)
|
||||
| ty::ReVar(..)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReEmpty(_)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue