Make ty::ParameterEnvironment, not ty::ctxt, implement Typer and

`UnboxedClosureTyper`. This requires adding a `tcx` field to
`ParameterEnvironment` but generally simplifies everything since we
only need to pass along an `UnboxedClosureTyper` or `Typer`.
This commit is contained in:
Niko Matsakis 2015-01-02 04:09:35 -05:00
parent 83ef3042de
commit 7474be0660
24 changed files with 288 additions and 259 deletions

View File

@ -99,7 +99,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
pub tcx: &'a ty::ctxt<'tcx>,
pub param_env: ParameterEnvironment<'tcx>,
pub param_env: ParameterEnvironment<'a, 'tcx>,
}
#[deriving(Clone, PartialEq)]
@ -148,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
pub fn check_crate(tcx: &ty::ctxt) {
visit::walk_crate(&mut MatchCheckCtxt {
tcx: tcx,
param_env: ty::empty_parameter_environment(),
param_env: ty::empty_parameter_environment(tcx),
}, tcx.map.krate());
tcx.sess.abort_if_errors();
}
@ -1061,8 +1061,7 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
cx: cx,
};
let mut visitor = ExprUseVisitor::new(&mut checker,
checker.cx.tcx,
&cx.param_env);
&checker.cx.param_env);
visitor.walk_expr(guard);
}

View File

