rustc: make the comon case of tcx.infer_ctxt(()) nicer.

This commit is contained in:
Eduard-Mihai Burtescu 2017-06-09 10:55:16 +03:00
parent 63481a57dc
commit fc5c31c48c
19 changed files with 102 additions and 112 deletions

View File

@ -31,7 +31,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use ty::relate::RelateResult;
use traits::{self, ObligationCause, PredicateObligations, Reveal};
use rustc_data_structures::unify::{self, UnificationTable};
use std::cell::{Cell, RefCell, Ref, RefMut};
use std::cell::{Cell, RefCell, Ref};
use std::fmt;
use syntax::ast;
use errors::DiagnosticBuilder;
@ -72,39 +72,14 @@ pub type Bound<T> = Option<T>;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
/// A version of &ty::TypeckTables which can be `Missing` (not needed),
/// `InProgress` (during typeck) or `Interned` (result of typeck).
/// Only the `InProgress` version supports `borrow_mut`.
#[derive(Copy, Clone)]
pub enum InferTables<'a, 'tcx: 'a> {
InProgress(&'a RefCell<ty::TypeckTables<'tcx>>),
Missing
}
impl<'a, 'tcx> InferTables<'a, 'tcx> {
pub fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
match self {
InferTables::InProgress(tables) => tables.borrow(),
InferTables::Missing => {
bug!("InferTables: infcx.tables.borrow() with no tables")
}
}
}
pub fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
match self {
InferTables::InProgress(tables) => tables.borrow_mut(),
InferTables::Missing => {
bug!("InferTables: infcx.tables.borrow_mut() with no tables")
}
}
}
}
pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub tables: InferTables<'a, 'tcx>,
/// During type-checking/inference of a body, `in_progress_tables`
/// contains a reference to the tables being built up, which are
/// used for reading closure kinds/signatures as they are inferred,
/// and for error reporting logic to read arbitrary node types.
pub in_progress_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
// Cache for projections. This cache is snapshotted along with the
// infcx.
@ -360,23 +335,7 @@ impl fmt::Display for FixupError {
}
}
pub trait InferEnv<'a, 'tcx> {
fn fresh_tables(self) -> Option<ty::TypeckTables<'tcx>>;
}
impl<'a, 'tcx> InferEnv<'a, 'tcx> for () {
fn fresh_tables(self) -> Option<ty::TypeckTables<'tcx>> {
None
}
}
impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::TypeckTables<'tcx> {
fn fresh_tables(self) -> Option<ty::TypeckTables<'tcx>> {
Some(self)
}
}
/// Helper type of a temporary returned by tcx.infer_ctxt(...).
/// Helper type of a temporary returned by tcx.infer_ctxt().
/// Necessary because we can't write the following bound:
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>).
pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
@ -386,16 +345,23 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self, env: E) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
InferCtxtBuilder {
global_tcx: self,
arena: DroplessArena::new(),
fresh_tables: env.fresh_tables().map(RefCell::new),
fresh_tables: None,
}
}
}
impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
/// Used only by `rustc_typeck` during body type-checking/inference,
/// will initialize `in_progress_tables` with fresh `TypeckTables`.
pub fn with_fresh_in_progress_tables(mut self) -> Self {
self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty()));
self
}
pub fn enter<F, R>(&'tcx mut self, f: F) -> R
where F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R
{
@ -404,11 +370,10 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
ref arena,
ref fresh_tables,
} = *self;
let tables = fresh_tables.as_ref()
.map_or(InferTables::Missing, InferTables::InProgress);
let in_progress_tables = fresh_tables.as_ref();
global_tcx.enter_local(arena, |tcx| f(InferCtxt {
tcx: tcx,
tables: tables,
tcx,
in_progress_tables,
projection_cache: RefCell::new(traits::ProjectionCache::new()),
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
int_unification_table: RefCell::new(UnificationTable::new()),
@ -531,7 +496,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
return value;
}
self.infer_ctxt(()).enter(|infcx| {
self.infer_ctxt().enter(|infcx| {
value.trans_normalize(&infcx, param_env)
})
}
@ -553,7 +518,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
return value;
}
self.infer_ctxt(()).enter(|infcx| {
self.infer_ctxt().enter(|infcx| {
value.trans_normalize(&infcx, env.reveal_all())
})
}
@ -757,10 +722,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
was_in_snapshot: in_snapshot,
// Borrow tables "in progress" (i.e. during typeck)
// to ban writes from within a snapshot to them.
_in_progress_tables: match self.tables {
InferTables::InProgress(ref tables) => tables.try_borrow().ok(),
_ => None
}
_in_progress_tables: self.in_progress_tables.map(|tables| {
tables.borrow()
})
}
}
@ -1366,14 +1330,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span)
-> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.
let local_closures = match self.tables {
InferTables::InProgress(_) => ty.has_closure_types(),
_ => false
};
if !local_closures {
// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.
if !self.in_progress_tables.is_some() || !ty.has_closure_types() {
if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
return ty.moves_by_default(self.tcx.global_tcx(), param_env, span);
}
}
@ -1391,7 +1351,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
def_id: DefId)
-> Option<ty::ClosureKind>
{
if let InferTables::InProgress(tables) = self.tables {
if let Some(tables) = self.in_progress_tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
return tables.borrow()
.closure_kinds
@ -1409,7 +1369,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn closure_type(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
if let InferTables::InProgress(tables) = self.tables {
if let Some(tables) = self.in_progress_tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
if let Some(&ty) = tables.borrow().closure_tys.get(&id) {
return ty;

View File

@ -29,7 +29,7 @@ use hir::{self, intravisit, Local, Pat, Body};
use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::map::NodeExpr;
use hir::def_id::DefId;
use infer::{self, InferCtxt, InferTables};
use infer::{self, InferCtxt};
use infer::type_variable::TypeVariableOrigin;
use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
use std::fmt;
@ -72,9 +72,12 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
}
impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
fn node_matches_type(&mut self, node_id: &'gcx NodeId) -> bool {
match self.infcx.tables.borrow().node_types.get(node_id) {
Some(&ty) => {
fn node_matches_type(&mut self, node_id: NodeId) -> bool {
let ty_opt = self.infcx.in_progress_tables.and_then(|tables| {
tables.borrow().node_id_to_type_opt(node_id)
});
match ty_opt {
Some(ty) => {
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
ty.walk().any(|inner_ty| {
inner_ty == *self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
@ -88,7 +91,7 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
}
})
}
_ => false,
None => false,
}
}
}
@ -99,7 +102,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
}
fn visit_local(&mut self, local: &'gcx Local) {
if self.found_local_pattern.is_none() && self.node_matches_type(&local.id) {
if self.found_local_pattern.is_none() && self.node_matches_type(local.id) {
self.found_local_pattern = Some(&*local.pat);
}
intravisit::walk_local(self, local);
@ -107,7 +110,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
fn visit_body(&mut self, body: &'gcx Body) {
for argument in &body.arguments {
if self.found_arg_pattern.is_none() && self.node_matches_type(&argument.id) {
if self.found_arg_pattern.is_none() && self.node_matches_type(argument.id) {
self.found_arg_pattern = Some(&*argument.pat);
}
}
@ -654,7 +657,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// Additional context information explaining why the closure only implements
// a particular trait.
if let InferTables::InProgress(tables) = self.tables {
if let Some(tables) = self.in_progress_tables {
match tables.borrow().closure_kinds.get(&node_id) {
Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
err.span_note(span, &format!(

View File

@ -484,7 +484,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
unnormalized_env.reveal);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let predicates = match fully_normalize(
&infcx,
cause,
@ -598,7 +598,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("normalize_and_test_predicates(predicates={:?})",
predicates);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty(Reveal::All);
let mut selcx = SelectionContext::new(&infcx);
let mut fulfill_cx = FulfillmentContext::new();

View File

@ -125,7 +125,7 @@ pub fn find_associated_item<'a, 'tcx>(
let ancestors = trait_def.ancestors(tcx, impl_data.impl_def_id);
match ancestors.defs(tcx, item.name, item.kind).next() {
Some(node_item) => {
let substs = tcx.infer_ctxt(()).enter(|infcx| {
let substs = tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty(Reveal::All);
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id,
@ -188,7 +188,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
// Create a infcx, taking the predicates of impl1 as assumptions:
let result = tcx.infer_ctxt(()).enter(|infcx| {
let result = tcx.infer_ctxt().enter(|infcx| {
// Normalize the trait reference. The WF rules ought to ensure
// that this always succeeds.
let impl1_trait_ref =

View File

@ -109,7 +109,7 @@ impl<'a, 'gcx, 'tcx> Children {
let possible_sibling = *slot;
let tcx = tcx.global_tcx();
let (le, ge) = tcx.infer_ctxt(()).enter(|infcx| {
let (le, ge) = tcx.infer_ctxt().enter(|infcx| {
let overlap = traits::overlapping_impls(&infcx,
possible_sibling,
impl_def_id);

View File

@ -46,7 +46,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
self.infer_ctxt(()).enter(|infcx| {
self.infer_ctxt().enter(|infcx| {
let mut selcx = SelectionContext::new(&infcx);
let param_env = ty::ParamEnv::empty(Reveal::All);

View File

@ -175,7 +175,7 @@ impl<'tcx> ty::ParamEnv<'tcx> {
self_type: Ty<'tcx>, span: Span)
-> Result<(), CopyImplementationError<'tcx>> {
// FIXME: (@jroesch) float this code up
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let (adt, substs) = match self_type.sty {
ty::TyAdt(adt, substs) => (adt, substs),
_ => return Err(CopyImplementationError::NotAnAdt),
@ -977,7 +977,7 @@ fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
{
let (param_env, ty) = query.into_parts();
let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem);
tcx.infer_ctxt(())
tcx.infer_ctxt()
.enter(|infcx| traits::type_known_to_meet_bound(&infcx,
param_env,
ty,
@ -991,7 +991,7 @@ fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
{
let (param_env, ty) = query.into_parts();
let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem);
tcx.infer_ctxt(())
tcx.infer_ctxt()
.enter(|infcx| traits::type_known_to_meet_bound(&infcx,
param_env,
ty,
@ -1005,7 +1005,7 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
{
let (param_env, ty) = query.into_parts();
let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem);
tcx.infer_ctxt(())
tcx.infer_ctxt()
.enter(|infcx| traits::type_known_to_meet_bound(&infcx,
param_env,
ty,

View File

@ -483,7 +483,7 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("resolve_trait_associated_const: trait_ref={:?}",
trait_ref);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let mut selcx = traits::SelectionContext::new(&infcx);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),

View File

@ -154,7 +154,7 @@ fn test_env<F>(source_string: &str,
index,
"test_crate",
|tcx| {
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let mut region_maps = RegionMaps::new();
body(Env {
infcx: &infcx,

View File

@ -956,7 +956,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
cx.param_env,
trait_ref.to_poly_trait_predicate());
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let mut selcx = traits::SelectionContext::new(&infcx);
match selcx.select(&obligation) {
// The method comes from a `T: Trait` bound.

View File

@ -83,7 +83,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
};
let src = MirSource::from_node(tcx, id);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let cx = Cx::new(&infcx, src);
let mut mir = if cx.tables().tainted_by_errors {
build::construct_error(cx, body_id)
@ -171,7 +171,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
{
let span = tcx.hir.span(ctor_id);
if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let (mut mir, src) =
shim::build_adt_ctor(&infcx, ctor_id, fields, span);

View File

@ -998,7 +998,7 @@ impl MirPass for QualifyAndPromoteConstants {
// Statics must be Sync.
if mode == Mode::Static {
let ty = mir.return_ty;
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
let mut fulfillment_cx = traits::FulfillmentContext::new();

View File

@ -759,7 +759,7 @@ impl MirPass for TypeckMir {
return;
}
let param_env = tcx.param_env(def_id);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let mut checker = TypeChecker::new(&infcx, item_id, param_env);
{
let mut verifier = TypeVerifier::new(&mut checker, mir);

View File

@ -219,7 +219,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env,
normalize_cause.clone());
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let inh = Inherited::new(infcx, impl_m.def_id);
let infcx = &inh.infcx;
@ -726,7 +726,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_trait_ref: ty::TraitRef<'tcx>) {
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let inh = Inherited::new(infcx, impl_c.def_id);
let infcx = &inh.infcx;

View File

@ -79,7 +79,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.
tcx.infer_ctxt(()).enter(|ref infcx| {
tcx.infer_ctxt().enter(|ref infcx| {
let impl_param_env = tcx.param_env(self_type_did);
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

View File

@ -108,7 +108,7 @@ use lint;
use util::common::{ErrorReported, indenter};
use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
use std::cell::{Cell, RefCell};
use std::cell::{Cell, RefCell, Ref, RefMut};
use std::collections::hash_map::Entry;
use std::cmp;
use std::mem::replace;
@ -147,6 +147,33 @@ mod compare_method;
mod intrinsic;
mod op;
/// A wrapper for InferCtxt's `in_progress_tables` field.
#[derive(Copy, Clone)]
struct MaybeInProgressTables<'a, 'tcx: 'a> {
maybe_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
}
impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
fn borrow(self) -> Ref<'a, ty::TypeckTables<'tcx>> {
match self.maybe_tables {
Some(tables) => tables.borrow(),
None => {
bug!("MaybeInProgressTables: inh/fcx.tables.borrow() with no tables")
}
}
}
fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> {
match self.maybe_tables {
Some(tables) => tables.borrow_mut(),
None => {
bug!("MaybeInProgressTables: inh/fcx.tables.borrow_mut() with no tables")
}
}
}
}
/// closures defined within the function. For example:
///
/// fn foo() {
@ -159,6 +186,8 @@ mod op;
pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
infcx: InferCtxt<'a, 'gcx, 'tcx>,
tables: MaybeInProgressTables<'a, 'tcx>,
locals: RefCell<NodeMap<Ty<'tcx>>>,
fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
@ -535,9 +564,8 @@ pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
-> InheritedBuilder<'a, 'gcx, 'tcx> {
let tables = ty::TypeckTables::empty();
InheritedBuilder {
infcx: tcx.infer_ctxt(tables),
infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(),
def_id,
}
}
@ -562,6 +590,9 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
});
Inherited {
tables: MaybeInProgressTables {
maybe_tables: infcx.in_progress_tables,
},
infcx: infcx,
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
locals: RefCell::new(NodeMap()),
@ -3302,14 +3333,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_expr_has_type(base_expr, struct_ty);
match struct_ty.sty {
ty::TyAdt(adt, substs) if adt.is_struct() => {
self.tables.borrow_mut().fru_field_types.insert(
expr.id,
adt.struct_variant().fields.iter().map(|f| {
self.normalize_associated_types_in(
expr.span, &f.ty(self.tcx, substs)
)
}).collect()
);
let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
}).collect();
self.tables.borrow_mut().fru_field_types.insert(expr.id, fru_field_types);
}
_ => {
span_err!(self.tcx.sess, base_expr.span, E0436,

View File

@ -208,7 +208,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source,
target);
tcx.infer_ctxt(()).enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let cause = ObligationCause::misc(span, impl_node_id);
let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
mt_b: ty::TypeAndMut<'tcx>,

View File

@ -70,7 +70,7 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
for (i, &impl1_def_id) in impls.iter().enumerate() {
for &impl2_def_id in &impls[(i + 1)..] {
self.tcx.infer_ctxt(()).enter(|infcx| {
self.tcx.infer_ctxt().enter(|infcx| {
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() {
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id)
}

View File

@ -155,7 +155,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
-> bool {
tcx.infer_ctxt(()).enter(|ref infcx| {
tcx.infer_ctxt().enter(|ref infcx| {
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
let mut fulfill_cx = FulfillmentContext::new();
match infcx.at(&cause, param_env).eq(expected, actual) {