impl<'tcx> RegionParameterDef<'tcx> {
pub fn to_early_bound_region(&self) -> ty::Region {
- ty::ReEarlyBound(ty::EarlyBoundRegion {
+ ty::ReEarlyBound(self.to_early_bound_region_data())
+ }
+
+ pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
+ ty::EarlyBoundRegion {
index: self.index,
name: self.name,
- })
+ }
}
+
pub fn to_bound_region(&self) -> ty::BoundRegion {
// this is an early bound region, so unaffected by #32330
ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)
let variances = self.tcx().item_variances(item_def_id);
let mut constrained_parameters: FnvHashSet<_> =
- variances[ast_generics.lifetimes.len()..]
- .iter().enumerate()
+ variances.iter().enumerate()
.filter(|&(_, &variance)| variance != ty::Bivariant)
- .map(|(index, _)| self.param_ty(ast_generics, index))
- .map(|p| Parameter::Type(p))
+ .map(|(index, _)| Parameter(index as u32))
.collect();
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
None,
&mut constrained_parameters);
- for (index, &variance) in variances.iter().enumerate() {
- let (span, name) = if index < ast_generics.lifetimes.len() {
- if variance != ty::Bivariant {
- continue;
- }
+ for (index, _) in variances.iter().enumerate() {
+ if constrained_parameters.contains(&Parameter(index as u32)) {
+ continue;
+ }
+ let (span, name) = if index < ast_generics.lifetimes.len() {
(ast_generics.lifetimes[index].lifetime.span,
ast_generics.lifetimes[index].lifetime.name)
} else {
- let index = index - ast_generics.lifetimes.len();
- let param_ty = self.param_ty(ast_generics, index);
- if constrained_parameters.contains(&Parameter::Type(param_ty)) {
- continue;
- }
- (ast_generics.ty_params[index].span, param_ty.name)
+ (ast_generics.ty_params[index].span,
+ ast_generics.ty_params[index].name)
};
self.report_bivariance(span, name);
}
}
- fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
- ty::ParamTy {
- idx: index as u32,
- name: ast_generics.ty_params[index].name
- }
- }
-
fn report_bivariance(&self,
span: Span,
param_name: ast::Name)
let ty_generics = generics_of_def_id(ccx, impl_def_id);
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
let param_ty = ty::ParamTy::for_def(ty_param);
- if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
+ if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string());
}
}
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
})
.flat_map(|ty| ctp::parameters_for(&ty, true))
- .filter_map(|p| match p {
- ctp::Parameter::Type(_) => None,
- ctp::Parameter::Region(r) => Some(r),
- })
.collect();
- for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
- let region = ty::EarlyBoundRegion {
- index: index as u32,
- name: lifetime_def.lifetime.name
- };
+ for (ty_lifetime, lifetime) in impl_scheme.generics.regions.iter()
+ .zip(&ast_generics.lifetimes)
+ {
+ let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
+
if
- lifetimes_in_associated_types.contains(®ion) && // (*)
- !input_parameters.contains(&ctp::Parameter::Region(region))
+ lifetimes_in_associated_types.contains(¶m) && // (*)
+ !input_parameters.contains(¶m)
{
- report_unused_parameter(ccx, lifetime_def.lifetime.span,
- "lifetime", ®ion.name.to_string());
+ report_unused_parameter(ccx, lifetime.lifetime.span,
+ "lifetime", &lifetime.lifetime.name.to_string());
}
}
use rustc::util::nodemap::FnvHashSet;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub enum Parameter {
- Type(ty::ParamTy),
- Region(ty::EarlyBoundRegion),
+pub struct Parameter(pub u32);
+
+impl From<ty::ParamTy> for Parameter {
+ fn from(param: ty::ParamTy) -> Self { Parameter(param.idx) }
+}
+
+impl From<ty::EarlyBoundRegion> for Parameter {
+ fn from(param: ty::EarlyBoundRegion) -> Self { Parameter(param.index) }
}
/// If `include_projections` is false, returns the list of parameters that are
// projections are not injective
return false;
}
- ty::TyParam(ref d) => {
- self.parameters.push(Parameter::Type(d.clone()));
+ ty::TyParam(data) => {
+ self.parameters.push(Parameter::from(data));
}
_ => {}
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
match *r {
ty::ReEarlyBound(data) => {
- self.parameters.push(Parameter::Region(data));
+ self.parameters.push(Parameter::from(data));
}
_ => {}
}
// * <U as Iterator>::Item = T
// * T: Debug
// * U: Iterator
+ debug!("setup_constraining_predicates: predicates={:?} \
+ impl_trait_ref={:?} input_parameters={:?}",
+ predicates, impl_trait_ref, input_parameters);
let mut i = 0;
let mut changed = true;
while changed {
changed = false;
for j in i..predicates.len() {
-
if let ty::Predicate::Projection(ref poly_projection) = predicates[j] {
// Note that we can skip binder here because the impl
// trait ref never contains any late-bound regions.
i += 1;
changed = true;
}
+ debug!("setup_constraining_predicates: predicates={:?} \
+ i={} impl_trait_ref={:?} input_parameters={:?}",
+ predicates, i, impl_trait_ref, input_parameters);
}
}
--- /dev/null
+// Copyright 2016 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.
+
+trait DeclarationParser {
+ type Declaration;
+}
+
+struct DeclarationListParser<'i, I, P>
+ where P: DeclarationParser<Declaration = I>
+{
+ input: &'i (),
+ parser: P
+}
+
+fn main() {}