Skip to content

Commit 14ea6e5

Browse files
committed
Auto merge of #57630 - Centril:rollup, r=Centril
Rollup of 8 pull requests Successful merges: - #56044 (Drop partially bound function parameters in the expected order) - #57352 (forbid manually impl'ing one of an object type's marker traits) - #57456 (RawVec doesn't always abort on allocation errors) - #57467 (Implement `check_attribute` to forbid `#[allow_internal_unsafe]`) - #57579 (Add core::iter::once_with()) - #57587 (Add 'rustc-env:RUST_BACKTRACE=0' to const-pat-ice test) - #57608 (Simplify 'product' factorial example) - #57614 ([rustdoc] Fix crates filtering box not being filled) Failed merges: r? @ghost
2 parents 9201924 + 9947b30 commit 14ea6e5

21 files changed

+417
-35
lines changed

src/liballoc/raw_vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use boxed::Box;
2222
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
2323
/// * Guards against 32-bit systems allocating more than isize::MAX bytes
2424
/// * Guards against overflowing your length
25-
/// * Aborts on OOM
25+
/// * Aborts on OOM or calls handle_alloc_error as applicable
2626
/// * Avoids freeing Unique::empty()
2727
/// * Contains a ptr::Unique and thus endows the user with all related benefits
2828
///

src/libcore/iter/iterator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2358,7 +2358,7 @@ pub trait Iterator {
23582358
///
23592359
/// ```
23602360
/// fn factorial(n: u32) -> u32 {
2361-
/// (1..).take_while(|&i| i <= n).product()
2361+
/// (1..=n).product()
23622362
/// }
23632363
/// assert_eq!(factorial(0), 1);
23642364
/// assert_eq!(factorial(1), 1);

src/libcore/iter/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ pub use self::sources::{RepeatWith, repeat_with};
329329
pub use self::sources::{Empty, empty};
330330
#[stable(feature = "iter_once", since = "1.2.0")]
331331
pub use self::sources::{Once, once};
332+
#[unstable(feature = "iter_once_with", issue = "57581")]
333+
pub use self::sources::{OnceWith, once_with};
332334
#[unstable(feature = "iter_unfold", issue = "55977")]
333335
pub use self::sources::{Unfold, unfold, Successors, successors};
334336

src/libcore/iter/sources.rs

+113
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,119 @@ pub fn once<T>(value: T) -> Once<T> {
377377
Once { inner: Some(value).into_iter() }
378378
}
379379

380+
/// An iterator that repeats elements of type `A` endlessly by
381+
/// applying the provided closure `F: FnMut() -> A`.
382+
///
383+
/// This `struct` is created by the [`once_with`] function.
384+
/// See its documentation for more.
385+
///
386+
/// [`once_with`]: fn.once_with.html
387+
#[derive(Copy, Clone, Debug)]
388+
#[unstable(feature = "iter_once_with", issue = "57581")]
389+
pub struct OnceWith<F> {
390+
gen: Option<F>,
391+
}
392+
393+
#[unstable(feature = "iter_once_with", issue = "57581")]
394+
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
395+
type Item = A;
396+
397+
#[inline]
398+
fn next(&mut self) -> Option<A> {
399+
self.gen.take().map(|f| f())
400+
}
401+
402+
#[inline]
403+
fn size_hint(&self) -> (usize, Option<usize>) {
404+
self.gen.iter().size_hint()
405+
}
406+
}
407+
408+
#[unstable(feature = "iter_once_with", issue = "57581")]
409+
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
410+
fn next_back(&mut self) -> Option<A> {
411+
self.next()
412+
}
413+
}
414+
415+
#[unstable(feature = "iter_once_with", issue = "57581")]
416+
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
417+
fn len(&self) -> usize {
418+
self.gen.iter().len()
419+
}
420+
}
421+
422+
#[unstable(feature = "iter_once_with", issue = "57581")]
423+
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
424+
425+
#[unstable(feature = "iter_once_with", issue = "57581")]
426+
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
427+
428+
/// Creates an iterator that lazily generates a value exactly once by invoking
429+
/// the provided closure.
430+
///
431+
/// This is commonly used to adapt a single value generator into a [`chain`] of
432+
/// other kinds of iteration. Maybe you have an iterator that covers almost
433+
/// everything, but you need an extra special case. Maybe you have a function
434+
/// which works on iterators, but you only need to process one value.
435+
///
436+
/// Unlike [`once`], this function will lazily generate the value on request.
437+
///
438+
/// [`once`]: fn.once.html
439+
/// [`chain`]: trait.Iterator.html#method.chain
440+
///
441+
/// # Examples
442+
///
443+
/// Basic usage:
444+
///
445+
/// ```
446+
/// #![feature(iter_once_with)]
447+
///
448+
/// use std::iter;
449+
///
450+
/// // one is the loneliest number
451+
/// let mut one = iter::once_with(|| 1);
452+
///
453+
/// assert_eq!(Some(1), one.next());
454+
///
455+
/// // just one, that's all we get
456+
/// assert_eq!(None, one.next());
457+
/// ```
458+
///
459+
/// Chaining together with another iterator. Let's say that we want to iterate
460+
/// over each file of the `.foo` directory, but also a configuration file,
461+
/// `.foorc`:
462+
///
463+
/// ```no_run
464+
/// #![feature(iter_once_with)]
465+
///
466+
/// use std::iter;
467+
/// use std::fs;
468+
/// use std::path::PathBuf;
469+
///
470+
/// let dirs = fs::read_dir(".foo").unwrap();
471+
///
472+
/// // we need to convert from an iterator of DirEntry-s to an iterator of
473+
/// // PathBufs, so we use map
474+
/// let dirs = dirs.map(|file| file.unwrap().path());
475+
///
476+
/// // now, our iterator just for our config file
477+
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
478+
///
479+
/// // chain the two iterators together into one big iterator
480+
/// let files = dirs.chain(config);
481+
///
482+
/// // this will give us all of the files in .foo as well as .foorc
483+
/// for f in files {
484+
/// println!("{:?}", f);
485+
/// }
486+
/// ```
487+
#[inline]
488+
#[unstable(feature = "iter_once_with", issue = "57581")]
489+
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
490+
OnceWith { gen: Some(gen) }
491+
}
492+
380493
/// Creates a new iterator where each iteration calls the provided closure
381494
/// `F: FnMut(&mut St) -> Option<T>`.
382495
///

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#![feature(extern_types)]
8080
#![feature(fundamental)]
8181
#![feature(intrinsics)]
82+
#![feature(iter_once_with)]
8283
#![feature(lang_items)]
8384
#![feature(link_llvm_intrinsics)]
8485
#![feature(never_type)]

