Skip to content
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

The Great Generics Generalisation: Ty Edition #48523

Merged
merged 40 commits into from
May 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
fe0c119
Consolidate ty::Generics
varkor Mar 8, 2018
de1c29c
Reduce parent_params to parent_count
varkor Feb 24, 2018
6355354
Rename ty::Generics::parameters to params
varkor Feb 24, 2018
e9e3d57
Rename ty::GenericParameterDef to GenericParam
varkor Feb 25, 2018
e5825c2
Prefer iterator to vec
varkor Feb 25, 2018
5b4e2b7
Inline Generics::own_count
varkor Mar 8, 2018
a9622dc
Fix generics type parameter handling in miri
varkor Mar 12, 2018
15d2759
Rename `has_type_parameters` to `requires_monomorphization`
varkor Apr 12, 2018
178a8f1
Rename GenericParam to GenericParamDef
varkor Apr 12, 2018
06f0a7c
Rename TypeParameterDef -> TypeParamDef and RegionParameterDef -> Reg…
varkor Apr 12, 2018
cadf96e
Fix tidy errors caused by renaming
varkor Apr 12, 2018
4a6c946
Generalise cases of explicit iteration of specific kinds
varkor Apr 12, 2018
b75f421
Generalise more cases of explicit iteration of specific kinds
varkor Apr 13, 2018
d557ff9
Eliminate ty::Generics::lifetimes()
varkor Apr 13, 2018
0b8b14f
Eliminate ty::Generics::types()
varkor Apr 14, 2018
6f257bf
Correct variable renaming fallout
varkor Apr 14, 2018
a17896a
Place Self at the start of ty::Generics' param lists
varkor Apr 15, 2018
7b45a89
Use GenericParamCount instead of FxHashMap
varkor Apr 18, 2018
df1c256
Replace type_param_to_index with param_def_id_to_index
varkor Apr 18, 2018
d62fc23
Refactor to address comments
varkor Apr 18, 2018
fc27c2e
Fix typo in late-bound region testing message
varkor Apr 18, 2018
5e89312
Inline get_type
varkor Apr 18, 2018
4bed895
Pull common parameters into GenericParamDef
varkor Apr 18, 2018
9f9d4be
Rename RegionParamDef to LifetimeParamDef
varkor Apr 18, 2018
18f77e2
Fix rebase fallout
varkor Apr 27, 2018
9200bde
Refactor generic params loops
varkor May 10, 2018
007de2f
Lift pure_wrt_drop to GenericParamDef
varkor May 10, 2018
365c8c3
Remove GenericParamDef::to_type
varkor May 10, 2018
fd8e284
Rename param_counts to own_counts
varkor May 10, 2018
fe1f651
Review refactoring
varkor May 11, 2018
b575c18
Refactoring generic counting loops
varkor May 11, 2018
25bf73d
Update bad-annotation error message
varkor May 11, 2018
030f10f
Clean up generic param handling
varkor May 14, 2018
d9190da
Refactor Substs methods on generic parameters
varkor May 14, 2018
3ae2468
Clean up shared subst code
varkor May 14, 2018
e9c28b2
Use Kind instead of UnpackedKind in Substs methods
varkor May 15, 2018
0a9371a
Add mk_param_from_def
varkor May 15, 2018
39a68e9
Clean up dropck_outlives PhantomData handling
varkor May 15, 2018
5ea91ac
Collapse Substs::identity_for_item in collect
varkor May 15, 2018
5be2bdb
One must always remember to clean up after themselves
varkor May 15, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1459,10 +1459,9 @@ impl<'a> LoweringContext<'a> {
return n;
}
assert!(!def_id.is_local());
let n = self.cstore
.item_generics_cloned_untracked(def_id, self.sess)
.regions
.len();
let item_generics =
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
let n = item_generics.own_counts().lifetimes;
self.type_def_lifetime_params.insert(def_id, n);
n
});
Expand Down
46 changes: 16 additions & 30 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,54 +735,40 @@ 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_count,
ref params,

// Reverse map to each `TypeParameterDef`'s `index` field, from
// Reverse map to each `TypeParamDef`'s `index` field, from
// `def_id.index` (`def_id.krate` is the same as the item's).
type_param_to_index: _, // Don't hash this
param_def_id_to_index: _, // Don't hash this
has_self,
has_late_bound_regions,
} = *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_count.hash_stable(hcx, hasher);
params.hash_stable(hcx, hasher);
has_self.hash_stable(hcx, hasher);
has_late_bound_regions.hash_stable(hcx, hasher);
}
}

impl<'a> HashStable<StableHashingContext<'a>>
for ty::RegionParameterDef {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let ty::RegionParameterDef {
name,
def_id,
index,
pure_wrt_drop
} = *self;

name.hash_stable(hcx, hasher);
def_id.hash_stable(hcx, hasher);
index.hash_stable(hcx, hasher);
pure_wrt_drop.hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(enum ty::GenericParamDefKind {
Lifetime,
Type(ty)
});

impl_stable_hash_for!(struct ty::TypeParameterDef {
impl_stable_hash_for!(struct ty::GenericParamDef {
name,
def_id,
index,
pure_wrt_drop,
kind
});

impl_stable_hash_for!(struct ty::TypeParamDef {
has_default,
object_lifetime_default,
pure_wrt_drop,
synthetic
});

Expand Down
16 changes: 8 additions & 8 deletions src/librustc/infer/anon_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use infer::outlives::free_region_map::FreeRegionRelations;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast;
use traits::{self, PredicateObligation};
use ty::{self, Ty, TyCtxt};
use ty::{self, Ty, TyCtxt, GenericParamDefKind};
use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
use ty::outlives::Component;
use ty::subst::{Kind, Substs, UnpackedKind};
Expand Down Expand Up @@ -313,12 +313,13 @@ 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 {
// Find the index of this region in the list of substitutions.
let index = region_def.index as usize;

for param in &abstract_type_generics.params {
match param.kind {
GenericParamDefKind::Lifetime => {}
_ => continue
}
// Get the value supplied for this region from the substs.
let subst_arg = anon_defn.substs.region_at(index);
let subst_arg = anon_defn.substs.region_at(param.index as usize);

// Compute the least upper bound of it with the other regions.
debug!("constrain_anon_types: least_region={:?}", least_region);
Expand Down Expand Up @@ -616,10 +617,9 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
// during trans.

let generics = self.tcx.generics_of(def_id);
let parent_len = generics.parent_count();
let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
|(index, &kind)| {
if index < parent_len {
if index < generics.parent_count {
// Accommodate missing regions in the parent kinds...
self.fold_kind_mapping_missing_regions_to_empty(kind)
} else {
Expand Down
67 changes: 33 additions & 34 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use hir::def_id::DefId;
use middle::free_region::RegionRelations;
use middle::region;
use middle::lang_items;
use ty::subst::Substs;
use ty::subst::{Kind, Substs};
use ty::{TyVid, IntVid, FloatVid};
use ty::{self, Ty, TyCtxt};
use ty::{self, Ty, TyCtxt, GenericParamDefKind};
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use ty::fold::TypeFoldable;
use ty::relate::RelateResult;
Expand Down Expand Up @@ -905,34 +905,35 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.next_region_var(RegionVariableOrigin::NLL(origin))
}

/// Create a region inference variable for the given
/// region parameter definition.
pub fn region_var_for_def(&self,
span: Span,
def: &ty::RegionParameterDef)
-> ty::Region<'tcx> {
self.next_region_var(EarlyBoundRegion(span, def.name))
}

/// Create a type inference variable for the given
/// type parameter definition. The substitutions are
/// for actual parameters that may be referred to by
/// the default of this type parameter, if it exists.
/// E.g. `struct Foo<A, B, C = (A, B)>(...);` when
/// used in a path such as `Foo::<T, U>::new()` will
/// use an inference variable for `C` with `[T, U]`
/// as the substitutions for the default, `(T, U)`.
pub fn type_var_for_def(&self,
span: Span,
def: &ty::TypeParameterDef)
-> Ty<'tcx> {
let ty_var_id = self.type_variables
.borrow_mut()
.new_var(self.universe(),
false,
TypeVariableOrigin::TypeParameterDefinition(span, def.name));

self.tcx.mk_var(ty_var_id)
pub fn var_for_def(&self,
span: Span,
param: &ty::GenericParamDef)
-> Kind<'tcx> {
match param.kind {
GenericParamDefKind::Lifetime => {
// Create a region inference variable for the given
// region parameter definition.
self.next_region_var(EarlyBoundRegion(span, param.name)).into()
}
GenericParamDefKind::Type(_) => {
// Create a type inference variable for the given
// type parameter definition. The substitutions are
// for actual parameters that may be referred to by
// the default of this type parameter, if it exists.
// E.g. `struct Foo<A, B, C = (A, B)>(...);` when
// used in a path such as `Foo::<T, U>::new()` will
// use an inference variable for `C` with `[T, U]`
// as the substitutions for the default, `(T, U)`.
let ty_var_id =
self.type_variables
.borrow_mut()
.new_var(self.universe(),
false,
TypeVariableOrigin::TypeParameterDefinition(span, param.name));

self.tcx.mk_var(ty_var_id).into()
}
}
}

/// Given a set of generics defined on a type or impl, returns a substitution mapping each
Expand All @@ -941,10 +942,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span,
def_id: DefId)
-> &'tcx Substs<'tcx> {
Substs::for_item(self.tcx, def_id, |def, _| {
self.region_var_for_def(span, def)
}, |def, _| {
self.type_var_for_def(span, def)
Substs::for_item(self.tcx, def_id, |param, _| {
self.var_for_def(span, param)
})
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#![cfg_attr(stage0, feature(dyn_trait))]
#![feature(from_ref)]
#![feature(fs_read_write)]
#![feature(iterator_find_map)]
#![cfg_attr(windows, feature(libc))]
#![cfg_attr(stage0, feature(macro_lifetime_matcher))]
#![feature(macro_vis_matcher)]
Expand Down
17 changes: 12 additions & 5 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use hir::map::Map;
use hir::ItemLocalId;
use hir::LifetimeName;
use ty::{self, TyCtxt};
use ty::{self, TyCtxt, GenericParamDefKind};

use errors::DiagnosticBuilder;
use rustc::lint;
Expand Down Expand Up @@ -667,8 +667,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
for lt_def in generics.lifetimes() {
let (lt_name, region) = Region::early(&self.tcx.hir, &mut index, &lt_def);
if let hir::LifetimeName::Underscore = lt_name {
// Pick the elided lifetime "definition" if one exists and use it to make an
// elision scope.
// Pick the elided lifetime "definition" if one exists and use it to make
// an elision scope.
elision = Some(region);
} else {
lifetimes.insert(lt_name, region);
Expand Down Expand Up @@ -1659,9 +1659,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
.entry(def_id)
.or_insert_with(|| {
tcx.generics_of(def_id)
.types
.params
.iter()
.map(|def| def.object_lifetime_default)
.filter_map(|param| {
match param.kind {
GenericParamDefKind::Type(ty) => {
Some(ty.object_lifetime_default)
}
GenericParamDefKind::Lifetime => None,
}
})
.collect()
})
};
Expand Down
9 changes: 7 additions & 2 deletions src/librustc/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
});

let names_map: FxHashSet<String> = generics
.regions
.params
.iter()
.map(|l| l.name.to_string())
.filter_map(|param| {
match param.kind {
ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
_ => None
}
})
.collect();

let body_ids: FxHashSet<_> = infcx
Expand Down
14 changes: 9 additions & 5 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use std::fmt;
use syntax::ast;
use session::DiagnosticMessageId;
use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use ty::GenericParamDefKind;
use ty::error::ExpectedFound;
use ty::fast_reject;
use ty::fold::TypeFolder;
Expand Down Expand Up @@ -378,12 +379,15 @@ 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.params.iter() {
let value = match param.kind {
GenericParamDefKind::Type(_) => {
trait_ref.substs[param.index as usize].to_string()
},
GenericParamDefKind::Lifetime => continue,
};
let name = param.name.to_string();
let ty = trait_ref.substs.type_for_def(param);
let ty_str = ty.to_string();
flags.push((name.clone(),
Some(ty_str.clone())));
flags.push((name, Some(value)));
}

if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
Expand Down
14 changes: 9 additions & 5 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use infer::outlives::env::OutlivesEnvironment;
use middle::region;
use middle::const_val::ConstEvalErr;
use ty::subst::Substs;
use ty::{self, AdtKind, Slice, Ty, TyCtxt, TypeFoldable, ToPredicate};
use ty::{self, AdtKind, Slice, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
use ty::error::{ExpectedFound, TypeError};
use infer::{InferCtxt};

Expand Down Expand Up @@ -841,10 +841,14 @@ fn vtable_methods<'a, 'tcx>(
// the method may have some early-bound lifetimes, add
// regions for those
let substs = trait_ref.map_bound(|trait_ref| {
Substs::for_item(
tcx, def_id,
|_, _| tcx.types.re_erased,
|def, _| trait_ref.substs.type_for_def(def))
Substs::for_item(tcx, def_id, |param, _| {
match param.kind {
GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
GenericParamDefKind::Type(_) => {
trait_ref.substs[param.index as usize]
}
}
})
});

// the trait type may have higher-ranked lifetimes in it;
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).own_counts().types != 0 {
return Some(MethodViolationCode::Generic);
}

Expand Down Expand Up @@ -387,7 +387,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

pub(super) fn is_object_safe_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_def_id: DefId)
-> bool {
trait_def_id: DefId) -> bool {
tcx.object_safety_violations(trait_def_id).is_empty()
}
Loading