From 914515f8090be23e7ae0acc29cdccf6360d1a03d Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 18 Nov 2018 14:49:24 +0000 Subject: [PATCH 01/23] Drop function parameters in expected order Given the function fn foo((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {} Prior to 1.12 we dropped both `_x` and `_y` before the rest of their respective parameters, since then we dropped `_x` and `_y` after. The original order appears to be the correct order, as the value created later is dropped first, so we revert to that order and add a test for it. --- src/librustc_mir/build/mod.rs | 14 ++-- .../fn-arg-incomplete-pattern-drop-order.rs | 68 +++++++++++++++++++ 2 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d95a74be776..bc12c262716 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -915,6 +915,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; @@ -946,13 +953,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. diff --git a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs new file mode 100644 index 00000000000..4d5a6fbba28 --- /dev/null +++ b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs @@ -0,0 +1,68 @@ +// Check that partially moved from function parameters are dropped after the +// named bindings that move from them. + +// ignore-wasm32-bare compiled with panic=abort by default + +use std::{panic, cell::RefCell}; + +struct LogDrop<'a>(i32, Context<'a>); + +#[derive(Copy, Clone)] +struct Context<'a> { + panic_on: i32, + drops: &'a RefCell>, +} + +impl<'a> Context<'a> { + fn record_drop(self, index: i32) { + self.drops.borrow_mut().push(index); + if index == self.panic_on { + panic!(); + } + } +} + +impl<'a> Drop for LogDrop<'a> { + fn drop(&mut self) { + self.1.record_drop(self.0); + } +} + +fn bindings_in_params((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {} +fn bindings_with_let(a: (LogDrop, LogDrop), b: (LogDrop, LogDrop)) { + // Drop order in foo is the same as the following bindings. + // _temp2 is declared after _x to avoid a difference between `_: T` and + // `x: T` in function parameters. + let _temp1 = a; + let (_x, _) = _temp1; + + let _temp2 = b; + let (_, _y) = _temp2; +} + +fn test_drop_order(panic_on: i32, fun: fn((LogDrop, LogDrop), (LogDrop, LogDrop))) { + let context = Context { + panic_on, + drops: &RefCell::new(Vec::new()), + }; + let one = LogDrop(1, context); + let two = LogDrop(2, context); + let three = LogDrop(3, context); + let four = LogDrop(4, context); + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + fun((three, four), (two, one)); + })); + if panic_on == 0 { + assert!(res.is_ok(), "should not have panicked"); + } else { + assert!(res.is_err(), "should have panicked"); + } + assert_eq!(*context.drops.borrow(), [1, 2, 3, 4], "incorrect drop order"); +} + +fn main() { + (0..=4).for_each(|i| test_drop_order(i, bindings_in_params)); + (0..=4).for_each(|i| test_drop_order(i, bindings_with_let)); + (0..=4).for_each(|i| test_drop_order(i, |(_x, _), (_, _y)| {})); +} From aa9bc68a1e50a7141ca8d6aaf90b104a435861fa Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Tue, 8 Jan 2019 17:21:30 -0500 Subject: [PATCH 02/23] RawVec doesn't always abort on allocation errors --- src/liballoc/raw_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index c05452bcf4d..5e4aac9ce78 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -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 /// From 6a90f1414fbe5109c0954f7927726c1f3e866067 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 9 Jan 2019 20:53:33 +0900 Subject: [PATCH 03/23] Add check_attribute --- src/librustc_lint/builtin.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a555b779097..f41954f5650 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -227,6 +227,12 @@ impl UnsafeCode { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { + fn check_attribute(&mut self, cx: &LateContext, 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: &LateContext, e: &hir::Expr) { if let hir::ExprKind::Block(ref blk, _) = e.node { // Don't warn about generated blocks, that'll just pollute the output. From 3cf3ed787740a82b4f3ab76db454218177a7a08a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 9 Jan 2019 21:13:42 +0900 Subject: [PATCH 04/23] Separate the description on different lines --- src/librustc_lint/builtin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f41954f5650..18b83fa1eae 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -229,7 +229,9 @@ impl UnsafeCode { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { fn check_attribute(&mut self, cx: &LateContext, 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"); + self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \ + macros using unsafe without triggering \ + the `unsafe_code` lint at their call site"); } } From 04c74f46f0a0ecf886f1c12b51483d38690fac22 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Sun, 13 Jan 2019 11:16:14 +0100 Subject: [PATCH 05/23] Add core::iter::once_with --- src/libcore/iter/mod.rs | 2 + src/libcore/iter/sources.rs | 108 ++++++++++++++++++++++++++++++++++++ src/libcore/lib.rs | 1 + src/libcore/tests/iter.rs | 17 ++++++ src/libcore/tests/lib.rs | 1 + 5 files changed, 129 insertions(+) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 03369d6c8f3..f647a61a584 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -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 = "0")] +pub use self::sources::{OnceWith, once_with}; #[unstable(feature = "iter_unfold", issue = "55977")] pub use self::sources::{Unfold, unfold, Successors, successors}; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 2a39089a8a2..d183fa3a7c2 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -377,6 +377,114 @@ pub fn once(value: T) -> Once { 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 = "0")] +pub struct OnceWith { + gen: Option, +} + +#[unstable(feature = "iter_once_with", issue = "0")] +impl A> Iterator for OnceWith { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.gen.take().map(|f| f()) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.gen.iter().size_hint() + } +} + +#[unstable(feature = "iter_once_with", issue = "0")] +impl A> DoubleEndedIterator for OnceWith { + fn next_back(&mut self) -> Option { + self.next() + } +} + +#[unstable(feature = "iter_once_with", issue = "0")] +impl A> ExactSizeIterator for OnceWith { + fn len(&self) -> usize { + self.gen.iter().len() + } +} + +#[unstable(feature = "iter_once_with", issue = "0")] +impl A> FusedIterator for OnceWith {} + +#[unstable(feature = "iter_once_with", issue = "0")] +unsafe impl A> TrustedLen for OnceWith {} + +/// 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 +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// 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 +/// 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 = "0")] +pub fn once_with A>(gen: F) -> OnceWith { + OnceWith { gen: Some(gen) } +} + /// Creates a new iterator where each iteration calls the provided closure /// `F: FnMut(&mut St) -> Option`. /// diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a5f20d08e47..598e7fd706a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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)] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index cf19851c17b..b62f55b2cd0 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1906,6 +1906,23 @@ fn test_once() { assert_eq!(it.next(), None); } +#[test] +fn test_once_with() { + let mut count = 0; + let mut it = once_with(|| { + count += 1; + 42 + }); + + assert_eq!(count, 0); + assert_eq!(it.next(), Some(42)); + assert_eq!(count, 1); + assert_eq!(it.next(), None); + assert_eq!(count, 1); + assert_eq!(it.next(), None); + assert_eq!(count, 1); +} + #[test] fn test_empty() { let mut it = empty::(); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 72846daf16a..a9b8decfd02 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -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)] From de6566ce391478c5c483fed98eaf6e3c37f4dab9 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 5 Jan 2019 16:19:34 +0200 Subject: [PATCH 06/23] forbid manually impl'ing one of an object type's marker traits This shouldn't break compatibility for crates that do not use `feature(optin_builtin_traits)`, because as the test shows, it is only possible to impl a marker trait for a trait object in the crate the marker trait is defined in, which must define `feature(optin_builtin_traits)`. Fixes #56934 --- src/librustc_typeck/coherence/mod.rs | 17 +++++++-- ...ce-impl-trait-for-marker-trait-negative.rs | 29 +++++++++++++++ ...mpl-trait-for-marker-trait-negative.stderr | 37 +++++++++++++++++++ ...ce-impl-trait-for-marker-trait-positive.rs | 29 +++++++++++++++ ...mpl-trait-for-marker-trait-positive.stderr | 37 +++++++++++++++++++ 5 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs create mode 100644 src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr create mode 100644 src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs create mode 100644 src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index ce71be07efd..8053ed130e9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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, @@ -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`)? } } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs new file mode 100644 index 00000000000..5ea69190951 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs @@ -0,0 +1,29 @@ +#![feature(optin_builtin_traits)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Negative impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl !Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 +// ...and also a direct component. +impl !Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + +// But implementing a marker if it is not present is OK. +impl !Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +impl !Send for dyn Marker2 {} //~ ERROR E0117 + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +impl !Send for dyn Object {} //~ ERROR E0321 +impl !Send for dyn Object + Marker2 {} //~ ERROR E0321 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr new file mode 100644 index 00000000000..6e146760db5 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -0,0 +1,37 @@ +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:14:1 + | +LL | impl !Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` + +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:16:1 + | +LL | impl !Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:22:1 + | +LL | impl !Send for dyn Marker2 {} //~ ERROR E0117 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference any types defined in this crate + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1 + | +LL | impl !Send for dyn Object {} //~ ERROR E0321 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1 + | +LL | impl !Send for dyn Object + Marker2 {} //~ ERROR E0321 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 5 previous errors + +Some errors occurred: E0117, E0321, E0371. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs new file mode 100644 index 00000000000..6b5689e8260 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs @@ -0,0 +1,29 @@ +#![feature(optin_builtin_traits)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Positive impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 +// ...and also a direct component. +impl Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + +// But implementing a marker if it is not present is OK. +impl Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +unsafe impl Send for dyn Marker2 {} //~ ERROR E0117 + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +unsafe impl Send for dyn Object {} //~ ERROR E0321 +unsafe impl Send for dyn Object + Marker2 {} //~ ERROR E0321 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr new file mode 100644 index 00000000000..4a8347613eb --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr @@ -0,0 +1,37 @@ +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:14:1 + | +LL | impl Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` + +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:16:1 + | +LL | impl Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:22:1 + | +LL | unsafe impl Send for dyn Marker2 {} //~ ERROR E0117 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference any types defined in this crate + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:26:1 + | +LL | unsafe impl Send for dyn Object {} //~ ERROR E0321 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1 + | +LL | unsafe impl Send for dyn Object + Marker2 {} //~ ERROR E0321 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 5 previous errors + +Some errors occurred: E0117, E0321, E0371. +For more information about an error, try `rustc --explain E0117`. From 791573271415a1f07c274d676da4fe39963ac92c Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Sun, 13 Jan 2019 21:24:15 +0100 Subject: [PATCH 07/23] Fix intradoc link and update issue number --- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/sources.rs | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index f647a61a584..cc173eff03e 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -329,7 +329,7 @@ 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 = "0")] +#[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}; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index d183fa3a7c2..103d02da22f 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -385,12 +385,12 @@ pub fn once(value: T) -> Once { /// /// [`once_with`]: fn.once_with.html #[derive(Copy, Clone, Debug)] -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] pub struct OnceWith { gen: Option, } -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] impl A> Iterator for OnceWith { type Item = A; @@ -405,24 +405,24 @@ impl A> Iterator for OnceWith { } } -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] impl A> DoubleEndedIterator for OnceWith { fn next_back(&mut self) -> Option { self.next() } } -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] impl A> ExactSizeIterator for OnceWith { fn len(&self) -> usize { self.gen.iter().len() } } -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] impl A> FusedIterator for OnceWith {} -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] unsafe impl A> TrustedLen for OnceWith {} /// Creates an iterator that lazily generates a value exactly once by invoking @@ -436,6 +436,7 @@ unsafe impl A> TrustedLen for OnceWith {} /// Unlike [`once`], this function will lazily generate the value on request. /// /// [`once`]: fn.once.html +/// [`chain`]: trait.Iterator.html#method.chain /// /// # Examples /// @@ -480,7 +481,7 @@ unsafe impl A> TrustedLen for OnceWith {} /// } /// ``` #[inline] -#[unstable(feature = "iter_once_with", issue = "0")] +#[unstable(feature = "iter_once_with", issue = "57581")] pub fn once_with A>(gen: F) -> OnceWith { OnceWith { gen: Some(gen) } } From e449f3d62927887c01fe8b16bfcb4282d007fca2 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Mon, 14 Jan 2019 00:45:57 +0100 Subject: [PATCH 08/23] Fix failing test --- src/libcore/tests/iter.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b62f55b2cd0..e2242ecc8cf 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1,3 +1,4 @@ +use core::cell::Cell; use core::iter::*; use core::{i8, i16, isize}; use core::usize; @@ -1908,19 +1909,19 @@ fn test_once() { #[test] fn test_once_with() { - let mut count = 0; + let mut count = Cell::new(0); let mut it = once_with(|| { - count += 1; + count.set(count.get() + 1); 42 }); - assert_eq!(count, 0); + assert_eq!(count.get(), 0); assert_eq!(it.next(), Some(42)); - assert_eq!(count, 1); + assert_eq!(count.get(), 1); assert_eq!(it.next(), None); - assert_eq!(count, 1); + assert_eq!(count.get(), 1); assert_eq!(it.next(), None); - assert_eq!(count, 1); + assert_eq!(count.get(), 1); } #[test] From f2dbdc4302b12c126953ac6ffb8609cb86659f22 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 14 Jan 2019 01:16:27 -0500 Subject: [PATCH 09/23] Add 'rustc-env:RUST_BACKTRACE=0' to const-pat-ice test This ensures that the test passes, regardless of what the user has set RUST_BACKTRACE to. --- src/test/ui/pattern/const-pat-ice.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/pattern/const-pat-ice.rs b/src/test/ui/pattern/const-pat-ice.rs index 6496a2ab69f..865c54be1ad 100644 --- a/src/test/ui/pattern/const-pat-ice.rs +++ b/src/test/ui/pattern/const-pat-ice.rs @@ -1,4 +1,5 @@ // failure-status: 101 +// rustc-env:RUST_BACKTRACE=0 // This is a repro test for an ICE in our pattern handling of constants. From 7c083a8fede186f2fc39a1d0e30ee156417473b0 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Mon, 14 Jan 2019 12:23:50 +0100 Subject: [PATCH 10/23] Remove unnecessary mut --- src/libcore/tests/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index e2242ecc8cf..3944bc749d0 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1909,7 +1909,7 @@ fn test_once() { #[test] fn test_once_with() { - let mut count = Cell::new(0); + let count = Cell::new(0); let mut it = once_with(|| { count.set(count.get() + 1); 42 From 84718c1999482f703ab7fc58a70ffc86269efac8 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Mon, 14 Jan 2019 17:20:41 +0100 Subject: [PATCH 11/23] Add feature(iter_once_with) --- src/libcore/iter/sources.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 103d02da22f..59220b32091 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -443,6 +443,8 @@ unsafe impl A> TrustedLen for OnceWith {} /// Basic usage: /// /// ``` +/// #![feature(iter_once_with)] +/// /// use std::iter; /// /// // one is the loneliest number From 3a1f0131a63a32a82f22b1c4ae04f8177730588f Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Mon, 14 Jan 2019 17:36:34 +0100 Subject: [PATCH 12/23] Add another feature(iter_once_with) --- src/libcore/iter/sources.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 59220b32091..2590fa6023a 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -461,6 +461,8 @@ unsafe impl A> TrustedLen for OnceWith {} /// `.foorc`: /// /// ```no_run +/// #![feature(iter_once_with)] +/// /// use std::iter; /// use std::fs; /// use std::path::PathBuf; From d808f938bc47d72fd5f7ff879a33e6be9bb6a499 Mon Sep 17 00:00:00 2001 From: timvisee Date: Mon, 14 Jan 2019 21:20:01 +0100 Subject: [PATCH 13/23] Simplify 'product' factorial example --- src/libcore/iter/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 640af748172..0ad29afbade 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -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); From ea5197c664bbd1f1f7e8210544a32f1cb1cdfaec Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 05:36:46 +0900 Subject: [PATCH 14/23] Add PartialEq --- src/libsyntax/ast.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e3a8980a975..99ab9fbcf5f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -853,13 +853,13 @@ pub struct Field { pub type SpannedIdent = Spanned; -#[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, From f18ae26840399371ea969e70e9d1a79823f800b8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 05:42:09 +0900 Subject: [PATCH 15/23] Run lint for unsafe on the ast --- src/librustc_lint/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 4dfb664451b..0d05cc1b2be 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -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, @@ -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, From 60a68bed7b1da4cd9052c2610525c3c50dd344d2 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 06:54:28 +0900 Subject: [PATCH 16/23] Make UnsafeCode EarlyLintPass --- src/librustc_lint/builtin.rs | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 18b83fa1eae..6cd632321cc 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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}; @@ -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; @@ -226,31 +226,30 @@ impl UnsafeCode { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { - fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) { +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"); + self.report_unsafe(cx, attr.span, "cannot use `allow_internal_unsafe` \ + with `forbid(unsafe_code)`"); } } - fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { - if let hir::ExprKind::Block(ref blk, _) = e.node { + 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") } @@ -259,19 +258,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") } } @@ -280,9 +278,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, _) = item.node { + if sig.header.unsafety == ast::Unsafety::Unsafe { self.report_unsafe(cx, item.span, "declaration of an `unsafe` method") } } From efd111e5026ccc78f78c3534267e5ba74899f268 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 06:55:17 +0900 Subject: [PATCH 17/23] Add test --- src/test/ui/lint/lint-forbid-internal-unsafe.rs | 16 ++++++++++++++++ .../ui/lint/lint-forbid-internal-unsafe.stderr | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/lint/lint-forbid-internal-unsafe.rs create mode 100644 src/test/ui/lint/lint-forbid-internal-unsafe.stderr diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.rs b/src/test/ui/lint/lint-forbid-internal-unsafe.rs new file mode 100644 index 00000000000..7f58b7280f3 --- /dev/null +++ b/src/test/ui/lint/lint-forbid-internal-unsafe.rs @@ -0,0 +1,16 @@ +#![forbid(unsafe_code)] +#![feature(allow_internal_unsafe)] + +#[allow_internal_unsafe] +//~^ ERROR: cannot use `allow_internal_unsafe` with `forbid(unsafe_code)` +macro_rules! evil { + ($e:expr) => { + unsafe { + $e + } + } +} + +fn main() { + println!("{}", evil!(*(0 as *const u8))); +} diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr new file mode 100644 index 00000000000..b65ba6118b9 --- /dev/null +++ b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr @@ -0,0 +1,14 @@ +error: cannot use `allow_internal_unsafe` with `forbid(unsafe_code)` + --> $DIR/lint-forbid-internal-unsafe.rs:4:1 + | +LL | #[allow_internal_unsafe] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/lint-forbid-internal-unsafe.rs:1:11 + | +LL | #![forbid(unsafe_code)] + | ^^^^^^^^^^^ + +error: aborting due to previous error + From a7623e70d5d3f27293483b0d609d7c446f3499f7 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 06:56:21 +0900 Subject: [PATCH 18/23] Add error check --- src/test/ui/lint/lint-unsafe-code.rs | 3 ++ src/test/ui/lint/lint-unsafe-code.stderr | 40 +++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/test/ui/lint/lint-unsafe-code.rs b/src/test/ui/lint/lint-unsafe-code.rs index 735f33f601f..b6d2da12db3 100644 --- a/src/test/ui/lint/lint-unsafe-code.rs +++ b/src/test/ui/lint/lint-unsafe-code.rs @@ -27,7 +27,9 @@ unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait trait Baz { unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method + //~^ ERROR: declaration of an `unsafe` method unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method + //~^ ERROR: declaration of an `unsafe` method } impl Baz for Bar { @@ -63,6 +65,7 @@ trait C { #[allow(unsafe_code)] unsafe fn baz(&self); unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method + //~^ ERROR: declaration of an `unsafe` method } impl C for Bar { diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index e2dd45e2c8a..2d08902dc69 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -28,56 +28,74 @@ error: declaration of an `unsafe` method LL | unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^ -error: implementation of an `unsafe` method +error: declaration of an `unsafe` method --> $DIR/lint-unsafe-code.rs:29:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:30:5 + --> $DIR/lint-unsafe-code.rs:29:5 + | +LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: declaration of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:31:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:34:5 + --> $DIR/lint-unsafe-code.rs:31:5 + | +LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:36:5 | LL | unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:35:5 + --> $DIR/lint-unsafe-code.rs:37:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:54:5 + --> $DIR/lint-unsafe-code.rs:56:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:65:5 +error: declaration of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:67:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:71:5 + --> $DIR/lint-unsafe-code.rs:67:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:75:5 + --> $DIR/lint-unsafe-code.rs:74:5 + | +LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:78:5 | LL | unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of an `unsafe` block - --> $DIR/lint-unsafe-code.rs:86:5 + --> $DIR/lint-unsafe-code.rs:89:5 | LL | unsafe {} //~ ERROR: usage of an `unsafe` block | ^^^^^^^^^ @@ -91,5 +109,5 @@ LL | unsafe {} //~ ERROR: usage of an `unsafe` block LL | unsafe_in_macro!() | ------------------ in this macro invocation -error: aborting due to 14 previous errors +error: aborting due to 17 previous errors From d38a59f8b5ad8ddbed5294bb4755618d7c2802aa Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 15 Jan 2019 00:26:50 +0200 Subject: [PATCH 19/23] fix test output changing in rebase --- .../coherence-impl-trait-for-marker-trait-negative.stderr | 2 +- .../coherence-impl-trait-for-marker-trait-positive.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr index 6e146760db5..c8a146cdd44 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl !Send for dyn Marker2 {} //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr index 4a8347613eb..78ca2f5279d 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr @@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | unsafe impl Send for dyn Marker2 {} //~ ERROR E0117 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | - = note: the impl does not reference any types defined in this crate + = note: the impl does not reference only types defined in this crate = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` From 0d695ff33089c91a68c4be0877a53a216b991f10 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jan 2019 00:41:41 +0100 Subject: [PATCH 20/23] Fix crates filtering box not being filled --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 75b0f5df0d8..e75b471a8e8 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2422,7 +2422,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); From d04f7560275ab61ff4b5049ea64599d79a052509 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 18:01:38 +0900 Subject: [PATCH 21/23] Restore error message --- src/librustc_lint/builtin.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6cd632321cc..50631a74fe6 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -229,8 +229,9 @@ impl UnsafeCode { 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, "cannot use `allow_internal_unsafe` \ - with `forbid(unsafe_code)`"); + self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \ + macros using unsafe without triggering \ + the `unsafe_code` lint at their call site"); } } From b39e9e2d07a79998f7e6a87f1c0855f5a939b92e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 18:02:22 +0900 Subject: [PATCH 22/23] Change from _ to None --- src/librustc_lint/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 50631a74fe6..52eab9b12f3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -280,7 +280,7 @@ impl EarlyLintPass for UnsafeCode { } fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) { - if let ast::TraitItemKind::Method(ref sig, _) = item.node { + 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") } From bd1551e46e4a788dc974f4aac8ba821133625663 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 15 Jan 2019 18:02:46 +0900 Subject: [PATCH 23/23] Fix tests --- .../ui/lint/lint-forbid-internal-unsafe.rs | 2 +- .../lint/lint-forbid-internal-unsafe.stderr | 2 +- src/test/ui/lint/lint-unsafe-code.rs | 3 -- src/test/ui/lint/lint-unsafe-code.stderr | 40 +++++-------------- 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.rs b/src/test/ui/lint/lint-forbid-internal-unsafe.rs index 7f58b7280f3..b08fbf6f845 100644 --- a/src/test/ui/lint/lint-forbid-internal-unsafe.rs +++ b/src/test/ui/lint/lint-forbid-internal-unsafe.rs @@ -2,7 +2,7 @@ #![feature(allow_internal_unsafe)] #[allow_internal_unsafe] -//~^ ERROR: cannot use `allow_internal_unsafe` with `forbid(unsafe_code)` +//~^ ERROR: `allow_internal_unsafe` allows defining macro_rules! evil { ($e:expr) => { unsafe { diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr index b65ba6118b9..59dab119682 100644 --- a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr +++ b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr @@ -1,4 +1,4 @@ -error: cannot use `allow_internal_unsafe` with `forbid(unsafe_code)` +error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site --> $DIR/lint-forbid-internal-unsafe.rs:4:1 | LL | #[allow_internal_unsafe] diff --git a/src/test/ui/lint/lint-unsafe-code.rs b/src/test/ui/lint/lint-unsafe-code.rs index b6d2da12db3..735f33f601f 100644 --- a/src/test/ui/lint/lint-unsafe-code.rs +++ b/src/test/ui/lint/lint-unsafe-code.rs @@ -27,9 +27,7 @@ unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait trait Baz { unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method - //~^ ERROR: declaration of an `unsafe` method unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method - //~^ ERROR: declaration of an `unsafe` method } impl Baz for Bar { @@ -65,7 +63,6 @@ trait C { #[allow(unsafe_code)] unsafe fn baz(&self); unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method - //~^ ERROR: declaration of an `unsafe` method } impl C for Bar { diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index 2d08902dc69..e2dd45e2c8a 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -28,74 +28,56 @@ error: declaration of an `unsafe` method LL | unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^ -error: declaration of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:29:5 - | -LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: implementation of an `unsafe` method --> $DIR/lint-unsafe-code.rs:29:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: declaration of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:31:5 +error: implementation of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:30:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:31:5 - | -LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:36:5 + --> $DIR/lint-unsafe-code.rs:34:5 | LL | unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:37:5 + --> $DIR/lint-unsafe-code.rs:35:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:56:5 + --> $DIR/lint-unsafe-code.rs:54:5 | LL | unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: declaration of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:67:5 +error: implementation of an `unsafe` method + --> $DIR/lint-unsafe-code.rs:65:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:67:5 + --> $DIR/lint-unsafe-code.rs:71:5 | LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:74:5 - | -LL | unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of an `unsafe` method - --> $DIR/lint-unsafe-code.rs:78:5 + --> $DIR/lint-unsafe-code.rs:75:5 | LL | unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of an `unsafe` block - --> $DIR/lint-unsafe-code.rs:89:5 + --> $DIR/lint-unsafe-code.rs:86:5 | LL | unsafe {} //~ ERROR: usage of an `unsafe` block | ^^^^^^^^^ @@ -109,5 +91,5 @@ LL | unsafe {} //~ ERROR: usage of an `unsafe` block LL | unsafe_in_macro!() | ------------------ in this macro invocation -error: aborting due to 17 previous errors +error: aborting due to 14 previous errors