about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-23 00:10:17 +0000
committerbors <bors@rust-lang.org>2019-06-23 00:10:17 +0000
commita96ba969156d257e5d5b692946fa8fe40ed6543a (patch)
tree6b20831f5e7fe26a17165678bc6c0ea78d492621
parentde02101e6d949c4a9040211e9ce8c488a997497e (diff)
parent74380b3336d6d93b74f65f0a1034b29b53aae268 (diff)
downloadrust-a96ba969156d257e5d5b692946fa8fe40ed6543a.tar.gz
rust-a96ba969156d257e5d5b692946fa8fe40ed6543a.zip
Auto merge of #62069 - Centril:rollup-m8n4uw7, r=Centril
Rollup of 5 pull requests

Successful merges:

 - #62047 (Trigger `unused_attribute` lint on `#[cfg_attr($pred,)]`)
 - #62049 (Fix one missing `dyn`.)
 - #62051 (Lint empty `#[derive()]` as unused attribute.)
 - #62057 (Deny explicit_outlives_requirements in the compiler)
 - #62068 (Fix meta-variable binding errors in macros)

Failed merges:

r? @ghost
-rw-r--r--src/libcore/fmt/mod.rs8
-rw-r--r--src/libcore/hash/mod.rs6
-rw-r--r--src/libcore/iter/traits/accum.rs4
-rw-r--r--src/libcore/macros.rs6
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/ptr/mod.rs12
-rw-r--r--src/libproc_macro/bridge/rpc.rs6
-rw-r--r--src/librustc/hir/itemlikevisit.rs2
-rw-r--r--src/librustc/infer/nll_relate/mod.rs2
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/weak_lang_items.rs2
-rw-r--r--src/librustc/ty/context.rs6
-rw-r--r--src/librustc/ty/query/plumbing.rs4
-rw-r--r--src/librustc_codegen_llvm/builder.rs2
-rw-r--r--src/librustc_codegen_llvm/lib.rs1
-rw-r--r--src/librustc_codegen_ssa/lib.rs1
-rw-r--r--src/librustc_data_structures/indexed_vec.rs2
-rw-r--r--src/librustc_lint/types.rs2
-rw-r--r--src/librustc_mir/dataflow/graphviz.rs2
-rw-r--r--src/librustc_mir/dataflow/mod.rs2
-rw-r--r--src/librustc_mir/interpret/intern.rs2
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs2
-rw-r--r--src/librustc_target/spec/mod.rs6
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/libserialize/serialize.rs18
-rw-r--r--src/libsyntax/config.rs21
-rw-r--r--src/libsyntax/ext/derive.rs4
-rw-r--r--src/libsyntax/ext/expand.rs12
-rw-r--r--src/libsyntax_ext/deriving/mod.rs2
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs2
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.rs13
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr21
-rw-r--r--src/test/ui/derives/deriving-meta-empty-trait-list.rs6
-rw-r--r--src/test/ui/derives/deriving-meta-empty-trait-list.stderr11
-rw-r--r--src/test/ui/issues/issue-22814.rs2
-rw-r--r--src/test/ui/malformed/malformed-derive-entry.rs3
-rw-r--r--src/test/ui/malformed/malformed-derive-entry.stderr8
38 files changed, 117 insertions, 91 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 2f6d745d146..17ea5843881 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -2070,19 +2070,19 @@ macro_rules! tuple {
     () => ();
     ( $($name:ident,)+ ) => (
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized {
+        impl<$($name:Debug),+> Debug for ($($name,)+) where last_type!($($name,)+): ?Sized {
             #[allow(non_snake_case, unused_assignments)]
             fn fmt(&self, f: &mut Formatter<'_>) -> Result {
                 let mut builder = f.debug_tuple("");
-                let ($(ref $name,)*) = *self;
+                let ($(ref $name,)+) = *self;
                 $(
                     builder.field(&$name);
-                )*
+                )+
 
                 builder.finish()
             }
         }
-        peel! { $($name,)* }
+        peel! { $($name,)+ }
     )
 }
 
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 98150fd9f82..38e38642842 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -617,11 +617,11 @@ mod impls {
 
         ( $($name:ident)+) => (
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
+            impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
                 #[allow(non_snake_case)]
                 fn hash<S: Hasher>(&self, state: &mut S) {
-                    let ($(ref $name,)*) = *self;
-                    $($name.hash(state);)*
+                    let ($(ref $name,)+) = *self;
+                    $($name.hash(state);)+
                 }
             }
         );
diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs
index 4eac5cbc8e6..adfb639bae3 100644
--- a/src/libcore/iter/traits/accum.rs
+++ b/src/libcore/iter/traits/accum.rs
@@ -72,10 +72,10 @@ macro_rules! integer_sum_product {
     ($($a:ty)*) => (
         integer_sum_product!(@impls 0, 1,
                 #[stable(feature = "iter_arith_traits", since = "1.12.0")],
-                $($a)+);
+                $($a)*);
         integer_sum_product!(@impls Wrapping(0), Wrapping(1),
                 #[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
-                $(Wrapping<$a>)+);
+                $(Wrapping<$a>)*);
     );
 }
 
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 8b44025f91f..589061b2826 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -15,7 +15,7 @@ macro_rules! panic {
         $crate::panic!($msg)
     );
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*),
+        $crate::panicking::panic_fmt(format_args!($fmt, $($arg)+),
                                      &(file!(), line!(), __rust_unstable_column!()))
     });
 }
@@ -558,7 +558,7 @@ macro_rules! unreachable {
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! unimplemented {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)+)));
 }
 
 /// Indicates unfinished code.
@@ -617,7 +617,7 @@ macro_rules! unimplemented {
 #[unstable(feature = "todo_macro", issue = "59277")]
 macro_rules! todo {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)+)));
 }
 
 /// Creates an array of [`MaybeUninit`].
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 74f685a6de2..3f4ff7c2f43 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -103,7 +103,7 @@ pub trait Sized {
 /// `Unsize` is implemented for:
 ///
 /// - `[T; N]` is `Unsize<[T]>`
-/// - `T` is `Unsize<Trait>` when `T: Trait`
+/// - `T` is `Unsize<dyn Trait>` when `T: Trait`
 /// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
 ///   - `T: Unsize<U>`
 ///   - Foo is a struct
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index ba88fde6ebc..fccb00d768c 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -2725,12 +2725,12 @@ macro_rules! fnptr_impls_safety_abi {
 
 macro_rules! fnptr_impls_args {
     ($($Arg: ident),+) => {
-        fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
+        fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
     };
     () => {
         // No variadic functions with 0 parameters
diff --git a/src/libproc_macro/bridge/rpc.rs b/src/libproc_macro/bridge/rpc.rs
index 5018be74f89..5c2f9ec9848 100644
--- a/src/libproc_macro/bridge/rpc.rs
+++ b/src/libproc_macro/bridge/rpc.rs
@@ -59,7 +59,7 @@ macro_rules! rpc_encode_decode {
         }
     };
     (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
-        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)* {
+        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
             fn encode(self, w: &mut Writer, s: &mut S) {
                 // HACK(eddyb): `Tag` enum duplicated between the
                 // two impls as there's no other place to stash it.
@@ -79,8 +79,8 @@ macro_rules! rpc_encode_decode {
             }
         }
 
-        impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)*> DecodeMut<'a, '_, S>
-            for $name $(<$($T),+>)*
+        impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
+            for $name $(<$($T),+>)?
         {
             fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
                 // HACK(eddyb): `Tag` enum duplicated between the
diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs
index bfc9e8f06e2..35b18124583 100644
--- a/src/librustc/hir/itemlikevisit.rs
+++ b/src/librustc/hir/itemlikevisit.rs
@@ -51,7 +51,7 @@ pub trait ItemLikeVisitor<'hir> {
     fn visit_impl_item(&mut self, impl_item: &'hir ImplItem);
 }
 
-pub struct DeepVisitor<'v, V: 'v> {
+pub struct DeepVisitor<'v, V> {
     visitor: &'v mut V,
 }
 
diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs
index 21489965b1b..a1a93eb5521 100644
--- a/src/librustc/infer/nll_relate/mod.rs
+++ b/src/librustc/infer/nll_relate/mod.rs
@@ -800,7 +800,7 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
 /// [blog post]: https://is.gd/0hKvIr
 struct TypeGeneralizer<'me, 'tcx, D>
 where
-    D: TypeRelatingDelegate<'tcx> + 'me,
+    D: TypeRelatingDelegate<'tcx>,
 {
     infcx: &'me InferCtxt<'me, 'tcx>,
 
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index e2f2799d963..257d5159f11 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -31,7 +31,6 @@
 #![deny(rust_2018_idioms)]
 #![deny(internal)]
 #![deny(unused_lifetimes)]
-#![allow(explicit_outlives_requirements)]
 
 #![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index b6cd24c291a..4fb88dadd1f 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -147,7 +147,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let lang_items = self.lang_items();
         let did = Some(item_def_id);
 
-        $(lang_items.$name() == did)||+
+        $(lang_items.$name() == did)||*
     }
 }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ce785f9a024..28399ed5439 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -231,7 +231,7 @@ pub struct CommonConsts<'tcx> {
     pub err: &'tcx Const<'tcx>,
 }
 
-pub struct LocalTableInContext<'a, V: 'a> {
+pub struct LocalTableInContext<'a, V> {
     local_id_root: Option<DefId>,
     data: &'a ItemLocalMap<V>
 }
@@ -294,7 +294,7 @@ impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
     }
 }
 
-pub struct LocalTableInContextMut<'a, V: 'a> {
+pub struct LocalTableInContextMut<'a, V> {
     local_id_root: Option<DefId>,
     data: &'a mut ItemLocalMap<V>
 }
@@ -2171,7 +2171,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
 
 /// An entry in an interner.
-struct Interned<'tcx, T: 'tcx+?Sized>(&'tcx T);
+struct Interned<'tcx, T: ?Sized>(&'tcx T);
 
 impl<'tcx, T: 'tcx+?Sized> Clone for Interned<'tcx, T> {
     fn clone(&self) -> Self {
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 0f158d2982a..7d5f984c1b6 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -89,7 +89,7 @@ macro_rules! profq_query_msg {
 
 /// A type representing the responsibility to execute the job in the `job` field.
 /// This will poison the relevant query if dropped.
-pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx> + 'a> {
+pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> {
     cache: &'a Lock<QueryCache<'tcx, Q>>,
     key: Q::Key,
     job: Lrc<QueryJob<'tcx>>,
@@ -230,7 +230,7 @@ pub struct CycleError<'tcx> {
 }
 
 /// The result of `try_get_lock`
-pub(super) enum TryGetJob<'a, 'tcx, D: QueryDescription<'tcx> + 'a> {
+pub(super) enum TryGetJob<'a, 'tcx, D: QueryDescription<'tcx>> {
     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
     NotYetStarted(JobOwner<'a, 'tcx, D>),
 
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index e06b4d8b306..0709368ad86 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -110,7 +110,7 @@ macro_rules! builder_methods_for_value_instructions {
             unsafe {
                 llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED)
             }
-        })*
+        })+
     }
 }
 
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 1eb6e9a5283..7283aa95b30 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -24,7 +24,6 @@
 #![deny(rust_2018_idioms)]
 #![deny(internal)]
 #![deny(unused_lifetimes)]
-#![allow(explicit_outlives_requirements)]
 
 use back::write::{create_target_machine, create_informational_target_machine};
 use syntax_pos::symbol::Symbol;
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 71393e224e4..b76f098773f 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -15,7 +15,6 @@
 #![deny(rust_2018_idioms)]
 #![deny(internal)]
 #![deny(unused_lifetimes)]
-#![allow(explicit_outlives_requirements)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index c7f6e54c3d5..635edbb927e 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -423,7 +423,7 @@ macro_rules! newtype_index {
     (@derives      [$($derives:ident,)*]
      @attrs        [$(#[$attrs:meta])*]
      @type         [$type:ident]
-     @max          [$_max:expr]
+     @max          [$max:expr]
      @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    $(#[doc = $doc:expr])*
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index cd4eecf2638..2fb534e8228 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -219,7 +219,7 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
                             return Some(format!("{:?}", $itypes))
                         })*
                         None
-                    },)*
+                    },)+
                     _ => None
                 }
             }
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
index f62ad2fbef7..7896592eea6 100644
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ b/src/librustc_mir/dataflow/graphviz.rs
@@ -30,7 +30,7 @@ impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
     fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state }
 }
 
