From 3e88b5bbf907bdb7d7610d66c27504be92330030 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 11 Feb 2015 10:28:52 -0500 Subject: [PATCH] Rote changes to fix fallout throughout the compiler from splitting the predicates and renaming some things. --- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/traits/object_safety.rs | 5 +- src/librustc/middle/traits/project.rs | 4 +- src/librustc/middle/traits/select.rs | 8 +- src/librustc/middle/traits/util.rs | 2 +- src/librustc/middle/ty.rs | 31 ++++-- src/librustc/middle/ty_fold.rs | 13 ++- src/librustc_typeck/check/_match.rs | 13 ++- src/librustc_typeck/check/compare_method.rs | 4 +- src/librustc_typeck/check/dropck.rs | 3 +- src/librustc_typeck/check/method/confirm.rs | 29 ++--- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 9 +- src/librustc_typeck/check/mod.rs | 112 +++++++++----------- src/librustc_typeck/check/regionck.rs | 4 +- src/librustc_typeck/check/wf.rs | 34 +++--- src/librustc_typeck/coherence/mod.rs | 3 + src/librustc_typeck/lib.rs | 12 --- src/librustdoc/clean/inline.rs | 20 ++-- src/librustdoc/clean/mod.rs | 19 ++-- 20 files changed, 180 insertions(+), 149 deletions(-) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index bddbb7c02ba..395e486059e 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -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) diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index c88e58266a0..b2701ae875c 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -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 { diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 7d02adea1fa..13f309e129a 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -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()); } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 5323a322436..5f659aa303e 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -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> { - 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 = diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 573efa72756..6c54da1c134 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -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> { debug!("predicates_for_generics(generic_bounds={})", diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index af80ce65474..6026359ddac 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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() } diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 69d32c3f5fc..645a7ab9440 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -400,6 +400,13 @@ fn fold_with>(&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>(&self, folder: &mut F) -> ty::GenericPredicates<'tcx> { + ty::GenericPredicates { predicates: self.predicates.fold_with(folder), } } @@ -440,9 +447,9 @@ fn fold_with>(&self, folder: &mut F) -> ty::ProjectionTy<'tc } } -impl<'tcx> TypeFoldable<'tcx> for ty::GenericBounds<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::GenericBounds<'tcx> { - ty::GenericBounds { +impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> { + fn fold_with>(&self, folder: &mut F) -> ty::InstantiatedPredicates<'tcx> { + ty::InstantiatedPredicates { predicates: self.predicates.fold_with(folder), } } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 1249e0d8ce1..3ea2743c63e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index a5b938c7600..1e1d7e09260 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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(); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 1be6bf05c99..ce67369ca9d 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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 Drop where ...`, we automatically // assume some predicate will be meaningful and thus // represents a type through which we could reach diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 77701af25d3..dfbfc86c659 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -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, diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 88455b3385a..55b4dae5b9e 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -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), diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index cfc04a9a92f..82bd4ae87ff 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d90ed7eda59..00bc3375fdd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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(&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>, 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); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 80f6e3800f7..bcb2ba6231d 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1588,8 +1588,8 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>, // ``` // // we can thus deduce that `>::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: diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 923614f9e8a..94670305be7 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -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(&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` 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(..) | diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index ed340b0882c..1542e74ff81 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5ad2dc2871c..ccfadaba244 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index dfa5b01270e..d1283d6f46b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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) }), }), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7ab9d8c6672..6c3d2d8fa19 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -860,7 +860,9 @@ fn clean(&self, cx: &DocContext) -> Generics { } } -impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, subst::ParamSpace) { +impl<'a, 'tcx> Clean 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::>(); - 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::>(); + // 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 for (ty::TypeScheme<'a>, ParamSpace) { +impl<'a> Clean 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) } } } -- GitLab