From 391ae7f37aee43000f0244e696fe178521fae2ce Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 15 May 2016 15:29:44 +0200 Subject: [PATCH 1/6] Add lifetime's bounds in doc generation --- src/librustdoc/clean/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7305b0f1fb8bc..b167c47c2657f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -795,7 +795,17 @@ impl Clean for hir::Lifetime { impl Clean 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()) + } } } From 067284b2917561f5bff1db4c521347d897dcaf3b Mon Sep 17 00:00:00 2001 From: Wang Xuerui Date: Mon, 16 May 2016 16:59:27 +0800 Subject: [PATCH 2/6] syntax_ext: format: nest_level's are no more `nest_level` is long dead since cac7a2053aba7be214d5e58e13867089638a8f50 (PR #14831), so is `check_positional_ok()`. Let's bid them farewell. --- src/libsyntax_ext/format.rs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 6c61d6b914c56..7d57614fd7982 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -68,7 +68,6 @@ struct Context<'a, 'b:'a> { name_positions: HashMap, /// Updated as arguments are consumed or methods are entered - nest_level: usize, 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(), From 2ea6c70a1ad43ae8af0e108ddcee4fc06ea9c77c Mon Sep 17 00:00:00 2001 From: Wang Xuerui Date: Mon, 16 May 2016 17:16:32 +0800 Subject: [PATCH 3/6] syntax_ext: format: remove reference to methods in comment --- src/libsyntax_ext/format.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 7d57614fd7982..abfa65580646d 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -67,7 +67,7 @@ struct Context<'a, 'b:'a> { name_positions: HashMap, - /// Updated as arguments are consumed or methods are entered + /// Updated as arguments are consumed next_arg: usize, } From b2613028feeb2c266befe121ff4d16b87c328f9d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 16 May 2016 22:36:13 +0200 Subject: [PATCH 4/6] Fix selected item background style --- src/librustdoc/html/static/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d256e939afcfc..a52a914fea680 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -640,6 +640,10 @@ span.since { margin-right: 5px; } +:target > code { + background: #FDFFD3; +} + /* Media Queries */ @media (max-width: 700px) { From f3c63d21c1af1da00bcf36e6e6490425ff3edbbc Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Mon, 16 May 2016 16:57:33 -0400 Subject: [PATCH 5/6] Add missing code fence to `diagnostics.rs` Closes #33662 --- src/librustc_borrowck/diagnostics.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index cdbad685008f2..b5d8192b4dd2c 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -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, From 29dad1a280f0f346bcbd013239ffb45b2866c2aa Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 17 May 2016 12:05:02 -0400 Subject: [PATCH 6/6] introduce a specializes cache This query is frequently used during trait selection and caching the result can be a reasonable performance win. --- src/librustc/traits/mod.rs | 1 + src/librustc/traits/specialize/mod.rs | 32 +++++++++++++++++++++++++-- src/librustc/ty/context.rs | 3 +++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 65df056fd424b..c5db2a8a7807b 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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; diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index d43d2de1f1fbc..b2d14dab9a0b0 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -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 { + self.map.get(&(a, b)).cloned() + } + + pub fn insert(&mut self, a: DefId, b: DefId, result: bool) { + self.map.insert((a, b), result); + } +} diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 39fe744c67d01..aa50266977795 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -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, + 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,