-struct Graph<'a, 'tcx, MWF:'a, P> where
+struct Graph<'a, 'tcx, MWF, P> where
     MWF: MirWithFlowState<'tcx>
 {
     mbcx: &'a MWF,
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 0728d5b21bb..89b952e9f8b 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -181,7 +181,7 @@ where
 
 struct PropagationContext<'b, 'a, 'tcx, O>
 where
-    O: 'b + BitDenotation<'tcx>,
+    O: BitDenotation<'tcx>,
 {
     builder: &'b mut DataflowAnalysis<'a, 'tcx, O>,
 }
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index d998f40c86e..416b66daa05 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -21,7 +21,7 @@ use super::{
 };
 use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext};
 
-struct InternVisitor<'rt, 'mir: 'rt, 'tcx: 'rt + 'mir> {
+struct InternVisitor<'rt, 'mir, 'tcx> {
     /// previously encountered safe references
     ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
     ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index a7cbe84330d..cb02e1a778c 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -30,7 +30,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![deny(rust_2018_idioms)]
 #![deny(internal)]
 #![deny(unused_lifetimes)]
-#![allow(explicit_outlives_requirements)]
 
 #[macro_use] extern crate log;
 #[macro_use]
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 815d210d36e..91fc19b71d8 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -92,7 +92,7 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug {
 #[derive(Debug)]
 struct DropCtxt<'l, 'b, 'tcx, D>
 where
-    D: DropElaborator<'b, 'tcx> + 'l,
+    D: DropElaborator<'b, 'tcx>,
 {
     elaborator: &'l mut D,
 
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 08cf062e858..75821aba470 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -119,19 +119,19 @@ macro_rules! flavor_mappings {
     ($((($($flavor:tt)*), $string:expr),)*) => (
         impl LinkerFlavor {
             pub const fn one_of() -> &'static str {
-                concat!("one of: ", $($string, " ",)+)
+                concat!("one of: ", $($string, " ",)*)
             }
 
             pub fn from_str(s: &str) -> Option<Self> {
                 Some(match s {
-                    $($string => $($flavor)*,)+
+                    $($string => $($flavor)*,)*
                     _ => return None,
                 })
             }
 
             pub fn desc(&self) -> &str {
                 match *self {
-                    $($($flavor)* => $string,)+
+                    $($($flavor)* => $string,)*
                 }
             }
         }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index cc6f7a07d96..ec0f431d9b2 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -75,7 +75,6 @@ This API is completely unstable and subject to change.
 #![deny(rust_2018_idioms)]
 #![deny(internal)]
 #![deny(unused_lifetimes)]
-#![allow(explicit_outlives_requirements)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 95095c712d2..2def2a455fb 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -739,33 +739,33 @@ macro_rules! count {
 macro_rules! tuple {
     () => ();
     ( $($name:ident,)+ ) => (
-        impl<$($name:Decodable),*> Decodable for ($($name,)*) {
+        impl<$($name:Decodable),+> Decodable for ($($name,)+) {
             #[allow(non_snake_case)]
-            fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)*), D::Error> {
-                let len: usize = count!($($name)*);
+            fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)+), D::Error> {
+                let len: usize = count!($($name)+);
                 d.read_tuple(len, |d| {
                     let mut i = 0;
                     let ret = ($(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name, D::Error> {
                         Decodable::decode(d)
-                    })?,)*);
+                    })?,)+);
                     Ok(ret)
                 })
             }
         }
-        impl<$($name:Encodable),*> Encodable for ($($name,)*) {
+        impl<$($name:Encodable),+> Encodable for ($($name,)+) {
             #[allow(non_snake_case)]
             fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-                let ($(ref $name,)*) = *self;
+                let ($(ref $name,)+) = *self;
                 let mut n = 0;
-                $(let $name = $name; n += 1;)*
+                $(let $name = $name; n += 1;)+
                 s.emit_tuple(n, |s| {
                     let mut i = 0;
-                    $(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s))?;)*
+                    $(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s))?;)+
                     Ok(())
                 })
             }
         }
-        peel! { $($name,)* }
+        peel! { $($name,)+ }
     )
 }
 
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 3b42e1de614..1ab367f73c1 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -91,10 +91,10 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if !attr.check_name(sym::cfg_attr) {
+        if attr.path != sym::cfg_attr {
             return vec![attr];
         }
-        if attr.tokens.len() == 0 {
+        if attr.tokens.is_empty() {
             self.sess.span_diagnostic
                 .struct_span_err(
                     attr.span,
@@ -108,7 +108,7 @@ impl<'a> StripUnconfigured<'a> {
                        <https://doc.rust-lang.org/reference/conditional-compilation.html\
                        #the-cfg_attr-attribute>")
                 .emit();
-            return Vec::new();
+            return vec![];
         }
 
         let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
@@ -133,17 +133,18 @@ impl<'a> StripUnconfigured<'a> {
             Ok(result) => result,
             Err(mut e) => {
                 e.emit();
-                return Vec::new();
+                return vec![];
             }
         };
 
-        // Check feature gate and lint on zero attributes in source. Even if the feature is gated,
-        // we still compute as if it wasn't, since the emitted error will stop compilation further
-        // along the compilation.
-        if expanded_attrs.len() == 0 {
-            // FIXME: Emit unused attribute lint here.
+        // Lint on zero attributes in source.
+        if expanded_attrs.is_empty() {
+            return vec![attr];
         }
 
+        // At this point we know the attribute is considered used.
+        attr::mark_used(&attr);
+
         if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
             // We call `process_cfg_attr` recursively in case there's a
             // `cfg_attr` inside of another `cfg_attr`. E.g.
@@ -159,7 +160,7 @@ impl<'a> StripUnconfigured<'a> {
             }))
             .collect()
         } else {
-            Vec::new()
+            vec![]
         }
     }
 
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index abc451c96ae..3b4243ed24f 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -30,10 +30,6 @@ pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) ->
 
         match attr.parse_list(cx.parse_sess,
                               |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) {
-            Ok(ref traits) if traits.is_empty() => {
-                cx.span_warn(attr.span, "empty trait list in `derive`");
-                false
-            }
             Ok(traits) => {
                 result.extend(traits);
                 true
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index cfd67575b6f..945cf36af46 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -98,9 +98,9 @@ macro_rules! ast_fragments {
                             }
                         });
                     }
-                    $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)*)*
+                    $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
                     $($(AstFragment::$Kind(ast) =>
-                        ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)*)*
+                        ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
                 }
             }
 
@@ -108,10 +108,10 @@ macro_rules! ast_fragments {
                 match *self {
                     AstFragment::OptExpr(Some(ref expr)) => visitor.visit_expr(expr),
                     AstFragment::OptExpr(None) => {}
-                    $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)*)*
+                    $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)*
                     $($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] {
                         visitor.$visit_ast_elt(ast_elt);
-                    })*)*
+                    })?)*
                 }
             }
         }
@@ -122,10 +122,10 @@ macro_rules! ast_fragments {
             }
             $($(fn $mut_visit_ast(&mut self, ast: &mut $AstTy) {
                 visit_clobber(ast, |ast| self.expand_fragment(AstFragment::$Kind(ast)).$make_ast());
-            })*)*
+            })?)*
             $($(fn $flat_map_ast_elt(&mut self, ast_elt: <$AstTy as IntoIterator>::Item) -> $AstTy {
                 self.expand_fragment(AstFragment::$Kind(smallvec![ast_elt])).$make_ast()
-            })*)*
+            })?)*
         }
 
         impl<'a> MacResult for crate::ext::tt::macro_rules::ParserAnyMacro<'a> {
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index 1fe6094fca6..e75eff2e857 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -88,7 +88,7 @@ macro_rules! derive_traits {
                         )
                     }),
                 );
-            )*
+            )+
         }
     }
 }
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index b5d5a38ce5b..c9d99e5831a 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -70,7 +70,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
         macro_rules! tt {
             ($ty:ident { $($field:ident $(: $value:expr)*),+ $(,)? }) => (
                 TokenTree::$ty(self::$ty {
-                    $($field $(: $value)*,)*
+                    $($field $(: $value)*,)+
                     span,
                 })
             );
diff --git a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.rs b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.rs
new file mode 100644
index 00000000000..4c96d6e7ca1
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.rs
@@ -0,0 +1,13 @@
+// Check that `#[cfg_attr($PREDICATE,)]` triggers the `unused_attribute` lint.
+
+// compile-flags: --cfg TRUE
+
+#![deny(unused)]
+
+#[cfg_attr(FALSE,)] //~ ERROR unused attribute
+fn _f() {}
+
+#[cfg_attr(TRUE,)] //~ ERROR unused attribute
+fn _g() {}
+
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr
new file mode 100644
index 00000000000..cd3563e66c7
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-attr-empty-is-unused.stderr
@@ -0,0 +1,21 @@
+error: unused attribute
+  --> $DIR/cfg-attr-empty-is-unused.rs:7:1
+   |
+LL | #[cfg_attr(FALSE,)]
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/cfg-attr-empty-is-unused.rs:5:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: #[deny(unused_attributes)] implied by #[deny(unused)]
+
+error: unused attribute
+  --> $DIR/cfg-attr-empty-is-unused.rs:10:1
+   |
+LL | #[cfg_attr(TRUE,)]
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/derives/deriving-meta-empty-trait-list.rs b/src/test/ui/derives/deriving-meta-empty-trait-list.rs
index 88248414615..4f2e31e8efb 100644
--- a/src/test/ui/derives/deriving-meta-empty-trait-list.rs
+++ b/src/test/ui/derives/deriving-meta-empty-trait-list.rs
@@ -1,6 +1,6 @@
-// compile-pass
+#![deny(unused)]
 
-#[derive()] //~ WARNING empty trait list in `derive`
-struct Bar;
+#[derive()] //~ ERROR unused attribute
+struct _Bar;
 
 pub fn main() {}
diff --git a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr
index f8414b6e65e..95c94ded3ea 100644
--- a/src/test/ui/derives/deriving-meta-empty-trait-list.stderr
+++ b/src/test/ui/derives/deriving-meta-empty-trait-list.stderr
@@ -1,6 +1,15 @@
-warning: empty trait list in `derive`
+error: unused attribute
   --> $DIR/deriving-meta-empty-trait-list.rs:3:1
    |
 LL | #[derive()]
    | ^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/deriving-meta-empty-trait-list.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: #[deny(unused_attributes)] implied by #[deny(unused)]
+
+error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-22814.rs b/src/test/ui/issues/issue-22814.rs
index b008c751064..bcc7a8a5ae0 100644
--- a/src/test/ui/issues/issue-22814.rs
+++ b/src/test/ui/issues/issue-22814.rs
@@ -3,7 +3,7 @@ trait Test {}
 
 macro_rules! test {
 ( $($name:ident)+) => (
-    impl<$($name: Test),*> Test for ($($name,)*) {
+    impl<$($name: Test),+> Test for ($($name,)+) {
     }
 )
 }
diff --git a/src/test/ui/malformed/malformed-derive-entry.rs b/src/test/ui/malformed/malformed-derive-entry.rs
index 3e53e15601b..a6d886318e8 100644
--- a/src/test/ui/malformed/malformed-derive-entry.rs
+++ b/src/test/ui/malformed/malformed-derive-entry.rs
@@ -4,9 +4,6 @@ struct Test1;
 #[derive(Copy="bad")] //~ ERROR expected one of `)`, `,`, or `::`, found `=`
 struct Test2;
 
-#[derive()] //~ WARNING empty trait list
-struct Test3;
-
 #[derive] //~ ERROR malformed `derive` attribute input
 struct Test4;
 
diff --git a/src/test/ui/malformed/malformed-derive-entry.stderr b/src/test/ui/malformed/malformed-derive-entry.stderr
index dfbc5faedac..f7500febe97 100644
--- a/src/test/ui/malformed/malformed-derive-entry.stderr
+++ b/src/test/ui/malformed/malformed-derive-entry.stderr
@@ -10,14 +10,8 @@ error: expected one of `)`, `,`, or `::`, found `=`
 LL | #[derive(Copy="bad")]
    |              ^ expected one of `)`, `,`, or `::` here
 
-warning: empty trait list in `derive`
-  --> $DIR/malformed-derive-entry.rs:7:1
-   |
-LL | #[derive()]
-   | ^^^^^^^^^^^
-
 error: malformed `derive` attribute input
-  --> $DIR/malformed-derive-entry.rs:10:1
+  --> $DIR/malformed-derive-entry.rs:7:1
    |
 LL | #[derive]
    | ^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`