-
Notifications
You must be signed in to change notification settings - Fork 13.3k
fix broken type parameter indexing logic in wfcheck #36119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2158,7 +2158,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, | |
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)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then again, |
||
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string()); | ||
} | ||
} | ||
|
@@ -2189,23 +2189,19 @@ fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, | |
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()); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,9 +13,14 @@ use rustc::ty::fold::{TypeFoldable, TypeVisitor}; | |
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please leave a comment explaining what this field is? Also, I think the field should be private, and you should write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, that's an internal conversion anyway...but I'd argue that's a problem with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anyway whatever. I don't care that much. |
||
|
||
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) } | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these entirely needed? Seems to me like it's less work to just use the index from wherever it first is available. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had enough index mixups. |
||
|
||
/// 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 | ||
return false; | ||
} | ||
ty::TyParam(ref d) => { | ||
self.parameters.push(Parameter::Type(d.clone())); | ||
ty::TyParam(data) => { | ||
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 { | ||
match *r { | ||
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 | ||
// * 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. | ||
|
@@ -181,5 +188,8 @@ pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx> | |
i += 1; | ||
changed = true; | ||
} | ||
debug!("setup_constraining_predicates: predicates={:?} \ | ||
i={} impl_trait_ref={:?} input_parameters={:?}", | ||
predicates, i, impl_trait_ref, input_parameters); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this just reuse a clone of the variances
Vec
instead of having a (heavier)FnvHashSet
?Only in the case of errors do we have less
constrainted_parameters
than generics, so a set doesn't make sense.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to use a strongly-typed
BitVector
everywhere (also in other places).