Consolidate ty::Generics
This commit is contained in:
parent
eca0da5985
commit
fe0c119e7d
27 changed files with 186 additions and 126 deletions
|
@ -1461,7 +1461,7 @@ impl<'a> LoweringContext<'a> {
|
|||
assert!(!def_id.is_local());
|
||||
let n = self.cstore
|
||||
.item_generics_cloned_untracked(def_id, self.sess)
|
||||
.regions
|
||||
.lifetimes()
|
||||
.len();
|
||||
self.type_def_lifetime_params.insert(def_id, n);
|
||||
n
|
||||
|
|
|
@ -735,10 +735,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::Generics {
|
|||
hasher: &mut StableHasher<W>) {
|
||||
let ty::Generics {
|
||||
parent,
|
||||
parent_regions,
|
||||
parent_types,
|
||||
ref regions,
|
||||
ref types,
|
||||
ref parent_parameters,
|
||||
ref parameters,
|
||||
|
||||
// Reverse map to each `TypeParameterDef`'s `index` field, from
|
||||
// `def_id.index` (`def_id.krate` is the same as the item's).
|
||||
|
@ -748,15 +746,18 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::Generics {
|
|||
} = *self;
|
||||
|
||||
parent.hash_stable(hcx, hasher);
|
||||
parent_regions.hash_stable(hcx, hasher);
|
||||
parent_types.hash_stable(hcx, hasher);
|
||||
regions.hash_stable(hcx, hasher);
|
||||
types.hash_stable(hcx, hasher);
|
||||
parent_parameters.hash_stable(hcx, hasher);
|
||||
parameters.hash_stable(hcx, hasher);
|
||||
has_self.hash_stable(hcx, hasher);
|
||||
has_late_bound_regions.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(enum ty::GenericParameterDef {
|
||||
Lifetime(lt),
|
||||
Type(ty)
|
||||
});
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>>
|
||||
for ty::RegionParameterDef {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
|
|
|
@ -313,7 +313,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
// `['a]` for the first impl trait and `'b` for the
|
||||
// second.
|
||||
let mut least_region = None;
|
||||
for region_def in &abstract_type_generics.regions {
|
||||
for region_def in abstract_type_generics.lifetimes() {
|
||||
// Find the index of this region in the list of substitutions.
|
||||
let index = region_def.index as usize;
|
||||
|
||||
|
|
|
@ -1659,7 +1659,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
.entry(def_id)
|
||||
.or_insert_with(|| {
|
||||
tcx.generics_of(def_id)
|
||||
.types
|
||||
.types()
|
||||
.iter()
|
||||
.map(|def| def.object_lifetime_default)
|
||||
.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())));
|
||||
}
|
||||
|
||||
for param in generics.types.iter() {
|
||||
for param in generics.types().iter() {
|
||||
let name = param.name.to_string();
|
||||
let ty = trait_ref.substs.type_for_def(param);
|
||||
let ty_str = ty.to_string();
|
||||
|
|
|
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// We can't monomorphize things like `fn foo<A>(...)`.
|
||||
if !self.generics_of(method.def_id).types.is_empty() {
|
||||
if !self.generics_of(method.def_id).types().is_empty() {
|
||||
return Some(MethodViolationCode::Generic);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
|
|||
let name = tcx.item_name(trait_def_id);
|
||||
let generics = tcx.generics_of(trait_def_id);
|
||||
let parser = Parser::new(&self.0);
|
||||
let types = &generics.types;
|
||||
let types = generics.types();
|
||||
let mut result = Ok(());
|
||||
for token in parser {
|
||||
match token {
|
||||
|
@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
|
|||
let name = tcx.item_name(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 generic_map = generics.types.iter().map(|param| {
|
||||
let generic_map = generics.types().iter().map(|param| {
|
||||
(param.name.to_string(),
|
||||
trait_ref.substs.type_for_def(param).to_string())
|
||||
}).collect::<FxHashMap<String, String>>();
|
||||
|
|
|
@ -757,6 +757,21 @@ impl ty::EarlyBoundRegion {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum GenericParameterDef {
|
||||
Lifetime(RegionParameterDef),
|
||||
Type(TypeParameterDef),
|
||||
}
|
||||
|
||||
impl GenericParameterDef {
|
||||
pub fn index(&self) -> u32 {
|
||||
match self {
|
||||
GenericParameterDef::Lifetime(lt) => lt.index,
|
||||
GenericParameterDef::Type(ty) => ty.index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the formal type/lifetime parameters associated
|
||||
/// with an item or method. Analogous to hir::Generics.
|
||||
///
|
||||
|
@ -769,10 +784,8 @@ impl ty::EarlyBoundRegion {
|
|||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct Generics {
|
||||
pub parent: Option<DefId>,
|
||||
pub parent_regions: u32,
|
||||
pub parent_types: u32,
|
||||
pub regions: Vec<RegionParameterDef>,
|
||||
pub types: Vec<TypeParameterDef>,
|
||||
pub parent_parameters: Vec<u32>,
|
||||
pub parameters: Vec<GenericParameterDef>,
|
||||
|
||||
/// Reverse map to each `TypeParameterDef`'s `index` field
|
||||
pub type_param_to_index: FxHashMap<DefId, u32>,
|
||||
|
@ -783,24 +796,56 @@ pub struct Generics {
|
|||
|
||||
impl<'a, 'gcx, 'tcx> Generics {
|
||||
pub fn parent_count(&self) -> usize {
|
||||
self.parent_regions as usize + self.parent_types as usize
|
||||
self.parent_parameters.iter().map(|&x| x as usize).sum()
|
||||
}
|
||||
|
||||
pub fn own_count(&self) -> usize {
|
||||
self.regions.len() + self.types.len()
|
||||
self.parameters.len()
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize {
|
||||
self.parent_count() + self.own_count()
|
||||
}
|
||||
|
||||
pub fn lifetimes(&self) -> Vec<&RegionParameterDef> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericParameterDef::Lifetime(lt) = p {
|
||||
Some(lt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn types(&self) -> Vec<&TypeParameterDef> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericParameterDef::Type(ty) = p {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn parent_lifetimes(&self) -> u32 {
|
||||
self.parent_parameters[0]
|
||||
}
|
||||
|
||||
pub fn parent_types(&self) -> u32 {
|
||||
self.parent_parameters[1]
|
||||
}
|
||||
|
||||
pub fn region_param(&'tcx self,
|
||||
param: &EarlyBoundRegion,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> &'tcx RegionParameterDef
|
||||
{
|
||||
if let Some(index) = param.index.checked_sub(self.parent_count() as u32) {
|
||||
&self.regions[index as usize - self.has_self as usize]
|
||||
// We're currently assuming that lifetimes precede other generic parameters.
|
||||
match self.parameters[index as usize - self.has_self as usize] {
|
||||
ty::GenericParameterDef::Lifetime(ref lt) => lt,
|
||||
_ => bug!("expected region parameter, but found another generic parameter")
|
||||
}
|
||||
} else {
|
||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
||||
.region_param(param, tcx)
|
||||
|
@ -840,17 +885,23 @@ impl<'a, 'gcx, 'tcx> Generics {
|
|||
// 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
|
||||
// number of regions.
|
||||
let type_param_offset = self.regions.len();
|
||||
let type_param_offset = self.lifetimes().len();
|
||||
|
||||
let has_self = self.has_self && self.parent.is_none();
|
||||
let is_separated_self = type_param_offset != 0 && idx == 0 && has_self;
|
||||
|
||||
if let Some(idx) = (idx as usize).checked_sub(type_param_offset) {
|
||||
if let Some(_) = (idx as usize).checked_sub(type_param_offset) {
|
||||
assert!(!is_separated_self, "found a Self after type_param_offset");
|
||||
&self.types[idx]
|
||||
match self.parameters[idx as usize] {
|
||||
ty::GenericParameterDef::Type(ref ty) => ty,
|
||||
_ => bug!("expected type parameter, but found another generic parameter")
|
||||
}
|
||||
} else {
|
||||
assert!(is_separated_self, "non-Self param before type_param_offset");
|
||||
&self.types[0]
|
||||
match self.parameters[type_param_offset] {
|
||||
ty::GenericParameterDef::Type(ref ty) => ty,
|
||||
_ => bug!("expected type parameter, but found another generic parameter")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
||||
|
|
|
@ -242,24 +242,31 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||
// Handle Self first, before all regions.
|
||||
let mut types = defs.types.iter();
|
||||
if defs.parent.is_none() && defs.has_self {
|
||||
let types = defs.types();
|
||||
let mut types = types.iter();
|
||||
let mut skip_self = defs.parent.is_none() && defs.has_self;
|
||||
if skip_self {
|
||||
let def = types.next().unwrap();
|
||||
let ty = mk_type(def, substs);
|
||||
assert_eq!(def.index as usize, substs.len());
|
||||
substs.push(ty.into());
|
||||
}
|
||||
|
||||
for def in &defs.regions {
|
||||
let region = mk_region(def, substs);
|
||||
assert_eq!(def.index as usize, substs.len());
|
||||
substs.push(Kind::from(region));
|
||||
}
|
||||
|
||||
for def in types {
|
||||
let ty = mk_type(def, substs);
|
||||
assert_eq!(def.index as usize, substs.len());
|
||||
substs.push(Kind::from(ty));
|
||||
for def in &defs.parameters {
|
||||
let param = match def {
|
||||
ty::GenericParameterDef::Lifetime(ref lt) => {
|
||||
UnpackedKind::Lifetime(mk_region(lt, substs))
|
||||
}
|
||||
ty::GenericParameterDef::Type(ref ty) => {
|
||||
if skip_self {
|
||||
skip_self = false;
|
||||
continue
|
||||
}
|
||||
UnpackedKind::Type(mk_type(ty, substs))
|
||||
}
|
||||
};
|
||||
assert_eq!(def.index() as usize, substs.len());
|
||||
substs.push(param.pack());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,10 +310,10 @@ impl PrintContext {
|
|||
if let Some(def_id) = generics.parent {
|
||||
// Methods.
|
||||
assert!(is_value_path);
|
||||
child_types = generics.types.len();
|
||||
child_types = generics.types().len();
|
||||
generics = tcx.generics_of(def_id);
|
||||
num_regions = generics.regions.len();
|
||||
num_types = generics.types.len();
|
||||
num_regions = generics.lifetimes().len();
|
||||
num_types = generics.types().len();
|
||||
|
||||
if has_self {
|
||||
print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?;
|
||||
|
@ -328,16 +328,16 @@ impl PrintContext {
|
|||
assert_eq!(has_self, false);
|
||||
} else {
|
||||
// Types and traits.
|
||||
num_regions = generics.regions.len();
|
||||
num_types = generics.types.len();
|
||||
num_regions = generics.lifetimes().len();
|
||||
num_types = generics.types().len();
|
||||
}
|
||||
}
|
||||
|
||||
if !verbose {
|
||||
if generics.types.last().map_or(false, |def| def.has_default) {
|
||||
if generics.types().last().map_or(false, |def| def.has_default) {
|
||||
if let Some(substs) = tcx.lift(&substs) {
|
||||
let tps = substs.types().rev().skip(child_types);
|
||||
for (def, actual) in generics.types.iter().rev().zip(tps) {
|
||||
for (def, actual) in generics.types().iter().rev().zip(tps) {
|
||||
if !def.has_default {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -929,7 +929,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||
hir::ImplItemKind::Const(..) => true,
|
||||
hir::ImplItemKind::Method(ref sig, _) => {
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let types = generics.parent_types as usize + generics.types.len();
|
||||
let types = generics.parent_types() as usize + generics.types().len();
|
||||
let needs_inline =
|
||||
(types > 0 || tcx.trans_fn_attrs(def_id).requests_inline())
|
||||
&& !self.metadata_output_only();
|
||||
|
|
|
@ -1076,7 +1076,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
|
|||
|
||||
fn item_has_type_parameters<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
generics.parent_types as usize + generics.types.len() > 0
|
||||
generics.parent_types() as usize + generics.types().len() > 0
|
||||
}
|
||||
|
||||
fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
continue;
|
||||
}
|
||||
|
||||
if !tcx.generics_of(method.def_id).types.is_empty() {
|
||||
if !tcx.generics_of(method.def_id).types().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// own error code.
|
||||
let message = if !tcx.generics_of(def_id).types.is_empty() {
|
||||
let message = if !tcx.generics_of(def_id).types().is_empty() {
|
||||
format!("#[derive] can't be used on a #[repr(packed)] struct with \
|
||||
type parameters (error E0133)")
|
||||
} else {
|
||||
|
|
|
@ -399,7 +399,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
|||
|
||||
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||
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).types() {
|
||||
if def.has_default {
|
||||
self.ev.tcx.type_of(def.def_id).visit_with(self);
|
||||
}
|
||||
|
@ -1335,7 +1335,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
|
|||
|
||||
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||
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).types() {
|
||||
if def.has_default {
|
||||
self.tcx.type_of(def.def_id).visit_with(self);
|
||||
}
|
||||
|
|
|
@ -417,7 +417,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||
get_type_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||
});
|
||||
names.extend(generics.types.iter().map(|param| param.name));
|
||||
names.extend(generics.types().iter().map(|param| param.name));
|
||||
names
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
// whatever & would get replaced with).
|
||||
let decl_generics = tcx.generics_of(def_id);
|
||||
let num_types_provided = parameters.types.len();
|
||||
let expected_num_region_params = decl_generics.regions.len();
|
||||
let expected_num_region_params = decl_generics.lifetimes().len();
|
||||
let supplied_num_region_params = parameters.lifetimes.len();
|
||||
if expected_num_region_params != supplied_num_region_params {
|
||||
report_lifetime_number_error(tcx, span,
|
||||
|
@ -221,7 +221,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
assert_eq!(decl_generics.has_self, self_ty.is_some());
|
||||
|
||||
// Check the number of type parameters supplied by the user.
|
||||
let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
|
||||
let ty_param_defs = &decl_generics.types()[self_ty.is_some() as usize..];
|
||||
if !infer_types || num_types_provided > ty_param_defs.len() {
|
||||
check_type_argument_count(tcx, span, num_types_provided, ty_param_defs);
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
return ty;
|
||||
}
|
||||
|
||||
let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
|
||||
let i = i - self_ty.is_some() as usize - decl_generics.lifetimes().len();
|
||||
if i < num_types_provided {
|
||||
// A provided type parameter.
|
||||
self.ast_ty_to_ty(¶meters.types[i])
|
||||
|
@ -1300,7 +1300,7 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||
}
|
||||
|
||||
fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
|
||||
ty_param_defs: &[ty::TypeParameterDef]) {
|
||||
ty_param_defs: &[&ty::TypeParameterDef]) {
|
||||
let accepted = ty_param_defs.len();
|
||||
let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
|
||||
if supplied < required {
|
||||
|
|
|
@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
trait_to_skol_substs: &Substs<'tcx>)
|
||||
-> Result<(), ErrorReported> {
|
||||
let span = tcx.sess.codemap().def_span(span);
|
||||
let trait_params = &trait_generics.regions[..];
|
||||
let impl_params = &impl_generics.regions[..];
|
||||
let trait_params = trait_generics.lifetimes();
|
||||
let impl_params = impl_generics.lifetimes();
|
||||
|
||||
debug!("check_region_bounds_on_impl_method: \
|
||||
trait_generics={:?} \
|
||||
|
@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
-> Result<(), ErrorReported> {
|
||||
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
||||
let num_impl_m_type_params = impl_m_generics.types.len();
|
||||
let num_trait_m_type_params = trait_m_generics.types.len();
|
||||
let num_impl_m_type_params = impl_m_generics.types().len();
|
||||
let num_trait_m_type_params = trait_m_generics.types().len();
|
||||
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_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 impl_m_generics = tcx.generics_of(impl_m.def_id);
|
||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
||||
for (impl_ty, trait_ty) in impl_m_generics.types.iter().zip(trait_m_generics.types.iter()) {
|
||||
for (impl_ty, trait_ty) in impl_m_generics.types().iter().zip(trait_m_generics.types().iter()) {
|
||||
if impl_ty.synthetic != trait_ty.synthetic {
|
||||
let impl_node_id = tcx.hir.as_local_node_id(impl_ty.def_id).unwrap();
|
||||
let impl_span = tcx.hir.span(impl_node_id);
|
||||
|
|
|
@ -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.len();
|
||||
let i_n_tps = tcx.generics_of(def_id).types().len();
|
||||
if i_n_tps != n_tps {
|
||||
let span = match it.node {
|
||||
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 i_n_tps = tcx.generics_of(def_id).types.len();
|
||||
let i_n_tps = tcx.generics_of(def_id).types().len();
|
||||
let name = it.name.as_str();
|
||||
|
||||
let (n_tps, inputs, output) = match &*name {
|
||||
|
|
|
@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
parent_substs.type_at(i)
|
||||
} else if let Some(ast_ty)
|
||||
= provided.as_ref().and_then(|p| {
|
||||
p.types.get(i - parent_substs.len() - method_generics.regions.len())
|
||||
p.types.get(i - parent_substs.len() - method_generics.lifetimes().len())
|
||||
})
|
||||
{
|
||||
self.to_ty(ast_ty)
|
||||
|
|
|
@ -288,8 +288,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let method_item = self.associated_item(trait_def_id, m_name, Namespace::Value).unwrap();
|
||||
let def_id = method_item.def_id;
|
||||
let generics = tcx.generics_of(def_id);
|
||||
assert_eq!(generics.types.len(), 0);
|
||||
assert_eq!(generics.regions.len(), 0);
|
||||
assert_eq!(generics.parameters.len(), 0);
|
||||
|
||||
debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
|
||||
let mut obligations = vec![];
|
||||
|
|
|
@ -1378,14 +1378,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
// method yet. So create fresh variables here for those too,
|
||||
// if there are any.
|
||||
let generics = self.tcx.generics_of(method);
|
||||
assert_eq!(substs.types().count(), generics.parent_types as usize);
|
||||
assert_eq!(substs.regions().count(), generics.parent_regions as usize);
|
||||
assert_eq!(substs.regions().count(), generics.parent_lifetimes() as usize);
|
||||
assert_eq!(substs.types().count(), generics.parent_types() as usize);
|
||||
|
||||
// Erase any late-bound regions from the method and substitute
|
||||
// in the values from the substitution.
|
||||
let xform_fn_sig = self.erase_late_bound_regions(&fn_sig);
|
||||
|
||||
if generics.types.is_empty() && generics.regions.is_empty() {
|
||||
if generics.parameters.is_empty() {
|
||||
xform_fn_sig.subst(self.tcx, substs)
|
||||
} else {
|
||||
let substs = Substs::for_item(self.tcx, method, |def, _| {
|
||||
|
|
|
@ -1239,7 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
|
|||
} else {
|
||||
for item in &m.items {
|
||||
let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
|
||||
if !generics.types.is_empty() {
|
||||
if !generics.types().is_empty() {
|
||||
let mut err = struct_span_err!(tcx.sess, item.span, E0044,
|
||||
"foreign items may not have type parameters");
|
||||
err.span_label(item.span, "can't have type parameters");
|
||||
|
@ -4799,7 +4799,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
// Skip over the lifetimes in the same segment.
|
||||
if let Some((_, generics)) = segment {
|
||||
i -= generics.regions.len();
|
||||
i -= generics.lifetimes().len();
|
||||
}
|
||||
|
||||
if let Some(ast_ty) = types.get(i) {
|
||||
|
@ -4918,11 +4918,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
// Check provided type parameters.
|
||||
let type_defs = segment.map_or(&[][..], |(_, generics)| {
|
||||
let type_defs = segment.map_or(vec![], |(_, generics)| {
|
||||
if generics.parent.is_none() {
|
||||
&generics.types[generics.has_self as usize..]
|
||||
generics.types()[generics.has_self as usize..].to_vec()
|
||||
} else {
|
||||
&generics.types
|
||||
generics.types()
|
||||
}
|
||||
});
|
||||
let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
|
||||
|
@ -4957,7 +4957,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// Check provided lifetime parameters.
|
||||
let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
|
||||
let lifetime_defs = segment.map_or(vec![], |(_, generics)| generics.lifetimes());
|
||||
let required_len = lifetime_defs.len();
|
||||
|
||||
// Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
|
||||
|
@ -5014,13 +5014,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
let segment = segment.map(|(path_segment, generics)| {
|
||||
let explicit = !path_segment.infer_types;
|
||||
let impl_trait = generics.types.iter()
|
||||
.any(|ty_param| {
|
||||
match ty_param.synthetic {
|
||||
Some(ImplTrait) => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
let impl_trait = generics.types().iter()
|
||||
.any(|ty_param| {
|
||||
match ty_param.synthetic {
|
||||
Some(ImplTrait) => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
|
||||
if explicit && impl_trait {
|
||||
let mut err = struct_span_err! {
|
||||
|
|
|
@ -641,12 +641,12 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let parent = tcx.generics_of(generics.parent.unwrap());
|
||||
let impl_params: FxHashMap<_, _> = parent.types
|
||||
.iter()
|
||||
.map(|tp| (tp.name, tp.def_id))
|
||||
.collect();
|
||||
let impl_params: FxHashMap<_, _> = parent.types()
|
||||
.iter()
|
||||
.map(|tp| (tp.name, tp.def_id))
|
||||
.collect();
|
||||
|
||||
for method_param in &generics.types {
|
||||
for method_param in generics.types() {
|
||||
if impl_params.contains_key(&method_param.name) {
|
||||
// Tighten up the span to focus on only the shadowing type
|
||||
let type_span = tcx.def_span(method_param.def_id);
|
||||
|
|
|
@ -881,8 +881,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
assert_eq!(has_self, false);
|
||||
parent_has_self = generics.has_self;
|
||||
own_start = generics.count() as u32;
|
||||
(generics.parent_regions + generics.regions.len() as u32,
|
||||
generics.parent_types + generics.types.len() as u32)
|
||||
(generics.parent_lifetimes() + generics.lifetimes().len() as u32,
|
||||
generics.parent_types() + generics.types().len() as u32)
|
||||
});
|
||||
|
||||
let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
|
||||
|
@ -971,12 +971,17 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
.map(|param| (param.def_id, param.index))
|
||||
.collect();
|
||||
|
||||
let parent_parameters = vec![parent_regions, parent_types];
|
||||
let lifetimes: Vec<ty::GenericParameterDef> =
|
||||
regions.into_iter().map(|lt| ty::GenericParameterDef::Lifetime(lt)).collect();
|
||||
let types: Vec<ty::GenericParameterDef> =
|
||||
types.into_iter().map(|ty| ty::GenericParameterDef::Type(ty)).collect();
|
||||
let parameters = lifetimes.into_iter().chain(types.into_iter()).collect();
|
||||
|
||||
tcx.alloc_generics(ty::Generics {
|
||||
parent: parent_def_id,
|
||||
parent_regions,
|
||||
parent_types,
|
||||
regions,
|
||||
types,
|
||||
parent_parameters,
|
||||
parameters,
|
||||
type_param_to_index,
|
||||
has_self: has_self || parent_has_self,
|
||||
has_late_bound_regions: has_late_bound_regions(tcx, node),
|
||||
|
|
|
@ -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);
|
||||
|
||||
// Disallow ANY unconstrained type parameters.
|
||||
for (ty_param, param) in impl_generics.types.iter().zip(impl_hir_generics.ty_params()) {
|
||||
for (ty_param, param) in impl_generics.types().iter().zip(impl_hir_generics.ty_params()) {
|
||||
let param_ty = ty::ParamTy::for_def(ty_param);
|
||||
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
|
||||
report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string());
|
||||
|
@ -122,7 +122,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
.flat_map(|def_id| {
|
||||
ctp::parameters_for(&tcx.type_of(def_id), true)
|
||||
}).collect();
|
||||
for (ty_lifetime, lifetime) in impl_generics.regions.iter()
|
||||
for (ty_lifetime, lifetime) in impl_generics.lifetimes().iter()
|
||||
.zip(impl_hir_generics.lifetimes())
|
||||
{
|
||||
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
|
||||
|
|
|
@ -225,30 +225,28 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
|
||||
fn generics_to_path_params(&self, generics: ty::Generics) -> hir::PathParameters {
|
||||
let lifetimes = HirVec::from_vec(
|
||||
generics
|
||||
.regions
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let name = if p.name == "" {
|
||||
hir::LifetimeName::Static
|
||||
} else {
|
||||
hir::LifetimeName::Name(p.name.as_symbol())
|
||||
};
|
||||
generics.lifetimes()
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let name = if p.name == "" {
|
||||
hir::LifetimeName::Static
|
||||
} else {
|
||||
hir::LifetimeName::Name(p.name.as_symbol())
|
||||
};
|
||||
|
||||
hir::Lifetime {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: DUMMY_SP,
|
||||
name,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
hir::Lifetime {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: DUMMY_SP,
|
||||
name,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
let types = HirVec::from_vec(
|
||||
generics
|
||||
.types
|
||||
.iter()
|
||||
.map(|p| P(self.ty_param_to_ty(p.clone())))
|
||||
.collect(),
|
||||
generics.types()
|
||||
.into_iter()
|
||||
.map(|p| P(self.ty_param_to_ty(p.clone())))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
hir::PathParameters {
|
||||
|
|
|
@ -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
|
||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||
// them.
|
||||
let stripped_typarams = gens.types.iter().filter_map(|tp| {
|
||||
let stripped_typarams = gens.types().iter().filter_map(|tp| {
|
||||
if tp.name == keywords::SelfType.name().as_str() {
|
||||
assert_eq!(tp.index, 0);
|
||||
None
|
||||
|
@ -1849,16 +1849,15 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
|||
// and instead see `where T: Foo + Bar + Sized + 'a`
|
||||
|
||||
Generics {
|
||||
params: gens.regions
|
||||
.clean(cx)
|
||||
.into_iter()
|
||||
.map(|lp| GenericParam::Lifetime(lp))
|
||||
.chain(
|
||||
simplify::ty_params(stripped_typarams)
|
||||
params: gens.lifetimes()
|
||||
.into_iter()
|
||||
.map(|tp| GenericParam::Type(tp))
|
||||
)
|
||||
.collect(),
|
||||
.map(|lp| GenericParam::Lifetime(lp.clean(cx)))
|
||||
.chain(
|
||||
simplify::ty_params(stripped_typarams)
|
||||
.into_iter()
|
||||
.map(|tp| GenericParam::Type(tp))
|
||||
)
|
||||
.collect(),
|
||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue