move projection mode into parameter environment

This commit is contained in:
Niko Matsakis 2017-05-17 08:01:04 -04:00
parent 4ed2edaafe
commit 6c4b961eff
28 changed files with 110 additions and 99 deletions

View File

@ -174,11 +174,6 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FxHashSet<traits::TraitErrorKey<'tcx>>>,
// Sadly, the behavior of projection varies a bit depending on the
// stage of compilation. The specifics are given in the
// documentation for `Reveal`.
projection_mode: Reveal,
// When an error occurs, we want to avoid reporting "derived"
// errors that are due to this original failure. Normally, we
// handle this with the `err_count_on_creation` count, which
@ -406,15 +401,15 @@ pub trait InferEnv<'a, 'tcx> {
fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>);
ty::ParamEnv<'tcx>);
}
impl<'a, 'tcx> InferEnv<'a, 'tcx> for () {
impl<'a, 'tcx> InferEnv<'a, 'tcx> for Reveal {
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>) {
(None, None, None)
ty::ParamEnv<'tcx>) {
(None, None, ty::ParamEnv::empty(self))
}
}
@ -422,8 +417,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParamEnv<'tcx> {
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>) {
(None, None, Some(self))
ty::ParamEnv<'tcx>) {
(None, None, self)
}
}
@ -431,8 +426,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParamEnv<
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>) {
(Some(self.0), None, Some(self.1))
ty::ParamEnv<'tcx>) {
(Some(self.0), None, self.1)
}
}
@ -440,8 +435,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParamEnv<'tcx
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>) {
(None, Some(self.0), Some(self.1))
ty::ParamEnv<'tcx>) {
(None, Some(self.0), self.1)
}
}
@ -449,11 +444,11 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParamEnv<'tcx>>) {
ty::ParamEnv<'tcx>) {
let def_id = tcx.hir.body_owner_def_id(self);
(Some(tcx.typeck_tables_of(def_id)),
None,
Some(tcx.param_env(def_id)))
tcx.param_env(def_id))
}
}
@ -465,15 +460,11 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
arena: DroplessArena,
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
tables: Option<&'a ty::TypeckTables<'gcx>>,
param_env: Option<ty::ParamEnv<'gcx>>,
projection_mode: Reveal,
param_env: ty::ParamEnv<'gcx>,
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self,
env: E,
projection_mode: Reveal)
-> InferCtxtBuilder<'a, 'gcx, 'tcx> {
pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self, env: E) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
let (tables, fresh_tables, param_env) = env.to_parts(self);
InferCtxtBuilder {
global_tcx: self,
@ -481,7 +472,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
fresh_tables: fresh_tables.map(RefCell::new),
tables: tables,
param_env: param_env,
projection_mode: projection_mode,
}
}
@ -498,12 +488,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
int_unification_table: RefCell::new(UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(self),
param_env: param_env.unwrap(),
param_env: param_env,
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
projection_cache: RefCell::new(traits::ProjectionCache::new()),
reported_trait_errors: RefCell::new(FxHashSet()),
projection_mode: Reveal::UserFacing,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count(),
in_snapshot: Cell::new(false),
@ -520,13 +509,11 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
ref arena,
ref fresh_tables,
tables,
ref mut param_env,
projection_mode,
param_env,
} = *self;
let tables = tables.map(InferTables::Interned).unwrap_or_else(|| {
fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress)
});
let param_env = param_env.take().unwrap_or_else(|| ty::ParamEnv::empty());
global_tcx.enter_local(arena, |tcx| f(InferCtxt {
tcx: tcx,
tables: tables,
@ -539,7 +526,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
reported_trait_errors: RefCell::new(FxHashSet()),
projection_mode: projection_mode,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
@ -643,11 +629,15 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
return value;
}
self.infer_ctxt((), Reveal::All).enter(|infcx| {
self.infer_ctxt(Reveal::All).enter(|infcx| {
value.trans_normalize(&infcx)
})
}
/// Does a best-effort to normalize any associated types in
/// `value`; this includes revealing specializable types, so this
/// should be not be used during type-checking, but only during
/// optimization and code generation.
pub fn normalize_associated_type_in_env<T>(
self, value: &T, env: ty::ParamEnv<'tcx>
) -> T
@ -661,7 +651,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
return value;
}
self.infer_ctxt(env, Reveal::All).enter(|infcx| {
self.infer_ctxt(env.reveal_all()).enter(|infcx| {
value.trans_normalize(&infcx)
})
}
@ -728,10 +718,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}
pub fn projection_mode(&self) -> Reveal {
self.projection_mode
}
pub fn is_in_snapshot(&self) -> bool {
self.in_snapshot.get()
}

View File

@ -11,7 +11,6 @@
use hir::def::Def;
use hir::def_id::DefId;
use infer::InferCtxt;
use traits::Reveal;
use ty::{self, Ty, TyCtxt};
use ty::layout::{LayoutError, Pointer, SizeSkeleton};
@ -140,7 +139,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
fn visit_nested_body(&mut self, body_id: hir::BodyId) {
let body = self.tcx.hir.body(body_id);
self.tcx.infer_ctxt(body_id, Reveal::All).enter(|infcx| {
self.tcx.infer_ctxt(body_id).enter(|infcx| {
let mut visitor = ExprVisitor {
infcx: &infcx
};

View File

@ -477,9 +477,10 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
predicates);
let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates));
let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
unnormalized_env.reveal);
tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(elaborated_env).enter(|infcx| {
let predicates = match fully_normalize(
&infcx, cause,
// You would really want to pass infcx.param_env.caller_bounds here,
@ -528,7 +529,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("normalize_param_env_or_error: resolved predicates={:?}",
predicates);
ty::ParamEnv::new(tcx.intern_predicates(&predicates))
ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal)
})
}
@ -590,7 +591,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("normalize_and_test_predicates(predicates={:?})",
predicates);
tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
tcx.infer_ctxt(Reveal::All).enter(|infcx| {
let mut selcx = SelectionContext::new(&infcx);
let mut fulfill_cx = FulfillmentContext::new();
let cause = ObligationCause::dummy();

View File

@ -36,7 +36,7 @@ use util::common::FN_OUTPUT_NAME;
/// Depending on the stage of compilation, we want projection to be
/// more or less conservative.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Reveal {
/// At type-checking time, we refuse to project any associated
/// type that is marked `default`. Non-`default` ("final") types
@ -278,12 +278,14 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
match ty.sty {
ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => { // (*)
// Only normalize `impl Trait` after type-checking, usually in trans.
if self.selcx.projection_mode() == Reveal::All {
let generic_ty = self.tcx().type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.fold_ty(concrete_ty)
} else {
ty
match self.param_env.reveal {
Reveal::UserFacing => ty,
Reveal::All => {
let generic_ty = self.tcx().type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.fold_ty(concrete_ty)
}
}
}

View File

@ -324,7 +324,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
pub fn projection_mode(&self) -> Reveal {
self.infcx.projection_mode()
self.param_env().reveal
}
/// Wraps the inference context's in_snapshot s.t. snapshot handling is only from the selection

View File

@ -122,7 +122,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((), Reveal::All).enter(|infcx| {
let substs = tcx.infer_ctxt(Reveal::All).enter(|infcx| {
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
let substs = translate_substs(&infcx, impl_data.impl_def_id,
substs, node_item.node);
@ -184,7 +184,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(penv, Reveal::UserFacing).enter(|infcx| {
let result = tcx.infer_ctxt(penv).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((), Reveal::UserFacing).enter(|infcx| {
let (le, ge) = tcx.infer_ctxt(Reveal::UserFacing).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((), Reveal::All).enter(|infcx| {
self.infer_ctxt(Reveal::All).enter(|infcx| {
let mut selcx = SelectionContext::new(&infcx);
let obligation_cause = ObligationCause::misc(span,

View File

@ -906,6 +906,12 @@ define_maps! { <'tcx>
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
[] is_object_safe: ObjectSafety(DefId) -> bool,
// Get the ParameterEnvironment for a given item; this environment
// will be in "user-facing" mode, meaning that it is suitabe for
// type-checking etc, and it does not normalize specializable
// associated types. This is almost always what you want,
// unless you are doing MIR optimizations, in which case you
// might want to use `reveal_all()` method to change modes.
[] param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,

View File

@ -1191,6 +1191,11 @@ pub struct ParamEnv<'tcx> {
/// the set of bounds on the in-scope type parameters, translated
/// into Obligations, and elaborated and normalized.
pub caller_bounds: &'tcx Slice<ty::Predicate<'tcx>>,
/// Typically, this is `Reveal::UserFacing`, but during trans we
/// want `Reveal::All` -- note that this is always paired with an
/// empty environment. To get that, use `ParamEnv::reveal()`.
pub reveal: traits::Reveal,
}
impl<'tcx> ParamEnv<'tcx> {
@ -1218,7 +1223,7 @@ impl<'tcx> ParamEnv<'tcx> {
}
} else {
ParamEnvAnd {
param_env: ParamEnv::empty(),
param_env: ParamEnv::empty(self.reveal),
value: value,
}
}
@ -2467,8 +2472,8 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
/// See `ParamEnv` struct def'n for details.
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ParamEnv<'tcx> {
def_id: DefId)
-> ParamEnv<'tcx> {
// Compute the bounds on Self and the type parameters.
let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
@ -2486,7 +2491,8 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// are any errors at that point, so after type checking you can be
// sure that this will succeed without errors anyway.
let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates));
let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
traits::Reveal::UserFacing);
let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)

View File

@ -150,20 +150,32 @@ pub enum Representability {
impl<'tcx> ty::ParamEnv<'tcx> {
/// Construct a trait environment suitable for contexts where
/// there are no where clauses in scope.
pub fn empty() -> Self {
Self::new(ty::Slice::empty())
pub fn empty(reveal: Reveal) -> Self {
Self::new(ty::Slice::empty(), reveal)
}
/// Construct a trait environment with the given set of predicates.
pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>) -> Self {
ty::ParamEnv { caller_bounds }
pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>,
reveal: Reveal)
-> Self {
ty::ParamEnv { caller_bounds, reveal }
}
/// Returns a new parameter environment with the same clauses, but
/// which "reveals" the true results of projections in all cases
/// (even for associated types that are specializable). This is
/// the desired behavior during trans and certain other special
/// contexts; normally though we want to use `Reveal::UserFacing`,
/// which is the default.
pub fn reveal_all(self) -> Self {
ty::ParamEnv { reveal: Reveal::All, ..self }
}
pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
self_type: Ty<'tcx>, span: Span)
-> Result<(), CopyImplementationError> {
// FIXME: (@jroesch) float this code up
tcx.infer_ctxt(self.clone(), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(self.clone()).enter(|infcx| {
let (adt, substs) = match self_type.sty {
ty::TyAdt(adt, substs) => (adt, substs),
_ => return Err(CopyImplementationError::NotAnAdt),
@ -970,7 +982,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(param_env, Reveal::UserFacing)
tcx.infer_ctxt(param_env)
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
}
@ -980,7 +992,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(param_env, Reveal::UserFacing)
tcx.infer_ctxt(param_env)
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
}
@ -990,7 +1002,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(param_env, Reveal::UserFacing)
tcx.infer_ctxt(param_env)
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
}

View File

@ -20,7 +20,6 @@ use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization::{cmt};
use rustc::middle::region::RegionMaps;
use rustc::session::Session;
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::lint;
use rustc_errors::{Diagnostic, Level, DiagnosticBuilder};
@ -518,7 +517,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
///
/// FIXME: this should be done by borrowck.
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
cx.tcx.infer_ctxt((cx.tables, cx.param_env), Reveal::UserFacing).enter(|infcx| {
cx.tcx.infer_ctxt((cx.tables, cx.param_env)).enter(|infcx| {
let mut checker = MutationChecker {
cx: cx,
};

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((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
let mut selcx = traits::SelectionContext::new(&infcx);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());

View File

@ -488,7 +488,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
if def.has_dtor(cx.tcx) {
return;
}
let param_env = ty::ParamEnv::empty();
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
if !ty.moves_by_default(cx.tcx, param_env, item.span) {
return;
}
@ -956,7 +956,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
trait_ref.to_poly_trait_predicate());
let param_env = tcx.param_env(method.def_id);
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(param_env).enter(|infcx| {
let mut selcx = traits::SelectionContext::new(&infcx);
match selcx.select(&obligation) {
// The method comes from a `T: Trait` bound.

View File

@ -725,7 +725,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
if gens.ty_params.is_empty() {
// sizes only make sense for non-generic types
let t = cx.tcx.type_of(cx.tcx.hir.local_def_id(it.id));
let layout = cx.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
let layout = cx.tcx.infer_ctxt(Reveal::All).enter(|infcx| {
let ty = cx.tcx.erase_regions(&t);
ty.layout(&infcx).unwrap_or_else(|e| {
bug!("failed to get layout for `{}`: {}", t, e)

View File

@ -18,7 +18,6 @@ use rustc::middle::region::CodeExtent;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
use rustc::mir::visit::MutVisitor;
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
use rustc::util::nodemap::NodeMap;
@ -84,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(body_id, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(body_id).enter(|infcx| {
let cx = Cx::new(&infcx, src);
let mut mir = if cx.tables().tainted_by_errors {
build::construct_error(cx, body_id)
@ -173,7 +172,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 {
let pe = tcx.param_env(tcx.hir.local_def_id(ctor_id));
tcx.infer_ctxt(pe, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(pe).enter(|infcx| {
let (mut mir, src) =
shim::build_adt_ctor(&infcx, ctor_id, fields, span);

View File

@ -18,7 +18,6 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc::mir::*;
use rustc::mir::transform::{MirPass, MirSource};
use rustc::mir::visit::*;
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::{Subst,Substs};
@ -545,9 +544,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
}
}
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>,
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>) -> Option<u64> {
tcx.infer_ctxt(param_env, traits::Reveal::All).enter(|infcx| {
tcx.infer_ctxt(param_env.reveal_all()).enter(|infcx| {
ty.layout(&infcx).ok().map(|layout| {
layout.size(&tcx.data_layout).bytes()
})

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((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
let mut fulfillment_cx = traits::FulfillmentContext::new();
fulfillment_cx.register_bound(&infcx, ty,

View File

@ -12,7 +12,7 @@
#![allow(unreachable_code)]
use rustc::infer::{self, InferCtxt, InferOk};
use rustc::traits::{self, Reveal};
use rustc::traits;
use rustc::ty::fold::TypeFoldable;
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
use rustc::middle::const_val::ConstVal;
@ -752,7 +752,7 @@ impl MirPass for TypeckMir {
return;
}
let param_env = tcx.param_env(def_id);
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(param_env).enter(|infcx| {
let mut checker = TypeChecker::new(&infcx, item_id);
{
let mut verifier = TypeVerifier::new(&mut checker, mir);

View File

@ -138,7 +138,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
self.check_const_eval(&body.value);
}
let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
let outer_penv = self.tcx.infer_ctxt(body_id).enter(|infcx| {
let param_env = infcx.param_env.clone();
let outer_penv = mem::replace(&mut self.param_env, param_env);
let region_maps = &self.tcx.region_maps(item_def_id);
@ -468,7 +468,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
in_fn: false,
promotable: false,
mut_rvalue_borrows: NodeSet(),
param_env: ty::ParamEnv::empty(),
param_env: ty::ParamEnv::empty(Reveal::UserFacing),
}.as_deep_visitor());
tcx.sess.abort_if_errors();
}

View File

@ -320,15 +320,15 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
}
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
ty.needs_drop(self.tcx, ty::ParamEnv::empty())
ty.needs_drop(self.tcx, ty::ParamEnv::empty(traits::Reveal::All))
}
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
ty.is_sized(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
}
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
ty.is_freeze(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
ty.is_freeze(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
}
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
@ -735,7 +735,7 @@ impl<'a, 'tcx> LayoutTyper<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
return TyLayout { ty: ty, layout: layout, variant_index: None };
}
self.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
self.tcx().infer_ctxt(traits::Reveal::All).enter(|infcx| {
infcx.layout_of(ty).unwrap_or_else(|e| {
match e {
ty::layout::LayoutError::SizeOverflow(_) =>

View File

@ -46,7 +46,7 @@ pub fn needs_drop_glue<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'tcx>
ty::TyAdt(def, _) if def.is_box() => {
let typ = t.boxed_ty();
if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) {
scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
scx.tcx().infer_ctxt(traits::Reveal::All).enter(|infcx| {
let layout = t.layout(&infcx).unwrap();
if layout.size(scx).bytes() == 0 {
// `Box<ZeroSizeType>` does not allocate.

View File

@ -212,13 +212,14 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// The key step here is to update the caller_bounds's predicates to be
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates));
let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates),
Reveal::UserFacing);
let param_env = traits::normalize_param_env_or_error(tcx,
impl_m.def_id,
param_env,
normalize_cause.clone());
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(param_env).enter(|infcx| {
let inh = Inherited::new(infcx, impl_m.def_id);
let infcx = &inh.infcx;
@ -713,7 +714,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((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(Reveal::UserFacing).enter(|infcx| {
let inh = Inherited::new(infcx, impl_c.def_id);
let infcx = &inh.infcx;

View File

@ -16,7 +16,7 @@ use rustc::infer::{self, InferOk};
use rustc::middle::region::{self, RegionMaps};
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::traits::{self, ObligationCause, Reveal};
use rustc::traits::{self, ObligationCause};
use util::common::ErrorReported;
use util::nodemap::FxHashSet;
@ -80,7 +80,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.
let impl_param_env = tcx.param_env(self_type_did);
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
tcx.infer_ctxt(impl_param_env).enter(|ref infcx| {
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

View File

@ -93,7 +93,7 @@ use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
use rustc::infer::type_variable::{TypeVariableOrigin};
use rustc::middle::region::CodeExtent;
use rustc::ty::subst::{Kind, Subst, Substs};
use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
use rustc::ty::{self, Ty, TyCtxt, Visibility};
use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
@ -530,7 +530,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
let tables = ty::TypeckTables::empty();
let param_env = tcx.param_env(def_id);
InheritedBuilder {
infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing),
infcx: tcx.infer_ctxt((tables, param_env)),
def_id,
}
}

View File

@ -15,7 +15,7 @@ use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::RegionMaps;
use rustc::middle::lang_items::UnsizeTraitLangItem;
use rustc::traits::{self, ObligationCause, Reveal};
use rustc::traits::{self, ObligationCause};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::TypeFoldable;
use rustc::ty::adjustment::CoerceUnsizedInfo;
@ -208,7 +208,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source,
target);
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(param_env).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((), Reveal::UserFacing).enter(|infcx| {
self.tcx.infer_ctxt(Reveal::UserFacing).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((), Reveal::UserFacing).enter(|ref infcx| {
tcx.infer_ctxt(Reveal::UserFacing).enter(|ref infcx| {
let mut fulfill_cx = FulfillmentContext::new();
match infcx.eq_types(false, &cause, expected, actual) {
Ok(InferOk { obligations, .. }) => {