1
Fork 0

Improve comments and address nits.

This commit is contained in:
Niko Matsakis 2014-12-11 04:35:51 -05:00
parent 5f43899db4
commit 124e1e18cc
5 changed files with 54 additions and 38 deletions

View file

@ -250,13 +250,15 @@ impl<'tcx> FulfillmentContext<'tcx> {
self.predicates.retain(|predicate| { self.predicates.retain(|predicate| {
// Hack: Retain does not pass in the index, but we want // Hack: Retain does not pass in the index, but we want
// to avoid processing the first `start_count` entries. // to avoid processing the first `start_count` entries.
if skip == 0 { let processed =
retain_predicate(selcx, predicate, if skip == 0 {
&mut selections, &mut errors, region_obligations) process_predicate(selcx, predicate,
} else { &mut selections, &mut errors, region_obligations)
skip -= 1; } else {
true skip -= 1;
} false
};
!processed
}); });
} }
@ -286,17 +288,17 @@ impl<'tcx> FulfillmentContext<'tcx> {
} }
} }
fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
predicate: &PredicateObligation<'tcx>, predicate: &PredicateObligation<'tcx>,
selections: &mut Vec<Selection<'tcx>>, selections: &mut Vec<Selection<'tcx>>,
errors: &mut Vec<FulfillmentError<'tcx>>, errors: &mut Vec<FulfillmentError<'tcx>>,
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>) region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
-> bool -> bool
{ {
/*! /*!
* Evaluates a predicate obligation and modifies the appropriate * Processes a predicate obligation and modifies the appropriate
* output array. Returns `true` if the predicate must be retained * output array with the successful/error result. Returns `false`
* because it could not be fully evaluated yet due to insufficient * if the predicate could not be processed due to insufficient
* type inference. * type inference.
*/ */
@ -308,11 +310,11 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
trait_ref: trait_ref.clone() }; trait_ref: trait_ref.clone() };
match selcx.select(&trait_obligation) { match selcx.select(&trait_obligation) {
Ok(None) => { Ok(None) => {
true false
} }
Ok(Some(s)) => { Ok(Some(s)) => {
selections.push(s); selections.push(s);
false true
} }
Err(selection_err) => { Err(selection_err) => {
debug!("predicate: {} error: {}", debug!("predicate: {} error: {}",
@ -322,7 +324,7 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
FulfillmentError::new( FulfillmentError::new(
predicate.clone(), predicate.clone(),
CodeSelectionError(selection_err))); CodeSelectionError(selection_err)));
false true
} }
} }
} }
@ -331,14 +333,14 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
let origin = infer::EquatePredicate(predicate.cause.span); let origin = infer::EquatePredicate(predicate.cause.span);
match infer::mk_eqty(selcx.infcx(), false, origin, a, b) { match infer::mk_eqty(selcx.infcx(), false, origin, a, b) {
Ok(()) => { Ok(()) => {
false true
} }
Err(_) => { Err(_) => {
errors.push( errors.push(
FulfillmentError::new( FulfillmentError::new(
predicate.clone(), predicate.clone(),
CodeSelectionError(Unimplemented))); CodeSelectionError(Unimplemented)));
false true
} }
} }
} }
@ -346,12 +348,12 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
ty::Predicate::RegionOutlives(r_a, r_b) => { ty::Predicate::RegionOutlives(r_a, r_b) => {
let origin = infer::RelateRegionParamBound(predicate.cause.span); let origin = infer::RelateRegionParamBound(predicate.cause.span);
let () = infer::mk_subr(selcx.infcx(), origin, r_b, r_a); // `b : a` ==> `a <= b` let () = infer::mk_subr(selcx.infcx(), origin, r_b, r_a); // `b : a` ==> `a <= b`
false true
} }
ty::Predicate::TypeOutlives(t_a, r_b) => { ty::Predicate::TypeOutlives(t_a, r_b) => {
register_region_obligation(tcx, t_a, r_b, predicate.cause, region_obligations); register_region_obligation(tcx, t_a, r_b, predicate.cause, region_obligations);
false true
} }
} }
} }

View file

@ -61,7 +61,12 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, Rc<ty::TraitRef<'tcx>>>;
pub struct ObligationCause<'tcx> { pub struct ObligationCause<'tcx> {
pub span: Span, pub span: Span,
// the id of XXX // The id of the fn body that triggered this obligation. This is
// used for region obligations to determine the precise
// environment in which the region obligation should be evaluated
// (in particular, closures can add new assumptions). See the
// field `region_obligations` of the `FulfillmentContext` for more
// information.
pub body_id: ast::NodeId, pub body_id: ast::NodeId,
pub code: ObligationCauseCode<'tcx> pub code: ObligationCauseCode<'tcx>

View file

@ -24,8 +24,16 @@ use super::{Obligation, ObligationCause, PredicateObligation,
VtableImpl, VtableParam, VtableParamData, VtableImplData}; VtableImpl, VtableParam, VtableParamData, VtableImplData};
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Elaboration iterator // `Elaboration` iterator
///////////////////////////////////////////////////////////////////////////
/// "Elaboration" is the process of identifying all the predicates that
/// are implied by a source predicate. Currently this basically means
/// walking the "supertraits" and other similar assumptions. For
/// example, if we know that `T : Ord`, the elaborator would deduce
/// that `T : PartialOrd` holds as well. Similarly, if we have `trait
/// Foo : 'static`, and we know that `T : Foo`, then we know that `T :
/// 'static`.
pub struct Elaborator<'cx, 'tcx:'cx> { pub struct Elaborator<'cx, 'tcx:'cx> {
tcx: &'cx ty::ctxt<'tcx>, tcx: &'cx ty::ctxt<'tcx>,
stack: Vec<StackEntry<'tcx>>, stack: Vec<StackEntry<'tcx>>,
@ -157,7 +165,10 @@ impl<'cx, 'tcx> Iterator<ty::Predicate<'tcx>> for Elaborator<'cx, 'tcx> {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Supertrait iterator // Supertrait iterator
///////////////////////////////////////////////////////////////////////////
/// A filter around the `Elaborator` that just yields up supertrait references,
/// not other kinds of predicates.
pub struct Supertraits<'cx, 'tcx:'cx> { pub struct Supertraits<'cx, 'tcx:'cx> {
elaborator: Elaborator<'cx, 'tcx>, elaborator: Elaborator<'cx, 'tcx>,
} }
@ -197,6 +208,8 @@ impl<'cx, 'tcx> Iterator<Rc<ty::TraitRef<'tcx>>> for Supertraits<'cx, 'tcx> {
} }
} }
///////////////////////////////////////////////////////////////////////////
// Other
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// determine the `self` type, using fresh variables for all variables // determine the `self` type, using fresh variables for all variables

View file

@ -1656,14 +1656,16 @@ impl<'tcx> Generics<'tcx> {
#[deriving(Clone, PartialEq, Eq, Hash, Show)] #[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum Predicate<'tcx> { pub enum Predicate<'tcx> {
/// where Foo : Bar /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the parameters in the `TypeSpace`.
Trait(Rc<TraitRef<'tcx>>), Trait(Rc<TraitRef<'tcx>>),
/// where Foo == Bar /// where `T1 == T2`.
Equate(Ty<'tcx>, Ty<'tcx>), Equate(/* T1 */ Ty<'tcx>, /* T2 */ Ty<'tcx>),
/// where 'a : 'b /// where 'a : 'b
RegionOutlives(Region, Region), RegionOutlives(/* 'a */ Region, /* 'b */ Region),
/// where T : 'a /// where T : 'a
TypeOutlives(Ty<'tcx>, Region), TypeOutlives(Ty<'tcx>, Region),
@ -1807,7 +1809,6 @@ impl<'tcx> ParameterEnvironment<'tcx> {
let method_generics = &method_ty.generics; let method_generics = &method_ty.generics;
construct_parameter_environment( construct_parameter_environment(
cx, cx,
method.span,
method_generics, method_generics,
method.pe_body().id) method.pe_body().id)
} }
@ -1842,7 +1843,6 @@ impl<'tcx> ParameterEnvironment<'tcx> {
let method_generics = &method_ty.generics; let method_generics = &method_ty.generics;
construct_parameter_environment( construct_parameter_environment(
cx, cx,
method.span,
method_generics, method_generics,
method.pe_body().id) method.pe_body().id)
} }
@ -1869,7 +1869,6 @@ impl<'tcx> ParameterEnvironment<'tcx> {
let fn_pty = ty::lookup_item_type(cx, fn_def_id); let fn_pty = ty::lookup_item_type(cx, fn_def_id);
construct_parameter_environment(cx, construct_parameter_environment(cx,
item.span,
&fn_pty.generics, &fn_pty.generics,
body.id) body.id)
} }
@ -1880,8 +1879,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
ast::ItemStatic(..) => { ast::ItemStatic(..) => {
let def_id = ast_util::local_def(id); let def_id = ast_util::local_def(id);
let pty = ty::lookup_item_type(cx, def_id); let pty = ty::lookup_item_type(cx, def_id);
construct_parameter_environment(cx, item.span, construct_parameter_environment(cx, &pty.generics, id)
&pty.generics, id)
} }
_ => { _ => {
cx.sess.span_bug(item.span, cx.sess.span_bug(item.span,
@ -5031,8 +5029,8 @@ pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
}) })
} }
/// Given a reference to a trait, returns the bounds declared on the /// Given a reference to a trait, returns the "superbounds" declared
/// trait, with appropriate substitutions applied. /// on the trait, with appropriate substitutions applied.
pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
trait_ref: &TraitRef<'tcx>) trait_ref: &TraitRef<'tcx>)
-> Vec<ty::Predicate<'tcx>> -> Vec<ty::Predicate<'tcx>>
@ -5929,7 +5927,6 @@ pub fn empty_parameter_environment<'tcx>() -> ParameterEnvironment<'tcx> {
/// See `ParameterEnvironment` struct def'n for details /// See `ParameterEnvironment` struct def'n for details
pub fn construct_parameter_environment<'tcx>( pub fn construct_parameter_environment<'tcx>(
tcx: &ctxt<'tcx>, tcx: &ctxt<'tcx>,
_span: Span,
generics: &ty::Generics<'tcx>, generics: &ty::Generics<'tcx>,
free_id: ast::NodeId) free_id: ast::NodeId)
-> ParameterEnvironment<'tcx> -> ParameterEnvironment<'tcx>

View file

@ -91,7 +91,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
let polytype = ty::lookup_item_type(ccx.tcx, item_def_id); let polytype = ty::lookup_item_type(ccx.tcx, item_def_id);
let param_env = let param_env =
ty::construct_parameter_environment(ccx.tcx, ty::construct_parameter_environment(ccx.tcx,
item.span,
&polytype.generics, &polytype.generics,
item.id); item.id);
let inh = Inherited::new(ccx.tcx, param_env); let inh = Inherited::new(ccx.tcx, param_env);