Skip to content

Commit 12e56ea

Browse files
committed
rustc: Wrap users of InferCtxt in an anonymous scope.
1 parent 8a704f6 commit 12e56ea

File tree

31 files changed

+876
-913
lines changed

31 files changed

+876
-913
lines changed

src/librustc/infer/mod.rs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,21 @@ impl fmt::Display for FixupError {
385385
}
386386

387387
impl<'a, 'tcx> InferCtxt<'a, 'tcx, 'tcx> {
388-
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
389-
tables: &'a RefCell<ty::Tables<'tcx>>,
390-
param_env: Option<ty::ParameterEnvironment<'tcx>>,
391-
projection_mode: ProjectionMode)
392-
-> Self {
393-
InferCtxt {
388+
pub fn enter<F, R>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
389+
tables: Option<ty::Tables<'tcx>>,
390+
param_env: Option<ty::ParameterEnvironment<'tcx>>,
391+
projection_mode: ProjectionMode,
392+
f: F) -> R
393+
where F: for<'b> FnOnce(InferCtxt<'b, 'tcx, 'tcx>) -> R
394+
{
395+
let new_tables;
396+
let tables = if let Some(tables) = tables {
397+
new_tables = RefCell::new(tables);
398+
&new_tables
399+
} else {
400+
&tcx.tables
401+
};
402+
f(InferCtxt {
394403
tcx: tcx,
395404
tables: tables,
396405
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
@@ -403,16 +412,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx, 'tcx> {
403412
projection_mode: projection_mode,
404413
tainted_by_errors_flag: Cell::new(false),
405414
err_count_on_creation: tcx.sess.err_count()
406-
}
415+
})
407416
}
408417

409-
pub fn normalizing(tcx: TyCtxt<'a, 'tcx, 'tcx>,
410-
tables: &'a RefCell<ty::Tables<'tcx>>,
411-
projection_mode: ProjectionMode)
412-
-> Self {
413-
let mut infcx = InferCtxt::new(tcx, tables, None, projection_mode);
414-
infcx.normalize = true;
415-
infcx
418+
pub fn enter_normalizing<F, R>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
419+
projection_mode: ProjectionMode,
420+
f: F) -> R
421+
where F: for<'b> FnOnce(InferCtxt<'b, 'tcx, 'tcx>) -> R
422+
{
423+
InferCtxt::enter(tcx, None, None, projection_mode, |mut infcx| {
424+
infcx.normalize = true;
425+
f(infcx)
426+
})
416427
}
417428
}
418429

@@ -453,23 +464,23 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
453464
return value;
454465
}
455466

456-
let infcx = InferCtxt::new(self, &self.tables, None, ProjectionMode::Any);
457-
let mut selcx = traits::SelectionContext::new(&infcx);
458-
let cause = traits::ObligationCause::dummy();
459-
let traits::Normalized { value: result, obligations } =
460-
traits::normalize(&mut selcx, cause, &value);
467+
InferCtxt::enter(self, None, None, ProjectionMode::Any, |infcx| {
468+
let mut selcx = traits::SelectionContext::new(&infcx);
469+
let cause = traits::ObligationCause::dummy();
470+
let traits::Normalized { value: result, obligations } =
471+
traits::normalize(&mut selcx, cause, &value);
461472

462-
debug!("normalize_associated_type: result={:?} obligations={:?}",
463-
result,
464-
obligations);
473+
debug!("normalize_associated_type: result={:?} obligations={:?}",
474+
result, obligations);
465475

466-
let mut fulfill_cx = traits::FulfillmentContext::new();
476+
let mut fulfill_cx = traits::FulfillmentContext::new();
467477

468-
for obligation in obligations {
469-
fulfill_cx.register_predicate_obligation(&infcx, obligation);
470-
}
478+
for obligation in obligations {
479+
fulfill_cx.register_predicate_obligation(&infcx, obligation);
480+
}
471481

472-
infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
482+
infcx.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
483+
})
473484
}
474485
}
475486

src/librustc/middle/intrinsicck.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ struct ItemVisitor<'a, 'tcx: 'a> {
3636
impl<'a, 'tcx> ItemVisitor<'a, 'tcx> {
3737
fn visit_const(&mut self, item_id: ast::NodeId, expr: &hir::Expr) {
3838
let param_env = ty::ParameterEnvironment::for_item(self.tcx, item_id);
39-
let infcx = InferCtxt::new(self.tcx, &self.tcx.tables,
40-
Some(param_env),
41-
ProjectionMode::Any);
42-
let mut visitor = ExprVisitor {
43-
infcx: &infcx
44-
};
45-
visitor.visit_expr(expr);
39+
InferCtxt::enter(self.tcx, None, Some(param_env), ProjectionMode::Any, |infcx| {
40+
let mut visitor = ExprVisitor {
41+
infcx: &infcx
42+
};
43+
visitor.visit_expr(expr);
44+
});
4645
}
4746
}
4847

@@ -115,12 +114,12 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx, 'tcx> {
115114
impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
116115
// const, static and N in [T; N].
117116
fn visit_expr(&mut self, expr: &hir::Expr) {
118-
let infcx = InferCtxt::new(self.tcx, &self.tcx.tables,
119-
None, ProjectionMode::Any);
120-
let mut visitor = ExprVisitor {
121-
infcx: &infcx
122-
};
123-
visitor.visit_expr(expr);
117+
InferCtxt::enter(self.tcx, None, None, ProjectionMode::Any, |infcx| {
118+
let mut visitor = ExprVisitor {
119+
infcx: &infcx
120+
};
121+
visitor.visit_expr(expr);
122+
});
124123
}
125124

126125
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
@@ -141,21 +140,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
141140

142141
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
143142
b: &'v hir::Block, s: Span, id: ast::NodeId) {
144-
match fk {
145-
FnKind::ItemFn(..) | FnKind::Method(..) => {
146-
let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
147-
let infcx = InferCtxt::new(self.tcx, &self.tcx.tables,
148-
Some(param_env),
149-
ProjectionMode::Any);
150-
let mut visitor = ExprVisitor {
151-
infcx: &infcx
152-
};
153-
visitor.visit_fn(fk, fd, b, s, id);
154-
}
155-
FnKind::Closure(..) => {
156-
span_bug!(s, "intrinsicck: closure outside of function")
157-
}
143+
if let FnKind::Closure(..) = fk {
144+
span_bug!(s, "intrinsicck: closure outside of function")
158145
}
146+
let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
147+
InferCtxt::enter(self.tcx, None, Some(param_env), ProjectionMode::Any, |infcx| {
148+
let mut visitor = ExprVisitor {
149+
infcx: &infcx
150+
};
151+
visitor.visit_fn(fk, fd, b, s, id);
152+
});
159153
}
160154
}
161155

src/librustc/middle/liveness.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,18 +1488,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
14881488

14891489
let param_env = ParameterEnvironment::for_item(self.ir.tcx, id);
14901490
let t_ret_subst = t_ret.subst(self.ir.tcx, &param_env.free_substs);
1491-
let infcx = InferCtxt::new(self.ir.tcx,
1492-
&self.ir.tcx.tables,
1493-
Some(param_env),
1494-
ProjectionMode::Any);
1495-
let cause = traits::ObligationCause::dummy();
1496-
let norm = traits::fully_normalize(&infcx,
1497-
cause,
1498-
&t_ret_subst);
1499-
1500-
if norm.unwrap().is_nil() {
1501-
// for nil return types, it is ok to not return a value expl.
1502-
} else {
1491+
let is_nil = InferCtxt::enter(self.ir.tcx, None, Some(param_env),
1492+
ProjectionMode::Any, |infcx| {
1493+
let cause = traits::ObligationCause::dummy();
1494+
traits::fully_normalize(&infcx, cause, &t_ret_subst).unwrap().is_nil()
1495+
});
1496+
1497+
// for nil return types, it is ok to not return a value expl.
1498+
if !is_nil {
15031499
let ends_with_stmt = match body.expr {
15041500
None if !body.stmts.is_empty() =>
15051501
match body.stmts.last().unwrap().node {

src/librustc/traits/mod.rs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub use self::object_safety::MethodViolationCode;
3737
pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
3838
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
3939
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
40-
pub use self::specialize::{Overlap, specialization_graph, specializes, translate_substs};
40+
pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
4141
pub use self::util::elaborate_predicates;
4242
pub use self::util::supertraits;
4343
pub use self::util::Supertraits;
@@ -422,42 +422,43 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
422422

423423
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
424424

425-
let infcx = InferCtxt::new(tcx, &tcx.tables, Some(elaborated_env),
426-
ProjectionMode::AnyFinal);
427-
let predicates = match fully_normalize(&infcx,
428-
cause,
429-
&infcx.parameter_environment.caller_bounds) {
430-
Ok(predicates) => predicates,
431-
Err(errors) => {
432-
infcx.report_fulfillment_errors(&errors);
433-
return infcx.parameter_environment; // an unnormalized env is better than nothing
434-
}
435-
};
436-
437-
debug!("normalize_param_env_or_error: normalized predicates={:?}",
438-
predicates);
439-
440-
let free_regions = FreeRegionMap::new();
441-
infcx.resolve_regions_and_report_errors(&free_regions, body_id);
442-
let predicates = match infcx.fully_resolve(&predicates) {
443-
Ok(predicates) => predicates,
444-
Err(fixup_err) => {
445-
// If we encounter a fixup error, it means that some type
446-
// variable wound up unconstrained. I actually don't know
447-
// if this can happen, and I certainly don't expect it to
448-
// happen often, but if it did happen it probably
449-
// represents a legitimate failure due to some kind of
450-
// unconstrained variable, and it seems better not to ICE,
451-
// all things considered.
452-
tcx.sess.span_err(span, &fixup_err.to_string());
453-
return infcx.parameter_environment; // an unnormalized env is better than nothing
454-
}
455-
};
425+
InferCtxt::enter(tcx, None, Some(elaborated_env), ProjectionMode::AnyFinal, |infcx| {
426+
let predicates = match fully_normalize(&infcx, cause,
427+
&infcx.parameter_environment.caller_bounds) {
428+
Ok(predicates) => predicates,
429+
Err(errors) => {
430+
infcx.report_fulfillment_errors(&errors);
431+
// An unnormalized env is better than nothing.
432+
return infcx.parameter_environment;
433+
}
434+
};
435+
436+
debug!("normalize_param_env_or_error: normalized predicates={:?}",
437+
predicates);
438+
439+
let free_regions = FreeRegionMap::new();
440+
infcx.resolve_regions_and_report_errors(&free_regions, body_id);
441+
let predicates = match infcx.fully_resolve(&predicates) {
442+
Ok(predicates) => predicates,
443+
Err(fixup_err) => {
444+
// If we encounter a fixup error, it means that some type
445+
// variable wound up unconstrained. I actually don't know
446+
// if this can happen, and I certainly don't expect it to
447+
// happen often, but if it did happen it probably
448+
// represents a legitimate failure due to some kind of
449+
// unconstrained variable, and it seems better not to ICE,
450+
// all things considered.
451+
tcx.sess.span_err(span, &fixup_err.to_string());
452+
// An unnormalized env is better than nothing.
453+
return infcx.parameter_environment;
454+
}
455+
};
456456

457-
debug!("normalize_param_env_or_error: resolved predicates={:?}",
458-
predicates);
457+
debug!("normalize_param_env_or_error: resolved predicates={:?}",
458+
predicates);
459459

460-
infcx.parameter_environment.with_caller_bounds(predicates)
460+
infcx.parameter_environment.with_caller_bounds(predicates)
461+
})
461462
}
462463

463464
pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx, 'tcx>,

src/librustc/traits/specialize/mod.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ use syntax::codemap::DUMMY_SP;
3131
pub mod specialization_graph;
3232

3333
/// Information pertinent to an overlapping impl error.
34-
pub struct Overlap<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
35-
pub in_context: InferCtxt<'a, 'gcx, 'tcx>,
34+
pub struct OverlapError {
3635
pub with_impl: DefId,
37-
pub on_trait_ref: ty::TraitRef<'tcx>,
36+
pub trait_desc: String,
37+
pub self_desc: Option<String>
3838
}
3939

4040
/// Given a subst for the requested impl, translate it to a subst
@@ -135,8 +135,6 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
135135
return false;
136136
}
137137

138-
let mut infcx = InferCtxt::normalizing(tcx, &tcx.tables, ProjectionMode::Topmost);
139-
140138
// create a parameter environment corresponding to a (skolemized) instantiation of impl1
141139
let scheme = tcx.lookup_item_type(impl1_def_id);
142140
let predicates = tcx.lookup_predicates(impl1_def_id);
@@ -148,18 +146,21 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
148146
.unwrap()
149147
.subst(tcx, &penv.free_substs);
150148

151-
// Normalize the trait reference, adding any obligations that arise into the impl1 assumptions
152-
let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = {
153-
let selcx = &mut SelectionContext::new(&infcx);
154-
traits::normalize(selcx, ObligationCause::dummy(), &impl1_trait_ref)
155-
};
156-
penv.caller_bounds.extend(normalization_obligations.into_iter().map(|o| o.predicate));
149+
InferCtxt::enter_normalizing(tcx, ProjectionMode::Topmost, |mut infcx| {
150+
// Normalize the trait reference, adding any obligations
151+
// that arise into the impl1 assumptions.
152+
let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = {
153+
let selcx = &mut SelectionContext::new(&infcx);
154+
traits::normalize(selcx, ObligationCause::dummy(), &impl1_trait_ref)
155+
};
156+
penv.caller_bounds.extend(normalization_obligations.into_iter().map(|o| o.predicate));
157157

158-
// Install the parameter environment, taking the predicates of impl1 as assumptions:
159-
infcx.parameter_environment = penv;
158+
// Install the parameter environment, taking the predicates of impl1 as assumptions:
159+
infcx.parameter_environment = penv;
160160

161-
// Attempt to prove that impl2 applies, given all of the above.
162-
fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok()
161+
// Attempt to prove that impl2 applies, given all of the above.
162+
fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok()
163+
})
163164
}
164165

165166
/// Attempt to fulfill all obligations of `target_impl` after unification with

0 commit comments

Comments
 (0)