diff --git a/src/doc/unstable-book/src/library-features/string-retain.md b/src/doc/unstable-book/src/library-features/string-retain.md deleted file mode 100644 index 049444aa49bdd..0000000000000 --- a/src/doc/unstable-book/src/library-features/string-retain.md +++ /dev/null @@ -1,23 +0,0 @@ -# `string_retain` - -The tracking issue for this feature is: [#43874] - -[#43874]: https://github.com/rust-lang/rust/issues/43874 - ------------------------- - -Retains only the characters specified by the predicate. - -In other words, remove all characters `c` such that `f(c)` returns `false`. -This method operates in place and preserves the order of the retained -characters. - -```rust -#![feature(string_retain)] - -let mut s = String::from("f_o_ob_ar"); - -s.retain(|c| c != '_'); - -assert_eq!(s, "foobar"); -``` diff --git a/src/liballoc/binary_heap.rs b/src/liballoc/binary_heap.rs index 8aaac5d6e08a5..f6a666b599b09 100644 --- a/src/liballoc/binary_heap.rs +++ b/src/liballoc/binary_heap.rs @@ -509,6 +509,31 @@ impl BinaryHeap { self.data.shrink_to_fit(); } + /// Discards capacity with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::BinaryHeap; + /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); + /// + /// assert!(heap.capacity() >= 100); + /// heap.shrink_to(10); + /// assert!(heap.capacity() >= 10); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.data.shrink_to(min_capacity) + } + /// Removes the greatest item from the binary heap and returns it, or `None` if it /// is empty. /// diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index e253122ffd6b6..23c12bef3aa7c 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1015,6 +1015,34 @@ impl String { self.vec.shrink_to_fit() } + /// Shrinks the capacity of this `String` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// let mut s = String::from("foo"); + /// + /// s.reserve(100); + /// assert!(s.capacity() >= 100); + /// + /// s.shrink_to(10); + /// assert!(s.capacity() >= 10); + /// s.shrink_to(0); + /// assert!(s.capacity() >= 3); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.vec.shrink_to(min_capacity) + } + /// Appends the given [`char`] to the end of this `String`. /// /// [`char`]: ../../std/primitive.char.html @@ -1177,8 +1205,6 @@ impl String { /// # Examples /// /// ``` - /// #![feature(string_retain)] - /// /// let mut s = String::from("f_o_ob_ar"); /// /// s.retain(|c| c != '_'); @@ -1186,7 +1212,7 @@ impl String { /// assert_eq!(s, "foobar"); /// ``` #[inline] - #[unstable(feature = "string_retain", issue = "43874")] + #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(char) -> bool { diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 953f95876be15..bcc999d738633 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -66,7 +66,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::Ordering; +use core::cmp::{self, Ordering}; use core::fmt; use core::hash::{self, Hash}; use core::intrinsics::{arith_offset, assume}; @@ -334,9 +334,10 @@ impl Vec { /// The vector will be able to hold exactly `capacity` elements without /// reallocating. If `capacity` is 0, the vector will not allocate. /// - /// It is important to note that this function does not specify the *length* - /// of the returned vector, but only the *capacity*. For an explanation of - /// the difference between length and capacity, see *[Capacity and reallocation]*. + /// It is important to note that although the returned vector has the + /// *capacity* specified, the vector will have a zero *length*. For an + /// explanation of the difference between length and capacity, see + /// *[Capacity and reallocation]*. /// /// [Capacity and reallocation]: #capacity-and-reallocation /// @@ -586,6 +587,31 @@ impl Vec { self.buf.shrink_to_fit(self.len); } + /// Shrinks the capacity of the vector with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// let mut vec = Vec::with_capacity(10); + /// vec.extend([1, 2, 3].iter().cloned()); + /// assert_eq!(vec.capacity(), 10); + /// vec.shrink_to(4); + /// assert!(vec.capacity() >= 4); + /// vec.shrink_to(0); + /// assert!(vec.capacity() >= 3); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.buf.shrink_to_fit(cmp::max(self.len, min_capacity)); + } + /// Converts the vector into [`Box<[T]>`][owned slice]. /// /// Note that this will drop any excess capacity. diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 0658777f0a0e0..be6e8d0f22f07 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -676,9 +676,42 @@ impl VecDeque { /// ``` #[stable(feature = "deque_extras_15", since = "1.5.0")] pub fn shrink_to_fit(&mut self) { + self.shrink_to(0); + } + + /// Shrinks the capacity of the `VecDeque` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::with_capacity(15); + /// buf.extend(0..4); + /// assert_eq!(buf.capacity(), 15); + /// buf.shrink_to(6); + /// assert!(buf.capacity() >= 6); + /// buf.shrink_to(0); + /// assert!(buf.capacity() >= 4); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity"); + // +1 since the ringbuffer always leaves one space empty // len + 1 can't overflow for an existing, well-formed ringbuffer. - let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); + let target_cap = cmp::max( + cmp::max(min_capacity, self.len()) + 1, + MINIMUM_CAPACITY + 1 + ).next_power_of_two(); + if target_cap < self.cap() { // There are three cases of interest: // All elements are out of desired bounds diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs deleted file mode 100644 index 2620448927d86..0000000000000 --- a/src/librustc_const_eval/lib.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! constant evaluation on the HIR and code to validate patterns/matches -//! -//! # Note -//! -//! This API is completely unstable and subject to change. - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(warnings)] - -#![feature(rustc_diagnostic_macros)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(macro_lifetime_matcher)] -#![cfg_attr(stage0, feature(i128_type))] -#![feature(from_ref)] - -extern crate arena; -#[macro_use] extern crate syntax; -#[macro_use] extern crate log; -#[macro_use] extern crate rustc; -extern crate rustc_const_math; -extern crate rustc_data_structures; -extern crate rustc_errors; -extern crate syntax_pos; - -// NB: This module needs to be declared first so diagnostics are -// registered before they are used. -mod diagnostics; - -mod eval; -mod _match; -pub mod check_match; -pub mod pattern; - -pub use eval::*; - -use rustc::ty::maps::Providers; - -pub fn provide(providers: &mut Providers) { - *providers = Providers { - check_match: check_match::check_match, - ..*providers - }; -} - -// Build the diagnostics array at the end so that the metadata includes error use sites. -__build_diagnostic_array! { librustc_const_eval, DIAGNOSTICS } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index a3115544f30b9..c6ebc99268057 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -901,7 +901,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, Some(future) => { let prev_graph = time(sess, "blocked while dep-graph loading finishes", || { future.open() - .expect("Could not join with background dep_graph thread") + .unwrap_or_else(|e| rustc_incremental::LoadResult::Error { + message: format!("could not decode incremental cache: {:?}", e) + }) .open(sess) }); DepGraph::new(prev_graph) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 5a33f566e903a..cad72ff778b55 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -39,6 +39,7 @@ pub use assert_dep_graph::assert_dep_graph; pub use persist::dep_graph_tcx_init; pub use persist::load_dep_graph; pub use persist::load_query_result_cache; +pub use persist::LoadResult; pub use persist::save_dep_graph; pub use persist::save_trans_partition; pub use persist::save_work_products; diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 38468e29427b0..44d6e532f79bb 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -89,7 +89,8 @@ impl LoadResult { pub fn open(self, sess: &Session) -> PreviousDepGraph { match self { LoadResult::Error { message } => { - sess.fatal(&message) /* never returns */ + sess.warn(&message); + PreviousDepGraph::new(SerializedDepGraph::new()) }, LoadResult::DataOutOfDate => { if let Err(err) = delete_all_session_dir_contents(sess) { diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index 2f864aaefba89..755a550b5bca3 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -27,6 +27,7 @@ pub use self::fs::prepare_session_directory; pub use self::load::dep_graph_tcx_init; pub use self::load::load_dep_graph; pub use self::load::load_query_result_cache; +pub use self::load::LoadResult; pub use self::save::save_dep_graph; pub use self::save::save_work_products; pub use self::work_product::save_trans_partition; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index d19359578330d..5bd63e0340e5c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -713,6 +713,7 @@ fn link_natively(sess: &Session, // linking executables as pie. Different versions of gcc seem to use // different quotes in the error message so don't check for them. if sess.target.target.options.linker_is_gnu && + sess.linker_flavor() != LinkerFlavor::Ld && (out.contains("unrecognized command line option") || out.contains("unknown argument")) && out.contains("-no-pie") && @@ -1008,8 +1009,9 @@ fn link_args(cmd: &mut Linker, } else { // recent versions of gcc can be configured to generate position // independent executables by default. We have to pass -no-pie to - // explicitly turn that off. - if sess.target.target.options.linker_is_gnu { + // explicitly turn that off. Not applicable to ld. + if sess.target.target.options.linker_is_gnu + && sess.linker_flavor() != LinkerFlavor::Ld { cmd.no_position_independent_executable(); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42c9d9e52f35c..3a79c14f4ec2a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1380,17 +1380,18 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option, has_self } } -impl<'tcx> Clean for ty::TraitRef<'tcx> { +impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec) { fn clean(&self, cx: &DocContext) -> TyParamBound { - inline::record_extern_fqn(cx, self.def_id, TypeKind::Trait); - let path = external_path(cx, &cx.tcx.item_name(self.def_id), - Some(self.def_id), true, vec![], self.substs); + let (trait_ref, ref bounds) = *self; + inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); + let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id), + Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs); - debug!("ty::TraitRef\n subst: {:?}\n", self.substs); + debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); // collect any late bound regions let mut late_bounds = vec![]; - for ty_s in self.input_types().skip(1) { + for ty_s in trait_ref.input_types().skip(1) { if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { @@ -1410,7 +1411,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { trait_: ResolvedPath { path, typarams: None, - did: self.def_id, + did: trait_ref.def_id, is_generic: false, }, generic_params: late_bounds, @@ -1420,6 +1421,12 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { } } +impl<'tcx> Clean for ty::TraitRef<'tcx> { + fn clean(&self, cx: &DocContext) -> TyParamBound { + (self, vec![]).clean(cx) + } +} + impl<'tcx> Clean>> for Substs<'tcx> { fn clean(&self, cx: &DocContext) -> Option> { let mut v = Vec::new(); @@ -2780,9 +2787,51 @@ impl<'tcx> Clean for Ty<'tcx> { let predicates_of = cx.tcx.predicates_of(def_id); let substs = cx.tcx.lift(&substs).unwrap(); let bounds = predicates_of.instantiate(cx.tcx, substs); - ImplTrait(bounds.predicates.into_iter().filter_map(|predicate| { - predicate.to_opt_poly_trait_ref().clean(cx) - }).collect()) + let mut regions = vec![]; + let mut has_sized = false; + let mut bounds = bounds.predicates.iter().filter_map(|predicate| { + let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() { + tr + } else if let ty::Predicate::TypeOutlives(pred) = *predicate { + // these should turn up at the end + pred.skip_binder().1.clean(cx).map(|r| regions.push(RegionBound(r))); + return None; + } else { + return None; + }; + + if let Some(sized) = cx.tcx.lang_items().sized_trait() { + if trait_ref.def_id() == sized { + has_sized = true; + return None; + } + } + + + let bounds = bounds.predicates.iter().filter_map(|pred| + if let ty::Predicate::Projection(proj) = *pred { + let proj = proj.skip_binder(); + if proj.projection_ty.trait_ref(cx.tcx) == *trait_ref.skip_binder() { + Some(TypeBinding { + name: cx.tcx.associated_item(proj.projection_ty.item_def_id) + .name.clean(cx), + ty: proj.ty.clean(cx), + }) + } else { + None + } + } else { + None + } + ).collect(); + + Some((trait_ref.skip_binder(), bounds).clean(cx)) + }).collect::>(); + bounds.extend(regions); + if !has_sized && !bounds.is_empty() { + bounds.insert(0, TyParamBound::maybe_sized(cx)); + } + ImplTrait(bounds) } ty::TyClosure(..) | ty::TyGenerator(..) => Tuple(vec![]), // FIXME(pcwalton) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a5519..2eee60890e87d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2243,14 +2243,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, implementor_dups: &FxHashMap<&str, (DefId, bool)>) -> Result<(), fmt::Error> { - write!(w, "
  • ")?; - if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() { - write!(w, "
    ")?; - write!(w, "[src]", - l, "goto source code")?; - write!(w, "
    ")?; - } - write!(w, "")?; + write!(w, "
  • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { @@ -2269,7 +2262,14 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, write!(w, ";")?; } } - writeln!(w, "")?; + write!(w, "")?; + if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() { + write!(w, "
    ")?; + write!(w, "[src]", + l, "goto source code")?; + write!(w, "
    ")?; + } + writeln!(w, "
  • ")?; Ok(()) } @@ -3314,10 +3314,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi Some(ref t) => format!("impl-{}", small_url_encode(&format!("{:#}", t))), None => "impl".to_string(), }); - write!(w, "

    {}", + write!(w, "

    \ +
    {}", id, i.inner_impl())?; write!(w, "", id)?; - write!(w, "")?; + write!(w, "")?; let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); if let Some(l) = (Item { item: &i.impl_item, cx: cx }).src_href() { write!(w, "
    ")?; @@ -3327,8 +3328,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } else { render_stability_since_raw(w, since, outer_version)?; } - write!(w, "
    ")?; - write!(w, "\n")?; + write!(w, "

    ")?; if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { write!(w, "
    {}
    ", Markdown(&*dox, &i.impl_item.links()))?; @@ -3357,19 +3357,20 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi write!(w, "

    ", id, item_type)?; write!(w, "{}", spotlight_decl(decl)?)?; write!(w, "

    ")?; } } clean::TypedefItem(ref tydef, _) => { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6c6c067f95189..66f45272e726b 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1171,6 +1171,10 @@ return h1.innerHTML; } + function pathSplitter(path) { + return '' + path.replace(/::/g, '::'); + } + function addTab(array, query, display) { var extraStyle = ''; if (display === false) { @@ -1225,7 +1229,7 @@ output += '' + '' + - displayPath + '' + + pathSplitter(displayPath) + '' + name + '' + '' + '' + escape(item.desc) + @@ -1713,19 +1717,20 @@ // we are collapsing the impl block function implHider(addOrRemove) { return function(n) { - if (hasClass(n, "method")) { - if (addOrRemove) { - addClass(n, "hidden-by-impl-hider"); - } else { - removeClass(n, "hidden-by-impl-hider"); + var is_method = hasClass(n, "method"); + if (is_method || hasClass(n, "type")) { + if (is_method === true) { + if (addOrRemove) { + addClass(n, "hidden-by-impl-hider"); + } else { + removeClass(n, "hidden-by-impl-hider"); + } } var ns = n.nextElementSibling; while (true) { if (ns && ( hasClass(ns, "docblock") || - hasClass(ns, "stability") || - false - )) { + hasClass(ns, "stability"))) { if (addOrRemove) { addClass(ns, "hidden-by-impl-hider"); } else { @@ -1741,12 +1746,13 @@ } var relatedDoc = toggle.parentNode; + var docblock = relatedDoc.nextElementSibling; while (!hasClass(relatedDoc, "impl-items")) { relatedDoc = relatedDoc.nextElementSibling; } - if (!relatedDoc) { + if (!relatedDoc && !hasClass(docblock, "docblock")) { return; } @@ -1754,7 +1760,8 @@ var action = mode; if (action === "toggle") { - if (hasClass(relatedDoc, "fns-now-collapsed")) { + if (hasClass(relatedDoc, "fns-now-collapsed") || + hasClass(docblock, "hidden-by-impl-hider")) { action = "show"; } else { action = "hide"; @@ -1763,10 +1770,12 @@ if (action === "show") { removeClass(relatedDoc, "fns-now-collapsed"); + removeClass(docblock, "hidden-by-usual-hider"); onEach(toggle.childNodes, adjustToggle(false)); onEach(relatedDoc.childNodes, implHider(false)); } else if (action === "hide") { addClass(relatedDoc, "fns-now-collapsed"); + addClass(docblock, "hidden-by-usual-hider"); onEach(toggle.childNodes, adjustToggle(true)); onEach(relatedDoc.childNodes, implHider(true)); } @@ -1816,6 +1825,9 @@ var func = function(e) { var next = e.nextElementSibling; + if (hasClass(e, 'impl') && next && hasClass(next, 'docblock')) { + next = next.nextElementSibling; + } if (!next) { return; } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 9b899dd4517ea..949b41d3aea22 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -296,6 +296,11 @@ nav.sub { overflow: auto; } +#results > table { + width: 100%; + table-layout: fixed; +} + .content pre.line-numbers { float: left; border: none; @@ -387,8 +392,6 @@ h4 > code, h3 > code, .invisible > code { .content .in-band { margin: 0px; padding: 0px; - display: inline-block; - max-width: calc(100% - 43px); } .in-band > code { @@ -403,7 +406,7 @@ h4 > code, h3 > code, .invisible > code { font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } -.content table { +.content table:not(.table-display) { border-spacing: 0 5px; border-collapse: separate; } @@ -470,7 +473,6 @@ h4 > code, h3 > code, .invisible > code { .content .methods > div:not(.important-traits) { margin-left: 40px; } .content .impl-items .docblock, .content .impl-items .stability { - margin-left: 40px; margin-bottom: .6em; } .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { @@ -577,8 +579,16 @@ a { display: block; } -.content .search-results td:first-child { padding-right: 0; } -.content .search-results td:first-child a { padding-right: 10px; } +.content .search-results td:first-child { + padding-right: 0; + width: 75%; +} +.content .search-results td:first-child a { + padding-right: 10px; +} +.content .search-results td:first-child a span { + float: left; +} tr.result span.primitive::after { content: ' (primitive type)'; @@ -1254,3 +1264,28 @@ kbd { /* important because of conflicting rule for small screens */ display: none !important; } + +#implementations-list > h3 > span.in-band { + width: 100%; +} + +.table-display { + width: 100%; + border: 0; + border-collapse: collapse; + border-spacing: 0; + font-size: 16px; +} + +.table-display tr td:first-child { + padding-right: 0; +} + +.table-display tr td:last-child { + float: right; +} +.table-display .out-of-band { + position: relative; + font-size: 19px; + display: block; +} diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f0bb781411fb4..474999a6646df 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -910,6 +910,46 @@ impl HashMap } } + /// Shrinks the capacity of the map with a lower limit. It will drop + /// down no lower than the supplied limit while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::HashMap; + /// + /// let mut map: HashMap = HashMap::with_capacity(100); + /// map.insert(1, 2); + /// map.insert(3, 4); + /// assert!(map.capacity() >= 100); + /// map.shrink_to(10); + /// assert!(map.capacity() >= 10); + /// map.shrink_to(0); + /// assert!(map.capacity() >= 2); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity"); + + let new_raw_cap = self.resize_policy.raw_capacity(max(self.len(), min_capacity)); + if self.raw_capacity() != new_raw_cap { + let old_table = replace(&mut self.table, RawTable::new(new_raw_cap)); + let old_size = old_table.size(); + + // Shrink the table. Naive algorithm for resizing: + for (h, k, v) in old_table.into_iter() { + self.insert_hashed_nocheck(h, k, v); + } + + debug_assert_eq!(self.table.size(), old_size); + } + } + /// Insert a pre-hashed key-value pair, without first checking /// that there's enough room in the buckets. Returns a reference to the /// newly insert value. diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 9e63ba2717a6a..855563a5cb8db 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -292,6 +292,34 @@ impl HashSet self.map.shrink_to_fit() } + /// Shrinks the capacity of the set with a lower limit. It will drop + /// down no lower than the supplied limit while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::with_capacity(100); + /// set.insert(1); + /// set.insert(2); + /// assert!(set.capacity() >= 100); + /// set.shrink_to(10); + /// assert!(set.capacity() >= 10); + /// set.shrink_to(0); + /// assert!(set.capacity() >= 2); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.map.shrink_to(min_capacity) + } + /// An iterator visiting all elements in arbitrary order. /// The iterator element type is `&'a T`. /// diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 3959e8533be5f..7520121a8c290 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -295,6 +295,36 @@ impl OsString { self.inner.shrink_to_fit() } + /// Shrinks the capacity of the `OsString` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::ffi::OsString; + /// + /// let mut s = OsString::from("foo"); + /// + /// s.reserve(100); + /// assert!(s.capacity() >= 100); + /// + /// s.shrink_to(10); + /// assert!(s.capacity() >= 10); + /// s.shrink_to(0); + /// assert!(s.capacity() >= 3); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + /// Converts this `OsString` into a boxed [`OsStr`]. /// /// [`OsStr`]: struct.OsStr.html diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 15a22443b6af7..68d3b946d9ef5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -298,6 +298,7 @@ #![feature(raw)] #![feature(rustc_attrs)] #![feature(stdsimd)] +#![feature(shrink_to)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] #![feature(slice_internals)] diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index 655bfdb916707..da27787babb97 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index e034938799866..e43bc6da5f1f8 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/wasm/os_str.rs b/src/libstd/sys/wasm/os_str.rs index 543c22ebe18a3..84f560af69bec 100644 --- a/src/libstd/sys/wasm/os_str.rs +++ b/src/libstd/sys/wasm/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 414c9c5418e45..bcc66b9954b89 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -113,6 +113,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + #[inline] pub fn into_box(self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 78b2bb5fe6e2f..dda4e1bab3b42 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -253,6 +253,11 @@ impl Wtf8Buf { self.bytes.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.bytes.shrink_to(min_capacity) + } + /// Returns the number of bytes that this string buffer can hold without reallocating. #[inline] pub fn capacity(&self) -> usize { diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 3d5cce81278ac..382ef2cc407dd 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -205,17 +205,13 @@ GEN_SUBTARGETS extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, const char *Feature) { -#if LLVM_RUSTLLVM +#if LLVM_VERSION_GE(6, 0) TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - const FeatureBitset &Bits = MCInfo->getFeatureBits(); - const ArrayRef FeatTable = MCInfo->getFeatureTable(); - - for (auto &FeatureEntry : FeatTable) - if (!strcmp(FeatureEntry.Key, Feature)) - return (Bits & FeatureEntry.Value) == FeatureEntry.Value; -#endif + return MCInfo->checkFeatures(std::string("+") + Feature); +#else return false; +#endif } enum class LLVMRustCodeModel { diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index 22469b2fde058..b1d7e5435c4cb 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// no-system-llvm -- needs MCSubtargetInfo::getFeatureTable() +// min-llvm-version 6.0 +// ^ needs MCSubtargetInfo::checkFeatures() // ignore-cloudabi no std::env #![feature(cfg_target_feature)] @@ -29,4 +30,7 @@ fn main() { assert!(cfg!(target_feature = "sse2"), "SSE2 was not detected as available on an x86 platform"); } + // check a negative case too -- whitelisted on x86, but not enabled by default + assert!(cfg!(not(target_feature = "avx2")), + "AVX2 shouldn't be detected as available by default on any platform"); } diff --git a/src/test/rustdoc/auxiliary/extern-impl-trait.rs b/src/test/rustdoc/auxiliary/extern-impl-trait.rs new file mode 100644 index 0000000000000..ba6c3e956953b --- /dev/null +++ b/src/test/rustdoc/auxiliary/extern-impl-trait.rs @@ -0,0 +1,37 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait Foo { + type Associated; +} + +pub struct X; +pub struct Y; + + +impl Foo for X { + type Associated = (); +} + +impl Foo for Y { + type Associated = (); +} + +impl X { + pub fn returns_sized<'a>(&'a self) -> impl Foo + 'a { + X + } +} + +impl Y { + pub fn returns_unsized<'a>(&'a self) -> Box + 'a> { + Box::new(X) + } +} diff --git a/src/test/rustdoc/extern-impl-trait.rs b/src/test/rustdoc/extern-impl-trait.rs new file mode 100644 index 0000000000000..02a8e962fe17b --- /dev/null +++ b/src/test/rustdoc/extern-impl-trait.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:extern-impl-trait.rs + +#![crate_name = "foo"] + +extern crate extern_impl_trait; + +// @has 'foo/struct.X.html' '//code' "impl Foo + 'a" +pub use extern_impl_trait::X; + +// @has 'foo/struct.Y.html' '//code' "impl ?Sized + Foo + 'a" +pub use extern_impl_trait::Y; diff --git a/src/test/rustdoc/synthetic_auto/complex.rs b/src/test/rustdoc/synthetic_auto/complex.rs index 531798c30c656..a4ebf6d3a7e83 100644 --- a/src/test/rustdoc/synthetic_auto/complex.rs +++ b/src/test/rustdoc/synthetic_auto/complex.rs @@ -30,7 +30,7 @@ mod foo { } // @has complex/struct.NotOuter.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'a, T, K: \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'a, T, K: \ // ?Sized> Send for NotOuter<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \ // -> &'b i8, T: MyTrait<'a>, >::MyItem: Copy, 'a: 'static" diff --git a/src/test/rustdoc/synthetic_auto/lifetimes.rs b/src/test/rustdoc/synthetic_auto/lifetimes.rs index 272925e5db542..1c1e7bc250526 100644 --- a/src/test/rustdoc/synthetic_auto/lifetimes.rs +++ b/src/test/rustdoc/synthetic_auto/lifetimes.rs @@ -18,10 +18,10 @@ where {} // @has lifetimes/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Send \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \ // for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Sync \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \ // for Foo<'c, K> where K: Sync" pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>, diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index d81e6309dff61..ef6797ecf3c54 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -9,10 +9,10 @@ // except according to those terms. // @has manual/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' 'impl Sync for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl Sync for \ // Foo where T: Sync' // -// @has - '//*[@id="implementations-list"]/*[@class="impl"]/*/code' \ +// @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' \ // 'impl Send for Foo' // // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1 diff --git a/src/test/rustdoc/synthetic_auto/negative.rs b/src/test/rustdoc/synthetic_auto/negative.rs index ec9cb710f1f8c..64480d28240b6 100644 --- a/src/test/rustdoc/synthetic_auto/negative.rs +++ b/src/test/rustdoc/synthetic_auto/negative.rs @@ -13,10 +13,10 @@ pub struct Inner { } // @has negative/struct.Outer.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl !Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl !Send for \ // Outer" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl \ // !Sync for Outer" pub struct Outer { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/nested.rs b/src/test/rustdoc/synthetic_auto/nested.rs index 1f33a8b13cbf8..ccdbe159b6c5a 100644 --- a/src/test/rustdoc/synthetic_auto/nested.rs +++ b/src/test/rustdoc/synthetic_auto/nested.rs @@ -18,10 +18,10 @@ where } // @has nested/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' 'impl Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl Send for \ // Foo where T: Copy' // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' \ // 'impl Sync for Foo where T: Sync' pub struct Foo { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 0b37f2ed31790..24fba221b9937 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -19,7 +19,7 @@ where } // @has no_redundancy/struct.Outer.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl Send for \ // Outer where T: Copy + Send" pub struct Outer { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/project.rs b/src/test/rustdoc/synthetic_auto/project.rs index 977607fb14826..d588190c4f9d2 100644 --- a/src/test/rustdoc/synthetic_auto/project.rs +++ b/src/test/rustdoc/synthetic_auto/project.rs @@ -33,10 +33,10 @@ where } // @has project/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Send \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \ // for Foo<'c, K> where K: MyTrait, 'c: 'static" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Sync \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \ // for Foo<'c, K> where K: MyTrait, ::MyItem: OtherTrait, 'c: 'static," pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>,