Skip to content

Commit 87c2ed5

Browse files
committed
---
yaml --- r: 136687 b: refs/heads/dist-snap c: c31623b h: refs/heads/master i: 136685: 43d1ff8 136683: 1120fae 136679: ee496fd 136671: 8f59a2d v: v3
1 parent bf2e0f6 commit 87c2ed5

File tree

5 files changed

+99
-76
lines changed

5 files changed

+99
-76
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: 189b7332968972f34cdbbbd9b62d97ababf53059
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: effb3636cc416ae81450e857352b832a86d5dd44
9+
refs/heads/dist-snap: c31623b0e42e73ef2c9411445d3172e2e9c9e467
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/librustc/middle/traits/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use syntax::codemap::{Span, DUMMY_SP};
2222

2323
pub use self::fulfill::FulfillmentContext;
2424
pub use self::select::SelectionContext;
25+
pub use self::select::SelectionCache;
2526
pub use self::util::supertraits;
2627
pub use self::util::transitive_bounds;
2728
pub use self::util::Supertraits;

branches/dist-snap/src/librustc/middle/traits/select.rs

Lines changed: 83 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use middle::ty_fold::TypeFoldable;
2828
use middle::typeck::check::regionmanip;
2929
use middle::typeck::infer;
3030
use middle::typeck::infer::{InferCtxt, TypeSkolemizer};
31+
use std::cell::RefCell;
32+
use std::collections::hashmap::HashMap;
3133
use std::rc::Rc;
3234
use syntax::ast;
3335
use util::ppaux::Repr;
@@ -46,15 +48,15 @@ struct ObligationStack<'prev> {
4648
previous: Option<&'prev ObligationStack<'prev>>
4749
}
4850

49-
// pub struct SelectionCache {
50-
// hashmap: RefCell<HashMap<CacheKey, Candidate>>,
51-
// }
51+
pub struct SelectionCache {
52+
hashmap: RefCell<HashMap<CacheKey, SelectionResult<Candidate>>>,
53+
}
5254

53-
// #[deriving(Hash,Eq,PartialEq)]
54-
// struct CacheKey {
55-
// trait_def_id: ast::DefId,
56-
// skol_obligation_self_ty: ty::t,
57-
// }
55+
#[deriving(Hash,Eq,PartialEq)]
56+
struct CacheKey {
57+
trait_def_id: ast::DefId,
58+
skol_obligation_self_ty: ty::t,
59+
}
5860

5961
#[deriving(PartialEq,Eq)]
6062
enum MatchResult<T> {
@@ -309,14 +311,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
309311
// First, check the cache.
310312
match self.check_candidate_cache(stack.obligation, stack.skol_obligation_self_ty) {
311313
Some(c) => {
312-
return Ok(Some(c));
314+
debug!("check_candidate_cache(obligation={}, skol_obligation_self_ty={}, \
315+
candidate={})",
316+
stack.obligation.trait_ref.def_id,
317+
stack.skol_obligation_self_ty.repr(self.tcx()),
318+
c.repr(self.tcx()));
319+
return c;
313320
}
314321
None => { }
315322
}
316323

317324
// If no match, compute result and insert into cache.
318325
let result = self.pick_candidate(stack);
319-
// self.insert_candidate_cache(obligation, skol_obligation_self_ty, result.clone());
326+
self.insert_candidate_cache(stack.obligation,
327+
stack.skol_obligation_self_ty,
328+
result.clone());
320329
result
321330
}
322331

@@ -330,9 +339,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
330339

331340
let mut candidates = try!(self.assemble_candidates(stack));
332341

333-
debug!("candidate_from_obligation: {} candidates for {}",
334-
candidates.len(),
335-
stack.repr(self.tcx()));
342+
debug!("assembled {} candidates for {}",
343+
candidates.len(), stack.repr(self.tcx()));
336344

337345
// Examine candidates to determine outcome. Ideally we will
338346
// have exactly one candidate that is definitively applicable.
@@ -348,55 +356,63 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
348356
debug!("0 matches, unimpl");
349357
Err(Unimplemented)
350358
} else {
351-
debug!("candidate_from_obligation({}) -> 0 matches, ambig",
352-
stack.repr(self.tcx()));
359+
debug!("0 matches, ambig");
353360
Ok(None)
354-
};
355-
}
356-
357-
if candidates.len() > 1 {
361+
}
362+
} else if candidates.len() > 1 {
358363
// Ambiguity. Possibly we should report back more
359364
// information on the potential candidates so we can give
360365
// a better error message.
361-
debug!("candidate_from_obligation({}) -> multiple matches, ambig",
362-
stack.repr(self.tcx()));
363-
364-
return Ok(None);
366+
debug!("multiple matches, ambig");
367+
Ok(None)
368+
} else {
369+
let candidate = candidates.pop().unwrap();
370+
Ok(Some(candidate))
365371
}
372+
}
366373

367-
let candidate = candidates.pop().unwrap();
368-
self.insert_candidate_cache(stack.obligation,
369-
stack.skol_obligation_self_ty,
370-
candidate.clone());
371-
Ok(Some(candidate))
374+
fn pick_candidate_cache(&self,
375+
_obligation: &Obligation,
376+
skol_obligation_self_ty: ty::t)
377+
-> &SelectionCache
378+
{
379+
if
380+
ty::type_has_self(skol_obligation_self_ty) ||
381+
ty::type_has_params(skol_obligation_self_ty)
382+
{
383+
&self.param_env.selection_cache
384+
} else {
385+
&self.tcx().selection_cache
386+
}
372387
}
373388

374389
fn check_candidate_cache(&mut self,
375-
_obligation: &Obligation,
376-
_skol_obligation_self_ty: ty::t)
377-
-> Option<Candidate>
390+
obligation: &Obligation,
391+
skol_obligation_self_ty: ty::t)
392+
-> Option<SelectionResult<Candidate>>
378393
{
379-
// let cache_key = CacheKey::new(obligation.trait_ref.def_id,
380-
// skol_obligation_self_ty);
381-
// let hashmap = self.tcx().selection_cache.hashmap.borrow();
382-
// hashmap.find(&cache_key).map(|c| (*c).clone())
383-
None
394+
let cache = self.pick_candidate_cache(obligation, skol_obligation_self_ty);
395+
let cache_key = CacheKey::new(obligation.trait_ref.def_id,
396+
skol_obligation_self_ty);
397+
let hashmap = cache.hashmap.borrow();
398+
hashmap.find(&cache_key).map(|c| (*c).clone())
384399
}
385400

386401
fn insert_candidate_cache(&mut self,
387-
_obligation: &Obligation,
388-
_skol_obligation_self_ty: ty::t,
389-
_candidate: Candidate)
402+
obligation: &Obligation,
403+
skol_obligation_self_ty: ty::t,
404+
candidate: SelectionResult<Candidate>)
390405
{
391-
// FIXME -- Enable caching. I think the right place to put the cache
392-
// is in the ParameterEnvironment, not the tcx, because otherwise
393-
// when there are distinct where clauses in scope the cache can get
394-
// confused.
395-
//
396-
//let cache_key = CacheKey::new(obligation.trait_ref.def_id,
397-
// skol_obligation_self_ty);
398-
//let mut hashmap = self.tcx().selection_cache.hashmap.borrow_mut();
399-
//hashmap.insert(cache_key, candidate);
406+
debug!("insert_candidate_cache(obligation={}, skol_obligation_self_ty={}, candidate={})",
407+
obligation.trait_ref.def_id,
408+
skol_obligation_self_ty.repr(self.tcx()),
409+
candidate.repr(self.tcx()));
410+
411+
let cache = self.pick_candidate_cache(obligation, skol_obligation_self_ty);
412+
let cache_key = CacheKey::new(obligation.trait_ref.def_id,
413+
skol_obligation_self_ty);
414+
let mut hashmap = cache.hashmap.borrow_mut();
415+
hashmap.insert(cache_key, candidate);
400416
}
401417

402418
fn assemble_candidates(&mut self,
@@ -1487,6 +1503,14 @@ impl Repr for ImplCandidate {
14871503
}
14881504
}
14891505

1506+
impl SelectionCache {
1507+
pub fn new() -> SelectionCache {
1508+
SelectionCache {
1509+
hashmap: RefCell::new(HashMap::new())
1510+
}
1511+
}
1512+
}
1513+
14901514
impl<'o> ObligationStack<'o> {
14911515
fn iter(&self) -> Option<&ObligationStack> {
14921516
Some(self)
@@ -1515,22 +1539,14 @@ impl<'o> Repr for ObligationStack<'o> {
15151539
}
15161540
}
15171541

1518-
// impl SelectionCache {
1519-
// pub fn new() -> SelectionCache {
1520-
// SelectionCache {
1521-
// hashmap: RefCell::new(HashMap::new())
1522-
// }
1523-
// }
1524-
// }
1525-
1526-
// impl CacheKey {
1527-
// pub fn new(trait_def_id: ast::DefId,
1528-
// skol_obligation_self_ty: ty::t)
1529-
// -> CacheKey
1530-
// {
1531-
// CacheKey {
1532-
// trait_def_id: trait_def_id,
1533-
// skol_obligation_self_ty: skol_obligation_self_ty
1534-
// }
1535-
// }
1536-
// }
1542+
impl CacheKey {
1543+
pub fn new(trait_def_id: ast::DefId,
1544+
skol_obligation_self_ty: ty::t)
1545+
-> CacheKey
1546+
{
1547+
CacheKey {
1548+
trait_def_id: trait_def_id,
1549+
skol_obligation_self_ty: skol_obligation_self_ty
1550+
}
1551+
}
1552+
}

branches/dist-snap/src/librustc/middle/ty.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ pub struct ctxt<'tcx> {
579579
/// Maps def IDs of traits to information about their associated types.
580580
pub trait_associated_types:
581581
RefCell<DefIdMap<Rc<Vec<AssociatedTypeInfo>>>>,
582+
583+
/// Caches the results of trait selection. This cache is used
584+
/// for things that do not have to do with the parameters in scope.
585+
pub selection_cache: traits::SelectionCache,
582586
}
583587

584588
pub enum tbox_flag {
@@ -1281,6 +1285,10 @@ pub struct ParameterEnvironment {
12811285
/// Note: This effectively *duplicates* the `bounds` array for
12821286
/// now.
12831287
pub caller_obligations: VecPerParamSpace<traits::Obligation>,
1288+
1289+
/// Caches the results of trait selection. This cache is used
1290+
/// for things that have to do with the parameters in scope.
1291+
pub selection_cache: traits::SelectionCache,
12841292
}
12851293

12861294
impl ParameterEnvironment {
@@ -1524,7 +1532,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
15241532
capture_modes: capture_modes,
15251533
associated_types: RefCell::new(DefIdMap::new()),
15261534
trait_associated_types: RefCell::new(DefIdMap::new()),
1527-
}
1535+
selection_cache: traits::SelectionCache::new(),
1536+
}
15281537
}
15291538

15301539
// Type constructors
@@ -5324,7 +5333,8 @@ pub fn empty_parameter_environment() -> ParameterEnvironment {
53245333
ty::ParameterEnvironment { free_substs: Substs::empty(),
53255334
bounds: VecPerParamSpace::empty(),
53265335
caller_obligations: VecPerParamSpace::empty(),
5327-
implicit_region_bound: ty::ReEmpty }
5336+
implicit_region_bound: ty::ReEmpty,
5337+
selection_cache: traits::SelectionCache::new(), }
53285338
}
53295339

53305340
pub fn construct_parameter_environment(
@@ -5396,6 +5406,7 @@ pub fn construct_parameter_environment(
53965406
bounds: bounds,
53975407
implicit_region_bound: ty::ReScope(free_id),
53985408
caller_obligations: obligations,
5409+
selection_cache: traits::SelectionCache::new(),
53995410
};
54005411

54015412
fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,

branches/dist-snap/src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,7 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
368368
-> Inherited<'a, 'tcx> {
369369
// It's kind of a kludge to manufacture a fake function context
370370
// and statement context, but we might as well do write the code only once
371-
let param_env = ty::ParameterEnvironment {
372-
free_substs: subst::Substs::empty(),
373-
bounds: subst::VecPerParamSpace::empty(),
374-
implicit_region_bound: ty::ReStatic,
375-
caller_obligations: subst::VecPerParamSpace::empty(),
376-
};
371+
let param_env = ty::empty_parameter_environment();
377372
Inherited::new(ccx.tcx, param_env)
378373
}
379374

0 commit comments

Comments
 (0)