提交 3e88b5bb 编写于 作者: N Niko Matsakis

Rote changes to fix fallout throughout the compiler from splitting the

predicates and renaming some things.
上级 3764699c
......@@ -283,7 +283,7 @@ pub fn overlapping_impls(infcx: &InferCtxt,
/// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
cause: ObligationCause<'tcx>,
generic_bounds: &ty::GenericBounds<'tcx>)
generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-> PredicateObligations<'tcx>
{
util::predicates_for_generics(tcx, cause, 0, generic_bounds)
......
......@@ -130,7 +130,10 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
let free_substs = ty::construct_free_substs(tcx, &trait_def.generics, ast::DUMMY_NODE_ID);
let predicates = trait_def.generics.to_bounds(tcx, &free_substs).predicates.into_vec();
let trait_predicates = ty::lookup_predicates(tcx, trait_def_id);
let predicates = trait_predicates.instantiate(tcx, &free_substs).predicates.into_vec();
elaborate_predicates(tcx, predicates)
.any(|predicate| {
match predicate {
......
......@@ -561,8 +561,8 @@ fn assemble_candidates_from_trait_def<'cx,'tcx>(
};
// If so, extract what we know from the trait and try to come up with a good answer.
let trait_def = ty::lookup_trait_def(selcx.tcx(), trait_ref.def_id);
let bounds = trait_def.generics.to_bounds(selcx.tcx(), trait_ref.substs);
let trait_predicates = ty::lookup_predicates(selcx.tcx(), trait_ref.def_id);
let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs);
assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
candidate_set, bounds.predicates.into_vec());
}
......
......@@ -923,8 +923,8 @@ fn match_projection_obligation_against_bounds_from_trait(
projection_trait_ref={}",
projection_trait_ref.repr(self.tcx()));
let trait_def = ty::lookup_trait_def(self.tcx(), projection_trait_ref.def_id);
let bounds = trait_def.generics.to_bounds(self.tcx(), projection_trait_ref.substs);
let trait_predicates = ty::lookup_predicates(self.tcx(), projection_trait_ref.def_id);
let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
debug!("match_projection_obligation_against_bounds_from_trait: \
bounds={}",
bounds.repr(self.tcx()));
......@@ -2314,8 +2314,8 @@ fn impl_obligations(&mut self,
snapshot: &infer::CombinedSnapshot)
-> VecPerParamSpace<PredicateObligation<'tcx>>
{
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
let bounds = impl_bounds.instantiate(self.tcx(), impl_substs);
let normalized_bounds =
project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
let normalized_bounds =
......
......@@ -290,7 +290,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
cause: ObligationCause<'tcx>,
recursion_depth: uint,
generic_bounds: &ty::GenericBounds<'tcx>)
generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-> VecPerParamSpace<PredicateObligation<'tcx>>
{
debug!("predicates_for_generics(generic_bounds={})",
......
......@@ -2153,10 +2153,12 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx
match ty::impl_or_trait_item(cx, method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
construct_parameter_environment(
cx,
method.span,
method_generics,
method_bounds,
method.pe_body().id)
}
TypeTraitItem(_) => {
......@@ -2188,10 +2190,12 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx
match ty::impl_or_trait_item(cx, method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
construct_parameter_environment(
cx,
method.span,
method_generics,
method_bounds,
method.pe_body().id)
}
TypeTraitItem(_) => {
......@@ -2214,11 +2218,13 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx
ast::ItemFn(_, _, _, _, ref body) => {
// We assume this is a function.
let fn_def_id = ast_util::local_def(id);
let fn_pty = ty::lookup_item_type(cx, fn_def_id);
let fn_scheme = lookup_item_type(cx, fn_def_id);
let fn_predicates = lookup_predicates(cx, fn_def_id);
construct_parameter_environment(cx,
item.span,
&fn_pty.generics,
&fn_scheme.generics,
&fn_predicates,
body.id)
}
ast::ItemEnum(..) |
......@@ -2227,8 +2233,13 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx
ast::ItemConst(..) |
ast::ItemStatic(..) => {
let def_id = ast_util::local_def(id);
let pty = ty::lookup_item_type(cx, def_id);
construct_parameter_environment(cx, item.span, &pty.generics, id)
let scheme = lookup_item_type(cx, def_id);
let predicates = lookup_predicates(cx, def_id);
construct_parameter_environment(cx,
item.span,
&scheme.generics,
&predicates,
id)
}
_ => {
cx.sess.span_bug(item.span,
......@@ -6320,7 +6331,7 @@ pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvi
/// parameters in the same way, this only has an effect on regions.
pub fn construct_free_substs<'a,'tcx>(
tcx: &'a ctxt<'tcx>,
generics: &ty::Generics<'tcx>,
generics: &Generics<'tcx>,
free_id: ast::NodeId)
-> Substs<'tcx>
{
......@@ -6365,6 +6376,7 @@ pub fn construct_parameter_environment<'a,'tcx>(
tcx: &'a ctxt<'tcx>,
span: Span,
generics: &ty::Generics<'tcx>,
generic_predicates: &ty::GenericPredicates<'tcx>,
free_id: ast::NodeId)
-> ParameterEnvironment<'a, 'tcx>
{
......@@ -6379,7 +6391,7 @@ pub fn construct_parameter_environment<'a,'tcx>(
// Compute the bounds on Self and the type parameters.
//
let bounds = generics.to_bounds(tcx, &free_substs);
let bounds = generic_predicates.instantiate(tcx, &free_substs);
let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
let predicates = bounds.predicates.into_vec();
......@@ -7013,8 +7025,7 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
impl<'tcx> RegionEscape for TypeScheme<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
self.ty.has_regions_escaping_depth(depth) ||
self.generics.has_regions_escaping_depth(depth)
self.ty.has_regions_escaping_depth(depth)
}
}
......@@ -7024,7 +7035,7 @@ fn has_regions_escaping_depth(&self, depth: u32) -> bool {
}
}
impl<'tcx> RegionEscape for Generics<'tcx> {
impl<'tcx> RegionEscape for GenericPredicates<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
self.predicates.has_regions_escaping_depth(depth)
}
......@@ -7133,7 +7144,7 @@ fn has_projection_types(&self) -> bool {
}
}
impl<'tcx> HasProjectionTypes for ty::GenericBounds<'tcx> {
impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
fn has_projection_types(&self) -> bool {
self.predicates.has_projection_types()
}
......
......@@ -400,6 +400,13 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Generics<'tcx> {
ty::Generics {
types: self.types.fold_with(folder),
regions: self.regions.fold_with(folder),
}
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::GenericPredicates<'tcx> {
ty::GenericPredicates {
predicates: self.predicates.fold_with(folder),
}
}
......@@ -440,9 +447,9 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ProjectionTy<'tc
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::GenericBounds<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::GenericBounds<'tcx> {
ty::GenericBounds {
impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::InstantiatedPredicates<'tcx> {
ty::InstantiatedPredicates {
predicates: self.predicates.fold_with(folder),
}
}
......
......@@ -467,8 +467,14 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
}
};
instantiate_path(pcx.fcx, path, ty::lookup_item_type(tcx, enum_def_id),
None, def, pat.span, pat.id);
instantiate_path(pcx.fcx,
path,
ty::lookup_item_type(tcx, enum_def_id),
&ty::lookup_predicates(tcx, enum_def_id),
None,
def,
pat.span,
pat.id);
let pat_ty = fcx.node_ty(pat.id);
demand::eqtype(fcx, pat.span, expected, pat_ty);
......@@ -499,6 +505,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
.map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
let ctor_scheme = ty::lookup_item_type(tcx, enum_def);
let ctor_predicates = ty::lookup_predicates(tcx, enum_def);
let path_scheme = if ty::is_fn_ty(ctor_scheme.ty) {
let fn_ret = ty::assert_no_late_bound_regions(tcx, &ty::ty_fn_ret(ctor_scheme.ty));
ty::TypeScheme {
......@@ -508,7 +515,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
} else {
ctor_scheme
};
instantiate_path(pcx.fcx, path, path_scheme, None, def, pat.span, pat.id);
instantiate_path(pcx.fcx, path, path_scheme, &ctor_predicates, None, def, pat.span, pat.id);
let pat_ty = fcx.node_ty(pat.id);
demand::eqtype(fcx, pat.span, expected, pat_ty);
......
......@@ -205,7 +205,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
// however, because we want to replace all late-bound regions with
// region variables.
let impl_bounds =
impl_m.generics.to_bounds(tcx, impl_to_skol_substs);
impl_m.predicates.instantiate(tcx, impl_to_skol_substs);
let (impl_bounds, _) =
infcx.replace_late_bound_regions_with_fresh_var(
......@@ -216,7 +216,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_bounds.repr(tcx));
// Normalize the associated types in the trait_bounds.
let trait_bounds = trait_m.generics.to_bounds(tcx, &trait_to_skol_substs);
let trait_bounds = trait_m.predicates.instantiate(tcx, &trait_to_skol_substs);
// Obtain the predicate split predicate sets for each.
let trait_pred = trait_bounds.predicates.split();
......
......@@ -131,8 +131,9 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
let dtor_typescheme = ty::lookup_item_type(rcx.tcx(), impl_did);
let dtor_generics = dtor_typescheme.generics;
let dtor_predicates = ty::lookup_predicates(rcx.tcx(), impl_did);
let has_pred_of_interest = dtor_generics.predicates.iter().any(|pred| {
let has_pred_of_interest = dtor_predicates.predicates.iter().any(|pred| {
// In `impl<T> Drop where ...`, we automatically
// assume some predicate will be meaningful and thus
// represents a type through which we could reach
......
......@@ -46,7 +46,7 @@ struct InstantiatedMethodSig<'tcx> {
/// Generic bounds on the method's parameters which must be added
/// as pending obligations.
method_bounds: ty::GenericBounds<'tcx>,
method_predicates: ty::InstantiatedPredicates<'tcx>,
}
pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
......@@ -99,7 +99,7 @@ fn confirm(&mut self,
// Create the final signature for the method, replacing late-bound regions.
let InstantiatedMethodSig {
method_sig, all_substs, method_bounds
method_sig, all_substs, method_predicates
} = self.instantiate_method_sig(&pick, all_substs);
let method_self_ty = method_sig.inputs[0];
......@@ -107,7 +107,7 @@ fn confirm(&mut self,
self.unify_receivers(self_ty, method_self_ty);
// Add any trait/regions obligations specified on the method's type parameters.
self.add_obligations(&pick, &all_substs, &method_bounds);
self.add_obligations(&pick, &all_substs, &method_predicates);
// Create the final `MethodCallee`.
let fty = ty::mk_bare_fn(self.tcx(), None, self.tcx().mk_bare_fn(ty::BareFnTy {
......@@ -416,18 +416,19 @@ fn instantiate_method_sig(&mut self,
// that obligation is not necessarily satisfied. (In the
// future, it would be.) But we know that the true `Self` DOES implement
// the trait. So we just delete this requirement. Hack hack hack.
let mut method_bounds = pick.method_ty.generics.to_bounds(self.tcx(), &all_substs);
let mut method_predicates = pick.method_ty.predicates.instantiate(self.tcx(), &all_substs);
match pick.kind {
probe::ObjectPick(..) => {
assert_eq!(method_bounds.predicates.get_slice(subst::SelfSpace).len(), 1);
method_bounds.predicates.pop(subst::SelfSpace);
assert_eq!(method_predicates.predicates.get_slice(subst::SelfSpace).len(), 1);
method_predicates.predicates.pop(subst::SelfSpace);
}
_ => { }
}
let method_bounds = self.fcx.normalize_associated_types_in(self.span, &method_bounds);
let method_predicates = self.fcx.normalize_associated_types_in(self.span,
&method_predicates);
debug!("method_bounds after subst = {}",
method_bounds.repr(self.tcx()));
debug!("method_predicates after subst = {}",
method_predicates.repr(self.tcx()));
// Instantiate late-bound regions and substitute the trait
// parameters into the method type to get the actual method type.
......@@ -446,22 +447,22 @@ fn instantiate_method_sig(&mut self,
InstantiatedMethodSig {
method_sig: method_sig,
all_substs: all_substs,
method_bounds: method_bounds,
method_predicates: method_predicates,
}
}
fn add_obligations(&mut self,
pick: &probe::Pick<'tcx>,
all_substs: &subst::Substs<'tcx>,
method_bounds: &ty::GenericBounds<'tcx>) {
debug!("add_obligations: pick={} all_substs={} method_bounds={}",
method_predicates: &ty::InstantiatedPredicates<'tcx>) {
debug!("add_obligations: pick={} all_substs={} method_predicates={}",
pick.repr(self.tcx()),
all_substs.repr(self.tcx()),
method_bounds.repr(self.tcx()));
method_predicates.repr(self.tcx()));
self.fcx.add_obligations_for_parameters(
traits::ObligationCause::misc(self.span, self.fcx.body_id),
method_bounds);
method_predicates);
self.fcx.add_default_region_param_bounds(
all_substs,
......
......@@ -221,7 +221,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
//
// Note that as the method comes from a trait, it should not have
// any late-bound regions appearing in its bounds.
let method_bounds = fcx.instantiate_bounds(span, trait_ref.substs, &method_ty.generics);
let method_bounds = fcx.instantiate_bounds(span, trait_ref.substs, &method_ty.predicates);
assert!(!method_bounds.has_escaping_regions());
fcx.add_obligations_for_parameters(
traits::ObligationCause::misc(span, fcx.body_id),
......
......@@ -666,8 +666,9 @@ fn assemble_projection_candidates(&mut self,
debug!("assemble_projection_candidates: projection_trait_ref={}",
projection_trait_ref.repr(self.tcx()));
let trait_def = ty::lookup_trait_def(self.tcx(), projection_trait_ref.def_id);
let bounds = trait_def.generics.to_bounds(self.tcx(), projection_trait_ref.substs);
let trait_predicates = ty::lookup_predicates(self.tcx(),
projection_trait_ref.def_id);
let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
let predicates = bounds.predicates.into_vec();
debug!("assemble_projection_candidates: predicates={}",
predicates.repr(self.tcx()));
......@@ -943,8 +944,8 @@ fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>) -> bool {
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
// Check whether the impl imposes obligations we have to worry about.
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
let impl_bounds = impl_generics.to_bounds(self.tcx(), substs);
let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
let impl_bounds = impl_bounds.instantiate(self.tcx(), substs);
let traits::Normalized { value: impl_bounds,
obligations: norm_obligations } =
traits::normalize(selcx, cause.clone(), &impl_bounds);
......
......@@ -93,7 +93,7 @@
use middle::region::{self, CodeExtent};
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
use middle::traits;
use middle::ty::{FnSig, VariantInfo, TypeScheme};
use middle::ty::{FnSig, GenericPredicates, VariantInfo, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
use middle::ty::{self, HasProjectionTypes, RegionEscape, Ty};
use middle::ty::liberate_late_bound_regions;
......@@ -101,7 +101,7 @@
use middle::ty_fold::{TypeFolder, TypeFoldable};
use rscope::RegionScope;
use session::Session;
use {CrateCtxt, lookup_def_ccx, no_params, require_same_types};
use {CrateCtxt, lookup_def_ccx, require_same_types};
use TypeAndSubsts;
use lint;
use util::common::{block_query, indenter, loop_query};
......@@ -1446,11 +1446,11 @@ fn instantiate_type_scheme<T>(&self,
fn instantiate_bounds(&self,
span: Span,
substs: &Substs<'tcx>,
generics: &ty::Generics<'tcx>)
-> ty::GenericBounds<'tcx>
bounds: &ty::GenericPredicates<'tcx>)
-> ty::InstantiatedPredicates<'tcx>
{
ty::GenericBounds {
predicates: self.instantiate_type_scheme(span, substs, &generics.predicates)
ty::InstantiatedPredicates {
predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
}
}
......@@ -1561,12 +1561,14 @@ pub fn instantiate_type(&self,
{
let type_scheme =
ty::lookup_item_type(self.tcx(), def_id);
let type_predicates =
ty::lookup_predicates(self.tcx(), def_id);
let substs =
self.infcx().fresh_substs_for_generics(
span,
&type_scheme.generics);
let bounds =
self.instantiate_bounds(span, &substs, &type_scheme.generics);
self.instantiate_bounds(span, &substs, &type_predicates);
self.add_obligations_for_parameters(
traits::ObligationCause::new(
span,
......@@ -1594,7 +1596,8 @@ fn instantiate_struct_literal_ty(&self,
{
let tcx = self.tcx();
let ty::TypeScheme { generics, ty: decl_ty } = ty::lookup_item_type(tcx, did);
let ty::TypeScheme { generics, ty: decl_ty } =
ty::lookup_item_type(tcx, did);
let wants_params =
generics.has_type_params(TypeSpace) || generics.has_region_params(TypeSpace);
......@@ -1843,16 +1846,16 @@ pub fn add_default_region_param_bounds(&self,
/// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
pub fn add_obligations_for_parameters(&self,
cause: traits::ObligationCause<'tcx>,
generic_bounds: &ty::GenericBounds<'tcx>)
predicates: &ty::InstantiatedPredicates<'tcx>)
{
assert!(!generic_bounds.has_escaping_regions());
assert!(!predicates.has_escaping_regions());
debug!("add_obligations_for_parameters(generic_bounds={})",
generic_bounds.repr(self.tcx()));
debug!("add_obligations_for_parameters(predicates={})",
predicates.repr(self.tcx()));
let obligations = traits::predicates_for_generics(self.tcx(),
cause,
generic_bounds);
predicates);
obligations.map_move(|o| self.register_predicate(o));
}
......@@ -3616,8 +3619,8 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
}
ast::ExprPath(ref path) => {
let defn = lookup_def(fcx, path.span, id);
let pty = type_scheme_for_def(fcx, expr.span, defn);
instantiate_path(fcx, path, pty, None, defn, expr.span, expr.id);
let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
instantiate_path(fcx, path, scheme, &predicates, None, defn, expr.span, expr.id);
// We always require that the type provided as the value for
// a type parameter outlives the moment of instantiation.
......@@ -3629,10 +3632,10 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
astconv::instantiate_trait_ref(fcx, fcx, &*qpath.trait_ref, Some(self_ty), None);
let defn = lookup_def(fcx, expr.span, id);
let pty = type_scheme_for_def(fcx, expr.span, defn);
let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
let mut path = qpath.trait_ref.path.clone();
path.segments.push(qpath.item_path.clone());
instantiate_path(fcx, &path, pty, Some(self_ty), defn, expr.span, expr.id);
instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty), defn, expr.span, expr.id);
// We always require that the type provided as the value for
// a type parameter outlives the moment of instantiation.
......@@ -4048,9 +4051,9 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
};
if let Some(did) = did {
let polytype = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
let substs = Substs::new_type(vec![idx_type], vec![]);
let bounds = fcx.instantiate_bounds(expr.span, &substs, &polytype.generics);
let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
fcx.add_obligations_for_parameters(
traits::ObligationCause::new(expr.span,
fcx.body_id,
......@@ -4631,46 +4634,36 @@ pub fn lookup_def(fcx: &FnCtxt, sp: Span, id: ast::NodeId) -> def::Def {
}
// Returns the type parameter count and the type for the given definition.
pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
sp: Span,
defn: def::Def)
-> TypeScheme<'tcx> {
fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
sp: Span,
defn: def::Def)
-> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
match defn {
def::DefLocal(nid) | def::DefUpvar(nid, _) => {
let typ = fcx.local_ty(sp, nid);
return no_params(typ);
}
def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) | def::DefConst(id) => {
return ty::lookup_item_type(fcx.ccx.tcx, id);
}
def::DefTrait(_) |
def::DefTy(..) |
def::DefAssociatedTy(..) |
def::DefAssociatedPath(..) |
def::DefPrimTy(_) |
def::DefTyParam(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type");
}
def::DefMod(..) | def::DefForeignMod(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found module");
}
def::DefUse(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found use");
}
def::DefRegion(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found region");
}
def::DefTyParamBinder(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type parameter");
}
def::DefLabel(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found label");
}
def::DefSelfTy(..) => {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found self ty");
}
def::DefLocal(nid) | def::DefUpvar(nid, _) => {
let typ = fcx.local_ty(sp, nid);
(ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
ty::GenericPredicates::empty())
}
def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) | def::DefConst(id) => {
(ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id))
}
def::DefTrait(_) |
def::DefTy(..) |
def::DefAssociatedTy(..) |
def::DefAssociatedPath(..) |
def::DefPrimTy(_) |
def::DefTyParam(..) |
def::DefMod(..) |
def::DefForeignMod(..) |
def::DefUse(..) |
def::DefRegion(..) |
def::DefTyParamBinder(..) |
def::DefLabel(..) |
def::DefSelfTy(..) => {
fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
}
}
}
......@@ -4679,6 +4672,7 @@ pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
path: &ast::Path,
type_scheme: TypeScheme<'tcx>,
type_predicates: &ty::GenericPredicates<'tcx>,
opt_self_ty: Option<Ty<'tcx>>,
def: def::Def,
span: Span,
......@@ -4864,7 +4858,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Add all the obligations that are required, substituting and
// normalized appropriately.
let bounds = fcx.instantiate_bounds(span, &substs, &type_scheme.generics);
let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
fcx.add_obligations_for_parameters(
traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
&bounds);
......
......@@ -1588,8 +1588,8 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
// ```
//
// we can thus deduce that `<T as SomeTrait<'a>>::SomeType : 'a`.
let trait_def = ty::lookup_trait_def(tcx, projection_ty.trait_ref.def_id);
let predicates = trait_def.generics.predicates.as_slice().to_vec();
let trait_predicates = ty::lookup_predicates(tcx, projection_ty.trait_ref.def_id);
let predicates = trait_predicates.predicates.as_slice().to_vec();
traits::elaborate_predicates(tcx, predicates)
.filter_map(|predicate| {
// we're only interesting in `T : 'a` style predicates:
......
......@@ -107,12 +107,12 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
});
}
ast::ItemTrait(..) => {
let trait_def =
ty::lookup_trait_def(ccx.tcx, local_def(item.id));
let trait_predicates =
ty::lookup_predicates(ccx.tcx, local_def(item.id));
reject_non_type_param_bounds(
ccx.tcx,
item.span,
&trait_def.generics);
&trait_predicates);
}
_ => {}
}
......@@ -124,11 +124,13 @@ fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
let ccx = self.ccx;
let item_def_id = local_def(item.id);
let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
reject_non_type_param_bounds(ccx.tcx, item.span, &type_scheme.generics);
let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
let param_env =
ty::construct_parameter_environment(ccx.tcx,
item.span,
&type_scheme.generics,
&type_predicates,
item.id);
let inh = Inherited::new(ccx.tcx, param_env);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
......@@ -283,9 +285,8 @@ fn check_impl(&mut self,
// Reject any predicates that do not involve a type parameter.
fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
span: Span,
generics: &ty::Generics<'tcx>) {
for predicate in generics.predicates.iter() {
predicates: &ty::GenericPredicates<'tcx>) {
for predicate in predicates.predicates.iter() {
match predicate {
&ty::Predicate::Trait(ty::Binder(ref tr)) => {
let found_param = tr.input_types().iter()
......@@ -367,7 +368,7 @@ fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
reject_non_type_param_bounds(
self.ccx.tcx,
method.span,
&ty_method.generics);
&ty_method.predicates);
reject_shadowing_type_parameters(
self.ccx.tcx,
method.span,
......@@ -415,9 +416,11 @@ pub fn new(fcx: &'cx FnCtxt<'cx,'tcx>,
/// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
/// to the point where impl `A : Trait<B>` is implemented).
pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id);
let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id);
let bounds = self.fcx.instantiate_bounds(self.span, trait_ref.substs, &trait_def.generics);
let bounds = self.fcx.instantiate_bounds(self.span,
trait_ref.substs,
&trait_predicates);
self.fcx.add_obligations_for_parameters(
traits::ObligationCause::new(
......@@ -482,8 +485,9 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match t.sty{
ty::ty_struct(type_id, substs) |
ty::ty_enum(type_id, substs) => {
let type_scheme = ty::lookup_item_type(self.fcx.tcx(), type_id);
let bounds = self.fcx.instantiate_bounds(self.span, substs, &type_scheme.generics);
let type_predicates = ty::lookup_predicates(self.fcx.tcx(), type_id);
let bounds = self.fcx.instantiate_bounds(self.span, substs,
&type_predicates);
if self.binding_count == 0 {
self.fcx.add_obligations_for_parameters(
......@@ -603,10 +607,10 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
.collect()
}
fn filter_to_trait_obligations<'tcx>(bounds: ty::GenericBounds<'tcx>)
-> ty::GenericBounds<'tcx>
fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>)
-> ty::InstantiatedPredicates<'tcx>
{
let mut result = ty::GenericBounds::empty();
let mut result = ty::InstantiatedPredicates::empty();
for (space, _, predicate) in bounds.predicates.iter_enumerated() {
match *predicate {
ty::Predicate::Trait(..) |
......
......@@ -247,6 +247,7 @@ fn instantiate_default_methods(
debug!("new_polytype={}", new_polytype.repr(tcx));
tcx.tcache.borrow_mut().insert(new_did, new_polytype);
tcx.predicates.borrow_mut().insert(new_did, new_method_ty.predicates.clone());
tcx.impl_or_trait_items
.borrow_mut()
.insert(new_did, ty::MethodTraitItem(new_method_ty));
......@@ -555,6 +556,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("subst_receiver_types_in_method_ty: combined_substs={}",
combined_substs.repr(tcx));
let method_predicates = method.predicates.subst(tcx, &combined_substs);
let mut method_generics = method.generics.subst(tcx, &combined_substs);
// replace the type parameters declared on the trait with those
......@@ -579,6 +581,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
ty::Method::new(
method.name,
method_generics,
method_predicates,
method_fty,
method.explicit_self,
method.vis,
......
......@@ -102,7 +102,6 @@
use middle::def;
use middle::infer;
use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::{self, Ty};
use session::config;
use util::common::time;
......@@ -177,17 +176,6 @@ fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
lookup_def_tcx(ccx.tcx, sp, id)
}
fn no_params<'tcx>(t: Ty<'tcx>) -> ty::TypeScheme<'tcx> {
ty::TypeScheme {
generics: ty::Generics {
types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty(),
predicates: VecPerParamSpace::empty(),
},
ty: t
}
}
fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
t1_is_expected: bool,
......
......@@ -166,10 +166,11 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
}
});
let trait_def = ty::lookup_trait_def(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
let bounds = trait_def.bounds.clean(cx);
clean::Trait {
unsafety: def.unsafety,
generics: (&def.generics, subst::TypeSpace).clean(cx),
generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
items: items.collect(),
bounds: bounds,
}
......@@ -181,9 +182,10 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) ->
ty::ty_bare_fn(_, ref f) => ((did, &f.sig).clean(cx), f.unsafety),
_ => panic!("bad function"),
};
let predicates = ty::lookup_predicates(tcx, did);
clean::Function {
decl: decl,
generics: (&t.generics, subst::FnSpace).clean(cx),
generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
unsafety: style,
}
}
......@@ -192,6 +194,7 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
use syntax::parse::token::special_idents::unnamed_field;
let t = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
let fields = ty::lookup_struct_fields(tcx, did);
clean::Struct {
......@@ -201,7 +204,7 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
[ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
_ => doctree::Plain,
},
generics: (&t.generics, subst::TypeSpace).clean(cx),
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
fields: fields.clean(cx),
fields_stripped: false,
}
......@@ -209,10 +212,11 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
let t = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
match t.ty.sty {
ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
return clean::EnumItem(clean::Enum {
generics: (&t.generics, subst::TypeSpace).clean(cx),
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
variants_stripped: false,
variants: ty::enum_variants(tcx, edid).clean(cx),
})
......@@ -222,7 +226,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn
clean::TypedefItem(clean::Typedef {
type_: t.ty.clean(cx),
generics: (&t.generics, subst::TypeSpace).clean(cx),
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
})
}
......@@ -293,6 +297,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
let attrs = load_attrs(cx, tcx, did);
let ty = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
.iter()
.filter_map(|did| {
......@@ -323,9 +328,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
ty::TypeTraitItem(ref assoc_ty) => {
let did = assoc_ty.def_id;
let type_scheme = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
// Not sure the choice of ParamSpace actually matters here, because an
// associated type won't have generics on the LHS
let typedef = (type_scheme, subst::ParamSpace::TypeSpace).clean(cx);
let typedef = (type_scheme, predicates, subst::ParamSpace::TypeSpace).clean(cx);
Some(clean::Item {
name: Some(assoc_ty.name.clean(cx)),
inner: clean::TypedefItem(typedef),
......@@ -349,7 +355,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
}
}),
for_: ty.ty.clean(cx),
generics: (&ty.generics, subst::TypeSpace).clean(cx),
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
items: trait_items,
polarity: polarity.map(|p| { p.clean(cx) }),
}),
......
......@@ -860,7 +860,9 @@ fn clean(&self, cx: &DocContext) -> Generics {
}
}
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
&'a ty::GenericPredicates<'tcx>,
subst::ParamSpace) {
fn clean(&self, cx: &DocContext) -> Generics {
use std::collections::HashSet;
use syntax::ast::TraitBoundModifier as TBM;
......@@ -885,7 +887,8 @@ fn has_sized_bound(bounds: &[TyParamBound], cx: &DocContext) -> bool {
false
}
let (gens, space) = *self;
let (gens, preds, space) = *self;
// 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.get_slice(space).iter().map(|tp| {
......@@ -899,7 +902,8 @@ fn has_sized_bound(bounds: &[TyParamBound], cx: &DocContext) -> bool {
srp.clean(cx)
}).collect::<Vec<_>>();
let where_predicates = gens.predicates.get_slice(space).to_vec().clean(cx);
let where_predicates = preds.predicates.get_slice(space).to_vec().clean(cx);
// Type parameters have a Sized bound by default unless removed with ?Sized.
// Scan through the predicates and mark any type parameter with a Sized
// bound, removing the bounds as we find them.
......@@ -913,6 +917,7 @@ fn has_sized_bound(bounds: &[TyParamBound], cx: &DocContext) -> bool {
}
Some(pred)
}).collect::<Vec<_>>();
// Finally, run through the type parameters again and insert a ?Sized unbound for
// any we didn't find to be Sized.
for tp in &stripped_typarams {
......@@ -1303,7 +1308,7 @@ fn clean(&self, cx: &DocContext) -> Item {
source: Span::empty(),
inner: TyMethodItem(TyMethod {
unsafety: self.fty.unsafety,
generics: (&self.generics, subst::FnSpace).clean(cx),
generics: (&self.generics, &self.predicates, subst::FnSpace).clean(cx),
self_: self_,
decl: (self.def_id, &sig).clean(cx),
abi: self.fty.abi
......@@ -2560,12 +2565,12 @@ fn clean(&self, cx: &DocContext) -> Item {
}
}
impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ParamSpace) {
impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) {
fn clean(&self, cx: &DocContext) -> Typedef {
let (ref ty_scheme, ps) = *self;
let (ref ty_scheme, ref predicates, ps) = *self;
Typedef {
type_: ty_scheme.ty.clean(cx),
generics: (&ty_scheme.generics, ps).clean(cx)
generics: (&ty_scheme.generics, predicates, ps).clean(cx)
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册