Skip to content

Commit

Permalink
Auto merge of #51214 - kennytm:rollup, r=kennytm
Browse files Browse the repository at this point in the history
Rollup of 12 pull requests

Successful merges:

 - #51050 (std::fs::DirEntry.metadata(): use fstatat instead of lstat when possible)
 - #51123 (Update build instructions)
 - #51127 (Add doc link from discriminant struct to function.)
 - #51146 (typeck: Do not pass the field check on field error)
 - #51147 (Stabilize SliceIndex trait.)
 - #51151 (Move slice::exact_chunks directly above exact_chunks_mut for more con…)
 - #51152 (Replace `if` with `if and only if` in the definition dox of `Sync`)
 - #51153 (Link panic and compile_error docs)
 - #51158 (Mention spec and indented blocks in doctest docs)
 - #51186 (Remove two redundant .nll.stderr files)
 - #51203 (Two minor `obligation_forest` tweaks.)
 - #51213 (fs: copy: Use File::set_permissions instead of fs::set_permissions)

Failed merges:
  • Loading branch information
bors committed May 30, 2018
2 parents fddb46e + b7b7b25 commit ab61e34
Show file tree
Hide file tree
Showing 16 changed files with 226 additions and 112 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Read ["Installation"] from [The Book].
3. Build and install:

```sh
$ git submodule update --init --recursive --progress
$ ./x.py build && sudo ./x.py install
```

Expand Down
24 changes: 24 additions & 0 deletions src/doc/rustdoc/src/documentation-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,27 @@ environment that has no network access.
compiles, then the test will fail. However please note that code failing
with the current Rust release may work in a future release, as new features
are added.

## Syntax reference

The *exact* syntax for code blocks, including the edge cases, can be found
in the [Fenced Code Blocks](https://spec.commonmark.org/0.28/#fenced-code-blocks)
section of the CommonMark specification.

Rustdoc also accepts *indented* code blocks as an alternative to fenced
code blocks: instead of surrounding your code with three backticks, you
can indent each line by four or more spaces.

``````markdown
let foo = "foo";
assert_eq!(foo, "foo");
``````

These, too, are documented in the CommonMark specification, in the
[Indented Code Blocks](https://spec.commonmark.org/0.28/#indented-code-blocks)
section.

However, it's preferable to use fenced code blocks over indented code blocks.
Not only are fenced code blocks considered more idiomatic for Rust code,
but there is no way to use directives such as `ignore` or `should_panic` with
indented code blocks.
1 change: 0 additions & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
#![feature(ptr_internals)]
#![feature(ptr_offset_from)]
#![feature(rustc_attrs)]
#![feature(slice_get_slice)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(str_internals)]
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub use core::slice::{RSplit, RSplitMut};
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "from_ref", since = "1.28.0")]
pub use core::slice::{from_ref, from_mut};
#[unstable(feature = "slice_get_slice", issue = "35729")]
#[stable(feature = "slice_get_slice", since = "1.28.0")]
pub use core::slice::SliceIndex;
#[unstable(feature = "exact_chunks", issue = "47115")]
pub use core::slice::{ExactChunks, ExactChunksMut};
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ pub trait Copy : Clone {
/// This trait is automatically implemented when the compiler determines
/// it's appropriate.
///
/// The precise definition is: a type `T` is `Sync` if `&T` is
/// The precise definition is: a type `T` is `Sync` if and only if `&T` is
/// [`Send`][send]. In other words, if there is no possibility of
/// [undefined behavior][ub] (including data races) when passing
/// `&T` references between threads.
Expand Down
4 changes: 3 additions & 1 deletion src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,9 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {

/// Opaque type representing the discriminant of an enum.
///
/// See the `discriminant` function in this module for more information.
/// See the [`discriminant`] function in this module for more information.
///
/// [`discriminant`]: fn.discriminant.html
#[stable(feature = "discriminant_value", since = "1.21.0")]
pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);

Expand Down
102 changes: 65 additions & 37 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,41 +691,6 @@ impl<T> [T] {
Chunks { v: self, chunk_size: chunk_size }
}

/// Returns an iterator over `chunk_size` elements of the slice at a
/// time. The chunks are slices and do not overlap. If `chunk_size` does
/// not divide the length of the slice, then the last up to `chunk_size-1`
/// elements will be omitted.
///
/// Due to each chunk having exactly `chunk_size` elements, the compiler
/// can often optimize the resulting code better than in the case of
/// [`chunks`].
///
/// # Panics
///
/// Panics if `chunk_size` is 0.
///
/// # Examples
///
/// ```
/// #![feature(exact_chunks)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.exact_chunks(2);
/// assert_eq!(iter.next().unwrap(), &['l', 'o']);
/// assert_eq!(iter.next().unwrap(), &['r', 'e']);
/// assert!(iter.next().is_none());
/// ```
///
/// [`chunks`]: #method.chunks
#[unstable(feature = "exact_chunks", issue = "47115")]
#[inline]
pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
assert!(chunk_size != 0);
let rem = self.len() % chunk_size;
let len = self.len() - rem;
ExactChunks { v: &self[..len], chunk_size: chunk_size}
}

/// Returns an iterator over `chunk_size` elements of the slice at a time.
/// The chunks are mutable slices, and do not overlap. If `chunk_size` does
/// not divide the length of the slice, then the last chunk will not
Expand Down Expand Up @@ -761,6 +726,41 @@ impl<T> [T] {
ChunksMut { v: self, chunk_size: chunk_size }
}

/// Returns an iterator over `chunk_size` elements of the slice at a
/// time. The chunks are slices and do not overlap. If `chunk_size` does
/// not divide the length of the slice, then the last up to `chunk_size-1`
/// elements will be omitted.
///
/// Due to each chunk having exactly `chunk_size` elements, the compiler
/// can often optimize the resulting code better than in the case of
/// [`chunks`].
///
/// # Panics
///
/// Panics if `chunk_size` is 0.
///
/// # Examples
///
/// ```
/// #![feature(exact_chunks)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.exact_chunks(2);
/// assert_eq!(iter.next().unwrap(), &['l', 'o']);
/// assert_eq!(iter.next().unwrap(), &['r', 'e']);
/// assert!(iter.next().is_none());
/// ```
///
/// [`chunks`]: #method.chunks
#[unstable(feature = "exact_chunks", issue = "47115")]
#[inline]
pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
assert!(chunk_size != 0);
let rem = self.len() % chunk_size;
let len = self.len() - rem;
ExactChunks { v: &self[..len], chunk_size: chunk_size}
}

/// Returns an iterator over `chunk_size` elements of the slice at a time.
/// The chunks are mutable slices, and do not overlap. If `chunk_size` does
/// not divide the length of the slice, then the last up to `chunk_size-1`
Expand Down Expand Up @@ -1977,35 +1977,63 @@ fn slice_index_overflow_fail() -> ! {
panic!("attempted to index slice up to maximum usize");
}

mod private_slice_index {
use super::ops;
#[stable(feature = "slice_get_slice", since = "1.28.0")]
pub trait Sealed {}

#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for usize {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::Range<usize> {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::RangeTo<usize> {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::RangeFrom<usize> {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::RangeFull {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::RangeInclusive<usize> {}
#[stable(feature = "slice_get_slice", since = "1.28.0")]
impl Sealed for ops::RangeToInclusive<usize> {}
}

/// A helper trait used for indexing operations.
#[unstable(feature = "slice_get_slice", issue = "35729")]
#[stable(feature = "slice_get_slice", since = "1.28.0")]
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
pub trait SliceIndex<T: ?Sized> {
pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// The output type returned by methods.
#[stable(feature = "slice_get_slice", since = "1.28.0")]
type Output: ?Sized;

/// Returns a shared reference to the output at this location, if in
/// bounds.
#[unstable(feature = "slice_index_methods", issue = "0")]
fn get(self, slice: &T) -> Option<&Self::Output>;

/// Returns a mutable reference to the output at this location, if in
/// bounds.
#[unstable(feature = "slice_index_methods", issue = "0")]
fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;

/// Returns a shared reference to the output at this location, without
/// performing any bounds checking.
#[unstable(feature = "slice_index_methods", issue = "0")]
unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;

/// Returns a mutable reference to the output at this location, without
/// performing any bounds checking.
#[unstable(feature = "slice_index_methods", issue = "0")]
unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;

/// Returns a shared reference to the output at this location, panicking
/// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "0")]
fn index(self, slice: &T) -> &Self::Output;

/// Returns a mutable reference to the output at this location, panicking
/// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "0")]
fn index_mut(self, slice: &mut T) -> &mut Self::Output;
}

