1
Fork 0

Auto merge of #33710 - Manishearth:rollup, r=Manishearth

Rollup of 5 pull requests

- Successful merges: #33656, #33666, #33673, #33675, #33695
- Failed merges:
This commit is contained in:
bors 2016-05-18 05:04:26 -07:00
commit 9743c661b0
7 changed files with 55 additions and 24 deletions

View file

@ -38,6 +38,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
pub use self::specialize::{SpecializesCache};
pub use self::util::elaborate_predicates;
pub use self::util::supertraits;
pub use self::util::Supertraits;

View file

@ -20,6 +20,7 @@
use super::{SelectionContext, FulfillmentContext};
use super::util::{fresh_type_vars_for_impl, impl_trait_ref_and_oblig};
use rustc_data_structures::fnv::FnvHashMap;
use hir::def_id::DefId;
use infer::{InferCtxt, TypeOrigin};
use middle::region;
@ -111,6 +112,10 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl1_def_id: DefId,
impl2_def_id: DefId) -> bool {
if let Some(r) = tcx.specializes_cache.borrow().check(impl1_def_id, impl2_def_id) {
return r;
}
// The feature gate should prevent introducing new specializations, but not
// taking advantage of upstream ones.
if !tcx.sess.features.borrow().specialization &&
@ -146,7 +151,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.unwrap()
.subst(tcx, &penv.free_substs);
tcx.normalizing_infer_ctxt(ProjectionMode::Topmost).enter(|mut infcx| {
let result = tcx.normalizing_infer_ctxt(ProjectionMode::Topmost).enter(|mut infcx| {
// Normalize the trait reference, adding any obligations
// that arise into the impl1 assumptions.
let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = {
@ -167,7 +172,10 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Attempt to prove that impl2 applies, given all of the above.
fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok()
})
});
tcx.specializes_cache.borrow_mut().insert(impl1_def_id, impl2_def_id, result);
result
}
/// Attempt to fulfill all obligations of `target_impl` after unification with
@ -225,3 +233,23 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
}
})
}
pub struct SpecializesCache {
map: FnvHashMap<(DefId, DefId), bool>
}
impl SpecializesCache {
pub fn new() -> Self {
SpecializesCache {
map: FnvHashMap()
}
}
pub fn check(&self, a: DefId, b: DefId) -> Option<bool> {
self.map.get(&(a, b)).cloned()
}
pub fn insert(&mut self, a: DefId, b: DefId, result: bool) {
self.map.insert((a, b), result);
}
}

View file

@ -291,6 +291,8 @@ impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> {
pub struct GlobalCtxt<'tcx> {
global_interners: CtxtInterners<'tcx>,
pub specializes_cache: RefCell<traits::SpecializesCache>,
pub dep_graph: DepGraph,
/// Common types, pre-interned for your convenience.
@ -637,6 +639,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let dep_graph = map.dep_graph.clone();
let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone());
tls::enter_global(GlobalCtxt {
specializes_cache: RefCell::new(traits::SpecializesCache::new()),
global_interners: interners,
dep_graph: dep_graph.clone(),
types: common_types,

View file

@ -391,6 +391,7 @@ fn you_know_nothing(jon_snow: &mut i32) {
// but it is already borrowed
};
}
```
In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
cannot be borrowed by the `starks` closure at the same time. To fix this issue,

View file

@ -795,7 +795,17 @@ impl Clean<Lifetime> for hir::Lifetime {
impl Clean<Lifetime> for hir::LifetimeDef {
fn clean(&self, _: &DocContext) -> Lifetime {
Lifetime(self.lifetime.name.to_string())
if self.bounds.len() > 0 {
let mut s = format!("{}: {}",
self.lifetime.name.to_string(),
self.bounds[0].name.to_string());
for bound in self.bounds.iter().skip(1) {
s.push_str(&format!(" + {}", bound.name.to_string()));
}
Lifetime(s)
} else {
Lifetime(self.lifetime.name.to_string())
}
}
}

View file

@ -640,6 +640,10 @@ span.since {
margin-right: 5px;
}
:target > code {
background: #FDFFD3;
}
/* Media Queries */
@media (max-width: 700px) {

View file

@ -67,8 +67,7 @@ struct Context<'a, 'b:'a> {
name_positions: HashMap<String, usize>,
/// Updated as arguments are consumed or methods are entered
nest_level: usize,
/// Updated as arguments are consumed
next_arg: usize,
}
@ -164,9 +163,7 @@ impl<'a, 'b> Context<'a, 'b> {
let pos = match arg.position {
parse::ArgumentNext => {
let i = self.next_arg;
if self.check_positional_ok() {
self.next_arg += 1;
}
self.next_arg += 1;
Exact(i)
}
parse::ArgumentIs(i) => Exact(i),
@ -189,25 +186,13 @@ impl<'a, 'b> Context<'a, 'b> {
self.verify_arg_type(Named(s.to_string()), Unsigned);
}
parse::CountIsNextParam => {
if self.check_positional_ok() {
let next_arg = self.next_arg;
self.verify_arg_type(Exact(next_arg), Unsigned);
self.next_arg += 1;
}
let next_arg = self.next_arg;
self.verify_arg_type(Exact(next_arg), Unsigned);
self.next_arg += 1;
}
}
}
fn check_positional_ok(&mut self) -> bool {
if self.nest_level != 0 {
self.ecx.span_err(self.fmtsp, "cannot use implicit positional \
arguments nested inside methods");
false
} else {
true
}
}
fn describe_num_args(&self) -> String {
match self.args.len() {
0 => "no arguments given".to_string(),
@ -655,7 +640,6 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
name_positions: HashMap::new(),
name_types: HashMap::new(),
name_ordering: name_ordering,
nest_level: 0,
next_arg: 0,
literal: String::new(),
pieces: Vec::new(),