rustc: use DefId instead of CodeExtent for FreeRegion's scope.
This commit is contained in:
parent
72aab7ade4
commit
6d4c2141b5
@ -409,11 +409,6 @@ impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
|
||||
Free(call_site_scope_data, decl)
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData {
|
||||
fn_id,
|
||||
body_id
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ty::DebruijnIndex {
|
||||
depth
|
||||
});
|
||||
@ -466,7 +461,7 @@ impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
|
||||
custom_kind
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ty::FreeRegion<'tcx> {
|
||||
impl_stable_hash_for!(struct ty::FreeRegion {
|
||||
scope,
|
||||
bound_region
|
||||
});
|
||||
|
@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
let node = fr.scope.map(|s| s.node_id())
|
||||
let node = self.hir.as_local_node_id(fr.scope)
|
||||
.unwrap_or(DUMMY_NODE_ID);
|
||||
let unknown;
|
||||
let tag = match self.hir.find(node) {
|
||||
|
@ -1009,7 +1009,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn add_given(&self,
|
||||
sub: ty::FreeRegion<'tcx>,
|
||||
sub: ty::FreeRegion,
|
||||
sup: ty::RegionVid)
|
||||
{
|
||||
self.region_vars.add_given(sub, sup);
|
||||
|
@ -127,7 +127,7 @@ pub enum UndoLogEntry<'tcx> {
|
||||
AddVerify(usize),
|
||||
|
||||
/// We added the given `given`
|
||||
AddGiven(ty::FreeRegion<'tcx>, ty::RegionVid),
|
||||
AddGiven(ty::FreeRegion, ty::RegionVid),
|
||||
|
||||
/// We added a GLB/LUB "combinaton variable"
|
||||
AddCombination(CombineMapType, TwoRegions<'tcx>),
|
||||
@ -213,7 +213,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
// record the fact that `'a <= 'b` is implied by the fn signature,
|
||||
// and then ignore the constraint when solving equations. This is
|
||||
// a bit of a hack but seems to work.
|
||||
givens: RefCell<FxHashSet<(ty::FreeRegion<'tcx>, ty::RegionVid)>>,
|
||||
givens: RefCell<FxHashSet<(ty::FreeRegion, ty::RegionVid)>>,
|
||||
|
||||
lubs: RefCell<CombineMap<'tcx>>,
|
||||
glbs: RefCell<CombineMap<'tcx>>,
|
||||
@ -661,7 +661,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_given(&self, sub: ty::FreeRegion<'tcx>, sup: ty::RegionVid) {
|
||||
pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
|
||||
// cannot add givens once regions are resolved
|
||||
assert!(self.values_are_none());
|
||||
|
||||
@ -931,19 +931,18 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
||||
b);
|
||||
}
|
||||
|
||||
(&ReFree(fr), &ReScope(s_id)) |
|
||||
(&ReScope(s_id), &ReFree(fr)) => {
|
||||
(&ReFree(ref fr), &ReScope(s_id)) |
|
||||
(&ReScope(s_id), &ReFree(ref fr)) => {
|
||||
// A "free" region can be interpreted as "some region
|
||||
// at least as big as the block fr.scope_id". So, we can
|
||||
// at least as big as fr.scope". So, we can
|
||||
// reasonably compare free regions and scopes:
|
||||
if let Some(fr_scope) = fr.scope {
|
||||
let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id);
|
||||
if r_id == fr_scope {
|
||||
// if the free region's scope `fr.scope_id` is bigger than
|
||||
// the scope region `s_id`, then the LUB is the free
|
||||
// region itself:
|
||||
return self.tcx.mk_region(ReFree(fr));
|
||||
}
|
||||
let fr_scope = region_rels.region_maps.free_extent(self.tcx, fr);
|
||||
let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id);
|
||||
if r_id == fr_scope {
|
||||
// if the free region's scope `fr.scope` is bigger than
|
||||
// the scope region `s_id`, then the LUB is the free
|
||||
// region itself:
|
||||
return self.tcx.mk_region(ReFree(*fr));
|
||||
}
|
||||
|
||||
// otherwise, we don't know what the free region is,
|
||||
|
@ -71,12 +71,9 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
|
||||
(&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
|
||||
self.region_maps.is_subscope_of(sub_scope, super_scope),
|
||||
|
||||
(&ty::ReScope(sub_scope), &ty::ReFree(fr)) => {
|
||||
// 1. It is safe to unwrap `fr.scope` because we
|
||||
// should only ever wind up comparing against
|
||||
// `ReScope` in the context of a method or
|
||||
// body, where `fr.scope` should be `Some`.
|
||||
self.region_maps.is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) ||
|
||||
(&ty::ReScope(sub_scope), &ty::ReFree(ref fr)) => {
|
||||
let fr_scope = self.region_maps.free_extent(self.tcx, fr);
|
||||
self.region_maps.is_subscope_of(sub_scope, fr_scope) ||
|
||||
self.is_static(super_region)
|
||||
}
|
||||
|
||||
|
@ -1440,9 +1440,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
// 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(
|
||||
Some(self.ir.tcx.call_site_extent(id)),
|
||||
&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);
|
||||
|
@ -790,7 +790,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
// The environment of a closure is guaranteed to
|
||||
// outlive any bindings introduced in the body of the
|
||||
// closure itself.
|
||||
scope: Some(self.tcx().call_site_extent(upvar_id.closure_expr_id)),
|
||||
scope: self.tcx().hir.local_def_id(upvar_id.closure_expr_id),
|
||||
bound_region: ty::BrEnv
|
||||
}));
|
||||
|
||||
|
@ -120,23 +120,6 @@ pub enum CodeExtentData {
|
||||
Remainder(BlockRemainder)
|
||||
}
|
||||
|
||||
/// extent of call-site for a function/method.
|
||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
|
||||
RustcDecodable, Debug, Copy)]
|
||||
pub struct CallSiteScopeData {
|
||||
pub fn_id: ast::NodeId, pub body_id: ast::NodeId,
|
||||
}
|
||||
|
||||
impl CallSiteScopeData {
|
||||
pub fn to_code_extent<'a, 'tcx, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CodeExtent<'tcx> {
|
||||
tcx.intern_code_extent(
|
||||
match *self {
|
||||
CallSiteScopeData { fn_id, body_id } =>
|
||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a subscope of `block` for a binding that is introduced
|
||||
/// by `block.stmts[first_statement_index]`. Such subscopes represent
|
||||
/// a suffix of the block. Note that each subscope does not include
|
||||
@ -612,6 +595,14 @@ impl<'tcx> RegionMaps<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Assuming that the provided region was defined within this `RegionMaps`,
|
||||
/// returns the outermost `CodeExtent` that the region outlives.
|
||||
pub fn free_extent<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, fr: &ty::FreeRegion)
|
||||
-> CodeExtent<'tcx> {
|
||||
let scope_id = tcx.hir.as_local_node_id(fr.scope).unwrap();
|
||||
tcx.call_site_extent(scope_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Records the lifetime of a local variable as `cx.var_parent`
|
||||
|
@ -19,7 +19,6 @@ use hir::map::Map;
|
||||
use session::Session;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use middle::region;
|
||||
use ty;
|
||||
|
||||
use std::cell::Cell;
|
||||
@ -42,7 +41,7 @@ pub enum Region {
|
||||
EarlyBound(/* index */ u32, /* lifetime decl */ ast::NodeId),
|
||||
LateBound(ty::DebruijnIndex, /* lifetime decl */ ast::NodeId),
|
||||
LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
|
||||
Free(region::CallSiteScopeData, /* lifetime decl */ ast::NodeId),
|
||||
Free(DefId, /* lifetime decl */ ast::NodeId),
|
||||
}
|
||||
|
||||
impl Region {
|
||||
@ -897,9 +896,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
if let Some(mut def) = result {
|
||||
if let Some(body_id) = outermost_body {
|
||||
let fn_id = self.hir_map.body_owner(body_id);
|
||||
let scope_data = region::CallSiteScopeData {
|
||||
fn_id: fn_id, body_id: body_id.node_id
|
||||
};
|
||||
match self.hir_map.get(fn_id) {
|
||||
hir::map::NodeItem(&hir::Item {
|
||||
node: hir::ItemFn(..), ..
|
||||
@ -910,7 +906,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
hir::map::NodeImplItem(&hir::ImplItem {
|
||||
node: hir::ImplItemKind::Method(..), ..
|
||||
}) => {
|
||||
def = Region::Free(scope_data, def.id().unwrap());
|
||||
let scope = self.hir_map.local_def_id(fn_id);
|
||||
def = Region::Free(scope, def.id().unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
// Search for a predicate like `Self : Sized` amongst the trait bounds.
|
||||
let free_substs = self.construct_free_substs(def_id, None);
|
||||
let free_substs = self.construct_free_substs(def_id);
|
||||
let predicates = self.predicates_of(def_id);
|
||||
let predicates = predicates.instantiate(self, free_substs).predicates;
|
||||
elaborate_predicates(self, predicates)
|
||||
|
@ -655,11 +655,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
self.intern_code_extent(CodeExtentData::Misc(n))
|
||||
}
|
||||
|
||||
// Returns the code extent for an item - the destruction scope.
|
||||
pub fn item_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
|
||||
self.intern_code_extent(CodeExtentData::DestructionScope(n))
|
||||
}
|
||||
|
||||
pub fn call_site_extent(self, fn_id: ast::NodeId) -> CodeExtent<'gcx> {
|
||||
self.intern_code_extent(CodeExtentData::CallSiteScope {
|
||||
fn_id,
|
||||
@ -852,15 +847,6 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::FreeRegion<'a> {
|
||||
type Lifted = ty::FreeRegion<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
let scope = self.scope.map(|code_extent| tcx.intern_code_extent(*code_extent));
|
||||
let bound_region = self.bound_region;
|
||||
Some(ty::FreeRegion { scope, bound_region })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
|
||||
type Lifted = Region<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
|
||||
|
@ -39,7 +39,7 @@
|
||||
//! 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 middle::region;
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::adjustment;
|
||||
use ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// 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: Option<region::CodeExtent<'tcx>>,
|
||||
all_outlive_scope: DefId,
|
||||
value: &Binder<T>)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx>
|
||||
|
@ -23,7 +23,6 @@ use ich::StableHashingContext;
|
||||
use middle::const_val::ConstVal;
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use middle::privacy::AccessLevels;
|
||||
use middle::region::CodeExtent;
|
||||
use middle::resolve_lifetime::ObjectLifetimeDefault;
|
||||
use mir::Mir;
|
||||
use traits;
|
||||
@ -1244,28 +1243,11 @@ pub struct ParameterEnvironment<'tcx> {
|
||||
/// See `construct_free_substs` for details.
|
||||
pub free_substs: &'tcx Substs<'tcx>,
|
||||
|
||||
/// Each type parameter has an implicit region bound that
|
||||
/// indicates it must outlive at least the function body (the user
|
||||
/// may specify stronger requirements). This field indicates the
|
||||
/// region of the callee. If it is `None`, then the parameter
|
||||
/// environment is for an item or something where the "callee" is
|
||||
/// not clear.
|
||||
pub implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||
|
||||
/// Obligations that the caller must satisfy. This is basically
|
||||
/// the set of bounds on the in-scope type parameters, translated
|
||||
/// into Obligations, and elaborated and normalized.
|
||||
pub caller_bounds: &'tcx [ty::Predicate<'tcx>],
|
||||
|
||||
/// Scope that is attached to free regions for this scope. This is
|
||||
/// usually the id of the fn body, but for more abstract scopes
|
||||
/// like structs we use None or the item extent.
|
||||
///
|
||||
/// FIXME(#3696). It would be nice to refactor so that free
|
||||
/// regions don't have this implicit scope and instead introduce
|
||||
/// relationships in the environment.
|
||||
pub free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||
|
||||
/// A cache for `moves_by_default`.
|
||||
pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
||||
|
||||
@ -1283,9 +1265,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
{
|
||||
ParameterEnvironment {
|
||||
free_substs: self.free_substs,
|
||||
implicit_region_bound: self.implicit_region_bound,
|
||||
caller_bounds: caller_bounds,
|
||||
free_id_outlive: self.free_id_outlive,
|
||||
is_copy_cache: RefCell::new(FxHashMap()),
|
||||
is_sized_cache: RefCell::new(FxHashMap()),
|
||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
||||
@ -2394,8 +2374,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
ty::ParameterEnvironment {
|
||||
free_substs: self.intern_substs(&[]),
|
||||
caller_bounds: Slice::empty(),
|
||||
implicit_region_bound: None,
|
||||
free_id_outlive: None,
|
||||
is_copy_cache: RefCell::new(FxHashMap()),
|
||||
is_sized_cache: RefCell::new(FxHashMap()),
|
||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
||||
@ -2407,15 +2385,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// In general, this means converting from bound parameters to
|
||||
/// free parameters. Since we currently represent bound/free type
|
||||
/// parameters in the same way, this only has an effect on regions.
|
||||
pub fn construct_free_substs(self,
|
||||
def_id: DefId,
|
||||
free_id_outlive: Option<CodeExtent<'gcx>>)
|
||||
-> &'gcx Substs<'gcx> {
|
||||
pub fn construct_free_substs(self, def_id: DefId) -> &'gcx Substs<'gcx> {
|
||||
|
||||
let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
|
||||
// map bound 'a => free 'a
|
||||
self.global_tcx().mk_region(ReFree(FreeRegion {
|
||||
scope: free_id_outlive,
|
||||
scope: def_id,
|
||||
bound_region: def.to_bound_region()
|
||||
}))
|
||||
}, |def, _| {
|
||||
@ -2433,14 +2408,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// Construct the free substs.
|
||||
//
|
||||
|
||||
let free_id_outlive = self.hir.as_local_node_id(def_id).map(|id| {
|
||||
if self.hir.maybe_body_owned_by(id).is_some() {
|
||||
self.call_site_extent(id)
|
||||
} else {
|
||||
self.item_extent(id)
|
||||
}
|
||||
});
|
||||
let free_substs = self.construct_free_substs(def_id, free_id_outlive);
|
||||
let free_substs = self.construct_free_substs(def_id);
|
||||
|
||||
//
|
||||
// Compute the bounds on Self and the type parameters.
|
||||
@ -2449,7 +2417,7 @@ 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(free_id_outlive, &ty::Binder(bounds));
|
||||
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
|
||||
@ -2466,17 +2434,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
//
|
||||
|
||||
let unnormalized_env = ty::ParameterEnvironment {
|
||||
free_substs: free_substs,
|
||||
implicit_region_bound: free_id_outlive.map(|f| tcx.mk_region(ty::ReScope(f))),
|
||||
free_substs,
|
||||
caller_bounds: tcx.intern_predicates(&predicates),
|
||||
free_id_outlive: free_id_outlive,
|
||||
is_copy_cache: RefCell::new(FxHashMap()),
|
||||
is_sized_cache: RefCell::new(FxHashMap()),
|
||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
||||
};
|
||||
|
||||
let body_id = free_id_outlive.map(|f| f.node_id())
|
||||
.unwrap_or(DUMMY_NODE_ID);
|
||||
let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
|
||||
self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
|
||||
});
|
||||
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
||||
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
|
||||
}
|
||||
|
@ -43,12 +43,8 @@ pub struct TypeAndMut<'tcx> {
|
||||
RustcEncodable, RustcDecodable, Copy)]
|
||||
/// A "free" region `fr` can be interpreted as "some region
|
||||
/// at least as big as the scope `fr.scope`".
|
||||
///
|
||||
/// If `fr.scope` is None, then this is in some context (e.g., an
|
||||
/// impl) where lifetimes are more abstract and the notion of the
|
||||
/// caller/callee stack frames are not applicable.
|
||||
pub struct FreeRegion<'tcx> {
|
||||
pub scope: Option<region::CodeExtent<'tcx>>,
|
||||
pub struct FreeRegion {
|
||||
pub scope: DefId,
|
||||
pub bound_region: BoundRegion,
|
||||
}
|
||||
|
||||
@ -760,7 +756,7 @@ pub enum RegionKind<'tcx> {
|
||||
/// When checking a function body, the types of all arguments and so forth
|
||||
/// that refer to bound region parameters are modified to refer to free
|
||||
/// region parameters.
|
||||
ReFree(FreeRegion<'tcx>),
|
||||
ReFree(FreeRegion),
|
||||
|
||||
/// A concrete region naming some statically determined extent
|
||||
/// (e.g. an expression or sequence of statements) within the
|
||||
|
@ -508,10 +508,8 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ParameterEnvironment(\
|
||||
free_substs={:?}, \
|
||||
implicit_region_bound={:?}, \
|
||||
caller_bounds={:?})",
|
||||
self.free_substs,
|
||||
self.implicit_region_bound,
|
||||
self.caller_bounds)
|
||||
}
|
||||
}
|
||||
@ -544,7 +542,7 @@ impl<'tcx> fmt::Display for ty::RegionKind<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::FreeRegion<'tcx> {
|
||||
impl fmt::Debug for ty::FreeRegion {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ReFree({:?}, {:?})",
|
||||
self.scope, self.bound_region)
|
||||
|
@ -353,7 +353,9 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||
let loan_scope = match *loan_region {
|
||||
ty::ReScope(scope) => scope,
|
||||
|
||||
ty::ReFree(ref fr) => fr.scope.unwrap_or(self.item_ub),
|
||||
ty::ReFree(ref fr) => {
|
||||
self.bccx.region_maps.free_extent(self.tcx(), fr)
|
||||
}
|
||||
|
||||
ty::ReStatic => self.item_ub,
|
||||
|
||||
|
@ -330,15 +330,15 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
||||
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
|
||||
}
|
||||
|
||||
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> {
|
||||
pub fn re_free(&self, id: u32) -> ty::Region<'tcx> {
|
||||
self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: Some(self.tcx().node_extent(nid)),
|
||||
scope: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
|
||||
bound_region: ty::BrAnon(id),
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn t_rptr_free(&self, nid: u32, id: u32) -> Ty<'tcx> {
|
||||
let r = self.re_free(ast::NodeId::from_u32(nid), id);
|
||||
pub fn t_rptr_free(&self, id: u32) -> Ty<'tcx> {
|
||||
let r = self.re_free(id);
|
||||
self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
|
||||
}
|
||||
|
||||
@ -464,7 +464,7 @@ fn sub_free_bound_false() {
|
||||
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound(1);
|
||||
env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
|
||||
@ -482,7 +482,7 @@ fn sub_bound_free_true() {
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound(1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
|
||||
})
|
||||
@ -518,7 +518,7 @@ fn lub_free_bound_infer() {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP));
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound(1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
env.check_lub(env.t_fn(&[t_infer1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
|
||||
@ -541,7 +541,7 @@ fn lub_bound_free() {
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound(1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
|
||||
@ -574,8 +574,8 @@ fn lub_bound_bound_inverse_order() {
|
||||
fn lub_free_free() {
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free2 = env.t_rptr_free(1, 2);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
let t_rptr_free2 = env.t_rptr_free(2);
|
||||
let t_rptr_static = env.t_rptr_static();
|
||||
env.check_lub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
|
||||
@ -600,8 +600,8 @@ fn lub_returning_scope() {
|
||||
fn glb_free_free_with_common_scope() {
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free2 = env.t_rptr_free(1, 2);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
let t_rptr_free2 = env.t_rptr_free(2);
|
||||
let t_rptr_scope = env.t_rptr_scope(1);
|
||||
env.check_glb(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
|
||||
@ -625,7 +625,7 @@ fn glb_bound_free() {
|
||||
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
|
||||
env.create_simple_region_hierarchy();
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound(1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
|
||||
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
|
||||
@ -751,7 +751,7 @@ fn escaping() {
|
||||
|
||||
assert!(!env.t_nil().has_escaping_regions());
|
||||
|
||||
let t_rptr_free1 = env.t_rptr_free(1, 1);
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
assert!(!t_rptr_free1.has_escaping_regions());
|
||||
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1));
|
||||
|
@ -206,13 +206,14 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
-> Ty<'tcx> {
|
||||
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
|
||||
|
||||
let closure_def_id = tcx.hir.local_def_id(closure_expr_id);
|
||||
let region = ty::ReFree(ty::FreeRegion {
|
||||
scope: Some(tcx.call_site_extent(closure_expr_id)),
|
||||
scope: closure_def_id,
|
||||
bound_region: ty::BoundRegion::BrEnv,
|
||||
});
|
||||
let region = tcx.mk_region(region);
|
||||
|
||||
match tcx.closure_kind(tcx.hir.local_def_id(closure_expr_id)) {
|
||||
match tcx.closure_kind(closure_def_id) {
|
||||
ty::ClosureKind::Fn =>
|
||||
tcx.mk_ref(region,
|
||||
ty::TypeAndMut { ty: closure_ty,
|
||||
|
@ -14,7 +14,6 @@ use rustc_const_math::ConstInt;
|
||||
use hair::cx::Cx;
|
||||
use hair::cx::block;
|
||||
use hair::cx::to_ref::ToRef;
|
||||
use rustc::hir::map;
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{self, AdtKind, VariantDef, Ty};
|
||||
@ -807,33 +806,20 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
closure_expr_id);
|
||||
let var_ty = cx.tables().node_id_to_type(id_var);
|
||||
|
||||
let body_id = match cx.tcx.hir.find(closure_expr_id) {
|
||||
Some(map::NodeExpr(expr)) => {
|
||||
match expr.node {
|
||||
hir::ExprClosure(.., body, _) => body.node_id,
|
||||
_ => {
|
||||
span_bug!(expr.span, "closure expr is not a closure expr");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
span_bug!(expr.span, "ast-map has garbage for closure expr");
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME free regions in closures are not right
|
||||
let closure_ty = cx.tables().node_id_to_type(closure_expr_id);
|
||||
|
||||
// FIXME we're just hard-coding the idea that the
|
||||
// signature will be &self or &mut self and hence will
|
||||
// have a bound region with number 0
|
||||
let closure_def_id = cx.tcx.hir.local_def_id(closure_expr_id);
|
||||
let region = ty::ReFree(ty::FreeRegion {
|
||||
scope: Some(cx.tcx.node_extent(body_id)),
|
||||
scope: closure_def_id,
|
||||
bound_region: ty::BoundRegion::BrAnon(0),
|
||||
});
|
||||
let region = cx.tcx.mk_region(region);
|
||||
|
||||
let self_expr = match cx.tcx.closure_kind(cx.tcx.hir.local_def_id(closure_expr_id)) {
|
||||
let self_expr = match cx.tcx.closure_kind(closure_def_id) {
|
||||
ty::ClosureKind::Fn => {
|
||||
let ref_closure_ty = cx.tcx.mk_ref(region,
|
||||
ty::TypeAndMut {
|
||||
|
@ -129,7 +129,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
Some(&rl::Region::Free(scope, id)) => {
|
||||
let name = tcx.hir.name(id);
|
||||
tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: Some(scope.to_code_extent(tcx)),
|
||||
scope,
|
||||
bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name)
|
||||
}))
|
||||
|
||||
|
@ -73,8 +73,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
||||
|
||||
let extent = self.tcx.call_site_extent(expr.id);
|
||||
let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig);
|
||||
let fn_sig = self.tcx.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);
|
||||
|
||||
|
@ -226,7 +226,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
normalize_cause.clone());
|
||||
|
||||
tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| {
|
||||
let inh = Inherited::new(infcx);
|
||||
let inh = Inherited::new(infcx, impl_m.def_id);
|
||||
let infcx = &inh.infcx;
|
||||
|
||||
debug!("compare_impl_method: caller_bounds={:?}",
|
||||
@ -283,7 +283,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
|
||||
|
||||
let trait_sig = tcx.liberate_late_bound_regions(
|
||||
infcx.parameter_environment.free_id_outlive,
|
||||
impl_m.def_id,
|
||||
&m_sig(trait_m));
|
||||
let trait_sig =
|
||||
trait_sig.subst(tcx, trait_to_skol_substs);
|
||||
@ -726,7 +726,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
||||
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
|
||||
let inh = Inherited::new(infcx);
|
||||
let inh = Inherited::new(infcx, impl_c.def_id);
|
||||
let infcx = &inh.infcx;
|
||||
|
||||
// The below is for the most part highly similar to the procedure
|
||||
|
@ -176,6 +176,14 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
// variables to get the concrete type, which can be used to
|
||||
// deanonymize TyAnon, after typeck is done with all functions.
|
||||
anon_types: RefCell<NodeMap<Ty<'tcx>>>,
|
||||
|
||||
/// Each type parameter has an implicit region bound that
|
||||
/// indicates it must outlive at least the function body (the user
|
||||
/// may specify stronger requirements). This field indicates the
|
||||
/// region of the callee. If it is `None`, then the parameter
|
||||
/// environment is for an item or something where the "callee" is
|
||||
/// not clear.
|
||||
implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
|
||||
@ -522,7 +530,8 @@ impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> {
|
||||
/// Necessary because we can't write the following bound:
|
||||
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>).
|
||||
pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>
|
||||
infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
@ -531,7 +540,8 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
let tables = ty::TypeckTables::empty();
|
||||
let param_env = tcx.parameter_environment(def_id);
|
||||
InheritedBuilder {
|
||||
infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing)
|
||||
infcx: tcx.infer_ctxt((tables, param_env), Reveal::UserFacing),
|
||||
def_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -540,12 +550,24 @@ impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
|
||||
fn enter<F, R>(&'tcx mut self, f: F) -> R
|
||||
where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R
|
||||
{
|
||||
self.infcx.enter(|infcx| f(Inherited::new(infcx)))
|
||||
let def_id = self.def_id;
|
||||
self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self {
|
||||
let tcx = infcx.tcx;
|
||||
let item_id = tcx.hir.as_local_node_id(def_id);
|
||||
let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
|
||||
let implicit_region_bound = item_id.and_then(|id| {
|
||||
if body_id.is_some() {
|
||||
Some(tcx.mk_region(ty::ReScope(tcx.call_site_extent(id))))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Inherited {
|
||||
infcx: infcx,
|
||||
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
|
||||
@ -553,6 +575,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
deferred_call_resolutions: RefCell::new(DefIdMap()),
|
||||
deferred_cast_checks: RefCell::new(Vec::new()),
|
||||
anon_types: RefCell::new(NodeMap()),
|
||||
implicit_region_bound,
|
||||
}
|
||||
}
|
||||
|
||||
@ -778,11 +801,10 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
check_abi(tcx, span, fn_sig.abi());
|
||||
|
||||
// Compute the fty from point of view of inside fn.
|
||||
let fn_scope = inh.tcx.call_site_extent(id);
|
||||
let fn_sig =
|
||||
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||
let fn_sig =
|
||||
inh.tcx.liberate_late_bound_regions(Some(fn_scope), &fn_sig);
|
||||
inh.tcx.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);
|
||||
|
||||
|
@ -1612,8 +1612,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> {
|
||||
let param_env = &self.parameter_environment;
|
||||
|
||||
debug!("param_bound(param_ty={:?})",
|
||||
param_ty);
|
||||
|
||||
@ -1621,7 +1619,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Add in the default bound of fn body that applies to all in
|
||||
// scope type parameters:
|
||||
param_bounds.extend(param_env.implicit_region_bound);
|
||||
param_bounds.extend(self.implicit_region_bound);
|
||||
|
||||
VerifyBound::AnyRegion(param_bounds)
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ use check::{Inherited, FnCtxt};
|
||||
use constrained_type_params::{identify_constrained_type_params, Parameter};
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use middle::region::{CodeExtent};
|
||||
use rustc::traits::{self, ObligationCauseCode};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
@ -161,7 +160,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let code = self.code.clone();
|
||||
self.for_id(item_id, span).with_fcx(|fcx, this| {
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
let free_id_outlive = fcx.parameter_environment.free_id_outlive;
|
||||
|
||||
let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
|
||||
|
||||
@ -184,10 +182,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let predicates = fcx.instantiate_bounds(span, item.def_id, free_substs);
|
||||
let sig = method_ty.fn_sig();
|
||||
this.check_fn_or_method(fcx, span, sig, &predicates,
|
||||
free_id_outlive, &mut implied_bounds);
|
||||
item.def_id, &mut implied_bounds);
|
||||
let sig_if_method = sig_if_method.expect("bad signature for method");
|
||||
this.check_method_receiver(fcx, sig_if_method, &item,
|
||||
free_id_outlive, self_ty);
|
||||
this.check_method_receiver(fcx, sig_if_method, &item, self_ty);
|
||||
}
|
||||
ty::AssociatedKind::Type => {
|
||||
if item.defaultness.has_value() {
|
||||
@ -338,9 +335,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
|
||||
|
||||
let mut implied_bounds = vec![];
|
||||
let free_id_outlive = fcx.tcx.call_site_extent(item.id);
|
||||
this.check_fn_or_method(fcx, item.span, sig, &predicates,
|
||||
Some(free_id_outlive), &mut implied_bounds);
|
||||
def_id, &mut implied_bounds);
|
||||
implied_bounds
|
||||
})
|
||||
}
|
||||
@ -426,12 +422,12 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
span: Span,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
predicates: &ty::InstantiatedPredicates<'tcx>,
|
||||
free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||
def_id: DefId,
|
||||
implied_bounds: &mut Vec<Ty<'tcx>>)
|
||||
{
|
||||
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(free_id_outlive, &sig);
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
|
||||
|
||||
for input_ty in sig.inputs() {
|
||||
fcx.register_wf_obligation(&input_ty, span, self.code.clone());
|
||||
@ -450,7 +446,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
|
||||
method_sig: &hir::MethodSig,
|
||||
method: &ty::AssociatedItem,
|
||||
free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||
self_ty: ty::Ty<'tcx>)
|
||||
{
|
||||
// check that the type of the method's receiver matches the
|
||||
@ -467,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(free_id_outlive, &fty.fn_sig());
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig());
|
||||
|
||||
debug!("check_method_receiver: sig={:?}", sig);
|
||||
|
||||
@ -483,7 +478,7 @@ 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(free_id_outlive,
|
||||
let rcvr_ty = fcx.tcx.liberate_late_bound_regions(method.def_id,
|
||||
&ty::Binder(rcvr_ty));
|
||||
|
||||
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
|
||||
|
@ -16,9 +16,9 @@ impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
|
||||
//~^ ERROR method not compatible with trait
|
||||
//~| lifetime mismatch
|
||||
//~| NOTE expected type `fn(&mut RepeatMut<'a, T>) -> std::option::Option<&mut T>`
|
||||
//~| NOTE the anonymous lifetime #1 defined on the method body
|
||||
//~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the method body
|
||||
{
|
||||
//~^ NOTE the anonymous lifetime #1 defined on the body
|
||||
//~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the body
|
||||
Some(&mut self.0)
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,17 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
12 | if x > y { x } else { y }
|
||||
| ^
|
||||
|
|
||||
note: ...the reference is valid for the lifetime 'a as defined on the body at 11:43...
|
||||
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:44
|
||||
note: ...the reference is valid for the lifetime 'a as defined on the function body at 11:0...
|
||||
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:1
|
||||
|
|
||||
11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
||||
| ____________________________________________^
|
||||
11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
||||
12 | | if x > y { x } else { y }
|
||||
13 | | }
|
||||
| |_^
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the body at 11:43
|
||||
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:44
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the function body at 11:0
|
||||
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:1
|
||||
|
|
||||
11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
||||
| ____________________________________________^
|
||||
11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
||||
12 | | if x > y { x } else { y }
|
||||
13 | | }
|
||||
| |_^
|
||||
|
@ -6,19 +6,17 @@ error[E0308]: mismatched types
|
||||
|
|
||||
= note: expected type `Ref<'a, _>`
|
||||
found type `Ref<'_, _>`
|
||||
note: the anonymous lifetime #2 defined on the body at 15:51...
|
||||
--> $DIR/ex2a-push-one-existing-name.rs:15:52
|
||||
note: the anonymous lifetime #2 defined on the function body at 15:0...
|
||||
--> $DIR/ex2a-push-one-existing-name.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
|
||||
| ____________________________________________________^
|
||||
15 | / fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
|
||||
16 | | x.push(y);
|
||||
17 | | }
|
||||
| |_^
|
||||
note: ...does not necessarily outlive the lifetime 'a as defined on the body at 15:51
|
||||
--> $DIR/ex2a-push-one-existing-name.rs:15:52
|
||||
note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 15:0
|
||||
--> $DIR/ex2a-push-one-existing-name.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
|
||||
| ____________________________________________________^
|
||||
15 | / fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
|
||||
16 | | x.push(y);
|
||||
17 | | }
|
||||
| |_^
|
||||
|
@ -6,19 +6,17 @@ error[E0308]: mismatched types
|
||||
|
|
||||
= note: expected type `Ref<'_, _>`
|
||||
found type `Ref<'_, _>`
|
||||
note: the anonymous lifetime #3 defined on the body at 15:43...
|
||||
--> $DIR/ex2b-push-no-existing-names.rs:15:44
|
||||
note: the anonymous lifetime #3 defined on the function body at 15:0...
|
||||
--> $DIR/ex2b-push-no-existing-names.rs:15:1
|
||||
|
|
||||
15 | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||
| ____________________________________________^
|
||||
15 | / fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||
16 | | x.push(y);
|
||||
17 | | }
|
||||
| |_^
|
||||
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 15:43
|
||||
--> $DIR/ex2b-push-no-existing-names.rs:15:44
|
||||
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 15:0
|
||||
--> $DIR/ex2b-push-no-existing-names.rs:15:1
|
||||
|
|
||||
15 | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||
| ____________________________________________^
|
||||
15 | / fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||
16 | | x.push(y);
|
||||
17 | | }
|
||||
| |_^
|
||||
|
@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
|
||||
16 | let z = Ref { data: y.data };
|
||||
| ^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66...
|
||||
--> $DIR/ex2c-push-inference-variable.rs:15:67
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
|
||||
--> $DIR/ex2c-push-inference-variable.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let z = Ref { data: y.data };
|
||||
17 | | x.push(z);
|
||||
18 | | }
|
||||
@ -18,11 +17,10 @@ note: ...so that reference does not outlive borrowed content
|
||||
|
|
||||
16 | let z = Ref { data: y.data };
|
||||
| ^^^^^^
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66...
|
||||
--> $DIR/ex2c-push-inference-variable.rs:15:67
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
|
||||
--> $DIR/ex2c-push-inference-variable.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let z = Ref { data: y.data };
|
||||
17 | | x.push(z);
|
||||
18 | | }
|
||||
|
@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
|
||||
17 | let b = Ref { data: y.data };
|
||||
| ^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66...
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:15:67
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let a: &mut Vec<Ref<i32>> = x;
|
||||
17 | | let b = Ref { data: y.data };
|
||||
18 | | a.push(b);
|
||||
@ -19,11 +18,10 @@ note: ...so that reference does not outlive borrowed content
|
||||
|
|
||||
17 | let b = Ref { data: y.data };
|
||||
| ^^^^^^
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66...
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:15:67
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
|
||||
--> $DIR/ex2d-push-inference-variable-2.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let a: &mut Vec<Ref<i32>> = x;
|
||||
17 | | let b = Ref { data: y.data };
|
||||
18 | | a.push(b);
|
||||
|
@ -4,11 +4,10 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
|
||||
17 | let b = Ref { data: y.data };
|
||||
| ^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66...
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:15:67
|
||||
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let a: &mut Vec<Ref<i32>> = x;
|
||||
17 | | let b = Ref { data: y.data };
|
||||
18 | | Vec::push(a, b);
|
||||
@ -19,11 +18,10 @@ note: ...so that reference does not outlive borrowed content
|
||||
|
|
||||
17 | let b = Ref { data: y.data };
|
||||
| ^^^^^^
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66...
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:15:67
|
||||
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
|
||||
--> $DIR/ex2e-push-inference-variable-3.rs:15:1
|
||||
|
|
||||
15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
| ___________________________________________________________________^
|
||||
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||
16 | | let a: &mut Vec<Ref<i32>> = x;
|
||||
17 | | let b = Ref { data: y.data };
|
||||
18 | | Vec::push(a, b);
|
||||
|
Loading…
x
Reference in New Issue
Block a user