refactor common logic into ParameterEnvironment::and()

This commit is contained in:
Niko Matsakis 2017-05-12 11:44:00 -04:00
parent 194d4bc15d
commit 5a5c265e24
2 changed files with 30 additions and 19 deletions

View File

@ -1259,11 +1259,34 @@ pub struct ParameterEnvironment<'tcx> {
} }
impl<'tcx> ParameterEnvironment<'tcx> { impl<'tcx> ParameterEnvironment<'tcx> {
pub fn and<T>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { /// Creates a suitable environment in which to perform trait
/// queries on the given value. This will either be `self` *or*
/// the empty environment, depending on whether `value` references
/// type parameters that are in scope. (If it doesn't, then any
/// judgements should be completely independent of the context,
/// and hence we can safely use the empty environment so as to
/// enable more sharing across functions.)
///
/// NB: This is a mildly dubious thing to do, in that a function
/// (or other environment) might have wacky where-clauses like
/// `where Box<u32>: Copy`, which are clearly never
/// satisfiable. The code will at present ignore these,
/// effectively, when type-checking the body of said
/// function. This preserves existing behavior in any
/// case. --nmatsakis
pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> {
assert!(!value.needs_infer());
if value.has_param_types() || value.has_self_ty() {
ParameterEnvironmentAnd { ParameterEnvironmentAnd {
param_env: self, param_env: self,
value: value, value: value,
} }
} else {
ParameterEnvironmentAnd {
param_env: ParameterEnvironment::empty(),
value: value,
}
}
} }
} }

View File

@ -724,11 +724,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
param_env: ParameterEnvironment<'tcx>, param_env: ParameterEnvironment<'tcx>,
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)) !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, pub fn is_sized(&'tcx self,
@ -736,11 +732,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
param_env: ParameterEnvironment<'tcx>, param_env: ParameterEnvironment<'tcx>,
span: Span)-> bool span: Span)-> bool
{ {
if self.has_param_types() || self.has_self_ty() {
tcx.at(span).is_sized_raw(param_env.and(self)) tcx.at(span).is_sized_raw(param_env.and(self))
} else {
tcx.is_sized_raw(ParameterEnvironment::empty().and(self))
}
} }
pub fn is_freeze(&'tcx self, pub fn is_freeze(&'tcx self,
@ -748,11 +740,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
param_env: ParameterEnvironment<'tcx>, param_env: ParameterEnvironment<'tcx>,
span: Span)-> bool span: Span)-> bool
{ {
if self.has_param_types() || self.has_self_ty() {
tcx.at(span).is_freeze_raw(param_env.and(self)) tcx.at(span).is_freeze_raw(param_env.and(self))
} else {
tcx.is_freeze_raw(ParameterEnvironment::empty().and(self))
}
} }
/// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely