Skip to content

Commit 63481a5

Browse files
committed
rustc: make InferCtxt optional in MemCategorizationContext.
1 parent 1f874de commit 63481a5

File tree

9 files changed

+105
-91
lines changed

9 files changed

+105
-91
lines changed

src/librustc/infer/mod.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -393,27 +393,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
393393
fresh_tables: env.fresh_tables().map(RefCell::new),
394394
}
395395
}
396-
397-
/// Fake InferCtxt with the global tcx. Used by pre-MIR borrowck
398-
/// for MemCategorizationContext/ExprUseVisitor.
399-
/// If any inference functionality is used, ICEs will occur.
400-
pub fn borrowck_fake_infer_ctxt(self) -> InferCtxt<'a, 'gcx, 'gcx> {
401-
InferCtxt {
402-
tcx: self,
403-
tables: InferTables::Missing,
404-
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
405-
int_unification_table: RefCell::new(UnificationTable::new()),
406-
float_unification_table: RefCell::new(UnificationTable::new()),
407-
region_vars: RegionVarBindings::new(self),
408-
selection_cache: traits::SelectionCache::new(),
409-
evaluation_cache: traits::EvaluationCache::new(),
410-
projection_cache: RefCell::new(traits::ProjectionCache::new()),
411-
reported_trait_errors: RefCell::new(FxHashSet()),
412-
tainted_by_errors_flag: Cell::new(false),
413-
err_count_on_creation: self.sess.err_count(),
414-
in_snapshot: Cell::new(false),
415-
}
416-
}
417396
}
418397

419398
impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {

src/librustc/middle/expr_use_visitor.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,16 +261,32 @@ macro_rules! return_if_err {
261261
)
262262
}
263263

264-
impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
264+
impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> {
265265
pub fn new(delegate: &'a mut (Delegate<'tcx>+'a),
266-
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
266+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
267267
param_env: ty::ParamEnv<'tcx>,
268268
region_maps: &'a RegionMaps,
269269
tables: &'a ty::TypeckTables<'tcx>)
270270
-> Self
271271
{
272272
ExprUseVisitor {
273-
mc: mc::MemCategorizationContext::new(infcx, region_maps, tables),
273+
mc: mc::MemCategorizationContext::new(tcx, region_maps, tables),
274+
delegate,
275+
param_env,
276+
}
277+
}
278+
}
279+
280+
impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
281+
pub fn with_infer(delegate: &'a mut (Delegate<'tcx>+'a),
282+
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
283+
param_env: ty::ParamEnv<'tcx>,
284+
region_maps: &'a RegionMaps,
285+
tables: &'a ty::TypeckTables<'tcx>)
286+
-> Self
287+
{
288+
ExprUseVisitor {
289+
mc: mc::MemCategorizationContext::with_infer(infcx, region_maps, tables),
274290
delegate,
275291
param_env,
276292
}
@@ -296,7 +312,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
296312
}
297313

298314
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
299-
self.mc.infcx.tcx
315+
self.mc.tcx
300316
}
301317

302318
fn delegate_consume(&mut self,
@@ -306,7 +322,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
306322
debug!("delegate_consume(consume_id={}, cmt={:?})",
307323
consume_id, cmt);
308324

309-
let mode = copy_or_move(self.mc.infcx, self.param_env, &cmt, DirectRefMove);
325+
let mode = copy_or_move(&self.mc, self.param_env, &cmt, DirectRefMove);
310326
self.delegate.consume(consume_id, consume_span, cmt, mode);
311327
}
312328

