Generalise more cases of explicit iteration of specific kinds
This commit is contained in:
parent
4a6c946368
commit
b75f421ee9
23 changed files with 110 additions and 71 deletions
|
@ -46,6 +46,7 @@ use hir::HirVec;
|
||||||
use hir::map::{DefKey, DefPathData, Definitions};
|
use hir::map::{DefKey, DefPathData, Definitions};
|
||||||
use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
|
use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
|
||||||
use hir::def::{Def, PathResolution};
|
use hir::def::{Def, PathResolution};
|
||||||
|
use ty::Kind;
|
||||||
use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
|
use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
|
||||||
use middle::cstore::CrateStore;
|
use middle::cstore::CrateStore;
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
|
@ -1461,7 +1462,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
assert!(!def_id.is_local());
|
assert!(!def_id.is_local());
|
||||||
let item_generics =
|
let item_generics =
|
||||||
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
|
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
|
||||||
let n = item_generics.lifetimes().count();
|
let n = item_generics.param_counts()[&Kind::Lifetime];
|
||||||
self.type_def_lifetime_params.insert(def_id, n);
|
self.type_def_lifetime_params.insert(def_id, n);
|
||||||
n
|
n
|
||||||
});
|
});
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
// `['a]` for the first impl trait and `'b` for the
|
// `['a]` for the first impl trait and `'b` for the
|
||||||
// second.
|
// second.
|
||||||
let mut least_region = None;
|
let mut least_region = None;
|
||||||
for region_def in abstract_type_generics.lifetimes() {
|
for region_def in abstract_type_generics.lifetimes_depr() {
|
||||||
// Find the index of this region in the list of substitutions.
|
// Find the index of this region in the list of substitutions.
|
||||||
let index = region_def.index as usize;
|
let index = region_def.index as usize;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#![cfg_attr(stage0, feature(dyn_trait))]
|
#![cfg_attr(stage0, feature(dyn_trait))]
|
||||||
#![feature(from_ref)]
|
#![feature(from_ref)]
|
||||||
#![feature(fs_read_write)]
|
#![feature(fs_read_write)]
|
||||||
|
#![feature(iterator_find_map)]
|
||||||
#![cfg_attr(windows, feature(libc))]
|
#![cfg_attr(windows, feature(libc))]
|
||||||
#![cfg_attr(stage0, feature(macro_lifetime_matcher))]
|
#![cfg_attr(stage0, feature(macro_lifetime_matcher))]
|
||||||
#![feature(macro_vis_matcher)]
|
#![feature(macro_vis_matcher)]
|
||||||
|
|
|
@ -1659,7 +1659,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
.entry(def_id)
|
.entry(def_id)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
tcx.generics_of(def_id)
|
tcx.generics_of(def_id)
|
||||||
.types()
|
.types_depr()
|
||||||
.map(|def| def.object_lifetime_default)
|
.map(|def| def.object_lifetime_default)
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
|
|
|
@ -378,7 +378,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
|
flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
for param in generics.types() {
|
for param in generics.types_depr() {
|
||||||
let name = param.name.to_string();
|
let name = param.name.to_string();
|
||||||
let ty = trait_ref.substs.type_for_def(param);
|
let ty = trait_ref.substs.type_for_def(param);
|
||||||
let ty_str = ty.to_string();
|
let ty_str = ty.to_string();
|
||||||
|
|
|
@ -21,7 +21,7 @@ use super::elaborate_predicates;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use traits;
|
use traits;
|
||||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, Ty, TyCtxt, Kind, TypeFoldable};
|
||||||
use ty::subst::Substs;
|
use ty::subst::Substs;
|
||||||
use ty::util::ExplicitSelf;
|
use ty::util::ExplicitSelf;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't monomorphize things like `fn foo<A>(...)`.
|
// We can't monomorphize things like `fn foo<A>(...)`.
|
||||||
if self.generics_of(method.def_id).types().count() != 0 {
|
if self.generics_of(method.def_id).param_counts()[&Kind::Type] != 0 {
|
||||||
return Some(MethodViolationCode::Generic);
|
return Some(MethodViolationCode::Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
|
||||||
let name = tcx.item_name(trait_ref.def_id);
|
let name = tcx.item_name(trait_ref.def_id);
|
||||||
let trait_str = tcx.item_path_str(trait_ref.def_id);
|
let trait_str = tcx.item_path_str(trait_ref.def_id);
|
||||||
let generics = tcx.generics_of(trait_ref.def_id);
|
let generics = tcx.generics_of(trait_ref.def_id);
|
||||||
let generic_map = generics.types().map(|param| {
|
let generic_map = generics.types_depr().map(|param| {
|
||||||
(param.name.to_string(), trait_ref.substs.type_for_def(param).to_string())
|
(param.name.to_string(), trait_ref.substs.type_for_def(param).to_string())
|
||||||
}).collect::<FxHashMap<String, String>>();
|
}).collect::<FxHashMap<String, String>>();
|
||||||
|
|
||||||
|
|
|
@ -782,6 +782,13 @@ impl GenericParamDef {
|
||||||
GenericParamDef::Type(ty) => ty.index,
|
GenericParamDef::Type(ty) => ty.index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_type(&self) -> Option<TypeParamDef> {
|
||||||
|
match *self {
|
||||||
|
GenericParamDef::Type(ty) => Some(ty),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the formal type/lifetime parameters associated
|
/// Information about the formal type/lifetime parameters associated
|
||||||
|
@ -828,7 +835,19 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||||
param_counts
|
param_counts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lifetimes(&self) -> impl DoubleEndedIterator<Item = &RegionParamDef> {
|
pub fn type_params_without_defaults(&self) -> usize {
|
||||||
|
let mut count = 0;
|
||||||
|
for param in self.params.iter() {
|
||||||
|
if let GenericParamDef::Type(ty) = param {
|
||||||
|
if !ty.has_default {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lifetimes_depr(&self) -> impl DoubleEndedIterator<Item = &RegionParamDef> {
|
||||||
self.params.iter().filter_map(|p| {
|
self.params.iter().filter_map(|p| {
|
||||||
if let GenericParamDef::Lifetime(lt) = p {
|
if let GenericParamDef::Lifetime(lt) = p {
|
||||||
Some(lt)
|
Some(lt)
|
||||||
|
@ -838,7 +857,7 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn types(&self) -> impl DoubleEndedIterator<Item = &TypeParamDef> {
|
pub fn types_depr(&self) -> impl DoubleEndedIterator<Item = &TypeParamDef> {
|
||||||
self.params.iter().filter_map(|p| {
|
self.params.iter().filter_map(|p| {
|
||||||
if let GenericParamDef::Type(ty) = p {
|
if let GenericParamDef::Type(ty) = p {
|
||||||
Some(ty)
|
Some(ty)
|
||||||
|
@ -849,9 +868,7 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
|
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
|
||||||
if self.params.iter().any(|p| {
|
if self.params.iter().any(|p| p.get_type().is_some()) {
|
||||||
if let GenericParamDef::Type(_) = p { true } else { false }
|
|
||||||
}) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some(parent_def_id) = self.parent {
|
if let Some(parent_def_id) = self.parent {
|
||||||
|
@ -912,7 +929,7 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||||
// And it can be seen that in both cases, to move from a substs
|
// And it can be seen that in both cases, to move from a substs
|
||||||
// offset to a generics offset you just have to offset by the
|
// offset to a generics offset you just have to offset by the
|
||||||
// number of regions.
|
// number of regions.
|
||||||
let type_param_offset = self.lifetimes().count();
|
let type_param_offset = self.param_counts()[&Kind::Lifetime];
|
||||||
|
|
||||||
let has_self = self.has_self && self.parent.is_none();
|
let has_self = self.has_self && self.parent.is_none();
|
||||||
let is_separated_self = type_param_offset != 0 && idx == 0 && has_self;
|
let is_separated_self = type_param_offset != 0 && idx == 0 && has_self;
|
||||||
|
|
|
@ -242,11 +242,10 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||||
where FR: FnMut(&ty::RegionParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
where FR: FnMut(&ty::RegionParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||||
FT: FnMut(&ty::TypeParamDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
FT: FnMut(&ty::TypeParamDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||||
// Handle Self first, before all regions.
|
// Handle Self first, before all regions.
|
||||||
let mut types = defs.types();
|
|
||||||
let mut skip_self = defs.parent.is_none() && defs.has_self;
|
let mut skip_self = defs.parent.is_none() && defs.has_self;
|
||||||
if skip_self {
|
if skip_self {
|
||||||
let def = types.next().unwrap();
|
let def = defs.params.iter().find_map(|p| p.get_type()).unwrap();
|
||||||
let ty = mk_type(def, substs);
|
let ty = mk_type(&def, substs);
|
||||||
assert_eq!(def.index as usize, substs.len());
|
assert_eq!(def.index as usize, substs.len());
|
||||||
substs.push(ty.into());
|
substs.push(ty.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,10 +335,10 @@ impl PrintContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !verbose {
|
if !verbose {
|
||||||
if generics.types().last().map_or(false, |def| def.has_default) {
|
if generics.types_depr().last().map_or(false, |def| def.has_default) {
|
||||||
if let Some(substs) = tcx.lift(&substs) {
|
if let Some(substs) = tcx.lift(&substs) {
|
||||||
let tps = substs.types().rev().skip(child_types);
|
let tps = substs.types().rev().skip(child_types);
|
||||||
for (def, actual) in generics.types().rev().zip(tps) {
|
for (def, actual) in generics.types_depr().rev().zip(tps) {
|
||||||
if !def.has_default {
|
if !def.has_default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.generics_of(method.def_id).types().count() != 0 {
|
if tcx.generics_of(method.def_id).param_counts()[&ty::Kind::Type] != 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt, Kind};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
|
use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
|
||||||
|
@ -357,7 +357,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
|
||||||
|
|
||||||
// FIXME: when we make this a hard error, this should have its
|
// FIXME: when we make this a hard error, this should have its
|
||||||
// own error code.
|
// own error code.
|
||||||
let message = if tcx.generics_of(def_id).types().count() != 0 {
|
let message = if tcx.generics_of(def_id).param_counts()[&Kind::Type] != 0 {
|
||||||
format!("#[derive] can't be used on a #[repr(packed)] struct with \
|
format!("#[derive] can't be used on a #[repr(packed)] struct with \
|
||||||
type parameters (error E0133)")
|
type parameters (error E0133)")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||||
use rustc::hir::itemlikevisit::DeepVisitor;
|
use rustc::hir::itemlikevisit::DeepVisitor;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle::privacy::{AccessLevel, AccessLevels};
|
use rustc::middle::privacy::{AccessLevel, AccessLevels};
|
||||||
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
|
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, GenericParamDef};
|
||||||
use rustc::ty::fold::TypeVisitor;
|
use rustc::ty::fold::TypeVisitor;
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
use rustc::ty::subst::UnpackedKind;
|
use rustc::ty::subst::UnpackedKind;
|
||||||
|
@ -399,9 +399,14 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||||
fn generics(&mut self) -> &mut Self {
|
fn generics(&mut self) -> &mut Self {
|
||||||
for def in self.ev.tcx.generics_of(self.item_def_id).types() {
|
for def in self.ev.tcx.generics_of(self.item_def_id).params.iter() {
|
||||||
if def.has_default {
|
match def {
|
||||||
self.ev.tcx.type_of(def.def_id).visit_with(self);
|
GenericParamDef::Type(ty) => {
|
||||||
|
if ty.has_default {
|
||||||
|
self.ev.tcx.type_of(ty.def_id).visit_with(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenericParamDef::Lifetime(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
@ -1335,9 +1340,14 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||||
fn generics(&mut self) -> &mut Self {
|
fn generics(&mut self) -> &mut Self {
|
||||||
for def in self.tcx.generics_of(self.item_def_id).types() {
|
for def in self.tcx.generics_of(self.item_def_id).params.iter() {
|
||||||
if def.has_default {
|
match def {
|
||||||
self.tcx.type_of(def.def_id).visit_with(self);
|
GenericParamDef::Type(ty) => {
|
||||||
|
if ty.has_default {
|
||||||
|
self.tcx.type_of(ty.def_id).visit_with(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenericParamDef::Lifetime(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
|
|
@ -280,7 +280,11 @@ crate fn adt_dtorck_constraint<'a, 'tcx>(
|
||||||
if def.is_phantom_data() {
|
if def.is_phantom_data() {
|
||||||
let result = DtorckConstraint {
|
let result = DtorckConstraint {
|
||||||
outlives: vec![],
|
outlives: vec![],
|
||||||
dtorck_types: vec![tcx.mk_param_from_def(&tcx.generics_of(def_id).types().next()
|
dtorck_types: vec![tcx.mk_param_from_def(
|
||||||
|
&tcx.generics_of(def_id)
|
||||||
|
.params
|
||||||
|
.iter()
|
||||||
|
.find_map(|p| p.get_type())
|
||||||
.expect("should be at least one type parameter"))],
|
.expect("should be at least one type parameter"))],
|
||||||
overflows: vec![],
|
overflows: vec![],
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
//! the guts are broken up into modules; see the comments in those modules.
|
//! the guts are broken up into modules; see the comments in those modules.
|
||||||
|
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
|
#![feature(iterator_find_map)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
|
@ -208,8 +208,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
// region with the current anon region binding (in other words,
|
// region with the current anon region binding (in other words,
|
||||||
// whatever & would get replaced with).
|
// whatever & would get replaced with).
|
||||||
let decl_generics = tcx.generics_of(def_id);
|
let decl_generics = tcx.generics_of(def_id);
|
||||||
|
let param_counts = decl_generics.param_counts();
|
||||||
let num_types_provided = parameters.types.len();
|
let num_types_provided = parameters.types.len();
|
||||||
let expected_num_region_params = decl_generics.lifetimes().count();
|
let expected_num_region_params = param_counts[&ty::Kind::Lifetime];
|
||||||
let supplied_num_region_params = parameters.lifetimes.len();
|
let supplied_num_region_params = parameters.lifetimes.len();
|
||||||
if expected_num_region_params != supplied_num_region_params {
|
if expected_num_region_params != supplied_num_region_params {
|
||||||
report_lifetime_number_error(tcx, span,
|
report_lifetime_number_error(tcx, span,
|
||||||
|
@ -221,10 +222,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
assert_eq!(decl_generics.has_self, self_ty.is_some());
|
assert_eq!(decl_generics.has_self, self_ty.is_some());
|
||||||
|
|
||||||
// Check the number of type parameters supplied by the user.
|
// Check the number of type parameters supplied by the user.
|
||||||
let ty_param_defs =
|
let type_params_offset = self_ty.is_some() as usize;
|
||||||
decl_generics.types().skip(self_ty.is_some() as usize).collect::<Vec<_>>();
|
let ty_param_defs = param_counts[&ty::Kind::Type] - type_params_offset;
|
||||||
if !infer_types || num_types_provided > ty_param_defs.len() {
|
if !infer_types || num_types_provided > ty_param_defs {
|
||||||
check_type_argument_count(tcx, span, num_types_provided, &ty_param_defs);
|
check_type_argument_count(tcx,
|
||||||
|
span,
|
||||||
|
num_types_provided,
|
||||||
|
ty_param_defs,
|
||||||
|
decl_generics.type_params_without_defaults() - type_params_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
|
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
|
||||||
|
@ -241,7 +246,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
};
|
};
|
||||||
|
|
||||||
let substs = Substs::for_item(tcx, def_id, |def, _| {
|
let substs = Substs::for_item(tcx, def_id, |def, _| {
|
||||||
let i = def.index as usize - self_ty.is_some() as usize;
|
let i = def.index as usize - type_params_offset;
|
||||||
if let Some(lifetime) = parameters.lifetimes.get(i) {
|
if let Some(lifetime) = parameters.lifetimes.get(i) {
|
||||||
self.ast_region_to_region(lifetime, Some(def))
|
self.ast_region_to_region(lifetime, Some(def))
|
||||||
} else {
|
} else {
|
||||||
|
@ -255,7 +260,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = i - self_ty.is_some() as usize - decl_generics.lifetimes().count();
|
let i = i - (param_counts[&ty::Kind::Lifetime] + type_params_offset);
|
||||||
if i < num_types_provided {
|
if i < num_types_provided {
|
||||||
// A provided type parameter.
|
// A provided type parameter.
|
||||||
self.ast_ty_to_ty(¶meters.types[i])
|
self.ast_ty_to_ty(¶meters.types[i])
|
||||||
|
@ -1300,10 +1305,14 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
(auto_traits, trait_bounds)
|
(auto_traits, trait_bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
|
fn check_type_argument_count(tcx: TyCtxt,
|
||||||
ty_param_defs: &[&ty::TypeParamDef]) {
|
span: Span,
|
||||||
let accepted = ty_param_defs.len();
|
supplied: usize,
|
||||||
let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
|
ty_param_defs: usize,
|
||||||
|
ty_param_defs_without_default: usize)
|
||||||
|
{
|
||||||
|
let accepted = ty_param_defs;
|
||||||
|
let required = ty_param_defs_without_default;
|
||||||
if supplied < required {
|
if supplied < required {
|
||||||
let expected = if required < accepted {
|
let expected = if required < accepted {
|
||||||
"expected at least"
|
"expected at least"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
use rustc::hir::{self, ImplItemKind, TraitItemKind};
|
use rustc::hir::{self, ImplItemKind, TraitItemKind};
|
||||||
use rustc::infer::{self, InferOk};
|
use rustc::infer::{self, InferOk};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt, Kind};
|
||||||
use rustc::ty::util::ExplicitSelf;
|
use rustc::ty::util::ExplicitSelf;
|
||||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
|
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
|
||||||
use rustc::ty::error::{ExpectedFound, TypeError};
|
use rustc::ty::error::{ExpectedFound, TypeError};
|
||||||
|
@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
trait_to_skol_substs: &Substs<'tcx>)
|
trait_to_skol_substs: &Substs<'tcx>)
|
||||||
-> Result<(), ErrorReported> {
|
-> Result<(), ErrorReported> {
|
||||||
let span = tcx.sess.codemap().def_span(span);
|
let span = tcx.sess.codemap().def_span(span);
|
||||||
let trait_params = trait_generics.lifetimes();
|
let trait_params = trait_generics.param_counts()[&Kind::Lifetime];
|
||||||
let impl_params = impl_generics.lifetimes();
|
let impl_params = impl_generics.param_counts()[&Kind::Lifetime];
|
||||||
|
|
||||||
debug!("check_region_bounds_on_impl_method: \
|
debug!("check_region_bounds_on_impl_method: \
|
||||||
trait_generics={:?} \
|
trait_generics={:?} \
|
||||||
|
@ -377,7 +377,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
// but found 0" it's confusing, because it looks like there
|
// but found 0" it's confusing, because it looks like there
|
||||||
// are zero. Since I don't quite know how to phrase things at
|
// are zero. Since I don't quite know how to phrase things at
|
||||||
// the moment, give a kind of vague error message.
|
// the moment, give a kind of vague error message.
|
||||||
if trait_params.count() != impl_params.count() {
|
if trait_params != impl_params {
|
||||||
let mut err = struct_span_err!(tcx.sess,
|
let mut err = struct_span_err!(tcx.sess,
|
||||||
span,
|
span,
|
||||||
E0195,
|
E0195,
|
||||||
|
@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
-> Result<(), ErrorReported> {
|
-> Result<(), ErrorReported> {
|
||||||
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
||||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
||||||
let num_impl_m_type_params = impl_m_generics.types().count();
|
let num_impl_m_type_params = impl_m_generics.param_counts()[&Kind::Type];
|
||||||
let num_trait_m_type_params = trait_m_generics.types().count();
|
let num_trait_m_type_params = trait_m_generics.param_counts()[&Kind::Type];
|
||||||
if num_impl_m_type_params != num_trait_m_type_params {
|
if num_impl_m_type_params != num_trait_m_type_params {
|
||||||
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
|
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
|
||||||
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
|
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
|
||||||
|
@ -728,7 +728,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut error_found = false;
|
let mut error_found = false;
|
||||||
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
||||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
||||||
for (impl_ty, trait_ty) in impl_m_generics.types().zip(trait_m_generics.types()) {
|
for (impl_ty, trait_ty) in impl_m_generics.types_depr().zip(trait_m_generics.types_depr()) {
|
||||||
if impl_ty.synthetic != trait_ty.synthetic {
|
if impl_ty.synthetic != trait_ty.synthetic {
|
||||||
let impl_node_id = tcx.hir.as_local_node_id(impl_ty.def_id).unwrap();
|
let impl_node_id = tcx.hir.as_local_node_id(impl_ty.def_id).unwrap();
|
||||||
let impl_span = tcx.hir.span(impl_node_id);
|
let impl_span = tcx.hir.span(impl_node_id);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
use intrinsics;
|
use intrinsics;
|
||||||
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc::ty::{self, TyCtxt, Ty};
|
use rustc::ty::{self, TyCtxt, Ty, Kind};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use require_same_types;
|
use require_same_types;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let i_n_tps = tcx.generics_of(def_id).types().count();
|
let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type];
|
||||||
if i_n_tps != n_tps {
|
if i_n_tps != n_tps {
|
||||||
let span = match it.node {
|
let span = match it.node {
|
||||||
hir::ForeignItemFn(_, _, ref generics) => generics.span,
|
hir::ForeignItemFn(_, _, ref generics) => generics.span,
|
||||||
|
@ -346,7 +346,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
};
|
};
|
||||||
|
|
||||||
let def_id = tcx.hir.local_def_id(it.id);
|
let def_id = tcx.hir.local_def_id(it.id);
|
||||||
let i_n_tps = tcx.generics_of(def_id).types().count();
|
let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type];
|
||||||
let name = it.name.as_str();
|
let name = it.name.as_str();
|
||||||
|
|
||||||
let (n_tps, inputs, output) = match &*name {
|
let (n_tps, inputs, output) = match &*name {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use check::{FnCtxt, PlaceOp, callee, Needs};
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty, Kind};
|
||||||
use rustc::ty::subst::Subst;
|
use rustc::ty::subst::Subst;
|
||||||
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
|
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
|
||||||
use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||||
|
@ -332,7 +332,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||||
parent_substs.type_at(i)
|
parent_substs.type_at(i)
|
||||||
} else if let Some(ast_ty)
|
} else if let Some(ast_ty)
|
||||||
= provided.as_ref().and_then(|p| {
|
= provided.as_ref().and_then(|p| {
|
||||||
p.types.get(i - parent_substs.len() - method_generics.lifetimes().count())
|
let idx =
|
||||||
|
i - parent_substs.len() - method_generics.param_counts()[&Kind::Lifetime];
|
||||||
|
p.types.get(idx)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
self.to_ty(ast_ty)
|
self.to_ty(ast_ty)
|
||||||
|
|
|
@ -96,7 +96,7 @@ use rustc::middle::region;
|
||||||
use rustc::mir::interpret::{GlobalId};
|
use rustc::mir::interpret::{GlobalId};
|
||||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||||
use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate, GenericParamDef};
|
use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
|
||||||
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
|
@ -4923,16 +4923,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
segment.map_or((0, 0, 0), |(_, generics)| {
|
segment.map_or((0, 0, 0), |(_, generics)| {
|
||||||
let params_count = generics.param_counts();
|
let params_count = generics.param_counts();
|
||||||
|
|
||||||
let offset_type_params = generics.parent.is_none() && generics.has_self;
|
let type_params_offset
|
||||||
let type_params = params_count[&ty::Kind::Type] - offset_type_params as usize;
|
= (generics.parent.is_none() && generics.has_self) as usize;
|
||||||
|
let type_params = params_count[&ty::Kind::Type] - type_params_offset;
|
||||||
let type_params_barring_defaults =
|
let type_params_barring_defaults =
|
||||||
type_params - generics.params.iter().filter(|param| {
|
generics.type_params_without_defaults() - type_params_offset;
|
||||||
if let GenericParamDef::Type(ty) = param {
|
|
||||||
ty.has_default
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}).count();
|
|
||||||
|
|
||||||
(type_params_barring_defaults, type_params, params_count[&ty::Kind::Lifetime])
|
(type_params_barring_defaults, type_params, params_count[&ty::Kind::Lifetime])
|
||||||
});
|
});
|
||||||
|
|
|
@ -377,7 +377,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
// For example this forbids the declaration:
|
// For example this forbids the declaration:
|
||||||
// struct Foo<T = Vec<[u32]>> { .. }
|
// struct Foo<T = Vec<[u32]>> { .. }
|
||||||
// Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
|
// Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
|
||||||
for d in generics.types().cloned().filter(is_our_default).map(|p| p.def_id) {
|
for d in generics.types_depr().cloned().filter(is_our_default).map(|p| p.def_id) {
|
||||||
let ty = fcx.tcx.type_of(d);
|
let ty = fcx.tcx.type_of(d);
|
||||||
// ignore dependent defaults -- that is, where the default of one type
|
// ignore dependent defaults -- that is, where the default of one type
|
||||||
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
|
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
|
tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
|
||||||
|
|
||||||
// Disallow ANY unconstrained type parameters.
|
// Disallow ANY unconstrained type parameters.
|
||||||
for (ty_param, param) in impl_generics.types().zip(impl_hir_generics.ty_params()) {
|
for (ty_param, param) in impl_generics.types_depr().zip(impl_hir_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::from(param_ty)) {
|
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
|
||||||
report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string());
|
report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string());
|
||||||
|
@ -122,13 +122,13 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
.flat_map(|def_id| {
|
.flat_map(|def_id| {
|
||||||
ctp::parameters_for(&tcx.type_of(def_id), true)
|
ctp::parameters_for(&tcx.type_of(def_id), true)
|
||||||
}).collect();
|
}).collect();
|
||||||
for (ty_lifetime, lifetime) in impl_generics.lifetimes().zip(impl_hir_generics.lifetimes()) {
|
for (ty_lt, lt) in impl_generics.lifetimes_depr().zip(impl_hir_generics.lifetimes()) {
|
||||||
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
|
let param = ctp::Parameter::from(ty_lt.to_early_bound_region_data());
|
||||||
|
|
||||||
if lifetimes_in_associated_types.contains(¶m) && // (*)
|
if lifetimes_in_associated_types.contains(¶m) && // (*)
|
||||||
!input_parameters.contains(¶m) {
|
!input_parameters.contains(¶m) {
|
||||||
report_unused_parameter(tcx, lifetime.lifetime.span,
|
report_unused_parameter(tcx, lt.lifetime.span,
|
||||||
"lifetime", &lifetime.lifetime.name.name().to_string());
|
"lifetime", <.lifetime.name.name().to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1800,7 +1800,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
// Bounds in the type_params and lifetimes fields are repeated in the
|
// Bounds in the type_params and lifetimes fields are repeated in the
|
||||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||||
// them.
|
// them.
|
||||||
let stripped_typarams = gens.types().filter_map(|tp| {
|
let stripped_typarams = gens.types_depr().filter_map(|tp| {
|
||||||
if tp.name == keywords::SelfType.name().as_str() {
|
if tp.name == keywords::SelfType.name().as_str() {
|
||||||
assert_eq!(tp.index, 0);
|
assert_eq!(tp.index, 0);
|
||||||
None
|
None
|
||||||
|
@ -1849,7 +1849,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
// and instead see `where T: Foo + Bar + Sized + 'a`
|
// and instead see `where T: Foo + Bar + Sized + 'a`
|
||||||
|
|
||||||
Generics {
|
Generics {
|
||||||
params: gens.lifetimes()
|
params: gens.lifetimes_depr()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|lp| GenericParamDef::Lifetime(lp.clean(cx)))
|
.map(|lp| GenericParamDef::Lifetime(lp.clean(cx)))
|
||||||
.chain(
|
.chain(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue