Auto merge of #48523 - varkor:generics-ty-generalisations, r=nikomatsakis
The Great Generics Generalisation: Ty Edition Part of the generic parameter refactoring effort, split off from https://github.com/rust-lang/rust/pull/48149. Contains the `ty`-relative refactoring. r? @eddyb
This commit is contained in:
commit
e44fc6c52d
48 changed files with 985 additions and 825 deletions
|
@ -224,42 +224,39 @@ 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 == "" {
|
||||
let mut lifetimes = vec![];
|
||||
let mut types = vec![];
|
||||
|
||||
for param in generics.params.iter() {
|
||||
match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => {
|
||||
let name = if param.name == "" {
|
||||
hir::LifetimeName::Static
|
||||
} else {
|
||||
hir::LifetimeName::Name(p.name.as_symbol())
|
||||
hir::LifetimeName::Name(param.name.as_symbol())
|
||||
};
|
||||
|
||||
hir::Lifetime {
|
||||
lifetimes.push(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(),
|
||||
);
|
||||
});
|
||||
}
|
||||
ty::GenericParamDefKind::Type(_) => {
|
||||
types.push(P(self.ty_param_to_ty(param.clone())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hir::PathParameters {
|
||||
lifetimes: lifetimes,
|
||||
types: types,
|
||||
lifetimes: HirVec::from_vec(lifetimes),
|
||||
types: HirVec::from_vec(types),
|
||||
bindings: HirVec::new(),
|
||||
parenthesized: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_param_to_ty(&self, param: ty::TypeParameterDef) -> hir::Ty {
|
||||
fn ty_param_to_ty(&self, param: ty::GenericParamDef) -> hir::Ty {
|
||||
debug!("ty_param_to_ty({:?}) {:?}", param, param.def_id);
|
||||
hir::Ty {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -494,7 +491,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
&self,
|
||||
tcx: TyCtxt<'b, 'c, 'd>,
|
||||
pred: ty::Predicate<'d>,
|
||||
) -> FxHashSet<GenericParam> {
|
||||
) -> FxHashSet<GenericParamDef> {
|
||||
pred.walk_tys()
|
||||
.flat_map(|t| {
|
||||
let mut regions = FxHashSet();
|
||||
|
@ -505,7 +502,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
// We only care about late bound regions, as we need to add them
|
||||
// to the 'for<>' section
|
||||
&ty::ReLateBound(_, ty::BoundRegion::BrNamed(_, name)) => {
|
||||
Some(GenericParam::Lifetime(Lifetime(name.to_string())))
|
||||
Some(GenericParamDef::Lifetime(Lifetime(name.to_string())))
|
||||
}
|
||||
&ty::ReVar(_) | &ty::ReEarlyBound(_) => None,
|
||||
_ => panic!("Unexpected region type {:?}", r),
|
||||
|
@ -853,7 +850,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
|
||||
for p in generic_params.iter_mut() {
|
||||
match p {
|
||||
&mut GenericParam::Type(ref mut ty) => {
|
||||
&mut GenericParamDef::Type(ref mut ty) => {
|
||||
// We never want something like 'impl<T=Foo>'
|
||||
ty.default.take();
|
||||
|
||||
|
@ -863,7 +860,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
ty.bounds.insert(0, TyParamBound::maybe_sized(self.cx));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
GenericParamDef::Lifetime(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ use rustc::hir::def::{self, Def, CtorKind};
|
|||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::hir::def_id::DefIndexAddressSpace;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
||||
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, GenericParamCount};
|
||||
use rustc::middle::stability;
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
@ -1336,14 +1336,18 @@ impl Clean<TyParam> for hir::TyParam {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<TyParam> for ty::TypeParameterDef {
|
||||
impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
|
||||
fn clean(&self, cx: &DocContext) -> TyParam {
|
||||
cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
|
||||
let has_default = match self.kind {
|
||||
ty::GenericParamDefKind::Type(ty) => ty.has_default,
|
||||
_ => panic!("tried to convert a non-type GenericParamDef as a type")
|
||||
};
|
||||
TyParam {
|
||||
name: self.name.clean(cx),
|
||||
did: self.def_id,
|
||||
bounds: vec![], // these are filled in from the where-clauses
|
||||
default: if self.has_default {
|
||||
default: if has_default {
|
||||
Some(cx.tcx.type_of(self.def_id).clean(cx))
|
||||
} else {
|
||||
None
|
||||
|
@ -1484,7 +1488,7 @@ impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
|
|||
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
||||
debug!(" hit an ReLateBound {:?}", reg);
|
||||
if let Some(lt) = reg.clean(cx) {
|
||||
late_bounds.push(GenericParam::Lifetime(lt));
|
||||
late_bounds.push(GenericParamDef::Lifetime(lt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1577,8 +1581,8 @@ impl Clean<Lifetime> for hir::LifetimeDef {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clean<Lifetime> for ty::RegionParameterDef {
|
||||
fn clean(&self, _: &DocContext) -> Lifetime {
|
||||
impl<'tcx> Clean<Lifetime> for ty::GenericParamDef {
|
||||
fn clean(&self, _cx: &DocContext) -> Lifetime {
|
||||
Lifetime(self.name.to_string())
|
||||
}
|
||||
}
|
||||
|
@ -1718,26 +1722,25 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
|||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum GenericParam {
|
||||
pub enum GenericParamDef {
|
||||
Lifetime(Lifetime),
|
||||
Type(TyParam),
|
||||
}
|
||||
|
||||
impl GenericParam {
|
||||
impl GenericParamDef {
|
||||
pub fn is_synthetic_type_param(&self) -> bool {
|
||||
if let GenericParam::Type(ref t) = *self {
|
||||
t.synthetic.is_some()
|
||||
} else {
|
||||
false
|
||||
match self {
|
||||
GenericParamDef::Type(ty) => ty.synthetic.is_some(),
|
||||
GenericParamDef::Lifetime(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<GenericParam> for hir::GenericParam {
|
||||
fn clean(&self, cx: &DocContext) -> GenericParam {
|
||||
impl Clean<GenericParamDef> for hir::GenericParam {
|
||||
fn clean(&self, cx: &DocContext) -> GenericParamDef {
|
||||
match *self {
|
||||
hir::GenericParam::Lifetime(ref l) => GenericParam::Lifetime(l.clean(cx)),
|
||||
hir::GenericParam::Type(ref t) => GenericParam::Type(t.clean(cx)),
|
||||
hir::GenericParam::Lifetime(ref l) => GenericParamDef::Lifetime(l.clean(cx)),
|
||||
hir::GenericParam::Type(ref t) => GenericParamDef::Type(t.clean(cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1745,7 +1748,7 @@ impl Clean<GenericParam> for hir::GenericParam {
|
|||
// maybe use a Generic enum and use Vec<Generic>?
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Default, Hash)]
|
||||
pub struct Generics {
|
||||
pub params: Vec<GenericParam>,
|
||||
pub params: Vec<GenericParamDef>,
|
||||
pub where_predicates: Vec<WherePredicate>,
|
||||
}
|
||||
|
||||
|
@ -1754,7 +1757,7 @@ impl Clean<Generics> for hir::Generics {
|
|||
let mut params = Vec::with_capacity(self.params.len());
|
||||
for p in &self.params {
|
||||
let p = p.clean(cx);
|
||||
if let GenericParam::Type(ref tp) = p {
|
||||
if let GenericParamDef::Type(ref tp) = p {
|
||||
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
|
||||
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
|
||||
}
|
||||
|
@ -1774,7 +1777,7 @@ impl Clean<Generics> for hir::Generics {
|
|||
WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
|
||||
if bounds.is_empty() {
|
||||
for param in &mut g.params {
|
||||
if let GenericParam::Type(ref mut type_param) = *param {
|
||||
if let GenericParamDef::Type(ref mut type_param) = *param {
|
||||
if &type_param.name == name {
|
||||
mem::swap(bounds, &mut type_param.bounds);
|
||||
break
|
||||
|
@ -1800,14 +1803,18 @@ 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| {
|
||||
if tp.name == keywords::SelfType.name().as_str() {
|
||||
assert_eq!(tp.index, 0);
|
||||
None
|
||||
let stripped_typarams = gens.params.iter().filter_map(|param| {
|
||||
if let ty::GenericParamDefKind::Type(_) = param.kind {
|
||||
if param.name == keywords::SelfType.name().as_str() {
|
||||
assert_eq!(param.index, 0);
|
||||
None
|
||||
} else {
|
||||
Some(param.clean(cx))
|
||||
}
|
||||
} else {
|
||||
Some(tp.clean(cx))
|
||||
None
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
}).collect::<Vec<TyParam>>();
|
||||
|
||||
let mut where_predicates = preds.predicates.to_vec().clean(cx);
|
||||
|
||||
|
@ -1849,16 +1856,20 @@ 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)
|
||||
.into_iter()
|
||||
.map(|tp| GenericParam::Type(tp))
|
||||
)
|
||||
.collect(),
|
||||
params: gens.params
|
||||
.iter()
|
||||
.flat_map(|param| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
Some(GenericParamDef::Lifetime(param.clean(cx)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).chain(
|
||||
simplify::ty_params(stripped_typarams)
|
||||
.into_iter()
|
||||
.map(|tp| GenericParamDef::Type(tp))
|
||||
)
|
||||
.collect(),
|
||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||
}
|
||||
}
|
||||
|
@ -2349,7 +2360,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
|||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct PolyTrait {
|
||||
pub trait_: Type,
|
||||
pub generic_params: Vec<GenericParam>,
|
||||
pub generic_params: Vec<GenericParamDef>,
|
||||
}
|
||||
|
||||
/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
|
||||
|
@ -2676,20 +2687,34 @@ impl Clean<Type> for hir::Ty {
|
|||
let mut ty_substs = FxHashMap();
|
||||
let mut lt_substs = FxHashMap();
|
||||
provided_params.with_parameters(|provided_params| {
|
||||
for (i, ty_param) in generics.ty_params().enumerate() {
|
||||
let ty_param_def = Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
|
||||
if let Some(ty) = provided_params.types.get(i).cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
||||
} else if let Some(default) = ty_param.default.clone() {
|
||||
ty_substs.insert(ty_param_def, default.into_inner().clean(cx));
|
||||
}
|
||||
}
|
||||
|
||||
for (i, lt_param) in generics.lifetimes().enumerate() {
|
||||
if let Some(lt) = provided_params.lifetimes.get(i).cloned() {
|
||||
if !lt.is_elided() {
|
||||
let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id);
|
||||
lt_substs.insert(lt_def_id, lt.clean(cx));
|
||||
let mut indices = GenericParamCount {
|
||||
lifetimes: 0,
|
||||
types: 0
|
||||
};
|
||||
for param in generics.params.iter() {
|
||||
match param {
|
||||
hir::GenericParam::Lifetime(lt_param) => {
|
||||
if let Some(lt) = provided_params.lifetimes
|
||||
.get(indices.lifetimes).cloned() {
|
||||
if !lt.is_elided() {
|
||||
let lt_def_id =
|
||||
cx.tcx.hir.local_def_id(lt_param.lifetime.id);
|
||||
lt_substs.insert(lt_def_id, lt.clean(cx));
|
||||
}
|
||||
}
|
||||
indices.lifetimes += 1;
|
||||
}
|
||||
hir::GenericParam::Type(ty_param) => {
|
||||
let ty_param_def =
|
||||
Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
|
||||
if let Some(ty) = provided_params.types
|
||||
.get(indices.types).cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
||||
} else if let Some(default) = ty_param.default.clone() {
|
||||
ty_substs.insert(ty_param_def,
|
||||
default.into_inner().clean(cx));
|
||||
}
|
||||
indices.types += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3425,7 +3450,7 @@ impl Clean<Item> for doctree::Typedef {
|
|||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct BareFunctionDecl {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub generic_params: Vec<GenericParam>,
|
||||
pub generic_params: Vec<GenericParamDef>,
|
||||
pub decl: FnDecl,
|
||||
pub abi: Abi,
|
||||
}
|
||||
|
@ -4184,7 +4209,7 @@ struct RegionDeps<'tcx> {
|
|||
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||
enum SimpleBound {
|
||||
RegionBound(Lifetime),
|
||||
TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParam>, hir::TraitBoundModifier)
|
||||
TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier)
|
||||
}
|
||||
|
||||
enum AutoTraitResult {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue