Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #57630

Merged
merged 31 commits into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
914515f
Drop function parameters in expected order
matthewjasper Nov 18, 2018
aa9bc68
RawVec doesn't always abort on allocation errors
fintelia Jan 8, 2019
6a90f14
Add check_attribute
JohnTitor Jan 9, 2019
3cf3ed7
Separate the description on different lines
JohnTitor Jan 9, 2019
04c74f4
Add core::iter::once_with
Jan 13, 2019
de6566c
forbid manually impl'ing one of an object type's marker traits
arielb1 Jan 5, 2019
7915732
Fix intradoc link and update issue number
Jan 13, 2019
e449f3d
Fix failing test
Jan 13, 2019
f2dbdc4
Add 'rustc-env:RUST_BACKTRACE=0' to const-pat-ice test
Aaron1011 Jan 14, 2019
7c083a8
Remove unnecessary mut
Jan 14, 2019
84718c1
Add feature(iter_once_with)
Jan 14, 2019
3a1f013
Add another feature(iter_once_with)
Jan 14, 2019
d808f93
Simplify 'product' factorial example
timvisee Jan 14, 2019
ea5197c
Add PartialEq
JohnTitor Jan 14, 2019
f18ae26
Run lint for unsafe on the ast
JohnTitor Jan 14, 2019
60a68be
Make UnsafeCode EarlyLintPass
JohnTitor Jan 14, 2019
efd111e
Add test
JohnTitor Jan 14, 2019
a7623e7
Add error check
JohnTitor Jan 14, 2019
d38a59f
fix test output changing in rebase
arielb1 Jan 14, 2019
0d695ff
Fix crates filtering box not being filled
GuillaumeGomez Jan 14, 2019
d04f756
Restore error message
JohnTitor Jan 15, 2019
b39e9e2
Change from _ to None
JohnTitor Jan 15, 2019
bd1551e
Fix tests
JohnTitor Jan 15, 2019
c4b8735
Rollup merge of #56044 - matthewjasper:function-param-drop-order, r=c…
Centril Jan 15, 2019
5fa44c4
Rollup merge of #57352 - arielb1:no-manual-markers, r=nikomatsakis
Centril Jan 15, 2019
77727fe
Rollup merge of #57456 - fintelia:patch-4, r=dtolnay
Centril Jan 15, 2019
e8cfae4
Rollup merge of #57467 - JohnTitor:implement-the-check-attribute-1, r…
Centril Jan 15, 2019
ae1ab8a
Rollup merge of #57579 - stjepang:once-with, r=SimonSapin
Centril Jan 15, 2019
cf43683
Rollup merge of #57587 - Aaron1011:fix/const-pat-ice, r=alexcrichton
Centril Jan 15, 2019
a52ec3c
Rollup merge of #57608 - timvisee:master, r=frewsxcv
Centril Jan 15, 2019
9947b30
Rollup merge of #57614 - GuillaumeGomez:fix-crate-filtering, r=QuietM…
Centril Jan 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use boxed::Box;
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
/// * Guards against 32-bit systems allocating more than isize::MAX bytes
/// * Guards against overflowing your length
/// * Aborts on OOM
/// * Aborts on OOM or calls handle_alloc_error as applicable
/// * Avoids freeing Unique::empty()
/// * Contains a ptr::Unique and thus endows the user with all related benefits
///
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2358,7 +2358,7 @@ pub trait Iterator {
///
/// ```
/// fn factorial(n: u32) -> u32 {
/// (1..).take_while(|&i| i <= n).product()
/// (1..=n).product()
/// }
/// assert_eq!(factorial(0), 1);
/// assert_eq!(factorial(1), 1);
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ pub use self::sources::{RepeatWith, repeat_with};
pub use self::sources::{Empty, empty};
#[stable(feature = "iter_once", since = "1.2.0")]
pub use self::sources::{Once, once};
#[unstable(feature = "iter_once_with", issue = "57581")]
pub use self::sources::{OnceWith, once_with};
#[unstable(feature = "iter_unfold", issue = "55977")]
pub use self::sources::{Unfold, unfold, Successors, successors};

Expand Down
113 changes: 113 additions & 0 deletions src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,119 @@ pub fn once<T>(value: T) -> Once<T> {
Once { inner: Some(value).into_iter() }
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`once_with`] function.
/// See its documentation for more.
///
/// [`once_with`]: fn.once_with.html
#[derive(Copy, Clone, Debug)]
#[unstable(feature = "iter_once_with", issue = "57581")]
pub struct OnceWith<F> {
gen: Option<F>,
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
self.gen.take().map(|f| f())
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.gen.iter().size_hint()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
fn next_back(&mut self) -> Option<A> {
self.next()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
fn len(&self) -> usize {
self.gen.iter().len()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}

#[unstable(feature = "iter_once_with", issue = "57581")]
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}

/// Creates an iterator that lazily generates a value exactly once by invoking
/// the provided closure.
///
/// This is commonly used to adapt a single value generator into a [`chain`] of
/// other kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// Unlike [`once`], this function will lazily generate the value on request.
///
/// [`once`]: fn.once.html
/// [`chain`]: trait.Iterator.html#method.chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iter_once_with)]
///
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once_with(|| 1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// #![feature(iter_once_with)]
///
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[inline]
#[unstable(feature = "iter_once_with", issue = "57581")]
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
OnceWith { gen: Some(gen) }
}

/// Creates a new iterator where each iteration calls the provided closure
/// `F: FnMut(&mut St) -> Option<T>`.
///
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
Expand Down
18 changes: 18 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::cell::Cell;
use core::iter::*;
use core::{i8, i16, isize};
use core::usize;
Expand Down Expand Up @@ -1906,6 +1907,23 @@ fn test_once() {
assert_eq!(it.next(), None);
}

#[test]
fn test_once_with() {
let count = Cell::new(0);
let mut it = once_with(|| {
count.set(count.get() + 1);
42
});

assert_eq!(count.get(), 0);
assert_eq!(it.next(), Some(42));
assert_eq!(count.get(), 1);
assert_eq!(it.next(), None);
assert_eq!(count.get(), 1);
assert_eq!(it.next(), None);
assert_eq!(count.get(), 1);
}

#[test]
fn test_empty() {
let mut it = empty::<i32>();
Expand Down
1 change: 1 addition & 0 deletions src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(hashmap_internals)]
#![feature(iter_copied)]
#![feature(iter_nth_back)]
#![feature(iter_once_with)]
#![feature(iter_unfold)]
#![feature(pattern)]
#![feature(range_is_empty)]
Expand Down
43 changes: 25 additions & 18 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
use syntax::symbol::keywords;
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
use syntax::visit::FnKind;

use rustc::hir::{self, GenericParamKind, PatKind};
use rustc::hir::intravisit::FnKind;

use nonstandard_style::{MethodLateContext, method_context};

Expand Down Expand Up @@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
}

impl UnsafeCode {
fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) {
fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
// This comes from a macro that has #[allow_internal_unsafe].
if span.allows_unsafe() {
return;
Expand All @@ -226,23 +226,31 @@ impl UnsafeCode {
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
if let hir::ExprKind::Block(ref blk, _) = e.node {
impl EarlyLintPass for UnsafeCode {
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
if attr.check_name("allow_internal_unsafe") {
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
macros using unsafe without triggering \
the `unsafe_code` lint at their call site");
}
}

fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
if let ast::ExprKind::Block(ref blk, _) = e.node {
// Don't warn about generated blocks, that'll just pollute the output.
if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
}
}
}

fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
match it.node {
hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
}

hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
}

Expand All @@ -251,19 +259,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
}

fn check_fn(&mut self,
cx: &LateContext,
fk: FnKind<'tcx>,
_: &hir::FnDecl,
_: &hir::Body,
cx: &EarlyContext,
fk: FnKind,
_: &ast::FnDecl,
span: Span,
_: ast::NodeId) {
match fk {
FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
self.report_unsafe(cx, span, "declaration of an `unsafe` function")
}

FnKind::Method(_, sig, ..) => {
if sig.header.unsafety == hir::Unsafety::Unsafe {
if sig.header.unsafety == ast::Unsafety::Unsafe {
self.report_unsafe(cx, span, "implementation of an `unsafe` method")
}
}
Expand All @@ -272,9 +279,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
}
}

fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
if sig.header.unsafety == hir::Unsafety::Unsafe {
fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
if let ast::TraitItemKind::Method(ref sig, None) = item.node {
if sig.header.unsafety == ast::Unsafety::Unsafe {
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
add_early_builtin!(sess,
UnusedParens,
UnusedImportBraces,
UnsafeCode,
AnonymousParameters,
UnusedDocComment,
BadRepr,
Expand All @@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
NonSnakeCase: NonSnakeCase,
NonUpperCaseGlobals: NonUpperCaseGlobals,
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
UnsafeCode: UnsafeCode,
UnusedAllocation: UnusedAllocation,
MissingCopyImplementations: MissingCopyImplementations,
UnstableFeatures: UnstableFeatures,
Expand Down
14 changes: 7 additions & 7 deletions src/librustc_mir/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let place = Place::Local(local);
let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;

// Make sure we drop (parts of) the argument even when not matched on.
self.schedule_drop(
pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
argument_scope, &place, ty,
DropKind::Value { cached_block: CachedBlock::default() },
);

if let Some(pattern) = pattern {
let pattern = self.hir.pattern_from_hir(pattern);
let span = pattern.span;
Expand Down Expand Up @@ -941,13 +948,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}
}

// Make sure we drop (parts of) the argument even when not matched on.
self.schedule_drop(
pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
argument_scope, &place, ty,
DropKind::Value { cached_block: CachedBlock::default() },
);
}

// Enter the argument pattern bindings source scope, if it exists.
Expand Down
17 changes: 13 additions & 4 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,23 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
// This is something like impl Trait1 for Trait2. Illegal
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.

if let Some(principal_def_id) = data.principal_def_id() {
if !tcx.is_object_safe(principal_def_id) {
let component_def_ids = data.iter().flat_map(|predicate| {
match predicate.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => Some(tr.def_id),
ty::ExistentialPredicate::AutoTrait(def_id) => Some(*def_id),
// An associated type projection necessarily comes with
// an additional `Trait` requirement.
ty::ExistentialPredicate::Projection(..) => None,
}
});

for component_def_id in component_def_ids {
if !tcx.is_object_safe(component_def_id) {
// This is an error, but it will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
} else {
let mut supertrait_def_ids =
traits::supertrait_def_ids(tcx, principal_def_id);
traits::supertrait_def_ids(tcx, component_def_id);
if supertrait_def_ids.any(|d| d == trait_def_id) {
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
struct_span_err!(tcx.sess,
Expand All @@ -193,6 +203,5 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
}
}
}
// FIXME: also check auto-trait def-ids? (e.g. `impl Sync for Foo+Sync`)?
}
}
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2431,7 +2431,7 @@ if (!DOMTokenList.prototype.remove) {
return;
}
var crates_text = [];
if (crates.length > 1) {
if (Object.keys(crates).length > 1) {
for (var crate in crates) {
if (crates.hasOwnProperty(crate)) {
crates_text.push(crate);
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,13 +853,13 @@ pub struct Field {

pub type SpannedIdent = Spanned<Ident>;

#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
pub enum BlockCheckMode {
Default,
Unsafe(UnsafeSource),
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
pub enum UnsafeSource {
CompilerGenerated,
UserProvided,
Expand Down
Loading