@@ -784,7 +800,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
784800
PatKind::Binding(hir::BindByRef(..), ..) =>
785801
mode.lub(BorrowingMatch),
786802
PatKind::Binding(hir::BindByValue(..), ..) => {
787-
match copy_or_move(self.mc.infcx, self.param_env, &cmt_pat, PatBindingMove) {
803+
match copy_or_move(&self.mc, self.param_env, &cmt_pat, PatBindingMove) {
788804
Copy => mode.lub(CopyingMatch),
789805
Move(..) => mode.lub(MovingMatch),
790806
}
@@ -801,7 +817,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
801817
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
802818

803819
let tcx = self.tcx();
804-
let infcx = self.mc.infcx;
805820
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
806821
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
807822
if let PatKind::Binding(bmode, def_id, ..) = pat.node {
@@ -826,7 +841,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
826841
}
827842
}
828843
hir::BindByValue(..) => {
829-
let mode = copy_or_move(infcx, param_env, &cmt_pat, PatBindingMove);
844+
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
830845
debug!("walk_pat binding consuming pat");
831846
delegate.consume_pat(pat, cmt_pat, mode);
832847
}
@@ -885,7 +900,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
885900
freevar.def));
886901
match upvar_capture {
887902
ty::UpvarCapture::ByValue => {
888-
let mode = copy_or_move(self.mc.infcx,
903+
let mode = copy_or_move(&self.mc,
889904
self.param_env,
890905
&cmt_var,
891906
CaptureMove);
@@ -917,13 +932,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
917932
}
918933
}
919934

920-
fn copy_or_move<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
935+
fn copy_or_move<'a, 'gcx, 'tcx>(mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
921936
param_env: ty::ParamEnv<'tcx>,
922937
cmt: &mc::cmt<'tcx>,
923938
move_reason: MoveReason)
924939
-> ConsumeMode
925940
{
926-
if infcx.type_moves_by_default(param_env, cmt.ty, cmt.span) {
941+
if mc.type_moves_by_default(param_env, cmt.ty, cmt.span) {
927942
Move(move_reason)
928943
} else {
929944
Copy

src/librustc/middle/mem_categorization.rs

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,10 @@ impl ast_node for hir::Pat {
282282

283283
#[derive(Clone)]
284284
pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
285-
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
285+
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
286286
pub region_maps: &'a RegionMaps,
287287
pub tables: &'a ty::TypeckTables<'tcx>,
288+
infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>,
288289
}
289290

290291
pub type McResult<T> = Result<T, ()>;
@@ -385,27 +386,51 @@ impl MutabilityCategory {
385386
}
386387
}
387388

388-
impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
389-
/// Context should be the `DefId` we use to fetch region-maps.
390-
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
389+
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> {
390+
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
391391
region_maps: &'a RegionMaps,
392392
tables: &'a ty::TypeckTables<'tcx>)
393-
-> MemCategorizationContext<'a, 'gcx, 'tcx> {
394-
MemCategorizationContext { infcx, region_maps, tables }
393+
-> MemCategorizationContext<'a, 'tcx, 'tcx> {
394+
MemCategorizationContext { tcx, region_maps, tables, infcx: None }
395395
}
396+
}
396397

397-
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
398-
self.infcx.tcx
398+
impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
399+
pub fn with_infer(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
400+
region_maps: &'a RegionMaps,
401+
tables: &'a ty::TypeckTables<'tcx>)
402+
-> MemCategorizationContext<'a, 'gcx, 'tcx> {
403+
MemCategorizationContext {
404+
tcx: infcx.tcx,
405+
region_maps,
406+
tables,
407+
infcx: Some(infcx),
408+
}
409+
}
410+
411+
pub fn type_moves_by_default(&self,
412+
param_env: ty::ParamEnv<'tcx>,
413+
ty: Ty<'tcx>,
414+
span: Span)
415+
-> bool {
416+
self.infcx.map(|infcx| infcx.type_moves_by_default(param_env, ty, span))
417+
.or_else(|| {
418+
self.tcx.lift_to_global(&(param_env, ty)).map(|(param_env, ty)| {
419+
ty.moves_by_default(self.tcx.global_tcx(), param_env, span)
420+
})
421+
})
422+
.unwrap_or(true)
399423
}
400424

401425
fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
402426
where T: TypeFoldable<'tcx>
403427
{
404-
self.infcx.resolve_type_vars_if_possible(value)
428+
self.infcx.map(|infcx| infcx.resolve_type_vars_if_possible(value))
429+
.unwrap_or_else(|| value.clone())
405430
}
406431

407432
fn is_tainted_by_errors(&self) -> bool {
408-
self.infcx.is_tainted_by_errors()
433+
self.infcx.map_or(false, |infcx| infcx.is_tainted_by_errors())
409434
}
410435