Expand Down
5 changes: 0 additions & 5 deletions src/librustc_data_structures/obligation_forest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ pub struct ObligationForest<O: ForestObligation> {
done_cache: FxHashSet<O::Predicate>,
/// An cache of the nodes in `nodes`, indexed by predicate.
waiting_cache: FxHashMap<O::Predicate, NodeIndex>,
/// A list of the obligations added in snapshots, to allow
/// for their removal.
cache_list: Vec<O::Predicate>,
scratch: Option<Vec<usize>>,
}

Expand Down Expand Up @@ -158,7 +155,6 @@ impl<O: ForestObligation> ObligationForest<O> {
nodes: vec![],
done_cache: FxHashSet(),
waiting_cache: FxHashMap(),
cache_list: vec![],
scratch: Some(vec![]),
}
}
Expand Down Expand Up @@ -207,7 +203,6 @@ impl<O: ForestObligation> ObligationForest<O> {
debug!("register_obligation_at({:?}, {:?}) - ok, new index is {}",
obligation, parent, self.nodes.len());
v.insert(NodeIndex::new(self.nodes.len()));
self.cache_list.push(obligation.as_predicate().clone());
self.nodes.push(Node::new(parent, obligation));
Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_data_structures/obligation_forest/node_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ pub struct NodeIndex {
}

impl NodeIndex {
#[inline]
pub fn new(value: usize) -> NodeIndex {
assert!(value < (u32::MAX as usize));
NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() }
}

#[inline]
pub fn get(self) -> usize {
(self.index.get() - 1) as usize
}
Expand Down
13 changes: 10 additions & 3 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
self.demand_eqtype(pat.span, expected, pat_ty);

// Type check subpatterns.
self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm);
pat_ty
if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
pat_ty
} else {
self.tcx.types.err
}
}

fn check_pat_path(&self,
Expand Down Expand Up @@ -846,7 +849,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
variant: &'tcx ty::VariantDef,
fields: &'gcx [Spanned<hir::FieldPat>],
etc: bool,
def_bm: ty::BindingMode) {
def_bm: ty::BindingMode) -> bool {
let tcx = self.tcx;

let (substs, adt) = match adt_ty.sty {
Expand All @@ -864,6 +867,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");

// Keep track of which fields have already appeared in the pattern.
let mut used_fields = FxHashMap();
let mut no_field_errors = true;

let mut inexistent_fields = vec![];
// Typecheck each field.
Expand All @@ -879,6 +883,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
format!("multiple uses of `{}` in pattern", field.ident))
.span_label(*occupied.get(), format!("first use of `{}`", field.ident))
.emit();
no_field_errors = false;
tcx.types.err
}
Vacant(vacant) => {
Expand All @@ -891,6 +896,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
})
.unwrap_or_else(|| {
inexistent_fields.push((span, field.ident));
no_field_errors = false;
tcx.types.err
})
}
Expand Down Expand Up @@ -989,5 +995,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
diag.emit();
}
}
no_field_errors
}
}
12 changes: 10 additions & 2 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@
/// The multi-argument form of this macro panics with a string and has the
/// [`format!`] syntax for building a string.
///
/// See also the macro [`compile_error!`], for raising errors during compilation.
///
/// [runwrap]: ../std/result/enum.Result.html#method.unwrap
/// [`Option`]: ../std/option/enum.Option.html#method.unwrap
/// [`Result`]: ../std/result/enum.Result.html
/// [`format!`]: ../std/macro.format.html
/// [`compile_error!`]: ../std/macro.compile_error.html
/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html
///
/// # Current implementation
Expand Down Expand Up @@ -286,13 +289,16 @@ pub mod builtin {
/// Unconditionally causes compilation to fail with the given error message when encountered.
///
/// This macro should be used when a crate uses a conditional compilation strategy to provide
/// better error messages for erroneous conditions.
/// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
/// which emits an error at *runtime*, rather than during compilation.
///
/// # Examples
///
/// Two such examples are macros and `#[cfg]` environments.
///
/// Emit better compiler error if a macro is passed invalid values.
/// Emit better compiler error if a macro is passed invalid values. Without the final branch,
/// the compiler would still emit an error, but the error's message would not mention the two
/// valid values.
///
/// ```compile_fail
/// macro_rules! give_me_foo_or_bar {
Expand All @@ -313,6 +319,8 @@ pub mod builtin {
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
/// ```
///
/// [`panic!`]: ../std/macro.panic.html
#[stable(feature = "compile_error_macro", since = "1.20.0")]
#[macro_export]
macro_rules! compile_error {
Expand Down
Loading

0 comments on commit ab61e34

Please sign in to comment.