mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
centralize the caching for is-copy, is-sized, and is-freeze
Use the trait-environment+type as the key. Note that these are only invoked on types that live for the entire compilation (no inference artifacts). We no longer need the various special-case bits and caches that were in place before.
This commit is contained in:
parent
81734e0e06
commit
1b7acb6f34
@ -108,6 +108,9 @@ pub enum DepNode<D: Clone + Debug> {
|
|||||||
SymbolName(D),
|
SymbolName(D),
|
||||||
SpecializationGraph(D),
|
SpecializationGraph(D),
|
||||||
ObjectSafety(D),
|
ObjectSafety(D),
|
||||||
|
IsCopy(D),
|
||||||
|
IsSized(D),
|
||||||
|
IsFreeze(D),
|
||||||
|
|
||||||
// The set of impls for a given trait. Ultimately, it would be
|
// The set of impls for a given trait. Ultimately, it would be
|
||||||
// nice to get more fine-grained here (e.g., to include a
|
// nice to get more fine-grained here (e.g., to include a
|
||||||
@ -233,6 +236,9 @@ impl<D: Clone + Debug> DepNode<D> {
|
|||||||
// they are always absolute.
|
// they are always absolute.
|
||||||
WorkProduct(ref id) => Some(WorkProduct(id.clone())),
|
WorkProduct(ref id) => Some(WorkProduct(id.clone())),
|
||||||
|
|
||||||
|
IsCopy(ref d) => op(d).map(IsCopy),
|
||||||
|
IsSized(ref d) => op(d).map(IsSized),
|
||||||
|
IsFreeze(ref d) => op(d).map(IsFreeze),
|
||||||
Hir(ref d) => op(d).map(Hir),
|
Hir(ref d) => op(d).map(Hir),
|
||||||
HirBody(ref d) => op(d).map(HirBody),
|
HirBody(ref d) => op(d).map(HirBody),
|
||||||
MetaData(ref d) => op(d).map(MetaData),
|
MetaData(ref d) => op(d).map(MetaData),
|
||||||
|
@ -28,7 +28,7 @@ use middle::lang_items;
|
|||||||
use mir::tcx::LvalueTy;
|
use mir::tcx::LvalueTy;
|
||||||
use ty::subst::{Kind, Subst, Substs};
|
use ty::subst::{Kind, Subst, Substs};
|
||||||
use ty::{TyVid, IntVid, FloatVid};
|
use ty::{TyVid, IntVid, FloatVid};
|
||||||
use ty::{self, Ty, TyCtxt};
|
use ty::{self, ParameterEnvironment, Ty, TyCtxt};
|
||||||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||||
@ -526,9 +526,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
|||||||
let tables = tables.map(InferTables::Interned).unwrap_or_else(|| {
|
let tables = tables.map(InferTables::Interned).unwrap_or_else(|| {
|
||||||
fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress)
|
fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress)
|
||||||
});
|
});
|
||||||
let param_env = param_env.take().unwrap_or_else(|| {
|
let param_env = param_env.take().unwrap_or_else(|| ParameterEnvironment::empty());
|
||||||
global_tcx.empty_parameter_environment()
|
|
||||||
});
|
|
||||||
global_tcx.enter_local(arena, |tcx| f(InferCtxt {
|
global_tcx.enter_local(arena, |tcx| f(InferCtxt {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
tables: tables,
|
tables: tables,
|
||||||
@ -650,7 +648,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize_associated_type_in_env<T>(
|
pub fn normalize_associated_type_in_env<T>(
|
||||||
self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
|
self, value: &T, env: ty::ParameterEnvironment<'tcx>
|
||||||
) -> T
|
) -> T
|
||||||
where T: TransNormalize<'tcx>
|
where T: TransNormalize<'tcx>
|
||||||
{
|
{
|
||||||
@ -662,7 +660,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.infer_ctxt(env.clone(), Reveal::All).enter(|infcx| {
|
self.infer_ctxt(env, Reveal::All).enter(|infcx| {
|
||||||
value.trans_normalize(&infcx)
|
value.trans_normalize(&infcx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1674,8 +1672,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
|
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> {
|
pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> {
|
||||||
&self.parameter_environment
|
self.parameter_environment
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closure_kind(&self,
|
pub fn closure_kind(&self,
|
||||||
|
@ -477,7 +477,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
|
||||||
predicates);
|
predicates);
|
||||||
|
|
||||||
let elaborated_env = unnormalized_env.with_caller_bounds(tcx.intern_predicates(&predicates));
|
let elaborated_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates));
|
||||||
|
|
||||||
tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| {
|
tcx.infer_ctxt(elaborated_env, Reveal::UserFacing).enter(|infcx| {
|
||||||
let predicates = match fully_normalize(
|
let predicates = match fully_normalize(
|
||||||
@ -528,7 +528,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
debug!("normalize_param_env_or_error: resolved predicates={:?}",
|
debug!("normalize_param_env_or_error: resolved predicates={:?}",
|
||||||
predicates);
|
predicates);
|
||||||
|
|
||||||
infcx.parameter_environment.with_caller_bounds(tcx.intern_predicates(&predicates))
|
ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'gcx> {
|
pub fn param_env(&self) -> ty::ParameterEnvironment<'gcx> {
|
||||||
self.infcx.param_env()
|
self.infcx.param_env()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,7 +1079,7 @@ impl<'a, 'gcx, 'tcx> Layout {
|
|||||||
let ptr_layout = |pointee: Ty<'gcx>| {
|
let ptr_layout = |pointee: Ty<'gcx>| {
|
||||||
let non_zero = !ty.is_unsafe_ptr();
|
let non_zero = !ty.is_unsafe_ptr();
|
||||||
let pointee = infcx.normalize_projections(pointee);
|
let pointee = infcx.normalize_projections(pointee);
|
||||||
if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) {
|
if pointee.is_sized(tcx, infcx.parameter_environment, DUMMY_SP) {
|
||||||
Ok(Scalar { value: Pointer, non_zero: non_zero })
|
Ok(Scalar { value: Pointer, non_zero: non_zero })
|
||||||
} else {
|
} else {
|
||||||
let unsized_part = tcx.struct_tail(pointee);
|
let unsized_part = tcx.struct_tail(pointee);
|
||||||
@ -1272,7 +1272,7 @@ impl<'a, 'gcx, 'tcx> Layout {
|
|||||||
let fields = &def.variants[0].fields;
|
let fields = &def.variants[0].fields;
|
||||||
let last_field = &fields[fields.len()-1];
|
let last_field = &fields[fields.len()-1];
|
||||||
let always_sized = tcx.type_of(last_field.did)
|
let always_sized = tcx.type_of(last_field.did)
|
||||||
.is_sized(tcx, ¶m_env, DUMMY_SP);
|
.is_sized(tcx, param_env, DUMMY_SP);
|
||||||
if !always_sized { StructKind::MaybeUnsizedUnivariant }
|
if !always_sized { StructKind::MaybeUnsizedUnivariant }
|
||||||
else { StructKind::AlwaysSizedUnivariant }
|
else { StructKind::AlwaysSizedUnivariant }
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
|
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
|
||||||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||||
use hir::def::Def;
|
use hir::def::Def;
|
||||||
use hir;
|
use hir;
|
||||||
use middle::const_val;
|
use middle::const_val;
|
||||||
@ -136,6 +136,15 @@ impl Key for (MirSuite, MirPassIndex, DefId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx, T: Clone + Hash + Eq + Debug> Key for ty::ParameterEnvironmentAnd<'tcx, T> {
|
||||||
|
fn map_crate(&self) -> CrateNum {
|
||||||
|
LOCAL_CRATE
|
||||||
|
}
|
||||||
|
fn default_span(&self, _: TyCtxt) -> Span {
|
||||||
|
DUMMY_SP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trait Value<'tcx>: Sized {
|
trait Value<'tcx>: Sized {
|
||||||
fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
|
fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
|
||||||
}
|
}
|
||||||
@ -244,6 +253,24 @@ impl<M: DepTrackingMapConfig<Key=DefId>> QueryDescription for M {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> QueryDescription for queries::is_copy_raw<'tcx> {
|
||||||
|
fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String {
|
||||||
|
format!("computing whether `{}` is `Copy`", env.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> QueryDescription for queries::is_sized_raw<'tcx> {
|
||||||
|
fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String {
|
||||||
|
format!("computing whether `{}` is `Sized`", env.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> QueryDescription for queries::is_freeze_raw<'tcx> {
|
||||||
|
fn describe(_tcx: TyCtxt, env: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> String {
|
||||||
|
format!("computing whether `{}` is freeze", env.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> QueryDescription for queries::super_predicates_of<'tcx> {
|
impl<'tcx> QueryDescription for queries::super_predicates_of<'tcx> {
|
||||||
fn describe(tcx: TyCtxt, def_id: DefId) -> String {
|
fn describe(tcx: TyCtxt, def_id: DefId) -> String {
|
||||||
format!("computing the supertraits of `{}`",
|
format!("computing the supertraits of `{}`",
|
||||||
@ -856,6 +883,12 @@ define_maps! { <'tcx>
|
|||||||
-> ty::trait_def::TraitImpls,
|
-> ty::trait_def::TraitImpls,
|
||||||
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
|
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
|
||||||
[] is_object_safe: ObjectSafety(DefId) -> bool,
|
[] is_object_safe: ObjectSafety(DefId) -> bool,
|
||||||
|
|
||||||
|
// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
|
||||||
|
// `ty.is_copy()`, etc, since that will prune the environment where possible.
|
||||||
|
[] is_copy_raw: is_copy_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool,
|
||||||
|
[] is_sized_raw: is_sized_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool,
|
||||||
|
[] is_freeze_raw: is_freeze_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
|
fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
|
||||||
@ -899,3 +932,18 @@ fn crate_variances(_: CrateNum) -> DepNode<DefId> {
|
|||||||
fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode<DefId> {
|
fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode<DefId> {
|
||||||
DepNode::TraitImpls(def_id)
|
DepNode::TraitImpls(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_copy_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
|
||||||
|
let krate_def_id = DefId::local(CRATE_DEF_INDEX);
|
||||||
|
DepNode::IsCopy(krate_def_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_sized_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
|
||||||
|
let krate_def_id = DefId::local(CRATE_DEF_INDEX);
|
||||||
|
DepNode::IsSized(krate_def_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_freeze_dep_node<'tcx>(_: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> DepNode<DefId> {
|
||||||
|
let krate_def_id = DefId::local(CRATE_DEF_INDEX);
|
||||||
|
DepNode::IsSized(krate_def_id)
|
||||||
|
}
|
||||||
|
@ -35,7 +35,7 @@ use util::common::ErrorReported;
|
|||||||
use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
|
use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use serialize::{self, Encodable, Encoder};
|
use serialize::{self, Encodable, Encoder};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::Cell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -507,8 +507,6 @@ bitflags! {
|
|||||||
// Caches for type_is_sized, type_moves_by_default
|
// Caches for type_is_sized, type_moves_by_default
|
||||||
const SIZEDNESS_CACHED = 1 << 16,
|
const SIZEDNESS_CACHED = 1 << 16,
|
||||||
const IS_SIZED = 1 << 17,
|
const IS_SIZED = 1 << 17,
|
||||||
const MOVENESS_CACHED = 1 << 18,
|
|
||||||
const MOVES_BY_DEFAULT = 1 << 19,
|
|
||||||
const FREEZENESS_CACHED = 1 << 20,
|
const FREEZENESS_CACHED = 1 << 20,
|
||||||
const IS_FREEZE = 1 << 21,
|
const IS_FREEZE = 1 << 21,
|
||||||
const NEEDS_DROP_CACHED = 1 << 22,
|
const NEEDS_DROP_CACHED = 1 << 22,
|
||||||
@ -1250,48 +1248,37 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// When type checking, we use the `ParameterEnvironment` to track
|
/// When type checking, we use the `ParameterEnvironment` to track
|
||||||
/// details about the type/lifetime parameters that are in scope.
|
/// details about the set of where-clauses that are in scope at this
|
||||||
/// It primarily stores the bounds information.
|
/// particular point.
|
||||||
///
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
/// Note: This information might seem to be redundant with the data in
|
|
||||||
/// `tcx.ty_param_defs`, but it is not. That table contains the
|
|
||||||
/// parameter definitions from an "outside" perspective, but this
|
|
||||||
/// struct will contain the bounds for a parameter as seen from inside
|
|
||||||
/// the function body. Currently the only real distinction is that
|
|
||||||
/// bound lifetime parameters are replaced with free ones, but in the
|
|
||||||
/// future I hope to refine the representation of types so as to make
|
|
||||||
/// more distinctions clearer.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ParameterEnvironment<'tcx> {
|
pub struct ParameterEnvironment<'tcx> {
|
||||||
/// Obligations that the caller must satisfy. This is basically
|
/// Obligations that the caller must satisfy. This is basically
|
||||||
/// the set of bounds on the in-scope type parameters, translated
|
/// the set of bounds on the in-scope type parameters, translated
|
||||||
/// into Obligations, and elaborated and normalized.
|
/// into Obligations, and elaborated and normalized.
|
||||||
pub caller_bounds: &'tcx [ty::Predicate<'tcx>],
|
pub caller_bounds: &'tcx Slice<ty::Predicate<'tcx>>,
|
||||||
|
|
||||||
/// A cache for `moves_by_default`.
|
|
||||||
pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
|
||||||
|
|
||||||
/// A cache for `type_is_sized`
|
|
||||||
pub is_sized_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
|
||||||
|
|
||||||
/// A cache for `type_is_freeze`
|
|
||||||
pub is_freeze_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
impl<'tcx> ParameterEnvironment<'tcx> {
|
||||||
pub fn with_caller_bounds(&self,
|
pub fn and<T>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> {
|
||||||
caller_bounds: &'tcx [ty::Predicate<'tcx>])
|
ParameterEnvironmentAnd {
|
||||||
-> ParameterEnvironment<'tcx>
|
param_env: self,
|
||||||
{
|
value: value,
|
||||||
ParameterEnvironment {
|
|
||||||
caller_bounds: caller_bounds,
|
|
||||||
is_copy_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_sized_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ParameterEnvironmentAnd<'tcx, T> {
|
||||||
|
pub param_env: ParameterEnvironment<'tcx>,
|
||||||
|
pub value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx, T> ParameterEnvironmentAnd<'tcx, T> {
|
||||||
|
pub fn into_parts(self) -> (ParameterEnvironment<'tcx>, T) {
|
||||||
|
(self.param_env, self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Destructor {
|
pub struct Destructor {
|
||||||
/// The def-id of the destructor method
|
/// The def-id of the destructor method
|
||||||
@ -2357,17 +2344,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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(self) -> ParameterEnvironment<'tcx> {
|
|
||||||
ty::ParameterEnvironment {
|
|
||||||
caller_bounds: Slice::empty(),
|
|
||||||
is_copy_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_sized_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See `ParameterEnvironment` struct def'n for details.
|
/// See `ParameterEnvironment` struct def'n for details.
|
||||||
pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> {
|
pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> {
|
||||||
//
|
//
|
||||||
@ -2391,12 +2367,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// sure that this will succeed without errors anyway.
|
// sure that this will succeed without errors anyway.
|
||||||
//
|
//
|
||||||
|
|
||||||
let unnormalized_env = ty::ParameterEnvironment {
|
let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates));
|
||||||
caller_bounds: tcx.intern_predicates(&predicates),
|
|
||||||
is_copy_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_sized_cache: RefCell::new(FxHashMap()),
|
|
||||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |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)
|
self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
|
||||||
@ -2566,6 +2537,7 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
|
|||||||
|
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::maps::Providers) {
|
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||||
|
util::provide(providers);
|
||||||
*providers = ty::maps::Providers {
|
*providers = ty::maps::Providers {
|
||||||
associated_item,
|
associated_item,
|
||||||
associated_item_def_ids,
|
associated_item_def_ids,
|
||||||
|
@ -15,20 +15,19 @@ use hir::map::DefPathData;
|
|||||||
use infer::InferCtxt;
|
use infer::InferCtxt;
|
||||||
use ich::{StableHashingContext, NodeIdHashingMode};
|
use ich::{StableHashingContext, NodeIdHashingMode};
|
||||||
use traits::{self, Reveal};
|
use traits::{self, Reveal};
|
||||||
use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
|
use ty::{self, Ty, TyCtxt, TypeFlags, TypeFoldable};
|
||||||
use ty::ParameterEnvironment;
|
use ty::ParameterEnvironment;
|
||||||
use ty::fold::TypeVisitor;
|
use ty::fold::TypeVisitor;
|
||||||
use ty::layout::{Layout, LayoutError};
|
use ty::layout::{Layout, LayoutError};
|
||||||
use ty::subst::{Subst, Kind};
|
use ty::subst::{Subst, Kind};
|
||||||
use ty::TypeVariants::*;
|
use ty::TypeVariants::*;
|
||||||
use util::common::ErrorReported;
|
use util::common::ErrorReported;
|
||||||
use util::nodemap::{FxHashMap, FxHashSet};
|
use util::nodemap::FxHashSet;
|
||||||
use middle::lang_items;
|
use middle::lang_items;
|
||||||
|
|
||||||
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
|
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
|
||||||
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
|
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
|
||||||
HashStable};
|
HashStable};
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::intrinsics;
|
use std::intrinsics;
|
||||||
@ -36,8 +35,6 @@ use syntax::ast::{self, Name};
|
|||||||
use syntax::attr::{self, SignedInt, UnsignedInt};
|
use syntax::attr::{self, SignedInt, UnsignedInt};
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use hir;
|
|
||||||
|
|
||||||
type Disr = ConstInt;
|
type Disr = ConstInt;
|
||||||
|
|
||||||
pub trait IntTypeExt {
|
pub trait IntTypeExt {
|
||||||
@ -153,6 +150,17 @@ pub enum Representability {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ParameterEnvironment<'tcx> {
|
impl<'tcx> ParameterEnvironment<'tcx> {
|
||||||
|
/// Construct a trait environment suitable for contexts where
|
||||||
|
/// there are no where clauses in scope.
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self::new(ty::Slice::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a trait environment with the given set of predicates.
|
||||||
|
pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>) -> Self {
|
||||||
|
ty::ParameterEnvironment { caller_bounds }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn can_type_implement_copy<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
self_type: Ty<'tcx>, span: Span)
|
self_type: Ty<'tcx>, span: Span)
|
||||||
-> Result<(), CopyImplementationError> {
|
-> Result<(), CopyImplementationError> {
|
||||||
@ -711,152 +719,40 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ty::TyS<'tcx> {
|
impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn moves_by_default(&'tcx self,
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
def_id: DefId,
|
param_env: ParameterEnvironment<'tcx>,
|
||||||
cache: &RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
span: Span)
|
||||||
span: Span) -> bool
|
-> bool {
|
||||||
|
if self.has_param_types() || self.has_self_ty() {
|
||||||
|
!tcx.at(span).is_copy_raw(param_env.and(self))
|
||||||
|
} else {
|
||||||
|
!tcx.is_copy_raw(ParameterEnvironment::empty().and(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_sized(&'tcx self,
|
||||||
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
param_env: ParameterEnvironment<'tcx>,
|
||||||
|
span: Span)-> bool
|
||||||
{
|
{
|
||||||
if self.has_param_types() || self.has_self_ty() {
|
if self.has_param_types() || self.has_self_ty() {
|
||||||
if let Some(result) = cache.borrow().get(self) {
|
tcx.at(span).is_sized_raw(param_env.and(self))
|
||||||
return *result;
|
} else {
|
||||||
}
|
tcx.is_sized_raw(ParameterEnvironment::empty().and(self))
|
||||||
}
|
}
|
||||||
let result =
|
}
|
||||||
tcx.infer_ctxt(param_env.clone(), Reveal::UserFacing)
|
|
||||||
.enter(|infcx| {
|
pub fn is_freeze(&'tcx self,
|
||||||
traits::type_known_to_meet_bound(&infcx, self, def_id, span)
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
});
|
param_env: ParameterEnvironment<'tcx>,
|
||||||
|
span: Span)-> bool
|
||||||
|
{
|
||||||
if self.has_param_types() || self.has_self_ty() {
|
if self.has_param_types() || self.has_self_ty() {
|
||||||
cache.borrow_mut().insert(self, result);
|
tcx.at(span).is_freeze_raw(param_env.and(self))
|
||||||
|
} else {
|
||||||
|
tcx.is_freeze_raw(ParameterEnvironment::empty().and(self))
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME (@jroesch): I made this public to use it, not sure if should be private
|
|
||||||
pub fn moves_by_default(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
|
||||||
span: Span) -> bool {
|
|
||||||
if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
|
|
||||||
return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(!self.needs_infer());
|
|
||||||
|
|
||||||
// Fast-path for primitive types
|
|
||||||
let result = match self.sty {
|
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyNever |
|
|
||||||
TyRawPtr(..) | TyFnDef(..) | TyFnPtr(_) | TyRef(_, TypeAndMut {
|
|
||||||
mutbl: hir::MutImmutable, ..
|
|
||||||
}) => Some(false),
|
|
||||||
|
|
||||||
TyStr | TyRef(_, TypeAndMut {
|
|
||||||
mutbl: hir::MutMutable, ..
|
|
||||||
}) => Some(true),
|
|
||||||
|
|
||||||
TyArray(..) | TySlice(..) | TyDynamic(..) | TyTuple(..) |
|
|
||||||
TyClosure(..) | TyAdt(..) | TyAnon(..) |
|
|
||||||
TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
|
|
||||||
}.unwrap_or_else(|| {
|
|
||||||
!self.impls_bound(tcx, param_env,
|
|
||||||
tcx.require_lang_item(lang_items::CopyTraitLangItem),
|
|
||||||
¶m_env.is_copy_cache, span) });
|
|
||||||
|
|
||||||
if !self.has_param_types() && !self.has_self_ty() {
|
|
||||||
self.flags.set(self.flags.get() | if result {
|
|
||||||
TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
|
|
||||||
} else {
|
|
||||||
TypeFlags::MOVENESS_CACHED
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_sized(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
|
||||||
span: Span) -> bool
|
|
||||||
{
|
|
||||||
if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
|
|
||||||
return self.flags.get().intersects(TypeFlags::IS_SIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.is_sized_uncached(tcx, param_env, span)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_sized_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
|
||||||
span: Span) -> bool {
|
|
||||||
assert!(!self.needs_infer());
|
|
||||||
|
|
||||||
// Fast-path for primitive types
|
|
||||||
let result = match self.sty {
|
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
|
||||||
TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
|
||||||
TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true),
|
|
||||||
|
|
||||||
TyStr | TyDynamic(..) | TySlice(_) => Some(false),
|
|
||||||
|
|
||||||
TyAdt(..) | TyProjection(..) | TyParam(..) |
|
|
||||||
TyInfer(..) | TyAnon(..) | TyError => None
|
|
||||||
}.unwrap_or_else(|| {
|
|
||||||
self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::SizedTraitLangItem),
|
|
||||||
¶m_env.is_sized_cache, span) });
|
|
||||||
|
|
||||||
if !self.has_param_types() && !self.has_self_ty() {
|
|
||||||
self.flags.set(self.flags.get() | if result {
|
|
||||||
TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
|
|
||||||
} else {
|
|
||||||
TypeFlags::SIZEDNESS_CACHED
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if and only if there are no `UnsafeCell`s
|
|
||||||
/// nested within the type (ignoring `PhantomData` or pointers).
|
|
||||||
#[inline]
|
|
||||||
pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
|
||||||
span: Span) -> bool
|
|
||||||
{
|
|
||||||
if self.flags.get().intersects(TypeFlags::FREEZENESS_CACHED) {
|
|
||||||
return self.flags.get().intersects(TypeFlags::IS_FREEZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.is_freeze_uncached(tcx, param_env, span)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
param_env: &ParameterEnvironment<'tcx>,
|
|
||||||
span: Span) -> bool {
|
|
||||||
assert!(!self.needs_infer());
|
|
||||||
|
|
||||||
// Fast-path for primitive types
|
|
||||||
let result = match self.sty {
|
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
|
||||||
TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
|
||||||
TyStr | TyNever => Some(true),
|
|
||||||
|
|
||||||
TyArray(..) | TySlice(_) |
|
|
||||||
TyTuple(..) | TyClosure(..) | TyAdt(..) |
|
|
||||||
TyDynamic(..) | TyProjection(..) | TyParam(..) |
|
|
||||||
TyInfer(..) | TyAnon(..) | TyError => None
|
|
||||||
}.unwrap_or_else(|| {
|
|
||||||
self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::FreezeTraitLangItem),
|
|
||||||
¶m_env.is_freeze_cache, span) });
|
|
||||||
|
|
||||||
if !self.has_param_types() && !self.has_self_ty() {
|
|
||||||
self.flags.set(self.flags.get() | if result {
|
|
||||||
TypeFlags::FREEZENESS_CACHED | TypeFlags::IS_FREEZE
|
|
||||||
} else {
|
|
||||||
TypeFlags::FREEZENESS_CACHED
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
|
/// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
|
||||||
@ -866,8 +762,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
/// (Note that this implies that if `ty` has a destructor attached,
|
/// (Note that this implies that if `ty` has a destructor attached,
|
||||||
/// then `needs_drop` will definitely return `true` for `ty`.)
|
/// then `needs_drop` will definitely return `true` for `ty`.)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn needs_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn needs_drop(&'tcx self,
|
||||||
param_env: &ty::ParameterEnvironment<'tcx>) -> bool {
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
param_env: ty::ParameterEnvironment<'tcx>)
|
||||||
|
-> bool {
|
||||||
if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
|
if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
|
||||||
return self.flags.get().intersects(TypeFlags::NEEDS_DROP);
|
return self.flags.get().intersects(TypeFlags::NEEDS_DROP);
|
||||||
}
|
}
|
||||||
@ -877,7 +775,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
|
|
||||||
fn needs_drop_inner(&'tcx self,
|
fn needs_drop_inner(&'tcx self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
param_env: ty::ParameterEnvironment<'tcx>,
|
||||||
stack: &mut FxHashSet<Ty<'tcx>>)
|
stack: &mut FxHashSet<Ty<'tcx>>)
|
||||||
-> bool {
|
-> bool {
|
||||||
if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
|
if self.flags.get().intersects(TypeFlags::NEEDS_DROP_CACHED) {
|
||||||
@ -902,7 +800,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
|
|
||||||
fn needs_drop_uncached(&'tcx self,
|
fn needs_drop_uncached(&'tcx self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
param_env: ty::ParameterEnvironment<'tcx>,
|
||||||
stack: &mut FxHashSet<Ty<'tcx>>)
|
stack: &mut FxHashSet<Ty<'tcx>>)
|
||||||
-> bool {
|
-> bool {
|
||||||
assert!(!self.needs_infer());
|
assert!(!self.needs_infer());
|
||||||
@ -1158,3 +1056,42 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||||||
r
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_copy_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>)
|
||||||
|
-> bool
|
||||||
|
{
|
||||||
|
let (param_env, ty) = query.into_parts();
|
||||||
|
let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem);
|
||||||
|
tcx.infer_ctxt(param_env, Reveal::UserFacing)
|
||||||
|
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>)
|
||||||
|
-> bool
|
||||||
|
{
|
||||||
|
let (param_env, ty) = query.into_parts();
|
||||||
|
let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem);
|
||||||
|
tcx.infer_ctxt(param_env, Reveal::UserFacing)
|
||||||
|
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
query: ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>)
|
||||||
|
-> bool
|
||||||
|
{
|
||||||
|
let (param_env, ty) = query.into_parts();
|
||||||
|
let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem);
|
||||||
|
tcx.infer_ctxt(param_env, Reveal::UserFacing)
|
||||||
|
.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||||
|
*providers = ty::maps::Providers {
|
||||||
|
is_copy_raw,
|
||||||
|
is_sized_raw,
|
||||||
|
is_freeze_raw,
|
||||||
|
..*providers
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -504,13 +504,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
|
impl fmt::Display for ty::RegionKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "ParameterEnvironment({:?})", self.caller_bounds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> fmt::Display for ty::RegionKind {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if verbose() {
|
if verbose() {
|
||||||
return write!(f, "{:?}", *self);
|
return write!(f, "{:?}", *self);
|
||||||
|
@ -45,7 +45,7 @@ impl MirPass for ElaborateDrops {
|
|||||||
}
|
}
|
||||||
let id = src.item_id();
|
let id = src.item_id();
|
||||||
let param_env = tcx.parameter_environment(tcx.hir.local_def_id(id));
|
let param_env = tcx.parameter_environment(tcx.hir.local_def_id(id));
|
||||||
let move_data = MoveData::gather_moves(mir, tcx, ¶m_env);
|
let move_data = MoveData::gather_moves(mir, tcx, param_env);
|
||||||
let elaborate_patch = {
|
let elaborate_patch = {
|
||||||
let mir = &*mir;
|
let mir = &*mir;
|
||||||
let env = MoveDataParamEnv {
|
let env = MoveDataParamEnv {
|
||||||
@ -196,7 +196,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
|||||||
self.ctxt.tcx
|
self.ctxt.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> {
|
fn param_env(&self) -> ty::ParameterEnvironment<'tcx> {
|
||||||
self.ctxt.param_env()
|
self.ctxt.param_env()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,8 +289,9 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
|
|||||||
|
|
||||||
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data }
|
fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data }
|
||||||
fn param_env(&self) -> &'b ty::ParameterEnvironment<'tcx> {
|
|
||||||
&self.env.param_env
|
fn param_env(&self) -> ty::ParameterEnvironment<'tcx> {
|
||||||
|
self.env.param_env
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialization_data_at(&self, loc: Location) -> InitializationData {
|
fn initialization_data_at(&self, loc: Location) -> InitializationData {
|
||||||
|
@ -191,7 +191,7 @@ pub struct MovePathLookup<'tcx> {
|
|||||||
struct MoveDataBuilder<'a, 'tcx: 'a> {
|
struct MoveDataBuilder<'a, 'tcx: 'a> {
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &'a ParameterEnvironment<'tcx>,
|
param_env: ParameterEnvironment<'tcx>,
|
||||||
data: MoveData<'tcx>,
|
data: MoveData<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ pub enum MovePathError {
|
|||||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||||
fn new(mir: &'a Mir<'tcx>,
|
fn new(mir: &'a Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &'a ParameterEnvironment<'tcx>)
|
param_env: ParameterEnvironment<'tcx>)
|
||||||
-> Self {
|
-> Self {
|
||||||
let mut move_paths = IndexVec::new();
|
let mut move_paths = IndexVec::new();
|
||||||
let mut path_map = IndexVec::new();
|
let mut path_map = IndexVec::new();
|
||||||
@ -370,7 +370,7 @@ impl<'tcx> MovePathLookup<'tcx> {
|
|||||||
impl<'a, 'tcx> MoveData<'tcx> {
|
impl<'a, 'tcx> MoveData<'tcx> {
|
||||||
pub fn gather_moves(mir: &Mir<'tcx>,
|
pub fn gather_moves(mir: &Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ParameterEnvironment<'tcx>)
|
param_env: ParameterEnvironment<'tcx>)
|
||||||
-> Self {
|
-> Self {
|
||||||
gather_moves(mir, tcx, param_env)
|
gather_moves(mir, tcx, param_env)
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ impl<'a, 'tcx> MoveData<'tcx> {
|
|||||||
|
|
||||||
fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
|
fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ParameterEnvironment<'tcx>)
|
param_env: ParameterEnvironment<'tcx>)
|
||||||
-> MoveData<'tcx> {
|
-> MoveData<'tcx> {
|
||||||
let mut builder = MoveDataBuilder::new(mir, tcx, param_env);
|
let mut builder = MoveDataBuilder::new(mir, tcx, param_env);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
|
|||||||
let mir = &tcx.mir_validated(def_id).borrow();
|
let mir = &tcx.mir_validated(def_id).borrow();
|
||||||
|
|
||||||
let param_env = tcx.parameter_environment(def_id);
|
let param_env = tcx.parameter_environment(def_id);
|
||||||
let move_data = MoveData::gather_moves(mir, tcx, ¶m_env);
|
let move_data = MoveData::gather_moves(mir, tcx, param_env);
|
||||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||||
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
||||||
let flow_inits =
|
let flow_inits =
|
||||||
@ -325,7 +325,7 @@ fn on_all_drop_children_bits<'a, 'tcx, F>(
|
|||||||
let ty = lvalue.ty(mir, tcx).to_ty(tcx);
|
let ty = lvalue.ty(mir, tcx).to_ty(tcx);
|
||||||
debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, lvalue, ty);
|
debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, lvalue, ty);
|
||||||
|
|
||||||
if ty.needs_drop(tcx, &ctxt.param_env) {
|
if ty.needs_drop(tcx, ctxt.param_env) {
|
||||||
each_child(child);
|
each_child(child);
|
||||||
} else {
|
} else {
|
||||||
debug!("on_all_drop_children_bits - skipping")
|
debug!("on_all_drop_children_bits - skipping")
|
||||||
@ -359,7 +359,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
|
|||||||
where F: FnMut(MovePathIndex, DropFlagState)
|
where F: FnMut(MovePathIndex, DropFlagState)
|
||||||
{
|
{
|
||||||
let move_data = &ctxt.move_data;
|
let move_data = &ctxt.move_data;
|
||||||
let param_env = &ctxt.param_env;
|
let param_env = ctxt.param_env;
|
||||||
debug!("drop_flag_effects_for_location({:?})", loc);
|
debug!("drop_flag_effects_for_location({:?})", loc);
|
||||||
|
|
||||||
// first, move out of the RHS
|
// first, move out of the RHS
|
||||||
|
@ -52,7 +52,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
|
|||||||
tcx: self.tcx,
|
tcx: self.tcx,
|
||||||
tables: self.tcx.body_tables(b),
|
tables: self.tcx.body_tables(b),
|
||||||
region_maps: &self.tcx.region_maps(def_id),
|
region_maps: &self.tcx.region_maps(def_id),
|
||||||
param_env: &self.tcx.parameter_environment(def_id)
|
param_env: self.tcx.parameter_environment(def_id)
|
||||||
}.visit_body(self.tcx.hir.body(b));
|
}.visit_body(self.tcx.hir.body(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn
|
|||||||
struct MatchVisitor<'a, 'tcx: 'a> {
|
struct MatchVisitor<'a, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
param_env: &'a ty::ParameterEnvironment<'tcx>,
|
param_env: ty::ParameterEnvironment<'tcx>,
|
||||||
region_maps: &'a RegionMaps,
|
region_maps: &'a RegionMaps,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
|
|||||||
///
|
///
|
||||||
/// FIXME: this should be done by borrowck.
|
/// FIXME: this should be done by borrowck.
|
||||||
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
|
fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
|
||||||
cx.tcx.infer_ctxt((cx.tables, cx.param_env.clone()), Reveal::UserFacing).enter(|infcx| {
|
cx.tcx.infer_ctxt((cx.tables, cx.param_env), Reveal::UserFacing).enter(|infcx| {
|
||||||
let mut checker = MutationChecker {
|
let mut checker = MutationChecker {
|
||||||
cx: cx,
|
cx: cx,
|
||||||
};
|
};
|
||||||
|
@ -527,13 +527,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
|
|||||||
if def.has_dtor(cx.tcx) {
|
if def.has_dtor(cx.tcx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let parameter_environment = cx.tcx.empty_parameter_environment();
|
let param_env = ty::ParameterEnvironment::empty();
|
||||||
// FIXME (@jroesch) should probably inver this so that the parameter env still impls this
|
if !ty.moves_by_default(cx.tcx, param_env, item.span) {
|
||||||
// method
|
|
||||||
if !ty.moves_by_default(cx.tcx, ¶meter_environment, item.span) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if parameter_environment.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() {
|
if param_env.can_type_implement_copy(cx.tcx, ty, item.span).is_ok() {
|
||||||
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
|
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
|
||||||
item.span,
|
item.span,
|
||||||
"type could implement `Copy`; consider adding `impl \
|
"type could implement `Copy`; consider adding `impl \
|
||||||
@ -1258,7 +1256,8 @@ impl LintPass for UnionsWithDropFields {
|
|||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
|
||||||
fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
|
fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
|
||||||
if let hir::ItemUnion(ref vdata, _) = item.node {
|
if let hir::ItemUnion(ref vdata, _) = item.node {
|
||||||
let param_env = &ctx.tcx.parameter_environment(ctx.tcx.hir.local_def_id(item.id));
|
let item_def_id = ctx.tcx.hir.local_def_id(item.id);
|
||||||
|
let param_env = ctx.tcx.parameter_environment(item_def_id);
|
||||||
for field in vdata.fields() {
|
for field in vdata.fields() {
|
||||||
let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id));
|
let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id));
|
||||||
if field_ty.needs_drop(ctx.tcx, param_env) {
|
if field_ty.needs_drop(ctx.tcx, param_env) {
|
||||||
|
@ -168,7 +168,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
|||||||
type with inference types/regions",
|
type with inference types/regions",
|
||||||
ty);
|
ty);
|
||||||
});
|
});
|
||||||
ty.needs_drop(self.tcx.global_tcx(), &self.infcx.parameter_environment)
|
ty.needs_drop(self.tcx.global_tcx(), self.infcx.parameter_environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
|
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
@ -40,8 +40,6 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
-> &'tcx Mir<'tcx>
|
-> &'tcx Mir<'tcx>
|
||||||
{
|
{
|
||||||
debug!("make_shim({:?})", instance);
|
debug!("make_shim({:?})", instance);
|
||||||
let did = instance.def_id();
|
|
||||||
let param_env = tcx.parameter_environment(did);
|
|
||||||
|
|
||||||
let mut result = match instance {
|
let mut result = match instance {
|
||||||
ty::InstanceDef::Item(..) =>
|
ty::InstanceDef::Item(..) =>
|
||||||
@ -98,7 +96,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::InstanceDef::DropGlue(def_id, ty) => {
|
ty::InstanceDef::DropGlue(def_id, ty) => {
|
||||||
build_drop_shim(tcx, ¶m_env, def_id, ty)
|
build_drop_shim(tcx, def_id, ty)
|
||||||
}
|
}
|
||||||
ty::InstanceDef::Intrinsic(_) => {
|
ty::InstanceDef::Intrinsic(_) => {
|
||||||
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
|
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
|
||||||
@ -144,7 +142,6 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
ty: Option<Ty<'tcx>>)
|
ty: Option<Ty<'tcx>>)
|
||||||
-> Mir<'tcx>
|
-> Mir<'tcx>
|
||||||
@ -189,10 +186,12 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
if let Some(..) = ty {
|
if let Some(..) = ty {
|
||||||
let patch = {
|
let patch = {
|
||||||
|
let param_env = tcx.parameter_environment(def_id);
|
||||||
let mut elaborator = DropShimElaborator {
|
let mut elaborator = DropShimElaborator {
|
||||||
mir: &mir,
|
mir: &mir,
|
||||||
patch: MirPatch::new(&mir),
|
patch: MirPatch::new(&mir),
|
||||||
tcx, param_env
|
tcx,
|
||||||
|
param_env
|
||||||
};
|
};
|
||||||
let dropee = Lvalue::Local(Local::new(1+0)).deref();
|
let dropee = Lvalue::Local(Local::new(1+0)).deref();
|
||||||
let resume_block = elaborator.patch.resume_block();
|
let resume_block = elaborator.patch.resume_block();
|
||||||
@ -218,7 +217,7 @@ pub struct DropShimElaborator<'a, 'tcx: 'a> {
|
|||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
patch: MirPatch<'tcx>,
|
patch: MirPatch<'tcx>,
|
||||||
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &'a ty::ParameterEnvironment<'tcx>,
|
param_env: ty::ParameterEnvironment<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> {
|
impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> {
|
||||||
@ -233,7 +232,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
|
|||||||
fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
|
fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
|
||||||
fn mir(&self) -> &'a Mir<'tcx> { self.mir }
|
fn mir(&self) -> &'a Mir<'tcx> { self.mir }
|
||||||
fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
|
fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
|
||||||
fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx> { self.param_env }
|
fn param_env(&self) -> ty::ParameterEnvironment<'tcx> { self.param_env }
|
||||||
|
|
||||||
fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
|
fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
|
||||||
if let DropFlagMode::Shallow = mode {
|
if let DropFlagMode::Shallow = mode {
|
||||||
|
@ -253,7 +253,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||||||
// a regular goto.
|
// a regular goto.
|
||||||
let ty = location.ty(&callee_mir, tcx).subst(tcx, callsite.substs);
|
let ty = location.ty(&callee_mir, tcx).subst(tcx, callsite.substs);
|
||||||
let ty = ty.to_ty(tcx);
|
let ty = ty.to_ty(tcx);
|
||||||
if ty.needs_drop(tcx, ¶m_env) {
|
if ty.needs_drop(tcx, param_env) {
|
||||||
cost += CALL_PENALTY;
|
cost += CALL_PENALTY;
|
||||||
if let Some(unwind) = unwind {
|
if let Some(unwind) = unwind {
|
||||||
work_list.push(unwind);
|
work_list.push(unwind);
|
||||||
|
@ -78,7 +78,7 @@ impl<'a, 'tcx> Qualif {
|
|||||||
/// Remove flags which are impossible for the given type.
|
/// Remove flags which are impossible for the given type.
|
||||||
fn restrict(&mut self, ty: Ty<'tcx>,
|
fn restrict(&mut self, ty: Ty<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: &ty::ParameterEnvironment<'tcx>) {
|
param_env: ty::ParameterEnvironment<'tcx>) {
|
||||||
if ty.is_freeze(tcx, param_env, DUMMY_SP) {
|
if ty.is_freeze(tcx, param_env, DUMMY_SP) {
|
||||||
*self = *self - Qualif::MUTABLE_INTERIOR;
|
*self = *self - Qualif::MUTABLE_INTERIOR;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||||||
/// Add the given type's qualification to self.qualif.
|
/// Add the given type's qualification to self.qualif.
|
||||||
fn add_type(&mut self, ty: Ty<'tcx>) {
|
fn add_type(&mut self, ty: Ty<'tcx>) {
|
||||||
self.add(Qualif::MUTABLE_INTERIOR | Qualif::NEEDS_DROP);
|
self.add(Qualif::MUTABLE_INTERIOR | Qualif::NEEDS_DROP);
|
||||||
self.qualif.restrict(ty, self.tcx, &self.param_env);
|
self.qualif.restrict(ty, self.tcx, self.param_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Within the provided closure, self.qualif will start
|
/// Within the provided closure, self.qualif will start
|
||||||
@ -544,7 +544,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||||||
static, use a constant instead");
|
static, use a constant instead");
|
||||||
}
|
}
|
||||||
let ty = lvalue.ty(this.mir, this.tcx).to_ty(this.tcx);
|
let ty = lvalue.ty(this.mir, this.tcx).to_ty(this.tcx);
|
||||||
this.qualif.restrict(ty, this.tcx, &this.param_env);
|
this.qualif.restrict(ty, this.tcx, this.param_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectionElem::ConstantIndex {..} |
|
ProjectionElem::ConstantIndex {..} |
|
||||||
|
@ -56,7 +56,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
|
|||||||
fn patch(&mut self) -> &mut MirPatch<'tcx>;
|
fn patch(&mut self) -> &mut MirPatch<'tcx>;
|
||||||
fn mir(&self) -> &'a Mir<'tcx>;
|
fn mir(&self) -> &'a Mir<'tcx>;
|
||||||
fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx>;
|
fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx>;
|
||||||
fn param_env(&self) -> &'a ty::ParameterEnvironment<'tcx>;
|
fn param_env(&self) -> ty::ParameterEnvironment<'tcx>;
|
||||||
|
|
||||||
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle;
|
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle;
|
||||||
fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>>;
|
fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>>;
|
||||||
|
@ -38,7 +38,7 @@ use rustc::middle::expr_use_visitor as euv;
|
|||||||
use rustc::middle::mem_categorization as mc;
|
use rustc::middle::mem_categorization as mc;
|
||||||
use rustc::middle::mem_categorization::Categorization;
|
use rustc::middle::mem_categorization::Categorization;
|
||||||
use rustc::mir::transform::MirSource;
|
use rustc::mir::transform::MirSource;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt};
|
||||||
use rustc::traits::Reveal;
|
use rustc::traits::Reveal;
|
||||||
use rustc::util::common::ErrorReported;
|
use rustc::util::common::ErrorReported;
|
||||||
use rustc::util::nodemap::NodeSet;
|
use rustc::util::nodemap::NodeSet;
|
||||||
@ -85,11 +85,11 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
|||||||
|
|
||||||
// Adds the worst effect out of all the values of one type.
|
// Adds the worst effect out of all the values of one type.
|
||||||
fn add_type(&mut self, ty: Ty<'gcx>) {
|
fn add_type(&mut self, ty: Ty<'gcx>) {
|
||||||
if !ty.is_freeze(self.tcx, &self.param_env, DUMMY_SP) {
|
if !ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
|
||||||
self.promotable = false;
|
self.promotable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ty.needs_drop(self.tcx, &self.param_env) {
|
if ty.needs_drop(self.tcx, self.param_env) {
|
||||||
self.promotable = false;
|
self.promotable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||||||
in_fn: false,
|
in_fn: false,
|
||||||
promotable: false,
|
promotable: false,
|
||||||
mut_rvalue_borrows: NodeSet(),
|
mut_rvalue_borrows: NodeSet(),
|
||||||
param_env: tcx.empty_parameter_environment(),
|
param_env: ParameterEnvironment::empty(),
|
||||||
}.as_deep_visitor());
|
}.as_deep_visitor());
|
||||||
tcx.sess.abort_if_errors();
|
tcx.sess.abort_if_errors();
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ use partitioning::CodegenUnit;
|
|||||||
use type_::Type;
|
use type_::Type;
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, ParameterEnvironment, Ty, TyCtxt};
|
||||||
use rustc::ty::layout::{LayoutTyper, TyLayout};
|
use rustc::ty::layout::{LayoutTyper, TyLayout};
|
||||||
use session::config::NoDebugInfo;
|
use session::config::NoDebugInfo;
|
||||||
use session::Session;
|
use session::Session;
|
||||||
@ -79,7 +79,6 @@ impl Stats {
|
|||||||
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||||
exported_symbols: NodeSet,
|
exported_symbols: NodeSet,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
empty_param_env: ty::ParameterEnvironment<'tcx>,
|
|
||||||
check_overflow: bool,
|
check_overflow: bool,
|
||||||
|
|
||||||
use_dll_storage_attrs: bool,
|
use_dll_storage_attrs: bool,
|
||||||
@ -315,7 +314,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||||||
|
|
||||||
SharedCrateContext {
|
SharedCrateContext {
|
||||||
exported_symbols: exported_symbols,
|
exported_symbols: exported_symbols,
|
||||||
empty_param_env: tcx.empty_parameter_environment(),
|
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
check_overflow: check_overflow,
|
check_overflow: check_overflow,
|
||||||
use_dll_storage_attrs: use_dll_storage_attrs,
|
use_dll_storage_attrs: use_dll_storage_attrs,
|
||||||
@ -323,15 +321,15 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.needs_drop(self.tcx, &self.empty_param_env)
|
ty.needs_drop(self.tcx, ParameterEnvironment::empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.is_sized(self.tcx, &self.empty_param_env, DUMMY_SP)
|
ty.is_sized(self.tcx, ParameterEnvironment::empty(), DUMMY_SP)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.is_freeze(self.tcx, &self.empty_param_env, DUMMY_SP)
|
ty.is_freeze(self.tcx, ParameterEnvironment::empty(), DUMMY_SP)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
|
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
|
||||||
|
@ -165,10 +165,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// Finally we register each of these predicates as an obligation in
|
// Finally we register each of these predicates as an obligation in
|
||||||
// a fresh FulfillmentCtxt, and invoke select_all_or_error.
|
// a fresh FulfillmentCtxt, and invoke select_all_or_error.
|
||||||
|
|
||||||
// Create a parameter environment that represents the implementation's
|
|
||||||
// method.
|
|
||||||
let impl_param_env = tcx.parameter_environment(impl_m.def_id);
|
|
||||||
|
|
||||||
// Create mapping from impl to skolemized.
|
// Create mapping from impl to skolemized.
|
||||||
let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id);
|
let impl_to_skol_substs = Substs::identity_for_item(tcx, impl_m.def_id);
|
||||||
|
|
||||||
@ -216,14 +212,13 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// The key step here is to update the caller_bounds's predicates to be
|
// The key step here is to update the caller_bounds's predicates to be
|
||||||
// the new hybrid bounds we computed.
|
// the new hybrid bounds we computed.
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
|
||||||
let trait_param_env = impl_param_env.with_caller_bounds(
|
let param_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&hybrid_preds.predicates));
|
||||||
tcx.intern_predicates(&hybrid_preds.predicates));
|
let param_env = traits::normalize_param_env_or_error(tcx,
|
||||||
let trait_param_env = traits::normalize_param_env_or_error(tcx,
|
impl_m.def_id,
|
||||||
impl_m.def_id,
|
param_env,
|
||||||
trait_param_env,
|
normalize_cause.clone());
|
||||||
normalize_cause.clone());
|
|
||||||
|
|
||||||
tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| {
|
tcx.infer_ctxt(param_env, Reveal::UserFacing).enter(|infcx| {
|
||||||
let inh = Inherited::new(infcx, impl_m.def_id);
|
let inh = Inherited::new(infcx, impl_m.def_id);
|
||||||
let infcx = &inh.infcx;
|
let infcx = &inh.infcx;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user