diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 9d9c3e238d4..412c188f5f4 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -250,13 +250,15 @@ impl<'tcx> FulfillmentContext<'tcx> { self.predicates.retain(|predicate| { // Hack: Retain does not pass in the index, but we want // to avoid processing the first `start_count` entries. - if skip == 0 { - retain_predicate(selcx, predicate, - &mut selections, &mut errors, region_obligations) - } else { - skip -= 1; - true - } + let processed = + if skip == 0 { + process_predicate(selcx, predicate, + &mut selections, &mut errors, region_obligations) + } else { + skip -= 1; + false + }; + !processed }); } @@ -286,17 +288,17 @@ impl<'tcx> FulfillmentContext<'tcx> { } } -fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, - predicate: &PredicateObligation<'tcx>, - selections: &mut Vec>, - errors: &mut Vec>, - region_obligations: &mut NodeMap>>) - -> bool +fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, + predicate: &PredicateObligation<'tcx>, + selections: &mut Vec>, + errors: &mut Vec>, + region_obligations: &mut NodeMap>>) + -> bool { /*! - * Evaluates a predicate obligation and modifies the appropriate - * output array. Returns `true` if the predicate must be retained - * because it could not be fully evaluated yet due to insufficient + * Processes a predicate obligation and modifies the appropriate + * output array with the successful/error result. Returns `false` + * if the predicate could not be processed due to insufficient * type inference. */ @@ -308,11 +310,11 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, trait_ref: trait_ref.clone() }; match selcx.select(&trait_obligation) { Ok(None) => { - true + false } Ok(Some(s)) => { selections.push(s); - false + true } Err(selection_err) => { debug!("predicate: {} error: {}", @@ -322,7 +324,7 @@ fn retain_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, FulfillmentError::new( predicate.clone(), 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); match infer::mk_eqty(selcx.infcx(), false, origin, a, b) { Ok(()) => { - false + true } Err(_) => { errors.push( FulfillmentError::new( predicate.clone(), 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) => { let origin = infer::RelateRegionParamBound(predicate.cause.span); let () = infer::mk_subr(selcx.infcx(), origin, r_b, r_a); // `b : a` ==> `a <= b` - false + true } ty::Predicate::TypeOutlives(t_a, r_b) => { register_region_obligation(tcx, t_a, r_b, predicate.cause, region_obligations); - false + true } } } diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index f438b61e27c..604a0607c0b 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -61,7 +61,12 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, Rc>>; pub struct ObligationCause<'tcx> { 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 code: ObligationCauseCode<'tcx> diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index a9532aceebb..52154e0be7a 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -24,8 +24,16 @@ use super::{Obligation, ObligationCause, PredicateObligation, 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> { tcx: &'cx ty::ctxt<'tcx>, stack: Vec>, @@ -157,7 +165,10 @@ impl<'cx, 'tcx> Iterator> for Elaborator<'cx, 'tcx> { /////////////////////////////////////////////////////////////////////////// // Supertrait iterator +/////////////////////////////////////////////////////////////////////////// +/// A filter around the `Elaborator` that just yields up supertrait references, +/// not other kinds of predicates. pub struct Supertraits<'cx, 'tcx:'cx> { elaborator: Elaborator<'cx, 'tcx>, } @@ -197,6 +208,8 @@ impl<'cx, 'tcx> Iterator>> for Supertraits<'cx, 'tcx> { } } +/////////////////////////////////////////////////////////////////////////// +// Other /////////////////////////////////////////////////////////////////////////// // determine the `self` type, using fresh variables for all variables diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ca226e2ca3f..ddbf69685cd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1656,14 +1656,16 @@ impl<'tcx> Generics<'tcx> { #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum Predicate<'tcx> { - /// where Foo : Bar + /// Corresponds to `where Foo : Bar`. `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>), - /// where Foo == Bar - Equate(Ty<'tcx>, Ty<'tcx>), + /// where `T1 == T2`. + Equate(/* T1 */ Ty<'tcx>, /* T2 */ Ty<'tcx>), /// where 'a : 'b - RegionOutlives(Region, Region), + RegionOutlives(/* 'a */ Region, /* 'b */ Region), /// where T : 'a TypeOutlives(Ty<'tcx>, Region), @@ -1807,7 +1809,6 @@ impl<'tcx> ParameterEnvironment<'tcx> { let method_generics = &method_ty.generics; construct_parameter_environment( cx, - method.span, method_generics, method.pe_body().id) } @@ -1842,7 +1843,6 @@ impl<'tcx> ParameterEnvironment<'tcx> { let method_generics = &method_ty.generics; construct_parameter_environment( cx, - method.span, method_generics, method.pe_body().id) } @@ -1869,7 +1869,6 @@ impl<'tcx> ParameterEnvironment<'tcx> { let fn_pty = ty::lookup_item_type(cx, fn_def_id); construct_parameter_environment(cx, - item.span, &fn_pty.generics, body.id) } @@ -1880,8 +1879,7 @@ impl<'tcx> ParameterEnvironment<'tcx> { 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) + construct_parameter_environment(cx, &pty.generics, id) } _ => { 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 -/// trait, with appropriate substitutions applied. +/// Given a reference to a trait, returns the "superbounds" declared +/// on the trait, with appropriate substitutions applied. pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, trait_ref: &TraitRef<'tcx>) -> Vec> @@ -5929,7 +5927,6 @@ pub fn empty_parameter_environment<'tcx>() -> ParameterEnvironment<'tcx> { /// See `ParameterEnvironment` struct def'n for details pub fn construct_parameter_environment<'tcx>( tcx: &ctxt<'tcx>, - _span: Span, generics: &ty::Generics<'tcx>, free_id: ast::NodeId) -> ParameterEnvironment<'tcx> diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index e89b127799c..8c82429e1c2 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -91,7 +91,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let polytype = ty::lookup_item_type(ccx.tcx, item_def_id); let param_env = ty::construct_parameter_environment(ccx.tcx, - item.span, &polytype.generics, item.id); let inh = Inherited::new(ccx.tcx, param_env);