Skip to content

Commit

Permalink
Auto merge of #48523 - varkor:generics-ty-generalisations, r=nikomats…
Browse files Browse the repository at this point in the history
…akis

The Great Generics Generalisation: Ty Edition

Part of the generic parameter refactoring effort, split off from #48149. Contains the `ty`-relative refactoring.

r? @eddyb
  • Loading branch information
bors committed May 15, 2018
2 parents f0fdaba + 5be2bdb commit e44fc6c
Show file tree
Hide file tree
Showing 48 changed files with 966 additions and 806 deletions.
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

0 comments on commit e44fc6c

Please sign in to comment.