@ -41,7 +41,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
{
let param_env = ParameterEnvironment::for_item(self.tcx, fn_id);
let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &param_env };
let mut euv = euv::ExprUseVisitor::new(&mut delegate, self.tcx, &param_env);
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &param_env);
euv.walk_fn(fd, b);
}
visit::walk_fn(self, fk, fd, b, s)
@ -50,7 +50,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
struct RvalueContextDelegate<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
param_env: &'a ty::ParameterEnvironment<'tcx>,
param_env: &'a ty::ParameterEnvironment<'a,'tcx>,
}
impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> {

View File

@ -54,7 +54,7 @@ struct CheckStaticVisitor<'a, 'tcx: 'a> {
}
struct GlobalVisitor<'a,'b,'tcx:'a+'b>(
euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>);
euv::ExprUseVisitor<'a,'b,'tcx,ty::ParameterEnvironment<'b,'tcx>>);
struct GlobalChecker {
static_consumptions: NodeSet,
const_borrows: NodeSet,
@ -70,8 +70,8 @@ pub fn check_crate(tcx: &ty::ctxt) {
static_local_borrows: NodeSet::new(),
};
{
let param_env = ty::empty_parameter_environment();
let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, &param_env);
let param_env = ty::empty_parameter_environment(tcx);
let visitor = euv::ExprUseVisitor::new(&mut checker, &param_env);
visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate());
}
visit::walk_crate(&mut CheckStaticVisitor {
@ -121,8 +121,8 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
let mut fulfill_cx = traits::FulfillmentContext::new();
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
let env = ty::empty_parameter_environment();
match fulfill_cx.select_all_or_error(&infcx, &env, self.tcx) {
let env = ty::empty_parameter_environment(self.tcx);
match fulfill_cx.select_all_or_error(&infcx, &env) {
Ok(()) => { },
Err(ref errors) => {
traits::report_fulfillment_errors(&infcx, errors);

View File

@ -23,7 +23,7 @@ use self::OverloadedCallType::*;
use middle::{def, region, pat_util};
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::ty::{mod, ParameterEnvironment, Ty};
use middle::ty::{mod};
use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
@ -299,7 +299,8 @@ pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> {
typer: &'t TYPER,
mc: mc::MemCategorizationContext<'t,TYPER>,
delegate: &'d mut (Delegate<'tcx>+'d),
param_env: &'t ParameterEnvironment<'tcx>,
}
// If the TYPER results in an error, it's because the type check
// failed (or will fail, when the error is uncovered and reported
// during writeback). In this case, we just ignore this part of the
@ -324,14 +325,12 @@ enum PassArgs {
impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
typer: &'t TYPER,
param_env: &'t ParameterEnvironment<'tcx>)
typer: &'t TYPER)
-> ExprUseVisitor<'d,'t,'tcx,TYPER> {
ExprUseVisitor {
typer: typer,
mc: mc::MemCategorizationContext::new(typer),
delegate: delegate,
param_env: param_env,
}
}

View File

@ -41,7 +41,7 @@ struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> {
// environments for each function we encounter. When we find a
// call to `transmute`, we can check it in the context of the top
// of the stack (which ought not to be empty).
param_envs: Vec<ty::ParameterEnvironment<'tcx>>,
param_envs: Vec<ty::ParameterEnvironment<'a,'tcx>>,
// Dummy sized/unsized types that use to substitute for type
// parameters in order to estimate how big a type will be for any

View File

@ -272,7 +272,6 @@ pub type McResult<T> = Result<T, ()>;
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool;
@ -1292,77 +1291,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.tcx().sess.span_bug(pat.span, "unexpanded macro");
}
}
}
pub fn cmt_to_string(&self, cmt: &cmt_<'tcx>) -> String {
fn upvar_to_string(upvar: &Upvar, is_copy: bool) -> String {
if upvar.is_unboxed {
let kind = match upvar.kind {
ty::FnUnboxedClosureKind => "Fn",
ty::FnMutUnboxedClosureKind => "FnMut",
ty::FnOnceUnboxedClosureKind => "FnOnce"
};
format!("captured outer variable in an `{}` closure", kind)
} else {
(match (upvar.kind, is_copy) {
(ty::FnOnceUnboxedClosureKind, true) => "captured outer variable in a proc",
_ => "captured outer variable"
}).to_string()
}
}
match cmt.cat {
cat_static_item => {
"static item".to_string()
}
cat_rvalue(..) => {
"non-lvalue".to_string()
}
cat_local(vid) => {
match self.tcx().map.find(vid) {
Some(ast_map::NodeArg(_)) => {
"argument".to_string()
}
_ => "local variable".to_string()
}
}
cat_deref(_, _, pk) => {
let upvar = cmt.upvar();
match upvar.as_ref().map(|i| &i.cat) {
Some(&cat_upvar(ref var)) => {
upvar_to_string(var, false)
}
Some(_) => unreachable!(),
None => {
match pk {
Implicit(..) => {
"dereference (dereference is implicit, due to indexing)".to_string()
}
Unique => format!("dereference of `{}`", ptr_sigil(pk)),
_ => format!("dereference of `{}`-pointer", ptr_sigil(pk))
}
}
}
}
cat_interior(_, InteriorField(NamedField(_))) => {
"field".to_string()
}
cat_interior(_, InteriorField(PositionalField(_))) => {
"anonymous field".to_string()
}
cat_interior(_, InteriorElement(VecElement)) => {
"vec content".to_string()
}
cat_interior(_, InteriorElement(OtherElement)) => {
"indexed content".to_string()
}
cat_upvar(ref var) => {
upvar_to_string(var, true)
}
cat_downcast(ref cmt, _) => {
self.cmt_to_string(&**cmt)
}
}
Ok(())
}
}
@ -1474,6 +1404,78 @@ impl<'tcx> cmt_<'tcx> {
NoteNone => None
}
}
pub fn descriptive_string(&self, tcx: &ty::ctxt) -> String {
fn upvar_to_string(upvar: &Upvar, is_copy: bool) -> String {
if upvar.is_unboxed {
let kind = match upvar.kind {
ty::FnUnboxedClosureKind => "Fn",
ty::FnMutUnboxedClosureKind => "FnMut",
ty::FnOnceUnboxedClosureKind => "FnOnce"
};
format!("captured outer variable in an `{}` closure", kind)
} else {
(match (upvar.kind, is_copy) {
(ty::FnOnceUnboxedClosureKind, true) => "captured outer variable in a proc",
_ => "captured outer variable"
}).to_string()
}
}
match self.cat {
cat_static_item => {
"static item".to_string()
}
cat_rvalue(..) => {
"non-lvalue".to_string()
}
cat_local(vid) => {
match tcx.map.find(vid) {
Some(ast_map::NodeArg(_)) => {
"argument".to_string()
}
_ => "local variable".to_string()
}
}
cat_deref(_, _, pk) => {
let upvar = self.upvar();
match upvar.as_ref().map(|i| &i.cat) {
Some(&cat_upvar(ref var)) => {
upvar_to_string(var, false)
}
Some(_) => unreachable!(),
None => {
match pk {
Implicit(..) => {
"dereference (dereference is implicit, due to indexing)".to_string()
}
Unique => format!("dereference of `{}`", ptr_sigil(pk)),
_ => format!("dereference of `{}`-pointer", ptr_sigil(pk))
}
}
}
}
cat_interior(_, InteriorField(NamedField(_))) => {
"field".to_string()
}
cat_interior(_, InteriorField(PositionalField(_))) => {
"anonymous field".to_string()
}
cat_interior(_, InteriorElement(VecElement)) => {
"vec content".to_string()
}
cat_interior(_, InteriorElement(OtherElement)) => {
"indexed content".to_string()
}
cat_upvar(ref var) => {
upvar_to_string(var, true)
}
cat_downcast(ref cmt, _) => {
cmt.descriptive_string(tcx)
}
}
}
}
impl<'tcx> Repr<'tcx> for cmt_<'tcx> {

View File

@ -42,8 +42,8 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
// Determine whether `impl2` can provide an implementation for those
// same types.
let param_env = ty::empty_parameter_environment();
let mut selcx = SelectionContext::intercrate(infcx, &param_env, infcx.tcx);
let param_env = ty::empty_parameter_environment(infcx.tcx);
let mut selcx = SelectionContext::intercrate(infcx, &param_env);
let obligation = Obligation::new(ObligationCause::dummy(),
ty::Binder(ty::TraitPredicate {
trait_ref: Rc::new(impl1_trait_ref),

View File

@ -109,7 +109,6 @@ impl<'tcx> FulfillmentContext<'tcx> {
/// `projection_ty` again.
pub fn normalize_projection_type<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>)
@ -122,7 +121,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
// FIXME(#20304) -- cache
let mut selcx = SelectionContext::new(infcx, param_env, typer);
let mut selcx = SelectionContext::new(infcx, typer);
let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0);
for obligation in normalized.obligations.into_iter() {
@ -186,11 +185,10 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_all_or_error<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
try!(self.select_where_possible(infcx, param_env, typer));
try!(self.select_where_possible(infcx, typer));
// Anything left is ambiguous.
let errors: Vec<FulfillmentError> =
@ -212,21 +210,19 @@ impl<'tcx> FulfillmentContext<'tcx> {
/// results in `O(n^2)` performance (#18208).
pub fn select_new_obligations<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);
let mut selcx = SelectionContext::new(infcx, typer);
self.select(&mut selcx, true)
}
pub fn select_where_possible<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);
let mut selcx = SelectionContext::new(infcx, typer);
self.select(&mut selcx, false)
}

View File

@ -46,7 +46,6 @@ use util::ppaux::Repr;
pub struct SelectionContext<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
/// Freshener used specifically for skolemizing entries on the
@ -181,12 +180,10 @@ enum EvaluationResult<'tcx> {
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: false,
@ -194,12 +191,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: true,
@ -210,14 +205,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx
}
pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'tcx> {
self.param_env
}
pub fn tcx(&self) -> &'cx ty::ctxt<'tcx> {
self.infcx.tcx
}
pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'cx, 'tcx> {
self.closure_typer.param_env()
}
///////////////////////////////////////////////////////////////////////////
// Selection
//
@ -650,7 +645,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// it's not worth going to more trouble to increase the
// hit-rate I don't think.
if self.intercrate {
return &self.param_env.selection_cache;
return &self.param_env().selection_cache;
}
// If the trait refers to any parameters in scope, then use
@ -659,7 +654,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cache_fresh_trait_pred.0.input_types().iter().any(
|&t| ty::type_has_self(t) || ty::type_has_params(t))
{
return &self.param_env.selection_cache;
return &self.param_env().selection_cache;
}
// If the trait refers to unbound type variables, and there
@ -668,11 +663,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// common case, then we can use the global environment.
// See the discussion in doc.rs for more details.
if
!self.param_env.caller_bounds.is_empty() &&
!self.param_env().caller_bounds.is_empty() &&
cache_fresh_trait_pred.0.input_types().iter().any(
|&t| ty::type_has_ty_infer(t))
{
return &self.param_env.selection_cache;
return &self.param_env().selection_cache;
}
// Otherwise, we can use the global cache.
@ -902,7 +897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.repr(self.tcx()));
let caller_trait_refs: Vec<_> =
self.param_env.caller_bounds.predicates.iter()
self.param_env().caller_bounds.predicates.iter()
.filter_map(|o| o.to_opt_poly_trait_ref())
.collect();

View File

@ -2058,7 +2058,9 @@ impl<'tcx> TraitRef<'tcx> {
/// future I hope to refine the representation of types so as to make
/// more distinctions clearer.
#[deriving(Clone)]
pub struct ParameterEnvironment<'tcx> {
pub struct ParameterEnvironment<'a, 'tcx:'a> {
pub tcx: &'a ctxt<'tcx>,
/// A substitution that can be applied to move from
/// the "outer" view of a type or method to the "inner" view.
/// In general, this means converting from bound parameters to
@ -2082,8 +2084,8 @@ pub struct ParameterEnvironment<'tcx> {
pub selection_cache: traits::SelectionCache<'tcx>,
}
impl<'tcx> ParameterEnvironment<'tcx> {
pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'tcx> {
impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
match cx.map.find(id) {
Some(ast_map::NodeImplItem(ref impl_item)) => {
match **impl_item {
@ -2272,6 +2274,8 @@ impl UnboxedClosureKind {
}
pub trait UnboxedClosureTyper<'tcx> {
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind;
@ -2424,6 +2428,21 @@ impl<'tcx> ctxt<'tcx> {
self.region_interner.borrow_mut().insert(region, region);
region
}
pub fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.unboxed_closures.borrow()[def_id].kind
}
pub fn unboxed_closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
}
}
// Interns a type/name combination, stores the resulting box in cx.interner,
@ -3377,7 +3396,8 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
ty_unboxed_closure(did, r, substs) => {
// FIXME(#14449): `borrowed_contents` below assumes `&mut`
// unboxed closure.
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
let param_env = ty::empty_parameter_environment(cx);
let upvars = unboxed_closure_upvars(&param_env, did, substs).unwrap();
TypeContents::union(upvars.as_slice(),
|f| tc_ty(cx, f.ty, cache))
| borrowed_contents(*r, MutMutable)
@ -3526,12 +3546,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
}
}
fn type_impls_bound<'tcx>(cx: &ctxt<'tcx>,
cache: &RefCell<HashMap<Ty<'tcx>,bool>>,
param_env: &ParameterEnvironment<'tcx>,
ty: Ty<'tcx>,
bound: ty::BuiltinBound)
-> bool
fn type_impls_bound<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
cache: &RefCell<HashMap<Ty<'tcx>,bool>>,
ty: Ty<'tcx>,
bound: ty::BuiltinBound,
span: Span)
-> bool
{
assert!(!ty::type_needs_infer(ty));
@ -3540,7 +3560,7 @@ fn type_impls_bound<'tcx>(cx: &ctxt<'tcx>,
None => {}
Some(&result) => {
debug!("type_impls_bound({}, {}) = {} (cached)",
ty_to_string(cx, ty),
ty.repr(param_env.tcx),
bound,
result);
return result
@ -3625,8 +3645,6 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
ty_str |
ty_bare_fn(..) |
ty_closure(_) |
ty_infer(_) |
ty_err |
ty_param(_) |
ty_projection(_) |
ty_vec(_, None) => {
@ -3659,9 +3677,12 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
r
}
ty_unboxed_closure(did, _, substs) => {
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty))
ty_err |
ty_infer(_) |
ty_unboxed_closure(..) => {
// this check is run on type definitions, so we don't expect to see
// inference by-products or unboxed closure types
cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[])
}
ty_tup(ref ts) => {
@ -3751,9 +3772,10 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
find_nonrepresentable(cx, sp, seen, iter)
}
ty_unboxed_closure(did, _, substs) => {
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
find_nonrepresentable(cx, sp, seen, upvars.iter().map(|f| f.ty))
ty_unboxed_closure(..) => {
// this check is run on type definitions, so we don't expect to see
// unboxed closure types
cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[])
}
_ => Representable,
}
@ -6377,19 +6399,20 @@ impl Variance {
/// Construct a parameter environment suitable for static contexts or other contexts where there
/// are no free type/lifetime parameters in scope.
pub fn empty_parameter_environment<'tcx>() -> ParameterEnvironment<'tcx> {
ty::ParameterEnvironment { free_substs: Substs::empty(),
pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
ty::ParameterEnvironment { tcx: cx,
free_substs: Substs::empty(),
caller_bounds: GenericBounds::empty(),
implicit_region_bound: ty::ReEmpty,
selection_cache: traits::SelectionCache::new(), }
}
/// See `ParameterEnvironment` struct def'n for details
pub fn construct_parameter_environment<'tcx>(
tcx: &ctxt<'tcx>,
pub fn construct_parameter_environment<'a,'tcx>(
tcx: &'a ctxt<'tcx>,
generics: &ty::Generics<'tcx>,
free_id: ast::NodeId)
-> ParameterEnvironment<'tcx>
-> ParameterEnvironment<'a, 'tcx>
{
//
@ -6432,6 +6455,7 @@ pub fn construct_parameter_environment<'tcx>(
bounds.repr(tcx));
return ty::ParameterEnvironment {
tcx: tcx,
free_substs: free_substs,
implicit_region_bound: ty::ReScope(free_id_scope),
caller_bounds: bounds,
@ -6522,48 +6546,59 @@ impl BorrowKind {
}
}
impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
self
impl<'tcx> ctxt<'tcx> {
pub fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause {
self.capture_modes.borrow()[closure_expr_id].clone()
}
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
ty::node_id_to_type(self, id)
pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
}
}
impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> {
self.tcx
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
ty::expr_ty_adjusted(self, expr)
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
Ok(ty::node_id_to_type(self.tcx, id))
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
Ok(ty::expr_ty_adjusted(self.tcx, expr))
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.method_map.borrow().get(&method_call).map(|method| method.ty)
self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
}
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
&self.adjustments
fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
&self.tcx.adjustments
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
self.method_map.borrow().contains_key(&MethodCall::expr(id))
self.tcx.is_method_call(id)
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
self.region_maps.temporary_scope(rvalue_id)
self.tcx.region_maps.temporary_scope(rvalue_id)
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
Some(self.upvar_borrow_map.borrow()[upvar_id].clone())
Some(self.tcx.upvar_borrow_map.borrow()[upvar_id].clone())
}
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause {
self.capture_modes.borrow()[closure_expr_id].clone()
self.tcx.capture_mode(closure_expr_id)
}
fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
@ -6571,12 +6606,16 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
}
}
impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> {
impl<'a,'tcx> UnboxedClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
self
}
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.unboxed_closures.borrow()[def_id].kind
self.tcx.unboxed_closure_kind(def_id)
}
fn unboxed_closure_type(&self,
@ -6584,7 +6623,7 @@ impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> {
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
self.tcx.unboxed_closure_type(def_id, substs)
}
fn unboxed_closure_upvars(&self,

View File

@ -87,7 +87,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
dfcx_loans: &'a LoanDataFlow<'a, 'tcx>,
move_data: move_data::FlowedMoveData<'a, 'tcx>,
all_loans: &'a [Loan<'tcx>],
param_env: &'a ty::ParameterEnvironment<'tcx>,
param_env: &'a ty::ParameterEnvironment<'a, 'tcx>,
}
impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
@ -208,9 +208,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
};
{
let mut euv = euv::ExprUseVisitor::new(&mut clcx,
bccx.tcx,
&param_env);
let mut euv = euv::ExprUseVisitor::new(&mut clcx, &param_env);
euv.walk_fn(decl, body);
}
}

View File

@ -51,9 +51,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);
{
let mut euv = euv::ExprUseVisitor::new(&mut glcx,
bccx.tcx,
&param_env);
let mut euv = euv::ExprUseVisitor::new(&mut glcx, &param_env);
euv.walk_fn(decl, body);
}
@ -485,13 +483,15 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
/// This visitor walks static initializer's expressions and makes
/// sure the loans being taken are sound.
struct StaticInitializerCtxt<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>
bccx: &'a BorrowckCtxt<'a, 'tcx>,
}
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
if let ast::ExprAddrOf(mutbl, ref base) = ex.node {
let base_cmt = self.bccx.cat_expr(&**base);
let param_env = ty::empty_parameter_environment(self.bccx.tcx);
let mc = mc::MemCategorizationContext::new(&param_env);
let base_cmt = mc.cat_expr(&**base).unwrap();
let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
// Check that we don't allow borrows of unsafe static items.
if check_aliasability(self.bccx, ex.span, euv::AddrOf,

View File

@ -511,14 +511,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.tcx.region_maps.is_subregion_of(r_sub, r_sup)
}
pub fn mc(&self) -> mc::MemCategorizationContext<'a, ty::ctxt<'tcx>> {
mc::MemCategorizationContext::new(self.tcx)
}
pub fn cat_expr(&self, expr: &ast::Expr) -> mc::cmt<'tcx> {
self.mc().cat_expr(expr)
}
pub fn report(&self, err: BckError<'tcx>) {
self.span_err(
err.span,
@ -526,13 +518,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.note_and_explain_bckerr(err);
}
pub fn report_use_of_moved_value(&self,
use_span: Span,
use_kind: MovedValueUseKind,
lp: &LoanPath<'tcx>,
the_move: &move_data::Move,
moved_lp: &LoanPath<'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>) {
pub fn report_use_of_moved_value<'b>(&self,
use_span: Span,
use_kind: MovedValueUseKind,
lp: &LoanPath<'tcx>,
the_move: &move_data::Move,
moved_lp: &LoanPath<'tcx>,
param_env: &ty::ParameterEnvironment<'b,'tcx>) {
let verb = match use_kind {
MovedInUse => "use",
MovedInCapture => "capture",
@ -608,8 +600,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
r)[])
}
};
let (suggestion, _) = move_suggestion(self.tcx, param_env, expr_ty,
("moved by default", ""));
let (suggestion, _) =
move_suggestion(param_env, expr_span, expr_ty, ("moved by default", ""));
self.tcx.sess.span_note(
expr_span,
format!("`{}` moved here{} because it has type `{}`, which is {}",
@ -646,11 +638,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
r)[])
}
};
let (suggestion, help) = move_suggestion(self.tcx,
param_env,
expr_ty,
("moved by default", "make a copy and \
capture that instead to override"));
let (suggestion, help) =
move_suggestion(param_env,
expr_span,
expr_ty,
("moved by default",
"make a copy and capture that instead to override"));
self.tcx.sess.span_note(
expr_span,
format!("`{}` moved into closure environment here{} because it \
@ -663,22 +656,27 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
}
fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
ty: Ty<'tcx>,
default_msgs: (&'static str, &'static str))
-> (&'static str, &'static str) {
fn move_suggestion<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>,
span: Span,
ty: Ty<'tcx>,
default_msgs: (&'static str, &'static str))
-> (&'static str, &'static str) {
match ty.sty {
ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(..),
..
}) =>
store: ty::RegionTraitStore(..),
..
}) => {
("a non-copyable stack closure",
"capture it in a new closure, e.g. `|x| f(x)`, to override"),
_ if ty::type_moves_by_default(tcx, ty, param_env) =>
("non-copyable",
"perhaps you meant to use `clone()`?"),
_ => default_msgs,
"capture it in a new closure, e.g. `|x| f(x)`, to override")
}
_ => {
if ty::type_moves_by_default(param_env, span, ty) {
("non-copyable",
"perhaps you meant to use `clone()`?")
} else {
default_msgs
}
}
}
}
}
@ -991,7 +989,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
pub fn cmt_to_string(&self, cmt: &mc::cmt_<'tcx>) -> String {
self.mc().cmt_to_string(cmt)
cmt.descriptive_string(self.tcx)
}
}

