Skip to content

Commit dd72b6b

Browse files
committed
fix broken type parameter indexing logic in wfcheck
Fixes #36075
1 parent 86dde9b commit dd72b6b

File tree

5 files changed

+65
-45
lines changed

5 files changed

+65
-45
lines changed

src/librustc/ty/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -717,11 +717,16 @@ pub struct RegionParameterDef<'tcx> {
717717

718718
impl<'tcx> RegionParameterDef<'tcx> {
719719
pub fn to_early_bound_region(&self) -> ty::Region {
720-
ty::ReEarlyBound(ty::EarlyBoundRegion {
720+
ty::ReEarlyBound(self.to_early_bound_region_data())
721+
}
722+
723+
pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
724+
ty::EarlyBoundRegion {
721725
index: self.index,
722726
name: self.name,
723-
})
727+
}
724728
}
729+
725730
pub fn to_bound_region(&self) -> ty::BoundRegion {
726731
// this is an early bound region, so unaffected by #32330
727732
ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)

src/librustc_typeck/check/wfcheck.rs

+9-22
Original file line numberDiff line numberDiff line change
@@ -457,44 +457,31 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
457457
let variances = self.tcx().item_variances(item_def_id);
458458

459459
let mut constrained_parameters: FnvHashSet<_> =
460-
variances[ast_generics.lifetimes.len()..]
461-
.iter().enumerate()
460+
variances.iter().enumerate()
462461
.filter(|&(_, &variance)| variance != ty::Bivariant)
463-
.map(|(index, _)| self.param_ty(ast_generics, index))
464-
.map(|p| Parameter::Type(p))
462+
.map(|(index, _)| Parameter(index as u32))
465463
.collect();
466464

467465
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
468466
None,
469467
&mut constrained_parameters);
470468

471-
for (index, &variance) in variances.iter().enumerate() {
472-
let (span, name) = if index < ast_generics.lifetimes.len() {
473-
if variance != ty::Bivariant {
474-
continue;
475-
}
469+
for (index, _) in variances.iter().enumerate() {
470+
if constrained_parameters.contains(&Parameter(index as u32)) {
471+
continue;
472+
}
476473

474+
let (span, name) = if index < ast_generics.lifetimes.len() {
477475
(ast_generics.lifetimes[index].lifetime.span,
478476
ast_generics.lifetimes[index].lifetime.name)
479477
} else {
480-
let index = index - ast_generics.lifetimes.len();
481-
let param_ty = self.param_ty(ast_generics, index);
482-
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
483-
continue;
484-
}
485-
(ast_generics.ty_params[index].span, param_ty.name)
478+
(ast_generics.ty_params[index].span,
479+
ast_generics.ty_params[index].name)
486480
};
487481
self.report_bivariance(span, name);
488482
}
489483
}
490484

491-
fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
492-
ty::ParamTy {
493-
idx: index as u32,
494-
name: ast_generics.ty_params[index].name
495-
}
496-
}
497-
498485
fn report_bivariance(&self,
499486
span: Span,
500487
param_name: ast::Name)

src/librustc_typeck/collect.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
21582158
let ty_generics = generics_of_def_id(ccx, impl_def_id);
21592159
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
21602160
let param_ty = ty::ParamTy::for_def(ty_param);
2161-
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2161+
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
21622162
report_unused_parameter(ccx, param.span, "type", &param_ty.to_string());
21632163
}
21642164
}
@@ -2189,23 +2189,19 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
21892189
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
21902190
})
21912191
.flat_map(|ty| ctp::parameters_for(&ty, true))
2192-
.filter_map(|p| match p {
2193-
ctp::Parameter::Type(_) => None,
2194-
ctp::Parameter::Region(r) => Some(r),
2195-
})
21962192
.collect();
21972193

2198-
for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2199-
let region = ty::EarlyBoundRegion {
2200-
index: index as u32,
2201-
name: lifetime_def.lifetime.name
2202-
};
2194+
for (ty_lifetime, lifetime) in impl_scheme.generics.regions.iter()
2195+
.zip(&ast_generics.lifetimes)
2196+
{
2197+
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
2198+
22032199
if
2204-
lifetimes_in_associated_types.contains(&region) && // (*)
2205-
!input_parameters.contains(&ctp::Parameter::Region(region))
2200+
lifetimes_in_associated_types.contains(&param) && // (*)
2201+
!input_parameters.contains(&param)
22062202
{
2207-
report_unused_parameter(ccx, lifetime_def.lifetime.span,
2208-
"lifetime", &region.name.to_string());
2203+
report_unused_parameter(ccx, lifetime.lifetime.span,
2204+
"lifetime", &lifetime.lifetime.name.to_string());
22092205
}
22102206
}
22112207

src/librustc_typeck/constrained_type_params.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ use rustc::ty::fold::{TypeFoldable, TypeVisitor};
1313
use rustc::util::nodemap::FnvHashSet;
1414

1515
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
16-
pub enum Parameter {
17-
Type(ty::ParamTy),
18-
Region(ty::EarlyBoundRegion),
16+
pub struct Parameter(pub u32);
17+
18+
impl From<ty::ParamTy> for Parameter {
19+
fn from(param: ty::ParamTy) -> Self { Parameter(param.idx) }
20+
}
21+
22+
impl From<ty::EarlyBoundRegion> for Parameter {
23+
fn from(param: ty::EarlyBoundRegion) -> Self { Parameter(param.index) }
1924
}
2025

2126
/// If `include_projections` is false, returns the list of parameters that are
@@ -49,8 +54,8 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
4954
// projections are not injective
5055
return false;
5156
}
52-
ty::TyParam(ref d) => {
53-
self.parameters.push(Parameter::Type(d.clone()));
57+
ty::TyParam(data) => {
58+
self.parameters.push(Parameter::from(data));
5459
}
5560
_ => {}
5661
}
@@ -61,7 +66,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
6166
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
6267
match *r {
6368
ty::ReEarlyBound(data) => {
64-
self.parameters.push(Parameter::Region(data));
69+
self.parameters.push(Parameter::from(data));
6570
}
6671
_ => {}
6772
}
@@ -141,13 +146,15 @@ pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>
141146
// * <U as Iterator>::Item = T
142147
// * T: Debug
143148
// * U: Iterator
149+
debug!("setup_constraining_predicates: predicates={:?} \
150+
impl_trait_ref={:?} input_parameters={:?}",
151+
predicates, impl_trait_ref, input_parameters);
144152
let mut i = 0;
145153
let mut changed = true;
146154
while changed {
147155
changed = false;
148156

149157
for j in i..predicates.len() {
150-
151158
if let ty::Predicate::Projection(ref poly_projection) = predicates[j] {
152159
// Note that we can skip binder here because the impl
153160
// trait ref never contains any late-bound regions.
@@ -181,5 +188,8 @@ pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>
181188
i += 1;
182189
changed = true;
183190
}
191+
debug!("setup_constraining_predicates: predicates={:?} \
192+
i={} impl_trait_ref={:?} input_parameters={:?}",
193+
predicates, i, impl_trait_ref, input_parameters);
184194
}
185195
}

src/test/run-pass/issue-36075.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait DeclarationParser {
12+
type Declaration;
13+
}
14+
15+
struct DeclarationListParser<'i, I, P>
16+
where P: DeclarationParser<Declaration = I>
17+
{
18+
input: &'i (),
19+
parser: P
20+
}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)