Simplify fields of MemCategorizationContext
This commit is contained in:
parent
4195b60323
commit
a5b8a3088a
4 changed files with 58 additions and 144 deletions
|
@ -10,7 +10,6 @@ use crate::hir::def_id::DefId;
|
||||||
use crate::hir::ptr::P;
|
use crate::hir::ptr::P;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
use crate::middle::mem_categorization as mc;
|
use crate::middle::mem_categorization as mc;
|
||||||
use crate::middle::region;
|
|
||||||
use crate::ty::{self, TyCtxt, adjustment};
|
use crate::ty::{self, TyCtxt, adjustment};
|
||||||
|
|
||||||
use crate::hir::{self, PatKind};
|
use crate::hir::{self, PatKind};
|
||||||
|
@ -85,7 +84,6 @@ impl OverloadedCallType {
|
||||||
pub struct ExprUseVisitor<'a, 'tcx> {
|
pub struct ExprUseVisitor<'a, 'tcx> {
|
||||||
mc: mc::MemCategorizationContext<'a, 'tcx>,
|
mc: mc::MemCategorizationContext<'a, 'tcx>,
|
||||||
delegate: &'a mut dyn Delegate<'tcx>,
|
delegate: &'a mut dyn Delegate<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the MC results in an error, it's because the type check
|
// If the MC results in an error, it's because the type check
|
||||||
|
@ -112,49 +110,22 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
///
|
///
|
||||||
/// - `delegate` -- who receives the callbacks
|
/// - `delegate` -- who receives the callbacks
|
||||||
/// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
|
/// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
|
||||||
/// - `region_scope_tree` --- region scope tree for the code being analyzed
|
|
||||||
/// - `tables` --- typeck results for the code being analyzed
|
/// - `tables` --- typeck results for the code being analyzed
|
||||||
///
|
|
||||||
/// See also `with_infer`, which is used *during* typeck.
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
delegate: &'a mut (dyn Delegate<'tcx> + 'a),
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
body_owner: DefId,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
region_scope_tree: &'a region::ScopeTree,
|
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
|
||||||
) -> Self {
|
|
||||||
ExprUseVisitor {
|
|
||||||
mc: mc::MemCategorizationContext::new(tcx,
|
|
||||||
param_env,
|
|
||||||
body_owner,
|
|
||||||
region_scope_tree,
|
|
||||||
tables),
|
|
||||||
delegate,
|
|
||||||
param_env,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|
||||||
pub fn with_infer(
|
|
||||||
delegate: &'a mut (dyn Delegate<'tcx> + 'a),
|
delegate: &'a mut (dyn Delegate<'tcx> + 'a),
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
body_owner: DefId,
|
body_owner: DefId,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
region_scope_tree: &'a region::ScopeTree,
|
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ExprUseVisitor {
|
ExprUseVisitor {
|
||||||
mc: mc::MemCategorizationContext::with_infer(
|
mc: mc::MemCategorizationContext::new(
|
||||||
infcx,
|
infcx,
|
||||||
param_env,
|
param_env,
|
||||||
body_owner,
|
body_owner,
|
||||||
region_scope_tree,
|
|
||||||
tables,
|
tables,
|
||||||
),
|
),
|
||||||
delegate,
|
delegate,
|
||||||
param_env,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,14 +148,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.mc.tcx
|
self.mc.tcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delegate_consume(&mut self, cmt: &mc::Place<'tcx>) {
|
fn delegate_consume(&mut self, place: &mc::Place<'tcx>) {
|
||||||
debug!("delegate_consume(cmt={:?})", cmt);
|
debug!("delegate_consume(place={:?})", place);
|
||||||
|
|
||||||
let mode = copy_or_move(&self.mc, self.param_env, cmt);
|
let mode = copy_or_move(&self.mc, place);
|
||||||
self.delegate.consume(cmt, mode);
|
self.delegate.consume(place, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consume_exprs(&mut self, exprs: &[hir::Expr]) {
|
fn consume_exprs(&mut self, exprs: &[hir::Expr]) {
|
||||||
|
@ -573,7 +544,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
|
debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
|
let ExprUseVisitor { ref mc, ref mut delegate } = *self;
|
||||||
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
|
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
|
||||||
if let PatKind::Binding(_, canonical_id, ..) = pat.kind {
|
if let PatKind::Binding(_, canonical_id, ..) = pat.kind {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -602,7 +573,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
delegate.borrow(&cmt_pat, bk);
|
delegate.borrow(&cmt_pat, bk);
|
||||||
}
|
}
|
||||||
ty::BindByValue(..) => {
|
ty::BindByValue(..) => {
|
||||||
let mode = copy_or_move(mc, param_env, &cmt_pat);
|
let mode = copy_or_move(mc, &cmt_pat);
|
||||||
debug!("walk_pat binding consuming pat");
|
debug!("walk_pat binding consuming pat");
|
||||||
delegate.consume(&cmt_pat, mode);
|
delegate.consume(&cmt_pat, mode);
|
||||||
}
|
}
|
||||||
|
@ -630,7 +601,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
var_id));
|
var_id));
|
||||||
match upvar_capture {
|
match upvar_capture {
|
||||||
ty::UpvarCapture::ByValue => {
|
ty::UpvarCapture::ByValue => {
|
||||||
let mode = copy_or_move(&self.mc, self.param_env, &cmt_var);
|
let mode = copy_or_move(&self.mc, &cmt_var);
|
||||||
self.delegate.consume(&cmt_var, mode);
|
self.delegate.consume(&cmt_var, mode);
|
||||||
}
|
}
|
||||||
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
||||||
|
@ -655,10 +626,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn copy_or_move<'a, 'tcx>(
|
fn copy_or_move<'a, 'tcx>(
|
||||||
mc: &mc::MemCategorizationContext<'a, 'tcx>,
|
mc: &mc::MemCategorizationContext<'a, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
place: &mc::Place<'tcx>,
|
||||||
cmt: &mc::Place<'tcx>,
|
|
||||||
) -> ConsumeMode {
|
) -> ConsumeMode {
|
||||||
if !mc.type_is_copy_modulo_regions(param_env, cmt.ty, cmt.span) {
|
if !mc.type_is_copy_modulo_regions(place.ty, place.span) {
|
||||||
Move
|
Move
|
||||||
} else {
|
} else {
|
||||||
Copy
|
Copy
|
||||||
|
|
|
@ -58,7 +58,6 @@ pub use self::Note::*;
|
||||||
|
|
||||||
use self::Aliasability::*;
|
use self::Aliasability::*;
|
||||||
|
|
||||||
use crate::middle::region;
|
|
||||||
use crate::hir::def_id::{DefId, LocalDefId};
|
use crate::hir::def_id::{DefId, LocalDefId};
|
||||||
use crate::hir::Node;
|
use crate::hir::Node;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
|
@ -212,13 +211,11 @@ impl HirNode for hir::Pat {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MemCategorizationContext<'a, 'tcx> {
|
pub struct MemCategorizationContext<'a, 'tcx> {
|
||||||
pub tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
pub body_owner: DefId,
|
|
||||||
pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
|
|
||||||
pub region_scope_tree: &'a region::ScopeTree,
|
|
||||||
pub tables: &'a ty::TypeckTables<'tcx>,
|
pub tables: &'a ty::TypeckTables<'tcx>,
|
||||||
infcx: Option<&'a InferCtxt<'a, 'tcx>>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
body_owner: DefId,
|
||||||
|
upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type McResult<T> = Result<T, ()>;
|
pub type McResult<T> = Result<T, ()>;
|
||||||
|
@ -327,81 +324,42 @@ impl MutabilityCategory {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
|
/// Creates a `MemCategorizationContext`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
body_owner: DefId,
|
|
||||||
region_scope_tree: &'a region::ScopeTree,
|
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
|
||||||
) -> MemCategorizationContext<'a, 'tcx> {
|
|
||||||
MemCategorizationContext {
|
|
||||||
tcx,
|
|
||||||
body_owner,
|
|
||||||
upvars: tcx.upvars(body_owner),
|
|
||||||
region_scope_tree,
|
|
||||||
tables,
|
|
||||||
infcx: None,
|
|
||||||
param_env,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|
||||||
/// Creates a `MemCategorizationContext` during type inference.
|
|
||||||
/// This is used during upvar analysis and a few other places.
|
|
||||||
/// Because the typeck tables are not yet complete, the results
|
|
||||||
/// from the analysis must be used with caution:
|
|
||||||
///
|
|
||||||
/// - rvalue promotions are not known, so the lifetimes of
|
|
||||||
/// temporaries may be overly conservative;
|
|
||||||
/// - similarly, as the results of upvar analysis are not yet
|
|
||||||
/// known, the results around upvar accesses may be incorrect.
|
|
||||||
pub fn with_infer(
|
|
||||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body_owner: DefId,
|
body_owner: DefId,
|
||||||
region_scope_tree: &'a region::ScopeTree,
|
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
) -> MemCategorizationContext<'a, 'tcx> {
|
) -> MemCategorizationContext<'a, 'tcx> {
|
||||||
let tcx = infcx.tcx;
|
|
||||||
|
|
||||||
MemCategorizationContext {
|
MemCategorizationContext {
|
||||||
tcx,
|
|
||||||
body_owner,
|
|
||||||
upvars: tcx.upvars(body_owner),
|
|
||||||
region_scope_tree,
|
|
||||||
tables,
|
tables,
|
||||||
infcx: Some(infcx),
|
infcx,
|
||||||
param_env,
|
param_env,
|
||||||
|
body_owner,
|
||||||
|
upvars: infcx.tcx.upvars(body_owner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_is_copy_modulo_regions(
|
crate fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
|
self.infcx.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn type_is_copy_modulo_regions(
|
||||||
&self,
|
&self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.infcx.map(|infcx| infcx.type_is_copy_modulo_regions(param_env, ty, span))
|
self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span)
|
||||||
.or_else(|| {
|
|
||||||
if (param_env, ty).has_local_value() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(ty.is_copy_modulo_regions(self.tcx, param_env, span))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_vars_if_possible<T>(&self, value: &T) -> T
|
fn resolve_vars_if_possible<T>(&self, value: &T) -> T
|
||||||
where T: TypeFoldable<'tcx>
|
where T: TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
self.infcx.map(|infcx| infcx.resolve_vars_if_possible(value))
|
self.infcx.resolve_vars_if_possible(value)
|
||||||
.unwrap_or_else(|| value.clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_tainted_by_errors(&self) -> bool {
|
fn is_tainted_by_errors(&self) -> bool {
|
||||||
self.infcx.map_or(false, |infcx| infcx.is_tainted_by_errors())
|
self.infcx.is_tainted_by_errors()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_type_vars_or_error(&self,
|
fn resolve_type_vars_or_error(&self,
|
||||||
|
@ -422,23 +380,20 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
None if self.is_tainted_by_errors() => Err(()),
|
None if self.is_tainted_by_errors() => Err(()),
|
||||||
None => {
|
None => {
|
||||||
bug!("no type for node {}: {} in mem_categorization",
|
bug!("no type for node {}: {} in mem_categorization",
|
||||||
id, self.tcx.hir().node_to_string(id));
|
id, self.tcx().hir().node_to_string(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_ty(&self,
|
crate fn node_ty(&self, hir_id: hir::HirId) -> McResult<Ty<'tcx>> {
|
||||||
hir_id: hir::HirId)
|
self.resolve_type_vars_or_error(hir_id, self.tables.node_type_opt(hir_id))
|
||||||
-> McResult<Ty<'tcx>> {
|
|
||||||
self.resolve_type_vars_or_error(hir_id,
|
|
||||||
self.tables.node_type_opt(hir_id))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
|
fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
|
||||||
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
|
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
|
crate fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
|
||||||
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
|
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +407,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
/// implicit deref patterns attached (e.g., it is really
|
/// implicit deref patterns attached (e.g., it is really
|
||||||
/// `&Some(x)`). In that case, we return the "outermost" type
|
/// `&Some(x)`). In that case, we return the "outermost" type
|
||||||
/// (e.g., `&Option<T>).
|
/// (e.g., `&Option<T>).
|
||||||
pub fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
|
pub(super) fn pat_ty_adjusted(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
|
||||||
// Check for implicit `&` types wrapping the pattern; note
|
// Check for implicit `&` types wrapping the pattern; note
|
||||||
// that these are never attached to binding patterns, so
|
// that these are never attached to binding patterns, so
|
||||||
// actually this is somewhat "disjoint" from the code below
|
// actually this is somewhat "disjoint" from the code below
|
||||||
|
@ -542,7 +497,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
adjustment::Adjust::Deref(overloaded) => {
|
adjustment::Adjust::Deref(overloaded) => {
|
||||||
// Equivalent to *expr or something similar.
|
// Equivalent to *expr or something similar.
|
||||||
let base = Rc::new(if let Some(deref) = overloaded {
|
let base = Rc::new(if let Some(deref) = overloaded {
|
||||||
let ref_ty = self.tcx.mk_ref(deref.region, ty::TypeAndMut {
|
let ref_ty = self.tcx().mk_ref(deref.region, ty::TypeAndMut {
|
||||||
ty: target,
|
ty: target,
|
||||||
mutbl: deref.mutbl,
|
mutbl: deref.mutbl,
|
||||||
});
|
});
|
||||||
|
@ -582,7 +537,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
expr.hir_id,
|
expr.hir_id,
|
||||||
expr,
|
expr,
|
||||||
base_cmt);
|
base_cmt);
|
||||||
let f_index = self.tcx.field_index(expr.hir_id, self.tables);
|
let f_index = self.tcx().field_index(expr.hir_id, self.tables);
|
||||||
Ok(self.cat_field(expr, base_cmt, f_index, f_ident, expr_ty))
|
Ok(self.cat_field(expr, base_cmt, f_index, f_ident, expr_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +603,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
Res::Def(DefKind::Static, def_id) => {
|
Res::Def(DefKind::Static, def_id) => {
|
||||||
// `#[thread_local]` statics may not outlive the current function, but
|
// `#[thread_local]` statics may not outlive the current function, but
|
||||||
// they also cannot be moved out of.
|
// they also cannot be moved out of.
|
||||||
let is_thread_local = self.tcx.get_attrs(def_id)[..]
|
let is_thread_local = self.tcx().get_attrs(def_id)[..]
|
||||||
.iter()
|
.iter()
|
||||||
.any(|attr| attr.check_name(sym::thread_local));
|
.any(|attr| attr.check_name(sym::thread_local));
|
||||||
|
|
||||||
|
@ -662,7 +617,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
hir_id,
|
hir_id,
|
||||||
span,
|
span,
|
||||||
cat,
|
cat,
|
||||||
mutbl: match self.tcx.static_mutability(def_id).unwrap() {
|
mutbl: match self.tcx().static_mutability(def_id).unwrap() {
|
||||||
Mutability::Immutable => McImmutable,
|
Mutability::Immutable => McImmutable,
|
||||||
Mutability::Mutable => McDeclared,
|
Mutability::Mutable => McDeclared,
|
||||||
},
|
},
|
||||||
|
@ -679,7 +634,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
hir_id,
|
hir_id,
|
||||||
span,
|
span,
|
||||||
cat: Categorization::Local(var_id),
|
cat: Categorization::Local(var_id),
|
||||||
mutbl: MutabilityCategory::from_local(self.tcx, self.tables, var_id),
|
mutbl: MutabilityCategory::from_local(self.tcx(), self.tables, var_id),
|
||||||
ty: expr_ty,
|
ty: expr_ty,
|
||||||
note: NoteNone
|
note: NoteNone
|
||||||
})
|
})
|
||||||
|
@ -722,25 +677,17 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
// FnOnce | copied | upvar -> &'up bk
|
// FnOnce | copied | upvar -> &'up bk
|
||||||
|
|
||||||
let closure_expr_def_id = self.body_owner;
|
let closure_expr_def_id = self.body_owner;
|
||||||
let fn_hir_id = self.tcx.hir().local_def_id_to_hir_id(
|
let fn_hir_id = self.tcx().hir().local_def_id_to_hir_id(
|
||||||
LocalDefId::from_def_id(closure_expr_def_id),
|
LocalDefId::from_def_id(closure_expr_def_id),
|
||||||
);
|
);
|
||||||
let ty = self.node_ty(fn_hir_id)?;
|
let ty = self.node_ty(fn_hir_id)?;
|
||||||
let kind = match ty.kind {
|
let kind = match ty.kind {
|
||||||
ty::Generator(..) => ty::ClosureKind::FnOnce,
|
ty::Generator(..) => ty::ClosureKind::FnOnce,
|
||||||
ty::Closure(closure_def_id, substs) => {
|
ty::Closure(closure_def_id, substs) => {
|
||||||
match self.infcx {
|
self.infcx.closure_kind(
|
||||||
// During upvar inference we may not know the
|
|
||||||
// closure kind, just use the LATTICE_BOTTOM value.
|
|
||||||
Some(infcx) =>
|
|
||||||
infcx.closure_kind(
|
|
||||||
closure_def_id,
|
closure_def_id,
|
||||||
substs
|
substs
|
||||||
).unwrap_or(ty::ClosureKind::LATTICE_BOTTOM),
|
).unwrap_or(ty::ClosureKind::LATTICE_BOTTOM)
|
||||||
|
|
||||||
None =>
|
|
||||||
substs.as_closure().kind(closure_def_id, self.tcx),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
|
_ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty),
|
||||||
};
|
};
|
||||||
|
@ -753,7 +700,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
let var_ty = self.node_ty(var_id)?;
|
let var_ty = self.node_ty(var_id)?;
|
||||||
|
|
||||||
// Mutability of original variable itself
|
// Mutability of original variable itself
|
||||||
let var_mutbl = MutabilityCategory::from_local(self.tcx, self.tables, var_id);
|
let var_mutbl = MutabilityCategory::from_local(self.tcx(), self.tables, var_id);
|
||||||
|
|
||||||
// Construct the upvar. This represents access to the field
|
// Construct the upvar. This represents access to the field
|
||||||
// from the environment (perhaps we should eventually desugar
|
// from the environment (perhaps we should eventually desugar
|
||||||
|
@ -818,7 +765,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
-> Place<'tcx>
|
-> Place<'tcx>
|
||||||
{
|
{
|
||||||
// Region of environment pointer
|
// Region of environment pointer
|
||||||
let env_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
let env_region = self.tcx().mk_region(ty::ReFree(ty::FreeRegion {
|
||||||
// The environment of a closure is guaranteed to
|
// The environment of a closure is guaranteed to
|
||||||
// outlive any bindings introduced in the body of the
|
// outlive any bindings introduced in the body of the
|
||||||
// closure itself.
|
// closure itself.
|
||||||
|
@ -839,7 +786,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
// one.
|
// one.
|
||||||
let cmt_result = Place {
|
let cmt_result = Place {
|
||||||
mutbl: McImmutable,
|
mutbl: McImmutable,
|
||||||
ty: self.tcx.types.err,
|
ty: self.tcx().types.err,
|
||||||
..cmt_result
|
..cmt_result
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -936,7 +883,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
ty::Ref(region, _, mutbl) => (region, mutbl),
|
ty::Ref(region, _, mutbl) => (region, mutbl),
|
||||||
_ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
|
_ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
|
||||||
};
|
};
|
||||||
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
|
let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut {
|
||||||
ty: place_ty,
|
ty: place_ty,
|
||||||
mutbl,
|
mutbl,
|
||||||
});
|
});
|
||||||
|
@ -1037,8 +984,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
variant_did: DefId)
|
variant_did: DefId)
|
||||||
-> cmt<'tcx> {
|
-> cmt<'tcx> {
|
||||||
// univariant enums do not need downcasts
|
// univariant enums do not need downcasts
|
||||||
let base_did = self.tcx.parent(variant_did).unwrap();
|
let base_did = self.tcx().parent(variant_did).unwrap();
|
||||||
if self.tcx.adt_def(base_did).variants.len() != 1 {
|
if self.tcx().adt_def(base_did).variants.len() != 1 {
|
||||||
let base_ty = base_cmt.ty;
|
let base_ty = base_cmt.ty;
|
||||||
let ret = Rc::new(Place {
|
let ret = Rc::new(Place {
|
||||||
hir_id: node.hir_id(),
|
hir_id: node.hir_id(),
|
||||||
|
@ -1179,10 +1126,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), variant_ctor_did) => {
|
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), variant_ctor_did) => {
|
||||||
let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
|
let variant_did = self.tcx().parent(variant_ctor_did).unwrap();
|
||||||
let enum_did = self.tcx.parent(variant_did).unwrap();
|
let enum_did = self.tcx().parent(variant_did).unwrap();
|
||||||
(self.cat_downcast_if_needed(pat, cmt, variant_did),
|
(self.cat_downcast_if_needed(pat, cmt, variant_did),
|
||||||
self.tcx.adt_def(enum_did)
|
self.tcx().adt_def(enum_did)
|
||||||
.variant_with_ctor_id(variant_ctor_did).fields.len())
|
.variant_with_ctor_id(variant_ctor_did).fields.len())
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
|
Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
|
||||||
|
@ -1204,7 +1151,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
def,
|
def,
|
||||||
pat.span,
|
pat.span,
|
||||||
);
|
);
|
||||||
self.tcx.sess.delay_span_bug(pat.span, &format!(
|
self.tcx().sess.delay_span_bug(pat.span, &format!(
|
||||||
"tuple struct pattern didn't resolve to variant or struct {:?}",
|
"tuple struct pattern didn't resolve to variant or struct {:?}",
|
||||||
def,
|
def,
|
||||||
));
|
));
|
||||||
|
@ -1230,7 +1177,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), variant_ctor_did) => {
|
Res::Def(DefKind::Ctor(CtorOf::Variant, _), variant_ctor_did) => {
|
||||||
let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
|
let variant_did = self.tcx().parent(variant_ctor_did).unwrap();
|
||||||
self.cat_downcast_if_needed(pat, cmt, variant_did)
|
self.cat_downcast_if_needed(pat, cmt, variant_did)
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Variant, variant_did) => {
|
Res::Def(DefKind::Variant, variant_did) => {
|
||||||
|
@ -1241,7 +1188,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
|
|
||||||
for fp in field_pats {
|
for fp in field_pats {
|
||||||
let field_ty = self.pat_ty_adjusted(&fp.pat)?; // see (*2)
|
let field_ty = self.pat_ty_adjusted(&fp.pat)?; // see (*2)
|
||||||
let f_index = self.tcx.field_index(fp.hir_id, self.tables);
|
let f_index = self.tcx().field_index(fp.hir_id, self.tables);
|
||||||
let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
|
let cmt_field = Rc::new(self.cat_field(pat, cmt.clone(), f_index,
|
||||||
fp.ident, field_ty));
|
fp.ident, field_ty));
|
||||||
self.cat_pattern_(cmt_field, &fp.pat, op)?;
|
self.cat_pattern_(cmt_field, &fp.pat, op)?;
|
||||||
|
|
|
@ -814,11 +814,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
F: for<'b> FnOnce(mc::MemCategorizationContext<'b, 'tcx>) -> R,
|
F: for<'b> FnOnce(mc::MemCategorizationContext<'b, 'tcx>) -> R,
|
||||||
{
|
{
|
||||||
f(mc::MemCategorizationContext::with_infer(
|
f(mc::MemCategorizationContext::new(
|
||||||
&self.infcx,
|
&self.infcx,
|
||||||
self.outlives_environment.param_env,
|
self.outlives_environment.param_env,
|
||||||
self.body_owner,
|
self.body_owner,
|
||||||
&self.region_scope_tree,
|
|
||||||
&self.tables.borrow(),
|
&self.tables.borrow(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,20 +171,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
|
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
|
||||||
assert_eq!(body_owner_def_id, closure_def_id);
|
assert_eq!(body_owner_def_id, closure_def_id);
|
||||||
let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id);
|
|
||||||
let mut delegate = InferBorrowKind {
|
let mut delegate = InferBorrowKind {
|
||||||
fcx: self,
|
fcx: self,
|
||||||
closure_def_id: closure_def_id,
|
closure_def_id,
|
||||||
current_closure_kind: ty::ClosureKind::LATTICE_BOTTOM,
|
current_closure_kind: ty::ClosureKind::LATTICE_BOTTOM,
|
||||||
current_origin: None,
|
current_origin: None,
|
||||||
adjust_upvar_captures: ty::UpvarCaptureMap::default(),
|
adjust_upvar_captures: ty::UpvarCaptureMap::default(),
|
||||||
};
|
};
|
||||||
euv::ExprUseVisitor::with_infer(
|
euv::ExprUseVisitor::new(
|
||||||
&mut delegate,
|
&mut delegate,
|
||||||
&self.infcx,
|
&self.infcx,
|
||||||
body_owner_def_id,
|
body_owner_def_id,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
region_scope_tree,
|
|
||||||
&self.tables.borrow(),
|
&self.tables.borrow(),
|
||||||
)
|
)
|
||||||
.consume_body(body);
|
.consume_body(body);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue