rustc: move liberate_late_bound_regions to rustc_typeck.
This commit is contained in:
parent
6d4c2141b5
commit
74c6788d9c
@ -96,9 +96,6 @@
|
||||
//!
|
||||
//! - `fallthrough_ln`: a live node that represents a fallthrough
|
||||
//!
|
||||
//! - `no_ret_var`: a synthetic variable that is only 'read' from, the
|
||||
//! fallthrough node. This allows us to detect functions where we fail
|
||||
//! to return explicitly.
|
||||
//! - `clean_exit_var`: a synthetic variable that is only 'read' from the
|
||||
//! fallthrough node. It is only live if the function could converge
|
||||
//! via means other than an explicit `return` expression. That is, it is
|
||||
@ -111,8 +108,6 @@ use self::VarKind::*;
|
||||
|
||||
use hir::def::*;
|
||||
use ty::{self, TyCtxt};
|
||||
use traits::{self, Reveal};
|
||||
use ty::subst::Subst;
|
||||
use lint;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
@ -256,7 +251,6 @@ struct LocalInfo {
|
||||
enum VarKind {
|
||||
Arg(NodeId, ast::Name),
|
||||
Local(LocalInfo),
|
||||
ImplicitRet,
|
||||
CleanExit
|
||||
}
|
||||
|
||||
@ -313,7 +307,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
||||
Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) => {
|
||||
self.variable_map.insert(node_id, v);
|
||||
},
|
||||
ImplicitRet | CleanExit => {}
|
||||
CleanExit => {}
|
||||
}
|
||||
|
||||
debug!("{:?} is {:?}", v, vk);
|
||||
@ -335,7 +329,6 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
||||
Local(LocalInfo { name, .. }) | Arg(_, name) => {
|
||||
name.to_string()
|
||||
},
|
||||
ImplicitRet => "<implicit-ret>".to_string(),
|
||||
CleanExit => "<clean-exit>".to_string()
|
||||
}
|
||||
}
|
||||
@ -382,7 +375,6 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
|
||||
// check for various error conditions
|
||||
lsets.visit_body(body);
|
||||
lsets.check_ret(id, sp, entry_ln);
|
||||
lsets.warn_about_unused_args(body, entry_ln);
|
||||
}
|
||||
|
||||
@ -500,7 +492,6 @@ fn invalid_users() -> Users {
|
||||
struct Specials {
|
||||
exit_ln: LiveNode,
|
||||
fallthrough_ln: LiveNode,
|
||||
no_ret_var: Variable,
|
||||
clean_exit_var: Variable
|
||||
}
|
||||
|
||||
@ -534,7 +525,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
let specials = Specials {
|
||||
exit_ln: ir.add_live_node(ExitNode),
|
||||
fallthrough_ln: ir.add_live_node(ExitNode),
|
||||
no_ret_var: ir.add_variable(ImplicitRet),
|
||||
clean_exit_var: ir.add_variable(CleanExit)
|
||||
};
|
||||
|
||||
@ -1420,43 +1410,6 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
fn check_ret(&self,
|
||||
id: NodeId,
|
||||
sp: Span,
|
||||
entry_ln: LiveNode)
|
||||
{
|
||||
let def_id = self.ir.tcx.hir.local_def_id(id);
|
||||
let fn_ty = self.ir.tcx.type_of(def_id);
|
||||
let fn_sig = match fn_ty.sty {
|
||||
ty::TyClosure(closure_def_id, substs) => {
|
||||
self.ir.tcx.closure_type(closure_def_id)
|
||||
.subst(self.ir.tcx, substs.substs)
|
||||
}
|
||||
_ => fn_ty.fn_sig()
|
||||
};
|
||||
|
||||
let fn_ret = fn_sig.output();
|
||||
|
||||
// within the fn body, late-bound regions are liberated
|
||||
// and must outlive the *call-site* of the function.
|
||||
let fn_ret =
|
||||
self.ir.tcx.liberate_late_bound_regions(def_id, &fn_ret);
|
||||
|
||||
if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
|
||||
let param_env = self.ir.tcx.parameter_environment(def_id);
|
||||
let t_ret_subst = fn_ret.subst(self.ir.tcx, ¶m_env.free_substs);
|
||||
let is_nil = self.ir.tcx.infer_ctxt(param_env, Reveal::All).enter(|infcx| {
|
||||
let cause = traits::ObligationCause::dummy();
|
||||
traits::fully_normalize(&infcx, cause, &t_ret_subst).unwrap().is_nil()
|
||||
});
|
||||
|
||||
// for nil return types, it is ok to not return a value expl.
|
||||
if !is_nil {
|
||||
span_bug!(sp, "not all control paths return a value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lvalue(&mut self, expr: &'tcx Expr) {
|
||||
match expr.node {
|
||||
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
|
||||
|
@ -39,7 +39,6 @@
|
||||
//! These methods return true to indicate that the visitor has found what it is looking for
|
||||
//! and does not need to visit anything else.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::adjustment;
|
||||
use ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
@ -326,23 +325,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
(result, replacer.map)
|
||||
}
|
||||
|
||||
|
||||
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
|
||||
/// `scope_id`.
|
||||
pub fn liberate_late_bound_regions<T>(self,
|
||||
all_outlive_scope: DefId,
|
||||
value: &Binder<T>)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
self.replace_late_bound_regions(value, |br| {
|
||||
self.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: all_outlive_scope,
|
||||
bound_region: br
|
||||
}))
|
||||
}).0
|
||||
}
|
||||
|
||||
/// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
|
||||
/// becomes `for<'a,'b> Foo`.
|
||||
pub fn flatten_late_bound_regions<T>(self, bound2_value: &Binder<Binder<T>>)
|
||||
|
@ -2417,7 +2417,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
let tcx = self.global_tcx();
|
||||
let generic_predicates = tcx.predicates_of(def_id);
|
||||
let bounds = generic_predicates.instantiate(tcx, free_substs);
|
||||
let bounds = tcx.liberate_late_bound_regions(def_id, &ty::Binder(bounds));
|
||||
let predicates = bounds.predicates;
|
||||
|
||||
// Finally, we have to normalize the bounds in the environment, in
|
||||
|
@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
||||
|
||||
let fn_sig = self.tcx.liberate_late_bound_regions(expr_def_id, &sig);
|
||||
let fn_sig = self.liberate_late_bound_regions(expr_def_id, &sig);
|
||||
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
|
||||
body.value.id, &fn_sig);
|
||||
|
||||
|
@ -282,7 +282,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
|
||||
|
||||
let trait_sig = tcx.liberate_late_bound_regions(
|
||||
let trait_sig = inh.liberate_late_bound_regions(
|
||||
impl_m.def_id,
|
||||
&m_sig(trait_m));
|
||||
let trait_sig =
|
||||
|
@ -628,6 +628,22 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
obligations);
|
||||
InferOk { value, obligations }
|
||||
}
|
||||
|
||||
/// Replace any late-bound regions bound in `value` with
|
||||
/// free variants attached to `all_outlive_scope`.
|
||||
fn liberate_late_bound_regions<T>(&self,
|
||||
all_outlive_scope: DefId,
|
||||
value: &ty::Binder<T>)
|
||||
-> T
|
||||
where T: TypeFoldable<'tcx>
|
||||
{
|
||||
self.tcx.replace_late_bound_regions(value, |br| {
|
||||
self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: all_outlive_scope,
|
||||
bound_region: br
|
||||
}))
|
||||
}).0
|
||||
}
|
||||
}
|
||||
|
||||
struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
|
||||
@ -804,7 +820,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let fn_sig =
|
||||
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||
let fn_sig =
|
||||
inh.tcx.liberate_late_bound_regions(def_id, &fn_sig);
|
||||
inh.liberate_late_bound_regions(def_id, &fn_sig);
|
||||
let fn_sig =
|
||||
inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
|
||||
|
||||
|
@ -427,7 +427,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
{
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
let sig = fcx.instantiate_type_scheme(span, free_substs, &sig);
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
|
||||
let sig = fcx.liberate_late_bound_regions(def_id, &sig);
|
||||
|
||||
for input_ty in sig.inputs() {
|
||||
fcx.register_wf_obligation(&input_ty, span, self.code.clone());
|
||||
@ -462,7 +462,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
let method_ty = fcx.tcx.type_of(method.def_id);
|
||||
let fty = fcx.instantiate_type_scheme(span, free_substs, &method_ty);
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig());
|
||||
let sig = fcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig());
|
||||
|
||||
debug!("check_method_receiver: sig={:?}", sig);
|
||||
|
||||
@ -478,8 +478,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
ExplicitSelf::ByBox => fcx.tcx.mk_box(self_ty)
|
||||
};
|
||||
let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
|
||||
let rcvr_ty = fcx.tcx.liberate_late_bound_regions(method.def_id,
|
||||
&ty::Binder(rcvr_ty));
|
||||
let rcvr_ty = fcx.liberate_late_bound_regions(method.def_id,
|
||||
&ty::Binder(rcvr_ty));
|
||||
|
||||
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user