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:
parent
83ef3042de
commit
7474be0660
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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: ¶m_env };
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, self.tcx, ¶m_env);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, ¶m_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> {
|
||||
|
@ -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, ¶m_env);
|
||||
let param_env = ty::empty_parameter_environment(tcx);
|
||||
let visitor = euv::ExprUseVisitor::new(&mut checker, ¶m_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);
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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, ¶m_env, infcx.tcx);
|
||||
let param_env = ty::empty_parameter_environment(infcx.tcx);
|
||||
let mut selcx = SelectionContext::intercrate(infcx, ¶m_env);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(),
|
||||
ty::Binder(ty::TraitPredicate {
|
||||
trait_ref: Rc::new(impl1_trait_ref),
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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(¶m_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,
|
||||
|
@ -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,
|
||||
¶m_env);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut clcx, ¶m_env);
|
||||
euv.walk_fn(decl, body);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
¶m_env);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut glcx, ¶m_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(¶m_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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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, ¶m_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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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, ¶m_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, ¶m_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()) {
|
||||
|
@ -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,
|
||||
|
@ -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, ¶m_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, ¶m_env, &mut fulfill_cx, &result);
|
||||
let result = drain_fulfillment_cx(DUMMY_SP, &infcx, &mut fulfill_cx, &result);
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -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={}",
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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); }
|
||||
|
Loading…
Reference in New Issue
Block a user