pub use self::freshen::TypeFreshener;
use hir::def_id::DefId;
-use middle::free_region::{FreeRegionMap, RegionRelations};
+use middle::free_region::RegionRelations;
use middle::region;
use middle::lang_items;
use mir::tcx::PlaceTy;
use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins};
use self::lexical_region_resolve::LexicalRegionResolutions;
+use self::outlives::free_region_map::FreeRegionMap;
use self::type_variable::TypeVariableOrigin;
use self::unify_key::ToType;
mod lub;
pub mod region_constraints;
mod lexical_region_resolve;
-mod outlives;
+pub mod outlives;
pub mod resolve;
mod freshen;
mod sub;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use middle::free_region::FreeRegionMap;
use infer::{InferCtxt, GenericKind};
+use infer::outlives::free_region_map::FreeRegionMap;
use infer::outlives::implied_bounds::ImpliedBound;
use ty::{self, Ty};
--- /dev/null
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use ty::{self, Lift, TyCtxt, Region};
+use rustc_data_structures::transitive_relation::TransitiveRelation;
+
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub struct FreeRegionMap<'tcx> {
+ // Stores the relation `a < b`, where `a` and `b` are regions.
+ //
+ // Invariant: only free regions like `'x` or `'static` are stored
+ // in this relation, not scopes.
+ relation: TransitiveRelation<Region<'tcx>>
+}
+
+impl<'tcx> FreeRegionMap<'tcx> {
+ pub fn new() -> Self {
+ FreeRegionMap { relation: TransitiveRelation::new() }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.relation.is_empty()
+ }
+
+ pub fn relate_free_regions_from_predicates(&mut self,
+ predicates: &[ty::Predicate<'tcx>]) {
+ debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
+ for predicate in predicates {
+ match *predicate {
+ ty::Predicate::Projection(..) |
+ ty::Predicate::Trait(..) |
+ ty::Predicate::Equate(..) |
+ ty::Predicate::Subtype(..) |
+ ty::Predicate::WellFormed(..) |
+ ty::Predicate::ObjectSafe(..) |
+ ty::Predicate::ClosureKind(..) |
+ ty::Predicate::TypeOutlives(..) |
+ ty::Predicate::ConstEvaluatable(..) => {
+ // No region bounds here
+ }
+ ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
+ self.relate_regions(r_b, r_a);
+ }
+ }
+ }
+ }
+
+ /// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
+ /// (with the exception that `'static: 'x` is not notable)
+ pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
+ debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
+ if is_free_or_static(sub) && is_free(sup) {
+ self.relation.add(sub, sup)
+ }
+ }
+
+ /// Tests whether `r_a <= sup`. Both must be free regions or
+ /// `'static`.
+ pub fn sub_free_regions<'a, 'gcx>(&self,
+ r_a: Region<'tcx>,
+ r_b: Region<'tcx>)
+ -> bool {
+ assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
+ if let ty::ReStatic = r_b {
+ true // `'a <= 'static` is just always true, and not stored in the relation explicitly
+ } else {
+ r_a == r_b || self.relation.contains(&r_a, &r_b)
+ }
+ }
+
+ /// Compute the least-upper-bound of two free regions. In some
+ /// cases, this is more conservative than necessary, in order to
+ /// avoid making arbitrary choices. See
+ /// `TransitiveRelation::postdom_upper_bound` for more details.
+ pub fn lub_free_regions<'a, 'gcx>(&self,
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ r_a: Region<'tcx>,
+ r_b: Region<'tcx>)
+ -> Region<'tcx> {
+ debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
+ assert!(is_free(r_a));
+ assert!(is_free(r_b));
+ let result = if r_a == r_b { r_a } else {
+ match self.relation.postdom_upper_bound(&r_a, &r_b) {
+ None => tcx.mk_region(ty::ReStatic),
+ Some(r) => *r,
+ }
+ };
+ debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
+ result
+ }
+
+ /// Returns all regions that are known to outlive `r_a`. For
+ /// example, in a function:
+ ///
+ /// ```
+ /// fn foo<'a, 'b: 'a, 'c: 'b>() { .. }
+ /// ```
+ ///
+ /// if `r_a` represents `'a`, this function would return `{'b, 'c}`.
+ pub fn regions_that_outlive<'a, 'gcx>(&self, r_a: Region<'tcx>) -> Vec<&Region<'tcx>> {
+ assert!(is_free(r_a) || *r_a == ty::ReStatic);
+ self.relation.greater_than(&r_a)
+ }
+}
+
+fn is_free(r: Region) -> bool {
+ match *r {
+ ty::ReEarlyBound(_) | ty::ReFree(_) => true,
+ _ => false
+ }
+}
+
+fn is_free_or_static(r: Region) -> bool {
+ match *r {
+ ty::ReStatic => true,
+ _ => is_free(r),
+ }
+}
+
+impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
+ relation
+});
+
+impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
+ type Lifted = FreeRegionMap<'tcx>;
+ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
+ self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
+ .map(|relation| FreeRegionMap { relation })
+ }
+}
//! Various code related to computing outlives relations.
pub mod env;
+pub mod free_region_map;
pub mod implied_bounds;
mod obligations;
//! `TransitiveRelation` type and use that to decide when one free
//! region outlives another and so forth.
+use infer::outlives::free_region_map::FreeRegionMap;
use hir::def_id::DefId;
use middle::region;
-use ty::{self, Lift, TyCtxt, Region};
-use rustc_data_structures::transitive_relation::TransitiveRelation;
+use ty::{self, TyCtxt, Region};
/// Combines a `region::ScopeTree` (which governs relationships between
/// scopes) and a `FreeRegionMap` (which governs relationships between
ty::ReStatic => true,
ty::ReEarlyBound(_) | ty::ReFree(_) => {
let re_static = self.tcx.mk_region(ty::ReStatic);
- self.free_regions.relation.contains(&re_static, &super_region)
+ self.free_regions.sub_free_regions(&re_static, &super_region)
}
_ => false
}
}
}
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct FreeRegionMap<'tcx> {
- // Stores the relation `a < b`, where `a` and `b` are regions.
- //
- // Invariant: only free regions like `'x` or `'static` are stored
- // in this relation, not scopes.
- relation: TransitiveRelation<Region<'tcx>>
-}
-
-impl<'tcx> FreeRegionMap<'tcx> {
- pub fn new() -> Self {
- FreeRegionMap { relation: TransitiveRelation::new() }
- }
-
- pub fn is_empty(&self) -> bool {
- self.relation.is_empty()
- }
-
- pub fn relate_free_regions_from_predicates(&mut self,
- predicates: &[ty::Predicate<'tcx>]) {
- debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
- for predicate in predicates {
- match *predicate {
- ty::Predicate::Projection(..) |
- ty::Predicate::Trait(..) |
- ty::Predicate::Equate(..) |
- ty::Predicate::Subtype(..) |
- ty::Predicate::WellFormed(..) |
- ty::Predicate::ObjectSafe(..) |
- ty::Predicate::ClosureKind(..) |
- ty::Predicate::TypeOutlives(..) |
- ty::Predicate::ConstEvaluatable(..) => {
- // No region bounds here
- }
- ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
- self.relate_regions(r_b, r_a);
- }
- }
- }
- }
-
- /// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
- /// (with the exception that `'static: 'x` is not notable)
- pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
- debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
- if is_free_or_static(sub) && is_free(sup) {
- self.relation.add(sub, sup)
- }
- }
-
- /// Tests whether `r_a <= sup`. Both must be free regions or
- /// `'static`.
- pub fn sub_free_regions<'a, 'gcx>(&self,
- r_a: Region<'tcx>,
- r_b: Region<'tcx>)
- -> bool {
- assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
- if let ty::ReStatic = r_b {
- true // `'a <= 'static` is just always true, and not stored in the relation explicitly
- } else {
- r_a == r_b || self.relation.contains(&r_a, &r_b)
- }
- }
-
- /// Compute the least-upper-bound of two free regions. In some
- /// cases, this is more conservative than necessary, in order to
- /// avoid making arbitrary choices. See
- /// `TransitiveRelation::postdom_upper_bound` for more details.
- pub fn lub_free_regions<'a, 'gcx>(&self,
- tcx: TyCtxt<'a, 'gcx, 'tcx>,
- r_a: Region<'tcx>,
- r_b: Region<'tcx>)
- -> Region<'tcx> {
- debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
- assert!(is_free(r_a));
- assert!(is_free(r_b));
- let result = if r_a == r_b { r_a } else {
- match self.relation.postdom_upper_bound(&r_a, &r_b) {
- None => tcx.mk_region(ty::ReStatic),
- Some(r) => *r,
- }
- };
- debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
- result
- }
-
- /// Returns all regions that are known to outlive `r_a`. For
- /// example, in a function:
- ///
- /// ```
- /// fn foo<'a, 'b: 'a, 'c: 'b>() { .. }
- /// ```
- ///
- /// if `r_a` represents `'a`, this function would return `{'b, 'c}`.
- pub fn regions_that_outlive<'a, 'gcx>(&self, r_a: Region<'tcx>) -> Vec<&Region<'tcx>> {
- assert!(is_free(r_a) || *r_a == ty::ReStatic);
- self.relation.greater_than(&r_a)
- }
-}
-
-fn is_free(r: Region) -> bool {
- match *r {
- ty::ReEarlyBound(_) | ty::ReFree(_) => true,
- _ => false
- }
-}
-
-fn is_free_or_static(r: Region) -> bool {
- match *r {
- ty::ReStatic => true,
- _ => is_free(r),
- }
-}
-
-impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
- relation
-});
-
-impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
- type Lifted = FreeRegionMap<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
- self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
- .map(|relation| FreeRegionMap { relation })
- }
-}
use hir;
use hir::def_id::DefId;
+use infer::outlives::free_region_map::FreeRegionMap;
use middle::const_val::ConstEvalErr;
use middle::region;
-use middle::free_region::FreeRegionMap;
use ty::subst::Substs;
use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, ToPredicate};
use ty::error::{ExpectedFound, TypeError};
use hir::map::DefPathHash;
use lint::{self, Lint};
use ich::{StableHashingContext, NodeIdHashingMode};
+use infer::outlives::free_region_map::FreeRegionMap;
use middle::const_val::ConstVal;
use middle::cstore::{CrateStore, LinkMeta};
use middle::cstore::EncodedMetadata;
-use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use middle::stability;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
-use rustc::middle::free_region::FreeRegionMap;
+use rustc::infer::outlives::free_region_map::FreeRegionMap;
use rustc::ty::{self, RegionVid};
use rustc::ty::subst::Substs;
use rustc::util::nodemap::FxHashMap;
use rustc::infer::RegionVariableOrigin;
use rustc::infer::NLLRegionVariableOrigin;
use rustc::infer::region_constraints::VarOrigins;
-use rustc::middle::free_region::FreeRegionMap;
+use rustc::infer::outlives::free_region_map::FreeRegionMap;
use rustc::mir::{Location, Mir};
use rustc::ty::{self, RegionVid};
use rustc_data_structures::indexed_vec::IndexVec;
use check::regionck::RegionCtxt;
use hir::def_id::DefId;
-use middle::free_region::FreeRegionMap;
use rustc::infer::{self, InferOk};
+use rustc::infer::outlives::free_region_map::FreeRegionMap;
use rustc::middle::region;
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
//! Check properties that are required by built-in traits and set
//! up data structures required by type-checking/translation.
-use rustc::middle::free_region::FreeRegionMap;
+use rustc::infer::outlives::free_region_map::FreeRegionMap;
use rustc::middle::region;
use rustc::middle::lang_items::UnsizeTraitLangItem;