411436
fn resolve_type_vars_or_error(&self,
@@ -426,7 +451,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
426451
None if self.is_tainted_by_errors() => Err(()),
427452
None => {
428453
bug!("no type for node {}: {} in mem_categorization",
429-
id, self.tcx().hir.node_to_string(id));
454+
id, self.tcx.hir.node_to_string(id));
430455
}
431456
}
432457
}
@@ -506,7 +531,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
506531
adjustment::Adjust::Deref(overloaded) => {
507532
// Equivalent to *expr or something similar.
508533
let base = if let Some(deref) = overloaded {
509-
let ref_ty = self.tcx().mk_ref(deref.region, ty::TypeAndMut {
534+
let ref_ty = self.tcx.mk_ref(deref.region, ty::TypeAndMut {
510535
ty: target,
511536
mutbl: deref.mutbl,
512537
});
@@ -624,17 +649,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
624649
}
625650

626651
Def::Upvar(def_id, _, fn_node_id) => {
627-
let var_id = self.tcx().hir.as_local_node_id(def_id).unwrap();
652+
let var_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
628653
self.cat_upvar(id, span, var_id, fn_node_id)
629654
}
630655

631656
Def::Local(def_id) => {
632-
let vid = self.tcx().hir.as_local_node_id(def_id).unwrap();
657+
let vid = self.tcx.hir.as_local_node_id(def_id).unwrap();
633658
Ok(Rc::new(cmt_ {
634659
id: id,
635660
span: span,
636661
cat: Categorization::Local(vid),
637-
mutbl: MutabilityCategory::from_local(self.tcx(), vid),
662+
mutbl: MutabilityCategory::from_local(self.tcx, vid),
638663
ty: expr_ty,
639664
note: NoteNone
640665
}))
@@ -686,7 +711,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
686711
let var_ty = self.node_ty(var_id)?;
687712

688713
// Mutability of original variable itself
689-
let var_mutbl = MutabilityCategory::from_local(self.tcx(), var_id);
714+
let var_mutbl = MutabilityCategory::from_local(self.tcx, var_id);
690715

691716
// Construct the upvar. This represents access to the field
692717
// from the environment (perhaps we should eventually desugar
@@ -753,11 +778,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
753778
-> cmt_<'tcx>
754779
{
755780
// Region of environment pointer
756-
let env_region = self.tcx().mk_region(ty::ReFree(ty::FreeRegion {
781+
let env_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
757782
// The environment of a closure is guaranteed to
758783
// outlive any bindings introduced in the body of the
759784
// closure itself.
760-
scope: self.tcx().hir.local_def_id(upvar_id.closure_expr_id),
785+
scope: self.tcx.hir.local_def_id(upvar_id.closure_expr_id),
761786
bound_region: ty::BrEnv
762787
}));
763788

@@ -774,7 +799,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
774799
// one.
775800
let cmt_result = cmt_ {
776801
mutbl: McImmutable,
777-
ty: self.tcx().types.err,
802+
ty: self.tcx.types.err,
778803
..cmt_result
779804
};
780805

@@ -806,7 +831,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
806831
pub fn temporary_scope(&self, id: ast::NodeId) -> ty::Region<'tcx>
807832
{
808833
let scope = self.region_maps.temporary_scope(id);
809-
self.tcx().mk_region(match scope {
834+
self.tcx.mk_region(match scope {
810835
Some(scope) => ty::ReScope(scope),
811836
None => ty::ReStatic
812837
})
@@ -817,20 +842,20 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
817842
span: Span,
818843
expr_ty: Ty<'tcx>)
819844
-> cmt<'tcx> {
820-
let promotable = self.tcx().rvalue_promotable_to_static.borrow().get(&id).cloned()
845+
let promotable = self.tcx.rvalue_promotable_to_static.borrow().get(&id).cloned()
821846
.unwrap_or(false);
822847

823848
// When the corresponding feature isn't toggled, only promote `[T; 0]`.
824849
let promotable = match expr_ty.sty {
825850
ty::TyArray(_, 0) => true,
826-
_ => promotable && self.tcx().sess.features.borrow().rvalue_static_promotion,
851+
_ => promotable && self.tcx.sess.features.borrow().rvalue_static_promotion,
827852
};
828853

829854
// Compute maximum lifetime of this rvalue. This is 'static if
830855
// we can promote to a constant, otherwise equal to enclosing temp
831856
// lifetime.
832857
let re = if promotable {
833-
self.tcx().types.re_static
858+
self.tcx.types.re_static
834859
} else {
835860
self.temporary_scope(id)
836861
};
@@ -911,7 +936,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
911936
span_bug!(expr.span, "cat_overloaded_lvalue: base is not a reference")
912937
}
913938
};
914-
let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut {
939+
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
915940
ty: lvalue_ty,
916941
mutbl,
917942
});
@@ -1098,8 +1123,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10981123
Def::Variant(variant_did) |
10991124
Def::VariantCtor(variant_did, ..) => {
11001125
// univariant enums do not need downcasts
1101-
let enum_did = self.tcx().parent_def_id(variant_did).unwrap();
1102-
if !self.tcx().adt_def(enum_did).is_univariant() {
1126+
let enum_did = self.tcx.parent_def_id(variant_did).unwrap();
1127+
if !self.tcx.adt_def(enum_did).is_univariant() {
11031128
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
11041129
} else {
11051130
cmt
@@ -1116,8 +1141,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11161141
let def = self.tables.qpath_def(qpath, pat.id);
11171142
let expected_len = match def {
11181143
Def::VariantCtor(def_id, CtorKind::Fn) => {
1119-
let enum_def = self.tcx().parent_def_id(def_id).unwrap();
1120-
self.tcx().adt_def(enum_def).variant_with_id(def_id).fields.len()
1144+
let enum_def = self.tcx.parent_def_id(def_id).unwrap();
1145+
self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()
11211146
}
11221147
Def::StructCtor(_, CtorKind::Fn) => {
11231148
match self.pat_ty(&pat)?.sty {

src/librustc_borrowck/borrowck/check_loans.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
200200
all_loans: all_loans,
201201
param_env,
202202
};
203-
let infcx = bccx.tcx.borrowck_fake_infer_ctxt();
204-
euv::ExprUseVisitor::new(&mut clcx, &infcx, param_env, &bccx.region_maps, bccx.tables)
203+
euv::ExprUseVisitor::new(&mut clcx, bccx.tcx, param_env, &bccx.region_maps, bccx.tables)
205204
.consume_body(body);
206205
}
207206

src/librustc_borrowck/borrowck/gather_loans/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
4949
};
5050

5151
let body = glcx.bccx.tcx.hir.body(body);
52-
let infcx = bccx.tcx.borrowck_fake_infer_ctxt();
53-
euv::ExprUseVisitor::new(&mut glcx, &infcx, param_env, &bccx.region_maps, bccx.tables)
52+
euv::ExprUseVisitor::new(&mut glcx, bccx.tcx, param_env, &bccx.region_maps, bccx.tables)
5453
.consume_body(body);
5554

5655
glcx.report_potential_errors();

src/librustc_const_eval/check_match.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -493,20 +493,18 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
493493
///
494494
/// FIXME: this should be done by borrowck.
495495
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
496-
cx.tcx.infer_ctxt(()).enter(|infcx| {
497-
let mut checker = MutationChecker {
498-
cx: cx,
499-
};
500-
ExprUseVisitor::new(&mut checker, &infcx, cx.param_env, cx.region_maps, cx.tables)
501-
.walk_expr(guard);
502-
});
496+
let mut checker = MutationChecker {
497+
cx: cx,
498+
};
499+
ExprUseVisitor::new(&mut checker, cx.tcx, cx.param_env, cx.region_maps, cx.tables)
500+
.walk_expr(guard);
503501
}
504502

505-
struct MutationChecker<'a, 'gcx: 'a> {
506-
cx: &'a MatchVisitor<'a, 'gcx>,
503+
struct MutationChecker<'a, 'tcx: 'a> {
504+
cx: &'a MatchVisitor<'a, 'tcx>,
507505
}
508506

509-
impl<'a, 'gcx, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'gcx> {
507+
impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
510508
fn matched_pat(&mut self, _: &Pat, _: cmt, _: euv::MatchMode) {}
511509
fn consume(&mut self, _: ast::NodeId, _: Span, _: cmt, _: ConsumeMode) {}
512510
fn consume_pat(&mut self, _: &Pat, _: cmt, _: ConsumeMode) {}

0 commit comments

Comments
 (0)