View File

@ -542,7 +542,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
check_match::Constructor::Variant(def_id)
};
let param_env = ty::empty_parameter_environment();
let param_env = ty::empty_parameter_environment(bcx.tcx());
let mcx = check_match::MatchCheckCtxt {
tcx: bcx.tcx(),
param_env: param_env,
@ -1008,7 +1008,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let mcx = check_match::MatchCheckCtxt {
tcx: bcx.tcx(),
param_env: ty::empty_parameter_environment(),
param_env: ty::empty_parameter_environment(bcx.tcx()),
};
let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
let repr = adt::represent_type(bcx.ccx(), left_ty);
@ -1262,8 +1262,7 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool
reassigned: false
};
{
let param_env = ty::empty_parameter_environment();
let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx, &param_env);
let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
visitor.walk_expr(body);
}
rc.reassigned
@ -1321,7 +1320,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
let variable_ty = node_id_type(bcx, p_id);
let llvariable_ty = type_of::type_of(ccx, variable_ty);
let tcx = bcx.tcx();
let param_env = ty::empty_parameter_environment();
let param_env = ty::empty_parameter_environment(tcx);
let llmatch;
let trmode;

View File

@ -61,7 +61,7 @@ use trans::datum;
use trans::machine;
use trans::type_::Type;
use trans::type_of;
use middle::ty::{mod, Ty};
use middle::ty::{mod, Ty, UnboxedClosureTyper};
use middle::ty::Disr;
use syntax::ast;
use syntax::attr;
@ -168,7 +168,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Univariant(mk_struct(cx, ftys[], packed, t), dtor)
}
ty::ty_unboxed_closure(def_id, _, substs) => {
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap();
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
Univariant(mk_struct(cx, upvar_types[], false, t), false)
}

View File

