From 5a5c265e24cc79a8e28f01930380cb8a2481165c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 11:44:00 -0400 Subject: [PATCH] refactor common logic into `ParameterEnvironment::and()` --- src/librustc/ty/mod.rs | 31 +++++++++++++++++++++++++++---- src/librustc/ty/util.rs | 18 +++--------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 1071fa1c0f6..8264809e9c9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1259,10 +1259,33 @@ pub struct ParameterEnvironment<'tcx> { } impl<'tcx> ParameterEnvironment<'tcx> { - pub fn and(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { - ParameterEnvironmentAnd { - param_env: self, - value: value, + /// 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: 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>(self, value: T) -> ParameterEnvironmentAnd<'tcx, T> { + assert!(!value.needs_infer()); + if value.has_param_types() || value.has_self_ty() { + ParameterEnvironmentAnd { + param_env: self, + value: value, + } + } else { + ParameterEnvironmentAnd { + param_env: ParameterEnvironment::empty(), + value: value, + } } } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index b9276281a54..da2552d37e2 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -724,11 +724,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span) -> 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)) - } + !tcx.at(span).is_copy_raw(param_env.and(self)) } pub fn is_sized(&'tcx self, @@ -736,11 +732,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span)-> bool { - if self.has_param_types() || self.has_self_ty() { - tcx.at(span).is_sized_raw(param_env.and(self)) - } else { - tcx.is_sized_raw(ParameterEnvironment::empty().and(self)) - } + tcx.at(span).is_sized_raw(param_env.and(self)) } pub fn is_freeze(&'tcx self, @@ -748,11 +740,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { param_env: ParameterEnvironment<'tcx>, span: Span)-> bool { - if self.has_param_types() || self.has_self_ty() { - tcx.at(span).is_freeze_raw(param_env.and(self)) - } else { - tcx.is_freeze_raw(ParameterEnvironment::empty().and(self)) - } + tcx.at(span).is_freeze_raw(param_env.and(self)) } /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely