mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Auto merge of #36119 - arielb1:ctp-again, r=eddyb
fix broken type parameter indexing logic in wfcheck r? @eddyb Fixes #36075
This commit is contained in:
commit
70598e04f9
@ -717,11 +717,16 @@ pub struct RegionParameterDef<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx> RegionParameterDef<'tcx> {
|
impl<'tcx> RegionParameterDef<'tcx> {
|
||||||
pub fn to_early_bound_region(&self) -> ty::Region {
|
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,
|
index: self.index,
|
||||||
name: self.name,
|
name: self.name,
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_bound_region(&self) -> ty::BoundRegion {
|
pub fn to_bound_region(&self) -> ty::BoundRegion {
|
||||||
// this is an early bound region, so unaffected by #32330
|
// this is an early bound region, so unaffected by #32330
|
||||||
ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)
|
ty::BoundRegion::BrNamed(self.def_id, self.name, Issue32330::WontChange)
|
||||||
|
@ -462,44 +462,31 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||||||
let variances = self.tcx().item_variances(item_def_id);
|
let variances = self.tcx().item_variances(item_def_id);
|
||||||
|
|
||||||
let mut constrained_parameters: FnvHashSet<_> =
|
let mut constrained_parameters: FnvHashSet<_> =
|
||||||
variances[ast_generics.lifetimes.len()..]
|
variances.iter().enumerate()
|
||||||
.iter().enumerate()
|
|
||||||
.filter(|&(_, &variance)| variance != ty::Bivariant)
|
.filter(|&(_, &variance)| variance != ty::Bivariant)
|
||||||
.map(|(index, _)| self.param_ty(ast_generics, index))
|
.map(|(index, _)| Parameter(index as u32))
|
||||||
.map(|p| Parameter::Type(p))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
|
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
|
||||||
None,
|
None,
|
||||||
&mut constrained_parameters);
|
&mut constrained_parameters);
|
||||||
|
|
||||||
for (index, &variance) in variances.iter().enumerate() {
|
for (index, _) in variances.iter().enumerate() {
|
||||||
let (span, name) = if index < ast_generics.lifetimes.len() {
|
if constrained_parameters.contains(&Parameter(index as u32)) {
|
||||||
if variance != ty::Bivariant {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (span, name) = if index < ast_generics.lifetimes.len() {
|
||||||
(ast_generics.lifetimes[index].lifetime.span,
|
(ast_generics.lifetimes[index].lifetime.span,
|
||||||
ast_generics.lifetimes[index].lifetime.name)
|
ast_generics.lifetimes[index].lifetime.name)
|
||||||
} else {
|
} else {
|
||||||
let index = index - ast_generics.lifetimes.len();
|
(ast_generics.ty_params[index].span,
|
||||||
let param_ty = self.param_ty(ast_generics, index);
|
ast_generics.ty_params[index].name)
|
||||||
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(ast_generics.ty_params[index].span, param_ty.name)
|
|
||||||
};
|
};
|
||||||
self.report_bivariance(span, 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,
|
fn report_bivariance(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
param_name: ast::Name)
|
param_name: ast::Name)
|
||||||
|
@ -2175,7 +2175,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
let ty_generics = generics_of_def_id(ccx, impl_def_id);
|
let ty_generics = generics_of_def_id(ccx, impl_def_id);
|
||||||
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
|
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
|
||||||
let param_ty = ty::ParamTy::for_def(ty_param);
|
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());
|
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2206,23 +2206,19 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
|
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
|
||||||
})
|
})
|
||||||
.flat_map(|ty| ctp::parameters_for(&ty, true))
|
.flat_map(|ty| ctp::parameters_for(&ty, true))
|
||||||
.filter_map(|p| match p {
|
|
||||||
ctp::Parameter::Type(_) => None,
|
|
||||||
ctp::Parameter::Region(r) => Some(r),
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
|
for (ty_lifetime, lifetime) in impl_scheme.generics.regions.iter()
|
||||||
let region = ty::EarlyBoundRegion {
|
.zip(&ast_generics.lifetimes)
|
||||||
index: index as u32,
|
|
||||||
name: lifetime_def.lifetime.name
|
|
||||||
};
|
|
||||||
if
|
|
||||||
lifetimes_in_associated_types.contains(®ion) && // (*)
|
|
||||||
!input_parameters.contains(&ctp::Parameter::Region(region))
|
|
||||||
{
|
{
|
||||||
report_unused_parameter(ccx, lifetime_def.lifetime.span,
|
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
|
||||||
"lifetime", ®ion.name.to_string());
|
|
||||||
|
if
|
||||||
|
lifetimes_in_associated_types.contains(¶m) && // (*)
|
||||||
|
!input_parameters.contains(¶m)
|
||||||
|
{
|
||||||
|
report_unused_parameter(ccx, lifetime.lifetime.span,
|
||||||
|
"lifetime", &lifetime.lifetime.name.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,14 @@ use rustc::ty::fold::{TypeFoldable, TypeVisitor};
|
|||||||
use rustc::util::nodemap::FnvHashSet;
|
use rustc::util::nodemap::FnvHashSet;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum Parameter {
|
pub struct Parameter(pub u32);
|
||||||
Type(ty::ParamTy),
|
|
||||||
Region(ty::EarlyBoundRegion),
|
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
|
/// If `include_projections` is false, returns the list of parameters that are
|
||||||
@ -49,8 +54,8 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
|
|||||||
// projections are not injective
|
// projections are not injective
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ty::TyParam(ref d) => {
|
ty::TyParam(data) => {
|
||||||
self.parameters.push(Parameter::Type(d.clone()));
|
self.parameters.push(Parameter::from(data));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -61,7 +66,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
|
|||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReEarlyBound(data) => {
|
ty::ReEarlyBound(data) => {
|
||||||
self.parameters.push(Parameter::Region(data));
|
self.parameters.push(Parameter::from(data));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -141,13 +146,15 @@ pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>
|
|||||||
// * <U as Iterator>::Item = T
|
// * <U as Iterator>::Item = T
|
||||||
// * T: Debug
|
// * T: Debug
|
||||||
// * U: Iterator
|
// * U: Iterator
|
||||||
|
debug!("setup_constraining_predicates: predicates={:?} \
|
||||||
|
impl_trait_ref={:?} input_parameters={:?}",
|
||||||
|
predicates, impl_trait_ref, input_parameters);
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut changed = true;
|
let mut changed = true;
|
||||||
while changed {
|
while changed {
|
||||||
changed = false;
|
changed = false;
|
||||||
|
|
||||||
for j in i..predicates.len() {
|
for j in i..predicates.len() {
|
||||||
|
|
||||||
if let ty::Predicate::Projection(ref poly_projection) = predicates[j] {
|
if let ty::Predicate::Projection(ref poly_projection) = predicates[j] {
|
||||||
// Note that we can skip binder here because the impl
|
// Note that we can skip binder here because the impl
|
||||||
// trait ref never contains any late-bound regions.
|
// trait ref never contains any late-bound regions.
|
||||||
@ -181,5 +188,8 @@ pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>
|
|||||||
i += 1;
|
i += 1;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
debug!("setup_constraining_predicates: predicates={:?} \
|
||||||
|
i={} impl_trait_ref={:?} input_parameters={:?}",
|
||||||
|
predicates, i, impl_trait_ref, input_parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
src/test/run-pass/issue-36075.rs
Normal file
22
src/test/run-pass/issue-36075.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// 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() {}
|
Loading…
Reference in New Issue
Block a user