Skip to content

Commit 70598e0

Browse files
authored
Auto merge of #36119 - arielb1:ctp-again, r=eddyb
fix broken type parameter indexing logic in wfcheck r? @eddyb Fixes #36075
2 parents 49e9bfd + dd72b6b commit 70598e0

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
@@ -462,44 +462,31 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
462462
let variances = self.tcx().item_variances(item_def_id);
463463

464464
let mut constrained_parameters: FnvHashSet<_> =
465-
variances[ast_generics.lifetimes.len()..]
466-
.iter().enumerate()
465+
variances.iter().enumerate()
467466
.filter(|&(_, &variance)| variance != ty::Bivariant)
468-
.map(|(index, _)| self.param_ty(ast_generics, index))
469-
.map(|p| Parameter::Type(p))
467+
.map(|(index, _)| Parameter(index as u32))
470468
.collect();
471469

472470
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
473471
None,
474472
&mut constrained_parameters);
475473

476-
for (index, &variance) in variances.iter().enumerate() {
477-
let (span, name) = if index < ast_generics.lifetimes.len() {
478-
if variance != ty::Bivariant {
479-
continue;
480-
}
474+
for (index, _) in variances.iter().enumerate() {
475+
if constrained_parameters.contains(&Parameter(index as u32)) {
476+
continue;
477+
}
481478

479+
let (span, name) = if index < ast_generics.lifetimes.len() {
482480
(ast_generics.lifetimes[index].lifetime.span,
483481
ast_generics.lifetimes[index].lifetime.name)
484482
} else {
485-
let index = index - ast_generics.lifetimes.len();
486-
let param_ty = self.param_ty(ast_generics, index);
487-
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
488-
continue;
489-
}
490-
(ast_generics.ty_params[index].span, param_ty.name)
483+
(ast_generics.ty_params[index].span,
484+
ast_generics.ty_params[index].name)
491485
};
492486
self.report_bivariance(span, name);
493487
}
494488
}
495489

496-
fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
497-
ty::ParamTy {
498-
idx: index as u32,
499-
name: ast_generics.ty_params[index].name
500-
}
501-
}
502-
503490
fn report_bivariance(&self,
504491
span: Span,
505492
param_name: ast::Name)

src/librustc_typeck/collect.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -2175,7 +2175,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
21752175
let ty_generics = generics_of_def_id(ccx, impl_def_id);
21762176
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
21772177
let param_ty = ty::ParamTy::for_def(ty_param);
2178-
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
2178+
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
21792179
report_unused_parameter(ccx, param.span, "type", &param_ty.to_string());
21802180
}
21812181
}
@@ -2206,23 +2206,19 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
22062206
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
22072207
})
22082208
.flat_map(|ty| ctp::parameters_for(&ty, true))
2209-
.filter_map(|p| match p {
2210-
ctp::Parameter::Type(_) => None,
2211-
ctp::Parameter::Region(r) => Some(r),
2212-
})
22132209
.collect();
22142210

2215-
for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
2216-
let region = ty::EarlyBoundRegion {
2217-
index: index as u32,
2218-
name: lifetime_def.lifetime.name
2219-
};
2211+
for (ty_lifetime, lifetime) in impl_scheme.generics.regions.iter()
2212+
.zip(&ast_generics.lifetimes)
2213+
{
2214+
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
2215+
22202216
if
2221-
lifetimes_in_associated_types.contains(&region) && // (*)
2222-
!input_parameters.contains(&ctp::Parameter::Region(region))
2217+
lifetimes_in_associated_types.contains(&param) && // (*)
2218+
!input_parameters.contains(&param)
22232219
{
2224-
report_unused_parameter(ccx, lifetime_def.lifetime.span,
2225-
"lifetime", &region.name.to_string());
2220+
report_unused_parameter(ccx, lifetime.lifetime.span,
2221+
"lifetime", &lifetime.lifetime.name.to_string());
22262222
}
22272223
}
22282224

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)