src/libcore/tests/iter.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::cell::Cell;
12
use core::iter::*;
23
use core::{i8, i16, isize};
34
use core::usize;
@@ -1906,6 +1907,23 @@ fn test_once() {
19061907
assert_eq!(it.next(), None);
19071908
}
19081909

1910+
#[test]
1911+
fn test_once_with() {
1912+
let count = Cell::new(0);
1913+
let mut it = once_with(|| {
1914+
count.set(count.get() + 1);
1915+
42
1916+
});
1917+
1918+
assert_eq!(count.get(), 0);
1919+
assert_eq!(it.next(), Some(42));
1920+
assert_eq!(count.get(), 1);
1921+
assert_eq!(it.next(), None);
1922+
assert_eq!(count.get(), 1);
1923+
assert_eq!(it.next(), None);
1924+
assert_eq!(count.get(), 1);
1925+
}
1926+
19091927
#[test]
19101928
fn test_empty() {
19111929
let mut it = empty::<i32>();

src/libcore/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(hashmap_internals)]
1313
#![feature(iter_copied)]
1414
#![feature(iter_nth_back)]
15+
#![feature(iter_once_with)]
1516
#![feature(iter_unfold)]
1617
#![feature(pattern)]
1718
#![feature(range_is_empty)]

src/librustc_lint/builtin.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
4040
use syntax::symbol::keywords;
4141
use syntax::errors::{Applicability, DiagnosticBuilder};
4242
use syntax::print::pprust::expr_to_string;
43+
use syntax::visit::FnKind;
4344

4445
use rustc::hir::{self, GenericParamKind, PatKind};
45-
use rustc::hir::intravisit::FnKind;
4646

4747
use nonstandard_style::{MethodLateContext, method_context};
4848

@@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
216216
}
217217

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

229-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
230-
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
231-
if let hir::ExprKind::Block(ref blk, _) = e.node {
229+
impl EarlyLintPass for UnsafeCode {
230+
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
231+
if attr.check_name("allow_internal_unsafe") {
232+
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
233+
macros using unsafe without triggering \
234+
the `unsafe_code` lint at their call site");
235+
}
236+
}
237+
238+
fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
239+
if let ast::ExprKind::Block(ref blk, _) = e.node {
232240
// Don't warn about generated blocks, that'll just pollute the output.
233-
if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
241+
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
234242
self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
235243
}
236244
}
237245
}
238246

239-
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
247+
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
240248
match it.node {
241-
hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
249+
ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
242250
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
243251
}
244252

245-
hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
253+
ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
246254
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
247255
}
248256

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

253261
fn check_fn(&mut self,
254-
cx: &LateContext,
255-
fk: FnKind<'tcx>,
256-
_: &hir::FnDecl,
257-
_: &hir::Body,
262+
cx: &EarlyContext,
263+
fk: FnKind,
264+
_: &ast::FnDecl,
258265
span: Span,
259266
_: ast::NodeId) {
260267
match fk {
261-
FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
268+
FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
262269
self.report_unsafe(cx, span, "declaration of an `unsafe` function")
263270
}
264271

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

275-
fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
276-
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
277-
if sig.header.unsafety == hir::Unsafety::Unsafe {
282+
fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
283+
if let ast::TraitItemKind::Method(ref sig, None) = item.node {
284+
if sig.header.unsafety == ast::Unsafety::Unsafe {
278285
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
279286
}
280287
}

src/librustc_lint/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
111111
add_early_builtin!(sess,
112112
UnusedParens,
113113
UnusedImportBraces,
114+
UnsafeCode,
114115
AnonymousParameters,
115116
UnusedDocComment,
116117
BadRepr,
@@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
134135
NonSnakeCase: NonSnakeCase,
135136
NonUpperCaseGlobals: NonUpperCaseGlobals,
136137
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
137-
UnsafeCode: UnsafeCode,
138138
UnusedAllocation: UnusedAllocation,
139139
MissingCopyImplementations: MissingCopyImplementations,
140140
UnstableFeatures: UnstableFeatures,

src/librustc_mir/build/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
910910
let place = Place::Local(local);
911911
let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
912912

913+
// Make sure we drop (parts of) the argument even when not matched on.
914+
self.schedule_drop(
915+
pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
916+
argument_scope, &place, ty,
917+
DropKind::Value { cached_block: CachedBlock::default() },
918+
);
919+
913920
if let Some(pattern) = pattern {
914921
let pattern = self.hir.pattern_from_hir(pattern);
915922
let span = pattern.span;
@@ -941,13 +948,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
941948
}
942949
}
943950
}
944-
945-
// Make sure we drop (parts of) the argument even when not matched on.
946-
self.schedule_drop(
947-
pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
948-
argument_scope, &place, ty,
949-
DropKind::Value { cached_block: CachedBlock::default() },
950-
);
951951
}
952952

953953
// Enter the argument pattern bindings source scope, if it exists.

src/librustc_typeck/coherence/mod.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,23 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
171171
// This is something like impl Trait1 for Trait2. Illegal
172172
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
173173

174-
if let Some(principal_def_id) = data.principal_def_id() {
175-
if !tcx.is_object_safe(principal_def_id) {
174+
let component_def_ids = data.iter().flat_map(|predicate| {
175+
match predicate.skip_binder() {
176+
ty::ExistentialPredicate::Trait(tr) => Some(tr.def_id),
177+
ty::ExistentialPredicate::AutoTrait(def_id) => Some(*def_id),
178+
// An associated type projection necessarily comes with
179+
// an additional `Trait` requirement.
180+
ty::ExistentialPredicate::Projection(..) => None,
181+
}
182+
});
183+
184+
for component_def_id in component_def_ids {
185+
if !tcx.is_object_safe(component_def_id) {
176186
// This is an error, but it will be reported by wfcheck. Ignore it here.
177187
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
178188
} else {
179189
let mut supertrait_def_ids =
180-
traits::supertrait_def_ids(tcx, principal_def_id);
190+
traits::supertrait_def_ids(tcx, component_def_id);
181191
if supertrait_def_ids.any(|d| d == trait_def_id) {
182192
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
183193
struct_span_err!(tcx.sess,
@@ -193,6 +203,5 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
193203
}
194204
}
195205
}
196-
// FIXME: also check auto-trait def-ids? (e.g. `impl Sync for Foo+Sync`)?
197206
}
198207
}

src/librustdoc/html/static/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2431,7 +2431,7 @@ if (!DOMTokenList.prototype.remove) {
24312431
return;
24322432
}
24332433
var crates_text = [];
2434-
if (crates.length > 1) {
2434+
if (Object.keys(crates).length > 1) {
24352435
for (var crate in crates) {
24362436
if (crates.hasOwnProperty(crate)) {
24372437
crates_text.push(crate);

src/libsyntax/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -853,13 +853,13 @@ pub struct Field {
853853

854854
pub type SpannedIdent = Spanned<Ident>;
855855

856-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
856+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
857857
pub enum BlockCheckMode {
858858
Default,
859859
Unsafe(UnsafeSource),
860860
}
861861

862-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
862+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
863863
pub enum UnsafeSource {
864864
CompilerGenerated,
865865
UserProvided,

0 commit comments

Comments
 (0)