@ -731,7 +731,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
}
ty::ty_unboxed_closure(def_id, _, substs) => {
let repr = adt::represent_type(cx.ccx(), t);
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap();
let typer = common::NormalizingUnboxedClosureTyper::new(cx.tcx());
let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
for (i, upvar) in upvars.iter().enumerate() {
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
cx = f(cx, llupvar, upvar.ty);
@ -1451,6 +1452,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
llfn: llfndecl,
llenv: None,
llretslotptr: Cell::new(None),
param_env: ty::empty_parameter_environment(ccx.tcx()),
alloca_insert_pt: Cell::new(None),
llreturn: Cell::new(None),
needs_ret_allocas: nested_returns,

View File

@ -302,6 +302,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
// section of the executable we're generating.
pub llfn: ValueRef,
// always an empty parameter-environment
pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
// The environment argument in a closure.
pub llenv: Option<ValueRef>,
@ -579,12 +582,12 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
self.tcx()
}
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
node_id_type(self, id)
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
Ok(node_id_type(self, id))
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
expr_ty_adjusted(self, expr)
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
Ok(expr_ty_adjusted(self, expr))
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
@ -627,11 +630,15 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
}
fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
self.param_env().type_moves_by_default(span, ty)
self.fcx.param_env.type_moves_by_default(span, ty)
}
}
impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> {
&self.fcx.param_env
}
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
@ -945,14 +952,10 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
// Parameter environment is used to give details about type parameters,
// but since we are in trans, everything is fully monomorphized.
let param_env = ty::empty_parameter_environment();
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &param_env, &typer);
let typer = NormalizingUnboxedClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());
let selection = match selcx.select(&obligation) {
@ -987,7 +990,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let vtable = selection.map_move_nested(|predicate| {
fulfill_cx.register_predicate_obligation(&infcx, predicate);
});
let vtable = drain_fulfillment_cx(span, &infcx, &param_env, &mut fulfill_cx, &vtable);
let vtable = drain_fulfillment_cx(span, &infcx, &mut fulfill_cx, &vtable);
info!("Cache miss: {}", trait_ref.repr(ccx.tcx()));
ccx.trait_cache().borrow_mut().insert(trait_ref,
@ -997,21 +1000,27 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
pub struct NormalizingUnboxedClosureTyper<'a,'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>
param_env: ty::ParameterEnvironment<'a, 'tcx>
}
impl<'a,'tcx> NormalizingUnboxedClosureTyper<'a,'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingUnboxedClosureTyper<'a,'tcx> {
NormalizingUnboxedClosureTyper { tcx: tcx }
// Parameter environment is used to give details about type parameters,
// but since we are in trans, everything is fully monomorphized.
NormalizingUnboxedClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
}
}
impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'a,'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
&self.param_env
}
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.tcx.unboxed_closure_kind(def_id)
self.param_env.tcx.unboxed_closure_kind(def_id)
}
fn unboxed_closure_type(&self,
@ -1021,8 +1030,8 @@ impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'
{
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
let closure_ty = self.tcx.unboxed_closure_type(def_id, substs);
monomorphize::normalize_associated_type(self.tcx, &closure_ty)
let closure_ty = self.param_env.tcx.unboxed_closure_type(def_id, substs);
monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty)
}
fn unboxed_closure_upvars(&self,
@ -1032,14 +1041,13 @@ impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'
{
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
let result = ty::unboxed_closure_upvars(self.tcx, def_id, substs);
monomorphize::normalize_associated_type(self.tcx, &result)
let result = ty::unboxed_closure_upvars(&self.param_env, def_id, substs);
monomorphize::normalize_associated_type(self.param_env.tcx, &result)
}
}
pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
infcx: &infer::InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
result: &T)
-> T
@ -1052,7 +1060,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
// contains unbound type parameters. It could be a slight
// optimization to stop iterating early.
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
match fulfill_cx.select_all_or_error(infcx, param_env, &typer) {
match fulfill_cx.select_all_or_error(infcx, &typer) {
Ok(()) => { }
Err(errors) => {
if errors.iter().all(|e| e.is_overflow()) {

View File

@ -28,6 +28,7 @@ use util::ppaux::{ty_to_string};
use std::fmt;
use syntax::ast;
use syntax::codemap::DUMMY_SP;
/// A `Datum` encapsulates the result of evaluating an expression. It
/// describes where the value is stored, what Rust type the value has,

View File

@ -322,9 +322,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
// FIXME(#20304) -- cache
let infcx = infer::new_infer_ctxt(tcx);
let param_env = ty::empty_parameter_environment();
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &param_env, &typer);
let typer = NormalizingUnboxedClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let cause = traits::ObligationCause::dummy();
let traits::Normalized { value: result, obligations } =
traits::normalize(&mut selcx, cause, value);
@ -337,7 +336,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
for obligation in obligations.into_iter() {
fulfill_cx.register_predicate_obligation(&infcx, obligation);
}
let result = drain_fulfillment_cx(DUMMY_SP, &infcx, &param_env, &mut fulfill_cx, &result);
let result = drain_fulfillment_cx(DUMMY_SP, &infcx, &mut fulfill_cx, &result);
result
}

View File

@ -18,7 +18,6 @@ use syntax::codemap::Span;
use util::ppaux::Repr;
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &(ty::UnboxedClosureTyper<'tcx>+'a),
fulfillment_cx: &mut FulfillmentContext<'tcx>,
span: Span,
@ -28,7 +27,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
{
debug!("normalize_associated_types_in(value={})", value.repr(infcx.tcx));
let mut selcx = SelectionContext::new(infcx, param_env, typer);
let mut selcx = SelectionContext::new(infcx, typer);
let cause = ObligationCause::new(span, body_id, MiscObligation);
let Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value);
debug!("normalize_associated_types_in: result={} predicates={}",

View File

@ -169,9 +169,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
poly_trait_ref.as_predicate());
// Now we want to know if this can be matched
let mut selcx = traits::SelectionContext::new(fcx.infcx(),
&fcx.inh.param_env,
fcx);
let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx);
if !selcx.evaluate_obligation(&obligation) {
debug!("--> Cannot match obligation");
return None; // Cannot be matched, no such method resolution is possible.

View File

@ -788,9 +788,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
debug!("impl_obligations={}", obligations.repr(self.tcx()));
// Evaluate those obligations to see if they might possibly hold.
let mut selcx = traits::SelectionContext::new(self.infcx(),
&self.fcx.inh.param_env,
self.fcx);
let mut selcx = traits::SelectionContext::new(self.infcx(), self.fcx);
obligations.all(|o| selcx.evaluate_obligation(o))
}

View File

@ -87,6 +87,7 @@ use middle::{const_eval, def};
use middle::infer;
use middle::lang_items::IteratorItem;
use middle::mem_categorization as mc;
use middle::mem_categorization::McResult;
use middle::pat_util::{mod, pat_id_map};
use middle::region::CodeExtent;
use middle::subst::{mod, Subst, Substs, VecPerParamSpace, ParamSpace};
@ -146,7 +147,7 @@ mod callee;
pub struct Inherited<'a, 'tcx: 'a> {
infcx: infer::InferCtxt<'a, 'tcx>,
locals: RefCell<NodeMap<Ty<'tcx>>>,
param_env: ty::ParameterEnvironment<'tcx>,
param_env: ty::ParameterEnvironment<'a, 'tcx>,
// Temporary tables:
node_types: RefCell<NodeMap<Ty<'tcx>>>,
@ -288,7 +289,6 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> {
self.ccx.tcx
}
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
let ty = self.node_ty(id);
self.resolve_type_vars_or_error(&ty)
@ -322,7 +322,7 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id))
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
self.tcx().temporary_scope(rvalue_id)
self.param_env().temporary_scope(rvalue_id)
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
self.inh.upvar_borrow_map.borrow().get(&upvar_id).cloned()
@ -334,6 +334,10 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
}
impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
&self.inh.param_env
}
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
@ -360,7 +364,7 @@ impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
impl<'a, 'tcx> Inherited<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>,
param_env: ty::ParameterEnvironment<'tcx>)
param_env: ty::ParameterEnvironment<'a, 'tcx>)
-> Inherited<'a, 'tcx> {
Inherited {
infcx: infer::new_infer_ctxt(tcx),
@ -388,7 +392,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
{
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
assoc::normalize_associated_types_in(&self.infcx,
&self.param_env,
typer,
&mut *fulfillment_cx, span,
body_id,
@ -418,7 +421,7 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
-> Inherited<'a, 'tcx> {
// It's kind of a kludge to manufacture a fake function context
// and statement context, but we might as well do write the code only once
let param_env = ty::empty_parameter_environment();
let param_env = ty::empty_parameter_environment(ccx.tcx);
Inherited::new(ccx.tcx, param_env)
}
@ -462,7 +465,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
body: &ast::Block,
id: ast::NodeId,
raw_fty: Ty<'tcx>,
param_env: ty::ParameterEnvironment<'tcx>) {
param_env: ty::ParameterEnvironment<'a, 'tcx>) {
match raw_fty.sty {
ty::ty_bare_fn(_, ref fn_ty) => {
let inh = Inherited::new(ccx.tcx, param_env);
@ -473,7 +476,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let fn_sig =
liberate_late_bound_regions(ccx.tcx, CodeExtent::from_node_id(body.id), &fn_sig);
let fn_sig =
inh.normalize_associated_types_in(ccx.tcx, body.span, body.id, &fn_sig);
inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig);
let fcx = check_fn(ccx, fn_ty.unsafety, id, &fn_sig,
decl, id, body, &inh);
@ -1225,7 +1228,6 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
let impl_sig =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
infcx.tcx,
&mut fulfillment_cx,
impl_m_span,
impl_m_body_id,
@ -1246,7 +1248,6 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
let trait_sig =
assoc::normalize_associated_types_in(&infcx,
&impl_param_env,
infcx.tcx,
&mut fulfillment_cx,
impl_m_span,
impl_m_body_id,
@ -1282,7 +1283,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
// Run the fulfillment context to completion to accommodate any
// associated type normalizations that may have occurred.
match fulfillment_cx.select_all_or_error(&infcx, &impl_param_env, tcx) {
match fulfillment_cx.select_all_or_error(&infcx, &impl_param_env) {
Ok(()) => { }
Err(errors) => {
traits::report_fulfillment_errors(&infcx, &errors);
@ -1660,11 +1661,11 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
pub fn infcx(&self) -> &infer::InferCtxt<'a, 'tcx> {
pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
&self.inh.infcx
}
pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> {
pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
&self.inh.param_env
}
@ -1835,7 +1836,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.inh.fulfillment_cx
.borrow_mut()
.normalize_projection_type(self.infcx(),
&self.inh.param_env,
self,
ty::ProjectionTy {
trait_ref: trait_ref,

View File

@ -287,9 +287,7 @@ pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
fcx.default_type_parameters();
let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
let r = fulfillment_cx.select_all_or_error(fcx.infcx(),
&fcx.inh.param_env,
fcx);
let r = fulfillment_cx.select_all_or_error(fcx.infcx(), fcx);
match r {
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
@ -302,7 +300,7 @@ pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt)
match
fcx.inh.fulfillment_cx
.borrow_mut()
.select_where_possible(fcx.infcx(), &fcx.inh.param_env, fcx)
.select_where_possible(fcx.infcx(), fcx)
{
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
@ -316,7 +314,7 @@ pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
match
fcx.inh.fulfillment_cx
.borrow_mut()
.select_new_obligations(fcx.infcx(), &fcx.inh.param_env, fcx)
.select_new_obligations(fcx.infcx(), fcx)
{
Ok(()) => { }
Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }