Improve comments and address nits.
This commit is contained in:
parent
5f43899db4
commit
124e1e18cc
5 changed files with 54 additions and 38 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue